]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_keychain/regressions/kc-40-seckey.m
Security-57740.51.3.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, kCFNumberSInt64Type, &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, kCFNumberSInt64Type, &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 CFReleaseNull(expectedBytes);
535 CFReleaseNull(password);
536 CFReleaseNull(salt);
537 CFReleaseNull(rounds);
538 CFReleaseNull(dklen);
539
540 return status;
541 }
542
543
544 static void testkeyderivation() {
545 for(size_t testcase = 0; testcase < kdfvLen; testcase++) {
546 // diag("Test %lu\n", testcase + 1);
547 ok(PBKDF2Test(&kdfv[testcase]), "Successful full test of KDF Vector");
548 }
549 }
550
551 #else
552 static size_t kdfvLen = 0; // no kdf functions in Sec for iphone
553 #endif /* !TARGET_OS_IPHONE */
554
555 static void delete_key(SecKeyRef *key) {
556 CFMutableDictionaryRef query = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks,
557 &kCFTypeDictionaryValueCallBacks);
558 CFDictionarySetValue(query, kSecValueRef, *key);
559 SecItemDelete(query);
560 CFReleaseNull(query);
561 CFReleaseNull(*key);
562 }
563
564 static const int kTestSupportedCount = 3 + (4 * 12) + 2 + (4 * 10) + 2;
565 static void testsupportedalgos(size_t keySizeInBits)
566 {
567 SecKeyRef pubKey = NULL, privKey = NULL;
568 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
569 CFNumberRef kzib;
570
571 int32_t iKeySizeInBits = (int32_t) keySizeInBits;
572 kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &iKeySizeInBits);
573 CFMutableDictionaryRef kgp = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
574 CFDictionaryAddValue(kgp, kSecAttrKeyType, kSecAttrKeyTypeRSA);
575 CFDictionaryAddValue(kgp, kSecAttrKeySizeInBits, kzib);
576
577 OSStatus status;
578 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
579 "Generate %ld bit (%ld byte) persistent RSA keypair",
580 keySizeInBits, keySizeInBytes);
581 CFRelease(kzib);
582 CFRelease(kgp);
583
584 is(SecKeyGetBlockSize(pubKey) * 8, (size_t) keySizeInBits, "public key size is ok");
585 is(SecKeyGetBlockSize(privKey) * 8, (size_t) keySizeInBits, "private key size is ok");
586
587 const SecKeyAlgorithm sign[] = {
588 kSecKeyAlgorithmRSASignatureRaw,
589 kSecKeyAlgorithmRSASignatureDigestPKCS1v15Raw,
590 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1,
591 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1,
592 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA224,
593 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA224,
594 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256,
595 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256,
596 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384,
597 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA384,
598 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512,
599 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA512,
600 };
601
602 for (size_t i = 0; i < array_size(sign); i++) {
603 SecKeyAlgorithm algorithm = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@"), sign[i]);
604 ok(SecKeyIsAlgorithmSupported(privKey, kSecKeyOperationTypeSign, algorithm),
605 "privKey supports sign algorithm %@", algorithm);
606 ok(SecKeyIsAlgorithmSupported(pubKey, kSecKeyOperationTypeVerify, algorithm),
607 "pubKey supports verify algorithm %@", algorithm);
608 // Since private key supports RSA decryption, our verify adapters happily accepts it.
609 ok(SecKeyIsAlgorithmSupported(privKey, kSecKeyOperationTypeVerify, algorithm),
610 "privKey supports verify algorithm %@", algorithm);
611 ok(!SecKeyIsAlgorithmSupported(pubKey, kSecKeyOperationTypeSign, algorithm),
612 "pubKey doesn't support sign algorithm %@", algorithm);
613 CFReleaseNull(algorithm);
614 }
615 ok(!SecKeyIsAlgorithmSupported(privKey, kSecKeyOperationTypeSign, kSecKeyAlgorithmECDSASignatureDigestX962),
616 "RSA privKey does not support ECDSA algorithm");
617 ok(!SecKeyIsAlgorithmSupported(privKey, kSecKeyOperationTypeVerify, kSecKeyAlgorithmECDSASignatureDigestX962),
618 "RSA pubKey does not support ECDSA algorithm");
619
620 const SecKeyAlgorithm crypt[] = {
621 kSecKeyAlgorithmRSAEncryptionRaw,
622 kSecKeyAlgorithmRSAEncryptionPKCS1,
623 kSecKeyAlgorithmRSAEncryptionOAEPSHA1,
624 kSecKeyAlgorithmRSAEncryptionOAEPSHA224,
625 kSecKeyAlgorithmRSAEncryptionOAEPSHA256,
626 kSecKeyAlgorithmRSAEncryptionOAEPSHA384,
627 kSecKeyAlgorithmRSAEncryptionOAEPSHA1AESGCM,
628 kSecKeyAlgorithmRSAEncryptionOAEPSHA224AESGCM,
629 kSecKeyAlgorithmRSAEncryptionOAEPSHA256AESGCM,
630 kSecKeyAlgorithmRSAEncryptionOAEPSHA384AESGCM,
631 // kSecKeyAlgorithmRSAEncryptionOAEPSHA512,
632 };
633 for (size_t i = 0; i < array_size(crypt); i++) {
634 SecKeyAlgorithm algorithm = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@"), crypt[i]);
635 ok(SecKeyIsAlgorithmSupported(privKey, kSecKeyOperationTypeDecrypt, algorithm),
636 "privKey supports decrypt algorithm %@", algorithm);
637 ok(SecKeyIsAlgorithmSupported(pubKey, kSecKeyOperationTypeEncrypt, algorithm),
638 "pubKey supports encrypt algorithm %@", algorithm);
639 ok(!SecKeyIsAlgorithmSupported(privKey, kSecKeyOperationTypeEncrypt, algorithm),
640 "privKey doesn't supports encrypt algorithm %@", algorithm);
641 ok(!SecKeyIsAlgorithmSupported(pubKey, kSecKeyOperationTypeDecrypt, algorithm),
642 "pubKey doesn't support decrypt algorithm %@", algorithm);
643 CFReleaseNull(algorithm);
644 }
645 ok(!SecKeyIsAlgorithmSupported(privKey, kSecKeyOperationTypeDecrypt, kSecKeyAlgorithmRSAEncryptionOAEPSHA512),
646 "privKey doesn't support decrypt algorithm %@", kSecKeyAlgorithmRSAEncryptionOAEPSHA512);
647 ok(!SecKeyIsAlgorithmSupported(privKey, kSecKeyOperationTypeDecrypt, kSecKeyAlgorithmRSAEncryptionOAEPSHA512AESGCM),
648 "privKey doesn't support decrypt algorithm %@", kSecKeyAlgorithmRSAEncryptionOAEPSHA512AESGCM);
649
650 /* Cleanup. */
651 delete_key(&pubKey);
652 delete_key(&privKey);
653 }
654
655 #if 0
656 #define kTestSupportedCount 15
657 static void testsupportedalgos(size_t keySizeInBits)
658 {
659 SecKeyRef pubKey = NULL, privKey = NULL;
660 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
661 CFNumberRef kzib;
662
663 int32_t iKeySizeInBits = (int32_t) keySizeInBits;
664 kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &iKeySizeInBits);
665 CFMutableDictionaryRef kgp = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
666 CFDictionaryAddValue(kgp, kSecAttrKeyType, kSecAttrKeyTypeRSA);
667 CFDictionaryAddValue(kgp, kSecAttrKeySizeInBits, kzib);
668 CFDictionaryAddValue(kgp, kSecAttrLabel, CFSTR("sectests:testsupportedalgos"));
669
670 OSStatus status;
671 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
672 "Generate %ld bit (%ld byte) persistent RSA keypair",
673 keySizeInBits, keySizeInBytes);
674 CFRelease(kzib);
675 CFRelease(kgp);
676
677 is(SecKeyGetBlockSize(pubKey) * 8, (size_t) keySizeInBits, "public key size is ok");
678 is(SecKeyGetBlockSize(privKey) * 8, (size_t) keySizeInBits, "private key size is ok");
679
680 CFSetRef keySet, expectedSet;
681
682 CFIndex value = kSecKeyAlgorithmECDSASignatureDigestX962;
683 CFNumberRef ECDSAX962 = CFNumberCreate(NULL, kCFNumberCFIndexType, &value);
684 value = kSecKeyAlgorithmRSAEncryptionRaw;
685 CFNumberRef RSARaw = CFNumberCreate(NULL, kCFNumberCFIndexType, &value);
686
687 { // privkey
688 keySet = SecKeyCopySupportedAlgorithms(privKey, kSecKeyOperationTypeSign);
689 const SecKeyAlgorithm sign[] = {
690 kSecKeyAlgorithmRSASignatureRaw,
691 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1,
692 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1,
693 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA224,
694 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA224,
695 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256,
696 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256,
697 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384,
698 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA384,
699 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512,
700 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA512,
701 };
702 expectedSet = createAlgorithmSet(sign, array_size(sign));
703 ok(CFSetIsSubset(expectedSet, keySet), "privkey contains expecting algos for signing");
704 ok(!CFSetContainsValue(keySet, ECDSAX962));
705 CFReleaseNull(keySet);
706 CFReleaseNull(expectedSet);
707
708 keySet = SecKeyCopySupportedAlgorithms(privKey, kSecKeyOperationTypeVerify);
709 expectedSet = createAlgorithmSet(sign, array_size(sign));
710 ok(CFSetIsSubset(expectedSet, keySet), "privkey contains expecting algos for verification");
711 ok(!CFSetContainsValue(keySet, ECDSAX962));
712 CFReleaseNull(keySet);
713 CFReleaseNull(expectedSet);
714
715 keySet = SecKeyCopySupportedAlgorithms(privKey, kSecKeyOperationTypeDecrypt);
716 const SecKeyAlgorithm decrypt[] = {
717 kSecKeyAlgorithmRSAEncryptionRaw,
718 kSecKeyAlgorithmRSAEncryptionPKCS1,
719 kSecKeyAlgorithmRSAEncryptionOAEPSHA1,
720 kSecKeyAlgorithmRSAEncryptionOAEPSHA224,
721 kSecKeyAlgorithmRSAEncryptionOAEPSHA256,
722 kSecKeyAlgorithmRSAEncryptionOAEPSHA384,
723 kSecKeyAlgorithmRSAEncryptionOAEPSHA512,
724 };
725 expectedSet = createAlgorithmSet(decrypt, array_size(decrypt));
726 ok(CFSetIsSubset(expectedSet, keySet), "privkey contains expecting algos for decryption");
727 CFReleaseNull(keySet);
728 CFReleaseNull(expectedSet);
729
730 keySet = SecKeyCopySupportedAlgorithms(privKey, kSecKeyOperationTypeEncrypt);
731 expectedSet = CFSetCreate(NULL, NULL, 0, &kCFTypeSetCallBacks);
732 is(CFSetGetCount(keySet), 0, "privkey contains no algos for encryption");
733 CFReleaseNull(keySet);
734 CFReleaseNull(expectedSet);
735 }
736
737 { // pubkey
738 keySet = SecKeyCopySupportedAlgorithms(pubKey, kSecKeyOperationTypeVerify);
739 const SecKeyAlgorithm verify[] = {
740 kSecKeyAlgorithmRSASignatureRaw,
741 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1,
742 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA224,
743 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256,
744 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384,
745 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512,
746 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1,
747 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA224,
748 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256,
749 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA384,
750 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA512,
751 };
752 expectedSet = createAlgorithmSet(verify, array_size(verify));
753 ok(CFSetIsSubset(expectedSet, keySet), "pubkey contains expecting algos for verification");
754 ok(!CFSetContainsValue(keySet, ECDSAX962),
755 "pubkey does not contain ECDSA algorithms for verification");
756 ok(!CFSetContainsValue(keySet, RSARaw),
757 "pubkey does not contain encryption-specific algorithm for verification");
758 CFReleaseNull(keySet);
759 CFReleaseNull(expectedSet);
760
761 keySet = SecKeyCopySupportedAlgorithms(pubKey, kSecKeyOperationTypeSign);
762 expectedSet = CFSetCreate(NULL, NULL, 0, &kCFTypeSetCallBacks);
763 is(CFSetGetCount(keySet), 0, "pubkey contains no algos for signing");
764 CFReleaseNull(keySet);
765 CFReleaseNull(expectedSet);
766
767 const SecKeyAlgorithm crypt[] = {
768 kSecKeyAlgorithmRSAEncryptionRaw,
769 kSecKeyAlgorithmRSAEncryptionPKCS1,
770 kSecKeyAlgorithmRSAEncryptionOAEPSHA1,
771 kSecKeyAlgorithmRSAEncryptionOAEPSHA224,
772 kSecKeyAlgorithmRSAEncryptionOAEPSHA256,
773 kSecKeyAlgorithmRSAEncryptionOAEPSHA384,
774 kSecKeyAlgorithmRSAEncryptionOAEPSHA512,
775 };
776 expectedSet = createAlgorithmSet(crypt, array_size(crypt));
777 keySet = SecKeyCopySupportedAlgorithms(pubKey, kSecKeyOperationTypeDecrypt);
778 #if TARGET_OS_IPHONE
779 ok(CFSetIsSubset(expectedSet, keySet), "pubkey contains expecting algos for decryption");
780 #else
781 ok(CFSetGetCount(keySet) == 0, "pubkey cannot decrypt");
782 #endif
783 CFReleaseNull(keySet);
784 CFReleaseNull(expectedSet);
785
786 keySet = SecKeyCopySupportedAlgorithms(pubKey, kSecKeyOperationTypeEncrypt);
787 expectedSet = createAlgorithmSet(crypt, array_size(crypt));
788 ok(CFSetIsSubset(expectedSet, keySet), "pubkey contains expecting algos for encryption");
789 CFReleaseNull(keySet);
790 CFReleaseNull(expectedSet);
791 }
792
793 /* Cleanup. */
794 CFReleaseNull(RSARaw);
795 CFReleaseNull(ECDSAX962);
796 delete_key(&pubKey);
797 delete_key(&privKey);
798 }
799 #endif
800
801 #if !TARGET_OS_IPHONE
802 static inline bool CFEqualSafe(CFTypeRef left, CFTypeRef right)
803 {
804 if (left == NULL || right == NULL)
805 return left == right;
806 else
807 return CFEqual(left, right);
808 }
809 #endif
810
811 #define kCreateWithDataTestCount 13
812 static void testcreatewithdata(unsigned long keySizeInBits)
813 {
814 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
815 int32_t keysz32 = (int32_t)keySizeInBits;
816
817 CFNumberRef kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &keysz32);
818 CFMutableDictionaryRef kgp = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks,
819 &kCFTypeDictionaryValueCallBacks);
820 CFDictionarySetValue(kgp, kSecAttrKeyType, kSecAttrKeyTypeRSA);
821 CFDictionarySetValue(kgp, kSecAttrKeySizeInBits, kzib);
822 CFDictionarySetValue(kgp, kSecAttrIsPermanent, kCFBooleanFalse);
823 CFDictionarySetValue(kgp, kSecAttrLabel, CFSTR("sectests:createwithdata"));
824
825 SecKeyRef pubKey = NULL, privKey = NULL;
826 OSStatus status;
827 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
828 "Generate %ld bit (%ld byte) RSA keypair (status = %d)",
829 keySizeInBits, keySizeInBytes, (int)status);
830 CFReleaseNull(kgp);
831
832 CFMutableDictionaryRef kcwd = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks,
833 &kCFTypeDictionaryValueCallBacks);;
834 CFDictionarySetValue(kcwd, kSecAttrKeyType, kSecAttrKeyTypeRSA);
835 CFDictionarySetValue(kcwd, kSecAttrKeySizeInBits, kzib);
836 CFDictionarySetValue(kcwd, kSecAttrIsPermanent, kCFBooleanFalse);
837 CFReleaseNull(kzib);
838
839 CFErrorRef error = NULL;
840 CFDataRef privExternalData = NULL, pubExternalData = NULL;
841 SecKeyRef dataKey = NULL;
842
843 { // privKey
844 privExternalData = SecKeyCopyExternalRepresentation(privKey, &error);
845 ok(privExternalData && CFGetTypeID(privExternalData) == CFDataGetTypeID(),
846 "priv key SecKeyCopyExternalRepresentation failed");
847 CFReleaseNull(error);
848
849 SKIP: {
850 skip("invalid priv key external data", 4, privExternalData);
851
852 CFDictionarySetValue(kcwd, kSecAttrKeyClass, kSecAttrKeyClassPrivate);
853 dataKey = SecKeyCreateWithData(privExternalData, kcwd, &error);
854 ok(dataKey, "priv key SecKeyCreateWithData failed");
855 CFReleaseNull(error);
856
857 CFDataRef external = SecKeyCopyExternalRepresentation(dataKey, NULL);
858 eq_cf(privExternalData, external, "priv keys differ");
859 CFReleaseNull(external);
860 CFReleaseNull(dataKey);
861
862 CFDictionarySetValue(kcwd, kSecAttrKeyClass, kSecAttrKeyClassPublic);
863 dataKey = SecKeyCreateWithData(privExternalData, kcwd, &error);
864 ok(!dataKey, "priv key SecKeyCreateWithData succeeded with invalid kSecAttrKeyClass");
865 CFReleaseNull(error);
866 CFReleaseNull(dataKey);
867
868 CFMutableDataRef modifiedExternalData = CFDataCreateMutableCopy(kCFAllocatorDefault, 0, privExternalData);
869 *CFDataGetMutableBytePtr(modifiedExternalData) ^= 0xff;
870
871 CFDictionarySetValue(kcwd, kSecAttrKeyClass, kSecAttrKeyClassPrivate);
872 dataKey = SecKeyCreateWithData(modifiedExternalData, kcwd, &error);
873 ok(!dataKey, "priv key SecKeyCreateWithData succeeded with invalid external data");
874 CFReleaseNull(error);
875 CFReleaseNull(dataKey);
876
877 CFReleaseNull(modifiedExternalData);
878 }
879 }
880
881 { // pubKey
882 pubExternalData = SecKeyCopyExternalRepresentation(pubKey, &error);
883 ok(pubExternalData && CFGetTypeID(pubExternalData) == CFDataGetTypeID(),
884 "pub key SecKeyCopyExternalRepresentation failed");
885 CFReleaseNull(error);
886
887 SKIP: {
888 skip("invalid pub key external data", 4, pubExternalData);
889
890 CFDictionarySetValue(kcwd, kSecAttrKeyClass, kSecAttrKeyClassPublic);
891 dataKey = SecKeyCreateWithData(pubExternalData, kcwd, &error);
892 ok(dataKey, "pub key SecKeyCreateWithData failed");
893 CFReleaseNull(error);
894
895 CFDataRef external = SecKeyCopyExternalRepresentation(dataKey, NULL);
896 eq_cf(pubExternalData, external, "pub keys differ");
897 CFReleaseNull(external);
898 CFReleaseNull(dataKey);
899
900 CFDictionarySetValue(kcwd, kSecAttrKeyClass, kSecAttrKeyClassPrivate);
901 dataKey = SecKeyCreateWithData(pubExternalData, kcwd, &error);
902 ok(!dataKey, "pub key SecKeyCreateWithData succeeded with invalid kSecAttrKeyClass");
903 CFReleaseNull(error);
904 CFReleaseNull(dataKey);
905
906 CFMutableDataRef modifiedExternalData = CFDataCreateMutableCopy(kCFAllocatorDefault, 0, pubExternalData);
907 *CFDataGetMutableBytePtr(modifiedExternalData) ^= 0xff;
908
909 CFDictionarySetValue(kcwd, kSecAttrKeyClass, kSecAttrKeyClassPublic);
910 dataKey = SecKeyCreateWithData(modifiedExternalData, kcwd, &error);
911 ok(!dataKey, "pub key SecKeyCreateWithData succeeded with invalid external data");
912 CFReleaseNull(error);
913 CFReleaseNull(dataKey);
914
915 CFReleaseNull(modifiedExternalData);
916 }
917 }
918
919 SKIP: {
920 skip("invalid pub key external data", 1, pubExternalData);
921
922 CFDictionarySetValue(kcwd, kSecAttrKeyClass, kSecAttrKeyClassPrivate);
923 dataKey = SecKeyCreateWithData(pubExternalData, kcwd, &error);
924 ok(!dataKey, "priv key SecKeyCreateWithData succeeded with public external data");
925 CFReleaseNull(error);
926 CFReleaseNull(dataKey);
927
928 CFReleaseNull(pubExternalData);
929 }
930
931 SKIP: {
932 skip("invalid priv key external data", 1, privExternalData);
933
934 CFDictionarySetValue(kcwd, kSecAttrKeyClass, kSecAttrKeyClassPublic);
935 dataKey = SecKeyCreateWithData(privExternalData, kcwd, &error);
936 ok(!dataKey, "pub key SecKeyCreateWithData succeeded with private external data");
937 CFReleaseNull(error);
938 CFReleaseNull(dataKey);
939
940 CFReleaseNull(privExternalData);
941 }
942
943 CFReleaseNull(kcwd);
944 delete_key(&pubKey);
945 delete_key(&privKey);
946 }
947
948 #define kCopyAttributesTestCount 20
949 static void testcopyattributes(unsigned long keySizeInBits, bool extractable)
950 {
951 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
952 int32_t keysz32 = (int32_t)keySizeInBits;
953
954 CFNumberRef kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &keysz32);
955 CFMutableDictionaryRef kgp = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks,
956 &kCFTypeDictionaryValueCallBacks);
957 CFDictionarySetValue(kgp, kSecAttrKeyType, kSecAttrKeyTypeRSA);
958 CFDictionarySetValue(kgp, kSecAttrKeySizeInBits, kzib);
959 CFDictionarySetValue(kgp, kSecAttrIsExtractable, extractable ? kCFBooleanTrue : kCFBooleanFalse);
960 CFDictionarySetValue(kgp, kSecAttrLabel, CFSTR("sectests:copyattributes"));
961 SecKeyRef pubKey = NULL, privKey = NULL;
962 OSStatus status;
963 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
964 "Generate %ld bit (%ld byte) RSA keypair (status = %d)",
965 keySizeInBits, keySizeInBytes, (int)status);
966 CFReleaseNull(kgp);
967
968 CFDictionaryRef attributes;
969 CFTypeRef attrValue = NULL, privAppLabel = NULL, pubAppLabel = NULL;
970
971 { // privKey
972 attributes = SecKeyCopyAttributes(privKey);
973 ok(attributes && CFGetTypeID(attributes) == CFDictionaryGetTypeID(),
974 "priv key SecKeyCopyAttributes failed");
975
976 SKIP: {
977 skip("invalid attributes", 8, attributes);
978
979 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanEncrypt);
980 eq_cf(attrValue, kCFBooleanFalse, "invalid priv key kSecAttrCanEncrypt");
981
982 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanDecrypt);
983 eq_cf(attrValue, kCFBooleanTrue, "invalid priv key kSecAttrCanDecrypt");
984
985 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanDerive);
986 eq_cf(attrValue, kCFBooleanTrue, "invalid priv key kSecAttrCanDerive");
987
988 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanSign);
989 eq_cf(attrValue, kCFBooleanTrue, "invalid priv key kSecAttrCanSign");
990
991 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanVerify);
992 eq_cf(attrValue, kCFBooleanFalse, "invalid priv key kSecAttrCanVerify");
993
994 attrValue = CFDictionaryGetValue(attributes, kSecAttrKeyClass);
995 eq_cf(attrValue, kSecAttrKeyClassPrivate, "priv key invalid kSecAttrKeyClass");
996
997 attrValue = CFDictionaryGetValue(attributes, kSecAttrKeyType);
998 eq_cf(attrValue, kSecAttrKeyTypeRSA, "invalid priv key kSecAttrKeyType");
999
1000 attrValue = CFDictionaryGetValue(attributes, kSecAttrKeySizeInBits);
1001 eq_cf(attrValue, kzib, "invalid priv key kSecAttrKeySizeInBits");
1002
1003 privAppLabel = CFDictionaryGetValue(attributes, kSecAttrApplicationLabel);
1004 CFRetainSafe(privAppLabel);
1005
1006 CFReleaseNull(attributes);
1007 }
1008 }
1009
1010 { // pubKey
1011 attributes = SecKeyCopyAttributes(pubKey);
1012 ok(attributes && CFGetTypeID(attributes) == CFDictionaryGetTypeID(),
1013 "pub key SecKeyCopyAttributes failed");
1014
1015 SKIP: {
1016 skip("invalid attributes", 8, attributes);
1017
1018 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanEncrypt);
1019 eq_cf(attrValue, kCFBooleanTrue, "pub key invalid kSecAttrCanEncrypt");
1020
1021 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanDecrypt);
1022 eq_cf(attrValue, kCFBooleanFalse, "pub key invalid kSecAttrCanDecrypt");
1023
1024 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanDerive);
1025 eq_cf(attrValue, kCFBooleanTrue, "pub key invalid kSecAttrCanDerive");
1026
1027 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanSign);
1028 eq_cf(attrValue, kCFBooleanFalse, "pub key invalid kSecAttrCanSign");
1029
1030 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanVerify);
1031 eq_cf(attrValue, kCFBooleanTrue, "pub key invalid kSecAttrCanVerify");
1032
1033 attrValue = CFDictionaryGetValue(attributes, kSecAttrKeyClass);
1034 eq_cf(attrValue, kSecAttrKeyClassPublic, "pub key invalid kSecAttrKeyClass");
1035
1036 attrValue = CFDictionaryGetValue(attributes, kSecAttrKeyType);
1037 eq_cf(attrValue, kSecAttrKeyTypeRSA, "pub key invalid kSecAttrKeyType");
1038
1039 attrValue = CFDictionaryGetValue(attributes, kSecAttrKeySizeInBits);
1040 eq_cf(attrValue, kzib, "pub key invalid kSecAttrKeySizeInBits");
1041
1042 pubAppLabel = CFDictionaryGetValue(attributes, kSecAttrApplicationLabel);
1043 CFRetainSafe(pubAppLabel);
1044
1045 CFReleaseNull(attributes);
1046 }
1047 }
1048
1049 eq_cf(privAppLabel, pubAppLabel, "priv key and pub key kSecAttrApplicationLabel differ");
1050
1051 CFReleaseNull(privAppLabel);
1052 CFReleaseNull(pubAppLabel);
1053 CFReleaseNull(kzib);
1054 delete_key(&pubKey);
1055 delete_key(&privKey);
1056 }
1057
1058 #define kCopyPublicKeyTestCount 5
1059 static void testcopypublickey(unsigned long keySizeInBits, bool extractable, bool permanent) {
1060 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
1061 int32_t keysz32 = (int32_t)keySizeInBits;
1062
1063 CFNumberRef kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &keysz32);
1064 CFMutableDictionaryRef kgp = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks,
1065 &kCFTypeDictionaryValueCallBacks);
1066 CFDictionarySetValue(kgp, kSecAttrKeyType, kSecAttrKeyTypeRSA);
1067 CFDictionarySetValue(kgp, kSecAttrKeySizeInBits, kzib);
1068 CFDictionarySetValue(kgp, kSecAttrIsPermanent, permanent ? kCFBooleanTrue : kCFBooleanFalse);
1069 CFDictionarySetValue(kgp, kSecAttrIsExtractable, extractable ? kCFBooleanTrue : kCFBooleanFalse);
1070 CFDictionarySetValue(kgp, kSecAttrLabel, CFSTR("sectests:copypublickey"));
1071 SecKeyRef pubKey = NULL, privKey = NULL;
1072 OSStatus status;
1073 if (permanent) {
1074 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
1075 "Generate %ld bit (%ld byte) RSA keypair (status = %d)",
1076 keySizeInBits, keySizeInBytes, (int)status);
1077 } else {
1078 NSError *error = nil;
1079 privKey = SecKeyCreateRandomKey(kgp, (void *)&error);
1080 pubKey = SecKeyCopyPublicKey(privKey);
1081 ok(privKey != NULL && pubKey != NULL, "Generate %ld bit (%ld byte) RSA keypair (error %@)",
1082 keySizeInBits, keySizeInBytes, error);
1083 }
1084 CFReleaseNull(kgp);
1085 CFReleaseNull(kzib);
1086
1087 CFDataRef pubKeyData = SecKeyCopyExternalRepresentation(pubKey, NULL);
1088
1089 SecKeyRef pubKeyCopy = NULL;
1090
1091 { // privKey
1092 pubKeyCopy = SecKeyCopyPublicKey(privKey);
1093 ok(pubKeyCopy, "priv key SecKeyCopyPublicKey failed");
1094 CFDataRef pubKeyCopyData = SecKeyCopyExternalRepresentation(pubKeyCopy, NULL);
1095 eq_cf(pubKeyCopyData, pubKeyData, "pub key from priv key SecKeyCopyPublicKey and pub key differ");
1096 CFReleaseNull(pubKeyCopy);
1097 CFReleaseNull(pubKeyCopyData);
1098 }
1099
1100 { // pubKey
1101 pubKeyCopy = SecKeyCopyPublicKey(pubKey);
1102 ok(pubKeyCopy, "pub key SecKeyCopyPublicKey failed");
1103 CFDataRef pubKeyCopyData = SecKeyCopyExternalRepresentation(pubKeyCopy, NULL);
1104 eq_cf(pubKeyCopyData, pubKeyData, "pub key from pub key SecKeyCopyPublicKey and pub key differ");
1105 CFReleaseNull(pubKeyCopy);
1106 CFReleaseNull(pubKeyCopyData);
1107 }
1108
1109 CFReleaseNull(pubKeyData);
1110 if (permanent) {
1111 delete_key(&pubKey);
1112 delete_key(&privKey);
1113 } else {
1114 CFReleaseSafe(pubKey);
1115 CFReleaseSafe(privKey);
1116 }
1117 }
1118
1119 static const char *kCertWithPubK = "\
1120 MIIELjCCAxagAwIBAgIJALJlcYRBqZlZMA0GCSqGSIb3DQEBBQUAMIGUMQswCQYDVQQGEwJVUzELMAkG\
1121 A1UECBMCQ0ExEjAQBgNVBAcTCUN1cGVydGlubzETMBEGA1UEChMKQXBwbGUgSW5jLjEPMA0GA1UECxMG\
1122 Q29yZU9TMRwwGgYDVQQDExNBcHBsZSBUZXN0IENBMSBDZXJ0MSAwHgYJKoZIhvcNAQkBFhF2a3V6ZWxh\
1123 QGFwcGxlLmNvbTAeFw0xNTA0MjkwODMyMDBaFw0yNTA0MjYwODMyMDBaMIGPMQswCQYDVQQGEwJVUzEL\
1124 MAkGA1UECBMCQ0ExEjAQBgNVBAcTCUN1cGVydGlubzETMBEGA1UEChMKQXBwbGUgSW5jLjEQMA4GA1UE\
1125 CxMHQ29yZSBPUzEWMBQGA1UEAxMNRmlsaXAgU3Rva2xhczEgMB4GCSqGSIb3DQEJARYRc3Rva2xhc0Bh\
1126 cHBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZcPMvjpu7i/2SkNDCrSC4Wa8m\
1127 j3r6Lgn0crL4AgU+g3apptyy1eFf4RpNRJTGJ9ZMApbRZ0b7wX87Dq6UlCJUI9RJPOy+/TW0FM6mUVaF\
1128 VSY+P+KMdRYGIOMLVI+LR6lRTf8MWbxZ238cqAIVnLHaE9HrXjyIrgX2IufJjt69WhwsJZuan7jmeXJS\
1129 0AnESB31wS5NOn0tFDtzNAAQmoP8N8q6ZNC85tPVWBM61YLNjwSYl74y14QfX401P2pQRvwxTortRImk\
1130 xjN4DBprG23e59UW2IBxYsqUA61jhA0yVy8gxYpCGa4bEBslhrnkAoSv+Zlyk7u2GyO13AC1dfRxAgMB\
1131 AAGjgYUwgYIwPwYDVR0RBDgwNqAhBgorBgEEAYI3FAIDoBMMEXN0b2tsYXNAYXBwbGUuY29tgRFzdG9r\
1132 bGFzQGFwcGxlLmNvbTA/BgNVHREEODA2oCEGCisGAQQBgjcUAgOgEwwRc3Rva2xhc0BhcHBsZS5jb22B\
1133 EXN0b2tsYXNAYXBwbGUuY29tMA0GCSqGSIb3DQEBBQUAA4IBAQB87bZdl4XEDFA7UdPouhR3dKRl6evS\
1134 MfC9/0jVcdB+P1mNJ/vIZdOZMY0asieOXhsI91nEcHUjbBCnu18mu2jR6SGiJsS/zr6enkpQMcztulMU\
1135 kcjuSjT1hEzRv0LvEgWPOK+VpVqk6N0ZhybBQYVH2ECf7OU48CkFQFg9eLv6VaSK9+FqcBWpq8fXyOa7\
1136 bL58bO5A3URHcmMWibv9/j+lpVeQBxt1UUwqBZT7DSLPw3QCj/zXfAGEu3izvEYaWwsQDhItwQJ6g6pp\
1137 DLO741C7K8eKgvGs8ptna4RSosQda9bdnhZwT+g0UcorsVTUo+sR9+LW7INJ1zovRCL7NXit";
1138
1139 static const char *kPubK = "\
1140 MIIBCgKCAQEA2XDzL46bu4v9kpDQwq0guFmvJo96+i4J9HKy+AIFPoN2qabcstXhX+EaTUSUxifWTAKW\
1141 0WdG+8F/Ow6ulJQiVCPUSTzsvv01tBTOplFWhVUmPj/ijHUWBiDjC1SPi0epUU3/DFm8Wdt/HKgCFZyx\
1142 2hPR6148iK4F9iLnyY7evVocLCWbmp+45nlyUtAJxEgd9cEuTTp9LRQ7czQAEJqD/DfKumTQvObT1VgT\
1143 OtWCzY8EmJe+MteEH1+NNT9qUEb8MU6K7USJpMYzeAwaaxtt3ufVFtiAcWLKlAOtY4QNMlcvIMWKQhmu\
1144 GxAbJYa55AKEr/mZcpO7thsjtdwAtXX0cQIDAQAB";
1145
1146 static const int kTestCountCopyPubKFromCert = 2;
1147 static void testcopypubkfromcert() {
1148 NSData *certData = [[NSData alloc] initWithBase64EncodedString:[NSString stringWithUTF8String:kCertWithPubK]
1149 options:NSDataBase64DecodingIgnoreUnknownCharacters];
1150 NSData *pubKData = [[NSData alloc] initWithBase64EncodedString:[NSString stringWithUTF8String:kPubK]
1151 options:NSDataBase64DecodingIgnoreUnknownCharacters];
1152 SecCertificateRef cert = SecCertificateCreateWithData(kCFAllocatorDefault, (CFDataRef)certData);
1153 SecKeyRef pubKey = NULL;
1154 ok_status(SecCertificateCopyPublicKey(cert, &pubKey), "export public key from certificate");
1155 NSData *pubKeyData = (__bridge_transfer NSData *)SecKeyCopyExternalRepresentation(pubKey, NULL);
1156 eq_cf( (__bridge CFTypeRef) pubKeyData, (__bridge CFTypeRef) pubKData, "public key exports itself into expected data");
1157 CFReleaseNull(pubKey);
1158 CFReleaseNull(cert);
1159 }
1160
1161 static inline CFDataRef CFDataCreateWithHash(CFAllocatorRef allocator, const struct ccdigest_info *di, const uint8_t *buffer, const uint8_t length) {
1162 CFMutableDataRef result = CFDataCreateMutable(allocator, di->output_size);
1163 CFDataSetLength(result, di->output_size);
1164
1165 ccdigest(di, length, buffer, CFDataGetMutableBytePtr(result));
1166
1167 return result;
1168 }
1169
1170 #define kSignAndVerifyTestCount 130
1171 static void testsignverify(unsigned long keySizeInBits)
1172 {
1173 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
1174 int32_t keysz32 = (int32_t)keySizeInBits;
1175
1176 CFNumberRef kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &keysz32);
1177 CFMutableDictionaryRef kgp = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks,
1178 &kCFTypeDictionaryValueCallBacks);
1179 CFDictionarySetValue(kgp, kSecAttrKeyType, kSecAttrKeyTypeRSA);
1180 CFDictionarySetValue(kgp, kSecAttrKeySizeInBits, kzib);
1181 CFDictionarySetValue(kgp, kSecAttrIsPermanent, kCFBooleanFalse);
1182 CFDictionarySetValue(kgp, kSecAttrLabel, CFSTR("sectests:signverify"));
1183 SecKeyRef pubKey = NULL, privKey = NULL, pubKeyIOS = NULL, privKeyIOS = NULL;
1184 OSStatus status;
1185 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
1186 "Generate %ld bit (%ld byte) RSA keypair (status = %d)",
1187 keySizeInBits, keySizeInBytes, (int)status);
1188 CFReleaseNull(kgp);
1189 CFReleaseNull(kzib);
1190
1191 CFDataRef privKeyData = SecKeyCopyExternalRepresentation(privKey, NULL);
1192 CFDictionaryRef privKeyAttrs = SecKeyCopyAttributes(privKey);
1193 privKeyIOS = SecKeyCreateWithData(privKeyData, privKeyAttrs, NULL);
1194 CFReleaseNull(privKeyData);
1195 CFReleaseNull(privKeyAttrs);
1196 ok(privKeyIOS, "create IOS version of the private key");
1197
1198 CFDataRef pubKeyData = SecKeyCopyExternalRepresentation(pubKey, NULL);
1199 CFDictionaryRef pubKeyAttrs = SecKeyCopyAttributes(pubKey);
1200 pubKeyIOS = SecKeyCreateWithData(pubKeyData, pubKeyAttrs, NULL);
1201 CFReleaseNull(pubKeyData);
1202 CFReleaseNull(pubKeyAttrs);
1203 ok(pubKeyIOS, "create IOS version of the public key");
1204
1205 SecKeyAlgorithm algorithms[] = {
1206 kSecKeyAlgorithmRSASignatureRaw,
1207 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1,
1208 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA224,
1209 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256,
1210 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384,
1211 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512,
1212 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1,
1213 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA224,
1214 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256,
1215 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA384,
1216 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA512,
1217 };
1218
1219 CFDataRef testData = CFStringCreateExternalRepresentation(kCFAllocatorDefault, CFSTR("test"), kCFStringEncodingUTF8, 0);
1220 ok(testData, "creating test data failed");
1221
1222 SKIP: {
1223 skip("invalid test data", 71, testData);
1224
1225 CFErrorRef error = NULL;
1226
1227 for (uint32_t ix = 0; ix < array_size(algorithms); ++ix) {
1228 SecKeyAlgorithm algorithm = algorithms[ix];
1229 SecKeyAlgorithm incompatibleAlgorithm = (CFEqual(algorithm, kSecKeyAlgorithmRSASignatureRaw)) ?
1230 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1 : kSecKeyAlgorithmRSASignatureRaw;
1231
1232 CFDataRef dataToSign = NULL;
1233 if (CFEqual(algorithm, kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1)) {
1234 dataToSign = CFDataCreateWithHash(kCFAllocatorDefault, ccsha1_di(),
1235 CFDataGetBytePtr(testData), CFDataGetLength(testData));
1236 ok(dataToSign, "creating digest failed for algorithm %@", algorithm);
1237 }
1238 else if (CFEqual(algorithm, kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA224)) {
1239 dataToSign = CFDataCreateWithHash(kCFAllocatorDefault, ccsha224_di(),
1240 CFDataGetBytePtr(testData), CFDataGetLength(testData));
1241 ok(dataToSign, "creating digest failed for algorithm %@", algorithm);
1242 }
1243 else if (CFEqual(algorithm, kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256)) {
1244 dataToSign = CFDataCreateWithHash(kCFAllocatorDefault, ccsha256_di(),
1245 CFDataGetBytePtr(testData), CFDataGetLength(testData));
1246 ok(dataToSign, "creating digest failed for algorithm %@", algorithm);
1247 }
1248 else if (CFEqual(algorithm, kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384)) {
1249 dataToSign = CFDataCreateWithHash(kCFAllocatorDefault, ccsha384_di(),
1250 CFDataGetBytePtr(testData), CFDataGetLength(testData));
1251 ok(dataToSign, "creating digest failed for algorithm %@", algorithm);
1252 }
1253 else if (CFEqual(algorithm, kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512)) {
1254 dataToSign = CFDataCreateWithHash(kCFAllocatorDefault, ccsha512_di(),
1255 CFDataGetBytePtr(testData), CFDataGetLength(testData));
1256 ok(dataToSign, "creating digest failed for algorithm %@", algorithm);
1257 }
1258 else {
1259 CFRetainAssign(dataToSign, testData);
1260 }
1261 CFReleaseNull(error);
1262
1263 SKIP: {
1264 skip("invalid data to sign", 7, dataToSign);
1265
1266 CFDataRef signature = SecKeyCreateSignature(pubKey, algorithm, dataToSign, &error);
1267 ok(!signature, "SecKeyCopySignature succeeded with pub key for algorithm %@", algorithm);
1268 CFReleaseNull(error);
1269 CFReleaseNull(signature);
1270
1271 signature = SecKeyCreateSignature(privKey, algorithm, dataToSign, &error);
1272 ok(signature, "SecKeyCopySignature failed for algorithm %@", algorithm);
1273 CFReleaseNull(error);
1274
1275 CFDataRef iosSignature = SecKeyCreateSignature(privKeyIOS, algorithm, dataToSign, &error);
1276 ok(iosSignature, "SecKeyCopySignature(ios) failed for algorithm %@", algorithm);
1277 CFReleaseNull(error);
1278
1279 SKIP: {
1280 skip("invalid signature", 4, signature);
1281
1282 ok(!SecKeyVerifySignature(privKey, algorithm, dataToSign, signature, &error),
1283 "SecKeyVerifySignature succeeded with priv key for algorithm %@", algorithm);
1284 CFReleaseNull(error);
1285
1286 ok(!SecKeyVerifySignature(pubKey, incompatibleAlgorithm, dataToSign, signature, &error),
1287 "SecKeyVerifySignature succeeded with wrong algorithm for algorithm %@", algorithm);
1288 CFReleaseNull(error);
1289
1290 ok(SecKeyVerifySignature(pubKey, algorithm, dataToSign, signature, &error),
1291 "SecKeyVerifySignature(osx) failed osx-signature for algorithm %@", algorithm);
1292 CFReleaseNull(error);
1293
1294 ok(SecKeyVerifySignature(pubKeyIOS, algorithm, dataToSign, signature, &error),
1295 "SecKeyVerifySignature(ios) failed for osx-signature for algorithm %@", algorithm);
1296
1297 ok(SecKeyVerifySignature(pubKey, algorithm, dataToSign, iosSignature, &error),
1298 "SecKeyVerifySignature(osx) failed for ios-signature for algorithm %@", algorithm);
1299 CFReleaseNull(error);
1300
1301 ok(SecKeyVerifySignature(pubKeyIOS, algorithm, dataToSign, iosSignature, &error),
1302 "SecKeyVerifySignature(ios) failed for ios-signature for algorithm %@", algorithm);
1303
1304 CFMutableDataRef modifiedSignature = CFDataCreateMutableCopy(kCFAllocatorDefault, 0, signature);
1305 *CFDataGetMutableBytePtr(modifiedSignature) ^= 0xff;
1306
1307 ok(!SecKeyVerifySignature(pubKey, algorithm, dataToSign, modifiedSignature, &error),
1308 "SecKeyVerifySignature succeeded with bad signature for algorithm %@", algorithm);
1309 CFReleaseNull(error);
1310
1311 CFMutableDataRef modifiedDataToSign = CFDataCreateMutableCopy(kCFAllocatorDefault, 0, dataToSign);
1312 *CFDataGetMutableBytePtr(modifiedDataToSign) ^= 0xff;
1313
1314 ok(!SecKeyVerifySignature(pubKey, algorithm, modifiedDataToSign, signature, &error),
1315 "SecKeyVerifySignature succeeded with bad data for algorithm %@", algorithm);
1316 CFReleaseNull(error);
1317
1318 CFReleaseNull(modifiedDataToSign);
1319 CFReleaseNull(modifiedSignature);
1320 CFReleaseNull(signature);
1321 CFReleaseNull(iosSignature);
1322 }
1323 CFReleaseNull(dataToSign);
1324 }
1325 }
1326 CFReleaseNull(testData);
1327 }
1328
1329 delete_key(&pubKey);
1330 delete_key(&privKey);
1331 CFReleaseNull(pubKeyIOS);
1332 CFReleaseNull(privKeyIOS);
1333 }
1334
1335 #define kNonExtractableTestCount 6
1336 static void testnonextractable(unsigned long keySizeInBits)
1337 {
1338 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
1339 int32_t keysz32 = (int32_t)keySizeInBits;
1340
1341 CFNumberRef kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &keysz32);
1342 CFMutableDictionaryRef kgp = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks,
1343 &kCFTypeDictionaryValueCallBacks);
1344 CFDictionarySetValue(kgp, kSecAttrKeyType, kSecAttrKeyTypeRSA);
1345 CFDictionarySetValue(kgp, kSecAttrKeySizeInBits, kzib);
1346 CFDictionarySetValue(kgp, kSecAttrIsPermanent, kCFBooleanTrue);
1347 CFDictionarySetValue(kgp, kSecAttrIsExtractable, kCFBooleanFalse);
1348 CFStringRef label = CFSTR("sectests:nonextractable");
1349 CFDictionarySetValue(kgp, kSecAttrLabel, label);
1350 SecKeyRef pubKey = NULL, privKey = NULL;
1351 OSStatus status;
1352 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
1353 "Generate %ld bit (%ld byte) RSA keypair (status = %d)",
1354 keySizeInBits, keySizeInBytes, (int)status);
1355 CFReleaseNull(kgp);
1356 CFReleaseNull(kzib);
1357
1358 // Get attributes, verify that ApplicationLabel is set and equals for both keys.
1359 CFDictionaryRef privAttrs = SecKeyCopyAttributes(privKey);
1360 CFDictionaryRef pubAttrs = SecKeyCopyAttributes(pubKey);
1361
1362 ok(privAttrs, "able to get private key attributes");
1363 ok(pubAttrs, "able to get public key attributes");
1364
1365 CFDataRef privLabel = CFDictionaryGetValue(privAttrs, kSecAttrApplicationLabel);
1366 CFDataRef pubLabel = CFDictionaryGetValue(pubAttrs, kSecAttrApplicationLabel);
1367
1368 ok(privLabel && CFGetTypeID(privLabel) == CFDataGetTypeID() && CFDataGetLength(privLabel) == 20,
1369 "priv appLabel is present and of correct type");
1370 ok(pubLabel && CFGetTypeID(pubLabel) == CFDataGetTypeID() && CFDataGetLength(pubLabel) == 20,
1371 "priv appLabel is present and of correct type");
1372 eq_cf(privLabel, pubLabel, "applabels of pub and priv keys are equal");
1373
1374 CFReleaseNull(pubAttrs);
1375 CFReleaseNull(privAttrs);
1376
1377 delete_key(&pubKey);
1378 delete_key(&privKey);
1379 }
1380
1381 #define kTestCount ((2 * kKeyGenTestCount) + kKeyGen2TestCount + (int) (kdfvLen*3)) + \
1382 kTestSupportedCount + kCreateWithDataTestCount + (kCopyAttributesTestCount * 2) + (kCopyPublicKeyTestCount * 4) + \
1383 kSignAndVerifyTestCount + kNonExtractableTestCount + \
1384 kTestCountCopyPubKFromCert
1385
1386 static void tests(void)
1387 {
1388 /* Comment out lines below for testing generating all common key sizes,
1389 disabled now for speed reasons. */
1390 //testkeygen(512);
1391 //testkeygen(768);
1392 testkeygen(1024);
1393 testkeygen(2056); // Stranged sized for edge cases in padding.
1394 //testkeygen(2048);
1395 //testkeygen(4096);
1396
1397 testkeygen2(1024); // lots of FAIL!
1398
1399 testsupportedalgos(1024);
1400 testcreatewithdata(1024);
1401 testcopyattributes(1024, true);
1402 testcopyattributes(1024, false);
1403 testcopypublickey(1024, true, true);
1404 testcopypublickey(1024, false, true);
1405 testcopypublickey(1024, true, false);
1406 testcopypublickey(1024, false, false);
1407 testsignverify(1024);
1408 testnonextractable(1024);
1409
1410 #if !TARGET_OS_IPHONE
1411 testkeyderivation();
1412 #endif
1413
1414 testcopypubkfromcert();
1415 }
1416
1417 int kc_40_seckey(int argc, char *const *argv)
1418 {
1419 plan_tests(kTestCount);
1420
1421 tests();
1422
1423 return 0;
1424 }