]> git.saurik.com Git - apple/security.git/blob - OSX/sec/Security/Regressions/secitem/si-62-csr.m
Security-59754.80.3.tar.gz
[apple/security.git] / OSX / sec / Security / Regressions / secitem / si-62-csr.m
1 /*
2 * Copyright (c) 2008-2017 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 #import <AssertMacros.h>
25 #import <Foundation/Foundation.h>
26
27 #include <Security/SecKey.h>
28 #include <Security/SecItem.h>
29 #include <Security/SecItemPriv.h>
30 #include <Security/SecCMS.h>
31 #include <Security/SecCertificateRequest.h>
32 #include <Security/SecSCEP.h>
33 #include <Security/SecCertificatePriv.h>
34 #include <Security/SecIdentityPriv.h>
35 #include <utilities/array_size.h>
36
37 #include <Security/SecInternal.h>
38 #include <CoreFoundation/CoreFoundation.h>
39 #include <stdlib.h>
40 #include <unistd.h>
41
42 #include "shared_regressions.h"
43
44 #include <fcntl.h>
45 __unused static inline void write_data(const char * path, CFDataRef data)
46 {
47 int data_file = open(path, O_CREAT|O_WRONLY|O_TRUNC, 0644);
48 write(data_file, CFDataGetBytePtr(data), CFDataGetLength(data));
49 close(data_file);
50 }
51
52
53 static void tests(void)
54 {
55 SecKeyRef phone_publicKey = NULL, phone_privateKey = NULL;
56 SecKeyRef ca_publicKey = NULL, ca_privateKey = NULL;
57
58 int keysize = 2048;
59 CFNumberRef key_size_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &keysize);
60 const void *keygen_keys[] = { kSecAttrKeyType, kSecAttrKeySizeInBits };
61 const void *keygen_vals[] = { kSecAttrKeyTypeRSA, key_size_num };
62 CFDictionaryRef parameters = CFDictionaryCreate(kCFAllocatorDefault,
63 keygen_keys, keygen_vals, array_size(keygen_vals),
64 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks );
65 CFReleaseNull(key_size_num);
66
67 CFMutableDictionaryRef subject_alt_names = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
68 CFDictionarySetValue(subject_alt_names, kSecSubjectAltNameDNSName, CFSTR("xey.nl"));
69
70 int key_usage = kSecKeyUsageDigitalSignature | kSecKeyUsageKeyEncipherment;
71 CFNumberRef key_usage_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &key_usage);
72
73 CFMutableDictionaryRef random_extensions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
74
75 const void *key[] = { kSecCSRChallengePassword, kSecSubjectAltName, kSecCertificateKeyUsage, kSecCertificateExtensions };
76 const void *val[] = { CFSTR("magic"), subject_alt_names, key_usage_num, random_extensions };
77 CFDictionaryRef csr_parameters = CFDictionaryCreate(kCFAllocatorDefault,
78 key, val, array_size(key), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
79
80 SecATV cn_phone[] = { { kSecOidCommonName, SecASN1PrintableString, CFSTR("My iPhone") }, {} };
81 SecATV c[] = { { kSecOidCountryName, SecASN1PrintableString, CFSTR("US") }, {} };
82 SecATV st[] = { { kSecOidStateProvinceName, SecASN1PrintableString, CFSTR("CA") }, {} };
83 SecATV l[] = { { kSecOidLocalityName, SecASN1PrintableString, CFSTR("Cupertino") }, {} };
84 SecATV o[] = { { CFSTR("2.5.4.10"), SecASN1PrintableString, CFSTR("Apple Inc.") }, {} };
85 SecATV ou[] = { { kSecOidOrganizationalUnit, SecASN1PrintableString, CFSTR("iPhone") }, {} };
86
87 SecRDN atvs_phone[] = { cn_phone, c, st, l, o, ou, NULL };
88
89 ok_status(SecKeyGeneratePair(parameters, &phone_publicKey, &phone_privateKey), "generate key pair");
90 ok_status(SecKeyGeneratePair(parameters, &ca_publicKey, &ca_privateKey), "generate key pair");
91
92 int self_key_usage = kSecKeyUsageKeyCertSign | kSecKeyUsageCRLSign;
93 CFNumberRef self_key_usage_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &self_key_usage);
94 int path_len = 0;
95 CFNumberRef path_len_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &path_len);
96 const void *self_key[] = { kSecCertificateKeyUsage, kSecCSRBasicContraintsPathLen };
97 const void *self_val[] = { self_key_usage_num, path_len_num };
98 CFDictionaryRef self_signed_parameters = CFDictionaryCreate(kCFAllocatorDefault,
99 self_key, self_val, array_size(self_key), NULL, NULL);
100
101 const void * ca_o[] = { kSecOidOrganization, CFSTR("Apple Inc.") };
102 const void * ca_cn[] = { kSecOidCommonName, CFSTR("Root CA") };
103 CFArrayRef ca_o_dn = CFArrayCreate(kCFAllocatorDefault, ca_o, 2, NULL);
104 CFArrayRef ca_cn_dn = CFArrayCreate(kCFAllocatorDefault, ca_cn, 2, NULL);
105 const void *ca_dn_array[2];
106 ca_dn_array[0] = CFArrayCreate(kCFAllocatorDefault, (const void **)&ca_o_dn, 1, NULL);
107 ca_dn_array[1] = CFArrayCreate(kCFAllocatorDefault, (const void **)&ca_cn_dn, 1, NULL);
108 CFArrayRef ca_rdns = CFArrayCreate(kCFAllocatorDefault, ca_dn_array, 2, NULL);
109
110 SecCertificateRef ca_cert = SecGenerateSelfSignedCertificate(ca_rdns,
111 self_signed_parameters, ca_publicKey, ca_privateKey);
112 SecCertificateRef ca_cert_phone_key =
113 SecGenerateSelfSignedCertificate(ca_rdns, self_signed_parameters, phone_publicKey, phone_privateKey);
114
115 CFReleaseSafe(self_signed_parameters);
116 CFReleaseSafe(self_key_usage_num);
117 CFReleaseSafe(path_len_num);
118 CFReleaseNull(ca_o_dn);
119 CFReleaseNull(ca_cn_dn);
120 CFReleaseNull(ca_dn_array[0]);
121 CFReleaseNull(ca_dn_array[1]);
122 CFReleaseNull(ca_rdns);
123
124 isnt(ca_cert, NULL, "got back a cert");
125 ok(SecCertificateIsSelfSignedCA(ca_cert), "cert is self-signed ca cert");
126 isnt(ca_cert_phone_key, NULL, "got back a cert");
127 ok(SecCertificateIsSelfSignedCA(ca_cert_phone_key), "cert is self-signed ca cert");
128 CFDataRef data = SecCertificateCopyData(ca_cert);
129 //write_data("/tmp/ca_cert.der", data);
130 CFReleaseSafe(data);
131
132 SecIdentityRef ca_identity = SecIdentityCreate(kCFAllocatorDefault, ca_cert, ca_privateKey);
133 SecIdentityRef ca_identity_phone_key = SecIdentityCreate(kCFAllocatorDefault, ca_cert_phone_key, phone_privateKey);
134 isnt(ca_identity, NULL, "got a identity");
135 isnt(ca_identity_phone_key, NULL, "got a identity");
136 CFDictionaryRef dict = CFDictionaryCreate(NULL, (const void **)&kSecValueRef, (const void **)&ca_identity, 1, NULL, NULL);
137 ok_status(SecItemAdd(dict, NULL), "add ca identity");
138 CFReleaseSafe(dict);
139 #if TARGET_OS_IPHONE
140 TODO: {
141 todo("Adding a cert with the same issuer/serial but a different key should return something other than errSecDuplicateItem");
142 #else
143 {
144 #endif
145 dict = CFDictionaryCreate(NULL, (const void **)&kSecValueRef, (const void **)&ca_identity_phone_key, 1, NULL, NULL);
146 is_status(errSecDuplicateItem, SecItemAdd(dict, NULL), "add ca identity");
147 CFReleaseSafe(dict);
148 }
149
150 CFDataRef csr = SecGenerateCertificateRequestWithParameters(atvs_phone, NULL, phone_publicKey, phone_privateKey);
151 isnt(csr, NULL, "got back a csr");
152 CFReleaseNull(csr);
153
154 //dict[kSecSubjectAltName, dict[ntPrincipalName, "foo@bar.org"]]
155 CFStringRef nt_princ_name_val = CFSTR("foo@bar.org");
156 CFDictionaryRef nt_princ = CFDictionaryCreate(NULL, (const void **)&kSecSubjectAltNameNTPrincipalName, (const void **)&nt_princ_name_val, 1, NULL, NULL);
157 CFDictionaryRef params = CFDictionaryCreate(NULL, (const void **)&kSecSubjectAltName, (const void **)&nt_princ, 1, NULL, NULL);
158
159 csr = SecGenerateCertificateRequestWithParameters(atvs_phone, params, phone_publicKey, phone_privateKey);
160 isnt(csr, NULL, "got back a csr");
161 //write_data("/var/tmp/csr-nt-princ", csr);
162 CFReleaseNull(csr);
163 CFReleaseNull(params);
164 CFReleaseNull(nt_princ);
165
166 csr = SecGenerateCertificateRequestWithParameters(atvs_phone, csr_parameters, phone_publicKey, phone_privateKey);
167 isnt(csr, NULL, "csr w/ params");
168 //write_data("/tmp/csr", csr);
169 CFDataRef subject, extensions;
170 CFStringRef challenge;
171 ok(SecVerifyCertificateRequest(csr, NULL, &challenge, &subject, &extensions), "verify csr");
172 CFReleaseNull(csr);
173
174 uint8_t serialno_byte = 42;
175 CFDataRef serialno = CFDataCreate(kCFAllocatorDefault, &serialno_byte, sizeof(serialno_byte));
176 SecCertificateRef cert = SecIdentitySignCertificate(ca_identity, serialno,
177 phone_publicKey, subject, extensions);
178 data = SecCertificateCopyData(cert);
179 //write_data("/tmp/iphone_cert.der", data);
180 CFReleaseNull(data);
181 CFReleaseNull(subject);
182 CFReleaseNull(extensions);
183 CFReleaseNull(challenge);
184
185 const void * email[] = { CFSTR("1.2.840.113549.1.9.1"), CFSTR("foo@bar.biz") };
186 const void * cn[] = { CFSTR("2.5.4.3"), CFSTR("S/MIME Baby") };
187 CFArrayRef email_dn = CFArrayCreate(kCFAllocatorDefault, email, 2, NULL);
188 CFArrayRef cn_dn = CFArrayCreate(kCFAllocatorDefault, cn, 2, NULL);
189 const void *dn_array[2];
190 dn_array[0] = CFArrayCreate(kCFAllocatorDefault, (const void **)&email_dn, 1, NULL);
191 dn_array[1] = CFArrayCreate(kCFAllocatorDefault, (const void **)&cn_dn, 1, NULL);
192 CFArrayRef rdns = CFArrayCreate(kCFAllocatorDefault, dn_array, 2, NULL);
193 CFDictionarySetValue(subject_alt_names, CFSTR("rfc822name"), CFSTR("mongo@pawn.org"));
194
195 uint8_t random_extension_data[] = { 0xde, 0xad, 0xbe, 0xef };
196 CFDataRef random_extension_value = CFDataCreate(kCFAllocatorDefault, random_extension_data, sizeof(random_extension_data));
197 CFDictionarySetValue(random_extensions, CFSTR("1.2.840.113635.100.6.1.2"), random_extension_value); // APPLE_FDR_ACCESS_OID
198 CFDictionarySetValue(random_extensions, CFSTR("1.2.840.113635.100.6.1.3"), CFSTR("that guy")); // APPLE_FDR_CLIENT_IDENTIFIER_OID
199 CFReleaseNull(random_extension_value);
200
201 csr = SecGenerateCertificateRequest(rdns, csr_parameters, phone_publicKey, phone_privateKey);
202 isnt(csr, NULL, "csr w/ params");
203 //write_data("/tmp/csr_neu", csr);
204 CFReleaseNull(csr);
205 CFReleaseNull(subject_alt_names);
206 CFDictionaryRemoveAllValues(random_extensions);
207
208 #if TARGET_OS_IPHONE
209 CFDataRef scep_request = SecSCEPGenerateCertificateRequest(rdns,
210 csr_parameters, phone_publicKey, phone_privateKey, NULL, ca_cert);
211 isnt(scep_request, NULL, "got scep blob");
212 //write_data("/tmp/scep_request.der", scep_request);
213 #endif
214
215 CFReleaseNull(email_dn);
216 CFReleaseNull(cn_dn);
217 CFReleaseNull(dn_array[0]);
218 CFReleaseNull(dn_array[1]);
219 CFReleaseNull(rdns);
220
221 #if TARGET_OS_IPHONE
222 CFDataRef scep_reply = SecSCEPCertifyRequest(scep_request, ca_identity, serialno, false);
223 isnt(scep_reply, NULL, "produced scep reply");
224 //write_data("/tmp/scep_reply.der", scep_reply);
225
226 CFArrayRef issued_certs = NULL;
227 ok(issued_certs = SecSCEPVerifyReply(scep_request, scep_reply, ca_cert, NULL), "verify scep reply");
228
229 // take the issued cert and CA cert and pretend it's a RA/CA couple
230 CFMutableArrayRef scep_certs = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, issued_certs);
231 CFArrayAppendValue(scep_certs, ca_cert);
232 SecCertificateRef ca_certificate = NULL, ra_signing_certificate = NULL, ra_encryption_certificate = NULL;
233
234 ok_status(SecSCEPValidateCACertMessage(scep_certs, NULL,
235 &ca_certificate, &ra_signing_certificate,
236 &ra_encryption_certificate), "pull apart array again");
237 ok(CFEqual(ca_cert, ca_certificate), "found ca");
238 ok(CFArrayContainsValue(issued_certs, CFRangeMake(0, CFArrayGetCount(issued_certs)), ra_signing_certificate), "found ra");
239 ok(!ra_encryption_certificate, "no separate encryption cert");
240
241 CFReleaseSafe(ca_certificate);
242 CFReleaseSafe(ra_signing_certificate);
243 CFReleaseSafe(scep_certs);
244
245 CFReleaseSafe(scep_request);
246 CFReleaseSafe(scep_reply);
247 CFReleaseSafe(issued_certs);
248 #endif
249
250 // cleanups
251 dict = CFDictionaryCreate(NULL, (const void **)&kSecValueRef, (const void **)&ca_identity, 1, NULL, NULL);
252 ok_status(SecItemDelete(dict), "delete ca identity");
253 CFReleaseSafe(dict);
254 dict = CFDictionaryCreate(NULL, (const void **)&kSecValueRef, (const void **)&phone_privateKey, 1, NULL, NULL);
255 ok_status(SecItemDelete(dict), "delete phone private key");
256 CFReleaseSafe(dict);
257
258 CFReleaseSafe(serialno);
259
260 CFReleaseSafe(cert);
261 CFReleaseSafe(ca_identity);
262 CFReleaseSafe(ca_cert);
263 CFReleaseSafe(ca_identity_phone_key);
264 CFReleaseSafe(ca_cert_phone_key);
265 CFReleaseSafe(csr_parameters);
266 CFReleaseSafe(random_extensions);
267 CFReleaseSafe(parameters);
268 CFReleaseSafe(ca_publicKey);
269 CFReleaseSafe(ca_privateKey);
270 CFReleaseSafe(phone_publicKey);
271 CFReleaseSafe(phone_privateKey);
272 }
273
274 static void test_ec_csr(void) {
275 SecKeyRef ecPublicKey = NULL, ecPrivateKey = NULL;
276
277 int keysize = 256;
278 CFNumberRef key_size_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &keysize);
279
280 const void *keyParamsKeys[] = { kSecAttrKeyType, kSecAttrKeySizeInBits };
281 const void *keyParamsValues[] = { kSecAttrKeyTypeECSECPrimeRandom, key_size_num};
282 CFDictionaryRef keyParameters = CFDictionaryCreate(NULL, keyParamsKeys, keyParamsValues, 2,
283 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
284 ok_status(SecKeyGeneratePair(keyParameters, &ecPublicKey, &ecPrivateKey),
285 "unable to generate EC key");
286
287 SecATV cn_phone[] = { { kSecOidCommonName, SecASN1PrintableString, CFSTR("My iPhone") }, {} };
288 SecATV c[] = { { kSecOidCountryName, SecASN1PrintableString, CFSTR("US") }, {} };
289 SecATV st[] = { { kSecOidStateProvinceName, SecASN1PrintableString, CFSTR("CA") }, {} };
290 SecATV l[] = { { kSecOidLocalityName, SecASN1PrintableString, CFSTR("Cupertino") }, {} };
291 SecATV o[] = { { CFSTR("2.5.4.10"), SecASN1PrintableString, CFSTR("Apple Inc.") }, {} };
292 SecATV ou[] = { { kSecOidOrganizationalUnit, SecASN1PrintableString, CFSTR("iPhone") }, {} };
293
294 SecRDN atvs_phone[] = { cn_phone, c, st, l, o, ou, NULL };
295
296 CFMutableDictionaryRef subject_alt_names = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
297 CFDictionarySetValue(subject_alt_names, kSecSubjectAltNameDNSName, CFSTR("xey.nl"));
298
299 int key_usage = kSecKeyUsageDigitalSignature | kSecKeyUsageKeyEncipherment;
300 CFNumberRef key_usage_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &key_usage);
301
302 CFMutableDictionaryRef random_extensions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
303
304 const void *key[] = { kSecCSRChallengePassword, kSecSubjectAltName, kSecCertificateKeyUsage, kSecCertificateExtensions };
305 const void *val[] = { CFSTR("magic"), subject_alt_names, key_usage_num, random_extensions };
306 CFDictionaryRef csr_parameters = CFDictionaryCreate(kCFAllocatorDefault,
307 key, val, array_size(key), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
308
309
310 CFDataRef csr = SecGenerateCertificateRequestWithParameters(atvs_phone, csr_parameters, ecPublicKey, ecPrivateKey);
311 isnt(csr, NULL, "csr w/ params");
312 //write_data("/tmp/csr", csr);
313 CFDataRef subject, extensions;
314 CFStringRef challenge;
315 ok(SecVerifyCertificateRequest(csr, NULL, &challenge, &subject, &extensions), "verify csr");
316
317 CFReleaseNull(csr);
318 CFReleaseNull(key_size_num);
319 CFReleaseNull(keyParameters);
320 CFReleaseNull(ecPublicKey);
321 CFReleaseNull(ecPrivateKey);
322 CFReleaseNull(subject_alt_names);
323 CFReleaseNull(key_usage_num);
324 CFReleaseNull(random_extensions);
325 CFReleaseNull(csr_parameters);
326 CFReleaseNull(subject);
327 CFReleaseNull(extensions);
328 CFReleaseNull(challenge);
329 }
330
331 static bool test_csr_create_sign_verify(SecKeyRef ca_priv, SecKeyRef leaf_priv,
332 CFStringRef cert_hashing_alg, CFStringRef csr_hashing_alg) {
333 bool status = false;
334 SecCertificateRef ca_cert = NULL, leaf_cert1 = NULL, leaf_cert2 = NULL;
335 SecIdentityRef ca_identity = NULL;
336 NSArray *leaf_rdns = nil, *anchors = nil;
337 NSDictionary *leaf_parameters = nil;
338 NSData *csr = nil, *serial_no = nil;
339 SecKeyRef csr_pub_key = NULL;
340 CFDataRef csr_subject = NULL, csr_extensions = NULL;
341 SecPolicyRef policy = NULL;
342 SecTrustRef trust = NULL;
343 SecTrustResultType trustResult = kSecTrustResultInvalid;
344
345 /* Generate a self-signed cert */
346 NSString *common_name = [NSString stringWithFormat:@"CSR Test Root: %@", cert_hashing_alg];
347 NSArray *ca_rdns = @[
348 @[@[(__bridge NSString*)kSecOidCountryName, @"US"]],
349 @[@[(__bridge NSString*)kSecOidOrganization, @"Apple Inc."]],
350 @[@[(__bridge NSString*)kSecOidCommonName, common_name]]
351 ];
352 NSDictionary *ca_parameters = @{
353 (__bridge NSString *)kSecCMSSignHashAlgorithm: (__bridge NSString*)cert_hashing_alg,
354 (__bridge NSString *)kSecCSRBasicContraintsPathLen: @0,
355 (__bridge NSString *)kSecCertificateKeyUsage: @(kSecKeyUsageKeyCertSign | kSecKeyUsageCRLSign)
356 };
357 ca_cert = SecGenerateSelfSignedCertificate((__bridge CFArrayRef)ca_rdns,
358 (__bridge CFDictionaryRef)ca_parameters,
359 NULL, ca_priv);
360 require(ca_cert, out);
361 ca_identity = SecIdentityCreate(NULL, ca_cert, ca_priv);
362 require(ca_identity, out);
363
364 /* Generate a CSR */
365 leaf_rdns = @[
366 @[@[(__bridge NSString*)kSecOidCountryName, @"US"]],
367 @[@[(__bridge NSString*)kSecOidOrganization, @"Apple Inc"]],
368 @[@[(__bridge NSString*)kSecOidCommonName, @"Leaf 1"]]
369 ];
370 leaf_parameters = @{
371 (__bridge NSString*)kSecCMSSignHashAlgorithm: (__bridge NSString*)csr_hashing_alg,
372 (__bridge NSString*)kSecSubjectAltName: @{
373 (__bridge NSString*)kSecSubjectAltNameDNSName : @[ @"valid.apple.com",
374 @"valid-qa.apple.com",
375 @"valid-uat.apple.com"]
376 },
377 (__bridge NSString*)kSecCertificateKeyUsage : @(kSecKeyUsageDigitalSignature)
378 };
379 csr = CFBridgingRelease(SecGenerateCertificateRequest((__bridge CFArrayRef)leaf_rdns,
380 (__bridge CFDictionaryRef)leaf_parameters,
381 NULL, leaf_priv));
382 require(csr, out);
383
384 /* Verify that CSR */
385 require(SecVerifyCertificateRequest((__bridge CFDataRef)csr, &csr_pub_key, NULL, &csr_subject, &csr_extensions), out);
386 require(csr_pub_key && csr_extensions && csr_subject, out);
387
388 /* Sign that CSR */
389 uint8_t serial_no_bytes[] = { 0xbb, 0x01 };
390 serial_no = [NSData dataWithBytes:serial_no_bytes length:sizeof(serial_no_bytes)];
391 leaf_cert1 = SecIdentitySignCertificateWithAlgorithm(ca_identity, (__bridge CFDataRef)serial_no,
392 csr_pub_key, csr_subject, csr_extensions, cert_hashing_alg);
393 require(leaf_cert1, out);
394
395 CFReleaseNull(csr_pub_key);
396 CFReleaseNull(csr_subject);
397 CFReleaseNull(csr_extensions);
398
399 /* Generate a CSR "with parameters" SPI */
400 SecATV c[] = { { kSecOidCountryName, SecASN1PrintableString, CFSTR("US") }, {} };
401 SecATV o[] = { { kSecOidOrganization, SecASN1PrintableString, CFSTR("Apple Inc.") }, {} };
402 SecATV cn[] = { { kSecOidCommonName, SecASN1PrintableString, CFSTR("Leaf 2") }, {} };
403
404 SecRDN atvs_leaf2[] = { c, o, cn, NULL };
405 csr = CFBridgingRelease(SecGenerateCertificateRequestWithParameters(atvs_leaf2, (__bridge CFDictionaryRef)leaf_parameters, NULL, leaf_priv));
406 require(csr, out);
407
408 /* Verify that CSR */
409 require(SecVerifyCertificateRequest((__bridge CFDataRef)csr, &csr_pub_key, NULL, &csr_subject, &csr_extensions), out);
410 require(csr_pub_key && csr_extensions && csr_subject, out);
411
412 /* Sign that CSR */
413 uint8_t serial_no_bytes2[] = { 0xbb, 0x02 };
414 serial_no = [NSData dataWithBytes:serial_no_bytes2 length:sizeof(serial_no_bytes2)];
415 leaf_cert2 = SecIdentitySignCertificateWithAlgorithm(ca_identity, (__bridge CFDataRef)serial_no,
416 csr_pub_key, csr_subject, csr_extensions, cert_hashing_alg);
417 require(leaf_cert2, out);
418
419 /* Verify the signed leaf certs chain to the root */
420 require(policy = SecPolicyCreateBasicX509(), out);
421 require_noerr(SecTrustCreateWithCertificates(leaf_cert1, policy, &trust), out);
422 anchors = @[ (__bridge id)ca_cert ];
423 require_noerr(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)anchors), out);
424 require_noerr(SecTrustEvaluate(trust, &trustResult), out);
425 require(trustResult == kSecTrustResultUnspecified || trustResult == kSecTrustResultProceed, out);
426 CFReleaseNull(trust);
427
428 require_noerr(SecTrustCreateWithCertificates(leaf_cert2, policy, &trust), out);
429 require_noerr(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)anchors), out);
430 require_noerr(SecTrustEvaluate(trust, &trustResult), out);
431 require(trustResult == kSecTrustResultUnspecified || trustResult == kSecTrustResultProceed, out);
432 CFReleaseNull(trust);
433
434 status = true;
435 out:
436 CFReleaseNull(ca_cert);
437 CFReleaseNull(ca_identity);
438 CFReleaseNull(leaf_cert1);
439 CFReleaseNull(leaf_cert2);
440 CFReleaseNull(csr_pub_key);
441 CFReleaseNull(csr_subject);
442 CFReleaseNull(csr_extensions);
443 CFReleaseNull(policy);
444 CFReleaseNull(trust);
445 return status;
446 }
447
448 static void test_algs(void) {
449 SecKeyRef ca_rsa_key = NULL, ca_ec_key = NULL;
450 SecKeyRef leaf_rsa_key = NULL, leaf_ec_key = NULL;
451 SecKeyRef publicKey = NULL;
452 NSDictionary *rsa_parameters = nil, *ec_parameters = nil;
453
454 rsa_parameters = @{
455 (__bridge NSString*)kSecAttrKeyType: (__bridge NSString*)kSecAttrKeyTypeRSA,
456 (__bridge NSString*)kSecAttrKeySizeInBits : @2048,
457 };
458 ok_status(SecKeyGeneratePair((__bridge CFDictionaryRef)rsa_parameters, &publicKey, &ca_rsa_key),
459 "Failed to generate CA RSA key");
460 CFReleaseNull(publicKey);
461 ok_status(SecKeyGeneratePair((__bridge CFDictionaryRef)rsa_parameters, &publicKey, &leaf_rsa_key),
462 "Failed to generate leaf RSA key");
463 CFReleaseNull(publicKey);
464
465 ec_parameters = @{
466 (__bridge NSString*)kSecAttrKeyType: (__bridge NSString*)kSecAttrKeyTypeECSECPrimeRandom,
467 (__bridge NSString*)kSecAttrKeySizeInBits : @384,
468 };
469 ok_status(SecKeyGeneratePair((__bridge CFDictionaryRef)ec_parameters, &publicKey, &ca_ec_key),
470 "Failed to generate CA EC key");
471 CFReleaseNull(publicKey);
472 ok_status(SecKeyGeneratePair((__bridge CFDictionaryRef)ec_parameters, &publicKey, &leaf_ec_key),
473 "Failed to generate leaf EC key");
474 CFReleaseNull(publicKey);
475
476 /* Single algorithm tests */
477 ok(test_csr_create_sign_verify(ca_rsa_key, leaf_rsa_key, kSecCMSHashingAlgorithmSHA1, kSecCMSHashingAlgorithmSHA1),
478 "Failed to run csr test with RSA SHA-1");
479 ok(test_csr_create_sign_verify(ca_rsa_key, leaf_rsa_key, kSecCMSHashingAlgorithmSHA256, kSecCMSHashingAlgorithmSHA256),
480 "Failed to run csr test with RSA SHA-256");
481 ok(test_csr_create_sign_verify(ca_rsa_key, leaf_rsa_key, kSecCMSHashingAlgorithmSHA384, kSecCMSHashingAlgorithmSHA384),
482 "Failed to run csr test with RSA SHA-384");
483 ok(test_csr_create_sign_verify(ca_rsa_key, leaf_rsa_key, kSecCMSHashingAlgorithmSHA512, kSecCMSHashingAlgorithmSHA512),
484 "Failed to run csr test with RSA SHA-512");
485 ok(test_csr_create_sign_verify(ca_ec_key, leaf_ec_key, kSecCMSHashingAlgorithmSHA256, kSecCMSHashingAlgorithmSHA256),
486 "Failed to run csr test with EC SHA-256");
487 ok(test_csr_create_sign_verify(ca_ec_key, leaf_ec_key, kSecCMSHashingAlgorithmSHA384, kSecCMSHashingAlgorithmSHA384),
488 "Failed to run csr test with EC SHA-384");
489 ok(test_csr_create_sign_verify(ca_ec_key, leaf_ec_key, kSecCMSHashingAlgorithmSHA512, kSecCMSHashingAlgorithmSHA512),
490 "Failed to run csr test with EC SHA-512");
491
492 /* Mix and match */
493 ok(test_csr_create_sign_verify(ca_rsa_key, leaf_ec_key, kSecCMSHashingAlgorithmSHA256, kSecCMSHashingAlgorithmSHA384),
494 "Failed to run csr test with RSA CA, EC leaf, SHA256 certs, SHA384 csrs");
495 ok(test_csr_create_sign_verify(ca_rsa_key, leaf_rsa_key, kSecCMSHashingAlgorithmSHA256, kSecCMSHashingAlgorithmSHA1),
496 "Failed to run csr test with RSA keys, SHA256 certs, SHA1 csrs");
497 ok(test_csr_create_sign_verify(ca_ec_key, leaf_ec_key, kSecCMSHashingAlgorithmSHA384, kSecCMSHashingAlgorithmSHA256),
498 "Failed to run csr test with EC keys, SHA384 certs, SHA256 csrs");
499
500 CFReleaseNull(ca_rsa_key);
501 CFReleaseNull(ca_ec_key);
502 CFReleaseNull(leaf_rsa_key);
503 CFReleaseNull(leaf_ec_key);
504 }
505
506 int si_62_csr(int argc, char *const *argv)
507 {
508 #if TARGET_OS_IPHONE
509 plan_tests(41);
510 #else
511 plan_tests(34);
512 #endif
513
514 tests();
515 test_ec_csr();
516 test_algs();
517
518 return 0;
519 }