static dispatch_data_t
execute_sectransform(SecTransformRef transformRef, dispatch_data_t data)
{
	const void * bytes;
	size_t size;

	dispatch_data_t map = dispatch_data_create_map(data, &bytes, &size);
	assert(map);

	CFDataRef dataRef = CFDataCreate(kCFAllocatorDefault, bytes, size);
	assert(dataRef);

	dispatch_release(map);

	SecTransformSetAttribute(transformRef, kSecTransformInputAttributeName, dataRef, NULL);

	CFDataRef transformedDataRef = SecTransformExecute(transformRef, NULL);
	assert(transformedDataRef);

	CFRelease(dataRef);

	dispatch_data_t output = dispatch_data_create(CFDataGetBytePtr(transformedDataRef), CFDataGetLength(transformedDataRef), dispatch_get_main_queue(), DISPATCH_DATA_DESTRUCTOR_DEFAULT);
	CFRelease(transformedDataRef);

	return output;
}
static CFStringRef
decryptString(SecKeyRef wrapKey, CFDataRef iv, CFDataRef wrappedPassword)
{
	CFStringRef retval = NULL;
	CFDataRef retData = NULL;
 	CFErrorRef error = NULL;

	SecTransformRef decryptTrans = SecDecryptTransformCreate(wrapKey, &error);
    if(error == NULL) {
  		SecTransformRef group = SecTransformCreateGroupTransform();
      
		SecTransformRef decodeTrans = SecDecodeTransformCreate(kSecBase64Encoding, &error);
  		if(error == NULL) SecTransformSetAttribute(decodeTrans, kSecTransformInputAttributeName, wrappedPassword, &error);
        
		if(error == NULL) SecTransformSetAttribute(decryptTrans, kSecEncryptionMode, kSecModeCBCKey, &error);
 		if(error == NULL) SecTransformSetAttribute(decryptTrans, kSecPaddingKey, kSecPaddingPKCS7Key, &error);
		if(error == NULL) SecTransformSetAttribute(decryptTrans, kSecIVKey, iv, &error);
 		SecTransformConnectTransforms(decodeTrans, kSecTransformOutputAttributeName, decryptTrans, kSecTransformInputAttributeName, group, &error);
		CFRelease(decodeTrans);  
		CFRelease(decryptTrans);
        if(error == NULL) retData =  SecTransformExecute(group, &error);
        
        if(error == NULL) retval = CFStringCreateFromExternalRepresentation(kCFAllocatorDefault, retData, kCFStringEncodingMacRoman);
        else secDebug(ASL_LEVEL_ERR, "Failed to decrypt recovery password\n", NULL);
        CFRelease(group);
	}
   return retval;
}
Exemplo n.º 3
0
TagLib::ByteVector TagLib::EncodeBase64(const TagLib::ByteVector& input)
{
    ByteVector result;

    CFErrorRef error;
    SFB::SecTransform encoder = SecEncodeTransformCreate(kSecBase64Encoding, &error);
    if(nullptr == encoder) {
        LOGGER_WARNING("org.sbooth.AudioEngine", "SecEncodeTransformCreate failed: " << error);
        return TagLib::ByteVector::null;
    }

    SFB::CFData sourceData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (const UInt8 *)input.data(), (CFIndex)input.size(), kCFAllocatorNull);
    if(!sourceData)
        return TagLib::ByteVector::null;

    if(!SecTransformSetAttribute(encoder, kSecTransformInputAttributeName, sourceData, &error)) {
        LOGGER_WARNING("org.sbooth.AudioEngine", "SecTransformSetAttribute failed: " << error);
        return TagLib::ByteVector::null;
    }

    SFB::CFData encodedData = (CFDataRef)SecTransformExecute(encoder, &error);
    if(!encodedData) {
        LOGGER_WARNING("org.sbooth.AudioEngine", "SecTransformExecute failed: " << error);
        return TagLib::ByteVector::null;
    }

    result.setData((const char *)CFDataGetBytePtr((CFDataRef)encodedData), (TagLib::uint)CFDataGetLength((CFDataRef)encodedData));

    return result;
}
void CryptoOperationImpl::finishImpl()
{
    CFErrorRef error = NULL;
    CFDataRef signature = (CFDataRef)SecTransformExecute(m_signingTransform, &error);
    
    if (NULL != error)
    {
        FireJSEvent("onabort", FB::VariantMap(), FB::variant_list_of());
        return;
    }
    
    CFIndex length = CFDataGetLength(signature);
    const UInt8 *signatureBytes = CFDataGetBytePtr(signature);
    
    std::vector<unsigned char> result((unsigned char*)signatureBytes, ((unsigned char*)signatureBytes) + length);
    
    set_result(result);
    
    CFRelease(signature);
    CFRelease(m_signingTransform);
    m_signingTransform = NULL;
    
    if (NULL != error)
    {
        FireJSEvent("onabort", FB::VariantMap(), FB::variant_list_of());
        return;
    }
    
    FireJSEvent("oncomplete", FB::VariantMap(), FB::variant_list_of());
}
static CFDataRef
b64decode(CFDataRef input)
{
	CFDataRef retval = NULL;
    CFErrorRef error = NULL;
	SecTransformRef decodeTrans = SecDecodeTransformCreate(kSecBase64Encoding, &error);
    if(error == NULL) SecTransformSetAttribute(decodeTrans, kSecTransformInputAttributeName, input, &error);
    if(error == NULL) retval = SecTransformExecute(decodeTrans, &error);
	if(decodeTrans) CFRelease(decodeTrans);
    return retval;
}
Exemplo n.º 6
0
static inline String base64(const String& input)
{
#ifdef OS_Darwin
    String result;
    SecTransformRef transform = SecEncodeTransformCreate(kSecBase64Encoding, 0);
    CFDataRef sourceData = CFDataCreate(kCFAllocatorDefault,
                                        reinterpret_cast<const UInt8*>(input.constData()),
                                        input.size());
    SecTransformSetAttribute(transform, kSecTransformInputAttributeName, sourceData, 0);
    CFDataRef encodedData = static_cast<CFDataRef>(SecTransformExecute(transform, 0));
    const long len = CFDataGetLength(encodedData);
    if (len > 0) {
        result.resize(len);
        CFDataGetBytes(encodedData, CFRangeMake(0, len), reinterpret_cast<UInt8*>(result.data()));
    }
    CFRelease(encodedData);
    CFRelease(transform);
    CFRelease(sourceData);
#else
    BIO *base64_filter = BIO_new(BIO_f_base64());
    BIO_set_flags(base64_filter, BIO_FLAGS_BASE64_NO_NL);

    BIO *bio = BIO_new(BIO_s_mem());
    BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);

    bio = BIO_push(base64_filter, bio);

    BIO_write(bio, input.constData(), input.size());

    BIO_flush(bio);

    char *new_data;

    const long bytes_written = BIO_get_mem_data(bio, &new_data);

    String result(new_data, bytes_written);
    BIO_free_all(bio);
#endif

    return result;
}
static CFDataRef
digestString(CFStringRef str)
{
	CFDataRef retval = NULL;
 	CFErrorRef error = NULL;
    
    CFDataRef inputString = CFStringCreateExternalRepresentation(kCFAllocatorDefault, str, kCFStringEncodingUTF8, 0xff);
    
    SecTransformRef	digestTrans = SecDigestTransformCreate(kSecDigestSHA2, 256, &error);
    if(error == NULL) {
        SecTransformSetAttribute(digestTrans, kSecTransformInputAttributeName, inputString, &error);
        if(error == NULL) {
        	retval = SecTransformExecute(digestTrans, &error);
            if(retval == NULL) {
                secDebug(ASL_LEVEL_ERR, "Couldn't create digest %s\n", CFStringGetCStringPtr(CFErrorCopyFailureReason(error), kCFStringEncodingUTF8));
            }
        }
        CFRelease(digestTrans);
    }
    CFRelease(inputString);
    return retval;
}
CFStringRef 
SecCreateRecoveryPassword(void)
{
	CFStringRef result = NULL;
	CFErrorRef error = NULL;
 	CFDataRef encodedData = NULL;
    CFDataRef randData = getRandomBytes(16);
	int i;
	
	// base32FDE is a "private" base32 encoding, it has no 0/O or L/l/1 in it (it uses 8 and 9).
	SecTransformRef	encodeTrans = SecEncodeTransformCreate(CFSTR("base32FDE"), &error);
    if(error == NULL) {
		SecTransformSetAttribute(encodeTrans, kSecTransformInputAttributeName, randData, &error);
		if(error == NULL) encodedData = SecTransformExecute(encodeTrans, &error);
     	CFRelease(encodeTrans);
   	}
    CFRelease(randData);

	if(encodedData != NULL && error == NULL) {
        CFStringRef	b32string = CFStringCreateFromExternalRepresentation(kCFAllocatorDefault, encodedData, kCFStringEncodingMacRoman);
        CFMutableStringRef encodedString = CFStringCreateMutableCopy(kCFAllocatorDefault, 64, b32string);
       
        // Add some hyphens to make the generated password easier to use
        for(i = 4; i < 34; i += 5)  CFStringInsert(encodedString, i, CFSTR("-"));
        // Trim so the last section is 4 characters long
		CFStringDelete(encodedString, CFRangeMake(29,CFStringGetLength(encodedString)-29));
        result = CFStringCreateCopy(kCFAllocatorDefault, encodedString);
        CFRelease(encodedString);
        CFRelease(b32string);
        CFRelease(encodedData);
	} else {
        secDebug(ASL_LEVEL_ERR, "Failed to base32 encode random data for recovery password\n", NULL);
    }

	return result;
	
}
Exemplo n.º 9
0
TagLib::ByteVector TagLib::DecodeBase64(const TagLib::ByteVector& input)
{
	SFB::CFError error;
	SFB::SecTransform decoder(SecDecodeTransformCreate(kSecBase64Encoding, &error));
    if(!decoder) {
		LOGGER_WARNING("org.sbooth.AudioEngine", "SecDecodeTransformCreate failed: " << error);
		return {};
	}

	SFB::CFData sourceData(CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (const UInt8 *)input.data(), (CFIndex)input.size(), kCFAllocatorNull));
	if(!sourceData)
		return {};

    if(!SecTransformSetAttribute(decoder, kSecTransformInputAttributeName, sourceData, &error)) {
		LOGGER_WARNING("org.sbooth.AudioEngine", "SecTransformSetAttribute failed: " << error);
		return {};
	}

	SFB::CFData decodedData((CFDataRef)SecTransformExecute(decoder, &error));
	if(!decodedData)
		return {};

	return {(const char *)CFDataGetBytePtr((CFDataRef)decodedData), (size_t)CFDataGetLength((CFDataRef)decodedData)};
}
Exemplo n.º 10
0
static int32_t ExecuteCFDataTransform(
    SecTransformRef xform, uint8_t* pbData, int32_t cbData, CFDataRef* pDataOut, CFErrorRef* pErrorOut)
{
    if (xform == nullptr || pbData == nullptr || cbData < 0 || pDataOut == nullptr || pErrorOut == nullptr)
    {
        return kErrorBadInput;
    }

    *pDataOut = nullptr;
    *pErrorOut = nullptr;

    CFTypeRef xformOutput = nullptr;
    CFDataRef cfData = nullptr;
    int32_t ret = INT_MIN;

    cfData = CFDataCreateWithBytesNoCopy(nullptr, pbData, cbData, kCFAllocatorNull);

    if (cfData == nullptr)
    {
        // This probably means that there wasn't enough memory available, but no
        // particular failure cases are described.
        return kErrorUnknownState;
    }

    if (!SecTransformSetAttribute(xform, kSecTransformInputAttributeName, cfData, pErrorOut))
    {
        ret = kErrorSeeError;
        goto cleanup;
    }

    xformOutput = SecTransformExecute(xform, pErrorOut);

    if (xformOutput == nullptr || *pErrorOut != nullptr)
    {
        ret = kErrorSeeError;
        goto cleanup;
    }

    if (CFGetTypeID(xformOutput) == CFDataGetTypeID())
    {
        CFDataRef cfDataOut = reinterpret_cast<CFDataRef>(const_cast<void*>(xformOutput));
        CFRetain(cfDataOut);
        *pDataOut = cfDataOut;
        ret = 1;
    }
    else
    {
        ret = kErrorUnknownState;
    }

cleanup:
    if (xformOutput != nullptr)
    {
        CFRelease(xformOutput);
    }

    if (cfData != nullptr)
    {
        CFRelease(cfData);
    }

    return ret;
}
Exemplo n.º 11
0
TagLib::ByteVector TagLib::DecodeBase64(const TagLib::ByteVector& input)
{
#if USE_SECURITY_FRAMEWORK
	ByteVector result;

	CFErrorRef error;
	SecTransformRef decoder = SecDecodeTransformCreate(kSecBase64Encoding, &error);
    if(nullptr == decoder) {
		CFShow(error); 
		return TagLib::ByteVector::null;
	}

	CFDataRef sourceData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (const UInt8 *)input.data(), input.size(), kCFAllocatorNull);
	if(nullptr == sourceData) {
		CFRelease(decoder), decoder = nullptr;

		return TagLib::ByteVector::null;
	}

    if(!SecTransformSetAttribute(decoder, kSecTransformInputAttributeName, sourceData, &error)) {
		CFShow(error); 

		CFRelease(sourceData), sourceData = nullptr;
		CFRelease(decoder), decoder = nullptr;

		return TagLib::ByteVector::null;
	}

	CFTypeRef decodedData = SecTransformExecute(decoder, &error);
	if(nullptr == decodedData) {
		CFShow(error); 

		CFRelease(sourceData), sourceData = nullptr;
		CFRelease(decoder), decoder = nullptr;

		return TagLib::ByteVector::null;
	}

	result.setData((const char *)CFDataGetBytePtr((CFDataRef)decodedData), (TagLib::uint)CFDataGetLength((CFDataRef)decodedData));

	CFRelease(decodedData), decodedData = nullptr;
	CFRelease(sourceData), sourceData = nullptr;
	CFRelease(decoder), decoder = nullptr;
	
	return result;
#else
	ByteVector result;

	BIO *b64 = BIO_new(BIO_f_base64());
	BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);

	BIO *bio = BIO_new_mem_buf(reinterpret_cast<void *>(const_cast<char *>(input.data())), input.size());
	bio = BIO_push(b64, bio);

	char inbuf [512];
	int inlen;
	while(0 < (inlen = BIO_read(bio, inbuf, 512)))
		result.append(ByteVector(inbuf, inlen));

	BIO_free_all(bio);
	
	return result;
#endif
}
Exemplo n.º 12
0
TagLib::ByteVector TagLib::EncodeBase64(const TagLib::ByteVector& input)
{
#if USE_SECURITY_FRAMEWORK
	ByteVector result;

	CFErrorRef error;
	SecTransformRef encoder = SecEncodeTransformCreate(kSecBase64Encoding, &error);
    if(nullptr == encoder) {
		CFShow(error); 
		return TagLib::ByteVector::null;
	}

	CFDataRef sourceData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (const UInt8 *)input.data(), input.size(), kCFAllocatorNull);
	if(nullptr == sourceData) {
		CFRelease(encoder), encoder = nullptr;
		
		return TagLib::ByteVector::null;
	}

    if(!SecTransformSetAttribute(encoder, kSecTransformInputAttributeName, sourceData, &error)) {
		CFShow(error); 
		
		CFRelease(sourceData), sourceData = nullptr;
		CFRelease(encoder), encoder = nullptr;
		
		return TagLib::ByteVector::null;
	}

	CFTypeRef encodedData = SecTransformExecute(encoder, &error);
	if(nullptr == encodedData) {
		CFShow(error); 
		
		CFRelease(sourceData), sourceData = nullptr;
		CFRelease(encoder), encoder = nullptr;
		
		return TagLib::ByteVector::null;
	}

	result.setData((const char *)CFDataGetBytePtr((CFDataRef)encodedData), (TagLib::uint)CFDataGetLength((CFDataRef)encodedData));

	CFRelease(encodedData), encodedData = nullptr;
	CFRelease(sourceData), sourceData = nullptr;
	CFRelease(encoder), encoder = nullptr;

	return result;
#else
	ByteVector result;

	BIO *b64 = BIO_new(BIO_f_base64());
	BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);

	BIO *bio = BIO_new(BIO_s_mem());
	bio = BIO_push(b64, bio);
	BIO_write(bio, input.data(), input.size());
	(void)BIO_flush(bio);

	void *mem = nullptr;
	long size = BIO_get_mem_data(bio, &mem);
	if(0 < size)
		result.setData(static_cast<const char *>(mem), static_cast<uint>(size));

	BIO_free_all(bio);

	return result;
#endif
}
bool
_mongoc_secure_transport_import_pem (const char *filename, const char *passphrase, CFArrayRef *items, SecExternalItemType *type)
{
   SecExternalFormat format = kSecFormatPEMSequence;
   SecItemImportExportKeyParameters params;
   SecTransformRef sec_transform;
   CFReadStreamRef read_stream;
   CFDataRef dataref;
   CFErrorRef error;
   CFURLRef url;
   OSStatus res;


   if (!filename) {
      MONGOC_INFO ("%s", "No certificate provided");
      return false;
   }

   params.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION;
   params.flags = 0;
   params.passphrase = NULL;
   params.alertTitle = NULL;
   params.alertPrompt = NULL;
   params.accessRef = NULL;
   params.keyUsage = NULL;
   params.keyAttributes = NULL;

   if (passphrase) {
      params.passphrase = CFStringCreateWithCString (kCFAllocatorDefault, passphrase, kCFStringEncodingUTF8);
   }

   url = CFURLCreateFromFileSystemRepresentation (kCFAllocatorDefault, (const UInt8 *)filename, strlen (filename), false);
   read_stream = CFReadStreamCreateWithFile (kCFAllocatorDefault, url);
   sec_transform = SecTransformCreateReadTransformWithReadStream (read_stream);
   dataref = SecTransformExecute (sec_transform, &error);


   if (error) {
      CFStringRef str = CFErrorCopyDescription (error);
      MONGOC_ERROR ("Failed importing PEM '%s': %s", filename, CFStringGetCStringPtr (str, CFStringGetFastestEncoding(str)));
      CFRelease (str);
      CFRelease (sec_transform);
      CFRelease (read_stream);
      CFRelease (url);

      if (passphrase) {
         CFRelease (params.passphrase);
      }
      return false;
   }

   res = SecItemImport (dataref, CFSTR(".pem"), &format, type, 0, &params, NULL, items);
   CFRelease (dataref);
   CFRelease (sec_transform);
   CFRelease (read_stream);
   CFRelease (url);

   if (passphrase) {
      CFRelease (params.passphrase);
   }
   if (res) {
      MONGOC_ERROR ("Failed importing PEM '%s' (code: %d)", filename, res);
      return false;
   }

   return true;
}
Exemplo n.º 14
0
CFDictionaryRef APCreateDictionaryForLicenseData(CFDataRef data)
{
    __block CFPropertyListRef propertyList = NULL;
    __block CFDataRef hashData = NULL;
    __block CFErrorRef error = NULL;
    __block SecTransformRef verifyFunction = NULL;
    __block CFBooleanRef valid = NULL;
    
    void(^cleanup)(void) = ^(void) {
        if (propertyList != NULL) {
            CFRelease(propertyList);
            propertyList = NULL;
        }
        if (hashData != NULL) {
            CFRelease(hashData);
            hashData = NULL;
        }
        if (error != NULL) {
            CFShow(error);
            CFRelease(error);
            error = NULL;
        }
        if (verifyFunction != NULL) {
            CFRelease(verifyFunction);
            verifyFunction = NULL;
        }
        if (valid != NULL) {
            CFRelease(valid);
            valid = NULL;
        }
    };
    
    if (!publicKeyRef) {
        CFShow(CFSTR("Public key is invalid"));
        return NULL;
    }
    
    
    // Make the property list from the data
    CFStringRef errorString = NULL;
    propertyList = CFPropertyListCreateFromXMLData(kCFAllocatorDefault, data, kCFPropertyListMutableContainers, &errorString);
    if (errorString || CFDictionaryGetTypeID() != CFGetTypeID(propertyList) || !CFPropertyListIsValid(propertyList, kCFPropertyListXMLFormat_v1_0)) {
        if (propertyList)
            CFRelease(propertyList);
        return NULL;
    }
    CFMutableDictionaryRef licenseDictionary = (CFMutableDictionaryRef)propertyList;
    
    
    CFDataRef signature = CFDictionaryGetValue(licenseDictionary, CFSTR("Signature"));
    if (!signature) {
        CFShow(CFSTR("No signature"));
        cleanup();
        return NULL;
    }
    
    
    hashData = APCreateHashFromDictionary(licenseDictionary);
    CFStringRef hashCheck = APCopyHexStringFromData(hashData);
    APSetHash(hashCheck);
    CFRelease(hashCheck);
    
    
    // Check the hash against license blacklist
    if (blacklist && CFArrayContainsValue(blacklist, CFRangeMake(0, CFArrayGetCount(blacklist)), hash)) {
        cleanup();
        return NULL;
    }
    
    
    // Verify the signed hash using the public key, passing the raw hash data as the input
    verifyFunction = SecVerifyTransformCreate(publicKeyRef, signature, &error);
    if (error) {
        cleanup();
        return NULL;
    }
    
    SecTransformSetAttribute(verifyFunction,
                             kSecTransformInputAttributeName,
                             hashData,
                             &error);
    if (error) {
        cleanup();
        return NULL;
    }
    
    SecTransformSetAttribute(verifyFunction,
                             kSecInputIsAttributeName,
                             kSecInputIsRaw,
                             &error);
    if (error) {
        cleanup();
        return NULL;
    }
    
    valid = SecTransformExecute(verifyFunction, &error);
    if (error) {
        cleanup();
        return NULL;
    }
    
    if (valid != kCFBooleanTrue) {
        cleanup();
        return NULL;
    }
    
    CFDictionaryRef resultDict = CFDictionaryCreateCopy(kCFAllocatorDefault, licenseDictionary);
    cleanup();
    return resultDict;
}
Exemplo n.º 15
0
CFDataRef APCreateHashFromDictionary(CFDictionaryRef dict)
{
    __block CFErrorRef error = NULL;
    __block SecTransformRef hashFunction = NULL;
    
    void(^cleanup)(void) = ^(void) {
        if (error != NULL) {
            CFShow(error);
            CFRelease(error);
            error = NULL;
        }
        if (hashFunction != NULL) {
            CFRelease(hashFunction);
            hashFunction = NULL;
        }
    };
    
    
    // Get the number of elements
    CFIndex count = CFDictionaryGetCount(dict);
    
    // Load the keys and build up the key array
    CFMutableArrayRef keyArray = CFArrayCreateMutable(kCFAllocatorDefault, count, NULL);
    CFStringRef keys[count];
    CFDictionaryGetKeysAndValues(dict, (const void**)&keys, NULL);
    for (int idx = 0; idx < count; idx++)
    {
        // Skip the signature key
        if (CFStringCompare(keys[idx], CFSTR("Signature"), 0) == kCFCompareEqualTo) {
            continue;
        }
        CFArrayAppendValue(keyArray, keys[idx]);
    }
    
    // Sort the array
    int context = kCFCompareCaseInsensitive;
    CFArraySortValues(keyArray, CFRangeMake(0, count-1), (CFComparatorFunction)CFStringCompare, &context);
    
    
    // Build the data
    CFMutableDataRef dictData = CFDataCreateMutable(kCFAllocatorDefault, 0);
    int keyCount = CFArrayGetCount(keyArray);
    for (int keyIndex = 0; keyIndex < keyCount; keyIndex++)
    {
        CFStringRef key = CFArrayGetValueAtIndex(keyArray, keyIndex);
        CFStringRef value = CFDictionaryGetValue(dict, key);
        
        CFDataRef valueData = CFStringCreateExternalRepresentation(kCFAllocatorDefault,
                                                                   value,
                                                                   kCFStringEncodingUTF8,
                                                                   0);
        const UInt8 *valueBuffer = CFDataGetBytePtr(valueData);
        CFDataAppendBytes(dictData, valueBuffer, CFDataGetLength(valueData));
        CFRelease(valueData);
    }
    
    
    // Hash the data
    hashFunction = SecDigestTransformCreate(kSecDigestSHA1, 0, &error);
    if (error != NULL) {
        CFRelease(dictData);
        cleanup();
        return NULL;
    }
    
    SecTransformSetAttribute(hashFunction,
                             kSecTransformInputAttributeName,
                             dictData,
                             &error);
    CFDataRef hashData = SecTransformExecute(hashFunction, &error);
    CFRelease(dictData);
    
    if (error != NULL) {
        cleanup();
        if (hashData) {
            CFRelease(hashData);
        }
        return NULL;
    }
    
    cleanup();
    
    return hashData;
}
Exemplo n.º 16
0
CFStringRef APPEMKeyCreateFromHexKey(CFStringRef hexKey)
{
    // Convert a raw 1024 bit key to a PEM formatted string that includes the headers
    // -----BEGIN RSA PUBLIC KEY-----
    // (base64 ASN1 encoded data here)
    // -----END RSA PUBLIC KEY-----
    uint8_t raw1[] = {
        0x30, 0x81, 0x9F,                                                    // SEQUENCE length 0x9F
        0x30, 0x0D,                                                            // SEQUENCE length 0x0D
        0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01,    // rsaEncryption, PKCS #1
        0x05, 0x00,                                                            // NULL
        0x03, 0x81, 0x8D, 0x00,                                                // BIT STRING, length 0x8D
        0x30, 0x81, 0x89,                                                    // SEQUENCE length 0x89
        0x02, 0x81, 0x81,                                                    // INTEGER length 0x81
        0x00                                                                // MSB = zero to make sure INTEGER is positively signed
    };
    
    uint8_t raw2[] = {
        0x02, 0x03, 0x00, 0x00, 0x03                                        // INTEGER length 3, value = 0x03 (RSA exponent)
    };
    
    
    // Munch through the hex string, taking two characters at a time for each byte
    // to append as the key data
    CFDataRef rawKey = APCopyDataFromHexString(hexKey);
    if (rawKey == NULL) {
        // Failed to import the key (bad hex digit?)
        CFShow(CFSTR("Bad public key?"));
        return NULL;
    }
    
    CFMutableDataRef keyData = CFDataCreateMutable(kCFAllocatorDefault, 0);
    CFDataAppendBytes(keyData, raw1, sizeof(raw1)/sizeof(uint8_t));
    
    const UInt8 *rawKeyBuffer = CFDataGetBytePtr(rawKey);
    CFDataAppendBytes(keyData, rawKeyBuffer, CFDataGetLength(rawKey));
    CFRelease(rawKey);
    
    CFDataAppendBytes(keyData, raw2, sizeof(raw2)/sizeof(uint8_t));
    
    
    // Just need to base64 encode this data now and wrap the string
    // in the BEGIN/END RSA PUBLIC KEY
    CFErrorRef error = NULL;
    SecTransformRef encoder = SecEncodeTransformCreate(kSecBase64Encoding, &error);
    if (error != NULL) {
        CFShow(error);
        if (encoder) {
            CFRelease(encoder);
        }
        if (keyData) {
            CFRelease(keyData);
        }
        return NULL;
    }
    SecTransformSetAttribute(encoder,
                             kSecTransformInputAttributeName,
                             keyData,
                             &error);
    if (error != NULL) {
        CFRelease(encoder);
        if (keyData) {
            CFRelease(keyData);
        }
        CFShow(error);
        return NULL;
    }
    CFDataRef encodedKeyData = SecTransformExecute(encoder, &error);
    const UInt8 *keyDataBuffer = CFDataGetBytePtr(encodedKeyData);
    CFStringRef keyDataString = CFStringCreateWithBytes(kCFAllocatorDefault,
                                                        keyDataBuffer,
                                                        CFDataGetLength(encodedKeyData),
                                                        kCFStringEncodingUTF8,
                                                        false);
    CFRelease(encodedKeyData);
    CFRelease(encoder);
    CFRelease(keyData);
    
    
    CFStringRef beginRSAKey = CFSTR("-----BEGIN RSA PUBLIC KEY-----");
    CFStringRef endRSAKey = CFSTR("-----END RSA PUBLIC KEY-----");
    
    CFStringRef pemKey = CFStringCreateWithFormat(kCFAllocatorDefault,
                                                  NULL,
                                                  CFSTR("%@\n%@\n%@"),
                                                  beginRSAKey,
                                                  keyDataString,
                                                  endRSAKey);
    CFRelease(keyDataString);
    
    return pemKey;
}