]> git.saurik.com Git - apple/security.git/blob - OSX/sec/Security/Regressions/secitem/si-41-sececkey.c
Security-58286.260.20.tar.gz
[apple/security.git] / OSX / sec / Security / Regressions / secitem / si-41-sececkey.c
1 /*
2 * Copyright (c) 2011-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 /*
26 * si-40-seckey.c
27 * Security
28 *
29 * Copyright (c) 2007-2009,2012-2014 Apple Inc. All Rights Reserved.
30 *
31 */
32
33 #include <CoreFoundation/CoreFoundation.h>
34 #include <Security/SecCertificate.h>
35 #include <Security/SecCertificateInternal.h>
36 #include <Security/SecKey.h>
37 #include <Security/SecECKey.h>
38 #include <Security/SecKeyPriv.h>
39 #include <Security/SecItem.h>
40 #include <Security/SecAsn1Types.h>
41 #include <Security/oidsalg.h>
42 #include <Security/SecureTransport.h>
43 #include <Security/SecRandom.h>
44 #include <utilities/array_size.h>
45 #include <utilities/SecCFRelease.h>
46 #include <utilities/SecCFWrappers.h>
47 #include <CommonCrypto/CommonDigest.h>
48 #include <libDER/libDER.h>
49 #include <stdlib.h>
50 #include <unistd.h>
51 #include <corecrypto/ccsha2.h>
52
53 #include "Security_regressions.h"
54
55 static void testdigestandsignalg(SecKeyRef privKey, SecKeyRef pubKey, const SecAsn1AlgId *algId) {
56 uint8_t dataToDigest[256] = {0,};
57 size_t dataToDigestLen = sizeof(dataToDigest);
58 size_t sigLen = SecKeyGetSize(privKey, kSecKeySignatureSize);
59 uint8_t sig[sigLen];
60
61 DERItem oid;
62 oid.length = algId->algorithm.Length;
63 oid.data = algId->algorithm.Data;
64
65 /* Get the oid in decimal for display purposes. */
66 CFStringRef oidStr = SecDERItemCopyOIDDecimalRepresentation(kCFAllocatorDefault, &oid);
67 char oidBuf[40];
68 CFStringGetCString(oidStr, oidBuf, sizeof(oidBuf), kCFStringEncodingUTF8);
69 CFRelease(oidStr);
70
71 SKIP: {
72 OSStatus status;
73
74 /* Time to sign. */
75 ok_status(status = SecKeyDigestAndSign(privKey, algId, dataToDigest, dataToDigestLen,
76 sig, &sigLen),
77 "digest and sign %s with %ld bit RSA key", oidBuf, sigLen * 8);
78
79 skip("SecKeyDigestAndSign failed", 3, status == errSecSuccess);
80
81 /* Verify the signature we just made. */
82 ok_status(SecKeyDigestAndVerify(pubKey, algId, dataToDigest, dataToDigestLen,
83 sig, sigLen), "digest and verify");
84 /* Invalidate the signature. */
85 sig[0] ^= 0xff;
86 is_status(SecKeyDigestAndVerify(pubKey, algId, dataToDigest, dataToDigestLen,
87 sig, sigLen), errSSLCrypto, "digest and verify bad sig");
88 sig[0] ^= 0xff;
89 dataToDigest[0] ^= 0xff;
90 is_status(SecKeyDigestAndVerify(pubKey, algId, dataToDigest, dataToDigestLen,
91 sig, sigLen), errSSLCrypto, "digest and verify bad digest");
92 }
93 }
94
95 static void testdigestandsign(SecKeyRef privKey, SecKeyRef pubKey) {
96 static const SecAsn1Oid *oids[] = {
97 &CSSMOID_ECDSA_WithSHA1,
98 #if 0
99 &CSSMOID_ECDSA_WithSHA224,
100 &CSSMOID_ECDSA_WithSHA256,
101 &CSSMOID_ECDSA_WithSHA384,
102 &CSSMOID_ECDSA_WithSHA512,
103 #endif
104 };
105
106 uint32_t ix;
107 SecAsn1AlgId algId = {};
108 for (ix = 0; ix < array_size(oids); ++ix) {
109 if (oids[ix]) {
110 algId.algorithm = *oids[ix];
111 } else {
112 algId.algorithm.Length = 0;
113 algId.algorithm.Data = NULL;
114 }
115
116 testdigestandsignalg(privKey, pubKey, &algId);
117 }
118 }
119
120 static void testkeygen(size_t keySizeInBits) {
121 SecKeyRef pubKey = NULL, privKey = NULL;
122 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
123 CFNumberRef kzib;
124 int32_t keysz32 = (int32_t)keySizeInBits;
125
126 kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &keysz32);
127 CFMutableDictionaryRef kgp = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
128 CFDictionaryAddValue(kgp, kSecAttrKeyType, kSecAttrKeyTypeEC);
129 CFDictionaryAddValue(kgp, kSecAttrKeySizeInBits, kzib);
130
131 OSStatus status;
132 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
133 "Generate %ld bit (%ld byte) EC keypair", keySizeInBits,
134 keySizeInBytes);
135 CFRelease(kzib);
136 CFRelease(kgp);
137
138 SKIP: {
139 skip("keygen failed", 8, status == errSecSuccess);
140 ok(pubKey, "pubkey returned");
141 ok(privKey, "privKey returned");
142 is(SecKeyGetSize(pubKey, kSecKeyKeySizeInBits), (size_t) keySizeInBits, "public key size is ok");
143 is(SecKeyGetSize(privKey, kSecKeyKeySizeInBits), (size_t) keySizeInBits, "private key size is ok");
144
145 /* Sign something. */
146 uint8_t something[20] = {0x80, 0xbe, 0xef, 0xba, 0xd0, };
147 uint8_t sig[8+2*keySizeInBytes];
148 size_t sigLen = sizeof(sig);
149 ok_status(SecKeyRawSign(privKey, kSecPaddingNone,
150 something, sizeof(something), sig, &sigLen), "sign something");
151 ok_status(SecKeyRawVerify(pubKey, kSecPaddingNone,
152 something, sizeof(something), sig, sigLen), "verify sig on something");
153
154 testdigestandsign(privKey, pubKey);
155
156 const void *privkeys[] = {
157 kSecValueRef
158 };
159 const void *privvalues[] = {
160 privKey
161 };
162 CFDictionaryRef privitem = CFDictionaryCreate(NULL, privkeys, privvalues,
163 array_size(privkeys), NULL, NULL);
164 ok_status(SecItemAdd(privitem, NULL), "add private key");
165 ok_status(SecItemDelete(privitem), "delete public key");
166 CFReleaseNull(privitem);
167
168 const void *pubkeys[] = {
169 kSecValueRef
170 };
171 const void *pubvalues[] = {
172 pubKey
173 };
174 CFDictionaryRef pubitem = CFDictionaryCreate(NULL, pubkeys, pubvalues,
175 array_size(pubkeys), NULL, NULL);
176 ok_status(SecItemAdd(pubitem, NULL), "add public key");
177 ok_status(SecItemDelete(pubitem), "delete public key");
178 CFReleaseNull(pubitem);
179
180 /* Cleanup. */
181 CFReleaseNull(pubKey);
182 CFReleaseNull(privKey);
183 }
184 }
185
186
187 static void testkeygen2(size_t keySizeInBits) {
188 SecKeyRef pubKey = NULL, privKey = NULL;
189 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
190 CFNumberRef kzib;
191 int32_t keysz32 = (int32_t)keySizeInBits;
192
193 CFUUIDRef ourUUID = CFUUIDCreate(kCFAllocatorDefault);
194 CFStringRef uuidString = CFUUIDCreateString(kCFAllocatorDefault, ourUUID);
195 CFMutableStringRef publicName = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, uuidString);
196 CFMutableStringRef privateName = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, uuidString);
197
198 CFReleaseNull(ourUUID);
199 CFReleaseNull(uuidString);
200
201 CFStringAppend(publicName, CFSTR("-Public-41"));
202 CFStringAppend(privateName, CFSTR("-Private-41"));
203
204 CFMutableDictionaryRef pubd = CFDictionaryCreateMutableForCFTypesWith(kCFAllocatorDefault,
205 kSecAttrLabel, publicName,
206 NULL);
207 CFMutableDictionaryRef privd = CFDictionaryCreateMutableForCFTypesWith(kCFAllocatorDefault,
208 kSecAttrLabel, privateName,
209 NULL);
210
211 kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &keysz32);
212 CFDictionaryRef kgp = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
213 kSecAttrKeyType, kSecAttrKeyTypeEC,
214 kSecAttrKeySizeInBits, kzib,
215 kSecAttrIsPermanent, kCFBooleanTrue,
216 kSecPublicKeyAttrs, pubd,
217 kSecPrivateKeyAttrs, privd,
218 NULL);
219
220 CFReleaseNull(kzib);
221
222 OSStatus status;
223 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
224 "Generate %ld bit (%ld byte) persistent RSA keypair",
225 keySizeInBits, keySizeInBytes);
226
227 CFReleaseNull(kgp);
228
229 SKIP: {
230 skip("keygen failed", 8, status == errSecSuccess);
231 ok(pubKey, "pubkey returned");
232 ok(privKey, "privKey returned");
233 is(SecKeyGetSize(pubKey, kSecKeyKeySizeInBits), (size_t) keySizeInBits, "public key size is ok");
234 is(SecKeyGetSize(privKey, kSecKeyKeySizeInBits), (size_t) keySizeInBits, "private key size is ok");
235
236 SecKeyRef pubKey2, privKey2;
237 CFDictionaryAddValue(pubd, kSecClass, kSecClassKey);
238 CFDictionaryAddValue(pubd, kSecReturnRef, kCFBooleanTrue);
239 CFDictionaryAddValue(privd, kSecClass, kSecClassKey);
240 CFDictionaryAddValue(privd, kSecReturnRef, kCFBooleanTrue);
241 CFDictionaryAddValue(privd, kSecAttrCanSign, kCFBooleanTrue);
242 ok_status(SecItemCopyMatching(pubd, (CFTypeRef *)&pubKey2),
243 "retrieve pub key by label");
244 ok(pubKey2, "got valid object");
245 ok_status(SecItemCopyMatching(privd, (CFTypeRef *)&privKey2),
246 "retrieve priv key by label and kSecAttrCanSign");
247 ok(privKey2, "got valid object");
248
249 /* Sign something. */
250 uint8_t something[20] = {0x80, 0xbe, 0xef, 0xba, 0xd0, };
251 size_t sigLen = SecKeyGetSize(privKey2, kSecKeySignatureSize);
252 uint8_t sig[sigLen];
253 if (privKey2 != NULL && pubKey2 != NULL) {
254 ok_status(SecKeyRawSign(privKey2, kSecPaddingPKCS1,
255 something, sizeof(something), sig, &sigLen), "sign something");
256 ok_status(SecKeyRawVerify(pubKey2, kSecPaddingPKCS1,
257 something, sizeof(something), sig, sigLen), "verify sig on something");
258 }
259
260 /* Cleanup. */
261 CFReleaseNull(pubKey2);
262 CFReleaseNull(privKey2);
263 }
264
265 /* delete from keychain - note: do it before releasing publicName and privateName
266 because pubd and privd have no retain/release callbacks */
267 ok_status(SecItemDelete(pubd), "delete generated pub key");
268 ok_status(SecItemDelete(privd), "delete generated priv key");
269
270 /* Cleanup. */
271 CFReleaseNull(pubKey);
272 CFReleaseNull(privKey);
273
274 CFReleaseNull(publicName);
275 CFReleaseNull(privateName);
276
277 CFReleaseNull(pubd);
278 CFReleaseNull(privd);
279 }
280
281 static void testkeywrap(unsigned long keySizeInBits, CFTypeRef alg)
282 {
283 SecKeyRef pubKey = NULL, privKey = NULL;
284 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
285 CFNumberRef kzib;
286 int32_t keysz32 = (int32_t)keySizeInBits;
287
288 CFUUIDRef ourUUID = CFUUIDCreate(kCFAllocatorDefault);
289 CFStringRef uuidString = CFUUIDCreateString(kCFAllocatorDefault, ourUUID);
290 CFMutableStringRef publicName = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, uuidString);
291 CFMutableStringRef privateName = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, uuidString);
292
293 CFReleaseNull(ourUUID);
294 CFReleaseNull(uuidString);
295
296 CFStringAppend(publicName, CFSTR("-Public-41"));
297 CFStringAppend(privateName, CFSTR("-Private-41"));
298
299 CFDictionaryRef pubd = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
300 kSecAttrLabel, publicName,
301 NULL);
302 CFDictionaryRef privd = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
303 kSecAttrLabel, privateName,
304 NULL);
305
306 CFReleaseNull(publicName);
307 CFReleaseNull(privateName);
308
309 kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &keysz32);
310 CFDictionaryRef kgp = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
311 kSecAttrKeyType, kSecAttrKeyTypeEC,
312 kSecAttrKeySizeInBits, kzib,
313 kSecAttrIsPermanent, kCFBooleanFalse,
314 kSecPublicKeyAttrs, pubd,
315 kSecPrivateKeyAttrs, privd,
316 NULL);
317 CFReleaseNull(pubd);
318 CFReleaseNull(privd);
319 CFReleaseNull(kzib);
320
321 OSStatus status;
322 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
323 "Generate %ld bit (%ld byte) persistent RSA keypair (status = %d)",
324 keySizeInBits, keySizeInBytes, (int)status);
325 CFReleaseNull(kgp);
326
327 CFErrorRef localError = NULL;
328
329 CFDataRef secret = CFDataCreate(NULL, (void *)"0123456789012345", 16);
330 ok(secret, "secret");
331
332 CFDataRef fp = CFDataCreate(NULL, (void *)"01234567890123456789", 20);
333 ok(fp, "fingerprint");
334
335
336 int8_t sym_alg_data = 8;
337 CFNumberRef symalg = CFNumberCreate(NULL, kCFNumberSInt8Type, &sym_alg_data);
338 CFDictionaryRef param = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
339 _kSecKeyWrapPGPWrapAlg, alg,
340 _kSecKeyWrapPGPSymAlg, symalg,
341 _kSecKeyWrapPGPFingerprint, fp,
342 NULL);
343
344 CFDataRef wrapped = _SecKeyCopyWrapKey(pubKey, kSecKeyWrapPublicKeyPGP, secret, param, NULL, &localError);
345 ok(wrapped, "wrap key: %@", localError);
346
347 CFDataRef unwrapped = _SecKeyCopyUnwrapKey(privKey, kSecKeyWrapPublicKeyPGP, wrapped, param, NULL, &localError);
348 ok(unwrapped, "unwrap key: %@", localError);
349
350 CFReleaseNull(symalg);
351
352 ok(CFEqual(unwrapped, secret), "keys still same");
353
354 CFReleaseNull(fp);
355 CFReleaseNull(secret);
356 CFReleaseNull(unwrapped);
357 CFReleaseNull(wrapped);
358 CFReleaseNull(param);
359 CFReleaseNull(privKey);
360 CFReleaseNull(pubKey);
361 }
362
363 const uint8_t EC_P256_KeyDER[]={
364 0x30, 0x6b, 0x02, 0x01, 0x01, 0x04, 0x20, 0x86, 0x87, 0x79, 0x59, 0xd1,
365 0xc6, 0x3c, 0x50, 0x24, 0x30, 0xa4, 0xaf, 0x89, 0x1d, 0xd1, 0x94, 0x23,
366 0x56, 0x79, 0x46, 0x93, 0x72, 0x31, 0x39, 0x24, 0xe6, 0x01, 0x96, 0xc8,
367 0xeb, 0xf3, 0x88, 0xa1, 0x44, 0x03, 0x42, 0x00, 0x04, 0x8c, 0xfa, 0xd7,
368 0x8a, 0xf1, 0xb9, 0xad, 0xd7, 0x3a, 0x33, 0xb5, 0x9a, 0xad, 0x52, 0x0d,
369 0x14, 0xd6, 0x6b, 0x35, 0x56, 0x79, 0xd6, 0x74, 0x2a, 0x37, 0x7e, 0x2f,
370 0x33, 0xa6, 0xab, 0xee, 0x35, 0x00, 0x70, 0x82, 0x89, 0x9c, 0xfc, 0x97,
371 0xc4, 0x89, 0x5c, 0x16, 0x50, 0xad, 0x60, 0x55, 0xa6, 0x70, 0xee, 0x07,
372 0x1b, 0xfe, 0xe4, 0xf0, 0xa0, 0x63, 0xc0, 0x73, 0x24, 0x97, 0x92, 0x04,
373 0xc7};
374
375 const uint8_t EC_P256_SigDER[]={
376 0x30, 0x45, 0x02, 0x20, 0x4b, 0x37, 0x7f, 0x45, 0xd0, 0x5d, 0xa6, 0x53,
377 0xb3, 0x62, 0x6f, 0x32, 0xdb, 0xfc, 0xf6, 0x3b, 0x84, 0xfa, 0x5a, 0xd9,
378 0x17, 0x67, 0x03, 0x73, 0x48, 0x0c, 0xad, 0x89, 0x13, 0x69, 0x61, 0xb3,
379 0x02, 0x21, 0x00, 0xd6, 0x23, 0xaf, 0xd9, 0x7d, 0x72, 0xba, 0x3b, 0x90,
380 0xc1, 0x23, 0x7d, 0xdb, 0x2c, 0xd1, 0x0d, 0xbb, 0xb4, 0x0f, 0x67, 0x26,
381 0xff, 0x3f, 0xa6, 0x47, 0xa4, 0x13, 0x0d, 0xe0, 0x45, 0xd5, 0x6b};
382
383 const uint8_t EC_P256_SigRaw[]= {
384 0x4b, 0x37, 0x7f, 0x45, 0xd0, 0x5d, 0xa6, 0x53, 0xb3, 0x62, 0x6f, 0x32,
385 0xdb, 0xfc, 0xf6, 0x3b, 0x84, 0xfa, 0x5a, 0xd9, 0x17, 0x67, 0x03, 0x73,
386 0x48, 0x0c, 0xad, 0x89, 0x13, 0x69, 0x61, 0xb3, 0xd6, 0x23, 0xaf, 0xd9,
387 0x7d, 0x72, 0xba, 0x3b, 0x90, 0xc1, 0x23, 0x7d, 0xdb, 0x2c, 0xd1, 0x0d,
388 0xbb, 0xb4, 0x0f, 0x67, 0x26, 0xff, 0x3f, 0xa6, 0x47, 0xa4, 0x13, 0x0d,
389 0xe0, 0x45, 0xd5, 0x6b};
390
391 const uint8_t EC_SigDigest[24] = "012345678912345678901234";
392
393 static void testsignformat(void)
394 {
395 SecKeyRef pkey = NULL;
396 SecKeyRef pubkey = NULL;
397 CFDataRef pubdata = NULL;
398 uint8_t EC_signature_DER[72];
399 uint8_t EC_signature_RAW[64];
400 size_t EC_signature_DER_size=sizeof(EC_signature_DER);
401 size_t EC_signature_RAW_size=sizeof(EC_signature_RAW);
402
403 ok((pkey = SecKeyCreateECPrivateKey(kCFAllocatorDefault,
404 EC_P256_KeyDER, sizeof(EC_P256_KeyDER),
405 kSecKeyEncodingPkcs1)) != NULL, "import privkey");
406
407 ok_status(SecKeyCopyPublicBytes(pkey, &pubdata), "pub key from priv key");
408
409 ok((pubkey = SecKeyCreateECPublicKey(kCFAllocatorDefault,
410 CFDataGetBytePtr(pubdata), CFDataGetLength(pubdata),
411 kSecKeyEncodingBytes))!=NULL,
412 "recreate seckey");
413
414 if (pubkey != NULL && pkey != NULL) {
415 // Verify fixed signature
416 ok_status(SecKeyRawVerify(pubkey, kSecPaddingPKCS1,
417 EC_SigDigest, sizeof(EC_SigDigest), EC_P256_SigDER, sizeof(EC_P256_SigDER)), "verify DER sig on something");
418
419 ok_status(SecKeyRawVerify(pubkey, kSecPaddingSigRaw,
420 EC_SigDigest, sizeof(EC_SigDigest), EC_P256_SigRaw, sizeof(EC_P256_SigRaw)), "verify RAW sig on something");
421
422 // Verify signature with mismatching format
423 ok_status(!SecKeyRawVerify(pubkey, kSecPaddingSigRaw,
424 EC_SigDigest, sizeof(EC_SigDigest), EC_P256_SigDER, sizeof(EC_P256_SigDER)), "verify DER sig with RAW option");
425
426 ok_status(!SecKeyRawVerify(pubkey, kSecPaddingPKCS1,
427 EC_SigDigest, sizeof(EC_SigDigest), EC_P256_SigRaw, sizeof(EC_P256_SigRaw)), "verify RAW sig with DER something");
428
429 // Sign something in each format
430 ok_status(SecKeyRawSign(pkey, kSecPaddingPKCS1,
431 EC_SigDigest, sizeof(EC_SigDigest), EC_signature_DER, &EC_signature_DER_size), "sign DER sig on something");
432
433 ok_status(SecKeyRawSign(pkey, kSecPaddingSigRaw,
434 EC_SigDigest, sizeof(EC_SigDigest), EC_signature_RAW, &EC_signature_RAW_size), "sign RAW sig on something");
435
436 // Verify expecting that verification does the right thing.
437 ok_status(SecKeyRawVerify(pubkey, kSecPaddingPKCS1,
438 EC_SigDigest, sizeof(EC_SigDigest), EC_signature_DER, EC_signature_DER_size), "verify DER sig on something");
439
440 ok_status(SecKeyRawVerify(pubkey, kSecPaddingSigRaw,
441 EC_SigDigest, sizeof(EC_SigDigest), EC_signature_RAW, EC_signature_RAW_size), "verify RAW sig on something");
442 }
443
444 CFReleaseNull(pkey);
445 CFReleaseNull(pubkey);
446 CFReleaseNull(pubdata);
447 }
448
449 static void testkeyexchange(unsigned long keySizeInBits)
450 {
451 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
452 CFNumberRef kzib;
453 int32_t keysz32 = (int32_t)keySizeInBits;
454
455 kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &keysz32);
456 CFDictionaryRef kgp = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
457 kSecAttrKeyType, kSecAttrKeyTypeEC,
458 kSecAttrKeySizeInBits, kzib,
459 kSecAttrIsPermanent, kCFBooleanFalse,
460 NULL);
461 CFReleaseNull(kzib);
462
463 SecKeyRef pubKey1 = NULL, privKey1 = NULL;
464 SecKeyRef pubKey2 = NULL, privKey2 = NULL;
465
466 OSStatus status;
467 ok_status(status = SecKeyGeneratePair(kgp, &pubKey1, &privKey1),
468 "Generate %ld bit (%ld byte) EC keypair (status = %d)",
469 keySizeInBits, keySizeInBytes, (int)status);
470 ok_status(status = SecKeyGeneratePair(kgp, &pubKey2, &privKey2),
471 "Generate %ld bit (%ld byte) EC keypair (status = %d)",
472 keySizeInBits, keySizeInBytes, (int)status);
473 CFReleaseNull(kgp);
474
475 const SecKeyAlgorithm algos[] = {
476 kSecKeyAlgorithmECDHKeyExchangeStandard,
477 kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA1,
478 kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA224,
479 kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA256,
480 kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA384,
481 kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA512,
482 kSecKeyAlgorithmECDHKeyExchangeCofactor,
483 kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA1,
484 kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA224,
485 kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA256,
486 kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA384,
487 kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA512,
488 };
489
490 // Strange size to test borderline conditions.
491 CFIndex rs = 273;
492 CFNumberRef requestedSize = CFNumberCreate(kCFAllocatorDefault, kCFNumberCFIndexType, &rs);
493 CFDataRef sharedInfo = CFDataCreate(kCFAllocatorDefault, (const UInt8 *)"sharedInput", 11);
494 CFDictionaryRef params = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
495 kSecKeyKeyExchangeParameterRequestedSize, requestedSize,
496 kSecKeyKeyExchangeParameterSharedInfo, sharedInfo,
497 NULL);
498 CFRelease(requestedSize);
499 CFRelease(sharedInfo);
500
501 for (size_t ix = 0; ix < array_size(algos); ++ix) {
502 CFErrorRef error = NULL;
503
504 CFDataRef secret1 = SecKeyCopyKeyExchangeResult(privKey1, algos[ix], pubKey2, params, &error);
505 ok(secret1 != NULL && CFGetTypeID(secret1) == CFDataGetTypeID());
506 CFReleaseNull(error);
507
508 CFDataRef secret2 = SecKeyCopyKeyExchangeResult(privKey2, algos[ix], pubKey1, params, &error);
509 ok(secret2 != NULL && CFGetTypeID(secret1) == CFDataGetTypeID());
510 CFReleaseNull(error);
511
512 eq_cf(secret1, secret2, "results of key exchange are equal");
513 if (algos[ix] != kSecKeyAlgorithmECDHKeyExchangeCofactor && algos[ix] != kSecKeyAlgorithmECDHKeyExchangeStandard) {
514 is(CFDataGetLength(secret1), rs, "generated response has expected length");
515 }
516
517 CFReleaseNull(secret1);
518 CFReleaseNull(secret2);
519 }
520
521 CFReleaseNull(privKey1);
522 CFReleaseNull(pubKey1);
523 CFReleaseNull(privKey2);
524 CFReleaseNull(pubKey2);
525 CFReleaseNull(params);
526 }
527
528 static void testsupportedalgos(size_t keySizeInBits)
529 {
530 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
531 CFNumberRef kzib;
532 int32_t keysz32 = (int32_t)keySizeInBits;
533
534 kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &keysz32);
535 CFDictionaryRef kgp = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
536 kSecAttrKeyType, kSecAttrKeyTypeEC,
537 kSecAttrKeySizeInBits, kzib,
538 kSecAttrIsPermanent, kCFBooleanFalse,
539 NULL);
540 CFReleaseNull(kzib);
541
542 SecKeyRef pubKey = NULL, privKey = NULL;
543
544 OSStatus status;
545 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
546 "Generate %ld bit (%ld byte) EC keypair (status = %d)",
547 keySizeInBits, keySizeInBytes, (int)status);
548
549 const SecKeyAlgorithm sign[] = {
550 kSecKeyAlgorithmECDSASignatureRFC4754,
551 kSecKeyAlgorithmECDSASignatureDigestX962,
552 kSecKeyAlgorithmECDSASignatureDigestX962SHA1,
553 kSecKeyAlgorithmECDSASignatureDigestX962SHA224,
554 kSecKeyAlgorithmECDSASignatureDigestX962SHA256,
555 kSecKeyAlgorithmECDSASignatureDigestX962SHA384,
556 kSecKeyAlgorithmECDSASignatureDigestX962SHA512,
557 kSecKeyAlgorithmECDSASignatureMessageX962SHA1,
558 kSecKeyAlgorithmECDSASignatureMessageX962SHA224,
559 kSecKeyAlgorithmECDSASignatureMessageX962SHA256,
560 kSecKeyAlgorithmECDSASignatureMessageX962SHA384,
561 kSecKeyAlgorithmECDSASignatureMessageX962SHA512,
562 };
563
564 for (size_t i = 0; i < array_size(sign); i++) {
565 ok(SecKeyIsAlgorithmSupported(privKey, kSecKeyOperationTypeSign, sign[i]),
566 "privKey supports sign algorithm %@", sign[i]);
567 ok(SecKeyIsAlgorithmSupported(pubKey, kSecKeyOperationTypeVerify, sign[i]),
568 "pubKey supports verify algorithm %@", sign[i]);
569 ok(!SecKeyIsAlgorithmSupported(privKey, kSecKeyOperationTypeVerify, sign[i]),
570 "privKey doesn't supports verify algorithm %@", sign[i]);
571 ok(!SecKeyIsAlgorithmSupported(pubKey, kSecKeyOperationTypeSign, sign[i]),
572 "pubKey doesn't support verify algorithm %@", sign[i]);
573 }
574
575 const SecKeyAlgorithm keyexchange[] = {
576 kSecKeyAlgorithmECDHKeyExchangeStandard,
577 kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA1,
578 kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA224,
579 kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA256,
580 kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA384,
581 kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA512,
582 kSecKeyAlgorithmECDHKeyExchangeCofactor,
583 kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA1,
584 kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA224,
585 kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA256,
586 kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA384,
587 kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA512,
588 };
589 for (size_t i = 0; i < array_size(crypt); i++) {
590 ok(SecKeyIsAlgorithmSupported(privKey, kSecKeyOperationTypeKeyExchange, keyexchange[i]),
591 "privKey supports keyexchange algorithm %@", keyexchange[i]);
592 ok(!SecKeyIsAlgorithmSupported(pubKey, kSecKeyOperationTypeKeyExchange, keyexchange[i]),
593 "pubKey doesn't support keyexchange algorithm %@", keyexchange[i]);
594 }
595
596 /* Cleanup. */
597 CFReleaseNull(kgp);
598 CFReleaseNull(pubKey);
599 CFReleaseNull(privKey);
600 }
601
602 static void testcreatewithdata(unsigned long keySizeInBits)
603 {
604 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
605 int32_t keysz32 = (int32_t)keySizeInBits;
606
607 CFNumberRef kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &keysz32);
608 CFDictionaryRef kgp = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
609 kSecAttrKeyType, kSecAttrKeyTypeEC,
610 kSecAttrKeySizeInBits, kzib,
611 kSecAttrIsPermanent, kCFBooleanFalse,
612 NULL);
613 SecKeyRef pubKey = NULL, privKey = NULL;
614 OSStatus status;
615 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
616 "Generate %ld bit (%ld byte) EC keypair (status = %d)",
617 keySizeInBits, keySizeInBytes, (int)status);
618 CFReleaseNull(kgp);
619
620 CFMutableDictionaryRef kcwd = CFDictionaryCreateMutableForCFTypesWith(kCFAllocatorDefault,
621 kSecAttrKeyType, kSecAttrKeyTypeEC,
622 kSecAttrKeySizeInBits, kzib,
623 kSecAttrIsPermanent, kCFBooleanFalse,
624 NULL);
625 CFReleaseNull(kzib);
626
627 CFErrorRef error = NULL;
628 CFDataRef privExternalData = NULL, pubExternalData = NULL;
629 SecKeyRef dataKey = NULL;
630
631 { // privKey
632 privExternalData = SecKeyCopyExternalRepresentation(privKey, &error);
633 ok(privExternalData && CFGetTypeID(privExternalData) == CFDataGetTypeID(),
634 "priv key SecKeyCopyExternalRepresentation failed");
635 CFReleaseNull(error);
636
637 SKIP: {
638 skip("invalid priv key external data", 4, privExternalData);
639
640 CFDictionarySetValue(kcwd, kSecAttrKeyClass, kSecAttrKeyClassPrivate);
641 dataKey = SecKeyCreateWithData(privExternalData, kcwd, &error);
642 ok(dataKey, "priv key SecKeyCreateWithData failed");
643 CFReleaseNull(error);
644
645 eq_cf(privKey, dataKey, "priv keys differ");
646 CFReleaseNull(dataKey);
647
648 CFDictionarySetValue(kcwd, kSecAttrKeyClass, kSecAttrKeyClassPublic);
649 dataKey = SecKeyCreateWithData(privExternalData, kcwd, &error);
650 ok(!dataKey, "priv key SecKeyCreateWithData succeeded with invalid kSecAttrKeyClass");
651 CFReleaseNull(error);
652 CFReleaseNull(dataKey);
653
654 CFMutableDataRef modifiedExternalData = CFDataCreateMutable(kCFAllocatorDefault, 0);
655 CFDataAppend(modifiedExternalData, privExternalData);
656 *CFDataGetMutableBytePtr(modifiedExternalData) ^= 0xff;
657
658 CFDictionarySetValue(kcwd, kSecAttrKeyClass, kSecAttrKeyClassPrivate);
659 dataKey = SecKeyCreateWithData(modifiedExternalData, kcwd, &error);
660 ok(!dataKey, "priv key SecKeyCreateWithData succeeded with invalid external data");
661 CFReleaseNull(error);
662 CFReleaseNull(dataKey);
663
664 CFReleaseNull(modifiedExternalData);
665 }
666 }
667
668 { // pubKey
669 pubExternalData = SecKeyCopyExternalRepresentation(pubKey, &error);
670 ok(pubExternalData && CFGetTypeID(pubExternalData) == CFDataGetTypeID(),
671 "pub key SecKeyCopyExternalRepresentation failed");
672 CFReleaseNull(error);
673
674 SKIP: {
675 skip("invalid pub key external data", 4, pubExternalData);
676
677 CFDictionarySetValue(kcwd, kSecAttrKeyClass, kSecAttrKeyClassPublic);
678 dataKey = SecKeyCreateWithData(pubExternalData, kcwd, &error);
679 ok(dataKey, "pub key SecKeyCreateWithData failed");
680 CFReleaseNull(error);
681
682 eq_cf(pubKey, dataKey, "pub keys differ");
683 CFReleaseNull(dataKey);
684
685 CFDictionarySetValue(kcwd, kSecAttrKeyClass, kSecAttrKeyClassPrivate);
686 dataKey = SecKeyCreateWithData(pubExternalData, kcwd, &error);
687 ok(!dataKey, "pub key SecKeyCreateWithData succeeded with invalid kSecAttrKeyClass");
688 CFReleaseNull(error);
689 CFReleaseNull(dataKey);
690
691 CFMutableDataRef modifiedExternalData = CFDataCreateMutable(kCFAllocatorDefault, 0);
692 CFDataAppend(modifiedExternalData, pubExternalData);
693 *CFDataGetMutableBytePtr(modifiedExternalData) ^= 0xff;
694
695 CFDictionarySetValue(kcwd, kSecAttrKeyClass, kSecAttrKeyClassPublic);
696 dataKey = SecKeyCreateWithData(modifiedExternalData, kcwd, &error);
697 ok(!dataKey, "pub key SecKeyCreateWithData succeeded with invalid external data");
698 CFReleaseNull(error);
699 CFReleaseNull(dataKey);
700
701 CFReleaseNull(modifiedExternalData);
702 }
703 }
704
705 SKIP: {
706 skip("invalid pub key external data", 1, pubExternalData);
707
708 CFDictionarySetValue(kcwd, kSecAttrKeyClass, kSecAttrKeyClassPrivate);
709 dataKey = SecKeyCreateWithData(pubExternalData, kcwd, &error);
710 ok(!dataKey, "priv key SecKeyCreateWithData succeeded with public external data");
711 CFReleaseNull(error);
712 CFReleaseNull(dataKey);
713
714 CFReleaseNull(pubExternalData);
715 }
716
717 SKIP: {
718 skip("invalid priv key external data", 1, privExternalData);
719
720 CFDictionarySetValue(kcwd, kSecAttrKeyClass, kSecAttrKeyClassPublic);
721 dataKey = SecKeyCreateWithData(privExternalData, kcwd, &error);
722 ok(!dataKey, "pub key SecKeyCreateWithData succeeded with private external data");
723 CFReleaseNull(error);
724 CFReleaseNull(dataKey);
725
726 CFReleaseNull(privExternalData);
727 }
728
729 CFReleaseNull(kcwd);
730 CFReleaseNull(pubKey);
731 CFReleaseNull(privKey);
732 }
733
734 static void testcopyattributes(unsigned long keySizeInBits)
735 {
736 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
737 int32_t keysz32 = (int32_t)keySizeInBits;
738
739 CFNumberRef kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &keysz32);
740 CFDictionaryRef kgp = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
741 kSecAttrKeyType, kSecAttrKeyTypeEC,
742 kSecAttrKeySizeInBits, kzib,
743 kSecAttrIsPermanent, kCFBooleanFalse,
744 NULL);
745 SecKeyRef pubKey = NULL, privKey = NULL;
746 OSStatus status;
747 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
748 "Generate %ld bit (%ld byte) EC keypair (status = %d)",
749 keySizeInBits, keySizeInBytes, (int)status);
750 CFReleaseNull(kgp);
751
752 CFDictionaryRef attributes;
753 CFTypeRef attrValue = NULL, privAppLabel = NULL, pubAppLabel = NULL;
754
755 { // privKey
756 attributes = SecKeyCopyAttributes(privKey);
757 ok(attributes && CFGetTypeID(attributes) == CFDictionaryGetTypeID(),
758 "priv key SecKeyCopyAttributes failed");
759
760 SKIP: {
761 skip("invalid attributes", 8, attributes);
762
763 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanEncrypt);
764 eq_cf(attrValue, kCFBooleanFalse, "invalid priv key kSecAttrCanEncrypt");
765
766 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanDecrypt);
767 eq_cf(attrValue, kCFBooleanTrue, "invalid priv key kSecAttrCanDecrypt");
768
769 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanDerive);
770 eq_cf(attrValue, kCFBooleanTrue, "invalid priv key kSecAttrCanDerive");
771
772 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanSign);
773 eq_cf(attrValue, kCFBooleanTrue, "invalid priv key kSecAttrCanSign");
774
775 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanVerify);
776 eq_cf(attrValue, kCFBooleanFalse, "invalid priv key kSecAttrCanVerify");
777
778 attrValue = CFDictionaryGetValue(attributes, kSecAttrKeyClass);
779 eq_cf(attrValue, kSecAttrKeyClassPrivate, "priv key invalid kSecAttrKeyClass");
780
781 attrValue = CFDictionaryGetValue(attributes, kSecAttrKeyType);
782 eq_cf(attrValue, kSecAttrKeyTypeEC, "invalid priv key kSecAttrKeyType");
783
784 attrValue = CFDictionaryGetValue(attributes, kSecAttrKeySizeInBits);
785 eq_cf(attrValue, kzib, "invalid priv key kSecAttrKeySizeInBits");
786
787 privAppLabel = CFDictionaryGetValue(attributes, kSecAttrApplicationLabel);
788 CFRetainSafe(privAppLabel);
789
790 CFReleaseNull(attributes);
791 }
792 }
793
794 { // pubKey
795 attributes = SecKeyCopyAttributes(pubKey);
796 ok(attributes && CFGetTypeID(attributes) == CFDictionaryGetTypeID(),
797 "pub key SecKeyCopyAttributes failed");
798
799 SKIP: {
800 skip("invalid attributes", 8, attributes);
801
802 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanEncrypt);
803 eq_cf(attrValue, kCFBooleanTrue, "pub key invalid kSecAttrCanEncrypt");
804
805 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanDecrypt);
806 eq_cf(attrValue, kCFBooleanFalse, "pub key invalid kSecAttrCanDecrypt");
807
808 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanDerive);
809 eq_cf(attrValue, kCFBooleanFalse, "pub key invalid kSecAttrCanDerive");
810
811 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanSign);
812 eq_cf(attrValue, kCFBooleanFalse, "pub key invalid kSecAttrCanSign");
813
814 attrValue = CFDictionaryGetValue(attributes, kSecAttrCanVerify);
815 eq_cf(attrValue, kCFBooleanTrue, "pub key invalid kSecAttrCanVerify");
816
817 attrValue = CFDictionaryGetValue(attributes, kSecAttrKeyClass);
818 eq_cf(attrValue, kSecAttrKeyClassPublic, "pub key invalid kSecAttrKeyClass");
819
820 attrValue = CFDictionaryGetValue(attributes, kSecAttrKeyType);
821 eq_cf(attrValue, kSecAttrKeyTypeEC, "pub key invalid kSecAttrKeyType");
822
823 attrValue = CFDictionaryGetValue(attributes, kSecAttrKeySizeInBits);
824 eq_cf(attrValue, kzib, "pub key invalid kSecAttrKeySizeInBits");
825
826 pubAppLabel = CFDictionaryGetValue(attributes, kSecAttrApplicationLabel);
827 CFRetainSafe(pubAppLabel);
828
829 CFReleaseNull(attributes);
830 }
831 }
832
833 eq_cf(privAppLabel, pubAppLabel, "priv key and pub key kSecAttrApplicationLabel differ");
834
835 CFReleaseNull(privAppLabel);
836 CFReleaseNull(pubAppLabel);
837 CFReleaseNull(kzib);
838 CFReleaseNull(pubKey);
839 CFReleaseNull(privKey);
840 }
841
842 static void testcopypublickey(unsigned long keySizeInBits)
843 {
844 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
845 int32_t keysz32 = (int32_t)keySizeInBits;
846
847 CFNumberRef kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &keysz32);
848 CFDictionaryRef kgp = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
849 kSecAttrKeyType, kSecAttrKeyTypeEC,
850 kSecAttrKeySizeInBits, kzib,
851 kSecAttrIsPermanent, kCFBooleanFalse,
852 NULL);
853 CFReleaseNull(kzib);
854
855 SecKeyRef pubKey = NULL, privKey = NULL;
856 OSStatus status;
857 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
858 "Generate %ld bit (%ld byte) EC keypair (status = %d)",
859 keySizeInBits, keySizeInBytes, (int)status);
860 CFReleaseNull(kgp);
861
862 SecKeyRef pubKeyCopy = NULL;
863
864 { // privKey
865 pubKeyCopy = SecKeyCopyPublicKey(privKey);
866 ok(pubKeyCopy, "priv key SecKeyCopyPublicKey failed");
867 eq_cf(pubKeyCopy, pubKey, "pub key from priv key SecKeyCopyPublicKey and pub key differ");
868 CFReleaseNull(pubKeyCopy);
869 }
870
871 { // pubKey
872 pubKeyCopy = SecKeyCopyPublicKey(pubKey);
873 ok(pubKeyCopy, "pub key SecKeyCopyPublicKey failed");
874 eq_cf(pubKeyCopy, pubKey, "pub key from pub key SecKeyCopyPublicKey and pub key differ");
875 CFReleaseNull(pubKeyCopy);
876 }
877
878 CFReleaseNull(pubKey);
879 CFReleaseNull(privKey);
880 }
881
882 static void testsignverify(unsigned long keySizeInBits)
883 {
884 size_t keySizeInBytes = (keySizeInBits + 7) / 8;
885 int32_t keysz32 = (int32_t)keySizeInBits;
886
887 CFNumberRef kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &keysz32);
888 CFDictionaryRef kgp = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
889 kSecAttrKeyType, kSecAttrKeyTypeEC,
890 kSecAttrKeySizeInBits, kzib,
891 kSecAttrIsPermanent, kCFBooleanFalse,
892 NULL);
893 CFReleaseNull(kzib);
894
895 SecKeyRef pubKey = NULL, privKey = NULL;
896 OSStatus status;
897 ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
898 "Generate %ld bit (%ld byte) EC keypair (status = %d)",
899 keySizeInBits, keySizeInBytes, (int)status);
900 CFReleaseNull(kgp);
901
902 SecKeyAlgorithm algorithms[] = {
903 kSecKeyAlgorithmECDSASignatureRFC4754,
904 kSecKeyAlgorithmECDSASignatureDigestX962,
905 kSecKeyAlgorithmECDSASignatureMessageX962SHA1,
906 kSecKeyAlgorithmECDSASignatureMessageX962SHA224,
907 kSecKeyAlgorithmECDSASignatureMessageX962SHA256,
908 kSecKeyAlgorithmECDSASignatureMessageX962SHA384,
909 kSecKeyAlgorithmECDSASignatureMessageX962SHA512
910 };
911
912 CFDataRef testData = CFStringCreateExternalRepresentation(kCFAllocatorDefault, CFSTR("test"), kCFStringEncodingUTF8, 0);
913 ok(testData, "creating test data failed");
914
915 SKIP: {
916 skip("invalid test data", 51, status == errSecSuccess && testData);
917
918 CFErrorRef error = NULL;
919
920 for (uint32_t ix = 0; ix < array_size(algorithms); ++ix) {
921 SecKeyAlgorithm algorithm = algorithms[ix];
922 SecKeyAlgorithm incompatibleAlgorithm = CFEqual(algorithm, kSecKeyAlgorithmECDSASignatureRFC4754) ?
923 kSecKeyAlgorithmECDSASignatureDigestX962 : kSecKeyAlgorithmECDSASignatureRFC4754;
924
925 CFDataRef dataToSign = NULL;
926 if (CFEqual(algorithm, kSecKeyAlgorithmECDSASignatureRFC4754) ||
927 CFEqual(algorithm, kSecKeyAlgorithmECDSASignatureDigestX962)) {
928 dataToSign = CFDataCreateWithHash(kCFAllocatorDefault, ccsha256_di(),
929 CFDataGetBytePtr(testData), CFDataGetLength(testData));
930 ok(dataToSign, "creating digest failed for algorithm %d", (int)algorithm);
931 CFReleaseNull(error);
932 }
933 else {
934 CFRetainAssign(dataToSign, testData);
935 }
936
937 SKIP: {
938 skip("invalid data to sign", 7, dataToSign != NULL);
939
940 CFDataRef signature = SecKeyCreateSignature(pubKey, algorithm, dataToSign, &error);
941 ok(!signature, "SecKeyCopySignature succeeded with pub key for algorithm %d", (int)algorithm);
942 CFReleaseNull(error);
943 CFReleaseNull(signature);
944
945 signature = SecKeyCreateSignature(privKey, algorithm, dataToSign, &error);
946 ok(signature, "SecKeyCopySignature failed for algorithm %d", (int)algorithm);
947 CFReleaseNull(error);
948
949 SKIP: {
950 skip("invalid signature", 5, signature != NULL);
951
952 ok(!SecKeyVerifySignature(privKey, algorithm, dataToSign, signature, &error),
953 "SecKeyVerifySignature succeeded with priv key for %d", (int)algorithm);
954 CFReleaseNull(error);
955
956 ok(!SecKeyVerifySignature(pubKey, incompatibleAlgorithm, dataToSign, signature, &error),
957 "SecKeyVerifySignature succeeded with wrong algorithm for %d", (int)algorithm);
958 CFReleaseNull(error);
959
960 ok(SecKeyVerifySignature(pubKey, algorithm, dataToSign, signature, &error),
961 "SecKeyVerifySignature failed for algorithm %d", (int)algorithm);
962 CFReleaseNull(error);
963
964 CFMutableDataRef modifiedSignature = CFDataCreateMutable(kCFAllocatorDefault, 0);
965 CFDataAppend(modifiedSignature, signature);
966 *CFDataGetMutableBytePtr(modifiedSignature) ^= 0xff;
967
968 ok(!SecKeyVerifySignature(pubKey, algorithm, dataToSign, modifiedSignature, &error),
969 "SecKeyVerifySignature succeeded with bad signature for algorithm %d", (int)algorithm);
970 CFReleaseNull(error);
971
972 CFMutableDataRef modifiedDataToSign = CFDataCreateMutable(kCFAllocatorDefault, 0);
973 CFDataAppend(modifiedDataToSign, dataToSign);
974 *CFDataGetMutableBytePtr(modifiedDataToSign) ^= 0xff;
975
976 ok(!SecKeyVerifySignature(pubKey, algorithm, modifiedDataToSign, signature, &error),
977 "SecKeyVerifySignature succeeded with bad data for %d", (int)algorithm);
978 CFReleaseNull(error);
979
980 CFReleaseNull(modifiedDataToSign);
981 CFReleaseNull(modifiedSignature);
982
983 CFReleaseNull(signature);
984 }
985 CFReleaseNull(dataToSign);
986 }
987 }
988 }
989
990 CFReleaseNull(testData);
991 CFReleaseNull(pubKey);
992 CFReleaseNull(privKey);
993 }
994
995 /* Test basic add delete update copy matching stuff. */
996 static void tests(void)
997 {
998 testsignformat();
999
1000 testkeygen(192);
1001 testkeygen(224);
1002 testkeygen(256);
1003 testkeygen(384);
1004 testkeygen(521);
1005
1006 testkeygen2(192);
1007 testkeygen2(224);
1008 testkeygen2(256);
1009 testkeygen2(384);
1010 testkeygen2(521);
1011
1012 testkeywrap(256, _kSecKeyWrapRFC6637WrapDigestSHA256KekAES128);
1013 testkeywrap(521, _kSecKeyWrapRFC6637WrapDigestSHA256KekAES128);
1014 testkeywrap(256, _kSecKeyWrapRFC6637WrapDigestSHA512KekAES256);
1015 testkeywrap(521, _kSecKeyWrapRFC6637WrapDigestSHA512KekAES256);
1016
1017 testkeyexchange(192);
1018 testkeyexchange(224);
1019 testkeyexchange(256);
1020 testkeyexchange(384);
1021 testkeyexchange(521);
1022
1023 testsupportedalgos(192);
1024 testcreatewithdata(192);
1025 testcopyattributes(192);
1026 testcopypublickey(192);
1027 testsignverify(192);
1028 }
1029
1030 int si_41_sececkey(int argc, char *const *argv)
1031 {
1032 plan_tests(557);
1033
1034 tests();
1035
1036 return 0;
1037 }