]> git.saurik.com Git - apple/security.git/blob - OSX/sec/Security/Regressions/secitem/si-20-sectrust.c
Security-57740.60.18.tar.gz
[apple/security.git] / OSX / sec / Security / Regressions / secitem / si-20-sectrust.c
1 /*
2 * Copyright (c) 2006-2010,2012-2016 Apple Inc. All Rights Reserved.
3 */
4
5 #include <AssertMacros.h>
6 #include <CoreFoundation/CoreFoundation.h>
7 #include <Security/SecCertificate.h>
8 #include <Security/SecCertificatePriv.h>
9 #include <Security/SecPolicyPriv.h>
10 #include <Security/SecTrustPriv.h>
11 #include <Security/SecItem.h>
12 #include <utilities/array_size.h>
13 #include <utilities/SecCFWrappers.h>
14 #include <stdlib.h>
15 #include <unistd.h>
16
17 #if TARGET_OS_IPHONE
18 #include <Security/SecInternal.h>
19 #include <ipc/securityd_client.h>
20 #endif
21
22 #include "shared_regressions.h"
23 #include "si-20-sectrust.h"
24
25 /* Test SecTrust API. */
26 static void basic_tests(void)
27 {
28 SecTrustRef trust = NULL;
29 CFArrayRef _anchors = NULL, certs = NULL, anchors = NULL, replacementPolicies;
30 SecCertificateRef cert0 = NULL, cert1 = NULL, _root = NULL, cert_xedge2 = NULL, garthc2 = NULL;
31 SecPolicyRef policy = NULL, replacementPolicy = NULL, replacementPolicy2 = NULL;
32 CFDateRef date = NULL;
33 CFDataRef c0_serial = NULL, serial = NULL;
34 CFDictionaryRef query = NULL;
35
36 isnt(cert0 = SecCertificateCreateWithBytes(NULL, _c0, sizeof(_c0)),
37 NULL, "create cert0");
38 isnt(cert1 = SecCertificateCreateWithBytes(NULL, _c1, sizeof(_c1)),
39 NULL, "create cert1");
40 const void *v_certs[] = {
41 cert0,
42 cert1
43 };
44 policy = SecPolicyCreateSSL(false, NULL);
45 certs = CFArrayCreate(NULL, v_certs,
46 array_size(v_certs), &kCFTypeArrayCallBacks);
47
48 /* SecTrustCreateWithCertificates failures. */
49 is_status(SecTrustCreateWithCertificates(kCFBooleanTrue, policy, &trust),
50 errSecParam, "create trust with boolean instead of cert");
51 is_status(SecTrustCreateWithCertificates(cert0, kCFBooleanTrue, &trust),
52 errSecParam, "create trust with boolean instead of policy");
53
54 /* SecTrustCreateWithCertificates using array of certs. */
55 ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust");
56
57 /* NOTE: prior to <rdar://11810677 SecTrustGetCertificateCount would return 1 at this point.
58 * Now, however, we do an implicit SecTrustEvaluate to build the chain if it has not yet been
59 * evaluated, so we now expect the full chain length.
60 */
61 is(SecTrustGetCertificateCount(trust), 3, "cert count is 3");
62 is(SecTrustGetCertificateAtIndex(trust, 0), cert0, "cert 0 is leaf");
63
64 /* Jul 30 2014. */
65 isnt(date = CFDateCreateForGregorianZuluMoment(NULL, 2014, 7, 30, 12, 0, 0),
66 NULL, "create verify date");
67 if (!date) { goto errOut; }
68 ok_status(SecTrustSetVerifyDate(trust, date), "set date");
69
70 SecTrustResultType trustResult;
71
72 #if TARGET_OS_IPHONE
73 SKIP: {
74 #ifdef NO_SERVER
75 skip("Can't fail to connect to securityd in NO_SERVER mode", 4, false);
76 #endif
77 // Test Restore OS environment
78 SecServerSetMachServiceName("com.apple.security.doesn't-exist");
79 ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust without securityd running");
80 is_status(trustResult, kSecTrustResultInvalid, "trustResult is kSecTrustResultInvalid");
81 is(SecTrustGetCertificateCount(trust), 1, "cert count is 1 without securityd running");
82 SecKeyRef pubKey = NULL;
83 ok(pubKey = SecTrustCopyPublicKey(trust), "copy public key without securityd running");
84 CFReleaseNull(pubKey);
85 SecServerSetMachServiceName(NULL);
86 // End of Restore OS environment tests
87 }
88 #endif
89
90 ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
91 is_status(trustResult, kSecTrustResultUnspecified,
92 "trustResult is kSecTrustResultUnspecified");
93
94 is(SecTrustGetCertificateCount(trust), 3, "cert count is 3");
95
96 if (!cert0) { goto errOut; }
97 c0_serial = CFDataCreate(NULL, _c0_serial, sizeof(_c0_serial));
98 #if TARGET_OS_IPHONE
99 ok(serial = SecCertificateCopySerialNumber(cert0), "copy cert0 serial");
100 #else
101 CFErrorRef error = NULL;
102 ok(serial = SecCertificateCopySerialNumber(cert0, &error), "copy cert0 serial");
103 CFReleaseNull(error);
104 #endif
105 ok(CFEqual(c0_serial, serial), "serial matches");
106 CFReleaseNull(serial);
107 CFReleaseNull(c0_serial);
108
109 anchors = CFArrayCreate(NULL, (const void **)&cert1, 1, &kCFTypeArrayCallBacks);
110 ok_status(SecTrustSetAnchorCertificates(trust, anchors), "set anchors");
111 ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
112 is_status(trustResult, kSecTrustResultUnspecified,
113 "trust is kSecTrustResultUnspecified");
114 is(SecTrustGetCertificateCount(trust), 2, "cert count is 2");
115
116 CFReleaseNull(anchors);
117 anchors = CFArrayCreate(NULL, NULL, 0, NULL);
118 ok_status(SecTrustSetAnchorCertificates(trust, anchors), "set empty anchors list");
119 ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
120 is_status(trustResult, kSecTrustResultRecoverableTrustFailure,
121 "trust is kSecTrustResultRecoverableTrustFailure");
122 CFReleaseNull(anchors);
123
124 ok_status(SecTrustSetAnchorCertificatesOnly(trust, false), "trust passed in anchors and system anchors");
125 ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
126 is_status(trustResult, kSecTrustResultUnspecified,
127 "trust is kSecTrustResultUnspecified");
128
129 ok_status(SecTrustSetAnchorCertificatesOnly(trust, true), "only trust passed in anchors (default)");
130 ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
131 is_status(trustResult, kSecTrustResultRecoverableTrustFailure,
132 "trust is kSecTrustResultRecoverableTrustFailure");
133
134 /* Test cert_1 intermediate from the keychain. */
135 CFReleaseNull(trust);
136 ok_status(SecTrustCreateWithCertificates(cert0, policy, &trust),
137 "create trust with single cert0");
138 ok_status(SecTrustSetVerifyDate(trust, date), "set date");
139
140 // Add cert1
141 query = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
142 kSecClass, kSecClassCertificate, kSecValueRef, cert1, NULL);
143 ok_status(SecItemAdd(query, NULL), "add cert1 to keychain");
144 ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
145 // Cleanup added cert1.
146 ok_status(SecItemDelete(query), "remove cert1 from keychain");
147 CFReleaseNull(query);
148 is_status(trustResult, kSecTrustResultUnspecified,
149 "trust is kSecTrustResultUnspecified");
150 is(SecTrustGetCertificateCount(trust), 3, "cert count is 3");
151
152 /* Set certs to be the xedge2 leaf. */
153 CFReleaseNull(certs);
154 isnt(cert_xedge2 = SecCertificateCreateWithBytes(NULL, xedge2_certificate,
155 sizeof(xedge2_certificate)), NULL, "create cert_xedge2");
156 certs = CFArrayCreate(NULL, (const void **)&cert_xedge2, 1, &kCFTypeArrayCallBacks);
157
158 CFReleaseNull(trust);
159 CFReleaseNull(policy);
160 CFReleaseNull(date);
161 bool server = true;
162 policy = SecPolicyCreateSSL(server, CFSTR("xedge2.apple.com"));
163 ok_status(SecTrustCreateWithCertificates(certs, policy, &trust),
164 "create trust for ssl server xedge2.apple.com");
165
166 /* This test uses a cert whose root is no longer in our trust store,
167 * so we need to explicitly set it as a trusted anchor
168 */
169 isnt(_root = SecCertificateCreateWithBytes(NULL, entrust1024RootCA, sizeof(entrust1024RootCA)),
170 NULL, "create root");
171 const void *v_roots[] = { _root };
172 isnt(_anchors = CFArrayCreate(NULL, v_roots, array_size(v_roots), &kCFTypeArrayCallBacks),
173 NULL, "create anchors");
174 if (!_anchors) { goto errOut; }
175 ok_status(SecTrustSetAnchorCertificates(trust, _anchors), "set anchors");
176
177 /* Jan 1st 2009. */
178 date = CFDateCreate(NULL, 252288000.0);
179 ok_status(SecTrustSetVerifyDate(trust, date), "set xedge2 trust date to Jan 1st 2009");
180 ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate xedge2 trust");
181 is_status(trustResult, kSecTrustResultUnspecified,
182 "trust is kSecTrustResultUnspecified");
183
184 CFReleaseNull(trust);
185 CFReleaseNull(policy);
186 server = false;
187 policy = SecPolicyCreateSSL(server, CFSTR("xedge2.apple.com"));
188 ok_status(SecTrustCreateWithCertificates(certs, policy, &trust),
189 "create trust for ssl client xedge2.apple.com");
190 ok_status(SecTrustSetAnchorCertificates(trust, _anchors), "set anchors");
191 ok_status(SecTrustSetVerifyDate(trust, date), "set xedge2 trust date to Jan 1st 2009");
192 ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate xedge2 trust");
193 is_status(trustResult, kSecTrustResultRecoverableTrustFailure,
194 "trust is kSecTrustResultRecoverableTrustFailure");
195
196 CFReleaseNull(trust);
197 CFReleaseNull(policy);
198 server = true;
199 policy = SecPolicyCreateIPSec(server, CFSTR("xedge2.apple.com"));
200 ok_status(SecTrustCreateWithCertificates(certs, policy, &trust),
201 "create trust for ip server xedge2.apple.com");
202 ok_status(SecTrustSetAnchorCertificates(trust, _anchors), "set anchors");
203 ok_status(SecTrustSetVerifyDate(trust, date), "set xedge2 trust date to Jan 1st 2009");
204 ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate xedge2 trust");
205 #if 0
206 /* Although this shouldn't be a valid ipsec cert, since we no longer
207 check for ekus in the ipsec policy it is. */
208 is_status(trustResult, kSecTrustResultRecoverableTrustFailure,
209 "trust is kSecTrustResultRecoverableTrustFailure");
210 #else
211 is_status(trustResult, kSecTrustResultUnspecified,
212 "trust is kSecTrustResultUnspecified");
213 #endif
214
215 CFReleaseNull(trust);
216 CFReleaseNull(policy);
217 server = true;
218 policy = SecPolicyCreateSSL(server, CFSTR("nowhere.com"));
219 ok_status(SecTrustCreateWithCertificates(certs, policy, &trust),
220 "create trust for ssl server nowhere.com");
221 replacementPolicy = SecPolicyCreateSSL(server, CFSTR("xedge2.apple.com"));
222 SecTrustSetPolicies(trust, replacementPolicy);
223 CFReleaseNull(replacementPolicy);
224 ok_status(SecTrustSetAnchorCertificates(trust, _anchors), "set anchors");
225 ok_status(SecTrustSetVerifyDate(trust, date), "set xedge2 trust date to Jan 1st 2009");
226 ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate xedge2 trust");
227 is_status(trustResult, kSecTrustResultUnspecified,
228 "trust is kSecTrustResultUnspecified");
229
230 CFReleaseNull(trust);
231 CFReleaseNull(policy);
232 server = true;
233 policy = SecPolicyCreateSSL(server, CFSTR("nowhere.com"));
234 ok_status(SecTrustCreateWithCertificates(certs, policy, &trust),
235 "create trust for ssl server nowhere.com");
236 replacementPolicy2 = SecPolicyCreateSSL(server, CFSTR("xedge2.apple.com"));
237 replacementPolicies = CFArrayCreate(kCFAllocatorDefault, (CFTypeRef*)&replacementPolicy2, 1, &kCFTypeArrayCallBacks);
238 SecTrustSetPolicies(trust, replacementPolicies);
239 CFReleaseNull(replacementPolicy2);
240 CFReleaseNull(replacementPolicies);
241 ok_status(SecTrustSetAnchorCertificates(trust, _anchors), "set anchors");
242 ok_status(SecTrustSetVerifyDate(trust, date), "set xedge2 trust date to Jan 1st 2009");
243 ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate xedge2 trust");
244 is_status(trustResult, kSecTrustResultUnspecified,
245 "trust is kSecTrustResultUnspecified");
246
247 /* Test self signed ssl cert with cert itself set as anchor. */
248 CFReleaseNull(trust);
249 CFReleaseNull(policy);
250 CFReleaseNull(certs);
251 CFReleaseNull(date);
252 server = true;
253 isnt(garthc2 = SecCertificateCreateWithBytes(NULL, garthc2_certificate,
254 sizeof(garthc2_certificate)), NULL, "create garthc2");
255 certs = CFArrayCreate(NULL, (const void **)&garthc2, 1, &kCFTypeArrayCallBacks);
256 policy = SecPolicyCreateSSL(server, CFSTR("garthc2.apple.com"));
257 ok_status(SecTrustCreateWithCertificates(certs, policy, &trust),
258 "create trust for ip server garthc2.apple.com");
259 date = CFDateCreate(NULL, 269568000.0);
260 ok_status(SecTrustSetVerifyDate(trust, date),
261 "set garthc2 trust date to Aug 2009");
262 ok_status(SecTrustSetAnchorCertificates(trust, certs),
263 "set garthc2 as anchor");
264 ok_status(SecTrustEvaluate(trust, &trustResult),
265 "evaluate self signed cert with cert as anchor");
266 is_status(trustResult, kSecTrustResultUnspecified,
267 "trust is kSecTrustResultUnspecified");
268
269
270 errOut:
271 CFReleaseSafe(garthc2);
272 CFReleaseSafe(cert_xedge2);
273 CFReleaseSafe(anchors);
274 CFReleaseSafe(trust);
275 CFReleaseSafe(serial);
276 CFReleaseSafe(c0_serial);
277 CFReleaseSafe(policy);
278 CFReleaseSafe(certs);
279 CFReleaseSafe(cert0);
280 CFReleaseSafe(cert1);
281 CFReleaseSafe(date);
282
283 CFReleaseSafe(_root);
284 CFReleaseSafe(_anchors);
285 }
286
287 static void negative_integer_tests(void)
288 {
289 /* Test that we can handle and fix up negative integer value(s) in ECDSA signature */
290 const void *negIntSigLeaf;
291 isnt(negIntSigLeaf = SecCertificateCreateWithBytes(NULL, _leaf_NegativeIntInSig,
292 sizeof(_leaf_NegativeIntInSig)), NULL, "create negIntSigLeaf");
293 CFArrayRef certs = NULL;
294 isnt(certs = CFArrayCreate(NULL, &negIntSigLeaf, 1, &kCFTypeArrayCallBacks), NULL, "failed to create certs array");
295 SecPolicyRef policy = NULL;
296 isnt(policy = SecPolicyCreateiAP(), NULL, "failed to create policy");
297 SecTrustRef trust = NULL;
298 ok_status(SecTrustCreateWithCertificates(certs, policy, &trust),
299 "create trust for negIntSigLeaf");
300
301 const void *rootAACA2;
302 isnt(rootAACA2 = SecCertificateCreateWithBytes(NULL, _root_AACA2,
303 sizeof(_root_AACA2)), NULL, "create rootAACA2");
304 CFArrayRef anchors = NULL;
305 isnt(anchors = CFArrayCreate(NULL, &rootAACA2, 1, &kCFTypeArrayCallBacks), NULL, "failed to create anchors array");
306 if (!anchors) { goto errOut; }
307 ok_status(SecTrustSetAnchorCertificates(trust, anchors), "set anchor certificates");
308
309 SecTrustResultType trustResult;
310 ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
311 is_status(trustResult, kSecTrustResultUnspecified, "expected kSecTrustResultUnspecified");
312
313 errOut:
314 CFReleaseNull(trust);
315 CFReleaseNull(certs);
316 CFReleaseNull(anchors);
317 CFReleaseNull(negIntSigLeaf);
318 CFReleaseNull(rootAACA2);
319 CFReleaseNull(policy);
320 }
321
322 static void rsa8k_tests(void)
323 {
324 /* Test prt_forest_fi that have a 8k RSA key */
325 const void *prt_forest_fi;
326 isnt(prt_forest_fi = SecCertificateCreateWithBytes(NULL, prt_forest_fi_certificate,
327 sizeof(prt_forest_fi_certificate)), NULL, "create prt_forest_fi");
328 CFArrayRef certs = NULL;
329 isnt(certs = CFArrayCreate(NULL, &prt_forest_fi, 1, &kCFTypeArrayCallBacks), NULL, "failed to create cert array");
330 SecPolicyRef policy = NULL;
331 isnt(policy = SecPolicyCreateSSL(false, CFSTR("owa.prt-forest.fi")), NULL, "failed to create policy");
332 SecTrustRef trust = NULL;
333 ok_status(SecTrustCreateWithCertificates(certs, policy, &trust),
334 "create trust for ip client owa.prt-forest.fi");
335 CFDateRef date = CFDateCreate(NULL, 391578321.0);
336 ok_status(SecTrustSetVerifyDate(trust, date),
337 "set owa.prt-forest.fi trust date to May 2013");
338
339 SecKeyRef pubkey = SecTrustCopyPublicKey(trust);
340 isnt(pubkey, NULL, "pubkey returned");
341
342 CFReleaseNull(certs);
343 CFReleaseNull(prt_forest_fi);
344 CFReleaseNull(policy);
345 CFReleaseNull(trust);
346 CFReleaseNull(pubkey);
347 CFReleaseNull(date);
348 }
349
350 static void date_tests(void)
351 {
352 /* Test long-lived cert chain that expires in 9999 */
353 CFDateRef date = NULL;
354 const void *leaf, *root;
355 isnt(leaf = SecCertificateCreateWithBytes(NULL, longleaf, sizeof(longleaf)), NULL, "create leaf");
356 isnt(root = SecCertificateCreateWithBytes(NULL, longroot, sizeof(longroot)), NULL, "create root");
357
358 CFArrayRef certs = NULL;
359 isnt(certs = CFArrayCreate(NULL, &leaf, 1, &kCFTypeArrayCallBacks), NULL, "failed to create cert array");
360 CFArrayRef anchors = NULL;
361 isnt(anchors = CFArrayCreate(NULL, &root, 1, &kCFTypeArrayCallBacks), NULL, "failed to create anchors array");
362
363 SecPolicyRef policy = NULL;
364 isnt(policy = SecPolicyCreateBasicX509(), NULL, "failed to create policy");
365 SecTrustRef trust = NULL;
366 SecTrustResultType trustResult;
367 ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust");
368 if (!anchors) { goto errOut; }
369 ok_status(SecTrustSetAnchorCertificates(trust, anchors), "set anchors");
370
371 /* September 4, 2013 (prior to "notBefore" date of 2 April 2014, should fail) */
372 isnt(date = CFDateCreate(NULL, 400000000), NULL, "failed to create date");
373 if (!date) { goto errOut; }
374 ok_status(SecTrustSetVerifyDate(trust, date), "set trust date to 23 Sep 2013");
375 ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust on 23 Sep 2013");
376 is_status(trustResult, kSecTrustResultRecoverableTrustFailure, "expected kSecTrustResultRecoverableTrustFailure");
377 CFReleaseNull(date);
378
379 /* January 17, 2016 (recent date within validity period, should succeed) */
380 isnt(date = CFDateCreate(NULL, 474747474), NULL, "failed to create date");
381 if (!date) { goto errOut; }
382 ok_status(SecTrustSetVerifyDate(trust, date), "set trust date to 17 Jan 2016");
383 ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust on 17 Jan 2016");
384 is_status(trustResult, kSecTrustResultUnspecified, "expected kSecTrustResultUnspecified");
385 CFReleaseNull(date);
386
387 /* December 20, 9999 (far-future date within validity period, should succeed) */
388 isnt(date = CFDateCreate(NULL, 252423000000), NULL, "failed to create date");
389 if (!date) { goto errOut; }
390 ok_status(SecTrustSetVerifyDate(trust, date), "set trust date to 20 Dec 9999");
391 ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust on 20 Dec 9999");
392 is_status(trustResult, kSecTrustResultUnspecified, "expected kSecTrustResultUnspecified");
393 CFReleaseNull(date);
394
395 /* January 12, 10000 (after the "notAfter" date of 31 Dec 9999, should fail) */
396 isnt(date = CFDateCreate(NULL, 252425000000), NULL, "failed to create date");
397 if (!date) { goto errOut; }
398 ok_status(SecTrustSetVerifyDate(trust, date), "set trust date to 12 Jan 10000");
399 ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust on 12 Jan 10000");
400 is_status(trustResult, kSecTrustResultRecoverableTrustFailure, "expected kSecTrustResultRecoverableTrustFailure");
401 CFReleaseNull(date);
402
403 errOut:
404 CFReleaseNull(trust);
405 CFReleaseNull(policy);
406 CFReleaseNull(anchors);
407 CFReleaseNull(certs);
408 CFReleaseNull(root);
409 CFReleaseNull(leaf);
410 }
411
412 static bool test_chain_of_three(uint8_t *cert0, size_t cert0len,
413 uint8_t *cert1, size_t cert1len,
414 uint8_t *root, size_t rootlen,
415 bool should_succeed, CF_RETURNS_RETAINED CFStringRef *failureReason)
416 {
417 bool ok = false;
418
419 const void *secCert0, *secCert1, *secRoot;
420 isnt(secCert0 = SecCertificateCreateWithBytes(NULL, cert0, cert0len), NULL, "create leaf");
421 isnt(secCert1 = SecCertificateCreateWithBytes(NULL, cert1, cert1len), NULL, "create subCA");
422 isnt(secRoot = SecCertificateCreateWithBytes(NULL, root, rootlen), NULL, "create root");
423
424 const void *v_certs[] = { secCert0, secCert1 };
425 CFArrayRef certs = NULL;
426 isnt(certs = CFArrayCreate(NULL, v_certs, sizeof(v_certs)/sizeof(*v_certs), &kCFTypeArrayCallBacks),
427 NULL, "failed to create cert array");
428 CFArrayRef anchors = NULL;
429 isnt(anchors = CFArrayCreate(NULL, &secRoot, 1, &kCFTypeArrayCallBacks), NULL, "failed to create anchors array");
430
431 SecPolicyRef policy = NULL;
432 isnt(policy = SecPolicyCreateBasicX509(), NULL, "failed to create policy");
433 CFDateRef date = NULL;
434 isnt(date = CFDateCreate(NULL, 472100000.0), NULL, "failed to create date"); // 17 Dec 2015
435
436 SecTrustRef trust = NULL;
437 SecTrustResultType trustResult;
438 ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "failed to create trust");
439 if (!date) { goto errOut; }
440 ok_status(SecTrustSetVerifyDate(trust, date), "failed to set verify date");
441 if (!anchors) { goto errOut; }
442 ok_status(SecTrustSetAnchorCertificates(trust, anchors), "failed to set anchors");
443
444 ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate chain");
445 is(SecTrustGetCertificateCount(trust), 3, "expected chain of 3");
446 bool did_succeed = (trustResult == kSecTrustResultUnspecified);
447
448 if (failureReason && should_succeed && !did_succeed) {
449 *failureReason = SecTrustCopyFailureDescription(trust);
450 } else if (failureReason && !should_succeed && did_succeed) {
451 *failureReason = CFSTR("expected kSecTrustResultRecoverableTrustFailure");
452 }
453
454 if ((should_succeed && did_succeed) || (!should_succeed && !did_succeed)) {
455 ok = true;
456 }
457
458 errOut:
459 CFReleaseNull(secCert0);
460 CFReleaseNull(secCert1);
461 CFReleaseNull(secRoot);
462 CFReleaseNull(certs);
463 CFReleaseNull(anchors);
464 CFReleaseNull(date);
465 CFReleaseNull(policy);
466 CFReleaseNull(trust);
467
468 return ok;
469 }
470
471 static void rsa_key_size_tests() {
472
473 ok(test_chain_of_three(_leaf2048A, sizeof(_leaf2048A),_int2048A, sizeof(_int2048A), _root512, sizeof(_root512),
474 false, NULL), "SECURITY: failed to detect weak root");
475 ok(test_chain_of_three(_leaf2048B, sizeof(_leaf2048B), _int512, sizeof(_int512), _root2048, sizeof(_root2048),
476 false, NULL), "SECURITY: failed to detect weak intermediate");
477 ok(test_chain_of_three(_leaf512, sizeof(_leaf512), _int2048B, sizeof(_int2048B), _root2048, sizeof(_root2048),
478 false, NULL), "SECURITY: failed to detect weak leaf");
479
480 CFStringRef failureReason = NULL;
481 ok(test_chain_of_three(_leaf1024, sizeof(_leaf1024), _int2048B, sizeof(_int2048B), _root2048, sizeof(_root2048),
482 true, &failureReason), "REGRESSION: key size test 1024-bit leaf: %@", failureReason);
483 CFReleaseNull(failureReason);
484 ok(test_chain_of_three(_leaf2048C, sizeof(_leaf2048C), _int2048B, sizeof(_int2048B), _root2048, sizeof(_root2048),
485 true, &failureReason), "REGRESSION: key size test 2048-bit leaf: %@", failureReason);
486 CFReleaseNull(failureReason);
487
488 }
489
490 static void ec_key_size_tests() {
491
492 /* Because CoreCrypto does not support P128, we fail to chain if any CAs use weakly sized curves */
493 ok(test_chain_of_three(_leaf128, sizeof(_leaf128), _int384B, sizeof(_int384B), _root384, sizeof(_root384),
494 false, NULL), "SECURITY: failed to detect weak leaf");
495
496 CFStringRef failureReason = NULL;
497 ok(test_chain_of_three(_leaf192, sizeof(_leaf192), _int384B, sizeof(_int384B), _root384, sizeof(_root384),
498 true, &failureReason), "REGRESSION: key size test 192-bit leaf: %@", failureReason);
499 CFReleaseNull(failureReason);
500 ok(test_chain_of_three(_leaf384C, sizeof(_leaf384C), _int384B, sizeof(_int384B), _root384, sizeof(_root384),
501 true, &failureReason), "REGRESSION: key size test 384-bit leaf: %@", failureReason);
502 CFReleaseNull(failureReason);
503
504 }
505
506 static void test_input_certificates() {
507 SecCertificateRef cert0 = NULL, cert1 = NULL;
508 SecPolicyRef policy = NULL;
509 SecTrustRef trust = NULL;
510 CFArrayRef certificates = NULL;
511
512 require(cert0 = SecCertificateCreateWithBytes(NULL, _c0, sizeof(_c0)), errOut);
513 require(cert1 = SecCertificateCreateWithBytes(NULL, _c1, sizeof(_c1)), errOut);
514 require(policy = SecPolicyCreateBasicX509(), errOut);
515 require_noerr(SecTrustCreateWithCertificates(cert0, policy, &trust), errOut);
516
517 ok_status(SecTrustCopyInputCertificates(trust, &certificates), "SecTrustCopyInputCertificates failed");
518 is(CFArrayGetCount(certificates), 1, "got too many input certs back");
519 is(CFArrayGetValueAtIndex(certificates, 0), cert0, "wrong input cert");
520 CFReleaseNull(certificates);
521
522 ok_status(SecTrustAddToInputCertificates(trust, cert1), "SecTrustAddToInputCertificates failed");
523 ok_status(SecTrustCopyInputCertificates(trust, &certificates), "SecTrustCopyInputCertificates failed");
524 is(CFArrayGetCount(certificates), 2, "got wrong number of input certs back");
525 is(CFArrayGetValueAtIndex(certificates, 0), cert0, "wrong input cert0");
526 is(CFArrayGetValueAtIndex(certificates, 1), cert1, "wrong input cert1");
527 is(SecTrustGetCertificateCount(trust), 3, "output number of certs is 3");
528
529 errOut:
530 CFReleaseNull(cert0);
531 CFReleaseNull(cert1);
532 CFReleaseNull(policy);
533 CFReleaseNull(trust);
534 CFReleaseNull(certificates);
535 }
536
537 static void test_async_trust() {
538 SecCertificateRef cert0 = NULL, cert1 = NULL;
539 SecPolicyRef policy = NULL;
540 SecTrustRef trust = NULL;
541 CFArrayRef certificates = NULL;
542 CFDateRef date = NULL;
543
544 require(cert0 = SecCertificateCreateWithBytes(NULL, _c0, sizeof(_c0)), errOut);
545 require(cert1 = SecCertificateCreateWithBytes(NULL, _c1, sizeof(_c1)), errOut);
546 const void *v_certs[] = {
547 cert0,
548 cert1
549 };
550 certificates = CFArrayCreate(NULL, v_certs,
551 array_size(v_certs),
552 &kCFTypeArrayCallBacks);
553
554 require(policy = SecPolicyCreateBasicX509(), errOut);
555 require_noerr(SecTrustCreateWithCertificates(certificates, policy, &trust), errOut);
556
557 /* Jul 30 2014. */
558 require(date = CFDateCreateForGregorianZuluMoment(NULL, 2014, 7, 30, 12, 0, 0), errOut);
559 require_noerr(SecTrustSetVerifyDate(trust, date), errOut);
560
561 /* This shouldn't crash. */
562 ok_status(SecTrustEvaluateAsync(trust, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
563 ^(SecTrustRef _Nonnull trustRef, SecTrustResultType trustResult) {
564 if ((trustResult == kSecTrustResultProceed) ||
565 (trustResult == kSecTrustResultUnspecified))
566 {
567 // Evaluation succeeded!
568 SecKeyRef publicKey = SecTrustCopyPublicKey(trustRef);
569
570 CFReleaseSafe(publicKey);
571
572 } else if (trustResult == kSecTrustResultRecoverableTrustFailure) {
573 // Evaluation failed, but may be able to recover . . .
574 } else {
575 // Evaluation failed
576 }
577 }), "evaluate trust asynchronously");
578 CFReleaseNull(trust);
579
580 errOut:
581 CFReleaseNull(cert0);
582 CFReleaseNull(cert1);
583 CFReleaseNull(policy);
584 CFReleaseNull(certificates);
585 CFReleaseNull(date);
586 }
587
588 int si_20_sectrust(int argc, char *const *argv)
589 {
590 #if TARGET_OS_IPHONE
591 plan_tests(101+9+(8*13)+9+1);
592 #else
593 plan_tests(97+9+(8*13)+9+1);
594 #endif
595
596 basic_tests();
597 negative_integer_tests();
598 rsa8k_tests();
599 date_tests();
600 rsa_key_size_tests();
601 ec_key_size_tests();
602 test_input_certificates();
603 test_async_trust();
604
605 return 0;
606 }