]> git.saurik.com Git - apple/security.git/blob - OSX/sec/Security/Regressions/secitem/si-40-seckey.c
Security-57740.1.18.tar.gz
[apple/security.git] / OSX / sec / Security / Regressions / secitem / si-40-seckey.c
1 /*
2 * Copyright (c) 2007-2009,2012-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 <CoreFoundation/CoreFoundation.h>
26 #include <Security/SecCertificate.h>
27 #include <Security/SecCertificateInternal.h>
28 #include <Security/SecKey.h>
29 #include <Security/SecKeyPriv.h>
30 #include <Security/SecItem.h>
31 #include <Security/SecAsn1Types.h>
32 #include <Security/oidsalg.h>
33 #include <Security/SecureTransport.h>
34 #include <Security/SecRandom.h>
35 #include <utilities/array_size.h>
36 #include <utilities/SecCFWrappers.h>
37 #include <CommonCrypto/CommonDigest.h>
38 #include <libDER/libDER.h>
39 #include <stdlib.h>
40 #include <unistd.h>
41 #include <corecrypto/ccsha1.h>
42 #include <corecrypto/ccsha2.h>
43
44 #include "Security_regressions.h"
45
46 #include "utilities/SecCFRelease.h"
47
48 static void testdigestandsignalg(SecKeyRef privKey, SecKeyRef pubKey, const SecAsn1AlgId *algId) {
49 uint8_t dataToDigest[256] = {0,};
50 size_t dataToDigestLen = sizeof(dataToDigest);
51 size_t sigLen = SecKeyGetSize(privKey, kSecKeySignatureSize);
52 uint8_t sig[sigLen];
53
54 DERItem oid;
55 oid.length = algId->algorithm.Length;
56 oid.data = algId->algorithm.Data;
57
58 /* Get the oid in decimal for display purposes. */
59 CFStringRef oidStr = SecDERItemCopyOIDDecimalRepresentation(kCFAllocatorDefault, &oid);
60 char oidBuf[40];
61 CFStringGetCString(oidStr, oidBuf, sizeof(oidBuf), kCFStringEncodingUTF8);
62 CFRelease(oidStr);
63
64 SKIP: {
65 OSStatus status;
66
67 /* Time to sign. */
68 ok_status(status = SecKeyDigestAndSign(privKey, algId, dataToDigest, dataToDigestLen,
69 sig, &sigLen), "digest and sign %s with %ld bit RSA key", oidBuf, sigLen * 8);
70
71 skip("SecKeyDigestAndSign failed", 3, status == errSecSuccess);
72
73 /* Verify the signature we just made. */
74 ok_status(SecKeyDigestAndVerify(pubKey, algId, dataToDigest, dataToDigestLen,
75 sig, sigLen), "digest and verify");
76 /* Invalidate the signature. */
77 sig[0] ^= 0xff;
78 is_status(SecKeyDigestAndVerify(pubKey, algId, dataToDigest, dataToDigestLen,
79 sig, sigLen), errSSLCrypto, "digest and verify bad sig");
80 sig[0] ^= 0xff;
81 dataToDigest[0] ^= 0xff;
82 is_status(SecKeyDigestAndVerify(pubKey, algId, dataToDigest, dataToDigestLen,
83 sig, sigLen), errSSLCrypto, "digest and verify bad digest");
84 }
85 }
86
87 static void testdigestandsign(SecKeyRef privKey, SecKeyRef pubKey) {
88 static const SecAsn1Oid *oids[] = {
89 &CSSMOID_SHA1WithRSA,
90 &CSSMOID_SHA224WithRSA,
91 &CSSMOID_SHA256WithRSA,
92 &CSSMOID_SHA384WithRSA,
93 &CSSMOID_SHA512WithRSA,
94 #if 0
95 &CSSMOID_SHA1WithRSA_OIW,
96 &CSSMOID_SHA1WithDSA, // BSAFE
97 &CSSMOID_SHA1WithDSA_CMS, // X509/CMS
98 &CSSMOID_SHA1WithDSA_JDK, // JDK 1.1
99 #endif
100 };
101
102
103 uint32_t ix;
104 SecAsn1AlgId algId = {};
105 for (ix = 0; ix < array_size(oids); ++ix) {
106 if (oids[ix]) {
107 algId.algorithm = *oids[ix];
108 } else {
109 algId.algorithm.Length = 0;
110 algId.algorithm.Data = NULL;
111 }
112
113 testdigestandsignalg(privKey, pubKey, &algId);
114 }
115 }
116
117 #if 0
118 static void dump_bytes(uint8_t* bytes, size_t amount)
119 {
120 while (amount > 0) {
121 printf("0x%02x ", *bytes);
122 ++bytes;
123 --amount;
124 }
125 }
126 #endif
127
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 + 2], 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
176 #define kKeyGenTestCount (50 + (3*kEncryptDecryptTestCount))
177 static void testkeygen(size_t keySizeInBits) {
178 SecKeyRef pubKey = NULL, privKey = NULL;
179 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
180 CFNumberRef kzib;
181
182 int32_t iKeySizeInBits = (int32_t) keySizeInBits;
183 kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &iKeySizeInBits);
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(SecKeyGetSize(pubKey, kSecKeyKeySizeInBits), (size_t) keySizeInBits, "public key size is ok");
200 is(SecKeyGetSize(privKey, kSecKeyKeySizeInBits), (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 (privKey != NULL && pubKey != NULL) {
209 is_status(SecKeyRawSign(privKey, kSecPaddingPKCS1,
210 something, something_len + 1, sig, &sigLen),
211 errSecParam, "sign overflow");
212 ok_status(SecKeyRawSign(privKey, kSecPaddingPKCS1,
213 something, something_len, sig, &sigLen), "sign something");
214 ok_status(SecKeyRawVerify(pubKey, kSecPaddingPKCS1,
215 something, something_len, sig, sigLen), "verify sig on something");
216
217 // Torture test ASN.1 encoder by setting high bit to 1.
218 uint8_t digest[CC_SHA512_DIGEST_LENGTH] = {
219 0x80, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
220 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
221 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
222 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
223 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
224 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
225 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
226 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
227 };
228 //CC_MD2(something, sizeof(something), digest);
229 ok_status(!SecKeyRawSign(privKey, kSecPaddingPKCS1MD2,
230 digest, CC_MD2_DIGEST_LENGTH, sig, &sigLen),
231 "don't sign md2 digest");
232 ok_status(!SecKeyRawVerify(pubKey, kSecPaddingPKCS1MD2,
233 digest, CC_MD2_DIGEST_LENGTH, sig, sigLen),
234 "verify sig on md2 digest fails");
235
236 //CC_MD5(something, sizeof(something), digest);
237 sigLen = sizeof(sig);
238 ok_status(!SecKeyRawSign(privKey, kSecPaddingPKCS1MD5,
239 digest, CC_MD5_DIGEST_LENGTH, sig, &sigLen),
240 "don't sign md5 digest");
241 ok_status(!SecKeyRawVerify(pubKey, kSecPaddingPKCS1MD5,
242 digest, CC_MD5_DIGEST_LENGTH, sig, sigLen),
243 "verify sig on md5 digest fails");
244
245 //CCDigest(kCCDigestSHA1, something, sizeof(something), digest);
246 sigLen = sizeof(sig);
247 ok_status(SecKeyRawSign(privKey, kSecPaddingPKCS1SHA1,
248 digest, CC_SHA1_DIGEST_LENGTH, sig, &sigLen),
249 "sign sha1 digest");
250 ok_status(SecKeyRawVerify(pubKey, kSecPaddingPKCS1SHA1,
251 digest, CC_SHA1_DIGEST_LENGTH, sig, sigLen),
252 "verify sig on sha1 digest");
253
254 uint8_t signature[keySizeInBytes], *ptr = signature;
255 size_t signature_len = sizeof(signature);
256 ok_status(SecKeyDecrypt(pubKey, kSecPaddingNone, sig, sigLen, signature, &signature_len), "inspect signature");
257 is(signature_len, keySizeInBytes - 1, "got signature");
258 while(*ptr && ((size_t)(ptr - signature) < signature_len)) ptr++;
259 is(signature + signature_len - ptr, 16 /* length(\0 || OID_SHA1) */ + CC_SHA1_DIGEST_LENGTH, "successful decode");
260
261 /* PKCS1 padding is 00 01 PAD * 8 or more 00 data.
262 data is SEQ { SEQ { OID NULL } BIT STRING 00 DIGEST }
263 So min data + pad overhead is 11 + 9 + oidlen
264 oidlen = 11 for the sha2 family of oids, so we have 29 bytes; or
265 232 bits of minimum overhead. */
266 const size_t pkcs1Overhead = 232;
267 if (keySizeInBits > 224 + pkcs1Overhead) {
268 //CC_SHA224(something, sizeof(something), digest);
269 sigLen = sizeof(sig);
270 ok_status(SecKeyRawSign(privKey, kSecPaddingPKCS1SHA224,
271 digest, CC_SHA224_DIGEST_LENGTH, sig, &sigLen),
272 "sign sha224 digest");
273 ok_status(SecKeyRawVerify(pubKey, kSecPaddingPKCS1SHA224,
274 digest, CC_SHA224_DIGEST_LENGTH, sig, sigLen),
275 "verify sig on sha224 digest");
276 }
277
278 if (keySizeInBits > 256 + pkcs1Overhead) {
279 //CC_SHA256(something, sizeof(something), digest);
280 sigLen = sizeof(sig);
281 ok_status(SecKeyRawSign(privKey, kSecPaddingPKCS1SHA256,
282 digest, CC_SHA256_DIGEST_LENGTH, sig, &sigLen),
283 "sign sha256 digest");
284 ok_status(SecKeyRawVerify(pubKey, kSecPaddingPKCS1SHA256,
285 digest, CC_SHA256_DIGEST_LENGTH, sig, sigLen),
286 "verify sig on sha256 digest");
287 }
288
289 if (keySizeInBits > 384 + pkcs1Overhead) {
290 //CC_SHA384(something, sizeof(something), digest);
291 sigLen = sizeof(sig);
292 ok_status(SecKeyRawSign(privKey, kSecPaddingPKCS1SHA384,
293 digest, CC_SHA384_DIGEST_LENGTH, sig, &sigLen),
294 "sign sha384 digest");
295 ok_status(SecKeyRawVerify(pubKey, kSecPaddingPKCS1SHA384,
296 digest, CC_SHA384_DIGEST_LENGTH, sig, sigLen),
297 "verify sig on sha384 digest");
298 }
299
300 if (keySizeInBits > 512 + pkcs1Overhead) {
301 //CC_SHA512(something, sizeof(something), digest);
302 sigLen = sizeof(sig);
303 ok_status(SecKeyRawSign(privKey, kSecPaddingPKCS1SHA512,
304 digest, CC_SHA512_DIGEST_LENGTH, sig, &sigLen),
305 "sign sha512 digest");
306 ok_status(SecKeyRawVerify(pubKey, kSecPaddingPKCS1SHA512,
307 digest, CC_SHA512_DIGEST_LENGTH, sig, sigLen),
308 "verify sig on sha512 digest");
309 }
310 }
311
312 test_encrypt_decrypt(pubKey, privKey, kSecPaddingNone, keySizeInBytes);
313 test_encrypt_decrypt(pubKey, privKey, kSecPaddingPKCS1, keySizeInBytes);
314 test_encrypt_decrypt(pubKey, privKey, kSecPaddingOAEP, keySizeInBytes);
315
316 testdigestandsign(privKey, pubKey);
317
318 const void *privkeys[] = {
319 kSecValueRef
320 };
321 const void *privvalues[] = {
322 privKey
323 };
324 CFDictionaryRef privitem = CFDictionaryCreate(NULL, privkeys, privvalues,
325 array_size(privkeys), NULL, NULL);
326 ok_status(SecItemAdd(privitem, NULL), "add private key");
327 ok_status(SecItemDelete(privitem), "delete private key");
328 CFReleaseNull(privitem);
329
330 const void *pubkeys[] = {
331 kSecValueRef
332 };
333 const void *pubvalues[] = {
334 pubKey
335 };
336 CFDictionaryRef pubitem = CFDictionaryCreate(NULL, pubkeys, pubvalues,
337 array_size(pubkeys), NULL, NULL);
338 ok_status(SecItemAdd(pubitem, NULL), "add public key");
339 ok_status(SecItemDelete(pubitem), "delete public key");
340 CFReleaseNull(pubitem);
341
342 /* Cleanup. */
343 CFReleaseNull(pubKey);
344 CFReleaseNull(privKey);
345 }
346 }
347
348 #define kKeyGen2TestCount 12
349 static void testkeygen2(size_t keySizeInBits) {
350 SecKeyRef pubKey = NULL, privKey = NULL;
351 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
352 CFNumberRef kzib;
353
354 CFUUIDRef ourUUID = CFUUIDCreate(kCFAllocatorDefault);
355 CFStringRef uuidString = CFUUIDCreateString(kCFAllocatorDefault, ourUUID);
356 CFMutableStringRef publicName = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, uuidString);
357 CFMutableStringRef privateName = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, uuidString);
358
359 CFReleaseNull(ourUUID);
360 CFReleaseNull(uuidString);
361
362 CFStringAppend(publicName, CFSTR("-Public-40"));
363 CFStringAppend(privateName, CFSTR("-Private-40"));
364 CFMutableDictionaryRef pubd = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
365 CFMutableDictionaryRef privd = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
366
367 CFDictionaryAddValue(pubd, kSecAttrLabel, publicName);
368 CFDictionaryAddValue(privd, kSecAttrLabel, privateName);
369
370 int32_t iKeySizeInBits = (int32_t) keySizeInBits;
371 kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &iKeySizeInBits);
372 CFMutableDictionaryRef kgp = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
373 CFDictionaryAddValue(kgp, kSecAttrKeyType, kSecAttrKeyTypeRSA);
374 CFDictionaryAddValue(kgp, kSecAttrKeySizeInBits, kzib);
375 CFDictionaryAddValue(kgp, kSecAttrIsPermanent, kCFBooleanTrue);
376 CFDictionaryAddValue(kgp, kSecPublicKeyAttrs, pubd);
377 CFDictionaryAddValue(kgp, kSecPrivateKeyAttrs, privd);
378
379 OSStatus status;
380 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
381 "Generate %ld bit (%ld byte) persistent RSA keypair",
382 keySizeInBits, keySizeInBytes);
383 CFRelease(kzib);
384 CFRelease(kgp);
385
386 SKIP: {
387 skip("keygen failed", 8, status == errSecSuccess);
388 ok(pubKey, "pubkey returned");
389 ok(privKey, "privKey returned");
390 is(SecKeyGetSize(pubKey, kSecKeyKeySizeInBits), (size_t) keySizeInBits, "public key size is ok");
391 is(SecKeyGetSize(privKey, kSecKeyKeySizeInBits), (size_t) keySizeInBits, "private key size is ok");
392
393 SecKeyRef pubKey2, privKey2;
394 CFDictionaryAddValue(pubd, kSecClass, kSecClassKey);
395 CFDictionaryAddValue(pubd, kSecReturnRef, kCFBooleanTrue);
396 CFDictionaryAddValue(privd, kSecClass, kSecClassKey);
397 CFDictionaryAddValue(privd, kSecReturnRef, kCFBooleanTrue);
398 CFDictionaryAddValue(privd, kSecAttrCanSign, kCFBooleanTrue);
399 ok_status(SecItemCopyMatching(pubd, (CFTypeRef *)&pubKey2),
400 "retrieve pub key by label");
401 ok_status(SecItemCopyMatching(privd, (CFTypeRef *)&privKey2),
402 "retrieve priv key by label and kSecAttrCanSign");
403
404 /* Sign something. */
405 uint8_t something[50] = {0x80, 0xbe, 0xef, 0xba, 0xd0, };
406 uint8_t sig[keySizeInBytes];
407 size_t sigLen = keySizeInBytes;
408 ok_status(SecKeyRawSign(privKey2, kSecPaddingPKCS1,
409 something, sizeof(something), sig, &sigLen), "sign something");
410 ok_status(SecKeyRawVerify(pubKey2, kSecPaddingPKCS1,
411 something, sizeof(something), sig, sigLen), "verify sig on something");
412
413 sigLen = keySizeInBytes;
414 is_status(SecKeyEncrypt(pubKey2, kSecPaddingPKCS1SHA1,
415 something, sizeof(something), sig, &sigLen), errSecParam,
416 "encrypt something with invalid padding");
417
418 /* Cleanup. */
419 CFReleaseNull(pubKey2);
420 CFReleaseNull(privKey2);
421
422 /* delete from keychain - note: do it before releasing publicName and privateName
423 because pubd and privd have no retain/release callbacks */
424 ok_status(SecItemDelete(pubd), "delete generated pub key");
425 ok_status(SecItemDelete(privd), "delete generated priv key");
426 }
427
428 /* Cleanup. */
429 CFReleaseNull(pubKey);
430 CFReleaseNull(privKey);
431
432 CFReleaseNull(publicName);
433 CFReleaseNull(privateName);
434
435 CFRelease(pubd);
436 CFRelease(privd);
437 }
438
439 static const int kTestSupportedCount = 3 + (4 * 11) + 2 + (4 * 5);
440 static void testsupportedalgos(size_t keySizeInBits)
441 {
442 SecKeyRef pubKey = NULL, privKey = NULL;
443 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
444 CFNumberRef kzib;
445
446 int32_t iKeySizeInBits = (int32_t) keySizeInBits;
447 kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &iKeySizeInBits);
448 CFMutableDictionaryRef kgp = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
449 CFDictionaryAddValue(kgp, kSecAttrKeyType, kSecAttrKeyTypeRSA);
450 CFDictionaryAddValue(kgp, kSecAttrKeySizeInBits, kzib);
451
452 OSStatus status;
453 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
454 "Generate %ld bit (%ld byte) persistent RSA keypair",
455 keySizeInBits, keySizeInBytes);
456 CFRelease(kzib);
457 CFRelease(kgp);
458
459 is(SecKeyGetSize(pubKey, kSecKeyKeySizeInBits), (size_t) keySizeInBits, "public key size is ok");
460 is(SecKeyGetSize(privKey, kSecKeyKeySizeInBits), (size_t) keySizeInBits, "private key size is ok");
461
462 const SecKeyAlgorithm sign[] = {
463 kSecKeyAlgorithmRSASignatureRaw,
464 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1,
465 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1,
466 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA224,
467 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA224,
468 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256,
469 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256,
470 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384,
471 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA384,
472 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512,
473 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA512,
474 };
475
476 for (size_t i = 0; i < array_size(sign); i++) {
477 ok(SecKeyIsAlgorithmSupported(privKey, kSecKeyOperationTypeSign, sign[i]),
478 "privKey supports sign algorithm %@", sign[i]);
479 ok(SecKeyIsAlgorithmSupported(pubKey, kSecKeyOperationTypeVerify, sign[i]),
480 "pubKey supports verify algorithm %@", sign[i]);
481 // Our privKey actually supports even verify operation because it is adapter over decrypt...
482 ok(SecKeyIsAlgorithmSupported(privKey, kSecKeyOperationTypeVerify, sign[i]),
483 "privKey supports verify algorithm %@", sign[i]);
484 ok(!SecKeyIsAlgorithmSupported(pubKey, kSecKeyOperationTypeSign, sign[i]),
485 "pubKey doesn't support verify algorithm %@", sign[i]);
486 }
487 ok(!SecKeyIsAlgorithmSupported(privKey, kSecKeyOperationTypeSign, kSecKeyAlgorithmECDSASignatureDigestX962),
488 "RSA privKey does not support ECDSA algorithm");
489 ok(!SecKeyIsAlgorithmSupported(privKey, kSecKeyOperationTypeVerify, kSecKeyAlgorithmECDSASignatureDigestX962),
490 "RSA pubKey does not support ECDSA algorithm");
491
492 const SecKeyAlgorithm crypt[] = {
493 kSecKeyAlgorithmRSAEncryptionRaw,
494 kSecKeyAlgorithmRSAEncryptionPKCS1,
495 kSecKeyAlgorithmRSAEncryptionOAEPSHA1,
496 kSecKeyAlgorithmRSAEncryptionOAEPSHA224,
497 kSecKeyAlgorithmRSAEncryptionOAEPSHA256,
498 // kSecKeyAlgorithmRSAEncryptionOAEPSHA384,
499 // kSecKeyAlgorithmRSAEncryptionOAEPSHA512,
500 };
501 for (size_t i = 0; i < array_size(crypt); i++) {
502 ok(SecKeyIsAlgorithmSupported(privKey, kSecKeyOperationTypeDecrypt, crypt[i]),
503 "privKey supports decrypt algorithm %@", crypt[i]);
504 ok(SecKeyIsAlgorithmSupported(pubKey, kSecKeyOperationTypeEncrypt, crypt[i]),
505 "pubKey supports encrypt algorithm %@", crypt[i]);
506 ok(!SecKeyIsAlgorithmSupported(privKey, kSecKeyOperationTypeEncrypt, crypt[i]),
507 "privKey doesn't supports encrypt algorithm %@", crypt[i]);
508 ok(SecKeyIsAlgorithmSupported(pubKey, kSecKeyOperationTypeDecrypt, crypt[i]),
509 "pubKey supports decrypt algorithm %@", crypt[i]);
510 }
511
512 /* Cleanup. */
513 CFReleaseNull(pubKey);
514 CFReleaseNull(privKey);
515 }
516
517 #define kCreateWithDataTestCount 13
518 static void testcreatewithdata(unsigned long keySizeInBits)
519 {
520 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
521 int32_t keysz32 = (int32_t)keySizeInBits;
522
523 CFNumberRef kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &keysz32);
524 CFDictionaryRef kgp = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
525 kSecAttrKeyType, kSecAttrKeyTypeRSA,
526 kSecAttrKeySizeInBits, kzib,
527 kSecAttrIsPermanent, kCFBooleanFalse,
528 NULL);
529 SecKeyRef pubKey = NULL, privKey = NULL;
530 OSStatus status;
531 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
532 "Generate %ld bit (%ld byte) RSA keypair (status = %d)",
533 keySizeInBits, keySizeInBytes, (int)status);
534 CFReleaseNull(kgp);
535
536 CFMutableDictionaryRef kcwd = CFDictionaryCreateMutableForCFTypesWith(kCFAllocatorDefault,
537 kSecAttrKeyType, kSecAttrKeyTypeRSA,
538 kSecAttrKeySizeInBits, kzib,
539 kSecAttrIsPermanent, kCFBooleanFalse,
540 NULL);
541 CFReleaseNull(kzib);
542
543 CFErrorRef error = NULL;
544 CFDataRef privExternalData = NULL, pubExternalData = NULL;
545 SecKeyRef dataKey = NULL;
546
547 { // privKey
548 privExternalData = SecKeyCopyExternalRepresentation(privKey, &error);
549 ok(privExternalData && CFGetTypeID(privExternalData) == CFDataGetTypeID(),
550 "priv key SecKeyCopyExternalRepresentation failed");
551 CFReleaseNull(error);
552
553 SKIP: {
554 skip("invalid priv key external data", 4, privExternalData);
555
556 CFDictionarySetValue(kcwd, kSecAttrKeyClass, kSecAttrKeyClassPrivate);
557 dataKey = SecKeyCreateWithData(privExternalData, kcwd, &error);
558 ok(dataKey, "priv key SecKeyCreateWithData failed");
559 CFReleaseNull(error);
560
561 eq_cf(privKey, dataKey, "priv keys differ");
562 CFReleaseNull(dataKey);
563
564 CFDictionarySetValue(kcwd, kSecAttrKeyClass, kSecAttrKeyClassPublic);
565 dataKey = SecKeyCreateWithData(privExternalData, kcwd, &error);
566 ok(!dataKey, "priv key SecKeyCreateWithData succeeded with invalid kSecAttrKeyClass");
567 CFReleaseNull(error);
568 CFReleaseNull(dataKey);
569
570 CFMutableDataRef modifiedExternalData = CFDataCreateMutable(kCFAllocatorDefault, 0);
571 CFDataAppend(modifiedExternalData, privExternalData);
572 *CFDataGetMutableBytePtr(modifiedExternalData) ^= 0xff;
573
574 CFDictionarySetValue(kcwd, kSecAttrKeyClass, kSecAttrKeyClassPrivate);
575 dataKey = SecKeyCreateWithData(modifiedExternalData, kcwd, &error);
576 ok(!dataKey, "priv key SecKeyCreateWithData succeeded with invalid external data");
577 CFReleaseNull(error);
578 CFReleaseNull(dataKey);
579
580 CFReleaseNull(modifiedExternalData);
581 }
582 }
583
584 { // pubKey
585 pubExternalData = SecKeyCopyExternalRepresentation(pubKey, &error);
586 ok(pubExternalData && CFGetTypeID(pubExternalData) == CFDataGetTypeID(),
587 "pub key SecKeyCopyExternalRepresentation failed");
588 CFReleaseNull(error);
589
590 SKIP: {
591 skip("invalid pub key external data", 4, pubExternalData);
592
593 CFDictionarySetValue(kcwd, kSecAttrKeyClass, kSecAttrKeyClassPublic);
594 dataKey = SecKeyCreateWithData(pubExternalData, kcwd, &error);
595 ok(dataKey, "pub key SecKeyCreateWithData failed");
596 CFReleaseNull(error);
597
598 eq_cf(pubKey, dataKey, "pub keys differ");
599 CFReleaseNull(dataKey);
600
601 CFDictionarySetValue(kcwd, kSecAttrKeyClass, kSecAttrKeyClassPrivate);
602 dataKey = SecKeyCreateWithData(pubExternalData, kcwd, &error);
603 ok(!dataKey, "pub key SecKeyCreateWithData succeeded with invalid kSecAttrKeyClass");
604 CFReleaseNull(error);
605 CFReleaseNull(dataKey);
606
607 CFMutableDataRef modifiedExternalData = CFDataCreateMutable(kCFAllocatorDefault, 0);
608 CFDataAppend(modifiedExternalData, pubExternalData);
609 *CFDataGetMutableBytePtr(modifiedExternalData) ^= 0xff;
610
611 CFDictionarySetValue(kcwd, kSecAttrKeyClass, kSecAttrKeyClassPublic);
612 dataKey = SecKeyCreateWithData(modifiedExternalData, kcwd, &error);
613 ok(!dataKey, "pub key SecKeyCreateWithData succeeded with invalid external data");
614 CFReleaseNull(error);
615 CFReleaseNull(dataKey);
616
617 CFReleaseNull(modifiedExternalData);
618 }
619 }
620
621 SKIP: {
622 skip("invalid pub key external data", 1, pubExternalData);
623
624 CFDictionarySetValue(kcwd, kSecAttrKeyClass, kSecAttrKeyClassPrivate);
625 dataKey = SecKeyCreateWithData(pubExternalData, kcwd, &error);
626 ok(!dataKey, "priv key SecKeyCreateWithData succeeded with public external data");
627 CFReleaseNull(error);
628 CFReleaseNull(dataKey);
629
630 CFReleaseNull(pubExternalData);
631 }
632
633 SKIP: {
634 skip("invalid priv key external data", 1, privExternalData);
635
636 CFDictionarySetValue(kcwd, kSecAttrKeyClass, kSecAttrKeyClassPublic);
637 dataKey = SecKeyCreateWithData(privExternalData, kcwd, &error);
638 ok(!dataKey, "pub key SecKeyCreateWithData succeeded with private external data");
639 CFReleaseNull(error);
640 CFReleaseNull(dataKey);
641
642 CFReleaseNull(privExternalData);
643 }
644
645 CFReleaseNull(kcwd);
646 CFReleaseNull(pubKey);
647 CFReleaseNull(privKey);
648 }
649
650 #define kCopyAttributesTestCount 20
651 static void testcopyattributes(unsigned long keySizeInBits)
652 {
653 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
654 int32_t keysz32 = (int32_t)keySizeInBits;
655
656 CFNumberRef kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &keysz32);
657 CFDictionaryRef kgp = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
658 kSecAttrKeyType, kSecAttrKeyTypeRSA,
659 kSecAttrKeySizeInBits, kzib,
660 kSecAttrIsPermanent, kCFBooleanFalse,
661 NULL);
662 SecKeyRef pubKey = NULL, privKey = NULL;
663 OSStatus status;
664 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
665 "Generate %ld bit (%ld byte) RSA keypair (status = %d)",
666 keySizeInBits, keySizeInBytes, (int)status);
667 CFReleaseNull(kgp);
668
669 CFDictionaryRef attributes;
670 CFTypeRef attrValue = NULL, privAppLabel = NULL, pubAppLabel = NULL;
671
672 { // privKey
673 attributes = SecKeyCopyAttributes(privKey);
674 ok(attributes && CFGetTypeID(attributes) == CFDictionaryGetTypeID(),
675 "priv key SecKeyCopyAttributes failed");
676
677 SKIP: {
678 skip("invalid attributes", 8, attributes);
679
680 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanEncrypt);
681 eq_cf(attrValue, kCFBooleanFalse, "invalid priv key kSecAttrCanEncrypt");
682
683 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanDecrypt);
684 eq_cf(attrValue, kCFBooleanTrue, "invalid priv key kSecAttrCanDecrypt");
685
686 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanDerive);
687 eq_cf(attrValue, kCFBooleanFalse, "invalid priv key kSecAttrCanDerive");
688
689 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanSign);
690 eq_cf(attrValue, kCFBooleanTrue, "invalid priv key kSecAttrCanSign");
691
692 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanVerify);
693 eq_cf(attrValue, kCFBooleanFalse, "invalid priv key kSecAttrCanVerify");
694
695 attrValue = CFDictionaryGetValue(attributes, kSecAttrKeyClass);
696 eq_cf(attrValue, kSecAttrKeyClassPrivate, "priv key invalid kSecAttrKeyClass");
697
698 attrValue = CFDictionaryGetValue(attributes, kSecAttrKeyType);
699 eq_cf(attrValue, kSecAttrKeyTypeRSA, "invalid priv key kSecAttrKeyType");
700
701 attrValue = CFDictionaryGetValue(attributes, kSecAttrKeySizeInBits);
702 eq_cf(attrValue, kzib, "invalid priv key kSecAttrKeySizeInBits");
703
704 privAppLabel = CFDictionaryGetValue(attributes, kSecAttrApplicationLabel);
705 CFRetainSafe(privAppLabel);
706
707 CFReleaseNull(attributes);
708 }
709 }
710
711 { // pubKey
712 attributes = SecKeyCopyAttributes(pubKey);
713 ok(attributes && CFGetTypeID(attributes) == CFDictionaryGetTypeID(),
714 "pub key SecKeyCopyAttributes failed");
715
716 SKIP: {
717 skip("invalid attributes", 8, attributes);
718
719 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanEncrypt);
720 eq_cf(attrValue, kCFBooleanTrue, "pub key invalid kSecAttrCanEncrypt");
721
722 // Although unusual, our RSA public key can even decrypt.
723 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanDecrypt);
724 eq_cf(attrValue, kCFBooleanTrue, "pub key invalid kSecAttrCanDecrypt");
725
726 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanDerive);
727 eq_cf(attrValue, kCFBooleanFalse, "pub key invalid kSecAttrCanDerive");
728
729 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanSign);
730 eq_cf(attrValue, kCFBooleanFalse, "pub key invalid kSecAttrCanSign");
731
732 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanVerify);
733 eq_cf(attrValue, kCFBooleanTrue, "pub key invalid kSecAttrCanVerify");
734
735 attrValue = CFDictionaryGetValue(attributes, kSecAttrKeyClass);
736 eq_cf(attrValue, kSecAttrKeyClassPublic, "pub key invalid kSecAttrKeyClass");
737
738 attrValue = CFDictionaryGetValue(attributes, kSecAttrKeyType);
739 eq_cf(attrValue, kSecAttrKeyTypeRSA, "pub key invalid kSecAttrKeyType");
740
741 attrValue = CFDictionaryGetValue(attributes, kSecAttrKeySizeInBits);
742 eq_cf(attrValue, kzib, "pub key invalid kSecAttrKeySizeInBits");
743
744 pubAppLabel = CFDictionaryGetValue(attributes, kSecAttrApplicationLabel);
745 CFRetainSafe(pubAppLabel);
746
747 CFReleaseNull(attributes);
748 }
749 }
750
751 eq_cf(privAppLabel, pubAppLabel, "priv key and pub key kSecAttrApplicationLabel differ");
752
753 CFReleaseNull(privAppLabel);
754 CFReleaseNull(pubAppLabel);
755 CFReleaseNull(kzib);
756 CFReleaseNull(pubKey);
757 CFReleaseNull(privKey);
758 }
759
760 #define kCopyPublicKeyTestCount 5
761 static void testcopypublickey(unsigned long keySizeInBits)
762 {
763 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
764 int32_t keysz32 = (int32_t)keySizeInBits;
765
766 CFNumberRef kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &keysz32);
767 CFDictionaryRef kgp = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
768 kSecAttrKeyType, kSecAttrKeyTypeRSA,
769 kSecAttrKeySizeInBits, kzib,
770 kSecAttrIsPermanent, kCFBooleanFalse,
771 NULL);
772 CFReleaseNull(kzib);
773
774 SecKeyRef pubKey = NULL, privKey = NULL;
775 OSStatus status;
776 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
777 "Generate %ld bit (%ld byte) RSA keypair (status = %d)",
778 keySizeInBits, keySizeInBytes, (int)status);
779 CFReleaseNull(kgp);
780
781 SecKeyRef pubKeyCopy = NULL;
782
783 { // privKey
784 pubKeyCopy = SecKeyCopyPublicKey(privKey);
785 ok(pubKeyCopy, "priv key SecKeyCopyPublicKey failed");
786 eq_cf(pubKeyCopy, pubKey, "pub key from priv key SecKeyCopyPublicKey and pub key differ");
787 CFReleaseNull(pubKeyCopy);
788 }
789
790 { // pubKey
791 pubKeyCopy = SecKeyCopyPublicKey(pubKey);
792 ok(pubKeyCopy, "pub key SecKeyCopyPublicKey failed");
793 eq_cf(pubKeyCopy, pubKey, "pub key from pub key SecKeyCopyPublicKey and pub key differ");
794 CFReleaseNull(pubKeyCopy);
795 }
796
797 CFReleaseNull(pubKey);
798 CFReleaseNull(privKey);
799 }
800
801 #define kSignAndVerifyTestCount 84
802 static void testsignverify(unsigned long keySizeInBits)
803 {
804 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
805 int32_t keysz32 = (int32_t)keySizeInBits;
806
807 CFNumberRef kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &keysz32);
808 CFDictionaryRef kgp = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
809 kSecAttrKeyType, kSecAttrKeyTypeRSA,
810 kSecAttrKeySizeInBits, kzib,
811 kSecAttrIsPermanent, kCFBooleanFalse,
812 NULL);
813 CFReleaseNull(kzib);
814
815 SecKeyRef pubKey = NULL, privKey = NULL;
816 OSStatus status;
817 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
818 "Generate %ld bit (%ld byte) RSA keypair (status = %d)",
819 keySizeInBits, keySizeInBytes, (int)status);
820 CFReleaseNull(kgp);
821
822 SecKeyAlgorithm algorithms[] = {
823 kSecKeyAlgorithmRSASignatureRaw,
824 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1,
825 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA224,
826 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256,
827 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384,
828 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512,
829 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1,
830 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA224,
831 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256,
832 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA384,
833 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA512,
834 };
835
836 CFDataRef testData = CFStringCreateExternalRepresentation(kCFAllocatorDefault, CFSTR("test"), kCFStringEncodingUTF8, 0);
837 ok(testData, "creating test data failed");
838
839 SKIP: {
840 skip("invalid test data", 71, testData);
841
842 CFErrorRef error = NULL;
843
844 for (uint32_t ix = 0; ix < array_size(algorithms); ++ix) {
845 SecKeyAlgorithm algorithm = algorithms[ix];
846 SecKeyAlgorithm incompatibleAlgorithm = (CFEqual(algorithm, kSecKeyAlgorithmRSASignatureRaw)) ?
847 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1 : kSecKeyAlgorithmRSASignatureRaw;
848
849 CFDataRef dataToSign = NULL;
850 if (CFEqual(algorithm, kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1)) {
851 dataToSign = CFDataCreateWithHash(kCFAllocatorDefault, ccsha1_di(),
852 CFDataGetBytePtr(testData), CFDataGetLength(testData));
853 ok(dataToSign, "creating digest failed for algorithm %@", algorithm);
854 }
855 else if (CFEqual(algorithm, kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA224)) {
856 dataToSign = CFDataCreateWithHash(kCFAllocatorDefault, ccsha224_di(),
857 CFDataGetBytePtr(testData), CFDataGetLength(testData));
858 ok(dataToSign, "creating digest failed for algorithm %@", algorithm);
859 }
860 else if (CFEqual(algorithm, kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256)) {
861 dataToSign = CFDataCreateWithHash(kCFAllocatorDefault, ccsha256_di(),
862 CFDataGetBytePtr(testData), CFDataGetLength(testData));
863 ok(dataToSign, "creating digest failed for algorithm %@", algorithm);
864 }
865 else if (CFEqual(algorithm, kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384)) {
866 dataToSign = CFDataCreateWithHash(kCFAllocatorDefault, ccsha384_di(),
867 CFDataGetBytePtr(testData), CFDataGetLength(testData));
868 ok(dataToSign, "creating digest failed for algorithm %@", algorithm);
869 }
870 else if (CFEqual(algorithm, kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512)) {
871 dataToSign = CFDataCreateWithHash(kCFAllocatorDefault, ccsha512_di(),
872 CFDataGetBytePtr(testData), CFDataGetLength(testData));
873 ok(dataToSign, "creating digest failed for algorithm %@", algorithm);
874 }
875 else {
876 CFRetainAssign(dataToSign, testData);
877 }
878 CFReleaseNull(error);
879
880 SKIP: {
881 skip("invalid data to sign", 7, dataToSign);
882
883 CFDataRef signature = SecKeyCreateSignature(pubKey, algorithm, dataToSign, &error);
884 ok(!signature, "SecKeyCopySignature succeeded with pub key for algorithm %@", algorithm);
885 CFReleaseNull(error);
886 CFReleaseNull(signature);
887
888 signature = SecKeyCreateSignature(privKey, algorithm, dataToSign, &error);
889 ok(signature, "SecKeyCopySignature failed for algorithm %@", algorithm);
890 CFReleaseNull(error);
891
892 SKIP: {
893 skip("invalid signature", 4, signature);
894
895 ok(!SecKeyVerifySignature(privKey, algorithm, dataToSign, signature, &error),
896 "SecKeyVerifySignature succeeded with priv key for algorithm %@", algorithm);
897 CFReleaseNull(error);
898
899 ok(!SecKeyVerifySignature(pubKey, incompatibleAlgorithm, dataToSign, signature, &error),
900 "SecKeyVerifySignature succeeded with wrong algorithm for algorithm %@", algorithm);
901 CFReleaseNull(error);
902
903 ok(SecKeyVerifySignature(pubKey, algorithm, dataToSign, signature, &error),
904 "SecKeyVerifySignature failed for algorithm %@", algorithm);
905 CFReleaseNull(error);
906
907 CFMutableDataRef modifiedSignature = CFDataCreateMutable(kCFAllocatorDefault, 0);
908 CFDataAppend(modifiedSignature, signature);
909 *CFDataGetMutableBytePtr(modifiedSignature) ^= 0xff;
910
911 ok(!SecKeyVerifySignature(pubKey, algorithm, dataToSign, modifiedSignature, &error),
912 "SecKeyVerifySignature succeeded with bad signature for algorithm %@", algorithm);
913 CFReleaseNull(error);
914
915 CFMutableDataRef modifiedDataToSign = CFDataCreateMutable(kCFAllocatorDefault, 0);
916 CFDataAppend(modifiedDataToSign, dataToSign);
917 *CFDataGetMutableBytePtr(modifiedDataToSign) ^= 0xff;
918
919 ok(!SecKeyVerifySignature(pubKey, algorithm, modifiedDataToSign, signature, &error),
920 "SecKeyVerifySignature succeeded with bad data for algorithm %@", algorithm);
921 CFReleaseNull(error);
922
923 CFReleaseNull(modifiedDataToSign);
924 CFReleaseNull(modifiedSignature);
925 CFReleaseNull(signature);
926 }
927 CFReleaseNull(dataToSign);
928 }
929 }
930 CFReleaseNull(testData);
931 }
932
933 CFReleaseNull(pubKey);
934 CFReleaseNull(privKey);
935 }
936
937 /* Test basic add delete update copy matching stuff. */
938 #define kTestCount ((3 * kKeyGenTestCount) + kKeyGen2TestCount + kTestSupportedCount + kCreateWithDataTestCount \
939 + kCopyAttributesTestCount + kCopyPublicKeyTestCount + kSignAndVerifyTestCount)
940 static void tests(void)
941 {
942 /* Comment out lines below for testing generating all common key sizes,
943 disabled now for speed reasons. */
944 //testkeygen(512);
945 testkeygen(768);
946 testkeygen(1024);
947 testkeygen(2056); // Stranged sized for edge cases in padding.
948 //testkeygen(2048);
949 //testkeygen(4096);
950
951 testkeygen2(768);
952
953 testsupportedalgos(768);
954 testcreatewithdata(768);
955 testcopyattributes(768);
956 testcopypublickey(768);
957 testsignverify(768);
958 }
959
960 int si_40_seckey(int argc, char *const *argv)
961 {
962 plan_tests(kTestCount);
963
964 tests();
965
966 return 0;
967 }