static CF_RETURNS_RETAINED CFDictionaryRef SecKeyGenerateAttributeDictionaryFor(SecKeyRef key, CFTypeRef keyType, CFDataRef privateBlob) { CFAllocatorRef allocator = CFGetAllocator(key); DICT_DECLARE(25); CFDataRef pubKeyDigest = NULL, pubKeyBlob = NULL; CFDictionaryRef dict = NULL; size_t sizeValue = SecKeyGetSize(key, kSecKeyKeySizeInBits); CFNumberRef sizeInBits = CFNumberCreate(allocator, kCFNumberLongType, &sizeValue); /* encode the public key. */ require_noerr(SecKeyCopyPublicBytes(key, &pubKeyBlob), errOut); require(pubKeyBlob, errOut); /* Calculate the digest of the public key. */ require(pubKeyDigest = SecSHA1DigestCreate(allocator, CFDataGetBytePtr(pubKeyBlob), CFDataGetLength(pubKeyBlob)), errOut); DICT_ADDPAIR(kSecClass, kSecClassKey); DICT_ADDPAIR(kSecAttrKeyClass, privateBlob ? kSecAttrKeyClassPrivate : kSecAttrKeyClassPublic); DICT_ADDPAIR(kSecAttrApplicationLabel, pubKeyDigest); DICT_ADDPAIR(kSecAttrIsPermanent, kCFBooleanTrue); DICT_ADDPAIR(kSecAttrIsPrivate, kCFBooleanTrue); DICT_ADDPAIR(kSecAttrIsModifiable, kCFBooleanTrue); DICT_ADDPAIR(kSecAttrKeyType, keyType); DICT_ADDPAIR(kSecAttrKeySizeInBits, sizeInBits); DICT_ADDPAIR(kSecAttrEffectiveKeySize, sizeInBits); DICT_ADDPAIR(kSecAttrIsSensitive, kCFBooleanFalse); DICT_ADDPAIR(kSecAttrWasAlwaysSensitive, kCFBooleanFalse); DICT_ADDPAIR(kSecAttrIsExtractable, kCFBooleanTrue); DICT_ADDPAIR(kSecAttrWasNeverExtractable, kCFBooleanFalse); DICT_ADDPAIR(kSecAttrCanEncrypt, kCFBooleanFalse); DICT_ADDPAIR(kSecAttrCanDecrypt, kCFBooleanTrue); DICT_ADDPAIR(kSecAttrCanDerive, kCFBooleanTrue); DICT_ADDPAIR(kSecAttrCanSign, kCFBooleanTrue); DICT_ADDPAIR(kSecAttrCanVerify, kCFBooleanFalse); DICT_ADDPAIR(kSecAttrCanSignRecover, kCFBooleanFalse); DICT_ADDPAIR(kSecAttrCanVerifyRecover, kCFBooleanFalse); DICT_ADDPAIR(kSecAttrCanWrap, kCFBooleanFalse); DICT_ADDPAIR(kSecAttrCanUnwrap, kCFBooleanTrue); DICT_ADDPAIR(kSecValueData, privateBlob ? privateBlob : pubKeyBlob); dict = DICT_CREATE(allocator); errOut: // @@@ Zero out key material. CFReleaseSafe(pubKeyDigest); CFReleaseSafe(pubKeyBlob); CFReleaseSafe(sizeInBits); return dict; }
/* Test basic add delete update copy matching stuff. */ static void tests(SecKeyDescriptor *descriptor) { const uint8_t *keyData = (const uint8_t *)"abc"; CFIndex keyDataLength = 3; SecKeyEncoding encoding = kSecKeyEncodingRaw; ok(customKey = SecKeyCreate(kCFAllocatorDefault, descriptor, keyData, keyDataLength, encoding), "create custom key"); is(customKey, initedCustomKey, "CustomKeyInit got the right key"); SecPadding padding = kSecPaddingPKCS1; const uint8_t *src = (const uint8_t *)"defgh"; size_t srcLen = 5; uint8_t dst[5]; size_t dstLen = 5; ok_status(SecKeyDecrypt(customKey, padding, src, srcLen, dst, &dstLen), "SecKeyDecrypt"); ok_status(SecKeyEncrypt(customKey, padding, src, srcLen, dst, &dstLen), "SecKeyEncrypt"); ok_status(SecKeyRawSign(customKey, padding, src, srcLen, dst, &dstLen), "SecKeyRawSign"); ok_status(SecKeyRawVerify(customKey, padding, src, srcLen, dst, dstLen), "SecKeyRawVerify"); is(SecKeyGetSize(customKey, kSecKeyKeySizeInBits), (size_t)5*8, "SecKeyGetSize"); CFDictionaryRef attrDict = NULL; ok(attrDict = SecKeyCopyAttributeDictionary(customKey), "SecKeyCopyAttributeDictionary"); CFReleaseNull(attrDict); CFDataRef pubdata = NULL; ok(SecKeyCopyPublicBytes(customKey, &pubdata) != 0, "SecKeyCopyPublicBytes"); CFReleaseNull(pubdata); CFDataRef wrapped; wrapped = _SecKeyCopyWrapKey(customKey, kSecKeyWrapPublicKeyPGP, pubdata, NULL, NULL, NULL); ok(wrapped == NULL, "_SecKeyCopyWrapKey"); CFReleaseNull(wrapped); wrapped = _SecKeyCopyUnwrapKey(customKey, kSecKeyWrapPublicKeyPGP, pubdata, NULL, NULL, NULL); ok(wrapped == NULL, "_SecKeyCopyUnwrapKey"); CFReleaseNull(wrapped); //ok(SecKeyGeneratePair(customKey, ), "SecKeyGeneratePair"); ok(SecKeyGetTypeID() != 0, "SecKeyGetTypeID works"); if (customKey) { CFRelease(customKey); customKey = NULL; } }
SecKeyRef SecKeyCreatePublicFromPrivate(SecKeyRef privateKey) { CFDataRef serializedPublic = NULL; SecKeyRef result = NULL; require_noerr_quiet(SecKeyCopyPublicBytes(privateKey, &serializedPublic), fail); require_quiet(serializedPublic, fail); result = SecKeyCreateFromPublicData(kCFAllocatorDefault, SecKeyGetAlgorithmID(privateKey), serializedPublic); fail: CFReleaseSafe(serializedPublic); return result; }
static CFDataRef SecKeyCopyPublicKeyHash(SecKeyRef key) { CFDataRef pubKeyDigest = NULL, pubKeyBlob = NULL; /* encode the public key. */ require_noerr(SecKeyCopyPublicBytes(key, &pubKeyBlob), errOut); require(pubKeyBlob, errOut); /* Calculate the digest of the public key. */ require(pubKeyDigest = SecSHA1DigestCreate(CFGetAllocator(key), CFDataGetBytePtr(pubKeyBlob), CFDataGetLength(pubKeyBlob)), errOut); errOut: CFReleaseNull(pubKeyBlob); return pubKeyDigest; }
static void tests(void) { CFDataRef message = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, _user_one_p12, sizeof(_user_one_p12), kCFAllocatorNull); CFArrayRef items = NULL; SecCertificateRef cert = NULL; SecKeyRef pkey = NULL; is_status(SecPKCS12Import(message, NULL, NULL), errSecAuthFailed, "try null password on a known good p12"); CFStringRef password = CFSTR("user-one"); CFDictionaryRef options = CFDictionaryCreate(NULL, (const void **)&kSecImportExportPassphrase, (const void **)&password, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); ok_status(SecPKCS12Import(message, options, &items), "import user one"); is(CFArrayGetCount(items), 1, "one identity"); CFDictionaryRef item = CFArrayGetValueAtIndex(items, 0); SecIdentityRef identity = NULL; ok(identity = (SecIdentityRef)CFDictionaryGetValue(item, kSecImportItemIdentity), "pull identity from imported data"); ok(CFGetTypeID(identity)==SecIdentityGetTypeID(),"this is a SecIdentityRef"); ok_status(SecIdentityCopyPrivateKey(identity, &pkey),"get private key"); ok_status(SecIdentityCopyCertificate(identity, &cert), "get certificate"); CFReleaseNull(items); CFReleaseNull(message); CFReleaseNull(options); CFReleaseNull(password); CFReleaseNull(cert); CFReleaseNull(pkey); message = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, _user_two_p12, sizeof(_user_two_p12), kCFAllocatorNull); items = NULL; password = CFSTR("user-two"); options = CFDictionaryCreate(NULL, (const void **)&kSecImportExportPassphrase, (const void **)&password, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); ok_status(SecPKCS12Import(message, options, &items), "import user two"); is(CFArrayGetCount(items), 1, "one identity"); item = CFArrayGetValueAtIndex(items, 0); ok(identity = (SecIdentityRef)CFDictionaryGetValue(item, kSecImportItemIdentity), "pull identity from imported data"); ok(CFGetTypeID(identity)==SecIdentityGetTypeID(),"this is a SecIdentityRef"); ok_status(SecIdentityCopyPrivateKey(identity, &pkey),"get private key"); ok_status(SecIdentityCopyCertificate(identity, &cert), "get certificate"); CFReleaseNull(items); CFReleaseNull(message); CFReleaseNull(options); CFReleaseNull(password); CFReleaseNull(cert); CFReleaseNull(pkey); message = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, ECDSA_fails_import_p12, ECDSA_fails_import_p12_len, kCFAllocatorNull); items = NULL; password = CFSTR("test"); options = CFDictionaryCreate(NULL, (const void **)&kSecImportExportPassphrase, (const void **)&password, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); ok_status(SecPKCS12Import(message, options, &items), "import ECDSA_fails_import_p12"); is(CFArrayGetCount(items), 1, "one identity"); item = CFArrayGetValueAtIndex(items, 0); ok(identity = (SecIdentityRef)CFDictionaryGetValue(item, kSecImportItemIdentity), "pull identity from imported data"); ok(CFGetTypeID(identity)==SecIdentityGetTypeID(),"this is a SecIdentityRef"); ok_status(SecIdentityCopyPrivateKey(identity, &pkey),"get private key"); ok_status(SecIdentityCopyCertificate(identity, &cert), "get certificate"); CFDataRef pubdata = NULL; SecKeyRef pubkey = NULL; ok_status(SecKeyCopyPublicBytes(pkey, &pubdata), "pub key from priv key"); ok(pubkey = SecKeyCreateECPublicKey(kCFAllocatorDefault, CFDataGetBytePtr(pubdata), CFDataGetLength(pubdata), kSecKeyEncodingBytes), "recreate seckey"); /* Sign something. */ uint8_t something[20] = {0x80, 0xbe, 0xef, 0xba, 0xd0, }; size_t sigLen = SecKeyGetSize(pkey, kSecKeySignatureSize); uint8_t sig[sigLen]; ok_status(SecKeyRawSign(pkey, kSecPaddingPKCS1, something, sizeof(something), sig, &sigLen), "sign something"); ok_status(SecKeyRawVerify(pubkey, kSecPaddingPKCS1, something, sizeof(something), sig, sigLen), "verify sig on something"); CFReleaseNull(pubdata); CFReleaseNull(pubkey); CFReleaseNull(pkey); ok(pkey = SecKeyCreateECPrivateKey(kCFAllocatorDefault, ECDSA_fails_import_priv_only, ECDSA_fails_import_priv_only_len, kSecKeyEncodingPkcs1), "import privkey without pub"); ok_status(SecKeyCopyPublicBytes(pkey, &pubdata), "pub key from priv key"); ok(pubkey = SecKeyCreateECPublicKey(kCFAllocatorDefault, CFDataGetBytePtr(pubdata), CFDataGetLength(pubdata), kSecKeyEncodingBytes), "recreate seckey"); ok_status(SecKeyRawVerify(pubkey, kSecPaddingPKCS1, something, sizeof(something), sig, sigLen), "verify sig on something"); CFReleaseNull(pubdata); CFReleaseNull(pubkey); CFReleaseNull(pkey); CFReleaseNull(items); CFReleaseNull(message); CFReleaseNull(options); CFReleaseNull(password); CFReleaseNull(cert); }