]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_keychain/regressions/kc-40-seckey.m
Security-57740.1.18.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 sig[0] ^= 0xff;
73 is_status(SecKeyDigestAndVerify(pubKey, algId, dataToDigest, dataToDigestLen,
74 sig, sigLen), errSSLCrypto, "digest and verify bad sig");
75 sig[0] ^= 0xff;
76 dataToDigest[0] ^= 0xff;
77 is_status(SecKeyDigestAndVerify(pubKey, algId, dataToDigest, dataToDigestLen,
78 sig, sigLen), errSSLCrypto, "digest and verify bad digest");
79 }
80 }
81
82 static void testdigestandsign(SecKeyRef privKey, SecKeyRef pubKey) {
83 static const SecAsn1Oid *oids[] = {
84 &CSSMOID_SHA1WithRSA,
85 &CSSMOID_SHA224WithRSA,
86 &CSSMOID_SHA256WithRSA,
87 &CSSMOID_SHA384WithRSA,
88 &CSSMOID_SHA512WithRSA,
89 #if 0
90 &CSSMOID_SHA1WithRSA_OIW,
91 &CSSMOID_SHA1WithDSA, // BSAFE
92 &CSSMOID_SHA1WithDSA_CMS, // X509/CMS
93 &CSSMOID_SHA1WithDSA_JDK, // JDK 1.1
94 #endif
95 };
96
97
98 uint32_t ix;
99 SecAsn1AlgId algId = {};
100 for (ix = 0; ix < sizeof(oids) / sizeof(*oids); ++ix) {
101 if (oids[ix]) {
102 algId.algorithm = *oids[ix];
103 } else {
104 algId.algorithm.Length = 0;
105 algId.algorithm.Data = NULL;
106 }
107
108 testdigestandsignalg(privKey, pubKey, &algId);
109 }
110 }
111 #endif
112
113 #if 0
114 static void dump_bytes(uint8_t* bytes, size_t amount)
115 {
116 while (amount > 0) {
117 printf("0x%02x ", *bytes);
118 ++bytes;
119 --amount;
120 }
121 }
122 #endif
123
124
125 #if !TARGET_OS_IPHONE
126 #define kEncryptDecryptTestCount 0
127 #else
128 #define kEncryptDecryptTestCount 6
129 static void test_encrypt_decrypt(SecKeyRef pubKey, SecKeyRef privKey, uint32_t padding, size_t keySizeInBytes)
130 {
131 SKIP: {
132 size_t max_len = keySizeInBytes;
133 switch (padding) {
134 case kSecPaddingNone: max_len = keySizeInBytes; break;
135 case kSecPaddingOAEP: max_len = keySizeInBytes - 2 - 2 * CC_SHA1_DIGEST_LENGTH; break;
136 case kSecPaddingPKCS1: max_len = keySizeInBytes - 11; break;
137 default: skip("what is the max_len for this padding?", 5, false);
138 }
139
140 uint8_t secret[max_len + 1], encrypted_secret[keySizeInBytes], decrypted_secret[keySizeInBytes];
141 uint8_t *secret_ptr = secret;
142 size_t secret_len = max_len;
143 size_t encrypted_secret_len = sizeof(encrypted_secret);
144 size_t decrypted_secret_len = sizeof(decrypted_secret);
145 memset(decrypted_secret, 0xff, decrypted_secret_len);
146 ok_status(SecRandomCopyBytes(kSecRandomDefault, sizeof(secret), secret),"rng");
147
148 // zero pad, no accidental second zero byte
149 if (padding == kSecPaddingNone) {
150 secret[0] = 0;
151 secret[1] = 128;
152 }
153
154 is_status(SecKeyEncrypt(pubKey, padding,
155 secret, sizeof(secret),
156 encrypted_secret, &encrypted_secret_len), errSecParam, "encrypt secret (overflow)");
157 ok_status(SecKeyEncrypt(pubKey, padding,
158 secret, secret_len,
159 encrypted_secret, &encrypted_secret_len), "encrypt secret");
160
161 ok_status(SecKeyDecrypt(privKey, padding,
162 encrypted_secret, encrypted_secret_len,
163 decrypted_secret, &decrypted_secret_len), "decrypt secret");
164
165 // zero padding is removed on decode
166 if (padding == kSecPaddingNone) {
167 secret_len--;
168 secret_ptr++;
169 }
170
171 ok(decrypted_secret_len == secret_len, "correct length");
172 ok_status(memcmp(secret_ptr, decrypted_secret, secret_len), "verify secret");
173 }
174 }
175 #endif
176
177 #define kKeyGenTestCount (12 + (3*kEncryptDecryptTestCount))
178 static void testkeygen(size_t keySizeInBits) {
179 SecKeyRef pubKey = NULL, privKey = NULL;
180 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
181 CFNumberRef kzib;
182
183 kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &keySizeInBits);
184 CFMutableDictionaryRef kgp = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
185 CFDictionaryAddValue(kgp, kSecAttrKeyType, kSecAttrKeyTypeRSA);
186 CFDictionaryAddValue(kgp, kSecAttrKeySizeInBits, kzib);
187
188 OSStatus status;
189 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
190 "Generate %ld bit (%ld byte) RSA keypair", keySizeInBits,
191 keySizeInBytes);
192 CFRelease(kzib);
193 CFRelease(kgp);
194
195 SKIP: {
196 skip("keygen failed", 8, status == errSecSuccess);
197 ok(pubKey, "pubkey returned");
198 ok(privKey, "privKey returned");
199 is(SecKeyGetBlockSize(pubKey) * 8, (size_t) keySizeInBits, "public key size is ok");
200 is(SecKeyGetBlockSize(privKey) * 8, (size_t) keySizeInBits, "private key size is ok");
201
202 /* Sign something. */
203 uint8_t something[keySizeInBytes];
204 size_t something_len = keySizeInBytes - 11;
205 ok_status(SecRandomCopyBytes(kSecRandomDefault, sizeof(something), something), "rng");
206 uint8_t sig[keySizeInBytes];
207 size_t sigLen = sizeof(sig);
208 #if TARGET_OS_IPHONE
209 /* TODO: This is returning another error on OS X */
210 is_status(SecKeyRawSign(privKey, kSecPaddingPKCS1,
211 something, something_len + 1, sig, &sigLen),
212 errSecParam, "sign overflow");
213 #endif
214 ok_status(SecKeyRawSign(privKey, kSecPaddingPKCS1,
215 something, something_len, sig, &sigLen), "sign something");
216 ok_status(SecKeyRawVerify(pubKey, kSecPaddingPKCS1,
217 something, something_len, sig, sigLen), "verify sig on something");
218
219 // Torture test ASN.1 encoder by setting high bit to 1.
220 uint8_t digest[CC_SHA512_DIGEST_LENGTH] = {
221 0x80, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
222 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
223 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
224 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
225 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
226 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
227 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
228 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
229 };
230 #if TARGET_OS_IPHONE
231 /* Thoses tests are making sure that MD2 and MD5 are NOT supported,
232 but they still are on OS X */
233
234 //CC_MD2(something, sizeof(something), digest);
235 ok_status(!SecKeyRawSign(privKey, kSecPaddingPKCS1MD2,
236 digest, CC_MD2_DIGEST_LENGTH, sig, &sigLen),
237 "don't sign md2 digest"); //FAIL
238 ok_status(!SecKeyRawVerify(pubKey, kSecPaddingPKCS1MD2,
239 digest, CC_MD2_DIGEST_LENGTH, sig, sigLen),
240 "verify sig on md2 digest fails"); //FAIL
241
242 //CC_MD5(something, sizeof(something), digest);
243 sigLen = sizeof(sig);
244 ok_status(!SecKeyRawSign(privKey, kSecPaddingPKCS1MD5,
245 digest, CC_MD5_DIGEST_LENGTH, sig, &sigLen),
246 "don't sign md5 digest"); //FAIL
247 ok_status(!SecKeyRawVerify(pubKey, kSecPaddingPKCS1MD5,
248 digest, CC_MD5_DIGEST_LENGTH, sig, sigLen),
249 "verify sig on md5 digest fails"); //FAIL
250 #endif
251
252 //CCDigest(kCCDigestSHA1, something, sizeof(something), digest);
253 sigLen = sizeof(sig);
254 ok_status(SecKeyRawSign(privKey, kSecPaddingPKCS1SHA1,
255 digest, CC_SHA1_DIGEST_LENGTH, sig, &sigLen),
256 "sign sha1 digest");
257 ok_status(SecKeyRawVerify(pubKey, kSecPaddingPKCS1SHA1,
258 digest, CC_SHA1_DIGEST_LENGTH, sig, sigLen),
259 "verify sig on sha1 digest");
260
261 #if TARGET_OS_IPHONE
262 /* The assumptions in these tests are just wrong on OS X */
263 uint8_t signature[keySizeInBytes], *ptr = signature;
264 size_t signature_len = sizeof(signature);
265 ok_status(SecKeyEncrypt(pubKey, kSecPaddingNone, sig, sigLen, signature, &signature_len), "inspect signature");
266 is(signature_len, keySizeInBytes - 1, "got signature"); // FAIL for 2056
267 while(*ptr && ((size_t)(ptr - signature) < signature_len)) ptr++;
268 is(signature + signature_len - ptr, 16 /* length(\0 || OID_SHA1) */ + CC_SHA1_DIGEST_LENGTH, "successful decode");
269 #endif
270
271 #if TARGET_OS_IPHONE
272 /* Those are not supported on OS X */
273 /* PKCS1 padding is 00 01 PAD * 8 or more 00 data.
274 data is SEQ { SEQ { OID NULL } BIT STRING 00 DIGEST }
275 So min data + pad overhead is 11 + 9 + oidlen
276 oidlen = 11 for the sha2 family of oids, so we have 29 bytes; or
277 232 bits of minimum overhead. */
278 const size_t pkcs1Overhead = 232;
279 if (keySizeInBits > 224 + pkcs1Overhead) {
280 //CC_SHA224(something, sizeof(something), digest);
281 sigLen = sizeof(sig);
282 ok_status(SecKeyRawSign(privKey, kSecPaddingPKCS1SHA224,
283 digest, CC_SHA224_DIGEST_LENGTH, sig, &sigLen),
284 "sign sha224 digest");
285 ok_status(SecKeyRawVerify(pubKey, kSecPaddingPKCS1SHA224,
286 digest, CC_SHA224_DIGEST_LENGTH, sig, sigLen),
287 "verify sig on sha224 digest");
288 }
289
290 if (keySizeInBits > 256 + pkcs1Overhead) {
291 //CC_SHA256(something, sizeof(something), digest);
292 sigLen = sizeof(sig);
293 ok_status(SecKeyRawSign(privKey, kSecPaddingPKCS1SHA256,
294 digest, CC_SHA256_DIGEST_LENGTH, sig, &sigLen),
295 "sign sha256 digest");
296 ok_status(SecKeyRawVerify(pubKey, kSecPaddingPKCS1SHA256,
297 digest, CC_SHA256_DIGEST_LENGTH, sig, sigLen),
298 "verify sig on sha256 digest");
299 }
300
301 if (keySizeInBits > 384 + pkcs1Overhead) {
302 //CC_SHA384(something, sizeof(something), digest);
303 sigLen = sizeof(sig);
304 ok_status(SecKeyRawSign(privKey, kSecPaddingPKCS1SHA384,
305 digest, CC_SHA384_DIGEST_LENGTH, sig, &sigLen),
306 "sign sha384 digest");
307 ok_status(SecKeyRawVerify(pubKey, kSecPaddingPKCS1SHA384,
308 digest, CC_SHA384_DIGEST_LENGTH, sig, sigLen),
309 "verify sig on sha384 digest");
310 }
311
312 if (keySizeInBits > 512 + pkcs1Overhead) {
313 //CC_SHA512(something, sizeof(something), digest);
314 sigLen = sizeof(sig);
315 ok_status(SecKeyRawSign(privKey, kSecPaddingPKCS1SHA512,
316 digest, CC_SHA512_DIGEST_LENGTH, sig, &sigLen),
317 "sign sha512 digest");
318 ok_status(SecKeyRawVerify(pubKey, kSecPaddingPKCS1SHA512,
319 digest, CC_SHA512_DIGEST_LENGTH, sig, sigLen),
320 "verify sig on sha512 digest");
321 }
322
323 test_encrypt_decrypt(pubKey, privKey, kSecPaddingNone, keySizeInBytes);
324 test_encrypt_decrypt(pubKey, privKey, kSecPaddingPKCS1, keySizeInBytes);
325 test_encrypt_decrypt(pubKey, privKey, kSecPaddingOAEP, keySizeInBytes);
326
327 testdigestandsign(privKey, pubKey);
328 #endif
329
330 const void *privkeys[] = {
331 kSecValueRef
332 };
333 const void *privvalues[] = {
334 privKey
335 };
336 CFDictionaryRef privitem = CFDictionaryCreate(NULL, privkeys, privvalues,
337 sizeof(privkeys) / sizeof(*privkeys), NULL, NULL);
338 #if TARGET_OS_IPHONE
339 /* OS X: keys are always added to the keychain when generated */
340 ok_status(SecItemAdd(privitem, NULL), "add private key"); //FAIL
341 #endif
342 ok_status(SecItemDelete(privitem), "delete private key");
343 CFReleaseNull(privitem);
344
345 const void *pubkeys[] = {
346 kSecValueRef
347 };
348 const void *pubvalues[] = {
349 pubKey
350 };
351 CFDictionaryRef pubitem = CFDictionaryCreate(NULL, pubkeys, pubvalues,
352 sizeof(pubkeys) / sizeof(*pubkeys), NULL, NULL);
353 #if TARGET_OS_IPHONE
354 /* OS X: keys are always added to the keychain when generated */
355 ok_status(SecItemAdd(pubitem, NULL), "add public key"); //FAIL
356 #endif
357 ok_status(SecItemDelete(pubitem), "delete public key");
358 CFReleaseNull(pubitem);
359
360 /* Cleanup. */
361 CFReleaseNull(pubKey);
362 CFReleaseNull(privKey);
363 }
364 }
365
366 #define kKeyGen2TestCount 11
367 static void testkeygen2(size_t keySizeInBits) {
368 SecKeyRef pubKey = NULL, privKey = NULL;
369 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
370 CFNumberRef kzib;
371
372 CFUUIDRef ourUUID = CFUUIDCreate(kCFAllocatorDefault);
373 CFStringRef uuidString = CFUUIDCreateString(kCFAllocatorDefault, ourUUID);
374 CFMutableStringRef publicName = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, uuidString);
375 CFMutableStringRef privateName = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, uuidString);
376
377 CFReleaseNull(ourUUID);
378 CFReleaseNull(uuidString);
379
380 CFStringAppend(publicName, CFSTR("-Public-40"));
381 CFStringAppend(privateName, CFSTR("-Private-40"));
382 CFMutableDictionaryRef pubd = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
383 CFMutableDictionaryRef privd = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
384
385 CFDictionaryAddValue(pubd, kSecAttrLabel, publicName);
386 CFDictionaryAddValue(privd, kSecAttrLabel, privateName);
387
388 kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &keySizeInBits);
389 CFMutableDictionaryRef kgp = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
390 CFDictionaryAddValue(kgp, kSecAttrKeyType, kSecAttrKeyTypeRSA);
391 CFDictionaryAddValue(kgp, kSecAttrKeySizeInBits, kzib);
392 CFDictionaryAddValue(kgp, kSecAttrIsPermanent, kCFBooleanTrue);
393 CFDictionaryAddValue(kgp, kSecPublicKeyAttrs, pubd);
394 CFDictionaryAddValue(kgp, kSecPrivateKeyAttrs, privd);
395
396 OSStatus status;
397 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
398 "Generate %ld bit (%ld byte) persistent RSA keypair",
399 keySizeInBits, keySizeInBytes);
400 CFRelease(kzib);
401 CFRelease(kgp);
402
403 SKIP: {
404 skip("keygen failed", 8, status == errSecSuccess);
405 ok(pubKey, "pubkey returned");
406 ok(privKey, "privKey returned");
407 is(SecKeyGetBlockSize(pubKey) * 8, (size_t) keySizeInBits, "public key size is ok");
408 is(SecKeyGetBlockSize(privKey) * 8, (size_t) keySizeInBits, "private key size is ok");
409
410 SecKeyRef pubKey2, privKey2;
411 CFDictionaryAddValue(pubd, kSecClass, kSecClassKey);
412 CFDictionaryAddValue(pubd, kSecReturnRef, kCFBooleanTrue);
413 CFDictionaryAddValue(privd, kSecClass, kSecClassKey);
414 CFDictionaryAddValue(privd, kSecReturnRef, kCFBooleanTrue);
415 CFDictionaryAddValue(privd, kSecAttrCanSign, kCFBooleanTrue);
416 ok_status(SecItemCopyMatching(pubd, (CFTypeRef *)&pubKey2),
417 "retrieve pub key by label");
418 ok_status(SecItemCopyMatching(privd, (CFTypeRef *)&privKey2),
419 "retrieve priv key by label and kSecAttrCanSign");
420
421 /* Sign something. */
422 uint8_t something[50] = {0x80, 0xbe, 0xef, 0xba, 0xd0, };
423 uint8_t sig[keySizeInBytes];
424 size_t sigLen = keySizeInBytes;
425 ok_status(SecKeyRawSign(privKey2, kSecPaddingPKCS1,
426 something, sizeof(something), sig, &sigLen), "sign something");
427 ok_status(SecKeyRawVerify(pubKey2, kSecPaddingPKCS1,
428 something, sizeof(something), sig, sigLen), "verify sig on something");
429
430 #if TARGET_OS_IPHONE
431 /* SecKeyEncrypt does not return errSecParam on OS X in that case */
432 sigLen = keySizeInBytes;
433 is_status(SecKeyEncrypt(pubKey2, kSecPaddingPKCS1SHA1,
434 something, sizeof(something), sig, &sigLen), errSecParam,
435 "encrypt something with invalid padding");
436 #endif
437
438 /* Cleanup. */
439 CFReleaseNull(pubKey2);
440 CFReleaseNull(privKey2);
441
442 /* delete from keychain - note: do it before releasing publicName and privateName
443 because pubd and privd have no retain/release callbacks */
444 ok_status(SecItemDelete(pubd), "delete generated pub key");
445 ok_status(SecItemDelete(privd), "delete generated priv key");
446 }
447
448 /* Cleanup. */
449 CFReleaseNull(pubKey);
450 CFReleaseNull(privKey);
451
452 CFReleaseNull(publicName);
453 CFReleaseNull(privateName);
454
455 CFRelease(pubd);
456 CFRelease(privd);
457 }
458
459
460 #if !TARGET_OS_IPHONE
461 // Only exists currently in MacOSX
462 typedef struct KDFVector_t {
463 char *password;
464 char *salt;
465 int rounds;
466 int alg;
467 int dklen;
468 char *expectedstr;
469 int expected_failure;
470 } KDFVector;
471
472 static KDFVector kdfv[] = {
473 // Test Case PBKDF2 - HMACSHA1 http://tools.ietf.org/html/draft-josefsson-pbkdf2-test-vectors-00
474 { "password", "salt", 1, 1, 160, "0c60c80f961f0e71f3a9b524af6012062fe037a6", 0 },
475 { "password", "salt", 2, 1, 160, "ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957", 0 },
476 { "password", "salt", 4096, 1, 160, "4b007901b765489abead49d926f721d065a429c1", 0 },
477 { "password", "salt", 1, 0, 160, NULL, -1} // This crashed
478 };
479
480 static size_t kdfvLen = sizeof(kdfv) / sizeof(KDFVector);
481
482 static int testSecKDF(CFStringRef password, CFDataRef salt, CFNumberRef rounds, CFStringRef alg, CFNumberRef dklen, CFDataRef expected, int expected_failure) {
483 CFMutableDictionaryRef parameters = CFDictionaryCreateMutable(kCFAllocatorDefault, 4, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
484 int retval = 0;
485
486 CFDictionaryAddValue(parameters, kSecAttrSalt, salt);
487 CFDictionaryAddValue(parameters, kSecAttrKeySizeInBits, dklen);
488 CFDictionaryAddValue(parameters, kSecAttrPRF, alg);
489 CFDictionaryAddValue(parameters, kSecAttrRounds, rounds);
490
491 SecKeyRef derivedKey = SecKeyDeriveFromPassword(password, parameters, NULL);
492 if(derivedKey == NULL && expected_failure) {
493 ok(1, "Correctly failed to produce a key");
494 goto errOut;
495 } else if(derivedKey == NULL) {
496 ok(0, "Could not generate a key when we should have");
497 goto errOut;
498 }
499 ok(1, "Made a new key");
500 retval = 1;
501 // NEEDS Fix -- ok(status = expectedEqualsComputed(expected, derivedKey), "Derived key is as expected");
502 errOut:
503 if(parameters) CFRelease(parameters);
504 if(derivedKey) CFRelease(derivedKey);
505 return retval;
506 }
507
508 static CFDataRef CFDataCreateFromHexBytes(char *s) {
509 if(!s) return NULL;
510 size_t len = strlen(s);
511 if(len%2) return NULL;
512 len /= 2;
513 uint8_t buf[len];
514 for(size_t i=0; i<len; i++) {
515 buf[i] = s[i*2] * 16 + s[i*2+1];
516 }
517 CFDataRef retval = CFDataCreate(NULL, buf, len);
518 return retval;
519 }
520
521
522 static int
523 PBKDF2Test(KDFVector *kdfvec)
524 {
525 CFDataRef expectedBytes = CFDataCreateFromHexBytes(kdfvec->expectedstr);
526 CFStringRef password = CFStringCreateWithCString(NULL, kdfvec->password, kCFStringEncodingUTF8);
527 CFDataRef salt = CFDataCreate(NULL, (const UInt8 *)kdfvec->salt, strlen(kdfvec->salt));
528 CFNumberRef rounds = CFNumberCreate(NULL, kCFNumberIntType, &kdfvec->rounds);
529 CFNumberRef dklen = CFNumberCreate(NULL, kCFNumberIntType, &kdfvec->dklen);
530 int status = 1;
531
532 ok(testSecKDF(password, salt, rounds, kSecAttrPRFHmacAlgSHA1, dklen, expectedBytes, kdfvec->expected_failure), "Test SecKeyDeriveFromPassword PBKDF2");
533
534 if(expectedBytes) CFRelease(expectedBytes);
535 return status;
536 }
537
538
539 static void testkeyderivation() {
540 for(size_t testcase = 0; testcase < kdfvLen; testcase++) {
541 // diag("Test %lu\n", testcase + 1);
542 ok(PBKDF2Test(&kdfv[testcase]), "Successful full test of KDF Vector");
543 }
544 }
545
546 #else
547 static size_t kdfvLen = 0; // no kdf functions in Sec for iphone
548 #endif /* !TARGET_OS_IPHONE */
549
550 static void delete_key(SecKeyRef *key) {
551 CFMutableDictionaryRef query = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks,
552 &kCFTypeDictionaryValueCallBacks);
553 CFDictionarySetValue(query, kSecValueRef, *key);
554 SecItemDelete(query);
555 CFReleaseNull(query);
556 CFReleaseNull(*key);
557 }
558
559 static const int kTestSupportedCount = 3 + (4 * 12) + 2 + (4 * 10) + 2;
560 static void testsupportedalgos(size_t keySizeInBits)
561 {
562 SecKeyRef pubKey = NULL, privKey = NULL;
563 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
564 CFNumberRef kzib;
565
566 int32_t iKeySizeInBits = (int32_t) keySizeInBits;
567 kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &iKeySizeInBits);
568 CFMutableDictionaryRef kgp = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
569 CFDictionaryAddValue(kgp, kSecAttrKeyType, kSecAttrKeyTypeRSA);
570 CFDictionaryAddValue(kgp, kSecAttrKeySizeInBits, kzib);
571
572 OSStatus status;
573 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
574 "Generate %ld bit (%ld byte) persistent RSA keypair",
575 keySizeInBits, keySizeInBytes);
576 CFRelease(kzib);
577 CFRelease(kgp);
578
579 is(SecKeyGetBlockSize(pubKey) * 8, (size_t) keySizeInBits, "public key size is ok");
580 is(SecKeyGetBlockSize(privKey) * 8, (size_t) keySizeInBits, "private key size is ok");
581
582 const SecKeyAlgorithm sign[] = {
583 kSecKeyAlgorithmRSASignatureRaw,
584 kSecKeyAlgorithmRSASignatureDigestPKCS1v15Raw,
585 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1,
586 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1,
587 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA224,
588 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA224,
589 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256,
590 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256,
591 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384,
592 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA384,
593 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512,
594 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA512,
595 };
596
597 for (size_t i = 0; i < array_size(sign); i++) {
598 SecKeyAlgorithm algorithm = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@"), sign[i]);
599 ok(SecKeyIsAlgorithmSupported(privKey, kSecKeyOperationTypeSign, algorithm),
600 "privKey supports sign algorithm %@", algorithm);
601 ok(SecKeyIsAlgorithmSupported(pubKey, kSecKeyOperationTypeVerify, algorithm),
602 "pubKey supports verify algorithm %@", algorithm);
603 // Since private key supports RSA decryption, our verify adapters happily accepts it.
604 ok(SecKeyIsAlgorithmSupported(privKey, kSecKeyOperationTypeVerify, algorithm),
605 "privKey supports verify algorithm %@", algorithm);
606 ok(!SecKeyIsAlgorithmSupported(pubKey, kSecKeyOperationTypeSign, algorithm),
607 "pubKey doesn't support sign algorithm %@", algorithm);
608 CFReleaseNull(algorithm);
609 }
610 ok(!SecKeyIsAlgorithmSupported(privKey, kSecKeyOperationTypeSign, kSecKeyAlgorithmECDSASignatureDigestX962),
611 "RSA privKey does not support ECDSA algorithm");
612 ok(!SecKeyIsAlgorithmSupported(privKey, kSecKeyOperationTypeVerify, kSecKeyAlgorithmECDSASignatureDigestX962),
613 "RSA pubKey does not support ECDSA algorithm");
614
615 const SecKeyAlgorithm crypt[] = {
616 kSecKeyAlgorithmRSAEncryptionRaw,
617 kSecKeyAlgorithmRSAEncryptionPKCS1,
618 kSecKeyAlgorithmRSAEncryptionOAEPSHA1,
619 kSecKeyAlgorithmRSAEncryptionOAEPSHA224,
620 kSecKeyAlgorithmRSAEncryptionOAEPSHA256,
621 kSecKeyAlgorithmRSAEncryptionOAEPSHA384,
622 kSecKeyAlgorithmRSAEncryptionOAEPSHA1AESGCM,
623 kSecKeyAlgorithmRSAEncryptionOAEPSHA224AESGCM,
624 kSecKeyAlgorithmRSAEncryptionOAEPSHA256AESGCM,
625 kSecKeyAlgorithmRSAEncryptionOAEPSHA384AESGCM,
626 // kSecKeyAlgorithmRSAEncryptionOAEPSHA512,
627 };
628 for (size_t i = 0; i < array_size(crypt); i++) {
629 SecKeyAlgorithm algorithm = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@"), crypt[i]);
630 ok(SecKeyIsAlgorithmSupported(privKey, kSecKeyOperationTypeDecrypt, algorithm),
631 "privKey supports decrypt algorithm %@", algorithm);
632 ok(SecKeyIsAlgorithmSupported(pubKey, kSecKeyOperationTypeEncrypt, algorithm),
633 "pubKey supports encrypt algorithm %@", algorithm);
634 ok(!SecKeyIsAlgorithmSupported(privKey, kSecKeyOperationTypeEncrypt, algorithm),
635 "privKey doesn't supports encrypt algorithm %@", algorithm);
636 ok(!SecKeyIsAlgorithmSupported(pubKey, kSecKeyOperationTypeDecrypt, algorithm),
637 "pubKey doesn't support decrypt algorithm %@", algorithm);
638 CFReleaseNull(algorithm);
639 }
640 ok(!SecKeyIsAlgorithmSupported(privKey, kSecKeyOperationTypeDecrypt, kSecKeyAlgorithmRSAEncryptionOAEPSHA512),
641 "privKey doesn't support decrypt algorithm %@", kSecKeyAlgorithmRSAEncryptionOAEPSHA512);
642 ok(!SecKeyIsAlgorithmSupported(privKey, kSecKeyOperationTypeDecrypt, kSecKeyAlgorithmRSAEncryptionOAEPSHA512AESGCM),
643 "privKey doesn't support decrypt algorithm %@", kSecKeyAlgorithmRSAEncryptionOAEPSHA512AESGCM);
644
645 /* Cleanup. */
646 delete_key(&pubKey);
647 delete_key(&privKey);
648 }
649
650 #if 0
651 #define kTestSupportedCount 15
652 static void testsupportedalgos(size_t keySizeInBits)
653 {
654 SecKeyRef pubKey = NULL, privKey = NULL;
655 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
656 CFNumberRef kzib;
657
658 int32_t iKeySizeInBits = (int32_t) keySizeInBits;
659 kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &iKeySizeInBits);
660 CFMutableDictionaryRef kgp = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
661 CFDictionaryAddValue(kgp, kSecAttrKeyType, kSecAttrKeyTypeRSA);
662 CFDictionaryAddValue(kgp, kSecAttrKeySizeInBits, kzib);
663 CFDictionaryAddValue(kgp, kSecAttrLabel, CFSTR("sectests:testsupportedalgos"));
664
665 OSStatus status;
666 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
667 "Generate %ld bit (%ld byte) persistent RSA keypair",
668 keySizeInBits, keySizeInBytes);
669 CFRelease(kzib);
670 CFRelease(kgp);
671
672 is(SecKeyGetBlockSize(pubKey) * 8, (size_t) keySizeInBits, "public key size is ok");
673 is(SecKeyGetBlockSize(privKey) * 8, (size_t) keySizeInBits, "private key size is ok");
674
675 CFSetRef keySet, expectedSet;
676
677 CFIndex value = kSecKeyAlgorithmECDSASignatureDigestX962;
678 CFNumberRef ECDSAX962 = CFNumberCreate(NULL, kCFNumberCFIndexType, &value);
679 value = kSecKeyAlgorithmRSAEncryptionRaw;
680 CFNumberRef RSARaw = CFNumberCreate(NULL, kCFNumberCFIndexType, &value);
681
682 { // privkey
683 keySet = SecKeyCopySupportedAlgorithms(privKey, kSecKeyOperationTypeSign);
684 const SecKeyAlgorithm sign[] = {
685 kSecKeyAlgorithmRSASignatureRaw,
686 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1,
687 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1,
688 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA224,
689 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA224,
690 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256,
691 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256,
692 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384,
693 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA384,
694 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512,
695 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA512,
696 };
697 expectedSet = createAlgorithmSet(sign, array_size(sign));
698 ok(CFSetIsSubset(expectedSet, keySet), "privkey contains expecting algos for signing");
699 ok(!CFSetContainsValue(keySet, ECDSAX962));
700 CFReleaseNull(keySet);
701 CFReleaseNull(expectedSet);
702
703 keySet = SecKeyCopySupportedAlgorithms(privKey, kSecKeyOperationTypeVerify);
704 expectedSet = createAlgorithmSet(sign, array_size(sign));
705 ok(CFSetIsSubset(expectedSet, keySet), "privkey contains expecting algos for verification");
706 ok(!CFSetContainsValue(keySet, ECDSAX962));
707 CFReleaseNull(keySet);
708 CFReleaseNull(expectedSet);
709
710 keySet = SecKeyCopySupportedAlgorithms(privKey, kSecKeyOperationTypeDecrypt);
711 const SecKeyAlgorithm decrypt[] = {
712 kSecKeyAlgorithmRSAEncryptionRaw,
713 kSecKeyAlgorithmRSAEncryptionPKCS1,
714 kSecKeyAlgorithmRSAEncryptionOAEPSHA1,
715 kSecKeyAlgorithmRSAEncryptionOAEPSHA224,
716 kSecKeyAlgorithmRSAEncryptionOAEPSHA256,
717 kSecKeyAlgorithmRSAEncryptionOAEPSHA384,
718 kSecKeyAlgorithmRSAEncryptionOAEPSHA512,
719 };
720 expectedSet = createAlgorithmSet(decrypt, array_size(decrypt));
721 ok(CFSetIsSubset(expectedSet, keySet), "privkey contains expecting algos for decryption");
722 CFReleaseNull(keySet);
723 CFReleaseNull(expectedSet);
724
725 keySet = SecKeyCopySupportedAlgorithms(privKey, kSecKeyOperationTypeEncrypt);
726 expectedSet = CFSetCreate(NULL, NULL, 0, &kCFTypeSetCallBacks);
727 is(CFSetGetCount(keySet), 0, "privkey contains no algos for encryption");
728 CFReleaseNull(keySet);
729 CFReleaseNull(expectedSet);
730 }
731
732 { // pubkey
733 keySet = SecKeyCopySupportedAlgorithms(pubKey, kSecKeyOperationTypeVerify);
734 const SecKeyAlgorithm verify[] = {
735 kSecKeyAlgorithmRSASignatureRaw,
736 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1,
737 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA224,
738 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256,
739 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384,
740 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512,
741 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1,
742 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA224,
743 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256,
744 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA384,
745 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA512,
746 };
747 expectedSet = createAlgorithmSet(verify, array_size(verify));
748 ok(CFSetIsSubset(expectedSet, keySet), "pubkey contains expecting algos for verification");
749 ok(!CFSetContainsValue(keySet, ECDSAX962),
750 "pubkey does not contain ECDSA algorithms for verification");
751 ok(!CFSetContainsValue(keySet, RSARaw),
752 "pubkey does not contain encryption-specific algorithm for verification");
753 CFReleaseNull(keySet);
754 CFReleaseNull(expectedSet);
755
756 keySet = SecKeyCopySupportedAlgorithms(pubKey, kSecKeyOperationTypeSign);
757 expectedSet = CFSetCreate(NULL, NULL, 0, &kCFTypeSetCallBacks);
758 is(CFSetGetCount(keySet), 0, "pubkey contains no algos for signing");
759 CFReleaseNull(keySet);
760 CFReleaseNull(expectedSet);
761
762 const SecKeyAlgorithm crypt[] = {
763 kSecKeyAlgorithmRSAEncryptionRaw,
764 kSecKeyAlgorithmRSAEncryptionPKCS1,
765 kSecKeyAlgorithmRSAEncryptionOAEPSHA1,
766 kSecKeyAlgorithmRSAEncryptionOAEPSHA224,
767 kSecKeyAlgorithmRSAEncryptionOAEPSHA256,
768 kSecKeyAlgorithmRSAEncryptionOAEPSHA384,
769 kSecKeyAlgorithmRSAEncryptionOAEPSHA512,
770 };
771 expectedSet = createAlgorithmSet(crypt, array_size(crypt));
772 keySet = SecKeyCopySupportedAlgorithms(pubKey, kSecKeyOperationTypeDecrypt);
773 #if TARGET_OS_IPHONE
774 ok(CFSetIsSubset(expectedSet, keySet), "pubkey contains expecting algos for decryption");
775 #else
776 ok(CFSetGetCount(keySet) == 0, "pubkey cannot decrypt");
777 #endif
778 CFReleaseNull(keySet);
779 CFReleaseNull(expectedSet);
780
781 keySet = SecKeyCopySupportedAlgorithms(pubKey, kSecKeyOperationTypeEncrypt);
782 expectedSet = createAlgorithmSet(crypt, array_size(crypt));
783 ok(CFSetIsSubset(expectedSet, keySet), "pubkey contains expecting algos for encryption");
784 CFReleaseNull(keySet);
785 CFReleaseNull(expectedSet);
786 }
787
788 /* Cleanup. */
789 CFReleaseNull(RSARaw);
790 CFReleaseNull(ECDSAX962);
791 delete_key(&pubKey);
792 delete_key(&privKey);
793 }
794 #endif
795
796 #if !TARGET_OS_IPHONE
797 static inline bool CFEqualSafe(CFTypeRef left, CFTypeRef right)
798 {
799 if (left == NULL || right == NULL)
800 return left == right;
801 else
802 return CFEqual(left, right);
803 }
804 #endif
805
806 #define kCreateWithDataTestCount 13
807 static void testcreatewithdata(unsigned long keySizeInBits)
808 {
809 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
810 int32_t keysz32 = (int32_t)keySizeInBits;
811
812 CFNumberRef kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &keysz32);
813 CFMutableDictionaryRef kgp = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks,
814 &kCFTypeDictionaryValueCallBacks);
815 CFDictionarySetValue(kgp, kSecAttrKeyType, kSecAttrKeyTypeRSA);
816 CFDictionarySetValue(kgp, kSecAttrKeySizeInBits, kzib);
817 CFDictionarySetValue(kgp, kSecAttrIsPermanent, kCFBooleanFalse);
818 CFDictionarySetValue(kgp, kSecAttrLabel, CFSTR("sectests:createwithdata"));
819
820 SecKeyRef pubKey = NULL, privKey = NULL;
821 OSStatus status;
822 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
823 "Generate %ld bit (%ld byte) RSA keypair (status = %d)",
824 keySizeInBits, keySizeInBytes, (int)status);
825 CFReleaseNull(kgp);
826
827 CFMutableDictionaryRef kcwd = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks,
828 &kCFTypeDictionaryValueCallBacks);;
829 CFDictionarySetValue(kcwd, kSecAttrKeyType, kSecAttrKeyTypeRSA);
830 CFDictionarySetValue(kcwd, kSecAttrKeySizeInBits, kzib);
831 CFDictionarySetValue(kcwd, kSecAttrIsPermanent, kCFBooleanFalse);
832 CFReleaseNull(kzib);
833
834 CFErrorRef error = NULL;
835 CFDataRef privExternalData = NULL, pubExternalData = NULL;
836 SecKeyRef dataKey = NULL;
837
838 { // privKey
839 privExternalData = SecKeyCopyExternalRepresentation(privKey, &error);
840 ok(privExternalData && CFGetTypeID(privExternalData) == CFDataGetTypeID(),
841 "priv key SecKeyCopyExternalRepresentation failed");
842 CFReleaseNull(error);
843
844 SKIP: {
845 skip("invalid priv key external data", 4, privExternalData);
846
847 CFDictionarySetValue(kcwd, kSecAttrKeyClass, kSecAttrKeyClassPrivate);
848 dataKey = SecKeyCreateWithData(privExternalData, kcwd, &error);
849 ok(dataKey, "priv key SecKeyCreateWithData failed");
850 CFReleaseNull(error);
851
852 eq_cf(privExternalData, SecKeyCopyExternalRepresentation(dataKey, NULL), "priv keys differ");
853 CFReleaseNull(dataKey);
854
855 CFDictionarySetValue(kcwd, kSecAttrKeyClass, kSecAttrKeyClassPublic);
856 dataKey = SecKeyCreateWithData(privExternalData, kcwd, &error);
857 ok(!dataKey, "priv key SecKeyCreateWithData succeeded with invalid kSecAttrKeyClass");
858 CFReleaseNull(error);
859 CFReleaseNull(dataKey);
860
861 CFMutableDataRef modifiedExternalData = CFDataCreateMutableCopy(kCFAllocatorDefault, 0, privExternalData);
862 *CFDataGetMutableBytePtr(modifiedExternalData) ^= 0xff;
863
864 CFDictionarySetValue(kcwd, kSecAttrKeyClass, kSecAttrKeyClassPrivate);
865 dataKey = SecKeyCreateWithData(modifiedExternalData, kcwd, &error);
866 ok(!dataKey, "priv key SecKeyCreateWithData succeeded with invalid external data");
867 CFReleaseNull(error);
868 CFReleaseNull(dataKey);
869
870 CFReleaseNull(modifiedExternalData);
871 }
872 }
873
874 { // pubKey
875 pubExternalData = SecKeyCopyExternalRepresentation(pubKey, &error);
876 ok(pubExternalData && CFGetTypeID(pubExternalData) == CFDataGetTypeID(),
877 "pub key SecKeyCopyExternalRepresentation failed");
878 CFReleaseNull(error);
879
880 SKIP: {
881 skip("invalid pub key external data", 4, pubExternalData);
882
883 CFDictionarySetValue(kcwd, kSecAttrKeyClass, kSecAttrKeyClassPublic);
884 dataKey = SecKeyCreateWithData(pubExternalData, kcwd, &error);
885 ok(dataKey, "pub key SecKeyCreateWithData failed");
886 CFReleaseNull(error);
887
888 eq_cf(pubExternalData, SecKeyCopyExternalRepresentation(dataKey, NULL), "pub keys differ");
889 CFReleaseNull(dataKey);
890
891 CFDictionarySetValue(kcwd, kSecAttrKeyClass, kSecAttrKeyClassPrivate);
892 dataKey = SecKeyCreateWithData(pubExternalData, kcwd, &error);
893 ok(!dataKey, "pub key SecKeyCreateWithData succeeded with invalid kSecAttrKeyClass");
894 CFReleaseNull(error);
895 CFReleaseNull(dataKey);
896
897 CFMutableDataRef modifiedExternalData = CFDataCreateMutableCopy(kCFAllocatorDefault, 0, pubExternalData);
898 *CFDataGetMutableBytePtr(modifiedExternalData) ^= 0xff;
899
900 CFDictionarySetValue(kcwd, kSecAttrKeyClass, kSecAttrKeyClassPublic);
901 dataKey = SecKeyCreateWithData(modifiedExternalData, kcwd, &error);
902 ok(!dataKey, "pub key SecKeyCreateWithData succeeded with invalid external data");
903 CFReleaseNull(error);
904 CFReleaseNull(dataKey);
905
906 CFReleaseNull(modifiedExternalData);
907 }
908 }
909
910 SKIP: {
911 skip("invalid pub key external data", 1, pubExternalData);
912
913 CFDictionarySetValue(kcwd, kSecAttrKeyClass, kSecAttrKeyClassPrivate);
914 dataKey = SecKeyCreateWithData(pubExternalData, kcwd, &error);
915 ok(!dataKey, "priv key SecKeyCreateWithData succeeded with public external data");
916 CFReleaseNull(error);
917 CFReleaseNull(dataKey);
918
919 CFReleaseNull(pubExternalData);
920 }
921
922 SKIP: {
923 skip("invalid priv key external data", 1, privExternalData);
924
925 CFDictionarySetValue(kcwd, kSecAttrKeyClass, kSecAttrKeyClassPublic);
926 dataKey = SecKeyCreateWithData(privExternalData, kcwd, &error);
927 ok(!dataKey, "pub key SecKeyCreateWithData succeeded with private external data");
928 CFReleaseNull(error);
929 CFReleaseNull(dataKey);
930
931 CFReleaseNull(privExternalData);
932 }
933
934 CFReleaseNull(kcwd);
935 delete_key(&pubKey);
936 delete_key(&privKey);
937 }
938
939 #define kCopyAttributesTestCount 20
940 static void testcopyattributes(unsigned long keySizeInBits, bool extractable)
941 {
942 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
943 int32_t keysz32 = (int32_t)keySizeInBits;
944
945 CFNumberRef kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &keysz32);
946 CFMutableDictionaryRef kgp = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks,
947 &kCFTypeDictionaryValueCallBacks);
948 CFDictionarySetValue(kgp, kSecAttrKeyType, kSecAttrKeyTypeRSA);
949 CFDictionarySetValue(kgp, kSecAttrKeySizeInBits, kzib);
950 CFDictionarySetValue(kgp, kSecAttrIsExtractable, extractable ? kCFBooleanTrue : kCFBooleanFalse);
951 CFDictionarySetValue(kgp, kSecAttrLabel, CFSTR("sectests:copyattributes"));
952 SecKeyRef pubKey = NULL, privKey = NULL;
953 OSStatus status;
954 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
955 "Generate %ld bit (%ld byte) RSA keypair (status = %d)",
956 keySizeInBits, keySizeInBytes, (int)status);
957 CFReleaseNull(kgp);
958
959 CFDictionaryRef attributes;
960 CFTypeRef attrValue = NULL, privAppLabel = NULL, pubAppLabel = NULL;
961
962 { // privKey
963 attributes = SecKeyCopyAttributes(privKey);
964 ok(attributes && CFGetTypeID(attributes) == CFDictionaryGetTypeID(),
965 "priv key SecKeyCopyAttributes failed");
966
967 SKIP: {
968 skip("invalid attributes", 8, attributes);
969
970 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanEncrypt);
971 eq_cf(attrValue, kCFBooleanFalse, "invalid priv key kSecAttrCanEncrypt");
972
973 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanDecrypt);
974 eq_cf(attrValue, kCFBooleanTrue, "invalid priv key kSecAttrCanDecrypt");
975
976 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanDerive);
977 eq_cf(attrValue, kCFBooleanTrue, "invalid priv key kSecAttrCanDerive");
978
979 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanSign);
980 eq_cf(attrValue, kCFBooleanTrue, "invalid priv key kSecAttrCanSign");
981
982 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanVerify);
983 eq_cf(attrValue, kCFBooleanFalse, "invalid priv key kSecAttrCanVerify");
984
985 attrValue = CFDictionaryGetValue(attributes, kSecAttrKeyClass);
986 eq_cf(attrValue, kSecAttrKeyClassPrivate, "priv key invalid kSecAttrKeyClass");
987
988 attrValue = CFDictionaryGetValue(attributes, kSecAttrKeyType);
989 eq_cf(attrValue, kSecAttrKeyTypeRSA, "invalid priv key kSecAttrKeyType");
990
991 attrValue = CFDictionaryGetValue(attributes, kSecAttrKeySizeInBits);
992 eq_cf(attrValue, kzib, "invalid priv key kSecAttrKeySizeInBits");
993
994 privAppLabel = CFDictionaryGetValue(attributes, kSecAttrApplicationLabel);
995 CFRetainSafe(privAppLabel);
996
997 CFReleaseNull(attributes);
998 }
999 }
1000
1001 { // pubKey
1002 attributes = SecKeyCopyAttributes(pubKey);
1003 ok(attributes && CFGetTypeID(attributes) == CFDictionaryGetTypeID(),
1004 "pub key SecKeyCopyAttributes failed");
1005
1006 SKIP: {
1007 skip("invalid attributes", 8, attributes);
1008
1009 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanEncrypt);
1010 eq_cf(attrValue, kCFBooleanTrue, "pub key invalid kSecAttrCanEncrypt");
1011
1012 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanDecrypt);
1013 eq_cf(attrValue, kCFBooleanFalse, "pub key invalid kSecAttrCanDecrypt");
1014
1015 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanDerive);
1016 eq_cf(attrValue, kCFBooleanTrue, "pub key invalid kSecAttrCanDerive");
1017
1018 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanSign);
1019 eq_cf(attrValue, kCFBooleanFalse, "pub key invalid kSecAttrCanSign");
1020
1021 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanVerify);
1022 eq_cf(attrValue, kCFBooleanTrue, "pub key invalid kSecAttrCanVerify");
1023
1024 attrValue = CFDictionaryGetValue(attributes, kSecAttrKeyClass);
1025 eq_cf(attrValue, kSecAttrKeyClassPublic, "pub key invalid kSecAttrKeyClass");
1026
1027 attrValue = CFDictionaryGetValue(attributes, kSecAttrKeyType);
1028 eq_cf(attrValue, kSecAttrKeyTypeRSA, "pub key invalid kSecAttrKeyType");
1029
1030 attrValue = CFDictionaryGetValue(attributes, kSecAttrKeySizeInBits);
1031 eq_cf(attrValue, kzib, "pub key invalid kSecAttrKeySizeInBits");
1032
1033 pubAppLabel = CFDictionaryGetValue(attributes, kSecAttrApplicationLabel);
1034 CFRetainSafe(pubAppLabel);
1035
1036 CFReleaseNull(attributes);
1037 }
1038 }
1039
1040 eq_cf(privAppLabel, pubAppLabel, "priv key and pub key kSecAttrApplicationLabel differ");
1041
1042 CFReleaseNull(privAppLabel);
1043 CFReleaseNull(pubAppLabel);
1044 CFReleaseNull(kzib);
1045 delete_key(&pubKey);
1046 delete_key(&privKey);
1047 }
1048
1049 #define kCopyPublicKeyTestCount 5
1050 static void testcopypublickey(unsigned long keySizeInBits, bool extractable, bool permanent) {
1051 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
1052 int32_t keysz32 = (int32_t)keySizeInBits;
1053
1054 CFNumberRef kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &keysz32);
1055 CFMutableDictionaryRef kgp = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks,
1056 &kCFTypeDictionaryValueCallBacks);
1057 CFDictionarySetValue(kgp, kSecAttrKeyType, kSecAttrKeyTypeRSA);
1058 CFDictionarySetValue(kgp, kSecAttrKeySizeInBits, kzib);
1059 CFDictionarySetValue(kgp, kSecAttrIsPermanent, permanent ? kCFBooleanTrue : kCFBooleanFalse);
1060 CFDictionarySetValue(kgp, kSecAttrIsExtractable, extractable ? kCFBooleanTrue : kCFBooleanFalse);
1061 CFDictionarySetValue(kgp, kSecAttrLabel, CFSTR("sectests:copypublickey"));
1062 SecKeyRef pubKey = NULL, privKey = NULL;
1063 OSStatus status;
1064 if (permanent) {
1065 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
1066 "Generate %ld bit (%ld byte) RSA keypair (status = %d)",
1067 keySizeInBits, keySizeInBytes, (int)status);
1068 } else {
1069 NSError *error = nil;
1070 privKey = SecKeyCreateRandomKey(kgp, (void *)&error);
1071 pubKey = SecKeyCopyPublicKey(privKey);
1072 ok(privKey != NULL && pubKey != NULL, "Generate %ld bit (%ld byte) RSA keypair (error %@)",
1073 keySizeInBits, keySizeInBytes, error);
1074 }
1075 CFReleaseNull(kgp);
1076 CFReleaseNull(kzib);
1077
1078 CFDataRef pubKeyData = SecKeyCopyExternalRepresentation(pubKey, NULL);
1079
1080 SecKeyRef pubKeyCopy = NULL;
1081
1082 { // privKey
1083 pubKeyCopy = SecKeyCopyPublicKey(privKey);
1084 ok(pubKeyCopy, "priv key SecKeyCopyPublicKey failed");
1085 CFDataRef pubKeyCopyData = SecKeyCopyExternalRepresentation(pubKeyCopy, NULL);
1086 eq_cf(pubKeyCopyData, pubKeyData, "pub key from priv key SecKeyCopyPublicKey and pub key differ");
1087 CFReleaseNull(pubKeyCopy);
1088 CFReleaseNull(pubKeyCopyData);
1089 }
1090
1091 { // pubKey
1092 pubKeyCopy = SecKeyCopyPublicKey(pubKey);
1093 ok(pubKeyCopy, "pub key SecKeyCopyPublicKey failed");
1094 CFDataRef pubKeyCopyData = SecKeyCopyExternalRepresentation(pubKeyCopy, NULL);
1095 eq_cf(pubKeyCopyData, pubKeyData, "pub key from pub key SecKeyCopyPublicKey and pub key differ");
1096 CFReleaseNull(pubKeyCopy);
1097 CFReleaseNull(pubKeyCopyData);
1098 }
1099
1100 CFReleaseNull(pubKeyData);
1101 if (permanent) {
1102 delete_key(&pubKey);
1103 delete_key(&privKey);
1104 } else {
1105 CFReleaseSafe(pubKey);
1106 CFReleaseSafe(privKey);
1107 }
1108 }
1109
1110 static const char *kCertWithPubK = "\
1111 MIIELjCCAxagAwIBAgIJALJlcYRBqZlZMA0GCSqGSIb3DQEBBQUAMIGUMQswCQYDVQQGEwJVUzELMAkG\
1112 A1UECBMCQ0ExEjAQBgNVBAcTCUN1cGVydGlubzETMBEGA1UEChMKQXBwbGUgSW5jLjEPMA0GA1UECxMG\
1113 Q29yZU9TMRwwGgYDVQQDExNBcHBsZSBUZXN0IENBMSBDZXJ0MSAwHgYJKoZIhvcNAQkBFhF2a3V6ZWxh\
1114 QGFwcGxlLmNvbTAeFw0xNTA0MjkwODMyMDBaFw0yNTA0MjYwODMyMDBaMIGPMQswCQYDVQQGEwJVUzEL\
1115 MAkGA1UECBMCQ0ExEjAQBgNVBAcTCUN1cGVydGlubzETMBEGA1UEChMKQXBwbGUgSW5jLjEQMA4GA1UE\
1116 CxMHQ29yZSBPUzEWMBQGA1UEAxMNRmlsaXAgU3Rva2xhczEgMB4GCSqGSIb3DQEJARYRc3Rva2xhc0Bh\
1117 cHBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZcPMvjpu7i/2SkNDCrSC4Wa8m\
1118 j3r6Lgn0crL4AgU+g3apptyy1eFf4RpNRJTGJ9ZMApbRZ0b7wX87Dq6UlCJUI9RJPOy+/TW0FM6mUVaF\
1119 VSY+P+KMdRYGIOMLVI+LR6lRTf8MWbxZ238cqAIVnLHaE9HrXjyIrgX2IufJjt69WhwsJZuan7jmeXJS\
1120 0AnESB31wS5NOn0tFDtzNAAQmoP8N8q6ZNC85tPVWBM61YLNjwSYl74y14QfX401P2pQRvwxTortRImk\
1121 xjN4DBprG23e59UW2IBxYsqUA61jhA0yVy8gxYpCGa4bEBslhrnkAoSv+Zlyk7u2GyO13AC1dfRxAgMB\
1122 AAGjgYUwgYIwPwYDVR0RBDgwNqAhBgorBgEEAYI3FAIDoBMMEXN0b2tsYXNAYXBwbGUuY29tgRFzdG9r\
1123 bGFzQGFwcGxlLmNvbTA/BgNVHREEODA2oCEGCisGAQQBgjcUAgOgEwwRc3Rva2xhc0BhcHBsZS5jb22B\
1124 EXN0b2tsYXNAYXBwbGUuY29tMA0GCSqGSIb3DQEBBQUAA4IBAQB87bZdl4XEDFA7UdPouhR3dKRl6evS\
1125 MfC9/0jVcdB+P1mNJ/vIZdOZMY0asieOXhsI91nEcHUjbBCnu18mu2jR6SGiJsS/zr6enkpQMcztulMU\
1126 kcjuSjT1hEzRv0LvEgWPOK+VpVqk6N0ZhybBQYVH2ECf7OU48CkFQFg9eLv6VaSK9+FqcBWpq8fXyOa7\
1127 bL58bO5A3URHcmMWibv9/j+lpVeQBxt1UUwqBZT7DSLPw3QCj/zXfAGEu3izvEYaWwsQDhItwQJ6g6pp\
1128 DLO741C7K8eKgvGs8ptna4RSosQda9bdnhZwT+g0UcorsVTUo+sR9+LW7INJ1zovRCL7NXit";
1129
1130 static const char *kPubK = "\
1131 MIIBCgKCAQEA2XDzL46bu4v9kpDQwq0guFmvJo96+i4J9HKy+AIFPoN2qabcstXhX+EaTUSUxifWTAKW\
1132 0WdG+8F/Ow6ulJQiVCPUSTzsvv01tBTOplFWhVUmPj/ijHUWBiDjC1SPi0epUU3/DFm8Wdt/HKgCFZyx\
1133 2hPR6148iK4F9iLnyY7evVocLCWbmp+45nlyUtAJxEgd9cEuTTp9LRQ7czQAEJqD/DfKumTQvObT1VgT\
1134 OtWCzY8EmJe+MteEH1+NNT9qUEb8MU6K7USJpMYzeAwaaxtt3ufVFtiAcWLKlAOtY4QNMlcvIMWKQhmu\
1135 GxAbJYa55AKEr/mZcpO7thsjtdwAtXX0cQIDAQAB";
1136
1137 static const int kTestCountCopyPubKFromCert = 2;
1138 static void testcopypubkfromcert() {
1139 NSData *certData = [[NSData alloc] initWithBase64EncodedString:[NSString stringWithUTF8String:kCertWithPubK]
1140 options:NSDataBase64DecodingIgnoreUnknownCharacters];
1141 NSData *pubKData = [[NSData alloc] initWithBase64EncodedString:[NSString stringWithUTF8String:kPubK]
1142 options:NSDataBase64DecodingIgnoreUnknownCharacters];
1143 SecCertificateRef cert = SecCertificateCreateWithData(kCFAllocatorDefault, (CFDataRef)certData);
1144 SecKeyRef pubKey = NULL;
1145 ok_status(SecCertificateCopyPublicKey(cert, &pubKey), "export public key from certificate");
1146 NSData *pubKeyData = (NSData *)SecKeyCopyExternalRepresentation(pubKey, NULL);
1147 eq_cf(pubKeyData, pubKData, "public key exports itself into expected data");
1148 CFReleaseNull(pubKey);
1149 CFReleaseNull(cert);
1150 }
1151
1152 static inline CFDataRef CFDataCreateWithHash(CFAllocatorRef allocator, const struct ccdigest_info *di, const uint8_t *buffer, const uint8_t length) {
1153 CFMutableDataRef result = CFDataCreateMutable(allocator, di->output_size);
1154 CFDataSetLength(result, di->output_size);
1155
1156 ccdigest(di, length, buffer, CFDataGetMutableBytePtr(result));
1157
1158 return result;
1159 }
1160
1161 #define kSignAndVerifyTestCount 130
1162 static void testsignverify(unsigned long keySizeInBits)
1163 {
1164 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
1165 int32_t keysz32 = (int32_t)keySizeInBits;
1166
1167 CFNumberRef kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &keysz32);
1168 CFMutableDictionaryRef kgp = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks,
1169 &kCFTypeDictionaryValueCallBacks);
1170 CFDictionarySetValue(kgp, kSecAttrKeyType, kSecAttrKeyTypeRSA);
1171 CFDictionarySetValue(kgp, kSecAttrKeySizeInBits, kzib);
1172 CFDictionarySetValue(kgp, kSecAttrIsPermanent, kCFBooleanFalse);
1173 CFDictionarySetValue(kgp, kSecAttrLabel, CFSTR("sectests:signverify"));
1174 SecKeyRef pubKey = NULL, privKey = NULL, pubKeyIOS = NULL, privKeyIOS = NULL;
1175 OSStatus status;
1176 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
1177 "Generate %ld bit (%ld byte) RSA keypair (status = %d)",
1178 keySizeInBits, keySizeInBytes, (int)status);
1179 CFReleaseNull(kgp);
1180 CFReleaseNull(kzib);
1181
1182 CFDataRef privKeyData = SecKeyCopyExternalRepresentation(privKey, NULL);
1183 CFDictionaryRef privKeyAttrs = SecKeyCopyAttributes(privKey);
1184 privKeyIOS = SecKeyCreateWithData(privKeyData, privKeyAttrs, NULL);
1185 CFReleaseNull(privKeyData);
1186 CFReleaseNull(privKeyAttrs);
1187 ok(privKeyIOS, "create IOS version of the private key");
1188
1189 CFDataRef pubKeyData = SecKeyCopyExternalRepresentation(pubKey, NULL);
1190 CFDictionaryRef pubKeyAttrs = SecKeyCopyAttributes(pubKey);
1191 pubKeyIOS = SecKeyCreateWithData(pubKeyData, pubKeyAttrs, NULL);
1192 CFReleaseNull(pubKeyData);
1193 CFReleaseNull(pubKeyAttrs);
1194 ok(pubKeyIOS, "create IOS version of the public key");
1195
1196 SecKeyAlgorithm algorithms[] = {
1197 kSecKeyAlgorithmRSASignatureRaw,
1198 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1,
1199 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA224,
1200 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256,
1201 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384,
1202 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512,
1203 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1,
1204 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA224,
1205 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256,
1206 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA384,
1207 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA512,
1208 };
1209
1210 CFDataRef testData = CFStringCreateExternalRepresentation(kCFAllocatorDefault, CFSTR("test"), kCFStringEncodingUTF8, 0);
1211 ok(testData, "creating test data failed");
1212
1213 SKIP: {
1214 skip("invalid test data", 71, testData);
1215
1216 CFErrorRef error = NULL;
1217
1218 for (uint32_t ix = 0; ix < array_size(algorithms); ++ix) {
1219 SecKeyAlgorithm algorithm = algorithms[ix];
1220 SecKeyAlgorithm incompatibleAlgorithm = (CFEqual(algorithm, kSecKeyAlgorithmRSASignatureRaw)) ?
1221 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1 : kSecKeyAlgorithmRSASignatureRaw;
1222
1223 CFDataRef dataToSign = NULL;
1224 if (CFEqual(algorithm, kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1)) {
1225 dataToSign = CFDataCreateWithHash(kCFAllocatorDefault, ccsha1_di(),
1226 CFDataGetBytePtr(testData), CFDataGetLength(testData));
1227 ok(dataToSign, "creating digest failed for algorithm %@", algorithm);
1228 }
1229 else if (CFEqual(algorithm, kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA224)) {
1230 dataToSign = CFDataCreateWithHash(kCFAllocatorDefault, ccsha224_di(),
1231 CFDataGetBytePtr(testData), CFDataGetLength(testData));
1232 ok(dataToSign, "creating digest failed for algorithm %@", algorithm);
1233 }
1234 else if (CFEqual(algorithm, kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256)) {
1235 dataToSign = CFDataCreateWithHash(kCFAllocatorDefault, ccsha256_di(),
1236 CFDataGetBytePtr(testData), CFDataGetLength(testData));
1237 ok(dataToSign, "creating digest failed for algorithm %@", algorithm);
1238 }
1239 else if (CFEqual(algorithm, kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384)) {
1240 dataToSign = CFDataCreateWithHash(kCFAllocatorDefault, ccsha384_di(),
1241 CFDataGetBytePtr(testData), CFDataGetLength(testData));
1242 ok(dataToSign, "creating digest failed for algorithm %@", algorithm);
1243 }
1244 else if (CFEqual(algorithm, kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512)) {
1245 dataToSign = CFDataCreateWithHash(kCFAllocatorDefault, ccsha512_di(),
1246 CFDataGetBytePtr(testData), CFDataGetLength(testData));
1247 ok(dataToSign, "creating digest failed for algorithm %@", algorithm);
1248 }
1249 else {
1250 CFRetainAssign(dataToSign, testData);
1251 }
1252 CFReleaseNull(error);
1253
1254 SKIP: {
1255 skip("invalid data to sign", 7, dataToSign);
1256
1257 CFDataRef signature = SecKeyCreateSignature(pubKey, algorithm, dataToSign, &error);
1258 ok(!signature, "SecKeyCopySignature succeeded with pub key for algorithm %@", algorithm);
1259 CFReleaseNull(error);
1260 CFReleaseNull(signature);
1261
1262 signature = SecKeyCreateSignature(privKey, algorithm, dataToSign, &error);
1263 ok(signature, "SecKeyCopySignature failed for algorithm %@", algorithm);
1264 CFReleaseNull(error);
1265
1266 CFDataRef iosSignature = SecKeyCreateSignature(privKeyIOS, algorithm, dataToSign, &error);
1267 ok(iosSignature, "SecKeyCopySignature(ios) failed for algorithm %@", algorithm);
1268 CFReleaseNull(error);
1269
1270 SKIP: {
1271 skip("invalid signature", 4, signature);
1272
1273 ok(!SecKeyVerifySignature(privKey, algorithm, dataToSign, signature, &error),
1274 "SecKeyVerifySignature succeeded with priv key for algorithm %@", algorithm);
1275 CFReleaseNull(error);
1276
1277 ok(!SecKeyVerifySignature(pubKey, incompatibleAlgorithm, dataToSign, signature, &error),
1278 "SecKeyVerifySignature succeeded with wrong algorithm for algorithm %@", algorithm);
1279 CFReleaseNull(error);
1280
1281 ok(SecKeyVerifySignature(pubKey, algorithm, dataToSign, signature, &error),
1282 "SecKeyVerifySignature(osx) failed osx-signature for algorithm %@", algorithm);
1283 CFReleaseNull(error);
1284
1285 ok(SecKeyVerifySignature(pubKeyIOS, algorithm, dataToSign, signature, &error),
1286 "SecKeyVerifySignature(ios) failed for osx-signature for algorithm %@", algorithm);
1287
1288 ok(SecKeyVerifySignature(pubKey, algorithm, dataToSign, iosSignature, &error),
1289 "SecKeyVerifySignature(osx) failed for ios-signature for algorithm %@", algorithm);
1290 CFReleaseNull(error);
1291
1292 ok(SecKeyVerifySignature(pubKeyIOS, algorithm, dataToSign, iosSignature, &error),
1293 "SecKeyVerifySignature(ios) failed for ios-signature for algorithm %@", algorithm);
1294
1295 CFMutableDataRef modifiedSignature = CFDataCreateMutableCopy(kCFAllocatorDefault, 0, signature);
1296 *CFDataGetMutableBytePtr(modifiedSignature) ^= 0xff;
1297
1298 ok(!SecKeyVerifySignature(pubKey, algorithm, dataToSign, modifiedSignature, &error),
1299 "SecKeyVerifySignature succeeded with bad signature for algorithm %@", algorithm);
1300 CFReleaseNull(error);
1301
1302 CFMutableDataRef modifiedDataToSign = CFDataCreateMutableCopy(kCFAllocatorDefault, 0, dataToSign);
1303 *CFDataGetMutableBytePtr(modifiedDataToSign) ^= 0xff;
1304
1305 ok(!SecKeyVerifySignature(pubKey, algorithm, modifiedDataToSign, signature, &error),
1306 "SecKeyVerifySignature succeeded with bad data for algorithm %@", algorithm);
1307 CFReleaseNull(error);
1308
1309 CFReleaseNull(modifiedDataToSign);
1310 CFReleaseNull(modifiedSignature);
1311 CFReleaseNull(signature);
1312 CFReleaseNull(iosSignature);
1313 }
1314 CFReleaseNull(dataToSign);
1315 }
1316 }
1317 CFReleaseNull(testData);
1318 }
1319
1320 delete_key(&pubKey);
1321 delete_key(&privKey);
1322 CFReleaseNull(pubKeyIOS);
1323 CFReleaseNull(privKeyIOS);
1324 }
1325
1326 #define kNonExtractableTestCount 6
1327 static void testnonextractable(unsigned long keySizeInBits)
1328 {
1329 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
1330 int32_t keysz32 = (int32_t)keySizeInBits;
1331
1332 CFNumberRef kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &keysz32);
1333 CFMutableDictionaryRef kgp = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks,
1334 &kCFTypeDictionaryValueCallBacks);
1335 CFDictionarySetValue(kgp, kSecAttrKeyType, kSecAttrKeyTypeRSA);
1336 CFDictionarySetValue(kgp, kSecAttrKeySizeInBits, kzib);
1337 CFDictionarySetValue(kgp, kSecAttrIsPermanent, kCFBooleanTrue);
1338 CFDictionarySetValue(kgp, kSecAttrIsExtractable, kCFBooleanFalse);
1339 CFStringRef label = CFSTR("sectests:nonextractable");
1340 CFDictionarySetValue(kgp, kSecAttrLabel, label);
1341 SecKeyRef pubKey = NULL, privKey = NULL;
1342 OSStatus status;
1343 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
1344 "Generate %ld bit (%ld byte) RSA keypair (status = %d)",
1345 keySizeInBits, keySizeInBytes, (int)status);
1346 CFReleaseNull(kgp);
1347 CFReleaseNull(kzib);
1348
1349 // Get attributes, verify that ApplicationLabel is set and equals for both keys.
1350 CFDictionaryRef privAttrs = SecKeyCopyAttributes(privKey);
1351 CFDictionaryRef pubAttrs = SecKeyCopyAttributes(pubKey);
1352
1353 ok(privAttrs, "able to get private key attributes");
1354 ok(pubAttrs, "able to get public key attributes");
1355
1356 CFDataRef privLabel = CFDictionaryGetValue(privAttrs, kSecAttrApplicationLabel);
1357 CFDataRef pubLabel = CFDictionaryGetValue(pubAttrs, kSecAttrApplicationLabel);
1358
1359 ok(privLabel && CFGetTypeID(privLabel) == CFDataGetTypeID() && CFDataGetLength(privLabel) == 20,
1360 "priv appLabel is present and of correct type");
1361 ok(pubLabel && CFGetTypeID(pubLabel) == CFDataGetTypeID() && CFDataGetLength(pubLabel) == 20,
1362 "priv appLabel is present and of correct type");
1363 eq_cf(privLabel, pubLabel, "applabels of pub and priv keys are equal");
1364
1365 CFReleaseNull(pubAttrs);
1366 CFReleaseNull(privAttrs);
1367
1368 delete_key(&pubKey);
1369 delete_key(&privKey);
1370 }
1371
1372 #define kTestCount ((2 * kKeyGenTestCount) + kKeyGen2TestCount + (int) (kdfvLen*3)) + \
1373 kTestSupportedCount + kCreateWithDataTestCount + (kCopyAttributesTestCount * 2) + (kCopyPublicKeyTestCount * 4) + \
1374 kSignAndVerifyTestCount + kNonExtractableTestCount + \
1375 kTestCountCopyPubKFromCert
1376
1377 static void tests(void)
1378 {
1379 /* Comment out lines below for testing generating all common key sizes,
1380 disabled now for speed reasons. */
1381 //testkeygen(512);
1382 //testkeygen(768);
1383 testkeygen(1024);
1384 testkeygen(2056); // Stranged sized for edge cases in padding.
1385 //testkeygen(2048);
1386 //testkeygen(4096);
1387
1388 testkeygen2(1024); // lots of FAIL!
1389
1390 testsupportedalgos(1024);
1391 testcreatewithdata(1024);
1392 testcopyattributes(1024, true);
1393 testcopyattributes(1024, false);
1394 testcopypublickey(1024, true, true);
1395 testcopypublickey(1024, false, true);
1396 testcopypublickey(1024, true, false);
1397 testcopypublickey(1024, false, false);
1398 testsignverify(1024);
1399 testnonextractable(1024);
1400
1401 #if !TARGET_OS_IPHONE
1402 testkeyderivation();
1403 #endif
1404
1405 testcopypubkfromcert();
1406 }
1407
1408 int kc_40_seckey(int argc, char *const *argv)
1409 {
1410 plan_tests(kTestCount);
1411
1412 tests();
1413
1414 return 0;
1415 }