tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

MacVerifyCrypto.cpp (6854B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 #include <CoreFoundation/CoreFoundation.h>
      6 #include <Security/Security.h>
      7 #include <dlfcn.h>
      8 
      9 #include "cryptox.h"
     10 
     11 // We declare the necessary parts of the Security Transforms API here since
     12 // we're building with the 10.6 SDK, which doesn't know about Security
     13 // Transforms.
     14 #if defined(__cplusplus)
     15 extern "C" {
     16 #endif
     17 const CFStringRef kSecTransformInputAttributeName = CFSTR("INPUT");
     18 typedef CFTypeRef SecTransformRef;
     19 typedef OpaqueSecKeyRef* SecKeyRef;
     20 
     21 typedef SecTransformRef (*SecTransformCreateReadTransformWithReadStreamFunc)(
     22    CFReadStreamRef inputStream);
     23 SecTransformCreateReadTransformWithReadStreamFunc
     24    SecTransformCreateReadTransformWithReadStreamPtr = NULL;
     25 typedef CFTypeRef (*SecTransformExecuteFunc)(SecTransformRef transform,
     26                                             CFErrorRef* error);
     27 SecTransformExecuteFunc SecTransformExecutePtr = NULL;
     28 typedef SecTransformRef (*SecVerifyTransformCreateFunc)(SecKeyRef key,
     29                                                        CFDataRef signature,
     30                                                        CFErrorRef* error);
     31 SecVerifyTransformCreateFunc SecVerifyTransformCreatePtr = NULL;
     32 typedef Boolean (*SecTransformSetAttributeFunc)(SecTransformRef transform,
     33                                                CFStringRef key,
     34                                                CFTypeRef value,
     35                                                CFErrorRef* error);
     36 SecTransformSetAttributeFunc SecTransformSetAttributePtr = NULL;
     37 #if defined(__cplusplus)
     38 }
     39 #endif
     40 
     41 CryptoX_Result CryptoMac_InitCryptoProvider() {
     42  if (!SecTransformCreateReadTransformWithReadStreamPtr) {
     43    SecTransformCreateReadTransformWithReadStreamPtr =
     44        (SecTransformCreateReadTransformWithReadStreamFunc)dlsym(
     45            RTLD_DEFAULT, "SecTransformCreateReadTransformWithReadStream");
     46  }
     47  if (!SecTransformExecutePtr) {
     48    SecTransformExecutePtr =
     49        (SecTransformExecuteFunc)dlsym(RTLD_DEFAULT, "SecTransformExecute");
     50  }
     51  if (!SecVerifyTransformCreatePtr) {
     52    SecVerifyTransformCreatePtr = (SecVerifyTransformCreateFunc)dlsym(
     53        RTLD_DEFAULT, "SecVerifyTransformCreate");
     54  }
     55  if (!SecTransformSetAttributePtr) {
     56    SecTransformSetAttributePtr = (SecTransformSetAttributeFunc)dlsym(
     57        RTLD_DEFAULT, "SecTransformSetAttribute");
     58  }
     59  if (!SecTransformCreateReadTransformWithReadStreamPtr ||
     60      !SecTransformExecutePtr || !SecVerifyTransformCreatePtr ||
     61      !SecTransformSetAttributePtr) {
     62    return CryptoX_Error;
     63  }
     64  return CryptoX_Success;
     65 }
     66 
     67 CryptoX_Result CryptoMac_VerifyBegin(CryptoX_SignatureHandle* aInputData) {
     68  if (!aInputData) {
     69    return CryptoX_Error;
     70  }
     71 
     72  void* inputData = CFDataCreateMutable(kCFAllocatorDefault, 0);
     73  if (!inputData) {
     74    return CryptoX_Error;
     75  }
     76 
     77  *aInputData = inputData;
     78  return CryptoX_Success;
     79 }
     80 
     81 CryptoX_Result CryptoMac_VerifyUpdate(CryptoX_SignatureHandle* aInputData,
     82                                      void* aBuf, unsigned int aLen) {
     83  if (aLen == 0) {
     84    return CryptoX_Success;
     85  }
     86  if (!aInputData || !*aInputData) {
     87    return CryptoX_Error;
     88  }
     89 
     90  CFMutableDataRef inputData = (CFMutableDataRef)*aInputData;
     91 
     92  CFDataAppendBytes(inputData, (const uint8*)aBuf, aLen);
     93  return CryptoX_Success;
     94 }
     95 
     96 CryptoX_Result CryptoMac_LoadPublicKey(const unsigned char* aCertData,
     97                                       unsigned int aDataSize,
     98                                       CryptoX_PublicKey* aPublicKey) {
     99  if (!aCertData || aDataSize == 0 || !aPublicKey) {
    100    return CryptoX_Error;
    101  }
    102  *aPublicKey = NULL;
    103  CFDataRef certData = CFDataCreate(kCFAllocatorDefault, aCertData, aDataSize);
    104  if (!certData) {
    105    return CryptoX_Error;
    106  }
    107 
    108  SecCertificateRef cert =
    109      SecCertificateCreateWithData(kCFAllocatorDefault, certData);
    110  CFRelease(certData);
    111  if (!cert) {
    112    return CryptoX_Error;
    113  }
    114 
    115  OSStatus status = SecCertificateCopyPublicKey(cert, (SecKeyRef*)aPublicKey);
    116  CFRelease(cert);
    117  if (status != 0) {
    118    return CryptoX_Error;
    119  }
    120 
    121  return CryptoX_Success;
    122 }
    123 
    124 CryptoX_Result CryptoMac_VerifySignature(CryptoX_SignatureHandle* aInputData,
    125                                         CryptoX_PublicKey* aPublicKey,
    126                                         const unsigned char* aSignature,
    127                                         unsigned int aSignatureLen) {
    128  if (!aInputData || !*aInputData || !aPublicKey || !*aPublicKey ||
    129      !aSignature || aSignatureLen == 0) {
    130    return CryptoX_Error;
    131  }
    132 
    133  CFDataRef signatureData =
    134      CFDataCreate(kCFAllocatorDefault, aSignature, aSignatureLen);
    135  if (!signatureData) {
    136    return CryptoX_Error;
    137  }
    138 
    139  CFErrorRef error;
    140  SecTransformRef verifier = SecVerifyTransformCreatePtr((SecKeyRef)*aPublicKey,
    141                                                         signatureData, &error);
    142  if (!verifier || error) {
    143    if (error) {
    144      CFRelease(error);
    145    }
    146    CFRelease(signatureData);
    147    return CryptoX_Error;
    148  }
    149 
    150  SecTransformSetAttributePtr(verifier, kSecDigestTypeAttribute, kSecDigestSHA2,
    151                              &error);
    152  if (error) {
    153    CFRelease(error);
    154    CFRelease(signatureData);
    155    CFRelease(verifier);
    156    return CryptoX_Error;
    157  }
    158 
    159  int digestLength = 384;
    160  CFNumberRef dLen =
    161      CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &digestLength);
    162  SecTransformSetAttributePtr(verifier, kSecDigestLengthAttribute, dLen,
    163                              &error);
    164  CFRelease(dLen);
    165  if (error) {
    166    CFRelease(error);
    167    CFRelease(signatureData);
    168    CFRelease(verifier);
    169    return CryptoX_Error;
    170  }
    171 
    172  SecTransformSetAttributePtr(verifier, kSecTransformInputAttributeName,
    173                              (CFDataRef)*aInputData, &error);
    174  if (error) {
    175    CFRelease(error);
    176    CFRelease(signatureData);
    177    CFRelease(verifier);
    178    return CryptoX_Error;
    179  }
    180 
    181  CryptoX_Result result = CryptoX_Error;
    182  CFTypeRef rv = SecTransformExecutePtr(verifier, &error);
    183  if (error) {
    184    CFRelease(error);
    185    CFRelease(signatureData);
    186    CFRelease(verifier);
    187    return CryptoX_Error;
    188  }
    189 
    190  if (CFGetTypeID(rv) == CFBooleanGetTypeID() &&
    191      CFBooleanGetValue((CFBooleanRef)rv) == true) {
    192    result = CryptoX_Success;
    193  }
    194 
    195  CFRelease(signatureData);
    196  CFRelease(verifier);
    197 
    198  return result;
    199 }
    200 
    201 void CryptoMac_FreeSignatureHandle(CryptoX_SignatureHandle* aInputData) {
    202  if (!aInputData || !*aInputData) {
    203    return;
    204  }
    205 
    206  CFMutableDataRef inputData = NULL;
    207  inputData = (CFMutableDataRef)*aInputData;
    208 
    209  CFRelease(inputData);
    210 }
    211 
    212 void CryptoMac_FreePublicKey(CryptoX_PublicKey* aPublicKey) {
    213  if (!aPublicKey || !*aPublicKey) {
    214    return;
    215  }
    216 
    217  CFRelease((SecKeyRef)*aPublicKey);
    218 }