]> git.saurik.com Git - apple/security.git/blob - tests/TrustTests/EvaluationTests/RevocationTests.m
Security-59306.101.1.tar.gz
[apple/security.git] / tests / TrustTests / EvaluationTests / RevocationTests.m
1 /*
2 * Copyright (c) 2006-2019 Apple Inc. All Rights Reserved.
3 */
4
5 #include <AssertMacros.h>
6 #import <XCTest/XCTest.h>
7 #include <CoreFoundation/CoreFoundation.h>
8 #include <Security/SecCertificate.h>
9 #include <Security/SecCertificatePriv.h>
10 #include <Security/SecPolicyPriv.h>
11 #include <Security/SecTrustPriv.h>
12 #include <utilities/array_size.h>
13 #include <utilities/SecCFRelease.h>
14 #include "trust/trustd/SecOCSPCache.h"
15
16 #import "../TestMacroConversions.h"
17 #import "../TrustEvaluationTestHelpers.h"
18 #import "TrustEvaluationTestCase.h"
19
20 #include "RevocationTests_data.h"
21
22 @interface RevocationTests : TrustEvaluationTestCase
23 @end
24
25 @implementation RevocationTests
26
27 - (void)setUp
28 {
29 // Delete the OCSP cache between each test
30 [super setUp];
31 SecOCSPCacheDeleteContent(nil);
32 }
33
34 #if !TARGET_OS_WATCH && !TARGET_OS_BRIDGE
35 /* watchOS and bridgeOS don't support networking in trustd */
36 - (void)testRevocation
37 {
38 if (!ping_host("ocsp.digicert.com")) {
39 XCTAssert(false, "Unable to contact required network resource");
40 return;
41 }
42
43 SecTrustRef trust;
44 SecCertificateRef cert0, cert1;
45 isnt(cert0 = SecCertificateCreateWithBytes(NULL, _ocsp_c0, sizeof(_ocsp_c0)),
46 NULL, "create cert0");
47 isnt(cert1 = SecCertificateCreateWithBytes(NULL, _ocsp_c1, sizeof(_ocsp_c1)),
48 NULL, "create cert1");
49 CFMutableArrayRef certs = CFArrayCreateMutable(kCFAllocatorDefault, 0,
50 &kCFTypeArrayCallBacks);
51 CFArrayAppendValue(certs, cert0);
52 CFArrayAppendValue(certs, cert1);
53
54 SecPolicyRef sslPolicy = SecPolicyCreateSSL(true, CFSTR("www.apple.com"));
55 SecPolicyRef ocspPolicy = SecPolicyCreateRevocation(kSecRevocationOCSPMethod);
56 const void *v_policies[] = { sslPolicy, ocspPolicy };
57 CFArrayRef policies = CFArrayCreate(NULL, v_policies,
58 array_size(v_policies), &kCFTypeArrayCallBacks);
59 CFRelease(sslPolicy);
60 CFRelease(ocspPolicy);
61 ok_status(SecTrustCreateWithCertificates(certs, policies, &trust),
62 "create trust");
63 /* April 14, 2019 at 10:46:40 PM PDT */
64 CFDateRef date = CFDateCreate(NULL, 577000000.0);
65 ok_status(SecTrustSetVerifyDate(trust, date), "set date");
66
67 is(SecTrustGetVerifyTime(trust), 577000000.0, "get date");
68
69 SecTrustResultType trustResult;
70 ok_status(SecTrustGetTrustResult(trust, &trustResult), "evaluate trust");
71 is_status(trustResult, kSecTrustResultUnspecified,
72 "trust is kSecTrustResultUnspecified");
73
74 /* Certificates are only EV if they are also CT. */
75 CFDictionaryRef info = SecTrustCopyInfo(trust);
76 CFBooleanRef ev = (CFBooleanRef)CFDictionaryGetValue(info,
77 kSecTrustInfoExtendedValidationKey);
78 ok(ev, "extended validation succeeded");
79
80 CFReleaseSafe(info);
81 CFReleaseSafe(trust);
82 CFReleaseSafe(policies);
83 CFReleaseSafe(certs);
84 CFReleaseSafe(cert0);
85 CFReleaseSafe(cert1);
86 CFReleaseSafe(date);
87 }
88
89 - (void) test_ocsp_responder_policy
90 {
91 SecCertificateRef leaf = NULL, subCA = NULL, responderCert = NULL;
92 CFMutableArrayRef certs = CFArrayCreateMutable(kCFAllocatorDefault, 0,
93 &kCFTypeArrayCallBacks);
94 SecTrustRef trust = NULL;
95 SecPolicyRef ocspSignerPolicy = NULL;
96 SecTrustResultType trustResult = kSecTrustResultInvalid;
97
98 /* August 14, 2018 at 9:26:40 PM PDT */
99 CFDateRef date = CFDateCreate(NULL, 556000000.0);
100
101 isnt(leaf = SecCertificateCreateWithBytes(NULL, valid_ist_certificate,
102 sizeof(valid_ist_certificate)), NULL, "create ist leaf");
103 isnt(subCA = SecCertificateCreateWithBytes(NULL, ist_intermediate_certificate,
104 sizeof(ist_intermediate_certificate)), NULL, "create ist subCA");
105 CFArrayAppendValue(certs, leaf);
106 CFArrayAppendValue(certs, subCA);
107
108 ok(ocspSignerPolicy = SecPolicyCreateOCSPSigner(),
109 "create ocspSigner policy");
110
111 ok_status(SecTrustCreateWithCertificates(certs, ocspSignerPolicy, &trust),
112 "create trust for c0 -> c1");
113 ok_status(SecTrustSetVerifyDate(trust, date), "set date");
114 ok_status(SecTrustGetTrustResult(trust, &trustResult), "evaluate trust");
115 is_status(trustResult, kSecTrustResultRecoverableTrustFailure,
116 "trust is kSecTrustResultRecoverableTrustFailure");
117
118 isnt(responderCert = SecCertificateCreateWithBytes(NULL, _responderCert,
119 sizeof(_responderCert)), NULL, "create responderCert");
120 CFArraySetValueAtIndex(certs, 0, responderCert);
121 ok_status(SecTrustCreateWithCertificates(certs, ocspSignerPolicy, &trust),
122 "create trust for ocspResponder -> c1");
123 ok_status(SecTrustSetVerifyDate(trust, date), "set date");
124 ok_status(SecTrustGetTrustResult(trust, &trustResult), "evaluate trust");
125 is_status(trustResult, kSecTrustResultUnspecified,
126 "trust is kSecTrustResultUnspecified");
127
128 CFReleaseNull(leaf);
129 CFReleaseNull(subCA);
130 CFReleaseNull(responderCert);
131 CFReleaseNull(certs);
132 CFReleaseNull(trust);
133 CFReleaseSafe(ocspSignerPolicy);
134 CFReleaseNull(date);
135 }
136
137 - (void)test_always_honor_cached_revoked_responses {
138 if (!ping_host("ocsp.apple.com")) {
139 XCTAssert(false, "Unable to contact required network resource");
140 return;
141 }
142
143 SecTrustRef trust;
144 SecCertificateRef rcert0, rcert1;
145 isnt(rcert0 = SecCertificateCreateWithBytes(NULL,
146 revoked_ist_certificate, sizeof(revoked_ist_certificate)),
147 NULL, "create rcert0");
148 isnt(rcert1 = SecCertificateCreateWithBytes(NULL,
149 ist_intermediate_certificate, sizeof(ist_intermediate_certificate)),
150 NULL, "create rcert1");
151 CFMutableArrayRef rcerts = CFArrayCreateMutable(kCFAllocatorDefault, 0,
152 &kCFTypeArrayCallBacks);
153 CFArrayAppendValue(rcerts, rcert0);
154 CFArrayAppendValue(rcerts, rcert1);
155
156 SecPolicyRef sslPolicy = SecPolicyCreateSSL(true, CFSTR("revoked.geotrust-global-ca.test-pages.certificatemanager.apple.com"));
157 SecPolicyRef ocspPolicy = SecPolicyCreateRevocation(kSecRevocationOCSPMethod);
158 const void *v_policies[] = { sslPolicy, ocspPolicy };
159 CFArrayRef policies = CFArrayCreate(NULL, v_policies,
160 array_size(v_policies), &kCFTypeArrayCallBacks);
161 CFRelease(sslPolicy);
162 CFRelease(ocspPolicy);
163 ok_status(SecTrustCreateWithCertificates(rcerts, policies, &trust),
164 "create trust");
165 /* Feb 5th 2015. */
166 CFDateRef date = CFDateCreate(NULL, 444900000);
167 ok_status(SecTrustSetVerifyDate(trust, date), "set date");
168 CFReleaseSafe(date);
169
170 is(SecTrustGetVerifyTime(trust), 444900000, "get date");
171
172 SecTrustResultType trustResult;
173 ok_status(SecTrustGetTrustResult(trust, &trustResult), "evaluate trust");
174 is(trustResult, kSecTrustResultFatalTrustFailure);
175 CFDictionaryRef results = SecTrustCopyResult(trust);
176 CFTypeRef revoked = NULL;
177 if (results) {
178 CFArrayRef perCertResults = CFDictionaryGetValue(results, CFSTR("TrustResultDetails"));
179 if (perCertResults) {
180 CFDictionaryRef leafResults = CFArrayGetValueAtIndex(perCertResults, 0);
181 if (leafResults) {
182 revoked = CFDictionaryGetValue(leafResults, CFSTR("Revocation"));
183 }
184 }
185 }
186 is(revoked != NULL, true, "revoked result is %@", revoked);
187 CFReleaseSafe(results);
188
189
190 /* Now verify the cert at a date in the past relative to the previous
191 date, but still within the cert's validity period. Although the
192 cached response from our prior attempt will appear to have been
193 produced in the future, it should still be honored since it's
194 validly signed.
195 */
196 /* Dec 11th 2014. */
197 date = CFDateCreate(NULL, 440000000);
198 ok_status(SecTrustSetVerifyDate(trust, date), "set date");
199 CFReleaseSafe(date);
200
201 is(SecTrustGetVerifyTime(trust), 440000000, "get date");
202
203 ok_status(SecTrustGetTrustResult(trust, &trustResult), "evaluate trust");
204 is(trustResult, kSecTrustResultFatalTrustFailure);
205 results = SecTrustCopyResult(trust);
206 revoked = NULL;
207 if (results) {
208 CFArrayRef perCertResults = CFDictionaryGetValue(results, CFSTR("TrustResultDetails"));
209 if (perCertResults) {
210 CFDictionaryRef leafResults = CFArrayGetValueAtIndex(perCertResults, 0);
211 if (leafResults) {
212 revoked = CFDictionaryGetValue(leafResults, CFSTR("Revocation"));
213 }
214 }
215 }
216 is(revoked != NULL, true, "revoked result is %@", revoked);
217 CFReleaseSafe(results);
218
219 CFReleaseSafe(trust);
220 CFReleaseSafe(policies);
221 CFReleaseSafe(rcerts);
222 CFReleaseSafe(rcert0);
223 CFReleaseSafe(rcert1);
224 }
225
226 - (void) test_require_positive_response
227 {
228 if (!ping_host("ocsp.apple.com")) {
229 XCTAssert(false, "Unable to contact required network resource");
230 return;
231 }
232
233 SecCertificateRef leaf = NULL, subCA = NULL, root = NULL;
234 SecPolicyRef policy = NULL, revocationPolicy = NULL;
235 SecTrustRef trust = NULL;
236 CFArrayRef certs = NULL, anchors = NULL;
237 CFDateRef verifyDate = NULL;
238 CFErrorRef error = NULL;
239
240 leaf = SecCertificateCreateWithBytes(NULL, _probablyNotRevokedLeaf, sizeof(_probablyNotRevokedLeaf));
241 subCA = SecCertificateCreateWithBytes(NULL, _devIDCA, sizeof(_devIDCA));
242 root = SecCertificateCreateWithBytes(NULL, _appleRoot, sizeof(_appleRoot));
243
244 const void *v_certs[] = { leaf, subCA };
245 const void *v_anchors[] = { root };
246
247 certs = CFArrayCreate(NULL, v_certs, 2, &kCFTypeArrayCallBacks);
248 policy = SecPolicyCreateAppleExternalDeveloper();
249 revocationPolicy = SecPolicyCreateRevocation(kSecRevocationRequirePositiveResponse | kSecRevocationOCSPMethod);
250 NSArray *policies = @[ (__bridge id)policy, (__bridge id)revocationPolicy ];
251 require_noerr_action(SecTrustCreateWithCertificates(certs, (__bridge CFArrayRef)policies, &trust), errOut,
252 fail("failed to create trust object"));
253
254 anchors = CFArrayCreate(NULL, v_anchors, 1, &kCFTypeArrayCallBacks);
255 require_noerr_action(SecTrustSetAnchorCertificates(trust, anchors), errOut, fail("failed to set anchors"));
256
257 verifyDate = CFDateCreate(NULL, 543000000.0); // March 17, 2018 at 10:20:00 AM PDT
258 require_noerr_action(SecTrustSetVerifyDate(trust, verifyDate), errOut, fail("failed to set verify date"));
259
260 /* Set no fetch allowed */
261 require_noerr_action(SecTrustSetNetworkFetchAllowed(trust, false), errOut, fail("failed to set network fetch disallowed"));
262
263 /* Evaluate trust. Since we required a response but disabled networking, should fail. */
264 is(SecTrustEvaluateWithError(trust, &error), false, "non-definitive revoked cert without network failed");
265 if (error) {
266 is(CFErrorGetCode(error), errSecIncompleteCertRevocationCheck, "got wrong error code for revoked cert, got %ld, expected %d",
267 (long)CFErrorGetCode(error), errSecIncompleteCertRevocationCheck);
268 } else {
269 fail("expected trust evaluation to fail and it did not.");
270 }
271 CFReleaseNull(error);
272
273 /* Set fetch allowed */
274 require_noerr_action(SecTrustSetNetworkFetchAllowed(trust, true), errOut, fail("failed to set network fetch allowed"));
275
276 /* Evaluate trust. We should re-do the evaluation and get a revoked failure from the OCSP check. */
277 is(SecTrustEvaluateWithError(trust, &error), false, "revoked cert with network succeeded");
278 if (error) {
279 is(CFErrorGetCode(error), errSecCertificateRevoked, "got wrong error code for revoked cert, got %ld, expected %d",
280 (long)CFErrorGetCode(error), errSecCertificateRevoked);
281 } else {
282 fail("expected trust evaluation to fail and it did not.");
283 }
284
285 errOut:
286 CFReleaseNull(leaf);
287 CFReleaseNull(subCA);
288 CFReleaseNull(root);
289 CFReleaseNull(policy);
290 CFReleaseNull(trust);
291 CFReleaseNull(certs);
292 CFReleaseNull(anchors);
293 CFReleaseNull(verifyDate);
294 CFReleaseNull(error);
295 }
296
297 - (void) test_set_fetch_allowed {
298 if (!ping_host("ocsp.apple.com")) {
299 XCTAssert(false, "Unable to contact required network resource");
300 return;
301 }
302
303 SecCertificateRef leaf = NULL, subCA = NULL, root = NULL;
304 SecPolicyRef policy = NULL;
305 SecTrustRef trust = NULL;
306 CFArrayRef certs = NULL, anchors = NULL;
307 CFDateRef verifyDate = NULL;
308 CFErrorRef error = NULL;
309
310 leaf = SecCertificateCreateWithBytes(NULL, _probablyNotRevokedLeaf, sizeof(_probablyNotRevokedLeaf));
311 subCA = SecCertificateCreateWithBytes(NULL, _devIDCA, sizeof(_devIDCA));
312 root = SecCertificateCreateWithBytes(NULL, _appleRoot, sizeof(_appleRoot));
313
314 const void *v_certs[] = { leaf, subCA };
315 const void *v_anchors[] = { root };
316
317 certs = CFArrayCreate(NULL, v_certs, 2, &kCFTypeArrayCallBacks);
318 policy = SecPolicyCreateAppleExternalDeveloper();
319 require_noerr_action(SecTrustCreateWithCertificates(certs, policy, &trust), errOut, fail("failed to create trust object"));
320
321 anchors = CFArrayCreate(NULL, v_anchors, 1, &kCFTypeArrayCallBacks);
322 require_noerr_action(SecTrustSetAnchorCertificates(trust, anchors), errOut, fail("failed to set anchors"));
323
324 verifyDate = CFDateCreate(NULL, 543000000.0); // March 17, 2018 at 10:20:00 AM PDT
325 require_noerr_action(SecTrustSetVerifyDate(trust, verifyDate), errOut, fail("failed to set verify date"));
326
327 /* Set no fetch allowed */
328 require_noerr_action(SecTrustSetNetworkFetchAllowed(trust, false), errOut, fail("failed to set network fetch disallowed"));
329
330 /* Evaluate trust. This cert is revoked, but is only listed as "probably not revoked" by valid.apple.com.
331 * Since network fetch is not allowed and we fail open, this cert should come back as trusted. */
332 ok(SecTrustEvaluateWithError(trust, &error), "non-definitive revoked cert without network failed");
333 CFReleaseNull(error);
334
335 /* Set fetch allowed */
336 require_noerr_action(SecTrustSetNetworkFetchAllowed(trust, true), errOut, fail("failed to set network fetch allowed"));
337
338 /* Evaluate trust. SetFetchAllowed should have reset the trust result, so now we should re-do the evaluation and get a revoked failure. */
339 is(SecTrustEvaluateWithError(trust, &error), false, "revoked cert with network succeeded");
340 if (error) {
341 is(CFErrorGetCode(error), errSecCertificateRevoked, "got wrong error code for revoked cert, got %ld, expected %d",
342 (long)CFErrorGetCode(error), errSecCertificateRevoked);
343 } else {
344 fail("expected trust evaluation to fail and it did not.");
345 }
346
347 errOut:
348 CFReleaseNull(leaf);
349 CFReleaseNull(subCA);
350 CFReleaseNull(root);
351 CFReleaseNull(policy);
352 CFReleaseNull(trust);
353 CFReleaseNull(certs);
354 CFReleaseNull(anchors);
355 CFReleaseNull(verifyDate);
356 CFReleaseNull(error);
357 }
358
359 - (void) test_check_if_trusted {
360 if (!ping_host("ocsp.apple.com")) {
361 XCTAssert(false, "Unable to contact required network resource");
362 return;
363 }
364
365 SecCertificateRef leaf = NULL, subCA = NULL, root = NULL;
366 SecPolicyRef codesigningPolicy = NULL, revocationPolicy = NULL;
367 SecTrustRef trust = NULL;
368 CFArrayRef certs = NULL, anchors = NULL, policies = NULL;
369 CFDateRef verifyDate = NULL, badVerifyDate = NULL;
370 CFErrorRef error = NULL;
371
372 leaf = SecCertificateCreateWithBytes(NULL, _probablyNotRevokedLeaf, sizeof(_probablyNotRevokedLeaf));
373 subCA = SecCertificateCreateWithBytes(NULL, _devIDCA, sizeof(_devIDCA));
374 root = SecCertificateCreateWithBytes(NULL, _appleRoot, sizeof(_appleRoot));
375
376 codesigningPolicy = SecPolicyCreateAppleExternalDeveloper();
377 revocationPolicy = SecPolicyCreateRevocation(kSecRevocationCheckIfTrusted);
378
379 const void *v_certs[] = { leaf, subCA };
380 const void *v_anchors[] = { root };
381 const void *v_policies[] = { codesigningPolicy, revocationPolicy };
382
383 certs = CFArrayCreate(NULL, v_certs, 2, &kCFTypeArrayCallBacks);
384 policies = CFArrayCreate(NULL, v_policies, 2, &kCFTypeArrayCallBacks);
385 require_noerr_action(SecTrustCreateWithCertificates(certs, policies, &trust), errOut, fail("failed to create trust object"));
386
387 anchors = CFArrayCreate(NULL, v_anchors, 1, &kCFTypeArrayCallBacks);
388 require_noerr_action(SecTrustSetAnchorCertificates(trust, anchors), errOut, fail("failed to set anchors"));
389 badVerifyDate = CFDateCreate(NULL, 490000000.0); // July 12, 2016 at 12:06:40 AM PDT (before cert issued)
390 require_noerr_action(SecTrustSetVerifyDate(trust, badVerifyDate), errOut, fail("failed to set verify date"));
391
392 /* Set no fetch allowed */
393 require_noerr_action(SecTrustSetNetworkFetchAllowed(trust, false), errOut, fail("failed to set network fetch disallowed"));
394
395 /* Evaluate trust. This cert is revoked, but is only listed as "probably not revoked" by valid.apple.com.
396 * Since we are evaluating it at a time before it was issued, it should come back as untrusted
397 * due to the temporal validity failure, but not due to revocation since we couldn't check for this
398 * untrusted chain. */
399 is(SecTrustEvaluateWithError(trust, &error), false, "not yet valid cert succeeded trust evaluation");
400 if (error) {
401 is(CFErrorGetCode(error), errSecCertificateExpired, "got wrong error code for expired cert");
402 } else {
403 fail("expected trust evaluation to fail and it did not.");
404 }
405 CFReleaseNull(error);
406
407 /* Set verify date within validity period */
408 verifyDate = CFDateCreate(NULL, 543000000.0); // March 17, 2018 at 10:20:00 AM PDT
409 require_noerr_action(SecTrustSetVerifyDate(trust, verifyDate), errOut, fail("failed to set verify date"));
410
411 /* Evaluate trust. Now that we trust the chain, we should do a revocation check and get a revocation failure. */
412 is(SecTrustEvaluateWithError(trust, &error), false, "revoked cert with network succeeded");
413 if (error) {
414 is(CFErrorGetCode(error), errSecCertificateRevoked, "got wrong error code for revoked cert, got %ld, expected %d",
415 (long)CFErrorGetCode(error), errSecCertificateRevoked);
416 } else {
417 fail("expected trust evaluation to fail and it did not.");
418 }
419
420 errOut:
421 CFReleaseNull(leaf);
422 CFReleaseNull(subCA);
423 CFReleaseNull(root);
424 CFReleaseNull(codesigningPolicy);
425 CFReleaseNull(revocationPolicy);
426 CFReleaseNull(trust);
427 CFReleaseNull(certs);
428 CFReleaseNull(anchors);
429 CFReleaseNull(policies);
430 CFReleaseNull(verifyDate);
431 CFReleaseNull(badVerifyDate);
432 CFReleaseNull(error);
433 }
434
435 - (void) test_cache {
436 if (!ping_host("ocsp.apple.com")) {
437 XCTAssert(false, "Unable to contact required network resource");
438 return;
439 }
440
441 SecCertificateRef leaf = NULL, subCA = NULL, root = NULL;
442 SecPolicyRef policy = NULL;
443 SecTrustRef trust = NULL;
444 CFArrayRef certs = NULL, anchors = NULL;
445 CFDateRef verifyDate = NULL;
446 CFErrorRef error = NULL;
447
448 leaf = SecCertificateCreateWithBytes(NULL, _probablyNotRevokedLeaf, sizeof(_probablyNotRevokedLeaf));
449 subCA = SecCertificateCreateWithBytes(NULL, _devIDCA, sizeof(_devIDCA));
450 root = SecCertificateCreateWithBytes(NULL, _appleRoot, sizeof(_appleRoot));
451
452 const void *v_certs[] = { leaf, subCA };
453 const void *v_anchors[] = { root };
454
455 certs = CFArrayCreate(NULL, v_certs, 2, &kCFTypeArrayCallBacks);
456 policy = SecPolicyCreateAppleExternalDeveloper();
457 require_noerr_action(SecTrustCreateWithCertificates(certs, policy, &trust), errOut, fail("failed to create trust object"));
458
459 anchors = CFArrayCreate(NULL, v_anchors, 1, &kCFTypeArrayCallBacks);
460 require_noerr_action(SecTrustSetAnchorCertificates(trust, anchors), errOut, fail("failed to set anchors"));
461
462 verifyDate = CFDateCreate(NULL, 543000000.0); // March 17, 2018 at 10:20:00 AM PDT
463 require_noerr_action(SecTrustSetVerifyDate(trust, verifyDate), errOut, fail("failed to set verify date"));
464
465 /* Evaluate trust. This cert is revoked, but is only listed as "probably not revoked" by valid.apple.com.
466 * This cert should come back as revoked after a network-based fetch. */
467 is(SecTrustEvaluateWithError(trust, &error), false, "revoked cert with network succeeded");
468 if (error) {
469 is(CFErrorGetCode(error), errSecCertificateRevoked, "got wrong error code for revoked cert, got %ld, expected %d",
470 (long)CFErrorGetCode(error), errSecCertificateRevoked);
471 } else {
472 fail("expected trust evaluation to fail and it did not.");
473 }
474
475 /* Set no fetch allowed, so we're relying on the cached response from above */
476 require_noerr_action(SecTrustSetNetworkFetchAllowed(trust, false), errOut, fail("failed to set network fetch disallowed"));
477
478 /* Evaluate trust. Cached response should tell us that it's revoked. */
479 is(SecTrustEvaluateWithError(trust, &error), false, "revoked cert with cached response succeeded");
480 if (error) {
481 is(CFErrorGetCode(error), errSecCertificateRevoked, "got wrong error code for revoked cert, got %ld, expected %d",
482 (long)CFErrorGetCode(error), errSecCertificateRevoked);
483 } else {
484 fail("expected trust evaluation to fail and it did not.");
485 }
486
487 errOut:
488 CFReleaseNull(leaf);
489 CFReleaseNull(subCA);
490 CFReleaseNull(root);
491 CFReleaseNull(policy);
492 CFReleaseNull(trust);
493 CFReleaseNull(certs);
494 CFReleaseNull(anchors);
495 CFReleaseNull(verifyDate);
496 CFReleaseNull(error);
497 }
498
499 - (void)test_revoked_responses_not_flushed_from_cache
500 {
501 if (!ping_host("ocsp.apple.com")) {
502 XCTAssert(false, "Unable to contact required network resource");
503 return;
504 }
505
506 SecCertificateRef leaf = NULL, subCA = NULL, root = NULL;
507 SecPolicyRef policy = NULL;
508 SecTrustRef trust = NULL;
509 CFArrayRef certs = NULL, anchors = NULL;
510 CFDateRef verifyDate = NULL;
511 CFErrorRef error = NULL;
512
513 leaf = SecCertificateCreateWithBytes(NULL, _probablyNotRevokedLeaf, sizeof(_probablyNotRevokedLeaf));
514 subCA = SecCertificateCreateWithBytes(NULL, _devIDCA, sizeof(_devIDCA));
515 root = SecCertificateCreateWithBytes(NULL, _appleRoot, sizeof(_appleRoot));
516
517 const void *v_certs[] = { leaf, subCA };
518 const void *v_anchors[] = { root };
519
520 certs = CFArrayCreate(NULL, v_certs, 2, &kCFTypeArrayCallBacks);
521 policy = SecPolicyCreateAppleExternalDeveloper();
522 require_noerr_action(SecTrustCreateWithCertificates(certs, policy, &trust), errOut, fail("failed to create trust object"));
523
524 anchors = CFArrayCreate(NULL, v_anchors, 1, &kCFTypeArrayCallBacks);
525 require_noerr_action(SecTrustSetAnchorCertificates(trust, anchors), errOut, fail("failed to set anchors"));
526
527 verifyDate = CFDateCreate(NULL, 543000000.0); // March 17, 2018 at 10:20:00 AM PDT
528 require_noerr_action(SecTrustSetVerifyDate(trust, verifyDate), errOut, fail("failed to set verify date"));
529
530 /* Evaluate trust. This cert is revoked, but is only listed as "probably not revoked" by valid.apple.com.
531 * This cert should come back as revoked after a network-based fetch. */
532 is(SecTrustEvaluateWithError(trust, &error), false, "revoked cert with network succeeded");
533 if (error) {
534 is(CFErrorGetCode(error), errSecCertificateRevoked, "got wrong error code for revoked cert, got %ld, expected %d",
535 (long)CFErrorGetCode(error), errSecCertificateRevoked);
536 } else {
537 fail("expected trust evaluation to fail and it did not.");
538 }
539
540 /* Set no fetch allowed, so we're relying on the cached response from above */
541 require_noerr_action(SecTrustSetNetworkFetchAllowed(trust, false), errOut, fail("failed to set network fetch disallowed"));
542
543 /* Evaluate trust. Cached response should tell us that it's revoked. */
544 is(SecTrustEvaluateWithError(trust, &error), false, "revoked cert with cached response succeeded");
545 if (error) {
546 is(CFErrorGetCode(error), errSecCertificateRevoked, "got wrong error code for revoked cert, got %ld, expected %d",
547 (long)CFErrorGetCode(error), errSecCertificateRevoked);
548 } else {
549 fail("expected trust evaluation to fail and it did not.");
550 }
551
552 /* flush the cache and reset the turst, the revoked response should still be present afterwards */
553 XCTAssert(SecTrustFlushResponseCache(NULL));
554 SecTrustSetNeedsEvaluation(trust);
555
556 is(SecTrustEvaluateWithError(trust, &error), false, "revoked cert with cached response succeeded");
557 if (error) {
558 is(CFErrorGetCode(error), errSecCertificateRevoked, "got wrong error code for revoked cert, got %ld, expected %d",
559 (long)CFErrorGetCode(error), errSecCertificateRevoked);
560 } else {
561 fail("expected trust evaluation to fail and it did not.");
562 }
563
564 errOut:
565 CFReleaseNull(leaf);
566 CFReleaseNull(subCA);
567 CFReleaseNull(root);
568 CFReleaseNull(policy);
569 CFReleaseNull(trust);
570 CFReleaseNull(certs);
571 CFReleaseNull(anchors);
572 CFReleaseNull(verifyDate);
573 CFReleaseNull(error);
574 }
575
576 - (void) test_results_dictionary_revocation_checked {
577 if (!ping_host("ocsp.digicert.com")) {
578 XCTAssert(false, "Unable to contact required network resource");
579 return;
580 }
581
582 SecCertificateRef leaf = NULL, subCA = NULL, root = NULL;
583 SecPolicyRef sslPolicy = NULL, ocspPolicy = NULL;
584 SecTrustRef trust = NULL;
585 CFArrayRef certs = NULL, anchors = NULL, policies = NULL;
586 CFDateRef verifyDate = NULL;
587 CFErrorRef error = NULL;
588
589 leaf = SecCertificateCreateWithBytes(NULL, _ocsp_c0, sizeof(_ocsp_c0));
590 subCA = SecCertificateCreateWithBytes(NULL, _ocsp_c1, sizeof(_ocsp_c1));
591 root = SecCertificateCreateWithBytes(NULL, _ocsp_c2, sizeof(_ocsp_c2));
592
593 sslPolicy = SecPolicyCreateSSL(true, CFSTR("www.apple.com"));
594 ocspPolicy = SecPolicyCreateRevocation(kSecRevocationOCSPMethod);
595
596 const void *v_certs[] = { leaf, subCA };
597 const void *v_anchors[] = { root };
598 const void *v_policies[] = { sslPolicy, ocspPolicy };
599
600 certs = CFArrayCreate(NULL, v_certs, 2, &kCFTypeArrayCallBacks);
601 policies = CFArrayCreate(NULL, v_policies, 2, &kCFTypeArrayCallBacks);
602 require_noerr_action(SecTrustCreateWithCertificates(certs, policies, &trust), errOut, fail("failed to create trust object"));
603
604 anchors = CFArrayCreate(NULL, v_anchors, 1, &kCFTypeArrayCallBacks);
605 require_noerr_action(SecTrustSetAnchorCertificates(trust, anchors), errOut, fail("failed to set anchors"));
606
607 verifyDate = CFDateCreate(NULL, 577000000.0); // April 14, 2019 at 10:46:40 PM PDT
608 require_noerr_action(SecTrustSetVerifyDate(trust, verifyDate), errOut, fail("failed to set verify date"));
609
610 is(SecTrustEvaluateWithError(trust, &error), true, "valid cert failed");
611
612 /* Verify that the results dictionary contains all the right keys for a valid cert where revocation checked */
613 CFDictionaryRef result = SecTrustCopyResult(trust);
614 isnt(result, NULL, "failed to copy result dictionary");
615 if (result) {
616 is(CFDictionaryGetValue(result, kSecTrustRevocationChecked), kCFBooleanTrue, "expected revocation checked flag");
617 CFDateRef validUntil = CFDictionaryGetValue(result, kSecTrustRevocationValidUntilDate);
618 isnt(validUntil, NULL, "expected revocation valid until date");
619 if (validUntil) {
620 ok(CFDateGetAbsoluteTime(validUntil) > CFAbsoluteTimeGetCurrent(), "expected valid until date in the future");
621 } else {
622 fail("did not get valid until date");
623 }
624 }
625 CFReleaseNull(result);
626
627 errOut:
628 CFReleaseNull(leaf);
629 CFReleaseNull(subCA);
630 CFReleaseNull(root);
631 CFReleaseNull(ocspPolicy);
632 CFReleaseNull(sslPolicy);
633 CFReleaseNull(trust);
634 CFReleaseNull(certs);
635 CFReleaseNull(anchors);
636 CFReleaseNull(policies);
637 CFReleaseNull(verifyDate);
638 CFReleaseNull(error);
639 }
640
641 - (void) test_revocation_checked_via_cache {
642 if (!ping_host("ocsp.digicert.com")) {
643 XCTAssert(false, "Unable to contact required network resource");
644 return;
645 }
646
647 SecCertificateRef leaf = NULL, subCA = NULL, root = NULL;
648 SecPolicyRef sslPolicy = NULL, ocspPolicy = NULL;
649 SecTrustRef trust = NULL;
650 CFArrayRef certs = NULL, anchors = NULL, policies = NULL;
651 CFDateRef verifyDate = NULL;
652 CFErrorRef error = NULL;
653
654 leaf = SecCertificateCreateWithBytes(NULL, _ocsp_c0, sizeof(_ocsp_c0));
655 subCA = SecCertificateCreateWithBytes(NULL, _ocsp_c1, sizeof(_ocsp_c1));
656 root = SecCertificateCreateWithBytes(NULL, _ocsp_c2, sizeof(_ocsp_c2));
657
658 sslPolicy = SecPolicyCreateSSL(true, CFSTR("www.apple.com"));
659 ocspPolicy = SecPolicyCreateRevocation(kSecRevocationOCSPMethod);
660
661 const void *v_certs[] = { leaf, subCA };
662 const void *v_anchors[] = { root };
663 const void *v_policies[] = { sslPolicy, ocspPolicy };
664
665 certs = CFArrayCreate(NULL, v_certs, 2, &kCFTypeArrayCallBacks);
666 policies = CFArrayCreate(NULL, v_policies, 2, &kCFTypeArrayCallBacks);
667 require_noerr_action(SecTrustCreateWithCertificates(certs, policies, &trust), errOut, fail("failed to create trust object"));
668
669 anchors = CFArrayCreate(NULL, v_anchors, 1, &kCFTypeArrayCallBacks);
670 require_noerr_action(SecTrustSetAnchorCertificates(trust, anchors), errOut, fail("failed to set anchors"));
671
672 verifyDate = CFDateCreate(NULL, 577000000.0); // April 14, 2019 at 10:46:40 PM PDT
673 require_noerr_action(SecTrustSetVerifyDate(trust, verifyDate), errOut, fail("failed to set verify date"));
674
675 is(SecTrustEvaluateWithError(trust, &error), true, "valid cert failed");
676
677 /* Set no fetch allowed, so we're relying on the cached response from above */
678 require_noerr_action(SecTrustSetNetworkFetchAllowed(trust, false), errOut, fail("failed to set network fetch disallowed"));
679
680 /* Evaluate trust. Cached response should tell us that it's revoked. */
681 is(SecTrustEvaluateWithError(trust, &error), true, "valid cert failed");
682
683 /* Verify that the results dictionary contains the kSecTrustRevocationChecked key for a valid cert where revocation checked */
684 CFDictionaryRef result = SecTrustCopyResult(trust);
685 isnt(result, NULL, "failed to copy result dictionary");
686 if (result) {
687 is(CFDictionaryGetValue(result, kSecTrustRevocationChecked), kCFBooleanTrue, "expected revocation checked flag");
688 }
689 CFReleaseNull(result);
690
691 errOut:
692 CFReleaseNull(leaf);
693 CFReleaseNull(subCA);
694 CFReleaseNull(root);
695 CFReleaseNull(ocspPolicy);
696 CFReleaseNull(sslPolicy);
697 CFReleaseNull(trust);
698 CFReleaseNull(certs);
699 CFReleaseNull(anchors);
700 CFReleaseNull(policies);
701 CFReleaseNull(verifyDate);
702 CFReleaseNull(error);
703 }
704
705 #else /* TARGET_OS_WATCH || TARGET_OS_BRIDGE */
706 - (void)testNoNetworking
707 {
708 SecCertificateRef leaf = NULL, subCA = NULL, root = NULL;
709 SecPolicyRef policy = NULL;
710 SecTrustRef trust = NULL;
711 CFArrayRef certs = NULL, anchors = NULL;
712 CFDateRef verifyDate = NULL;
713 CFErrorRef error = NULL;
714
715 leaf = SecCertificateCreateWithBytes(NULL, _probablyNotRevokedLeaf, sizeof(_probablyNotRevokedLeaf));
716 subCA = SecCertificateCreateWithBytes(NULL, _devIDCA, sizeof(_devIDCA));
717 root = SecCertificateCreateWithBytes(NULL, _appleRoot, sizeof(_appleRoot));
718
719 const void *v_certs[] = { leaf, subCA };
720 const void *v_anchors[] = { root };
721
722 certs = CFArrayCreate(NULL, v_certs, 2, &kCFTypeArrayCallBacks);
723 policy = SecPolicyCreateAppleExternalDeveloper();
724 require_noerr_action(SecTrustCreateWithCertificates(certs, policy, &trust), errOut, fail("failed to create trust object"));
725
726 anchors = CFArrayCreate(NULL, v_anchors, 1, &kCFTypeArrayCallBacks);
727 require_noerr_action(SecTrustSetAnchorCertificates(trust, anchors), errOut, fail("failed to set anchors"));
728
729 verifyDate = CFDateCreate(NULL, 543000000.0); // March 17, 2018 at 10:20:00 AM PDT
730 require_noerr_action(SecTrustSetVerifyDate(trust, verifyDate), errOut, fail("failed to set verify date"));
731
732 /* Evaluate trust. Since we aren't allowed to do networking (and this cert is only "Probably Not Revoked" in Valid),
733 * we shouldn't see this cert as revoked */
734 is(SecTrustEvaluateWithError(trust, &error), true, "revoked cert with no network failed");
735
736 errOut:
737 CFReleaseNull(leaf);
738 CFReleaseNull(subCA);
739 CFReleaseNull(root);
740 CFReleaseNull(policy);
741 CFReleaseNull(trust);
742 CFReleaseNull(certs);
743 CFReleaseNull(anchors);
744 CFReleaseNull(verifyDate);
745 CFReleaseNull(error);
746 }
747 #endif /* !TARGET_OS_WATCH && !TARGET_OS_BRIDGE */
748
749 #if !TARGET_OS_BRIDGE
750 /* bridgeOS doesn't use Valid */
751 - (NSNumber *)runRevocationCheckNoNetwork:(SecCertificateRef)leaf
752 subCA:(SecCertificateRef)subCA
753 {
754 CFArrayRef anchors = NULL;
755 SecPolicyRef smimePolicy = NULL, revocationPolicy = NULL;
756 CFArrayRef certs = NULL;
757 SecTrustRef trust = NULL;
758 CFDateRef date = NULL;
759 CFErrorRef error = NULL;
760 NSArray *policies = nil;
761 NSDictionary *result = nil;
762 NSNumber *revocationChecked = nil;
763
764 const void *v_certs[] = { leaf };
765 require_action(certs = CFArrayCreate(NULL, v_certs, array_size(v_certs), &kCFTypeArrayCallBacks), errOut,
766 fail("unable to create certificates array"));
767 require_action(anchors = CFArrayCreate(NULL, (const void **)&subCA, 1, &kCFTypeArrayCallBacks), errOut,
768 fail("unable to create anchors array"));
769
770 require_action(smimePolicy = SecPolicyCreateSMIME(kSecSignSMIMEUsage, NULL), errOut, fail("unable to create policy"));
771 revocationPolicy = SecPolicyCreateRevocation(kSecRevocationUseAnyAvailableMethod | kSecRevocationCheckIfTrusted);
772 policies = @[(__bridge id)smimePolicy, (__bridge id)revocationPolicy];
773 ok_status(SecTrustCreateWithCertificates(certs, (__bridge CFArrayRef)policies, &trust), "failed to create trust");
774 ok_status(SecTrustSetNetworkFetchAllowed(trust, false), "SecTrustSetNetworkFetchAllowed failed");
775
776 require_noerr_action(SecTrustSetAnchorCertificates(trust, anchors), errOut,
777 fail("unable to set anchors"));
778 ok(SecTrustEvaluateWithError(trust, &error), "Not trusted");
779 result = CFBridgingRelease(SecTrustCopyResult(trust));
780 revocationChecked = result[(__bridge NSString *)kSecTrustRevocationChecked];
781
782 errOut:
783 CFReleaseNull(anchors);
784 CFReleaseNull(smimePolicy);
785 CFReleaseNull(revocationPolicy);
786 CFReleaseNull(certs);
787 CFReleaseNull(trust);
788 CFReleaseNull(date);
789 CFReleaseNull(error);
790
791 return revocationChecked;
792 }
793
794 - (void) test_revocation_checked_via_valid {
795 SecCertificateRef leaf = NULL, subCA = NULL;
796 NSNumber *revocationChecked = NULL;
797
798 require_action(leaf = SecCertificateCreateWithBytes(NULL, _leaf_sha256_valid_cav2_complete_ok1, sizeof(_leaf_sha256_valid_cav2_complete_ok1)), errOut,
799 fail("unable to create cert"));
800 require_action(subCA = SecCertificateCreateWithBytes(NULL, _ca_sha256_valid_cav2_complete, sizeof(_ca_sha256_valid_cav2_complete)), errOut, fail("unable to create cert"));
801
802 revocationChecked = [self runRevocationCheckNoNetwork:leaf
803 subCA:subCA];
804 XCTAssert(revocationChecked != NULL, "kSecTrustRevocationChecked is not in the result dictionary");
805
806 errOut:
807 CFReleaseNull(leaf);
808 CFReleaseNull(subCA);
809 }
810
811 - (void) test_revocation_not_checked_no_network {
812 /* The intermediate does not have the noCAv2 flag and is "probably not revoked,", so
813 kSecTrustRevocationChecked should not be in the results dictionary */
814 SecCertificateRef leaf = NULL, subCA = NULL;
815 NSNumber *revocationChecked = NULL;
816
817 require_action(leaf = SecCertificateCreateWithBytes(NULL, _leaf_serial_invalid_incomplete_ok1, sizeof(_leaf_serial_invalid_incomplete_ok1)), errOut,
818 fail("unable to create cert"));
819 require_action(subCA = SecCertificateCreateWithBytes(NULL, _ca_serial_invalid_incomplete, sizeof(_ca_serial_invalid_incomplete)), errOut, fail("unable to create cert"));
820
821 revocationChecked = [self runRevocationCheckNoNetwork:leaf
822 subCA:subCA];
823 XCTAssert(revocationChecked == NULL, "kSecTrustRevocationChecked is in the result dictionary");
824
825 errOut:
826 CFReleaseNull(leaf);
827 CFReleaseNull(subCA);
828 }
829 #endif /* !TARGET_OS_BRIDGE */
830
831 /* bridgeOS and watchOS do not support networked OCSP but do support stapling */
832 - (void) test_stapled_revoked_response {
833 SecCertificateRef leaf = NULL, subCA = NULL, root = NULL;
834 SecPolicyRef policy = NULL;
835 SecTrustRef trust = NULL;
836 CFArrayRef certs = NULL, anchors = NULL;
837 CFDateRef verifyDate = NULL;
838 CFErrorRef error = NULL;
839 CFDataRef ocspResponse = NULL;
840
841 leaf = SecCertificateCreateWithBytes(NULL, _probablyNotRevokedLeaf, sizeof(_probablyNotRevokedLeaf));
842 subCA = SecCertificateCreateWithBytes(NULL, _devIDCA, sizeof(_devIDCA));
843 root = SecCertificateCreateWithBytes(NULL, _appleRoot, sizeof(_appleRoot));
844
845 const void *v_certs[] = { leaf, subCA };
846 const void *v_anchors[] = { root };
847
848 certs = CFArrayCreate(NULL, v_certs, 2, &kCFTypeArrayCallBacks);
849 policy = SecPolicyCreateAppleExternalDeveloper();
850 require_noerr_action(SecTrustCreateWithCertificates(certs, policy, &trust), errOut, fail("failed to create trust object"));
851
852 anchors = CFArrayCreate(NULL, v_anchors, 1, &kCFTypeArrayCallBacks);
853 require_noerr_action(SecTrustSetAnchorCertificates(trust, anchors), errOut, fail("failed to set anchors"));
854
855 verifyDate = CFDateCreate(NULL, 543000000.0); // March 17, 2018 at 10:20:00 AM PDT
856 require_noerr_action(SecTrustSetVerifyDate(trust, verifyDate), errOut, fail("failed to set verify date"));
857
858 /* Set the stapled response */
859 ocspResponse = CFDataCreate(NULL, _devID_OCSPResponse, sizeof(_devID_OCSPResponse));
860 ok_status(SecTrustSetOCSPResponse(trust, ocspResponse), "failed to set OCSP response");
861
862 /* Set no fetch allowed, so we're relying on the stapled response from above */
863 require_noerr_action(SecTrustSetNetworkFetchAllowed(trust, false), errOut, fail("failed to set network fetch disallowed"));
864
865 /* Evaluate trust. This cert is revoked, but is only listed as "probably not revoked" by valid.apple.com.
866 * This cert should come back as revoked because of the stapled revoked response. */
867 is(SecTrustEvaluateWithError(trust, &error), false, "revoked cert with stapled response succeeded");
868 if (error) {
869 is(CFErrorGetCode(error), errSecCertificateRevoked, "got wrong error code for revoked cert, got %ld, expected %d",
870 (long)CFErrorGetCode(error), errSecCertificateRevoked);
871 } else {
872 fail("expected trust evaluation to fail and it did not.");
873 }
874
875 errOut:
876 CFReleaseNull(leaf);
877 CFReleaseNull(subCA);
878 CFReleaseNull(root);
879 CFReleaseNull(policy);
880 CFReleaseNull(trust);
881 CFReleaseNull(certs);
882 CFReleaseNull(anchors);
883 CFReleaseNull(verifyDate);
884 CFReleaseNull(error);
885 CFReleaseNull(ocspResponse);
886 }
887
888 - (void) test_results_dictionary_revocation_reason {
889 SecCertificateRef leaf = NULL, subCA = NULL, root = NULL;
890 SecPolicyRef policy = NULL;
891 SecTrustRef trust = NULL;
892 CFArrayRef certs = NULL, anchors = NULL;
893 CFDateRef verifyDate = NULL;
894 CFErrorRef error = NULL;
895 CFDataRef ocspResponse = NULL;
896
897 leaf = SecCertificateCreateWithBytes(NULL, _probablyNotRevokedLeaf, sizeof(_probablyNotRevokedLeaf));
898 subCA = SecCertificateCreateWithBytes(NULL, _devIDCA, sizeof(_devIDCA));
899 root = SecCertificateCreateWithBytes(NULL, _appleRoot, sizeof(_appleRoot));
900
901 const void *v_certs[] = { leaf, subCA };
902 const void *v_anchors[] = { root };
903
904 certs = CFArrayCreate(NULL, v_certs, 2, &kCFTypeArrayCallBacks);
905 policy = SecPolicyCreateAppleExternalDeveloper();
906 require_noerr_action(SecTrustCreateWithCertificates(certs, policy, &trust), errOut, fail("failed to create trust object"));
907
908 anchors = CFArrayCreate(NULL, v_anchors, 1, &kCFTypeArrayCallBacks);
909 require_noerr_action(SecTrustSetAnchorCertificates(trust, anchors), errOut, fail("failed to set anchors"));
910
911 verifyDate = CFDateCreate(NULL, 543000000.0); // March 17, 2018 at 10:20:00 AM PDT
912 require_noerr_action(SecTrustSetVerifyDate(trust, verifyDate), errOut, fail("failed to set verify date"));
913
914 /* Set the stapled response */
915 ocspResponse = CFDataCreate(NULL, _devID_OCSPResponse, sizeof(_devID_OCSPResponse));
916 ok_status(SecTrustSetOCSPResponse(trust, ocspResponse), "failed to set OCSP response");
917
918 /* Evaluate trust. This cert is revoked, but is only listed as "probably revoked" by valid.apple.com.
919 * This cert should come back as revoked. */
920 is(SecTrustEvaluateWithError(trust, &error), false, "revoked cert succeeded");
921 if (error) {
922 is(CFErrorGetCode(error), errSecCertificateRevoked, "got wrong error code for revoked cert, got %ld, expected %d",
923 (long)CFErrorGetCode(error), errSecCertificateRevoked);
924
925 /* Verify that the results dictionary contains all the right keys for a revoked cert */
926 CFDictionaryRef result = SecTrustCopyResult(trust);
927 isnt(result, NULL, "failed to copy result dictionary");
928 if (result) {
929 int64_t reason = 4; // superceded
930 CFNumberRef cfreason = CFNumberCreate(NULL, kCFNumberSInt64Type, &reason);
931 is(CFNumberCompare(cfreason, CFDictionaryGetValue(result, kSecTrustRevocationReason), NULL), kCFCompareEqualTo, "expected revocation reason 4");
932 CFReleaseNull(cfreason);
933 }
934 CFReleaseNull(result);
935 } else {
936 fail("expected trust evaluation to fail and it did not.");
937 }
938
939 errOut:
940 CFReleaseNull(leaf);
941 CFReleaseNull(subCA);
942 CFReleaseNull(root);
943 CFReleaseNull(policy);
944 CFReleaseNull(trust);
945 CFReleaseNull(certs);
946 CFReleaseNull(anchors);
947 CFReleaseNull(verifyDate);
948 CFReleaseNull(error);
949 CFReleaseNull(ocspResponse);
950 }
951
952 @end