2 * Copyright (c) 2007-2009,2013-2014 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
25 #include <TargetConditionals.h>
26 #include <CoreFoundation/CoreFoundation.h>
27 #include <Foundation/Foundation.h>
28 #include <Security/Security.h>
29 #include <Security/SecRandom.h>
30 #include <CommonCrypto/CommonDigest.h>
31 #include <Security/SecKeyPriv.h>
32 #include <Security/SecItem.h>
33 #include <Security/SecCertificatePriv.h>
35 #include <corecrypto/ccsha1.h>
36 #include <corecrypto/ccsha2.h>
38 #include "keychain_regressions.h"
39 #include "utilities/SecCFRelease.h"
40 #include "utilities/array_size.h"
43 static void testdigestandsignalg(SecKeyRef privKey, SecKeyRef pubKey, const SecAsn1AlgId *algId) {
44 uint8_t dataToDigest[256];
45 size_t dataToDigestLen = sizeof(dataToDigest);
46 size_t sigLen = SecKeyGetSize(privKey, kSecKeySignatureSize);
50 oid.length = algId->algorithm.Length;
51 oid.data = algId->algorithm.Data;
53 /* Get the oid in decimal for display purposes. */
54 CFStringRef oidStr = SecDERItemCopyOIDDecimalRepresentation(kCFAllocatorDefault, &oid);
56 CFStringGetCString(oidStr, oidBuf, sizeof(oidBuf), kCFStringEncodingUTF8);
63 ok_status(status = SecKeyDigestAndSign(privKey, algId, dataToDigest, dataToDigestLen,
64 sig, &sigLen), "digest and sign %s with %ld bit RSA key", oidBuf, sigLen * 8);
66 skip("SecKeyDigestAndSign failed", 3, status == errSecSuccess);
68 /* Verify the signature we just made. */
69 ok_status(SecKeyDigestAndVerify(pubKey, algId, dataToDigest, dataToDigestLen,
70 sig, sigLen), "digest and verify");
71 /* Invalidate the signature. */
72 /* Tweak the least-significant bit to avoid putting the signature out of range. */
74 is_status(SecKeyDigestAndVerify(pubKey, algId, dataToDigest, dataToDigestLen,
75 sig, sigLen), errSSLCrypto, "digest and verify bad sig");
77 dataToDigest[0] ^= 0xff;
78 is_status(SecKeyDigestAndVerify(pubKey, algId, dataToDigest, dataToDigestLen,
79 sig, sigLen), errSSLCrypto, "digest and verify bad digest");
83 static void testdigestandsign(SecKeyRef privKey, SecKeyRef pubKey) {
84 static const SecAsn1Oid *oids[] = {
86 &CSSMOID_SHA224WithRSA,
87 &CSSMOID_SHA256WithRSA,
88 &CSSMOID_SHA384WithRSA,
89 &CSSMOID_SHA512WithRSA,
91 &CSSMOID_SHA1WithRSA_OIW,
92 &CSSMOID_SHA1WithDSA, // BSAFE
93 &CSSMOID_SHA1WithDSA_CMS, // X509/CMS
94 &CSSMOID_SHA1WithDSA_JDK, // JDK 1.1
100 SecAsn1AlgId algId = {};
101 for (ix = 0; ix < sizeof(oids) / sizeof(*oids); ++ix) {
103 algId.algorithm = *oids[ix];
105 algId.algorithm.Length = 0;
106 algId.algorithm.Data = NULL;
109 testdigestandsignalg(privKey, pubKey, &algId);
115 static void dump_bytes(uint8_t* bytes, size_t amount)
118 printf("0x%02x ", *bytes);
126 #if !TARGET_OS_IPHONE
127 #define kEncryptDecryptTestCount 0
129 #define kEncryptDecryptTestCount 6
130 static void test_encrypt_decrypt(SecKeyRef pubKey, SecKeyRef privKey, uint32_t padding, size_t keySizeInBytes)
133 size_t max_len = keySizeInBytes;
135 case kSecPaddingNone: max_len = keySizeInBytes; break;
136 case kSecPaddingOAEP: max_len = keySizeInBytes - 2 - 2 * CC_SHA1_DIGEST_LENGTH; break;
137 case kSecPaddingPKCS1: max_len = keySizeInBytes - 11; break;
138 default: skip("what is the max_len for this padding?", 5, false);
141 uint8_t secret[max_len + 1], encrypted_secret[keySizeInBytes], decrypted_secret[keySizeInBytes];
142 uint8_t *secret_ptr = secret;
143 size_t secret_len = max_len;
144 size_t encrypted_secret_len = sizeof(encrypted_secret);
145 size_t decrypted_secret_len = sizeof(decrypted_secret);
146 memset(decrypted_secret, 0xff, decrypted_secret_len);
147 ok_status(SecRandomCopyBytes(kSecRandomDefault, sizeof(secret), secret),"rng");
149 // zero pad, no accidental second zero byte
150 if (padding == kSecPaddingNone) {
155 is_status(SecKeyEncrypt(pubKey, padding,
156 secret, sizeof(secret),
157 encrypted_secret, &encrypted_secret_len), errSecParam, "encrypt secret (overflow)");
158 ok_status(SecKeyEncrypt(pubKey, padding,
160 encrypted_secret, &encrypted_secret_len), "encrypt secret");
162 ok_status(SecKeyDecrypt(privKey, padding,
163 encrypted_secret, encrypted_secret_len,
164 decrypted_secret, &decrypted_secret_len), "decrypt secret");
166 // zero padding is removed on decode
167 if (padding == kSecPaddingNone) {
172 ok(decrypted_secret_len == secret_len, "correct length");
173 ok_status(memcmp(secret_ptr, decrypted_secret, secret_len), "verify secret");
178 #define kKeyGenTestCount (12 + (3*kEncryptDecryptTestCount))
179 static void testkeygen(size_t keySizeInBits) {
180 SecKeyRef pubKey = NULL, privKey = NULL;
181 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
184 kzib = CFNumberCreate(NULL, kCFNumberSInt64Type, &keySizeInBits);
185 CFMutableDictionaryRef kgp = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
186 CFDictionaryAddValue(kgp, kSecAttrKeyType, kSecAttrKeyTypeRSA);
187 CFDictionaryAddValue(kgp, kSecAttrKeySizeInBits, kzib);
190 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
191 "Generate %ld bit (%ld byte) RSA keypair", keySizeInBits,
197 skip("keygen failed", 8, status == errSecSuccess);
198 ok(pubKey, "pubkey returned");
199 ok(privKey, "privKey returned");
200 is(SecKeyGetBlockSize(pubKey) * 8, (size_t) keySizeInBits, "public key size is ok");
201 is(SecKeyGetBlockSize(privKey) * 8, (size_t) keySizeInBits, "private key size is ok");
203 /* Sign something. */
204 uint8_t something[keySizeInBytes];
205 size_t something_len = keySizeInBytes - 11;
206 ok_status(SecRandomCopyBytes(kSecRandomDefault, sizeof(something), something), "rng");
207 uint8_t sig[keySizeInBytes];
208 size_t sigLen = sizeof(sig);
210 /* TODO: This is returning another error on OS X */
211 is_status(SecKeyRawSign(privKey, kSecPaddingPKCS1,
212 something, something_len + 1, sig, &sigLen),
213 errSecParam, "sign overflow");
215 ok_status(SecKeyRawSign(privKey, kSecPaddingPKCS1,
216 something, something_len, sig, &sigLen), "sign something");
217 ok_status(SecKeyRawVerify(pubKey, kSecPaddingPKCS1,
218 something, something_len, sig, sigLen), "verify sig on something");
220 // Torture test ASN.1 encoder by setting high bit to 1.
221 uint8_t digest[CC_SHA512_DIGEST_LENGTH] = {
222 0x80, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
223 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
224 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
225 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
226 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
227 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
228 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
229 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
232 /* Thoses tests are making sure that MD2 and MD5 are NOT supported,
233 but they still are on OS X */
235 //CC_MD2(something, sizeof(something), digest);
236 ok_status(!SecKeyRawSign(privKey, kSecPaddingPKCS1MD2,
237 digest, CC_MD2_DIGEST_LENGTH, sig, &sigLen),
238 "don't sign md2 digest"); //FAIL
239 ok_status(!SecKeyRawVerify(pubKey, kSecPaddingPKCS1MD2,
240 digest, CC_MD2_DIGEST_LENGTH, sig, sigLen),
241 "verify sig on md2 digest fails"); //FAIL
243 //CC_MD5(something, sizeof(something), digest);
244 sigLen = sizeof(sig);
245 ok_status(!SecKeyRawSign(privKey, kSecPaddingPKCS1MD5,
246 digest, CC_MD5_DIGEST_LENGTH, sig, &sigLen),
247 "don't sign md5 digest"); //FAIL
248 ok_status(!SecKeyRawVerify(pubKey, kSecPaddingPKCS1MD5,
249 digest, CC_MD5_DIGEST_LENGTH, sig, sigLen),
250 "verify sig on md5 digest fails"); //FAIL
253 //CCDigest(kCCDigestSHA1, something, sizeof(something), digest);
254 sigLen = sizeof(sig);
255 ok_status(SecKeyRawSign(privKey, kSecPaddingPKCS1SHA1,
256 digest, CC_SHA1_DIGEST_LENGTH, sig, &sigLen),
258 ok_status(SecKeyRawVerify(pubKey, kSecPaddingPKCS1SHA1,
259 digest, CC_SHA1_DIGEST_LENGTH, sig, sigLen),
260 "verify sig on sha1 digest");
263 /* The assumptions in these tests are just wrong on OS X */
264 uint8_t signature[keySizeInBytes], *ptr = signature;
265 size_t signature_len = sizeof(signature);
266 ok_status(SecKeyEncrypt(pubKey, kSecPaddingNone, sig, sigLen, signature, &signature_len), "inspect signature");
267 is(signature_len, keySizeInBytes - 1, "got signature"); // FAIL for 2056
268 while(*ptr && ((size_t)(ptr - signature) < signature_len)) ptr++;
269 is(signature + signature_len - ptr, 16 /* length(\0 || OID_SHA1) */ + CC_SHA1_DIGEST_LENGTH, "successful decode");
273 /* Those are not supported on OS X */
274 /* PKCS1 padding is 00 01 PAD * 8 or more 00 data.
275 data is SEQ { SEQ { OID NULL } BIT STRING 00 DIGEST }
276 So min data + pad overhead is 11 + 9 + oidlen
277 oidlen = 11 for the sha2 family of oids, so we have 29 bytes; or
278 232 bits of minimum overhead. */
279 const size_t pkcs1Overhead = 232;
280 if (keySizeInBits > 224 + pkcs1Overhead) {
281 //CC_SHA224(something, sizeof(something), digest);
282 sigLen = sizeof(sig);
283 ok_status(SecKeyRawSign(privKey, kSecPaddingPKCS1SHA224,
284 digest, CC_SHA224_DIGEST_LENGTH, sig, &sigLen),
285 "sign sha224 digest");
286 ok_status(SecKeyRawVerify(pubKey, kSecPaddingPKCS1SHA224,
287 digest, CC_SHA224_DIGEST_LENGTH, sig, sigLen),
288 "verify sig on sha224 digest");
291 if (keySizeInBits > 256 + pkcs1Overhead) {
292 //CC_SHA256(something, sizeof(something), digest);
293 sigLen = sizeof(sig);
294 ok_status(SecKeyRawSign(privKey, kSecPaddingPKCS1SHA256,
295 digest, CC_SHA256_DIGEST_LENGTH, sig, &sigLen),
296 "sign sha256 digest");
297 ok_status(SecKeyRawVerify(pubKey, kSecPaddingPKCS1SHA256,
298 digest, CC_SHA256_DIGEST_LENGTH, sig, sigLen),
299 "verify sig on sha256 digest");
302 if (keySizeInBits > 384 + pkcs1Overhead) {
303 //CC_SHA384(something, sizeof(something), digest);
304 sigLen = sizeof(sig);
305 ok_status(SecKeyRawSign(privKey, kSecPaddingPKCS1SHA384,
306 digest, CC_SHA384_DIGEST_LENGTH, sig, &sigLen),
307 "sign sha384 digest");
308 ok_status(SecKeyRawVerify(pubKey, kSecPaddingPKCS1SHA384,
309 digest, CC_SHA384_DIGEST_LENGTH, sig, sigLen),
310 "verify sig on sha384 digest");
313 if (keySizeInBits > 512 + pkcs1Overhead) {
314 //CC_SHA512(something, sizeof(something), digest);
315 sigLen = sizeof(sig);
316 ok_status(SecKeyRawSign(privKey, kSecPaddingPKCS1SHA512,
317 digest, CC_SHA512_DIGEST_LENGTH, sig, &sigLen),
318 "sign sha512 digest");
319 ok_status(SecKeyRawVerify(pubKey, kSecPaddingPKCS1SHA512,
320 digest, CC_SHA512_DIGEST_LENGTH, sig, sigLen),
321 "verify sig on sha512 digest");
324 test_encrypt_decrypt(pubKey, privKey, kSecPaddingNone, keySizeInBytes);
325 test_encrypt_decrypt(pubKey, privKey, kSecPaddingPKCS1, keySizeInBytes);
326 test_encrypt_decrypt(pubKey, privKey, kSecPaddingOAEP, keySizeInBytes);
328 testdigestandsign(privKey, pubKey);
331 const void *privkeys[] = {
334 const void *privvalues[] = {
337 CFDictionaryRef privitem = CFDictionaryCreate(NULL, privkeys, privvalues,
338 sizeof(privkeys) / sizeof(*privkeys), NULL, NULL);
340 /* OS X: keys are always added to the keychain when generated */
341 ok_status(SecItemAdd(privitem, NULL), "add private key"); //FAIL
343 ok_status(SecItemDelete(privitem), "delete private key");
344 CFReleaseNull(privitem);
346 const void *pubkeys[] = {
349 const void *pubvalues[] = {
352 CFDictionaryRef pubitem = CFDictionaryCreate(NULL, pubkeys, pubvalues,
353 sizeof(pubkeys) / sizeof(*pubkeys), NULL, NULL);
355 /* OS X: keys are always added to the keychain when generated */
356 ok_status(SecItemAdd(pubitem, NULL), "add public key"); //FAIL
358 ok_status(SecItemDelete(pubitem), "delete public key");
359 CFReleaseNull(pubitem);
362 CFReleaseNull(pubKey);
363 CFReleaseNull(privKey);
367 #define kKeyGen2TestCount 11
368 static void testkeygen2(size_t keySizeInBits) {
369 SecKeyRef pubKey = NULL, privKey = NULL;
370 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
373 CFUUIDRef ourUUID = CFUUIDCreate(kCFAllocatorDefault);
374 CFStringRef uuidString = CFUUIDCreateString(kCFAllocatorDefault, ourUUID);
375 CFMutableStringRef publicName = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, uuidString);
376 CFMutableStringRef privateName = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, uuidString);
378 CFReleaseNull(ourUUID);
379 CFReleaseNull(uuidString);
381 CFStringAppend(publicName, CFSTR("-Public-40"));
382 CFStringAppend(privateName, CFSTR("-Private-40"));
383 CFMutableDictionaryRef pubd = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
384 CFMutableDictionaryRef privd = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
386 CFDictionaryAddValue(pubd, kSecAttrLabel, publicName);
387 CFDictionaryAddValue(privd, kSecAttrLabel, privateName);
389 kzib = CFNumberCreate(NULL, kCFNumberSInt64Type, &keySizeInBits);
390 CFMutableDictionaryRef kgp = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
391 CFDictionaryAddValue(kgp, kSecAttrKeyType, kSecAttrKeyTypeRSA);
392 CFDictionaryAddValue(kgp, kSecAttrKeySizeInBits, kzib);
393 CFDictionaryAddValue(kgp, kSecAttrIsPermanent, kCFBooleanTrue);
394 CFDictionaryAddValue(kgp, kSecPublicKeyAttrs, pubd);
395 CFDictionaryAddValue(kgp, kSecPrivateKeyAttrs, privd);
398 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
399 "Generate %ld bit (%ld byte) persistent RSA keypair",
400 keySizeInBits, keySizeInBytes);
405 skip("keygen failed", 8, status == errSecSuccess);
406 ok(pubKey, "pubkey returned");
407 ok(privKey, "privKey returned");
408 is(SecKeyGetBlockSize(pubKey) * 8, (size_t) keySizeInBits, "public key size is ok");
409 is(SecKeyGetBlockSize(privKey) * 8, (size_t) keySizeInBits, "private key size is ok");
411 SecKeyRef pubKey2, privKey2;
412 CFDictionaryAddValue(pubd, kSecClass, kSecClassKey);
413 CFDictionaryAddValue(pubd, kSecReturnRef, kCFBooleanTrue);
414 CFDictionaryAddValue(privd, kSecClass, kSecClassKey);
415 CFDictionaryAddValue(privd, kSecReturnRef, kCFBooleanTrue);
416 CFDictionaryAddValue(privd, kSecAttrCanSign, kCFBooleanTrue);
417 ok_status(SecItemCopyMatching(pubd, (CFTypeRef *)&pubKey2),
418 "retrieve pub key by label");
419 ok_status(SecItemCopyMatching(privd, (CFTypeRef *)&privKey2),
420 "retrieve priv key by label and kSecAttrCanSign");
422 /* Sign something. */
423 uint8_t something[50] = {0x80, 0xbe, 0xef, 0xba, 0xd0, };
424 uint8_t sig[keySizeInBytes];
425 size_t sigLen = keySizeInBytes;
426 ok_status(SecKeyRawSign(privKey2, kSecPaddingPKCS1,
427 something, sizeof(something), sig, &sigLen), "sign something");
428 ok_status(SecKeyRawVerify(pubKey2, kSecPaddingPKCS1,
429 something, sizeof(something), sig, sigLen), "verify sig on something");
432 /* SecKeyEncrypt does not return errSecParam on OS X in that case */
433 sigLen = keySizeInBytes;
434 is_status(SecKeyEncrypt(pubKey2, kSecPaddingPKCS1SHA1,
435 something, sizeof(something), sig, &sigLen), errSecParam,
436 "encrypt something with invalid padding");
440 CFReleaseNull(pubKey2);
441 CFReleaseNull(privKey2);
443 /* delete from keychain - note: do it before releasing publicName and privateName
444 because pubd and privd have no retain/release callbacks */
445 ok_status(SecItemDelete(pubd), "delete generated pub key");
446 ok_status(SecItemDelete(privd), "delete generated priv key");
450 CFReleaseNull(pubKey);
451 CFReleaseNull(privKey);
453 CFReleaseNull(publicName);
454 CFReleaseNull(privateName);
461 #if !TARGET_OS_IPHONE
462 // Only exists currently in MacOSX
463 typedef struct KDFVector_t {
470 int expected_failure;
473 static KDFVector kdfv[] = {
474 // Test Case PBKDF2 - HMACSHA1 http://tools.ietf.org/html/draft-josefsson-pbkdf2-test-vectors-00
475 { "password", "salt", 1, 1, 160, "0c60c80f961f0e71f3a9b524af6012062fe037a6", 0 },
476 { "password", "salt", 2, 1, 160, "ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957", 0 },
477 { "password", "salt", 4096, 1, 160, "4b007901b765489abead49d926f721d065a429c1", 0 },
478 { "password", "salt", 1, 0, 160, NULL, -1} // This crashed
481 static size_t kdfvLen = sizeof(kdfv) / sizeof(KDFVector);
483 static int testSecKDF(CFStringRef password, CFDataRef salt, CFNumberRef rounds, CFStringRef alg, CFNumberRef dklen, CFDataRef expected, int expected_failure) {
484 CFMutableDictionaryRef parameters = CFDictionaryCreateMutable(kCFAllocatorDefault, 4, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
487 CFDictionaryAddValue(parameters, kSecAttrSalt, salt);
488 CFDictionaryAddValue(parameters, kSecAttrKeySizeInBits, dklen);
489 CFDictionaryAddValue(parameters, kSecAttrPRF, alg);
490 CFDictionaryAddValue(parameters, kSecAttrRounds, rounds);
492 SecKeyRef derivedKey = SecKeyDeriveFromPassword(password, parameters, NULL);
493 if(derivedKey == NULL && expected_failure) {
494 ok(1, "Correctly failed to produce a key");
496 } else if(derivedKey == NULL) {
497 ok(0, "Could not generate a key when we should have");
500 ok(1, "Made a new key");
502 // NEEDS Fix -- ok(status = expectedEqualsComputed(expected, derivedKey), "Derived key is as expected");
504 if(parameters) CFRelease(parameters);
505 if(derivedKey) CFRelease(derivedKey);
509 static CFDataRef CFDataCreateFromHexBytes(char *s) {
511 size_t len = strlen(s);
512 if(len%2) return NULL;
515 for(size_t i=0; i<len; i++) {
516 buf[i] = s[i*2] * 16 + s[i*2+1];
518 CFDataRef retval = CFDataCreate(NULL, buf, len);
524 PBKDF2Test(KDFVector *kdfvec)
526 CFDataRef expectedBytes = CFDataCreateFromHexBytes(kdfvec->expectedstr);
527 CFStringRef password = CFStringCreateWithCString(NULL, kdfvec->password, kCFStringEncodingUTF8);
528 CFDataRef salt = CFDataCreate(NULL, (const UInt8 *)kdfvec->salt, strlen(kdfvec->salt));
529 CFNumberRef rounds = CFNumberCreate(NULL, kCFNumberIntType, &kdfvec->rounds);
530 CFNumberRef dklen = CFNumberCreate(NULL, kCFNumberIntType, &kdfvec->dklen);
533 ok(testSecKDF(password, salt, rounds, kSecAttrPRFHmacAlgSHA1, dklen, expectedBytes, kdfvec->expected_failure), "Test SecKeyDeriveFromPassword PBKDF2");
535 CFReleaseNull(expectedBytes);
536 CFReleaseNull(password);
538 CFReleaseNull(rounds);
539 CFReleaseNull(dklen);
545 static void testkeyderivation() {
546 for(size_t testcase = 0; testcase < kdfvLen; testcase++) {
547 // diag("Test %lu\n", testcase + 1);
548 ok(PBKDF2Test(&kdfv[testcase]), "Successful full test of KDF Vector");
553 static size_t kdfvLen = 0; // no kdf functions in Sec for iphone
554 #endif /* !TARGET_OS_IPHONE */
556 static void delete_key(SecKeyRef *key) {
557 CFMutableDictionaryRef query = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks,
558 &kCFTypeDictionaryValueCallBacks);
559 CFDictionarySetValue(query, kSecValueRef, *key);
560 SecItemDelete(query);
561 CFReleaseNull(query);
565 static const int kTestSupportedCount = 3 + (4 * 12) + 2 + (4 * 10) + 2;
566 static void testsupportedalgos(size_t keySizeInBits)
568 SecKeyRef pubKey = NULL, privKey = NULL;
569 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
572 int32_t iKeySizeInBits = (int32_t) keySizeInBits;
573 kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &iKeySizeInBits);
574 CFMutableDictionaryRef kgp = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
575 CFDictionaryAddValue(kgp, kSecAttrKeyType, kSecAttrKeyTypeRSA);
576 CFDictionaryAddValue(kgp, kSecAttrKeySizeInBits, kzib);
579 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
580 "Generate %ld bit (%ld byte) persistent RSA keypair",
581 keySizeInBits, keySizeInBytes);
585 is(SecKeyGetBlockSize(pubKey) * 8, (size_t) keySizeInBits, "public key size is ok");
586 is(SecKeyGetBlockSize(privKey) * 8, (size_t) keySizeInBits, "private key size is ok");
588 const SecKeyAlgorithm sign[] = {
589 kSecKeyAlgorithmRSASignatureRaw,
590 kSecKeyAlgorithmRSASignatureDigestPKCS1v15Raw,
591 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1,
592 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1,
593 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA224,
594 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA224,
595 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256,
596 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256,
597 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384,
598 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA384,
599 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512,
600 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA512,
603 for (size_t i = 0; i < array_size(sign); i++) {
604 SecKeyAlgorithm algorithm = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@"), sign[i]);
605 ok(SecKeyIsAlgorithmSupported(privKey, kSecKeyOperationTypeSign, algorithm),
606 "privKey supports sign algorithm %@", algorithm);
607 ok(SecKeyIsAlgorithmSupported(pubKey, kSecKeyOperationTypeVerify, algorithm),
608 "pubKey supports verify algorithm %@", algorithm);
609 // Since private key supports RSA decryption, our verify adapters happily accepts it.
610 ok(SecKeyIsAlgorithmSupported(privKey, kSecKeyOperationTypeVerify, algorithm),
611 "privKey supports verify algorithm %@", algorithm);
612 ok(!SecKeyIsAlgorithmSupported(pubKey, kSecKeyOperationTypeSign, algorithm),
613 "pubKey doesn't support sign algorithm %@", algorithm);
614 CFReleaseNull(algorithm);
616 ok(!SecKeyIsAlgorithmSupported(privKey, kSecKeyOperationTypeSign, kSecKeyAlgorithmECDSASignatureDigestX962),
617 "RSA privKey does not support ECDSA algorithm");
618 ok(!SecKeyIsAlgorithmSupported(privKey, kSecKeyOperationTypeVerify, kSecKeyAlgorithmECDSASignatureDigestX962),
619 "RSA pubKey does not support ECDSA algorithm");
621 const SecKeyAlgorithm crypt[] = {
622 kSecKeyAlgorithmRSAEncryptionRaw,
623 kSecKeyAlgorithmRSAEncryptionPKCS1,
624 kSecKeyAlgorithmRSAEncryptionOAEPSHA1,
625 kSecKeyAlgorithmRSAEncryptionOAEPSHA224,
626 kSecKeyAlgorithmRSAEncryptionOAEPSHA256,
627 kSecKeyAlgorithmRSAEncryptionOAEPSHA384,
628 kSecKeyAlgorithmRSAEncryptionOAEPSHA1AESGCM,
629 kSecKeyAlgorithmRSAEncryptionOAEPSHA224AESGCM,
630 kSecKeyAlgorithmRSAEncryptionOAEPSHA256AESGCM,
631 kSecKeyAlgorithmRSAEncryptionOAEPSHA384AESGCM,
632 // kSecKeyAlgorithmRSAEncryptionOAEPSHA512,
634 for (size_t i = 0; i < array_size(crypt); i++) {
635 SecKeyAlgorithm algorithm = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@"), crypt[i]);
636 ok(SecKeyIsAlgorithmSupported(privKey, kSecKeyOperationTypeDecrypt, algorithm),
637 "privKey supports decrypt algorithm %@", algorithm);
638 ok(SecKeyIsAlgorithmSupported(pubKey, kSecKeyOperationTypeEncrypt, algorithm),
639 "pubKey supports encrypt algorithm %@", algorithm);
640 ok(!SecKeyIsAlgorithmSupported(privKey, kSecKeyOperationTypeEncrypt, algorithm),
641 "privKey doesn't support encrypt algorithm %@", algorithm);
642 if (i >= 6 /* >= kSecKeyAlgorithmRSAEncryptionOAEPSHA1AESGCM */) {
643 ok(!SecKeyIsAlgorithmSupported(pubKey, kSecKeyOperationTypeDecrypt, algorithm),
644 "pubKey doesn't support algorithm %@", algorithm);
646 ok(SecKeyIsAlgorithmSupported(pubKey, kSecKeyOperationTypeDecrypt, algorithm),
647 "pubKey supports decrypt algorithm %@", algorithm);
649 CFReleaseNull(algorithm);
651 ok(!SecKeyIsAlgorithmSupported(privKey, kSecKeyOperationTypeDecrypt, kSecKeyAlgorithmRSAEncryptionOAEPSHA512),
652 "privKey doesn't support decrypt algorithm %@", kSecKeyAlgorithmRSAEncryptionOAEPSHA512);
653 ok(!SecKeyIsAlgorithmSupported(privKey, kSecKeyOperationTypeDecrypt, kSecKeyAlgorithmRSAEncryptionOAEPSHA512AESGCM),
654 "privKey doesn't support decrypt algorithm %@", kSecKeyAlgorithmRSAEncryptionOAEPSHA512AESGCM);
658 delete_key(&privKey);
662 #define kTestSupportedCount 15
663 static void testsupportedalgos(size_t keySizeInBits)
665 SecKeyRef pubKey = NULL, privKey = NULL;
666 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
669 int32_t iKeySizeInBits = (int32_t) keySizeInBits;
670 kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &iKeySizeInBits);
671 CFMutableDictionaryRef kgp = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
672 CFDictionaryAddValue(kgp, kSecAttrKeyType, kSecAttrKeyTypeRSA);
673 CFDictionaryAddValue(kgp, kSecAttrKeySizeInBits, kzib);
674 CFDictionaryAddValue(kgp, kSecAttrLabel, CFSTR("sectests:testsupportedalgos"));
677 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
678 "Generate %ld bit (%ld byte) persistent RSA keypair",
679 keySizeInBits, keySizeInBytes);
683 is(SecKeyGetBlockSize(pubKey) * 8, (size_t) keySizeInBits, "public key size is ok");
684 is(SecKeyGetBlockSize(privKey) * 8, (size_t) keySizeInBits, "private key size is ok");
686 CFSetRef keySet, expectedSet;
688 CFIndex value = kSecKeyAlgorithmECDSASignatureDigestX962;
689 CFNumberRef ECDSAX962 = CFNumberCreate(NULL, kCFNumberCFIndexType, &value);
690 value = kSecKeyAlgorithmRSAEncryptionRaw;
691 CFNumberRef RSARaw = CFNumberCreate(NULL, kCFNumberCFIndexType, &value);
694 keySet = SecKeyCopySupportedAlgorithms(privKey, kSecKeyOperationTypeSign);
695 const SecKeyAlgorithm sign[] = {
696 kSecKeyAlgorithmRSASignatureRaw,
697 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1,
698 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1,
699 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA224,
700 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA224,
701 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256,
702 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256,
703 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384,
704 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA384,
705 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512,
706 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA512,
708 expectedSet = createAlgorithmSet(sign, array_size(sign));
709 ok(CFSetIsSubset(expectedSet, keySet), "privkey contains expecting algos for signing");
710 ok(!CFSetContainsValue(keySet, ECDSAX962));
711 CFReleaseNull(keySet);
712 CFReleaseNull(expectedSet);
714 keySet = SecKeyCopySupportedAlgorithms(privKey, kSecKeyOperationTypeVerify);
715 expectedSet = createAlgorithmSet(sign, array_size(sign));
716 ok(CFSetIsSubset(expectedSet, keySet), "privkey contains expecting algos for verification");
717 ok(!CFSetContainsValue(keySet, ECDSAX962));
718 CFReleaseNull(keySet);
719 CFReleaseNull(expectedSet);
721 keySet = SecKeyCopySupportedAlgorithms(privKey, kSecKeyOperationTypeDecrypt);
722 const SecKeyAlgorithm decrypt[] = {
723 kSecKeyAlgorithmRSAEncryptionRaw,
724 kSecKeyAlgorithmRSAEncryptionPKCS1,
725 kSecKeyAlgorithmRSAEncryptionOAEPSHA1,
726 kSecKeyAlgorithmRSAEncryptionOAEPSHA224,
727 kSecKeyAlgorithmRSAEncryptionOAEPSHA256,
728 kSecKeyAlgorithmRSAEncryptionOAEPSHA384,
729 kSecKeyAlgorithmRSAEncryptionOAEPSHA512,
731 expectedSet = createAlgorithmSet(decrypt, array_size(decrypt));
732 ok(CFSetIsSubset(expectedSet, keySet), "privkey contains expecting algos for decryption");
733 CFReleaseNull(keySet);
734 CFReleaseNull(expectedSet);
736 keySet = SecKeyCopySupportedAlgorithms(privKey, kSecKeyOperationTypeEncrypt);
737 expectedSet = CFSetCreate(NULL, NULL, 0, &kCFTypeSetCallBacks);
738 is(CFSetGetCount(keySet), 0, "privkey contains no algos for encryption");
739 CFReleaseNull(keySet);
740 CFReleaseNull(expectedSet);
744 keySet = SecKeyCopySupportedAlgorithms(pubKey, kSecKeyOperationTypeVerify);
745 const SecKeyAlgorithm verify[] = {
746 kSecKeyAlgorithmRSASignatureRaw,
747 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1,
748 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA224,
749 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256,
750 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384,
751 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512,
752 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1,
753 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA224,
754 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256,
755 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA384,
756 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA512,
758 expectedSet = createAlgorithmSet(verify, array_size(verify));
759 ok(CFSetIsSubset(expectedSet, keySet), "pubkey contains expecting algos for verification");
760 ok(!CFSetContainsValue(keySet, ECDSAX962),
761 "pubkey does not contain ECDSA algorithms for verification");
762 ok(!CFSetContainsValue(keySet, RSARaw),
763 "pubkey does not contain encryption-specific algorithm for verification");
764 CFReleaseNull(keySet);
765 CFReleaseNull(expectedSet);
767 keySet = SecKeyCopySupportedAlgorithms(pubKey, kSecKeyOperationTypeSign);
768 expectedSet = CFSetCreate(NULL, NULL, 0, &kCFTypeSetCallBacks);
769 is(CFSetGetCount(keySet), 0, "pubkey contains no algos for signing");
770 CFReleaseNull(keySet);
771 CFReleaseNull(expectedSet);
773 const SecKeyAlgorithm crypt[] = {
774 kSecKeyAlgorithmRSAEncryptionRaw,
775 kSecKeyAlgorithmRSAEncryptionPKCS1,
776 kSecKeyAlgorithmRSAEncryptionOAEPSHA1,
777 kSecKeyAlgorithmRSAEncryptionOAEPSHA224,
778 kSecKeyAlgorithmRSAEncryptionOAEPSHA256,
779 kSecKeyAlgorithmRSAEncryptionOAEPSHA384,
780 kSecKeyAlgorithmRSAEncryptionOAEPSHA512,
782 expectedSet = createAlgorithmSet(crypt, array_size(crypt));
783 keySet = SecKeyCopySupportedAlgorithms(pubKey, kSecKeyOperationTypeDecrypt);
785 ok(CFSetIsSubset(expectedSet, keySet), "pubkey contains expecting algos for decryption");
787 ok(CFSetGetCount(keySet) == 0, "pubkey cannot decrypt");
789 CFReleaseNull(keySet);
790 CFReleaseNull(expectedSet);
792 keySet = SecKeyCopySupportedAlgorithms(pubKey, kSecKeyOperationTypeEncrypt);
793 expectedSet = createAlgorithmSet(crypt, array_size(crypt));
794 ok(CFSetIsSubset(expectedSet, keySet), "pubkey contains expecting algos for encryption");
795 CFReleaseNull(keySet);
796 CFReleaseNull(expectedSet);
800 CFReleaseNull(RSARaw);
801 CFReleaseNull(ECDSAX962);
803 delete_key(&privKey);
807 #if !TARGET_OS_IPHONE
808 static inline bool CFEqualSafe(CFTypeRef left, CFTypeRef right)
810 if (left == NULL || right == NULL)
811 return left == right;
813 return CFEqual(left, right);
817 #define kCreateWithDataTestCount 13
818 static void testcreatewithdata(unsigned long keySizeInBits)
820 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
821 int32_t keysz32 = (int32_t)keySizeInBits;
823 CFNumberRef kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &keysz32);
824 CFMutableDictionaryRef kgp = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks,
825 &kCFTypeDictionaryValueCallBacks);
826 CFDictionarySetValue(kgp, kSecAttrKeyType, kSecAttrKeyTypeRSA);
827 CFDictionarySetValue(kgp, kSecAttrKeySizeInBits, kzib);
828 CFDictionarySetValue(kgp, kSecAttrIsPermanent, kCFBooleanFalse);
829 CFDictionarySetValue(kgp, kSecAttrLabel, CFSTR("sectests:createwithdata"));
831 SecKeyRef pubKey = NULL, privKey = NULL;
833 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
834 "Generate %ld bit (%ld byte) RSA keypair (status = %d)",
835 keySizeInBits, keySizeInBytes, (int)status);
838 CFMutableDictionaryRef kcwd = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks,
839 &kCFTypeDictionaryValueCallBacks);;
840 CFDictionarySetValue(kcwd, kSecAttrKeyType, kSecAttrKeyTypeRSA);
841 CFDictionarySetValue(kcwd, kSecAttrKeySizeInBits, kzib);
842 CFDictionarySetValue(kcwd, kSecAttrIsPermanent, kCFBooleanFalse);
845 CFErrorRef error = NULL;
846 CFDataRef privExternalData = NULL, pubExternalData = NULL;
847 SecKeyRef dataKey = NULL;
850 privExternalData = SecKeyCopyExternalRepresentation(privKey, &error);
851 ok(privExternalData && CFGetTypeID(privExternalData) == CFDataGetTypeID(),
852 "priv key SecKeyCopyExternalRepresentation failed");
853 CFReleaseNull(error);
856 skip("invalid priv key external data", 4, privExternalData);
858 CFDictionarySetValue(kcwd, kSecAttrKeyClass, kSecAttrKeyClassPrivate);
859 dataKey = SecKeyCreateWithData(privExternalData, kcwd, &error);
860 ok(dataKey, "priv key SecKeyCreateWithData failed");
861 CFReleaseNull(error);
863 CFDataRef external = SecKeyCopyExternalRepresentation(dataKey, NULL);
864 eq_cf(privExternalData, external, "priv keys differ");
865 CFReleaseNull(external);
866 CFReleaseNull(dataKey);
868 CFDictionarySetValue(kcwd, kSecAttrKeyClass, kSecAttrKeyClassPublic);
869 dataKey = SecKeyCreateWithData(privExternalData, kcwd, &error);
870 ok(!dataKey, "priv key SecKeyCreateWithData succeeded with invalid kSecAttrKeyClass");
871 CFReleaseNull(error);
872 CFReleaseNull(dataKey);
874 CFMutableDataRef modifiedExternalData = CFDataCreateMutableCopy(kCFAllocatorDefault, 0, privExternalData);
875 *CFDataGetMutableBytePtr(modifiedExternalData) ^= 0xff;
877 CFDictionarySetValue(kcwd, kSecAttrKeyClass, kSecAttrKeyClassPrivate);
878 dataKey = SecKeyCreateWithData(modifiedExternalData, kcwd, &error);
879 ok(!dataKey, "priv key SecKeyCreateWithData succeeded with invalid external data");
880 CFReleaseNull(error);
881 CFReleaseNull(dataKey);
883 CFReleaseNull(modifiedExternalData);
888 pubExternalData = SecKeyCopyExternalRepresentation(pubKey, &error);
889 ok(pubExternalData && CFGetTypeID(pubExternalData) == CFDataGetTypeID(),
890 "pub key SecKeyCopyExternalRepresentation failed");
891 CFReleaseNull(error);
894 skip("invalid pub key external data", 4, pubExternalData);
896 CFDictionarySetValue(kcwd, kSecAttrKeyClass, kSecAttrKeyClassPublic);
897 dataKey = SecKeyCreateWithData(pubExternalData, kcwd, &error);
898 ok(dataKey, "pub key SecKeyCreateWithData failed");
899 CFReleaseNull(error);
901 CFDataRef external = SecKeyCopyExternalRepresentation(dataKey, NULL);
902 eq_cf(pubExternalData, external, "pub keys differ");
903 CFReleaseNull(external);
904 CFReleaseNull(dataKey);
906 CFDictionarySetValue(kcwd, kSecAttrKeyClass, kSecAttrKeyClassPrivate);
907 dataKey = SecKeyCreateWithData(pubExternalData, kcwd, &error);
908 ok(!dataKey, "pub key SecKeyCreateWithData succeeded with invalid kSecAttrKeyClass");
909 CFReleaseNull(error);
910 CFReleaseNull(dataKey);
912 CFMutableDataRef modifiedExternalData = CFDataCreateMutableCopy(kCFAllocatorDefault, 0, pubExternalData);
913 *CFDataGetMutableBytePtr(modifiedExternalData) ^= 0xff;
915 CFDictionarySetValue(kcwd, kSecAttrKeyClass, kSecAttrKeyClassPublic);
916 dataKey = SecKeyCreateWithData(modifiedExternalData, kcwd, &error);
917 ok(!dataKey, "pub key SecKeyCreateWithData succeeded with invalid external data");
918 CFReleaseNull(error);
919 CFReleaseNull(dataKey);
921 CFReleaseNull(modifiedExternalData);
926 skip("invalid pub key external data", 1, pubExternalData);
928 CFDictionarySetValue(kcwd, kSecAttrKeyClass, kSecAttrKeyClassPrivate);
929 dataKey = SecKeyCreateWithData(pubExternalData, kcwd, &error);
930 ok(!dataKey, "priv key SecKeyCreateWithData succeeded with public external data");
931 CFReleaseNull(error);
932 CFReleaseNull(dataKey);
934 CFReleaseNull(pubExternalData);
938 skip("invalid priv key external data", 1, privExternalData);
940 CFDictionarySetValue(kcwd, kSecAttrKeyClass, kSecAttrKeyClassPublic);
941 dataKey = SecKeyCreateWithData(privExternalData, kcwd, &error);
942 ok(!dataKey, "pub key SecKeyCreateWithData succeeded with private external data");
943 CFReleaseNull(error);
944 CFReleaseNull(dataKey);
946 CFReleaseNull(privExternalData);
951 delete_key(&privKey);
954 #define kCopyAttributesTestCount 20
955 static void testcopyattributes(unsigned long keySizeInBits, bool extractable)
957 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
958 int32_t keysz32 = (int32_t)keySizeInBits;
960 CFNumberRef kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &keysz32);
961 CFMutableDictionaryRef kgp = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks,
962 &kCFTypeDictionaryValueCallBacks);
963 CFDictionarySetValue(kgp, kSecAttrKeyType, kSecAttrKeyTypeRSA);
964 CFDictionarySetValue(kgp, kSecAttrKeySizeInBits, kzib);
965 CFDictionarySetValue(kgp, kSecAttrIsExtractable, extractable ? kCFBooleanTrue : kCFBooleanFalse);
966 CFDictionarySetValue(kgp, kSecAttrLabel, CFSTR("sectests:copyattributes"));
967 SecKeyRef pubKey = NULL, privKey = NULL;
969 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
970 "Generate %ld bit (%ld byte) RSA keypair (status = %d)",
971 keySizeInBits, keySizeInBytes, (int)status);
974 CFDictionaryRef attributes;
975 CFTypeRef attrValue = NULL, privAppLabel = NULL, pubAppLabel = NULL;
978 attributes = SecKeyCopyAttributes(privKey);
979 ok(attributes && CFGetTypeID(attributes) == CFDictionaryGetTypeID(),
980 "priv key SecKeyCopyAttributes failed");
983 skip("invalid attributes", 8, attributes);
985 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanEncrypt);
986 eq_cf(attrValue, kCFBooleanFalse, "invalid priv key kSecAttrCanEncrypt");
988 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanDecrypt);
989 eq_cf(attrValue, kCFBooleanTrue, "invalid priv key kSecAttrCanDecrypt");
991 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanDerive);
992 eq_cf(attrValue, kCFBooleanTrue, "invalid priv key kSecAttrCanDerive");
994 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanSign);
995 eq_cf(attrValue, kCFBooleanTrue, "invalid priv key kSecAttrCanSign");
997 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanVerify);
998 eq_cf(attrValue, kCFBooleanFalse, "invalid priv key kSecAttrCanVerify");
1000 attrValue = CFDictionaryGetValue(attributes, kSecAttrKeyClass);
1001 eq_cf(attrValue, kSecAttrKeyClassPrivate, "priv key invalid kSecAttrKeyClass");
1003 attrValue = CFDictionaryGetValue(attributes, kSecAttrKeyType);
1004 eq_cf(attrValue, kSecAttrKeyTypeRSA, "invalid priv key kSecAttrKeyType");
1006 attrValue = CFDictionaryGetValue(attributes, kSecAttrKeySizeInBits);
1007 eq_cf(attrValue, kzib, "invalid priv key kSecAttrKeySizeInBits");
1009 privAppLabel = CFDictionaryGetValue(attributes, kSecAttrApplicationLabel);
1010 CFRetainSafe(privAppLabel);
1012 CFReleaseNull(attributes);
1017 attributes = SecKeyCopyAttributes(pubKey);
1018 ok(attributes && CFGetTypeID(attributes) == CFDictionaryGetTypeID(),
1019 "pub key SecKeyCopyAttributes failed");
1022 skip("invalid attributes", 8, attributes);
1024 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanEncrypt);
1025 eq_cf(attrValue, kCFBooleanTrue, "pub key invalid kSecAttrCanEncrypt");
1027 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanDecrypt);
1028 eq_cf(attrValue, kCFBooleanFalse, "pub key invalid kSecAttrCanDecrypt");
1030 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanDerive);
1031 eq_cf(attrValue, kCFBooleanTrue, "pub key invalid kSecAttrCanDerive");
1033 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanSign);
1034 eq_cf(attrValue, kCFBooleanFalse, "pub key invalid kSecAttrCanSign");
1036 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanVerify);
1037 eq_cf(attrValue, kCFBooleanTrue, "pub key invalid kSecAttrCanVerify");
1039 attrValue = CFDictionaryGetValue(attributes, kSecAttrKeyClass);
1040 eq_cf(attrValue, kSecAttrKeyClassPublic, "pub key invalid kSecAttrKeyClass");
1042 attrValue = CFDictionaryGetValue(attributes, kSecAttrKeyType);
1043 eq_cf(attrValue, kSecAttrKeyTypeRSA, "pub key invalid kSecAttrKeyType");
1045 attrValue = CFDictionaryGetValue(attributes, kSecAttrKeySizeInBits);
1046 eq_cf(attrValue, kzib, "pub key invalid kSecAttrKeySizeInBits");
1048 pubAppLabel = CFDictionaryGetValue(attributes, kSecAttrApplicationLabel);
1049 CFRetainSafe(pubAppLabel);
1051 CFReleaseNull(attributes);
1055 eq_cf(privAppLabel, pubAppLabel, "priv key and pub key kSecAttrApplicationLabel differ");
1057 CFReleaseNull(privAppLabel);
1058 CFReleaseNull(pubAppLabel);
1059 CFReleaseNull(kzib);
1060 delete_key(&pubKey);
1061 delete_key(&privKey);
1064 #define kCopyPublicKeyTestCount 5
1065 static void testcopypublickey(unsigned long keySizeInBits, bool extractable, bool permanent) {
1066 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
1067 int32_t keysz32 = (int32_t)keySizeInBits;
1069 CFNumberRef kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &keysz32);
1070 CFMutableDictionaryRef kgp = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks,
1071 &kCFTypeDictionaryValueCallBacks);
1072 CFDictionarySetValue(kgp, kSecAttrKeyType, kSecAttrKeyTypeRSA);
1073 CFDictionarySetValue(kgp, kSecAttrKeySizeInBits, kzib);
1074 CFDictionarySetValue(kgp, kSecAttrIsPermanent, permanent ? kCFBooleanTrue : kCFBooleanFalse);
1075 CFDictionarySetValue(kgp, kSecAttrIsExtractable, extractable ? kCFBooleanTrue : kCFBooleanFalse);
1076 CFDictionarySetValue(kgp, kSecAttrLabel, CFSTR("sectests:copypublickey"));
1077 SecKeyRef pubKey = NULL, privKey = NULL;
1080 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
1081 "Generate %ld bit (%ld byte) RSA keypair (status = %d)",
1082 keySizeInBits, keySizeInBytes, (int)status);
1084 NSError *error = nil;
1085 privKey = SecKeyCreateRandomKey(kgp, (void *)&error);
1086 pubKey = SecKeyCopyPublicKey(privKey);
1087 ok(privKey != NULL && pubKey != NULL, "Generate %ld bit (%ld byte) RSA keypair (error %@)",
1088 keySizeInBits, keySizeInBytes, error);
1091 CFReleaseNull(kzib);
1093 CFDataRef pubKeyData = SecKeyCopyExternalRepresentation(pubKey, NULL);
1095 SecKeyRef pubKeyCopy = NULL;
1098 pubKeyCopy = SecKeyCopyPublicKey(privKey);
1099 ok(pubKeyCopy, "priv key SecKeyCopyPublicKey failed");
1100 CFDataRef pubKeyCopyData = SecKeyCopyExternalRepresentation(pubKeyCopy, NULL);
1101 eq_cf(pubKeyCopyData, pubKeyData, "pub key from priv key SecKeyCopyPublicKey and pub key differ");
1102 CFReleaseNull(pubKeyCopy);
1103 CFReleaseNull(pubKeyCopyData);
1107 pubKeyCopy = SecKeyCopyPublicKey(pubKey);
1108 ok(pubKeyCopy, "pub key SecKeyCopyPublicKey failed");
1109 CFDataRef pubKeyCopyData = SecKeyCopyExternalRepresentation(pubKeyCopy, NULL);
1110 eq_cf(pubKeyCopyData, pubKeyData, "pub key from pub key SecKeyCopyPublicKey and pub key differ");
1111 CFReleaseNull(pubKeyCopy);
1112 CFReleaseNull(pubKeyCopyData);
1115 CFReleaseNull(pubKeyData);
1117 delete_key(&pubKey);
1118 delete_key(&privKey);
1120 CFReleaseSafe(pubKey);
1121 CFReleaseSafe(privKey);
1125 static const char *kCertWithPubK = "\
1126 MIIELjCCAxagAwIBAgIJALJlcYRBqZlZMA0GCSqGSIb3DQEBBQUAMIGUMQswCQYDVQQGEwJVUzELMAkG\
1127 A1UECBMCQ0ExEjAQBgNVBAcTCUN1cGVydGlubzETMBEGA1UEChMKQXBwbGUgSW5jLjEPMA0GA1UECxMG\
1128 Q29yZU9TMRwwGgYDVQQDExNBcHBsZSBUZXN0IENBMSBDZXJ0MSAwHgYJKoZIhvcNAQkBFhF2a3V6ZWxh\
1129 QGFwcGxlLmNvbTAeFw0xNTA0MjkwODMyMDBaFw0yNTA0MjYwODMyMDBaMIGPMQswCQYDVQQGEwJVUzEL\
1130 MAkGA1UECBMCQ0ExEjAQBgNVBAcTCUN1cGVydGlubzETMBEGA1UEChMKQXBwbGUgSW5jLjEQMA4GA1UE\
1131 CxMHQ29yZSBPUzEWMBQGA1UEAxMNRmlsaXAgU3Rva2xhczEgMB4GCSqGSIb3DQEJARYRc3Rva2xhc0Bh\
1132 cHBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZcPMvjpu7i/2SkNDCrSC4Wa8m\
1133 j3r6Lgn0crL4AgU+g3apptyy1eFf4RpNRJTGJ9ZMApbRZ0b7wX87Dq6UlCJUI9RJPOy+/TW0FM6mUVaF\
1134 VSY+P+KMdRYGIOMLVI+LR6lRTf8MWbxZ238cqAIVnLHaE9HrXjyIrgX2IufJjt69WhwsJZuan7jmeXJS\
1135 0AnESB31wS5NOn0tFDtzNAAQmoP8N8q6ZNC85tPVWBM61YLNjwSYl74y14QfX401P2pQRvwxTortRImk\
1136 xjN4DBprG23e59UW2IBxYsqUA61jhA0yVy8gxYpCGa4bEBslhrnkAoSv+Zlyk7u2GyO13AC1dfRxAgMB\
1137 AAGjgYUwgYIwPwYDVR0RBDgwNqAhBgorBgEEAYI3FAIDoBMMEXN0b2tsYXNAYXBwbGUuY29tgRFzdG9r\
1138 bGFzQGFwcGxlLmNvbTA/BgNVHREEODA2oCEGCisGAQQBgjcUAgOgEwwRc3Rva2xhc0BhcHBsZS5jb22B\
1139 EXN0b2tsYXNAYXBwbGUuY29tMA0GCSqGSIb3DQEBBQUAA4IBAQB87bZdl4XEDFA7UdPouhR3dKRl6evS\
1140 MfC9/0jVcdB+P1mNJ/vIZdOZMY0asieOXhsI91nEcHUjbBCnu18mu2jR6SGiJsS/zr6enkpQMcztulMU\
1141 kcjuSjT1hEzRv0LvEgWPOK+VpVqk6N0ZhybBQYVH2ECf7OU48CkFQFg9eLv6VaSK9+FqcBWpq8fXyOa7\
1142 bL58bO5A3URHcmMWibv9/j+lpVeQBxt1UUwqBZT7DSLPw3QCj/zXfAGEu3izvEYaWwsQDhItwQJ6g6pp\
1143 DLO741C7K8eKgvGs8ptna4RSosQda9bdnhZwT+g0UcorsVTUo+sR9+LW7INJ1zovRCL7NXit";
1145 static const char *kPubK = "\
1146 MIIBCgKCAQEA2XDzL46bu4v9kpDQwq0guFmvJo96+i4J9HKy+AIFPoN2qabcstXhX+EaTUSUxifWTAKW\
1147 0WdG+8F/Ow6ulJQiVCPUSTzsvv01tBTOplFWhVUmPj/ijHUWBiDjC1SPi0epUU3/DFm8Wdt/HKgCFZyx\
1148 2hPR6148iK4F9iLnyY7evVocLCWbmp+45nlyUtAJxEgd9cEuTTp9LRQ7czQAEJqD/DfKumTQvObT1VgT\
1149 OtWCzY8EmJe+MteEH1+NNT9qUEb8MU6K7USJpMYzeAwaaxtt3ufVFtiAcWLKlAOtY4QNMlcvIMWKQhmu\
1150 GxAbJYa55AKEr/mZcpO7thsjtdwAtXX0cQIDAQAB";
1152 static const int kTestCountCopyPubKFromCert = 2;
1153 static void testcopypubkfromcert() {
1154 NSData *certData = [[NSData alloc] initWithBase64EncodedString:[NSString stringWithUTF8String:kCertWithPubK]
1155 options:NSDataBase64DecodingIgnoreUnknownCharacters];
1156 NSData *pubKData = [[NSData alloc] initWithBase64EncodedString:[NSString stringWithUTF8String:kPubK]
1157 options:NSDataBase64DecodingIgnoreUnknownCharacters];
1158 SecCertificateRef cert = SecCertificateCreateWithData(kCFAllocatorDefault, (CFDataRef)certData);
1159 SecKeyRef pubKey = NULL;
1160 ok_status(SecCertificateCopyPublicKey(cert, &pubKey), "export public key from certificate");
1161 NSData *pubKeyData = (__bridge_transfer NSData *)SecKeyCopyExternalRepresentation(pubKey, NULL);
1162 eq_cf( (__bridge CFTypeRef) pubKeyData, (__bridge CFTypeRef) pubKData, "public key exports itself into expected data");
1163 CFReleaseNull(pubKey);
1164 CFReleaseNull(cert);
1167 static inline CFDataRef CFDataCreateWithHash(CFAllocatorRef allocator, const struct ccdigest_info *di, const uint8_t *buffer, const uint8_t length) {
1168 CFMutableDataRef result = CFDataCreateMutable(allocator, di->output_size);
1169 CFDataSetLength(result, di->output_size);
1171 ccdigest(di, length, buffer, CFDataGetMutableBytePtr(result));
1176 #define kSignAndVerifyTestCount 130
1177 static void testsignverify(unsigned long keySizeInBits)
1179 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
1180 int32_t keysz32 = (int32_t)keySizeInBits;
1182 CFNumberRef kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &keysz32);
1183 CFMutableDictionaryRef kgp = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks,
1184 &kCFTypeDictionaryValueCallBacks);
1185 CFDictionarySetValue(kgp, kSecAttrKeyType, kSecAttrKeyTypeRSA);
1186 CFDictionarySetValue(kgp, kSecAttrKeySizeInBits, kzib);
1187 CFDictionarySetValue(kgp, kSecAttrIsPermanent, kCFBooleanFalse);
1188 CFDictionarySetValue(kgp, kSecAttrLabel, CFSTR("sectests:signverify"));
1189 SecKeyRef pubKey = NULL, privKey = NULL, pubKeyIOS = NULL, privKeyIOS = NULL;
1191 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
1192 "Generate %ld bit (%ld byte) RSA keypair (status = %d)",
1193 keySizeInBits, keySizeInBytes, (int)status);
1195 CFReleaseNull(kzib);
1197 CFDataRef privKeyData = SecKeyCopyExternalRepresentation(privKey, NULL);
1198 CFDictionaryRef privKeyAttrs = SecKeyCopyAttributes(privKey);
1199 privKeyIOS = SecKeyCreateWithData(privKeyData, privKeyAttrs, NULL);
1200 CFReleaseNull(privKeyData);
1201 CFReleaseNull(privKeyAttrs);
1202 ok(privKeyIOS, "create IOS version of the private key");
1204 CFDataRef pubKeyData = SecKeyCopyExternalRepresentation(pubKey, NULL);
1205 CFDictionaryRef pubKeyAttrs = SecKeyCopyAttributes(pubKey);
1206 pubKeyIOS = SecKeyCreateWithData(pubKeyData, pubKeyAttrs, NULL);
1207 CFReleaseNull(pubKeyData);
1208 CFReleaseNull(pubKeyAttrs);
1209 ok(pubKeyIOS, "create IOS version of the public key");
1211 SecKeyAlgorithm algorithms[] = {
1212 kSecKeyAlgorithmRSASignatureRaw,
1213 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1,
1214 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA224,
1215 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256,
1216 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384,
1217 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512,
1218 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1,
1219 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA224,
1220 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256,
1221 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA384,
1222 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA512,
1225 CFDataRef testData = CFStringCreateExternalRepresentation(kCFAllocatorDefault, CFSTR("test"), kCFStringEncodingUTF8, 0);
1226 ok(testData, "creating test data failed");
1229 skip("invalid test data", 71, testData);
1231 CFErrorRef error = NULL;
1233 for (uint32_t ix = 0; ix < array_size(algorithms); ++ix) {
1234 SecKeyAlgorithm algorithm = algorithms[ix];
1235 SecKeyAlgorithm incompatibleAlgorithm = (CFEqual(algorithm, kSecKeyAlgorithmRSASignatureRaw)) ?
1236 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1 : kSecKeyAlgorithmRSASignatureRaw;
1238 CFDataRef dataToSign = NULL;
1239 if (CFEqual(algorithm, kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1)) {
1240 dataToSign = CFDataCreateWithHash(kCFAllocatorDefault, ccsha1_di(),
1241 CFDataGetBytePtr(testData), CFDataGetLength(testData));
1242 ok(dataToSign, "creating digest failed for algorithm %@", algorithm);
1244 else if (CFEqual(algorithm, kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA224)) {
1245 dataToSign = CFDataCreateWithHash(kCFAllocatorDefault, ccsha224_di(),
1246 CFDataGetBytePtr(testData), CFDataGetLength(testData));
1247 ok(dataToSign, "creating digest failed for algorithm %@", algorithm);
1249 else if (CFEqual(algorithm, kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256)) {
1250 dataToSign = CFDataCreateWithHash(kCFAllocatorDefault, ccsha256_di(),
1251 CFDataGetBytePtr(testData), CFDataGetLength(testData));
1252 ok(dataToSign, "creating digest failed for algorithm %@", algorithm);
1254 else if (CFEqual(algorithm, kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384)) {
1255 dataToSign = CFDataCreateWithHash(kCFAllocatorDefault, ccsha384_di(),
1256 CFDataGetBytePtr(testData), CFDataGetLength(testData));
1257 ok(dataToSign, "creating digest failed for algorithm %@", algorithm);
1259 else if (CFEqual(algorithm, kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512)) {
1260 dataToSign = CFDataCreateWithHash(kCFAllocatorDefault, ccsha512_di(),
1261 CFDataGetBytePtr(testData), CFDataGetLength(testData));
1262 ok(dataToSign, "creating digest failed for algorithm %@", algorithm);
1265 CFRetainAssign(dataToSign, testData);
1267 CFReleaseNull(error);
1270 skip("invalid data to sign", 7, dataToSign);
1272 CFDataRef signature = SecKeyCreateSignature(pubKey, algorithm, dataToSign, &error);
1273 ok(!signature, "SecKeyCopySignature succeeded with pub key for algorithm %@", algorithm);
1274 CFReleaseNull(error);
1275 CFReleaseNull(signature);
1277 signature = SecKeyCreateSignature(privKey, algorithm, dataToSign, &error);
1278 ok(signature, "SecKeyCopySignature failed for algorithm %@", algorithm);
1279 CFReleaseNull(error);
1281 CFDataRef iosSignature = SecKeyCreateSignature(privKeyIOS, algorithm, dataToSign, &error);
1282 ok(iosSignature, "SecKeyCopySignature(ios) failed for algorithm %@", algorithm);
1283 CFReleaseNull(error);
1286 skip("invalid signature", 4, signature);
1288 ok(!SecKeyVerifySignature(privKey, algorithm, dataToSign, signature, &error),
1289 "SecKeyVerifySignature succeeded with priv key for algorithm %@", algorithm);
1290 CFReleaseNull(error);
1292 ok(!SecKeyVerifySignature(pubKey, incompatibleAlgorithm, dataToSign, signature, &error),
1293 "SecKeyVerifySignature succeeded with wrong algorithm for algorithm %@", algorithm);
1294 CFReleaseNull(error);
1296 ok(SecKeyVerifySignature(pubKey, algorithm, dataToSign, signature, &error),
1297 "SecKeyVerifySignature(osx) failed osx-signature for algorithm %@", algorithm);
1298 CFReleaseNull(error);
1300 ok(SecKeyVerifySignature(pubKeyIOS, algorithm, dataToSign, signature, &error),
1301 "SecKeyVerifySignature(ios) failed for osx-signature for algorithm %@", algorithm);
1303 ok(SecKeyVerifySignature(pubKey, algorithm, dataToSign, iosSignature, &error),
1304 "SecKeyVerifySignature(osx) failed for ios-signature for algorithm %@", algorithm);
1305 CFReleaseNull(error);
1307 ok(SecKeyVerifySignature(pubKeyIOS, algorithm, dataToSign, iosSignature, &error),
1308 "SecKeyVerifySignature(ios) failed for ios-signature for algorithm %@", algorithm);
1310 CFMutableDataRef modifiedSignature = CFDataCreateMutableCopy(kCFAllocatorDefault, 0, signature);
1311 *CFDataGetMutableBytePtr(modifiedSignature) ^= 0xff;
1313 ok(!SecKeyVerifySignature(pubKey, algorithm, dataToSign, modifiedSignature, &error),
1314 "SecKeyVerifySignature succeeded with bad signature for algorithm %@", algorithm);
1315 CFReleaseNull(error);
1317 CFMutableDataRef modifiedDataToSign = CFDataCreateMutableCopy(kCFAllocatorDefault, 0, dataToSign);
1318 *CFDataGetMutableBytePtr(modifiedDataToSign) ^= 0xff;
1320 ok(!SecKeyVerifySignature(pubKey, algorithm, modifiedDataToSign, signature, &error),
1321 "SecKeyVerifySignature succeeded with bad data for algorithm %@", algorithm);
1322 CFReleaseNull(error);
1324 CFReleaseNull(modifiedDataToSign);
1325 CFReleaseNull(modifiedSignature);
1326 CFReleaseNull(signature);
1327 CFReleaseNull(iosSignature);
1329 CFReleaseNull(dataToSign);
1332 CFReleaseNull(testData);
1335 delete_key(&pubKey);
1336 delete_key(&privKey);
1337 CFReleaseNull(pubKeyIOS);
1338 CFReleaseNull(privKeyIOS);
1341 #define kNonExtractableTestCount 6
1342 static void testnonextractable(unsigned long keySizeInBits)
1344 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
1345 int32_t keysz32 = (int32_t)keySizeInBits;
1347 CFNumberRef kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &keysz32);
1348 CFMutableDictionaryRef kgp = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks,
1349 &kCFTypeDictionaryValueCallBacks);
1350 CFDictionarySetValue(kgp, kSecAttrKeyType, kSecAttrKeyTypeRSA);
1351 CFDictionarySetValue(kgp, kSecAttrKeySizeInBits, kzib);
1352 CFDictionarySetValue(kgp, kSecAttrIsPermanent, kCFBooleanTrue);
1353 CFDictionarySetValue(kgp, kSecAttrIsExtractable, kCFBooleanFalse);
1354 CFStringRef label = CFSTR("sectests:nonextractable");
1355 CFDictionarySetValue(kgp, kSecAttrLabel, label);
1356 SecKeyRef pubKey = NULL, privKey = NULL;
1358 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
1359 "Generate %ld bit (%ld byte) RSA keypair (status = %d)",
1360 keySizeInBits, keySizeInBytes, (int)status);
1362 CFReleaseNull(kzib);
1364 // Get attributes, verify that ApplicationLabel is set and equals for both keys.
1365 CFDictionaryRef privAttrs = SecKeyCopyAttributes(privKey);
1366 CFDictionaryRef pubAttrs = SecKeyCopyAttributes(pubKey);
1368 ok(privAttrs, "able to get private key attributes");
1369 ok(pubAttrs, "able to get public key attributes");
1371 CFDataRef privLabel = CFDictionaryGetValue(privAttrs, kSecAttrApplicationLabel);
1372 CFDataRef pubLabel = CFDictionaryGetValue(pubAttrs, kSecAttrApplicationLabel);
1374 ok(privLabel && CFGetTypeID(privLabel) == CFDataGetTypeID() && CFDataGetLength(privLabel) == 20,
1375 "priv appLabel is present and of correct type");
1376 ok(pubLabel && CFGetTypeID(pubLabel) == CFDataGetTypeID() && CFDataGetLength(pubLabel) == 20,
1377 "priv appLabel is present and of correct type");
1378 eq_cf(privLabel, pubLabel, "applabels of pub and priv keys are equal");
1380 CFReleaseNull(pubAttrs);
1381 CFReleaseNull(privAttrs);
1383 delete_key(&pubKey);
1384 delete_key(&privKey);
1387 #define kTestCount ((2 * kKeyGenTestCount) + kKeyGen2TestCount + (int) (kdfvLen*3)) + \
1388 kTestSupportedCount + kCreateWithDataTestCount + (kCopyAttributesTestCount * 2) + (kCopyPublicKeyTestCount * 4) + \
1389 kSignAndVerifyTestCount + kNonExtractableTestCount + \
1390 kTestCountCopyPubKFromCert
1392 static void tests(void)
1394 /* Comment out lines below for testing generating all common key sizes,
1395 disabled now for speed reasons. */
1399 testkeygen(2056); // Stranged sized for edge cases in padding.
1403 testkeygen2(1024); // lots of FAIL!
1405 testsupportedalgos(1024);
1406 testcreatewithdata(1024);
1407 testcopyattributes(1024, true);
1408 testcopyattributes(1024, false);
1409 testcopypublickey(1024, true, true);
1410 testcopypublickey(1024, false, true);
1411 testcopypublickey(1024, true, false);
1412 testcopypublickey(1024, false, false);
1413 testsignverify(1024);
1414 testnonextractable(1024);
1416 #if !TARGET_OS_IPHONE
1417 testkeyderivation();
1420 testcopypubkfromcert();
1423 int kc_40_seckey(int argc, char *const *argv)
1425 plan_tests(kTestCount);