]> git.saurik.com Git - apple/security.git/blob - OSX/sec/Security/Regressions/secitem/si-62-csr.c
Security-58286.31.2.tar.gz
[apple/security.git] / OSX / sec / Security / Regressions / secitem / si-62-csr.c
1 /*
2 * Copyright (c) 2008-2010,2012-2014 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24
25 #include <Security/SecKey.h>
26 #include <Security/SecItem.h>
27 #include <Security/SecItemPriv.h>
28 #include <Security/SecCMS.h>
29 #include <Security/SecCertificateRequest.h>
30 #include <Security/SecSCEP.h>
31 #include <Security/SecCertificatePriv.h>
32 #include <Security/SecIdentityPriv.h>
33 #include <utilities/array_size.h>
34
35 #include <Security/SecInternal.h>
36 #include <CoreFoundation/CoreFoundation.h>
37 #include <stdlib.h>
38 #include <unistd.h>
39
40 #include "shared_regressions.h"
41
42 #include <fcntl.h>
43 __unused static inline void write_data(const char * path, CFDataRef data)
44 {
45 int data_file = open(path, O_CREAT|O_WRONLY|O_TRUNC, 0644);
46 write(data_file, CFDataGetBytePtr(data), CFDataGetLength(data));
47 close(data_file);
48 }
49
50
51 static void tests(void)
52 {
53 SecKeyRef phone_publicKey = NULL, phone_privateKey = NULL;
54 SecKeyRef ca_publicKey = NULL, ca_privateKey = NULL;
55
56 int keysize = 2048;
57 CFNumberRef key_size_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &keysize);
58 const void *keygen_keys[] = { kSecAttrKeyType, kSecAttrKeySizeInBits };
59 const void *keygen_vals[] = { kSecAttrKeyTypeRSA, key_size_num };
60 CFDictionaryRef parameters = CFDictionaryCreate(kCFAllocatorDefault,
61 keygen_keys, keygen_vals, array_size(keygen_vals),
62 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks );
63 CFReleaseNull(key_size_num);
64
65 CFMutableDictionaryRef subject_alt_names = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
66 CFDictionarySetValue(subject_alt_names, CFSTR("dnsname"), CFSTR("xey.nl"));
67
68 int key_usage = kSecKeyUsageDigitalSignature | kSecKeyUsageKeyEncipherment;
69 CFNumberRef key_usage_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &key_usage);
70
71 CFMutableDictionaryRef random_extensions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
72
73 const void *key[] = { kSecCSRChallengePassword, kSecSubjectAltName, kSecCertificateKeyUsage, kSecCertificateExtensions };
74 const void *val[] = { CFSTR("magic"), subject_alt_names, key_usage_num, random_extensions };
75 CFDictionaryRef csr_parameters = CFDictionaryCreate(kCFAllocatorDefault,
76 key, val, array_size(key), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
77
78 SecATV cn_phone[] = { { kSecOidCommonName, SecASN1PrintableString, CFSTR("My iPhone") }, {} };
79 SecATV c[] = { { kSecOidCountryName, SecASN1PrintableString, CFSTR("US") }, {} };
80 SecATV st[] = { { kSecOidStateProvinceName, SecASN1PrintableString, CFSTR("CA") }, {} };
81 SecATV l[] = { { kSecOidLocalityName, SecASN1PrintableString, CFSTR("Cupertino") }, {} };
82 SecATV o[] = { { CFSTR("2.5.4.10"), SecASN1PrintableString, CFSTR("Apple Inc.") }, {} };
83 SecATV ou[] = { { kSecOidOrganizationalUnit, SecASN1PrintableString, CFSTR("iPhone") }, {} };
84
85 SecRDN atvs_phone[] = { cn_phone, c, st, l, o, ou, NULL };
86
87 ok_status(SecKeyGeneratePair(parameters, &phone_publicKey, &phone_privateKey), "generate key pair");
88 ok_status(SecKeyGeneratePair(parameters, &ca_publicKey, &ca_privateKey), "generate key pair");
89
90 int self_key_usage = kSecKeyUsageKeyCertSign | kSecKeyUsageCRLSign;
91 CFNumberRef self_key_usage_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &self_key_usage);
92 int path_len = 0;
93 CFNumberRef path_len_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &path_len);
94 const void *self_key[] = { kSecCertificateKeyUsage, kSecCSRBasicContraintsPathLen };
95 const void *self_val[] = { self_key_usage_num, path_len_num };
96 CFDictionaryRef self_signed_parameters = CFDictionaryCreate(kCFAllocatorDefault,
97 self_key, self_val, array_size(self_key), NULL, NULL);
98
99 const void * ca_o[] = { kSecOidOrganization, CFSTR("Apple Inc.") };
100 const void * ca_cn[] = { kSecOidCommonName, CFSTR("Root CA") };
101 CFArrayRef ca_o_dn = CFArrayCreate(kCFAllocatorDefault, ca_o, 2, NULL);
102 CFArrayRef ca_cn_dn = CFArrayCreate(kCFAllocatorDefault, ca_cn, 2, NULL);
103 const void *ca_dn_array[2];
104 ca_dn_array[0] = CFArrayCreate(kCFAllocatorDefault, (const void **)&ca_o_dn, 1, NULL);
105 ca_dn_array[1] = CFArrayCreate(kCFAllocatorDefault, (const void **)&ca_cn_dn, 1, NULL);
106 CFArrayRef ca_rdns = CFArrayCreate(kCFAllocatorDefault, ca_dn_array, 2, NULL);
107
108 SecCertificateRef ca_cert = SecGenerateSelfSignedCertificate(ca_rdns,
109 self_signed_parameters, ca_publicKey, ca_privateKey);
110 SecCertificateRef ca_cert_phone_key =
111 SecGenerateSelfSignedCertificate(ca_rdns, self_signed_parameters, phone_publicKey, phone_privateKey);
112
113 CFReleaseSafe(self_signed_parameters);
114 CFReleaseSafe(self_key_usage_num);
115 CFReleaseSafe(path_len_num);
116 CFReleaseNull(ca_o_dn);
117 CFReleaseNull(ca_cn_dn);
118 CFReleaseNull(ca_dn_array[0]);
119 CFReleaseNull(ca_dn_array[1]);
120 CFReleaseNull(ca_rdns);
121
122 isnt(ca_cert, NULL, "got back a cert");
123 ok(SecCertificateIsSelfSignedCA(ca_cert), "cert is self-signed ca cert");
124 isnt(ca_cert_phone_key, NULL, "got back a cert");
125 ok(SecCertificateIsSelfSignedCA(ca_cert_phone_key), "cert is self-signed ca cert");
126 CFDataRef data = SecCertificateCopyData(ca_cert);
127 //write_data("/tmp/ca_cert.der", data);
128 CFReleaseSafe(data);
129
130 SecIdentityRef ca_identity = SecIdentityCreate(kCFAllocatorDefault, ca_cert, ca_privateKey);
131 SecIdentityRef ca_identity_phone_key = SecIdentityCreate(kCFAllocatorDefault, ca_cert_phone_key, phone_privateKey);
132 isnt(ca_identity, NULL, "got a identity");
133 isnt(ca_identity_phone_key, NULL, "got a identity");
134 CFDictionaryRef dict = CFDictionaryCreate(NULL, (const void **)&kSecValueRef, (const void **)&ca_identity, 1, NULL, NULL);
135 ok_status(SecItemAdd(dict, NULL), "add ca identity");
136 CFReleaseSafe(dict);
137 #if TARGET_OS_IPHONE
138 TODO: {
139 todo("Adding a cert with the same issuer/serial but a different key should return something other than errSecDuplicateItem");
140 #else
141 {
142 #endif
143 dict = CFDictionaryCreate(NULL, (const void **)&kSecValueRef, (const void **)&ca_identity_phone_key, 1, NULL, NULL);
144 is_status(errSecDuplicateItem, SecItemAdd(dict, NULL), "add ca identity");
145 CFReleaseSafe(dict);
146 }
147
148 CFDataRef csr = SecGenerateCertificateRequestWithParameters(atvs_phone, NULL, phone_publicKey, phone_privateKey);
149 isnt(csr, NULL, "got back a csr");
150 CFReleaseNull(csr);
151
152 //dict[kSecSubjectAltName, dict[ntPrincipalName, "foo@bar.org"]]
153 CFStringRef nt_princ_name_val = CFSTR("foo@bar.org");
154 CFStringRef nt_princ_name_key = CFSTR("ntPrincipalName");
155 CFDictionaryRef nt_princ = CFDictionaryCreate(NULL, (const void **)&nt_princ_name_key, (const void **)&nt_princ_name_val, 1, NULL, NULL);
156 CFDictionaryRef params = CFDictionaryCreate(NULL, (const void **)&kSecSubjectAltName, (const void **)&nt_princ, 1, NULL, NULL);
157
158 csr = SecGenerateCertificateRequestWithParameters(atvs_phone, params, phone_publicKey, phone_privateKey);
159 isnt(csr, NULL, "got back a csr");
160 //write_data("/var/tmp/csr-nt-princ", csr);
161 CFReleaseNull(csr);
162 CFReleaseNull(params);
163 CFReleaseNull(nt_princ);
164
165 csr = SecGenerateCertificateRequestWithParameters(atvs_phone, csr_parameters, phone_publicKey, phone_privateKey);
166 isnt(csr, NULL, "csr w/ params");
167 //write_data("/tmp/csr", csr);
168 CFDataRef subject, extensions;
169 CFStringRef challenge;
170 ok(SecVerifyCertificateRequest(csr, NULL, &challenge, &subject, &extensions), "verify csr");
171 CFReleaseNull(csr);
172
173 uint8_t serialno_byte = 42;
174 CFDataRef serialno = CFDataCreate(kCFAllocatorDefault, &serialno_byte, sizeof(serialno_byte));
175 SecCertificateRef cert = SecIdentitySignCertificate(ca_identity, serialno,
176 phone_publicKey, subject, extensions);
177 data = SecCertificateCopyData(cert);
178 //write_data("/tmp/iphone_cert.der", data);
179 CFReleaseNull(data);
180 CFReleaseNull(subject);
181 CFReleaseNull(extensions);
182 CFReleaseNull(challenge);
183
184 const void * email[] = { CFSTR("1.2.840.113549.1.9.1"), CFSTR("foo@bar.biz") };
185 const void * cn[] = { CFSTR("2.5.4.3"), CFSTR("S/MIME Baby") };
186 CFArrayRef email_dn = CFArrayCreate(kCFAllocatorDefault, email, 2, NULL);
187 CFArrayRef cn_dn = CFArrayCreate(kCFAllocatorDefault, cn, 2, NULL);
188 const void *dn_array[2];
189 dn_array[0] = CFArrayCreate(kCFAllocatorDefault, (const void **)&email_dn, 1, NULL);
190 dn_array[1] = CFArrayCreate(kCFAllocatorDefault, (const void **)&cn_dn, 1, NULL);
191 CFArrayRef rdns = CFArrayCreate(kCFAllocatorDefault, dn_array, 2, NULL);
192 CFDictionarySetValue(subject_alt_names, CFSTR("rfc822name"), CFSTR("mongo@pawn.org"));
193
194 uint8_t random_extension_data[] = { 0xde, 0xad, 0xbe, 0xef };
195 CFDataRef random_extension_value = CFDataCreate(kCFAllocatorDefault, random_extension_data, sizeof(random_extension_data));
196 CFDictionarySetValue(random_extensions, CFSTR("1.2.840.113635.100.6.1.2"), random_extension_value); // APPLE_FDR_ACCESS_OID
197 CFDictionarySetValue(random_extensions, CFSTR("1.2.840.113635.100.6.1.3"), CFSTR("that guy")); // APPLE_FDR_CLIENT_IDENTIFIER_OID
198 CFReleaseNull(random_extension_value);
199
200 csr = SecGenerateCertificateRequest(rdns, csr_parameters, phone_publicKey, phone_privateKey);
201 isnt(csr, NULL, "csr w/ params");
202 //write_data("/tmp/csr_neu", csr);
203 CFReleaseNull(csr);
204 CFReleaseNull(subject_alt_names);
205 CFDictionaryRemoveAllValues(random_extensions);
206
207 #if TARGET_OS_IPHONE
208 CFDataRef scep_request = SecSCEPGenerateCertificateRequest(rdns,
209 csr_parameters, phone_publicKey, phone_privateKey, NULL, ca_cert);
210 isnt(scep_request, NULL, "got scep blob");
211 //write_data("/tmp/scep_request.der", scep_request);
212 #endif
213
214 CFReleaseNull(email_dn);
215 CFReleaseNull(cn_dn);
216 CFReleaseNull(dn_array[0]);
217 CFReleaseNull(dn_array[1]);
218 CFReleaseNull(rdns);
219
220 #if TARGET_OS_IPHONE
221 CFDataRef scep_reply = SecSCEPCertifyRequest(scep_request, ca_identity, serialno, false);
222 isnt(scep_reply, NULL, "produced scep reply");
223 //write_data("/tmp/scep_reply.der", scep_reply);
224
225 CFArrayRef issued_certs = NULL;
226 ok(issued_certs = SecSCEPVerifyReply(scep_request, scep_reply, ca_cert, NULL), "verify scep reply");
227
228 // take the issued cert and CA cert and pretend it's a RA/CA couple
229 CFMutableArrayRef scep_certs = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, issued_certs);
230 CFArrayAppendValue(scep_certs, ca_cert);
231 SecCertificateRef ca_certificate = NULL, ra_signing_certificate = NULL, ra_encryption_certificate = NULL;
232
233 ok_status(SecSCEPValidateCACertMessage(scep_certs, NULL,
234 &ca_certificate, &ra_signing_certificate,
235 &ra_encryption_certificate), "pull apart array again");
236 ok(CFEqual(ca_cert, ca_certificate), "found ca");
237 ok(CFArrayContainsValue(issued_certs, CFRangeMake(0, CFArrayGetCount(issued_certs)), ra_signing_certificate), "found ra");
238 ok(!ra_encryption_certificate, "no separate encryption cert");
239
240 CFReleaseSafe(ca_certificate);
241 CFReleaseSafe(ra_signing_certificate);
242 CFReleaseSafe(scep_certs);
243
244 CFReleaseSafe(scep_request);
245 CFReleaseSafe(scep_reply);
246 CFReleaseSafe(issued_certs);
247 #endif
248
249 // cleanups
250 dict = CFDictionaryCreate(NULL, (const void **)&kSecValueRef, (const void **)&ca_identity, 1, NULL, NULL);
251 ok_status(SecItemDelete(dict), "delete ca identity");
252 CFReleaseSafe(dict);
253 dict = CFDictionaryCreate(NULL, (const void **)&kSecValueRef, (const void **)&phone_privateKey, 1, NULL, NULL);
254 ok_status(SecItemDelete(dict), "delete phone private key");
255 CFReleaseSafe(dict);
256
257 CFReleaseSafe(serialno);
258
259 CFReleaseSafe(cert);
260 CFReleaseSafe(ca_identity);
261 CFReleaseSafe(ca_cert);
262 CFReleaseSafe(ca_identity_phone_key);
263 CFReleaseSafe(ca_cert_phone_key);
264 CFReleaseSafe(csr_parameters);
265 CFReleaseSafe(random_extensions);
266 CFReleaseSafe(parameters);
267 CFReleaseSafe(ca_publicKey);
268 CFReleaseSafe(ca_privateKey);
269 CFReleaseSafe(phone_publicKey);
270 CFReleaseSafe(phone_privateKey);
271 }
272
273 static void test_ec_csr(void) {
274 SecKeyRef ecPublicKey = NULL, ecPrivateKey = NULL;
275
276 int keysize = 256;
277 CFNumberRef key_size_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &keysize);
278
279 const void *keyParamsKeys[] = { kSecAttrKeyType, kSecAttrKeySizeInBits };
280 const void *keyParamsValues[] = { kSecAttrKeyTypeECSECPrimeRandom, key_size_num};
281 CFDictionaryRef keyParameters = CFDictionaryCreate(NULL, keyParamsKeys, keyParamsValues, 2,
282 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
283 ok_status(SecKeyGeneratePair(keyParameters, &ecPublicKey, &ecPrivateKey),
284 "unable to generate EC key");
285
286 SecATV cn_phone[] = { { kSecOidCommonName, SecASN1PrintableString, CFSTR("My iPhone") }, {} };
287 SecATV c[] = { { kSecOidCountryName, SecASN1PrintableString, CFSTR("US") }, {} };
288 SecATV st[] = { { kSecOidStateProvinceName, SecASN1PrintableString, CFSTR("CA") }, {} };
289 SecATV l[] = { { kSecOidLocalityName, SecASN1PrintableString, CFSTR("Cupertino") }, {} };
290 SecATV o[] = { { CFSTR("2.5.4.10"), SecASN1PrintableString, CFSTR("Apple Inc.") }, {} };
291 SecATV ou[] = { { kSecOidOrganizationalUnit, SecASN1PrintableString, CFSTR("iPhone") }, {} };
292
293 SecRDN atvs_phone[] = { cn_phone, c, st, l, o, ou, NULL };
294
295 CFMutableDictionaryRef subject_alt_names = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
296 CFDictionarySetValue(subject_alt_names, CFSTR("dnsname"), CFSTR("xey.nl"));
297
298 int key_usage = kSecKeyUsageDigitalSignature | kSecKeyUsageKeyEncipherment;
299 CFNumberRef key_usage_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &key_usage);
300
301 CFMutableDictionaryRef random_extensions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
302
303 const void *key[] = { kSecCSRChallengePassword, kSecSubjectAltName, kSecCertificateKeyUsage, kSecCertificateExtensions };
304 const void *val[] = { CFSTR("magic"), subject_alt_names, key_usage_num, random_extensions };
305 CFDictionaryRef csr_parameters = CFDictionaryCreate(kCFAllocatorDefault,
306 key, val, array_size(key), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
307
308
309 CFDataRef csr = SecGenerateCertificateRequestWithParameters(atvs_phone, csr_parameters, ecPublicKey, ecPrivateKey);
310 isnt(csr, NULL, "csr w/ params");
311 //write_data("/tmp/csr", csr);
312 CFDataRef subject, extensions;
313 CFStringRef challenge;
314 ok(SecVerifyCertificateRequest(csr, NULL, &challenge, &subject, &extensions), "verify csr");
315
316 CFReleaseNull(csr);
317 CFReleaseNull(key_size_num);
318 CFReleaseNull(keyParameters);
319 CFReleaseNull(ecPublicKey);
320 CFReleaseNull(ecPrivateKey);
321 CFReleaseNull(subject_alt_names);
322 CFReleaseNull(key_usage_num);
323 CFReleaseNull(random_extensions);
324 CFReleaseNull(csr_parameters);
325 CFReleaseNull(subject);
326 CFReleaseNull(extensions);
327 CFReleaseNull(challenge);
328 }
329
330 int si_62_csr(int argc, char *const *argv)
331 {
332 #if TARGET_OS_IPHONE
333 plan_tests(27);
334 #else
335 plan_tests(20);
336 #endif
337
338 tests();
339 test_ec_csr();
340
341 return 0;
342 }