]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_keychain/regressions/kc-40-seckey.m
Security-59306.140.5.tar.gz
[apple/security.git] / OSX / libsecurity_keychain / regressions / kc-40-seckey.m
1 /*
2 * Copyright (c) 2007-2009,2013-2014 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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
11 * file.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24
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>
34
35 #include <corecrypto/ccsha1.h>
36 #include <corecrypto/ccsha2.h>
37
38 #include "keychain_regressions.h"
39 #include "utilities/SecCFRelease.h"
40 #include "utilities/array_size.h"
41
42 #if TARGET_OS_IPHONE
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);
47 uint8_t sig[sigLen];
48
49 DERItem oid;
50 oid.length = algId->algorithm.Length;
51 oid.data = algId->algorithm.Data;
52
53 /* Get the oid in decimal for display purposes. */
54 CFStringRef oidStr = SecDERItemCopyOIDDecimalRepresentation(kCFAllocatorDefault, &oid);
55 char oidBuf[40];
56 CFStringGetCString(oidStr, oidBuf, sizeof(oidBuf), kCFStringEncodingUTF8);
57 CFRelease(oidStr);
58
59 SKIP: {
60 OSStatus status;
61
62 /* Time to sign. */
63 ok_status(status = SecKeyDigestAndSign(privKey, algId, dataToDigest, dataToDigestLen,
64 sig, &sigLen), "digest and sign %s with %ld bit RSA key", oidBuf, sigLen * 8);
65
66 skip("SecKeyDigestAndSign failed", 3, status == errSecSuccess);
67
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. */
73 sig[sigLen-1] ^= 1;
74 is_status(SecKeyDigestAndVerify(pubKey, algId, dataToDigest, dataToDigestLen,
75 sig, sigLen), errSSLCrypto, "digest and verify bad sig");
76 sig[sigLen-1] ^= 1;
77 dataToDigest[0] ^= 0xff;
78 is_status(SecKeyDigestAndVerify(pubKey, algId, dataToDigest, dataToDigestLen,
79 sig, sigLen), errSSLCrypto, "digest and verify bad digest");
80 }
81 }
82
83 static void testdigestandsign(SecKeyRef privKey, SecKeyRef pubKey) {
84 static const SecAsn1Oid *oids[] = {
85 &CSSMOID_SHA1WithRSA,
86 &CSSMOID_SHA224WithRSA,
87 &CSSMOID_SHA256WithRSA,
88 &CSSMOID_SHA384WithRSA,
89 &CSSMOID_SHA512WithRSA,
90 #if 0
91 &CSSMOID_SHA1WithRSA_OIW,
92 &CSSMOID_SHA1WithDSA, // BSAFE
93 &CSSMOID_SHA1WithDSA_CMS, // X509/CMS
94 &CSSMOID_SHA1WithDSA_JDK, // JDK 1.1
95 #endif
96 };
97
98
99 uint32_t ix;
100 SecAsn1AlgId algId = {};
101 for (ix = 0; ix < sizeof(oids) / sizeof(*oids); ++ix) {
102 if (oids[ix]) {
103 algId.algorithm = *oids[ix];
104 } else {
105 algId.algorithm.Length = 0;
106 algId.algorithm.Data = NULL;
107 }
108
109 testdigestandsignalg(privKey, pubKey, &algId);
110 }
111 }
112 #endif
113
114 #if 0
115 static void dump_bytes(uint8_t* bytes, size_t amount)
116 {
117 while (amount > 0) {
118 printf("0x%02x ", *bytes);
119 ++bytes;
120 --amount;
121 }
122 }
123 #endif
124
125
126 #if !TARGET_OS_IPHONE
127 #define kEncryptDecryptTestCount 0
128 #else
129 #define kEncryptDecryptTestCount 6
130 static void test_encrypt_decrypt(SecKeyRef pubKey, SecKeyRef privKey, uint32_t padding, size_t keySizeInBytes)
131 {
132 SKIP: {
133 size_t max_len = keySizeInBytes;
134 switch (padding) {
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);
139 }
140
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");
148
149 // zero pad, no accidental second zero byte
150 if (padding == kSecPaddingNone) {
151 secret[0] = 0;
152 secret[1] = 128;
153 }
154
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,
159 secret, secret_len,
160 encrypted_secret, &encrypted_secret_len), "encrypt secret");
161
162 ok_status(SecKeyDecrypt(privKey, padding,
163 encrypted_secret, encrypted_secret_len,
164 decrypted_secret, &decrypted_secret_len), "decrypt secret");
165
166 // zero padding is removed on decode
167 if (padding == kSecPaddingNone) {
168 secret_len--;
169 secret_ptr++;
170 }
171
172 ok(decrypted_secret_len == secret_len, "correct length");
173 ok_status(memcmp(secret_ptr, decrypted_secret, secret_len), "verify secret");
174 }
175 }
176 #endif
177
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;
182 CFNumberRef kzib;
183
184 kzib = CFNumberCreate(NULL, kCFNumberSInt64Type, &keySizeInBits);
185 CFMutableDictionaryRef kgp = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
186 CFDictionaryAddValue(kgp, kSecAttrKeyType, kSecAttrKeyTypeRSA);
187 CFDictionaryAddValue(kgp, kSecAttrKeySizeInBits, kzib);
188
189 OSStatus status;
190 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
191 "Generate %ld bit (%ld byte) RSA keypair", keySizeInBits,
192 keySizeInBytes);
193 CFRelease(kzib);
194 CFRelease(kgp);
195
196 SKIP: {
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");
202
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);
209 #if TARGET_OS_IPHONE
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");
214 #endif
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");
219
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,
230 };
231 #if TARGET_OS_IPHONE
232 /* Thoses tests are making sure that MD2 and MD5 are NOT supported,
233 but they still are on OS X */
234
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
242
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
251 #endif
252
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),
257 "sign sha1 digest");
258 ok_status(SecKeyRawVerify(pubKey, kSecPaddingPKCS1SHA1,
259 digest, CC_SHA1_DIGEST_LENGTH, sig, sigLen),
260 "verify sig on sha1 digest");
261
262 #if TARGET_OS_IPHONE
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");
270 #endif
271
272 #if TARGET_OS_IPHONE
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");
289 }
290
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");
300 }
301
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");
311 }
312
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");
322 }
323
324 test_encrypt_decrypt(pubKey, privKey, kSecPaddingNone, keySizeInBytes);
325 test_encrypt_decrypt(pubKey, privKey, kSecPaddingPKCS1, keySizeInBytes);
326 test_encrypt_decrypt(pubKey, privKey, kSecPaddingOAEP, keySizeInBytes);
327
328 testdigestandsign(privKey, pubKey);
329 #endif
330
331 const void *privkeys[] = {
332 kSecValueRef
333 };
334 const void *privvalues[] = {
335 privKey
336 };
337 CFDictionaryRef privitem = CFDictionaryCreate(NULL, privkeys, privvalues,
338 sizeof(privkeys) / sizeof(*privkeys), NULL, NULL);
339 #if TARGET_OS_IPHONE
340 /* OS X: keys are always added to the keychain when generated */
341 ok_status(SecItemAdd(privitem, NULL), "add private key"); //FAIL
342 #endif
343 ok_status(SecItemDelete(privitem), "delete private key");
344 CFReleaseNull(privitem);
345
346 const void *pubkeys[] = {
347 kSecValueRef
348 };
349 const void *pubvalues[] = {
350 pubKey
351 };
352 CFDictionaryRef pubitem = CFDictionaryCreate(NULL, pubkeys, pubvalues,
353 sizeof(pubkeys) / sizeof(*pubkeys), NULL, NULL);
354 #if TARGET_OS_IPHONE
355 /* OS X: keys are always added to the keychain when generated */
356 ok_status(SecItemAdd(pubitem, NULL), "add public key"); //FAIL
357 #endif
358 ok_status(SecItemDelete(pubitem), "delete public key");
359 CFReleaseNull(pubitem);
360
361 /* Cleanup. */
362 CFReleaseNull(pubKey);
363 CFReleaseNull(privKey);
364 }
365 }
366
367 #define kKeyGen2TestCount 11
368 static void testkeygen2(size_t keySizeInBits) {
369 SecKeyRef pubKey = NULL, privKey = NULL;
370 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
371 CFNumberRef kzib;
372
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);
377
378 CFReleaseNull(ourUUID);
379 CFReleaseNull(uuidString);
380
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);
385
386 CFDictionaryAddValue(pubd, kSecAttrLabel, publicName);
387 CFDictionaryAddValue(privd, kSecAttrLabel, privateName);
388
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);
396
397 OSStatus status;
398 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
399 "Generate %ld bit (%ld byte) persistent RSA keypair",
400 keySizeInBits, keySizeInBytes);
401 CFRelease(kzib);
402 CFRelease(kgp);
403
404 SKIP: {
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");
410
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");
421
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");
430
431 #if TARGET_OS_IPHONE
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");
437 #endif
438
439 /* Cleanup. */
440 CFReleaseNull(pubKey2);
441 CFReleaseNull(privKey2);
442
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");
447 }
448
449 /* Cleanup. */
450 CFReleaseNull(pubKey);
451 CFReleaseNull(privKey);
452
453 CFReleaseNull(publicName);
454 CFReleaseNull(privateName);
455
456 CFRelease(pubd);
457 CFRelease(privd);
458 }
459
460
461 #if !TARGET_OS_IPHONE
462 // Only exists currently in MacOSX
463 typedef struct KDFVector_t {
464 char *password;
465 char *salt;
466 int rounds;
467 int alg;
468 int dklen;
469 char *expectedstr;
470 int expected_failure;
471 } KDFVector;
472
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
479 };
480
481 static size_t kdfvLen = sizeof(kdfv) / sizeof(KDFVector);
482
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);
485 int retval = 0;
486
487 CFDictionaryAddValue(parameters, kSecAttrSalt, salt);
488 CFDictionaryAddValue(parameters, kSecAttrKeySizeInBits, dklen);
489 CFDictionaryAddValue(parameters, kSecAttrPRF, alg);
490 CFDictionaryAddValue(parameters, kSecAttrRounds, rounds);
491
492 SecKeyRef derivedKey = SecKeyDeriveFromPassword(password, parameters, NULL);
493 if(derivedKey == NULL && expected_failure) {
494 ok(1, "Correctly failed to produce a key");
495 goto errOut;
496 } else if(derivedKey == NULL) {
497 ok(0, "Could not generate a key when we should have");
498 goto errOut;
499 }
500 ok(1, "Made a new key");
501 retval = 1;
502 // NEEDS Fix -- ok(status = expectedEqualsComputed(expected, derivedKey), "Derived key is as expected");
503 errOut:
504 if(parameters) CFRelease(parameters);
505 if(derivedKey) CFRelease(derivedKey);
506 return retval;
507 }
508
509 static CFDataRef CFDataCreateFromHexBytes(char *s) {
510 if(!s) return NULL;
511 size_t len = strlen(s);
512 if(len%2) return NULL;
513 len /= 2;
514 uint8_t buf[len];
515 for(size_t i=0; i<len; i++) {
516 buf[i] = s[i*2] * 16 + s[i*2+1];
517 }
518 CFDataRef retval = CFDataCreate(NULL, buf, len);
519 return retval;
520 }
521
522
523 static int
524 PBKDF2Test(KDFVector *kdfvec)
525 {
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);
531 int status = 1;
532
533 ok(testSecKDF(password, salt, rounds, kSecAttrPRFHmacAlgSHA1, dklen, expectedBytes, kdfvec->expected_failure), "Test SecKeyDeriveFromPassword PBKDF2");
534
535 CFReleaseNull(expectedBytes);
536 CFReleaseNull(password);
537 CFReleaseNull(salt);
538 CFReleaseNull(rounds);
539 CFReleaseNull(dklen);
540
541 return status;
542 }
543
544
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");
549 }
550 }
551
552 #else
553 static size_t kdfvLen = 0; // no kdf functions in Sec for iphone
554 #endif /* !TARGET_OS_IPHONE */
555
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);
562 CFReleaseNull(*key);
563 }
564
565 static const int kTestSupportedCount = 3 + (4 * 12) + 2 + (4 * 10) + 2;
566 static void testsupportedalgos(size_t keySizeInBits)
567 {
568 SecKeyRef pubKey = NULL, privKey = NULL;
569 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
570 CFNumberRef kzib;
571
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);
577
578 OSStatus status;
579 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
580 "Generate %ld bit (%ld byte) persistent RSA keypair",
581 keySizeInBits, keySizeInBytes);
582 CFRelease(kzib);
583 CFRelease(kgp);
584
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");
587
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,
601 };
602
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);
615 }
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");
620
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,
633 };
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);
645 } else {
646 ok(SecKeyIsAlgorithmSupported(pubKey, kSecKeyOperationTypeDecrypt, algorithm),
647 "pubKey supports decrypt algorithm %@", algorithm);
648 }
649 CFReleaseNull(algorithm);
650 }
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);
655
656 /* Cleanup. */
657 delete_key(&pubKey);
658 delete_key(&privKey);
659 }
660
661 #if 0
662 #define kTestSupportedCount 15
663 static void testsupportedalgos(size_t keySizeInBits)
664 {
665 SecKeyRef pubKey = NULL, privKey = NULL;
666 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
667 CFNumberRef kzib;
668
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"));
675
676 OSStatus status;
677 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
678 "Generate %ld bit (%ld byte) persistent RSA keypair",
679 keySizeInBits, keySizeInBytes);
680 CFRelease(kzib);
681 CFRelease(kgp);
682
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");
685
686 CFSetRef keySet, expectedSet;
687
688 CFIndex value = kSecKeyAlgorithmECDSASignatureDigestX962;
689 CFNumberRef ECDSAX962 = CFNumberCreate(NULL, kCFNumberCFIndexType, &value);
690 value = kSecKeyAlgorithmRSAEncryptionRaw;
691 CFNumberRef RSARaw = CFNumberCreate(NULL, kCFNumberCFIndexType, &value);
692
693 { // privkey
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,
707 };
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);
713
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);
720
721 keySet = SecKeyCopySupportedAlgorithms(privKey, kSecKeyOperationTypeDecrypt);
722 const SecKeyAlgorithm decrypt[] = {
723 kSecKeyAlgorithmRSAEncryptionRaw,
724 kSecKeyAlgorithmRSAEncryptionPKCS1,
725 kSecKeyAlgorithmRSAEncryptionOAEPSHA1,
726 kSecKeyAlgorithmRSAEncryptionOAEPSHA224,
727 kSecKeyAlgorithmRSAEncryptionOAEPSHA256,
728 kSecKeyAlgorithmRSAEncryptionOAEPSHA384,
729 kSecKeyAlgorithmRSAEncryptionOAEPSHA512,
730 };
731 expectedSet = createAlgorithmSet(decrypt, array_size(decrypt));
732 ok(CFSetIsSubset(expectedSet, keySet), "privkey contains expecting algos for decryption");
733 CFReleaseNull(keySet);
734 CFReleaseNull(expectedSet);
735
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);
741 }
742
743 { // pubkey
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,
757 };
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);
766
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);
772
773 const SecKeyAlgorithm crypt[] = {
774 kSecKeyAlgorithmRSAEncryptionRaw,
775 kSecKeyAlgorithmRSAEncryptionPKCS1,
776 kSecKeyAlgorithmRSAEncryptionOAEPSHA1,
777 kSecKeyAlgorithmRSAEncryptionOAEPSHA224,
778 kSecKeyAlgorithmRSAEncryptionOAEPSHA256,
779 kSecKeyAlgorithmRSAEncryptionOAEPSHA384,
780 kSecKeyAlgorithmRSAEncryptionOAEPSHA512,
781 };
782 expectedSet = createAlgorithmSet(crypt, array_size(crypt));
783 keySet = SecKeyCopySupportedAlgorithms(pubKey, kSecKeyOperationTypeDecrypt);
784 #if TARGET_OS_IPHONE
785 ok(CFSetIsSubset(expectedSet, keySet), "pubkey contains expecting algos for decryption");
786 #else
787 ok(CFSetGetCount(keySet) == 0, "pubkey cannot decrypt");
788 #endif
789 CFReleaseNull(keySet);
790 CFReleaseNull(expectedSet);
791
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);
797 }
798
799 /* Cleanup. */
800 CFReleaseNull(RSARaw);
801 CFReleaseNull(ECDSAX962);
802 delete_key(&pubKey);
803 delete_key(&privKey);
804 }
805 #endif
806
807 #if !TARGET_OS_IPHONE
808 static inline bool CFEqualSafe(CFTypeRef left, CFTypeRef right)
809 {
810 if (left == NULL || right == NULL)
811 return left == right;
812 else
813 return CFEqual(left, right);
814 }
815 #endif
816
817 #define kCreateWithDataTestCount 13
818 static void testcreatewithdata(unsigned long keySizeInBits)
819 {
820 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
821 int32_t keysz32 = (int32_t)keySizeInBits;
822
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"));
830
831 SecKeyRef pubKey = NULL, privKey = NULL;
832 OSStatus status;
833 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
834 "Generate %ld bit (%ld byte) RSA keypair (status = %d)",
835 keySizeInBits, keySizeInBytes, (int)status);
836 CFReleaseNull(kgp);
837
838 CFMutableDictionaryRef kcwd = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks,
839 &kCFTypeDictionaryValueCallBacks);;
840 CFDictionarySetValue(kcwd, kSecAttrKeyType, kSecAttrKeyTypeRSA);
841 CFDictionarySetValue(kcwd, kSecAttrKeySizeInBits, kzib);
842 CFDictionarySetValue(kcwd, kSecAttrIsPermanent, kCFBooleanFalse);
843 CFReleaseNull(kzib);
844
845 CFErrorRef error = NULL;
846 CFDataRef privExternalData = NULL, pubExternalData = NULL;
847 SecKeyRef dataKey = NULL;
848
849 { // privKey
850 privExternalData = SecKeyCopyExternalRepresentation(privKey, &error);
851 ok(privExternalData && CFGetTypeID(privExternalData) == CFDataGetTypeID(),
852 "priv key SecKeyCopyExternalRepresentation failed");
853 CFReleaseNull(error);
854
855 SKIP: {
856 skip("invalid priv key external data", 4, privExternalData);
857
858 CFDictionarySetValue(kcwd, kSecAttrKeyClass, kSecAttrKeyClassPrivate);
859 dataKey = SecKeyCreateWithData(privExternalData, kcwd, &error);
860 ok(dataKey, "priv key SecKeyCreateWithData failed");
861 CFReleaseNull(error);
862
863 CFDataRef external = SecKeyCopyExternalRepresentation(dataKey, NULL);
864 eq_cf(privExternalData, external, "priv keys differ");
865 CFReleaseNull(external);
866 CFReleaseNull(dataKey);
867
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);
873
874 CFMutableDataRef modifiedExternalData = CFDataCreateMutableCopy(kCFAllocatorDefault, 0, privExternalData);
875 *CFDataGetMutableBytePtr(modifiedExternalData) ^= 0xff;
876
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);
882
883 CFReleaseNull(modifiedExternalData);
884 }
885 }
886
887 { // pubKey
888 pubExternalData = SecKeyCopyExternalRepresentation(pubKey, &error);
889 ok(pubExternalData && CFGetTypeID(pubExternalData) == CFDataGetTypeID(),
890 "pub key SecKeyCopyExternalRepresentation failed");
891 CFReleaseNull(error);
892
893 SKIP: {
894 skip("invalid pub key external data", 4, pubExternalData);
895
896 CFDictionarySetValue(kcwd, kSecAttrKeyClass, kSecAttrKeyClassPublic);
897 dataKey = SecKeyCreateWithData(pubExternalData, kcwd, &error);
898 ok(dataKey, "pub key SecKeyCreateWithData failed");
899 CFReleaseNull(error);
900
901 CFDataRef external = SecKeyCopyExternalRepresentation(dataKey, NULL);
902 eq_cf(pubExternalData, external, "pub keys differ");
903 CFReleaseNull(external);
904 CFReleaseNull(dataKey);
905
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);
911
912 CFMutableDataRef modifiedExternalData = CFDataCreateMutableCopy(kCFAllocatorDefault, 0, pubExternalData);
913 *CFDataGetMutableBytePtr(modifiedExternalData) ^= 0xff;
914
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);
920
921 CFReleaseNull(modifiedExternalData);
922 }
923 }
924
925 SKIP: {
926 skip("invalid pub key external data", 1, pubExternalData);
927
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);
933
934 CFReleaseNull(pubExternalData);
935 }
936
937 SKIP: {
938 skip("invalid priv key external data", 1, privExternalData);
939
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);
945
946 CFReleaseNull(privExternalData);
947 }
948
949 CFReleaseNull(kcwd);
950 delete_key(&pubKey);
951 delete_key(&privKey);
952 }
953
954 #define kCopyAttributesTestCount 20
955 static void testcopyattributes(unsigned long keySizeInBits, bool extractable)
956 {
957 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
958 int32_t keysz32 = (int32_t)keySizeInBits;
959
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;
968 OSStatus status;
969 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
970 "Generate %ld bit (%ld byte) RSA keypair (status = %d)",
971 keySizeInBits, keySizeInBytes, (int)status);
972 CFReleaseNull(kgp);
973
974 CFDictionaryRef attributes;
975 CFTypeRef attrValue = NULL, privAppLabel = NULL, pubAppLabel = NULL;
976
977 { // privKey
978 attributes = SecKeyCopyAttributes(privKey);
979 ok(attributes && CFGetTypeID(attributes) == CFDictionaryGetTypeID(),
980 "priv key SecKeyCopyAttributes failed");
981
982 SKIP: {
983 skip("invalid attributes", 8, attributes);
984
985 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanEncrypt);
986 eq_cf(attrValue, kCFBooleanFalse, "invalid priv key kSecAttrCanEncrypt");
987
988 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanDecrypt);
989 eq_cf(attrValue, kCFBooleanTrue, "invalid priv key kSecAttrCanDecrypt");
990
991 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanDerive);
992 eq_cf(attrValue, kCFBooleanTrue, "invalid priv key kSecAttrCanDerive");
993
994 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanSign);
995 eq_cf(attrValue, kCFBooleanTrue, "invalid priv key kSecAttrCanSign");
996
997 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanVerify);
998 eq_cf(attrValue, kCFBooleanFalse, "invalid priv key kSecAttrCanVerify");
999
1000 attrValue = CFDictionaryGetValue(attributes, kSecAttrKeyClass);
1001 eq_cf(attrValue, kSecAttrKeyClassPrivate, "priv key invalid kSecAttrKeyClass");
1002
1003 attrValue = CFDictionaryGetValue(attributes, kSecAttrKeyType);
1004 eq_cf(attrValue, kSecAttrKeyTypeRSA, "invalid priv key kSecAttrKeyType");
1005
1006 attrValue = CFDictionaryGetValue(attributes, kSecAttrKeySizeInBits);
1007 eq_cf(attrValue, kzib, "invalid priv key kSecAttrKeySizeInBits");
1008
1009 privAppLabel = CFDictionaryGetValue(attributes, kSecAttrApplicationLabel);
1010 CFRetainSafe(privAppLabel);
1011
1012 CFReleaseNull(attributes);
1013 }
1014 }
1015
1016 { // pubKey
1017 attributes = SecKeyCopyAttributes(pubKey);
1018 ok(attributes && CFGetTypeID(attributes) == CFDictionaryGetTypeID(),
1019 "pub key SecKeyCopyAttributes failed");
1020
1021 SKIP: {
1022 skip("invalid attributes", 8, attributes);
1023
1024 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanEncrypt);
1025 eq_cf(attrValue, kCFBooleanTrue, "pub key invalid kSecAttrCanEncrypt");
1026
1027 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanDecrypt);
1028 eq_cf(attrValue, kCFBooleanFalse, "pub key invalid kSecAttrCanDecrypt");
1029
1030 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanDerive);
1031 eq_cf(attrValue, kCFBooleanTrue, "pub key invalid kSecAttrCanDerive");
1032
1033 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanSign);
1034 eq_cf(attrValue, kCFBooleanFalse, "pub key invalid kSecAttrCanSign");
1035
1036 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanVerify);
1037 eq_cf(attrValue, kCFBooleanTrue, "pub key invalid kSecAttrCanVerify");
1038
1039 attrValue = CFDictionaryGetValue(attributes, kSecAttrKeyClass);
1040 eq_cf(attrValue, kSecAttrKeyClassPublic, "pub key invalid kSecAttrKeyClass");
1041
1042 attrValue = CFDictionaryGetValue(attributes, kSecAttrKeyType);
1043 eq_cf(attrValue, kSecAttrKeyTypeRSA, "pub key invalid kSecAttrKeyType");
1044
1045 attrValue = CFDictionaryGetValue(attributes, kSecAttrKeySizeInBits);
1046 eq_cf(attrValue, kzib, "pub key invalid kSecAttrKeySizeInBits");
1047
1048 pubAppLabel = CFDictionaryGetValue(attributes, kSecAttrApplicationLabel);
1049 CFRetainSafe(pubAppLabel);
1050
1051 CFReleaseNull(attributes);
1052 }
1053 }
1054
1055 eq_cf(privAppLabel, pubAppLabel, "priv key and pub key kSecAttrApplicationLabel differ");
1056
1057 CFReleaseNull(privAppLabel);
1058 CFReleaseNull(pubAppLabel);
1059 CFReleaseNull(kzib);
1060 delete_key(&pubKey);
1061 delete_key(&privKey);
1062 }
1063
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;
1068
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;
1078 OSStatus status;
1079 if (permanent) {
1080 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
1081 "Generate %ld bit (%ld byte) RSA keypair (status = %d)",
1082 keySizeInBits, keySizeInBytes, (int)status);
1083 } else {
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);
1089 }
1090 CFReleaseNull(kgp);
1091 CFReleaseNull(kzib);
1092
1093 CFDataRef pubKeyData = SecKeyCopyExternalRepresentation(pubKey, NULL);
1094
1095 SecKeyRef pubKeyCopy = NULL;
1096
1097 { // privKey
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);
1104 }
1105
1106 { // pubKey
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);
1113 }
1114
1115 CFReleaseNull(pubKeyData);
1116 if (permanent) {
1117 delete_key(&pubKey);
1118 delete_key(&privKey);
1119 } else {
1120 CFReleaseSafe(pubKey);
1121 CFReleaseSafe(privKey);
1122 }
1123 }
1124
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";
1144
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";
1151
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(pubKey = SecCertificateCopyKey(cert), "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);
1165 }
1166
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);
1170
1171 ccdigest(di, length, buffer, CFDataGetMutableBytePtr(result));
1172
1173 return result;
1174 }
1175
1176 #define kSignAndVerifyTestCount 130
1177 static void testsignverify(unsigned long keySizeInBits)
1178 {
1179 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
1180 int32_t keysz32 = (int32_t)keySizeInBits;
1181
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;
1190 OSStatus status;
1191 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
1192 "Generate %ld bit (%ld byte) RSA keypair (status = %d)",
1193 keySizeInBits, keySizeInBytes, (int)status);
1194 CFReleaseNull(kgp);
1195 CFReleaseNull(kzib);
1196
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");
1203
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");
1210
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,
1223 };
1224
1225 CFDataRef testData = CFStringCreateExternalRepresentation(kCFAllocatorDefault, CFSTR("test"), kCFStringEncodingUTF8, 0);
1226 ok(testData, "creating test data failed");
1227
1228 SKIP: {
1229 skip("invalid test data", 71, testData);
1230
1231 CFErrorRef error = NULL;
1232
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;
1237
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);
1243 }
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);
1248 }
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);
1253 }
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);
1258 }
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);
1263 }
1264 else {
1265 CFRetainAssign(dataToSign, testData);
1266 }
1267 CFReleaseNull(error);
1268
1269 SKIP: {
1270 skip("invalid data to sign", 7, dataToSign);
1271
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);
1276
1277 signature = SecKeyCreateSignature(privKey, algorithm, dataToSign, &error);
1278 ok(signature, "SecKeyCopySignature failed for algorithm %@", algorithm);
1279 CFReleaseNull(error);
1280
1281 CFDataRef iosSignature = SecKeyCreateSignature(privKeyIOS, algorithm, dataToSign, &error);
1282 ok(iosSignature, "SecKeyCopySignature(ios) failed for algorithm %@", algorithm);
1283 CFReleaseNull(error);
1284
1285 SKIP: {
1286 skip("invalid signature", 4, signature);
1287
1288 ok(!SecKeyVerifySignature(privKey, algorithm, dataToSign, signature, &error),
1289 "SecKeyVerifySignature succeeded with priv key for algorithm %@", algorithm);
1290 CFReleaseNull(error);
1291
1292 ok(!SecKeyVerifySignature(pubKey, incompatibleAlgorithm, dataToSign, signature, &error),
1293 "SecKeyVerifySignature succeeded with wrong algorithm for algorithm %@", algorithm);
1294 CFReleaseNull(error);
1295
1296 ok(SecKeyVerifySignature(pubKey, algorithm, dataToSign, signature, &error),
1297 "SecKeyVerifySignature(osx) failed osx-signature for algorithm %@", algorithm);
1298 CFReleaseNull(error);
1299
1300 ok(SecKeyVerifySignature(pubKeyIOS, algorithm, dataToSign, signature, &error),
1301 "SecKeyVerifySignature(ios) failed for osx-signature for algorithm %@", algorithm);
1302
1303 ok(SecKeyVerifySignature(pubKey, algorithm, dataToSign, iosSignature, &error),
1304 "SecKeyVerifySignature(osx) failed for ios-signature for algorithm %@", algorithm);
1305 CFReleaseNull(error);
1306
1307 ok(SecKeyVerifySignature(pubKeyIOS, algorithm, dataToSign, iosSignature, &error),
1308 "SecKeyVerifySignature(ios) failed for ios-signature for algorithm %@", algorithm);
1309
1310 CFMutableDataRef modifiedSignature = CFDataCreateMutableCopy(kCFAllocatorDefault, 0, signature);
1311 *CFDataGetMutableBytePtr(modifiedSignature) ^= 0xff;
1312
1313 ok(!SecKeyVerifySignature(pubKey, algorithm, dataToSign, modifiedSignature, &error),
1314 "SecKeyVerifySignature succeeded with bad signature for algorithm %@", algorithm);
1315 CFReleaseNull(error);
1316
1317 CFMutableDataRef modifiedDataToSign = CFDataCreateMutableCopy(kCFAllocatorDefault, 0, dataToSign);
1318 *CFDataGetMutableBytePtr(modifiedDataToSign) ^= 0xff;
1319
1320 ok(!SecKeyVerifySignature(pubKey, algorithm, modifiedDataToSign, signature, &error),
1321 "SecKeyVerifySignature succeeded with bad data for algorithm %@", algorithm);
1322 CFReleaseNull(error);
1323
1324 CFReleaseNull(modifiedDataToSign);
1325 CFReleaseNull(modifiedSignature);
1326 CFReleaseNull(signature);
1327 CFReleaseNull(iosSignature);
1328 }
1329 CFReleaseNull(dataToSign);
1330 }
1331 }
1332 CFReleaseNull(testData);
1333 }
1334
1335 delete_key(&pubKey);
1336 delete_key(&privKey);
1337 CFReleaseNull(pubKeyIOS);
1338 CFReleaseNull(privKeyIOS);
1339 }
1340
1341 #define kNonExtractableTestCount 6
1342 static void testnonextractable(unsigned long keySizeInBits)
1343 {
1344 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
1345 int32_t keysz32 = (int32_t)keySizeInBits;
1346
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;
1357 OSStatus status;
1358 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
1359 "Generate %ld bit (%ld byte) RSA keypair (status = %d)",
1360 keySizeInBits, keySizeInBytes, (int)status);
1361 CFReleaseNull(kgp);
1362 CFReleaseNull(kzib);
1363
1364 // Get attributes, verify that ApplicationLabel is set and equals for both keys.
1365 CFDictionaryRef privAttrs = SecKeyCopyAttributes(privKey);
1366 CFDictionaryRef pubAttrs = SecKeyCopyAttributes(pubKey);
1367
1368 ok(privAttrs, "able to get private key attributes");
1369 ok(pubAttrs, "able to get public key attributes");
1370
1371 CFDataRef privLabel = CFDictionaryGetValue(privAttrs, kSecAttrApplicationLabel);
1372 CFDataRef pubLabel = CFDictionaryGetValue(pubAttrs, kSecAttrApplicationLabel);
1373
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");
1379
1380 CFReleaseNull(pubAttrs);
1381 CFReleaseNull(privAttrs);
1382
1383 delete_key(&pubKey);
1384 delete_key(&privKey);
1385 }
1386
1387 #define kTestCount ((2 * kKeyGenTestCount) + kKeyGen2TestCount + (int) (kdfvLen*3)) + \
1388 kTestSupportedCount + kCreateWithDataTestCount + (kCopyAttributesTestCount * 2) + (kCopyPublicKeyTestCount * 4) + \
1389 kSignAndVerifyTestCount + kNonExtractableTestCount + \
1390 kTestCountCopyPubKFromCert
1391
1392 static void tests(void)
1393 {
1394 /* Comment out lines below for testing generating all common key sizes,
1395 disabled now for speed reasons. */
1396 //testkeygen(512);
1397 //testkeygen(768);
1398 testkeygen(1024);
1399 testkeygen(2056); // Stranged sized for edge cases in padding.
1400 //testkeygen(2048);
1401 //testkeygen(4096);
1402
1403 testkeygen2(1024); // lots of FAIL!
1404
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);
1415
1416 #if !TARGET_OS_IPHONE
1417 testkeyderivation();
1418 #endif
1419
1420 testcopypubkfromcert();
1421 }
1422
1423 int kc_40_seckey(int argc, char *const *argv)
1424 {
1425 plan_tests(kTestCount);
1426
1427 tests();
1428
1429 return 0;
1430 }