Open dtokos opened 8 years ago
I have no plan for Mac OS X, but I suggest you using openssl library for OS X.
Can been supported by using this code below to create SecKeyRef
and some compatible implementations using old APIs.
For SecKeyRawSign/SecKeyEncrypt/SecKeyDecrypt
:
#if TARGET_OS_OSX
#pragma clang diagnostic push
#pragma clang diagnostic ignored"-Wnonnull"
static OSStatus OSXSecKeyRawSign(SecKeyRef key, SecPadding padding, const uint8_t *plainText, size_t plainTextLen, uint8_t *cipherText, size_t *cipherTextLen)
{
CFErrorRef error = NULL;
SecTransformRef encrypt = SecEncryptTransformCreate(key, &error);
if (error) {
NSLog(@"Encryption failed: %@\n", (__bridge NSError *)error);
return (OSStatus)[(__bridge NSError *)error code];
}
CFDataRef sourceData = CFDataCreate(kCFAllocatorDefault, plainText, plainTextLen);
SecTransformSetAttribute(encrypt, kSecTransformInputAttributeName,
sourceData, &error);
CFDataRef encryptedData = SecTransformExecute(encrypt, &error);
if (error) {
NSLog(@"Encryption failed: %@\n", (__bridge NSError *)error);
return (OSStatus)[(__bridge NSError *)error code];
}
if ((unsigned long)CFDataGetLength(encryptedData) > *cipherTextLen) {
return errSecBufferTooSmall;
}
*cipherTextLen = CFDataGetLength(encryptedData);
CFDataGetBytes(encryptedData, CFRangeMake(0, *cipherTextLen), cipherText);
return noErr;
}
static OSStatus OSXSecKeyEncrypt(SecKeyRef key, SecPadding padding, const uint8_t *plainText, size_t plainTextLen, uint8_t *cipherText, size_t *cipherTextLen)
{
CFErrorRef error = NULL;
SecTransformRef encrypt = SecEncryptTransformCreate(key, &error);
if (error) {
NSLog(@"Encryption failed: %@\n", (__bridge NSError *)error);
return (OSStatus)[(__bridge NSError *)error code];
}
SecTransformSetAttribute(
encrypt,
kSecPaddingKey,
NULL,//kSecPaddingPKCS1Key (rdar://13661366 : NULL means kSecPaddingPKCS1Key and
//kSecPaddingPKCS1Key fails horribly)
&error);
CFDataRef sourceData = CFDataCreate(kCFAllocatorDefault, plainText, plainTextLen);
SecTransformSetAttribute(encrypt, kSecTransformInputAttributeName,
sourceData, &error);
CFDataRef encryptedData = SecTransformExecute(encrypt, &error);
if (error) {
NSLog(@"Encryption failed: %@\n", (__bridge NSError *)error);
return (OSStatus)[(__bridge NSError *)error code];
}
if ((unsigned long)CFDataGetLength(encryptedData) > *cipherTextLen) {
return errSecBufferTooSmall;
}
*cipherTextLen = CFDataGetLength(encryptedData);
CFDataGetBytes(encryptedData, CFRangeMake(0, *cipherTextLen), cipherText);
return noErr;
}
static OSStatus OSXSecKeyDecrypt(SecKeyRef key, SecPadding padding, const uint8_t *cipherText, size_t cipherTextLen, uint8_t *plainText, size_t *plainTextLen)
{
CFErrorRef error = NULL;
SecTransformRef decrypt = SecDecryptTransformCreate(key, &error);
if (error) {
NSLog(@"Decryption failed: %@\n", (__bridge NSError *)error);
return (OSStatus)[(__bridge NSError *)error code];
}
SecTransformSetAttribute(
decrypt,
kSecPaddingKey,
NULL,//kSecPaddingPKCS1Key (rdar://13661366 : NULL means kSecPaddingPKCS1Key and
//kSecPaddingPKCS1Key fails horribly)
&error);
CFDataRef sourceData = CFDataCreate(kCFAllocatorDefault, cipherText, cipherTextLen);
SecTransformSetAttribute(decrypt, kSecTransformInputAttributeName,
sourceData, &error);
CFDataRef decryptedData = SecTransformExecute(decrypt, &error);
if (error) {
NSLog(@"Decryption failed: %@\n", (__bridge NSError *)error);
return (OSStatus)[(__bridge NSError *)error code];
}
if ((unsigned long)CFDataGetLength(decryptedData) > *plainTextLen) {
return errSecBufferTooSmall;
}
*plainTextLen = CFDataGetLength(decryptedData);
CFDataGetBytes(decryptedData, CFRangeMake(0, *plainTextLen), plainText);
return noErr;
}
#pragma clang diagnostic pop
For SecKeyRef generation (don't use Keychain):
#if TARGET_OS_OSX
NSDictionary *publicKey = @{(__bridge NSString *)kSecAttrKeyType : (__bridge NSString *)kSecAttrKeyTypeRSA, (__bridge NSString *)kSecAttrKeyClass : (__bridge NSString *)kSecAttrKeyClassPublic};
SecKeyRef keyRef = SecKeyCreateFromData((__bridge CFDictionaryRef)publicKey, (__bridge CFDataRef)data, nil);
// SecKeyRef keyRef = SecKeyCreateWithData((__bridge CFDataRef)data, (__bridge CFDictionaryRef)publicKey, nil);
return keyRef;
#endif
Hello,
i found this useful obc-c class and tested it. It works on iOS but not on OSX. I was searching all over the internet an i didn't find any class for OSX. Can be this somehow modified or are u planning OSX support?
Thanks for info, have a nice day