2 * Copyright (c) 2007-2009,2012-2014 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
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>
41 #include <corecrypto/ccsha1.h>
42 #include <corecrypto/ccsha2.h>
44 #include "Security_regressions.h"
46 #include "utilities/SecCFRelease.h"
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
);
55 oid
.length
= algId
->algorithm
.Length
;
56 oid
.data
= algId
->algorithm
.Data
;
58 /* Get the oid in decimal for display purposes. */
59 CFStringRef oidStr
= SecDERItemCopyOIDDecimalRepresentation(kCFAllocatorDefault
, &oid
);
61 CFStringGetCString(oidStr
, oidBuf
, sizeof(oidBuf
), kCFStringEncodingUTF8
);
68 ok_status(status
= SecKeyDigestAndSign(privKey
, algId
, dataToDigest
, dataToDigestLen
,
69 sig
, &sigLen
), "digest and sign %s with %ld bit RSA key", oidBuf
, sigLen
* 8);
71 skip("SecKeyDigestAndSign failed", 3, status
== errSecSuccess
);
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 /* Tweak the least-significant bit to avoid putting the signature out of range. */
79 is_status(SecKeyDigestAndVerify(pubKey
, algId
, dataToDigest
, dataToDigestLen
,
80 sig
, sigLen
), errSSLCrypto
, "digest and verify bad sig");
82 dataToDigest
[0] ^= 0xff;
83 is_status(SecKeyDigestAndVerify(pubKey
, algId
, dataToDigest
, dataToDigestLen
,
84 sig
, sigLen
), errSSLCrypto
, "digest and verify bad digest");
88 static void testdigestandsign(SecKeyRef privKey
, SecKeyRef pubKey
) {
89 static const SecAsn1Oid
*oids
[] = {
91 &CSSMOID_SHA224WithRSA
,
92 &CSSMOID_SHA256WithRSA
,
93 &CSSMOID_SHA384WithRSA
,
94 &CSSMOID_SHA512WithRSA
,
96 &CSSMOID_SHA1WithRSA_OIW
,
97 &CSSMOID_SHA1WithDSA
, // BSAFE
98 &CSSMOID_SHA1WithDSA_CMS
, // X509/CMS
99 &CSSMOID_SHA1WithDSA_JDK
, // JDK 1.1
105 SecAsn1AlgId algId
= {};
106 for (ix
= 0; ix
< array_size(oids
); ++ix
) {
108 algId
.algorithm
= *oids
[ix
];
110 algId
.algorithm
.Length
= 0;
111 algId
.algorithm
.Data
= NULL
;
114 testdigestandsignalg(privKey
, pubKey
, &algId
);
119 static void dump_bytes(uint8_t* bytes
, size_t amount
)
122 printf("0x%02x ", *bytes
);
129 #define kEncryptDecryptTestCount 6
130 static void test_encrypt_decrypt(SecKeyRef pubKey
, SecKeyRef privKey
, uint32_t padding
, size_t keySizeInBytes
)
133 size_t max_len
= keySizeInBytes
;
135 case kSecPaddingNone
: max_len
= keySizeInBytes
; break;
136 case kSecPaddingOAEP
: max_len
= keySizeInBytes
- 2 - 2 * CC_SHA1_DIGEST_LENGTH
; break;
137 case kSecPaddingPKCS1
: max_len
= keySizeInBytes
- 11; break;
138 default: skip("what is the max_len for this padding?", 5, false);
141 uint8_t secret
[max_len
+ 2], encrypted_secret
[keySizeInBytes
], decrypted_secret
[keySizeInBytes
];
142 uint8_t *secret_ptr
= secret
;
143 size_t secret_len
= max_len
;
144 size_t encrypted_secret_len
= sizeof(encrypted_secret
);
145 size_t decrypted_secret_len
= sizeof(decrypted_secret
);
146 memset(decrypted_secret
, 0xff, decrypted_secret_len
);
147 ok_status(SecRandomCopyBytes(kSecRandomDefault
, sizeof(secret
), secret
),"rng");
149 // zero pad, no accidental second zero byte
150 if (padding
== kSecPaddingNone
) {
155 is_status(SecKeyEncrypt(pubKey
, padding
,
156 secret
, sizeof(secret
),
157 encrypted_secret
, &encrypted_secret_len
), errSecParam
, "encrypt secret (overflow)");
158 ok_status(SecKeyEncrypt(pubKey
, padding
,
160 encrypted_secret
, &encrypted_secret_len
), "encrypt secret");
162 ok_status(SecKeyDecrypt(privKey
, padding
,
163 encrypted_secret
, encrypted_secret_len
,
164 decrypted_secret
, &decrypted_secret_len
), "decrypt secret");
166 // zero padding is removed on decode
167 if (padding
== kSecPaddingNone
) {
172 ok(decrypted_secret_len
== secret_len
, "correct length");
173 ok_status(memcmp(secret_ptr
, decrypted_secret
, secret_len
), "verify secret");
177 #define kKeyGenTestCount (50 + (3*kEncryptDecryptTestCount))
178 static void testkeygen(size_t keySizeInBits
) {
179 SecKeyRef pubKey
= NULL
, privKey
= NULL
;
180 size_t keySizeInBytes
= (keySizeInBits
+ 7) / 8;
183 int32_t iKeySizeInBits
= (int32_t) keySizeInBits
;
184 kzib
= CFNumberCreate(NULL
, kCFNumberSInt32Type
, &iKeySizeInBits
);
185 CFMutableDictionaryRef kgp
= CFDictionaryCreateMutable(NULL
, 0, NULL
, NULL
);
186 CFDictionaryAddValue(kgp
, kSecAttrKeyType
, kSecAttrKeyTypeRSA
);
187 CFDictionaryAddValue(kgp
, kSecAttrKeySizeInBits
, kzib
);
190 ok_status(status
= SecKeyGeneratePair(kgp
, &pubKey
, &privKey
),
191 "Generate %ld bit (%ld byte) RSA keypair", keySizeInBits
,
197 skip("keygen failed", 8, status
== errSecSuccess
);
198 ok(pubKey
, "pubkey returned");
199 ok(privKey
, "privKey returned");
200 is(SecKeyGetSize(pubKey
, kSecKeyKeySizeInBits
), (size_t) keySizeInBits
, "public key size is ok");
201 is(SecKeyGetSize(privKey
, kSecKeyKeySizeInBits
), (size_t) keySizeInBits
, "private key size is ok");
203 /* Sign something. */
204 uint8_t something
[keySizeInBytes
];
205 size_t something_len
= keySizeInBytes
- 11;
206 ok_status(SecRandomCopyBytes(kSecRandomDefault
, sizeof(something
), something
),"rng");
207 uint8_t sig
[keySizeInBytes
];
208 size_t sigLen
= sizeof(sig
);
209 if (privKey
!= NULL
&& pubKey
!= NULL
) {
210 is_status(SecKeyRawSign(privKey
, kSecPaddingPKCS1
,
211 something
, something_len
+ 1, sig
, &sigLen
),
212 errSecParam
, "sign overflow");
213 ok_status(SecKeyRawSign(privKey
, kSecPaddingPKCS1
,
214 something
, something_len
, sig
, &sigLen
), "sign something");
215 ok_status(SecKeyRawVerify(pubKey
, kSecPaddingPKCS1
,
216 something
, something_len
, sig
, sigLen
), "verify sig on something");
218 // Torture test ASN.1 encoder by setting high bit to 1.
219 uint8_t digest
[CC_SHA512_DIGEST_LENGTH
] = {
220 0x80, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
221 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
222 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
223 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
224 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
225 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
226 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
227 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
229 //CC_MD2(something, sizeof(something), digest);
230 ok_status(!SecKeyRawSign(privKey
, kSecPaddingPKCS1MD2
,
231 digest
, CC_MD2_DIGEST_LENGTH
, sig
, &sigLen
),
232 "don't sign md2 digest");
233 ok_status(!SecKeyRawVerify(pubKey
, kSecPaddingPKCS1MD2
,
234 digest
, CC_MD2_DIGEST_LENGTH
, sig
, sigLen
),
235 "verify sig on md2 digest fails");
237 //CC_MD5(something, sizeof(something), digest);
238 sigLen
= sizeof(sig
);
239 ok_status(!SecKeyRawSign(privKey
, kSecPaddingPKCS1MD5
,
240 digest
, CC_MD5_DIGEST_LENGTH
, sig
, &sigLen
),
241 "don't sign md5 digest");
242 ok_status(!SecKeyRawVerify(pubKey
, kSecPaddingPKCS1MD5
,
243 digest
, CC_MD5_DIGEST_LENGTH
, sig
, sigLen
),
244 "verify sig on md5 digest fails");
246 //CCDigest(kCCDigestSHA1, something, sizeof(something), digest);
247 sigLen
= sizeof(sig
);
248 ok_status(SecKeyRawSign(privKey
, kSecPaddingPKCS1SHA1
,
249 digest
, CC_SHA1_DIGEST_LENGTH
, sig
, &sigLen
),
251 ok_status(SecKeyRawVerify(pubKey
, kSecPaddingPKCS1SHA1
,
252 digest
, CC_SHA1_DIGEST_LENGTH
, sig
, sigLen
),
253 "verify sig on sha1 digest");
255 uint8_t signature
[keySizeInBytes
], *ptr
= signature
;
256 size_t signature_len
= sizeof(signature
);
257 ok_status(SecKeyDecrypt(pubKey
, kSecPaddingNone
, sig
, sigLen
, signature
, &signature_len
), "inspect signature");
258 is(signature_len
, keySizeInBytes
- 1, "got signature");
259 while(*ptr
&& ((size_t)(ptr
- signature
) < signature_len
)) ptr
++;
260 is(signature
+ signature_len
- ptr
, 16 /* length(\0 || OID_SHA1) */ + CC_SHA1_DIGEST_LENGTH
, "successful decode");
262 /* PKCS1 padding is 00 01 PAD * 8 or more 00 data.
263 data is SEQ { SEQ { OID NULL } BIT STRING 00 DIGEST }
264 So min data + pad overhead is 11 + 9 + oidlen
265 oidlen = 11 for the sha2 family of oids, so we have 29 bytes; or
266 232 bits of minimum overhead. */
267 const size_t pkcs1Overhead
= 232;
268 if (keySizeInBits
> 224 + pkcs1Overhead
) {
269 //CC_SHA224(something, sizeof(something), digest);
270 sigLen
= sizeof(sig
);
271 ok_status(SecKeyRawSign(privKey
, kSecPaddingPKCS1SHA224
,
272 digest
, CC_SHA224_DIGEST_LENGTH
, sig
, &sigLen
),
273 "sign sha224 digest");
274 ok_status(SecKeyRawVerify(pubKey
, kSecPaddingPKCS1SHA224
,
275 digest
, CC_SHA224_DIGEST_LENGTH
, sig
, sigLen
),
276 "verify sig on sha224 digest");
279 if (keySizeInBits
> 256 + pkcs1Overhead
) {
280 //CC_SHA256(something, sizeof(something), digest);
281 sigLen
= sizeof(sig
);
282 ok_status(SecKeyRawSign(privKey
, kSecPaddingPKCS1SHA256
,
283 digest
, CC_SHA256_DIGEST_LENGTH
, sig
, &sigLen
),
284 "sign sha256 digest");
285 ok_status(SecKeyRawVerify(pubKey
, kSecPaddingPKCS1SHA256
,
286 digest
, CC_SHA256_DIGEST_LENGTH
, sig
, sigLen
),
287 "verify sig on sha256 digest");
290 if (keySizeInBits
> 384 + pkcs1Overhead
) {
291 //CC_SHA384(something, sizeof(something), digest);
292 sigLen
= sizeof(sig
);
293 ok_status(SecKeyRawSign(privKey
, kSecPaddingPKCS1SHA384
,
294 digest
, CC_SHA384_DIGEST_LENGTH
, sig
, &sigLen
),
295 "sign sha384 digest");
296 ok_status(SecKeyRawVerify(pubKey
, kSecPaddingPKCS1SHA384
,
297 digest
, CC_SHA384_DIGEST_LENGTH
, sig
, sigLen
),
298 "verify sig on sha384 digest");
301 if (keySizeInBits
> 512 + pkcs1Overhead
) {
302 //CC_SHA512(something, sizeof(something), digest);
303 sigLen
= sizeof(sig
);
304 ok_status(SecKeyRawSign(privKey
, kSecPaddingPKCS1SHA512
,
305 digest
, CC_SHA512_DIGEST_LENGTH
, sig
, &sigLen
),
306 "sign sha512 digest");
307 ok_status(SecKeyRawVerify(pubKey
, kSecPaddingPKCS1SHA512
,
308 digest
, CC_SHA512_DIGEST_LENGTH
, sig
, sigLen
),
309 "verify sig on sha512 digest");
313 test_encrypt_decrypt(pubKey
, privKey
, kSecPaddingNone
, keySizeInBytes
);
314 test_encrypt_decrypt(pubKey
, privKey
, kSecPaddingPKCS1
, keySizeInBytes
);
315 test_encrypt_decrypt(pubKey
, privKey
, kSecPaddingOAEP
, keySizeInBytes
);
317 testdigestandsign(privKey
, pubKey
);
319 const void *privkeys
[] = {
322 const void *privvalues
[] = {
325 CFDictionaryRef privitem
= CFDictionaryCreate(NULL
, privkeys
, privvalues
,
326 array_size(privkeys
), NULL
, NULL
);
327 ok_status(SecItemAdd(privitem
, NULL
), "add private key");
328 ok_status(SecItemDelete(privitem
), "delete private key");
329 CFReleaseNull(privitem
);
331 const void *pubkeys
[] = {
334 const void *pubvalues
[] = {
337 CFDictionaryRef pubitem
= CFDictionaryCreate(NULL
, pubkeys
, pubvalues
,
338 array_size(pubkeys
), NULL
, NULL
);
339 ok_status(SecItemAdd(pubitem
, NULL
), "add public key");
340 ok_status(SecItemDelete(pubitem
), "delete public key");
341 CFReleaseNull(pubitem
);
344 CFReleaseNull(pubKey
);
345 CFReleaseNull(privKey
);
349 #define kKeyGen2TestCount 12
350 static void testkeygen2(size_t keySizeInBits
) {
351 SecKeyRef pubKey
= NULL
, privKey
= NULL
;
352 int32_t keySizeInBytes
= (int32_t)((keySizeInBits
+ 7) / 8);
355 CFUUIDRef ourUUID
= CFUUIDCreate(kCFAllocatorDefault
);
356 CFStringRef uuidString
= CFUUIDCreateString(kCFAllocatorDefault
, ourUUID
);
357 CFMutableStringRef publicName
= CFStringCreateMutableCopy(kCFAllocatorDefault
, 0, uuidString
);
358 CFMutableStringRef privateName
= CFStringCreateMutableCopy(kCFAllocatorDefault
, 0, uuidString
);
360 CFReleaseNull(ourUUID
);
361 CFReleaseNull(uuidString
);
363 CFStringAppend(publicName
, CFSTR("-Public-40"));
364 CFStringAppend(privateName
, CFSTR("-Private-40"));
365 CFMutableDictionaryRef pubd
= CFDictionaryCreateMutable(NULL
, 0, NULL
, NULL
);
366 CFMutableDictionaryRef privd
= CFDictionaryCreateMutable(NULL
, 0, NULL
, NULL
);
368 CFDictionaryAddValue(pubd
, kSecAttrLabel
, publicName
);
369 CFDictionaryAddValue(privd
, kSecAttrLabel
, privateName
);
371 int32_t iKeySizeInBits
= (int32_t) keySizeInBits
;
372 kzib
= CFNumberCreate(NULL
, kCFNumberSInt32Type
, &iKeySizeInBits
);
373 CFMutableDictionaryRef kgp
= CFDictionaryCreateMutable(NULL
, 0, NULL
, NULL
);
374 CFDictionaryAddValue(kgp
, kSecAttrKeyType
, kSecAttrKeyTypeRSA
);
375 CFDictionaryAddValue(kgp
, kSecAttrKeySizeInBits
, kzib
);
376 CFDictionaryAddValue(kgp
, kSecAttrIsPermanent
, kCFBooleanTrue
);
377 CFDictionaryAddValue(kgp
, kSecPublicKeyAttrs
, pubd
);
378 CFDictionaryAddValue(kgp
, kSecPrivateKeyAttrs
, privd
);
381 ok_status(status
= SecKeyGeneratePair(kgp
, &pubKey
, &privKey
),
382 "Generate %d bit (%d byte) persistent RSA keypair",
383 (int)keySizeInBits
, (int)keySizeInBytes
);
388 skip("keygen failed", 8, status
== errSecSuccess
);
389 ok(pubKey
, "pubkey returned");
390 ok(privKey
, "privKey returned");
391 is(SecKeyGetSize(pubKey
, kSecKeyKeySizeInBits
), (size_t) keySizeInBits
, "public key size is ok");
392 is(SecKeyGetSize(privKey
, kSecKeyKeySizeInBits
), (size_t) keySizeInBits
, "private key size is ok");
394 SecKeyRef pubKey2
, privKey2
;
395 CFDictionaryAddValue(pubd
, kSecClass
, kSecClassKey
);
396 CFDictionaryAddValue(pubd
, kSecReturnRef
, kCFBooleanTrue
);
397 CFDictionaryAddValue(privd
, kSecClass
, kSecClassKey
);
398 CFDictionaryAddValue(privd
, kSecReturnRef
, kCFBooleanTrue
);
399 CFDictionaryAddValue(privd
, kSecAttrCanSign
, kCFBooleanTrue
);
400 ok_status(SecItemCopyMatching(pubd
, (CFTypeRef
*)&pubKey2
),
401 "retrieve pub key by label");
402 ok_status(SecItemCopyMatching(privd
, (CFTypeRef
*)&privKey2
),
403 "retrieve priv key by label and kSecAttrCanSign");
405 /* Sign something. */
406 uint8_t something
[50] = {0x80, 0xbe, 0xef, 0xba, 0xd0, };
407 uint8_t sig
[keySizeInBytes
];
408 size_t sigLen
= keySizeInBytes
;
409 ok_status(SecKeyRawSign(privKey2
, kSecPaddingPKCS1
,
410 something
, sizeof(something
), sig
, &sigLen
), "sign something");
411 ok_status(SecKeyRawVerify(pubKey2
, kSecPaddingPKCS1
,
412 something
, sizeof(something
), sig
, sigLen
), "verify sig on something");
414 sigLen
= keySizeInBytes
;
415 is_status(SecKeyEncrypt(pubKey2
, kSecPaddingPKCS1SHA1
,
416 something
, sizeof(something
), sig
, &sigLen
), errSecParam
,
417 "encrypt something with invalid padding");
420 CFReleaseNull(pubKey2
);
421 CFReleaseNull(privKey2
);
423 /* delete from keychain - note: do it before releasing publicName and privateName
424 because pubd and privd have no retain/release callbacks */
425 ok_status(SecItemDelete(pubd
), "delete generated pub key");
426 ok_status(SecItemDelete(privd
), "delete generated priv key");
430 CFReleaseNull(pubKey
);
431 CFReleaseNull(privKey
);
433 CFReleaseNull(publicName
);
434 CFReleaseNull(privateName
);
440 static const int kTestSupportedCount
= 3 + (4 * 11) + 2 + (4 * 5);
441 static void testsupportedalgos(size_t keySizeInBits
)
443 SecKeyRef pubKey
= NULL
, privKey
= NULL
;
444 int32_t keySizeInBytes
= (int)((keySizeInBits
+ 7) / 8);
447 int32_t iKeySizeInBits
= (int32_t) keySizeInBits
;
448 kzib
= CFNumberCreate(NULL
, kCFNumberSInt32Type
, &iKeySizeInBits
);
449 CFMutableDictionaryRef kgp
= CFDictionaryCreateMutable(NULL
, 0, NULL
, NULL
);
450 CFDictionaryAddValue(kgp
, kSecAttrKeyType
, kSecAttrKeyTypeRSA
);
451 CFDictionaryAddValue(kgp
, kSecAttrKeySizeInBits
, kzib
);
454 ok_status(status
= SecKeyGeneratePair(kgp
, &pubKey
, &privKey
),
455 "Generate %d bit (%d byte) persistent RSA keypair",
456 (int)keySizeInBits
, (int)keySizeInBytes
);
460 is(SecKeyGetSize(pubKey
, kSecKeyKeySizeInBits
), (size_t) keySizeInBits
, "public key size is ok");
461 is(SecKeyGetSize(privKey
, kSecKeyKeySizeInBits
), (size_t) keySizeInBits
, "private key size is ok");
463 const SecKeyAlgorithm sign
[] = {
464 kSecKeyAlgorithmRSASignatureRaw
,
465 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1
,
466 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1
,
467 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA224
,
468 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA224
,
469 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256
,
470 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256
,
471 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384
,
472 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA384
,
473 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512
,
474 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA512
,
477 for (size_t i
= 0; i
< array_size(sign
); i
++) {
478 ok(SecKeyIsAlgorithmSupported(privKey
, kSecKeyOperationTypeSign
, sign
[i
]),
479 "privKey supports sign algorithm %@", sign
[i
]);
480 ok(SecKeyIsAlgorithmSupported(pubKey
, kSecKeyOperationTypeVerify
, sign
[i
]),
481 "pubKey supports verify algorithm %@", sign
[i
]);
482 // Our privKey actually supports even verify operation because it is adapter over decrypt...
483 ok(SecKeyIsAlgorithmSupported(privKey
, kSecKeyOperationTypeVerify
, sign
[i
]),
484 "privKey supports verify algorithm %@", sign
[i
]);
485 ok(!SecKeyIsAlgorithmSupported(pubKey
, kSecKeyOperationTypeSign
, sign
[i
]),
486 "pubKey doesn't support verify algorithm %@", sign
[i
]);
488 ok(!SecKeyIsAlgorithmSupported(privKey
, kSecKeyOperationTypeSign
, kSecKeyAlgorithmECDSASignatureDigestX962
),
489 "RSA privKey does not support ECDSA algorithm");
490 ok(!SecKeyIsAlgorithmSupported(privKey
, kSecKeyOperationTypeVerify
, kSecKeyAlgorithmECDSASignatureDigestX962
),
491 "RSA pubKey does not support ECDSA algorithm");
493 const SecKeyAlgorithm crypt
[] = {
494 kSecKeyAlgorithmRSAEncryptionRaw
,
495 kSecKeyAlgorithmRSAEncryptionPKCS1
,
496 kSecKeyAlgorithmRSAEncryptionOAEPSHA1
,
497 kSecKeyAlgorithmRSAEncryptionOAEPSHA224
,
498 kSecKeyAlgorithmRSAEncryptionOAEPSHA256
,
499 // kSecKeyAlgorithmRSAEncryptionOAEPSHA384,
500 // kSecKeyAlgorithmRSAEncryptionOAEPSHA512,
502 for (size_t i
= 0; i
< array_size(crypt
); i
++) {
503 ok(SecKeyIsAlgorithmSupported(privKey
, kSecKeyOperationTypeDecrypt
, crypt
[i
]),
504 "privKey supports decrypt algorithm %@", crypt
[i
]);
505 ok(SecKeyIsAlgorithmSupported(pubKey
, kSecKeyOperationTypeEncrypt
, crypt
[i
]),
506 "pubKey supports encrypt algorithm %@", crypt
[i
]);
507 ok(!SecKeyIsAlgorithmSupported(privKey
, kSecKeyOperationTypeEncrypt
, crypt
[i
]),
508 "privKey doesn't supports encrypt algorithm %@", crypt
[i
]);
509 ok(SecKeyIsAlgorithmSupported(pubKey
, kSecKeyOperationTypeDecrypt
, crypt
[i
]),
510 "pubKey supports decrypt algorithm %@", crypt
[i
]);
514 CFReleaseNull(pubKey
);
515 CFReleaseNull(privKey
);
518 #define kCreateWithDataTestCount 13
519 static void testcreatewithdata(unsigned long keySizeInBits
)
521 size_t keySizeInBytes
= (keySizeInBits
+ 7) / 8;
522 int32_t keysz32
= (int32_t)keySizeInBits
;
524 CFNumberRef kzib
= CFNumberCreate(NULL
, kCFNumberSInt32Type
, &keysz32
);
525 CFDictionaryRef kgp
= CFDictionaryCreateForCFTypes(kCFAllocatorDefault
,
526 kSecAttrKeyType
, kSecAttrKeyTypeRSA
,
527 kSecAttrKeySizeInBits
, kzib
,
528 kSecAttrIsPermanent
, kCFBooleanFalse
,
530 SecKeyRef pubKey
= NULL
, privKey
= NULL
;
532 ok_status(status
= SecKeyGeneratePair(kgp
, &pubKey
, &privKey
),
533 "Generate %ld bit (%ld byte) RSA keypair (status = %d)",
534 keySizeInBits
, keySizeInBytes
, (int)status
);
537 CFMutableDictionaryRef kcwd
= CFDictionaryCreateMutableForCFTypesWith(kCFAllocatorDefault
,
538 kSecAttrKeyType
, kSecAttrKeyTypeRSA
,
539 kSecAttrKeySizeInBits
, kzib
,
540 kSecAttrIsPermanent
, kCFBooleanFalse
,
544 CFErrorRef error
= NULL
;
545 CFDataRef privExternalData
= NULL
, pubExternalData
= NULL
;
546 SecKeyRef dataKey
= NULL
;
549 privExternalData
= SecKeyCopyExternalRepresentation(privKey
, &error
);
550 ok(privExternalData
&& CFGetTypeID(privExternalData
) == CFDataGetTypeID(),
551 "priv key SecKeyCopyExternalRepresentation failed");
552 CFReleaseNull(error
);
555 skip("invalid priv key external data", 4, privExternalData
);
557 CFDictionarySetValue(kcwd
, kSecAttrKeyClass
, kSecAttrKeyClassPrivate
);
558 dataKey
= SecKeyCreateWithData(privExternalData
, kcwd
, &error
);
559 ok(dataKey
, "priv key SecKeyCreateWithData failed");
560 CFReleaseNull(error
);
562 eq_cf(privKey
, dataKey
, "priv keys differ");
563 CFReleaseNull(dataKey
);
565 CFDictionarySetValue(kcwd
, kSecAttrKeyClass
, kSecAttrKeyClassPublic
);
566 dataKey
= SecKeyCreateWithData(privExternalData
, kcwd
, &error
);
567 ok(!dataKey
, "priv key SecKeyCreateWithData succeeded with invalid kSecAttrKeyClass");
568 CFReleaseNull(error
);
569 CFReleaseNull(dataKey
);
571 CFMutableDataRef modifiedExternalData
= CFDataCreateMutable(kCFAllocatorDefault
, 0);
572 CFDataAppend(modifiedExternalData
, privExternalData
);
573 *CFDataGetMutableBytePtr(modifiedExternalData
) ^= 0xff;
575 CFDictionarySetValue(kcwd
, kSecAttrKeyClass
, kSecAttrKeyClassPrivate
);
576 dataKey
= SecKeyCreateWithData(modifiedExternalData
, kcwd
, &error
);
577 ok(!dataKey
, "priv key SecKeyCreateWithData succeeded with invalid external data");
578 CFReleaseNull(error
);
579 CFReleaseNull(dataKey
);
581 CFReleaseNull(modifiedExternalData
);
586 pubExternalData
= SecKeyCopyExternalRepresentation(pubKey
, &error
);
587 ok(pubExternalData
&& CFGetTypeID(pubExternalData
) == CFDataGetTypeID(),
588 "pub key SecKeyCopyExternalRepresentation failed");
589 CFReleaseNull(error
);
592 skip("invalid pub key external data", 4, pubExternalData
);
594 CFDictionarySetValue(kcwd
, kSecAttrKeyClass
, kSecAttrKeyClassPublic
);
595 dataKey
= SecKeyCreateWithData(pubExternalData
, kcwd
, &error
);
596 ok(dataKey
, "pub key SecKeyCreateWithData failed");
597 CFReleaseNull(error
);
599 eq_cf(pubKey
, dataKey
, "pub keys differ");
600 CFReleaseNull(dataKey
);
602 CFDictionarySetValue(kcwd
, kSecAttrKeyClass
, kSecAttrKeyClassPrivate
);
603 dataKey
= SecKeyCreateWithData(pubExternalData
, kcwd
, &error
);
604 ok(!dataKey
, "pub key SecKeyCreateWithData succeeded with invalid kSecAttrKeyClass");
605 CFReleaseNull(error
);
606 CFReleaseNull(dataKey
);
608 CFMutableDataRef modifiedExternalData
= CFDataCreateMutable(kCFAllocatorDefault
, 0);
609 CFDataAppend(modifiedExternalData
, pubExternalData
);
610 *CFDataGetMutableBytePtr(modifiedExternalData
) ^= 0xff;
612 CFDictionarySetValue(kcwd
, kSecAttrKeyClass
, kSecAttrKeyClassPublic
);
613 dataKey
= SecKeyCreateWithData(modifiedExternalData
, kcwd
, &error
);
614 ok(!dataKey
, "pub key SecKeyCreateWithData succeeded with invalid external data");
615 CFReleaseNull(error
);
616 CFReleaseNull(dataKey
);
618 CFReleaseNull(modifiedExternalData
);
623 skip("invalid pub key external data", 1, pubExternalData
);
625 CFDictionarySetValue(kcwd
, kSecAttrKeyClass
, kSecAttrKeyClassPrivate
);
626 dataKey
= SecKeyCreateWithData(pubExternalData
, kcwd
, &error
);
627 ok(!dataKey
, "priv key SecKeyCreateWithData succeeded with public external data");
628 CFReleaseNull(error
);
629 CFReleaseNull(dataKey
);
631 CFReleaseNull(pubExternalData
);
635 skip("invalid priv key external data", 1, privExternalData
);
637 CFDictionarySetValue(kcwd
, kSecAttrKeyClass
, kSecAttrKeyClassPublic
);
638 dataKey
= SecKeyCreateWithData(privExternalData
, kcwd
, &error
);
639 ok(!dataKey
, "pub key SecKeyCreateWithData succeeded with private external data");
640 CFReleaseNull(error
);
641 CFReleaseNull(dataKey
);
643 CFReleaseNull(privExternalData
);
647 CFReleaseNull(pubKey
);
648 CFReleaseNull(privKey
);
651 #define kCopyAttributesTestCount 20
652 static void testcopyattributes(unsigned long keySizeInBits
)
654 size_t keySizeInBytes
= (keySizeInBits
+ 7) / 8;
655 int32_t keysz32
= (int32_t)keySizeInBits
;
657 CFNumberRef kzib
= CFNumberCreate(NULL
, kCFNumberSInt32Type
, &keysz32
);
658 CFDictionaryRef kgp
= CFDictionaryCreateForCFTypes(kCFAllocatorDefault
,
659 kSecAttrKeyType
, kSecAttrKeyTypeRSA
,
660 kSecAttrKeySizeInBits
, kzib
,
661 kSecAttrIsPermanent
, kCFBooleanFalse
,
663 SecKeyRef pubKey
= NULL
, privKey
= NULL
;
665 ok_status(status
= SecKeyGeneratePair(kgp
, &pubKey
, &privKey
),
666 "Generate %ld bit (%ld byte) RSA keypair (status = %d)",
667 keySizeInBits
, keySizeInBytes
, (int)status
);
670 CFDictionaryRef attributes
;
671 CFTypeRef attrValue
= NULL
, privAppLabel
= NULL
, pubAppLabel
= NULL
;
674 attributes
= SecKeyCopyAttributes(privKey
);
675 ok(attributes
&& CFGetTypeID(attributes
) == CFDictionaryGetTypeID(),
676 "priv key SecKeyCopyAttributes failed");
679 skip("invalid attributes", 8, attributes
);
681 attrValue
= CFDictionaryGetValue(attributes
, kSecAttrCanEncrypt
);
682 eq_cf(attrValue
, kCFBooleanFalse
, "invalid priv key kSecAttrCanEncrypt");
684 attrValue
= CFDictionaryGetValue(attributes
, kSecAttrCanDecrypt
);
685 eq_cf(attrValue
, kCFBooleanTrue
, "invalid priv key kSecAttrCanDecrypt");
687 attrValue
= CFDictionaryGetValue(attributes
, kSecAttrCanDerive
);
688 eq_cf(attrValue
, kCFBooleanFalse
, "invalid priv key kSecAttrCanDerive");
690 attrValue
= CFDictionaryGetValue(attributes
, kSecAttrCanSign
);
691 eq_cf(attrValue
, kCFBooleanTrue
, "invalid priv key kSecAttrCanSign");
693 attrValue
= CFDictionaryGetValue(attributes
, kSecAttrCanVerify
);
694 eq_cf(attrValue
, kCFBooleanFalse
, "invalid priv key kSecAttrCanVerify");
696 attrValue
= CFDictionaryGetValue(attributes
, kSecAttrKeyClass
);
697 eq_cf(attrValue
, kSecAttrKeyClassPrivate
, "priv key invalid kSecAttrKeyClass");
699 attrValue
= CFDictionaryGetValue(attributes
, kSecAttrKeyType
);
700 eq_cf(attrValue
, kSecAttrKeyTypeRSA
, "invalid priv key kSecAttrKeyType");
702 attrValue
= CFDictionaryGetValue(attributes
, kSecAttrKeySizeInBits
);
703 eq_cf(attrValue
, kzib
, "invalid priv key kSecAttrKeySizeInBits");
705 privAppLabel
= CFDictionaryGetValue(attributes
, kSecAttrApplicationLabel
);
706 CFRetainSafe(privAppLabel
);
708 CFReleaseNull(attributes
);
713 attributes
= SecKeyCopyAttributes(pubKey
);
714 ok(attributes
&& CFGetTypeID(attributes
) == CFDictionaryGetTypeID(),
715 "pub key SecKeyCopyAttributes failed");
718 skip("invalid attributes", 8, attributes
);
720 attrValue
= CFDictionaryGetValue(attributes
, kSecAttrCanEncrypt
);
721 eq_cf(attrValue
, kCFBooleanTrue
, "pub key invalid kSecAttrCanEncrypt");
723 // Although unusual, our RSA public key can even decrypt.
724 attrValue
= CFDictionaryGetValue(attributes
, kSecAttrCanDecrypt
);
725 eq_cf(attrValue
, kCFBooleanTrue
, "pub key invalid kSecAttrCanDecrypt");
727 attrValue
= CFDictionaryGetValue(attributes
, kSecAttrCanDerive
);
728 eq_cf(attrValue
, kCFBooleanFalse
, "pub key invalid kSecAttrCanDerive");
730 attrValue
= CFDictionaryGetValue(attributes
, kSecAttrCanSign
);
731 eq_cf(attrValue
, kCFBooleanFalse
, "pub key invalid kSecAttrCanSign");
733 attrValue
= CFDictionaryGetValue(attributes
, kSecAttrCanVerify
);
734 eq_cf(attrValue
, kCFBooleanTrue
, "pub key invalid kSecAttrCanVerify");
736 attrValue
= CFDictionaryGetValue(attributes
, kSecAttrKeyClass
);
737 eq_cf(attrValue
, kSecAttrKeyClassPublic
, "pub key invalid kSecAttrKeyClass");
739 attrValue
= CFDictionaryGetValue(attributes
, kSecAttrKeyType
);
740 eq_cf(attrValue
, kSecAttrKeyTypeRSA
, "pub key invalid kSecAttrKeyType");
742 attrValue
= CFDictionaryGetValue(attributes
, kSecAttrKeySizeInBits
);
743 eq_cf(attrValue
, kzib
, "pub key invalid kSecAttrKeySizeInBits");
745 pubAppLabel
= CFDictionaryGetValue(attributes
, kSecAttrApplicationLabel
);
746 CFRetainSafe(pubAppLabel
);
748 CFReleaseNull(attributes
);
752 eq_cf(privAppLabel
, pubAppLabel
, "priv key and pub key kSecAttrApplicationLabel differ");
754 CFReleaseNull(privAppLabel
);
755 CFReleaseNull(pubAppLabel
);
757 CFReleaseNull(pubKey
);
758 CFReleaseNull(privKey
);
761 #define kCopyPublicKeyTestCount 5
762 static void testcopypublickey(unsigned long keySizeInBits
)
764 size_t keySizeInBytes
= (keySizeInBits
+ 7) / 8;
765 int32_t keysz32
= (int32_t)keySizeInBits
;
767 CFNumberRef kzib
= CFNumberCreate(NULL
, kCFNumberSInt32Type
, &keysz32
);
768 CFDictionaryRef kgp
= CFDictionaryCreateForCFTypes(kCFAllocatorDefault
,
769 kSecAttrKeyType
, kSecAttrKeyTypeRSA
,
770 kSecAttrKeySizeInBits
, kzib
,
771 kSecAttrIsPermanent
, kCFBooleanFalse
,
775 SecKeyRef pubKey
= NULL
, privKey
= NULL
;
777 ok_status(status
= SecKeyGeneratePair(kgp
, &pubKey
, &privKey
),
778 "Generate %ld bit (%ld byte) RSA keypair (status = %d)",
779 keySizeInBits
, keySizeInBytes
, (int)status
);
782 SecKeyRef pubKeyCopy
= NULL
;
785 pubKeyCopy
= SecKeyCopyPublicKey(privKey
);
786 ok(pubKeyCopy
, "priv key SecKeyCopyPublicKey failed");
787 eq_cf(pubKeyCopy
, pubKey
, "pub key from priv key SecKeyCopyPublicKey and pub key differ");
788 CFReleaseNull(pubKeyCopy
);
792 pubKeyCopy
= SecKeyCopyPublicKey(pubKey
);
793 ok(pubKeyCopy
, "pub key SecKeyCopyPublicKey failed");
794 eq_cf(pubKeyCopy
, pubKey
, "pub key from pub key SecKeyCopyPublicKey and pub key differ");
795 CFReleaseNull(pubKeyCopy
);
798 CFReleaseNull(pubKey
);
799 CFReleaseNull(privKey
);
802 #define kSignAndVerifyTestCount 84
803 static void testsignverify(unsigned long keySizeInBits
)
805 size_t keySizeInBytes
= (keySizeInBits
+ 7) / 8;
806 int32_t keysz32
= (int32_t)keySizeInBits
;
808 CFNumberRef kzib
= CFNumberCreate(NULL
, kCFNumberSInt32Type
, &keysz32
);
809 CFDictionaryRef kgp
= CFDictionaryCreateForCFTypes(kCFAllocatorDefault
,
810 kSecAttrKeyType
, kSecAttrKeyTypeRSA
,
811 kSecAttrKeySizeInBits
, kzib
,
812 kSecAttrIsPermanent
, kCFBooleanFalse
,
816 SecKeyRef pubKey
= NULL
, privKey
= NULL
;
818 ok_status(status
= SecKeyGeneratePair(kgp
, &pubKey
, &privKey
),
819 "Generate %ld bit (%ld byte) RSA keypair (status = %d)",
820 keySizeInBits
, keySizeInBytes
, (int)status
);
823 SecKeyAlgorithm algorithms
[] = {
824 kSecKeyAlgorithmRSASignatureRaw
,
825 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1
,
826 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA224
,
827 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256
,
828 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384
,
829 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512
,
830 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1
,
831 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA224
,
832 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256
,
833 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA384
,
834 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA512
,
837 CFDataRef testData
= CFStringCreateExternalRepresentation(kCFAllocatorDefault
, CFSTR("test"), kCFStringEncodingUTF8
, 0);
838 ok(testData
, "creating test data failed");
841 skip("invalid test data", 71, testData
);
843 CFErrorRef error
= NULL
;
845 for (uint32_t ix
= 0; ix
< array_size(algorithms
); ++ix
) {
846 SecKeyAlgorithm algorithm
= algorithms
[ix
];
847 SecKeyAlgorithm incompatibleAlgorithm
= (CFEqual(algorithm
, kSecKeyAlgorithmRSASignatureRaw
)) ?
848 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1
: kSecKeyAlgorithmRSASignatureRaw
;
850 CFDataRef dataToSign
= NULL
;
851 if (CFEqual(algorithm
, kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1
)) {
852 dataToSign
= CFDataCreateWithHash(kCFAllocatorDefault
, ccsha1_di(),
853 CFDataGetBytePtr(testData
), CFDataGetLength(testData
));
854 ok(dataToSign
, "creating digest failed for algorithm %@", algorithm
);
856 else if (CFEqual(algorithm
, kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA224
)) {
857 dataToSign
= CFDataCreateWithHash(kCFAllocatorDefault
, ccsha224_di(),
858 CFDataGetBytePtr(testData
), CFDataGetLength(testData
));
859 ok(dataToSign
, "creating digest failed for algorithm %@", algorithm
);
861 else if (CFEqual(algorithm
, kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256
)) {
862 dataToSign
= CFDataCreateWithHash(kCFAllocatorDefault
, ccsha256_di(),
863 CFDataGetBytePtr(testData
), CFDataGetLength(testData
));
864 ok(dataToSign
, "creating digest failed for algorithm %@", algorithm
);
866 else if (CFEqual(algorithm
, kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384
)) {
867 dataToSign
= CFDataCreateWithHash(kCFAllocatorDefault
, ccsha384_di(),
868 CFDataGetBytePtr(testData
), CFDataGetLength(testData
));
869 ok(dataToSign
, "creating digest failed for algorithm %@", algorithm
);
871 else if (CFEqual(algorithm
, kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512
)) {
872 dataToSign
= CFDataCreateWithHash(kCFAllocatorDefault
, ccsha512_di(),
873 CFDataGetBytePtr(testData
), CFDataGetLength(testData
));
874 ok(dataToSign
, "creating digest failed for algorithm %@", algorithm
);
877 CFRetainAssign(dataToSign
, testData
);
879 CFReleaseNull(error
);
882 skip("invalid data to sign", 7, dataToSign
);
884 CFDataRef signature
= SecKeyCreateSignature(pubKey
, algorithm
, dataToSign
, &error
);
885 ok(!signature
, "SecKeyCopySignature succeeded with pub key for algorithm %@", algorithm
);
886 CFReleaseNull(error
);
887 CFReleaseNull(signature
);
889 signature
= SecKeyCreateSignature(privKey
, algorithm
, dataToSign
, &error
);
890 ok(signature
, "SecKeyCopySignature failed for algorithm %@", algorithm
);
891 CFReleaseNull(error
);
894 skip("invalid signature", 4, signature
);
896 ok(!SecKeyVerifySignature(privKey
, algorithm
, dataToSign
, signature
, &error
),
897 "SecKeyVerifySignature succeeded with priv key for algorithm %@", algorithm
);
898 CFReleaseNull(error
);
900 ok(!SecKeyVerifySignature(pubKey
, incompatibleAlgorithm
, dataToSign
, signature
, &error
),
901 "SecKeyVerifySignature succeeded with wrong algorithm for algorithm %@", algorithm
);
902 CFReleaseNull(error
);
904 ok(SecKeyVerifySignature(pubKey
, algorithm
, dataToSign
, signature
, &error
),
905 "SecKeyVerifySignature failed for algorithm %@", algorithm
);
906 CFReleaseNull(error
);
908 CFMutableDataRef modifiedSignature
= CFDataCreateMutable(kCFAllocatorDefault
, 0);
909 CFDataAppend(modifiedSignature
, signature
);
910 *CFDataGetMutableBytePtr(modifiedSignature
) ^= 0xff;
912 ok(!SecKeyVerifySignature(pubKey
, algorithm
, dataToSign
, modifiedSignature
, &error
),
913 "SecKeyVerifySignature succeeded with bad signature for algorithm %@", algorithm
);
914 CFReleaseNull(error
);
916 CFMutableDataRef modifiedDataToSign
= CFDataCreateMutable(kCFAllocatorDefault
, 0);
917 CFDataAppend(modifiedDataToSign
, dataToSign
);
918 *CFDataGetMutableBytePtr(modifiedDataToSign
) ^= 0xff;
920 ok(!SecKeyVerifySignature(pubKey
, algorithm
, modifiedDataToSign
, signature
, &error
),
921 "SecKeyVerifySignature succeeded with bad data for algorithm %@", algorithm
);
922 CFReleaseNull(error
);
924 CFReleaseNull(modifiedDataToSign
);
925 CFReleaseNull(modifiedSignature
);
926 CFReleaseNull(signature
);
928 CFReleaseNull(dataToSign
);
931 CFReleaseNull(testData
);
934 CFReleaseNull(pubKey
);
935 CFReleaseNull(privKey
);
939 #define kSPKITestCount 4
940 static void testspki(CFStringRef keytype
, size_t keySizeInBits
)
942 SecKeyRef pubKey
= NULL
, privKey
= NULL
, pubKey2
= NULL
;
943 size_t keySizeInBytes
= (keySizeInBits
+ 7) / 8;
945 int32_t keysz32
= (int32_t)keySizeInBits
;
946 CFDataRef spki
= NULL
;
948 kzib
= CFNumberCreate(NULL
, kCFNumberSInt32Type
, &keysz32
);
949 CFMutableDictionaryRef kgp
= CFDictionaryCreateMutable(NULL
, 0, NULL
, NULL
);
950 CFDictionaryAddValue(kgp
, kSecAttrKeyType
, keytype
);
951 CFDictionaryAddValue(kgp
, kSecAttrKeySizeInBits
, kzib
);
954 ok_status(status
= SecKeyGeneratePair(kgp
, &pubKey
, &privKey
),
955 "Generate %ld bit (%ld byte) keypair", keySizeInBits
, keySizeInBytes
);
959 spki
= SecKeyCopySubjectPublicKeyInfo(pubKey
);
960 ok(spki
, "failed to create SPKI");
962 pubKey2
= SecKeyCreateFromSubjectPublicKeyInfoData(NULL
, spki
);
963 ok(pubKey2
, "failed to create key from SPKI");
965 eq_cf(pubKey
, pubKey2
, "public not same after going though SPKI");
967 CFReleaseNull(pubKey
);
968 CFReleaseNull(pubKey2
);
969 CFReleaseNull(privKey
);
974 /* Test basic add delete update copy matching stuff. */
975 #define kTestCount ((3 * kKeyGenTestCount) + kKeyGen2TestCount + kTestSupportedCount + kCreateWithDataTestCount \
976 + kCopyAttributesTestCount + kCopyPublicKeyTestCount + kSignAndVerifyTestCount + ((3 + 3) * kSPKITestCount))
977 static void tests(void)
979 /* Comment out lines below for testing generating all common key sizes,
980 disabled now for speed reasons. */
984 testkeygen(2056); // Stranged sized for edge cases in padding.
990 testsupportedalgos(768);
991 testcreatewithdata(768);
992 testcopyattributes(768);
993 testcopypublickey(768);
996 testspki(kSecAttrKeyTypeRSA
, 1024);
997 testspki(kSecAttrKeyTypeRSA
, 2048);
998 testspki(kSecAttrKeyTypeRSA
, 4096);
1000 testspki(kSecAttrKeyTypeEC
, 256);
1001 testspki(kSecAttrKeyTypeEC
, 384);
1002 testspki(kSecAttrKeyTypeEC
, 521);
1005 int si_40_seckey(int argc
, char *const *argv
)
1007 plan_tests(kTestCount
);