]> git.saurik.com Git - apple/security.git/blob - OSX/sec/Security/Regressions/secitem/si-23-sectrust-ocsp.c
Security-59306.80.4.tar.gz
[apple/security.git] / OSX / sec / Security / Regressions / secitem / si-23-sectrust-ocsp.c
1 /*
2 * Copyright (c) 2006-2018 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 <utilities/array_size.h>
12 #include <utilities/SecCFRelease.h>
13 #include <stdlib.h>
14 #include <sys/socket.h>
15 #include <sys/types.h>
16 #include <netinet/in.h>
17 #include <arpa/inet.h>
18 #include <netdb.h>
19 #include <unistd.h>
20 #include <string.h>
21
22 #include "shared_regressions.h"
23
24 #include "si-23-sectrust-ocsp.h"
25
26 static void tests(void)
27 {
28 SecTrustRef trust;
29 SecCertificateRef cert0, cert1;
30 isnt(cert0 = SecCertificateCreateWithBytes(NULL, _ocsp_c0, sizeof(_ocsp_c0)),
31 NULL, "create cert0");
32 isnt(cert1 = SecCertificateCreateWithBytes(NULL, _ocsp_c1, sizeof(_ocsp_c1)),
33 NULL, "create cert1");
34 CFMutableArrayRef certs = CFArrayCreateMutable(kCFAllocatorDefault, 0,
35 &kCFTypeArrayCallBacks);
36 CFArrayAppendValue(certs, cert0);
37 CFArrayAppendValue(certs, cert1);
38
39 SecPolicyRef sslPolicy = SecPolicyCreateSSL(true, CFSTR("www.apple.com"));
40 SecPolicyRef ocspPolicy = SecPolicyCreateRevocation(kSecRevocationOCSPMethod);
41 const void *v_policies[] = { sslPolicy, ocspPolicy };
42 CFArrayRef policies = CFArrayCreate(NULL, v_policies,
43 array_size(v_policies), &kCFTypeArrayCallBacks);
44 CFRelease(sslPolicy);
45 CFRelease(ocspPolicy);
46 ok_status(SecTrustCreateWithCertificates(certs, policies, &trust),
47 "create trust");
48 /* April 14, 2019 at 10:46:40 PM PDT */
49 CFDateRef date = CFDateCreate(NULL, 577000000.0);
50 ok_status(SecTrustSetVerifyDate(trust, date), "set date");
51
52 is(SecTrustGetVerifyTime(trust), 577000000.0, "get date");
53
54 SecTrustResultType trustResult;
55 ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
56 is_status(trustResult, kSecTrustResultUnspecified,
57 "trust is kSecTrustResultUnspecified");
58
59 /* Certificates are only EV if they are also CT. */
60 CFDictionaryRef info = SecTrustCopyInfo(trust);
61 CFBooleanRef ev = (CFBooleanRef)CFDictionaryGetValue(info,
62 kSecTrustInfoExtendedValidationKey);
63 ok(ev, "extended validation succeeded");
64
65 CFReleaseSafe(info);
66 CFReleaseSafe(trust);
67 CFReleaseSafe(policies);
68 CFReleaseSafe(certs);
69 CFReleaseSafe(cert0);
70 CFReleaseSafe(cert1);
71 CFReleaseSafe(date);
72 }
73
74 static void test_ocsp_responder_policy() {
75 SecCertificateRef leaf = NULL, subCA = NULL, responderCert = NULL;
76 CFMutableArrayRef certs = CFArrayCreateMutable(kCFAllocatorDefault, 0,
77 &kCFTypeArrayCallBacks);
78 SecTrustRef trust = NULL;
79 SecPolicyRef ocspSignerPolicy = NULL;
80 SecTrustResultType trustResult = kSecTrustResultInvalid;
81
82 /* August 14, 2018 at 9:26:40 PM PDT */
83 CFDateRef date = CFDateCreate(NULL, 556000000.0);
84
85 isnt(leaf = SecCertificateCreateWithBytes(NULL, valid_ist_certificate,
86 sizeof(valid_ist_certificate)), NULL, "create ist leaf");
87 isnt(subCA = SecCertificateCreateWithBytes(NULL, ist_intermediate_certificate,
88 sizeof(ist_intermediate_certificate)), NULL, "create ist subCA");
89 CFArrayAppendValue(certs, leaf);
90 CFArrayAppendValue(certs, subCA);
91
92 ok(ocspSignerPolicy = SecPolicyCreateOCSPSigner(),
93 "create ocspSigner policy");
94
95 ok_status(SecTrustCreateWithCertificates(certs, ocspSignerPolicy, &trust),
96 "create trust for c0 -> c1");
97 ok_status(SecTrustSetVerifyDate(trust, date), "set date");
98 ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
99 is_status(trustResult, kSecTrustResultRecoverableTrustFailure,
100 "trust is kSecTrustResultRecoverableTrustFailure");
101
102 isnt(responderCert = SecCertificateCreateWithBytes(NULL, _responderCert,
103 sizeof(_responderCert)), NULL, "create responderCert");
104 CFArraySetValueAtIndex(certs, 0, responderCert);
105 ok_status(SecTrustCreateWithCertificates(certs, ocspSignerPolicy, &trust),
106 "create trust for ocspResponder -> c1");
107 ok_status(SecTrustSetVerifyDate(trust, date), "set date");
108 ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
109 is_status(trustResult, kSecTrustResultUnspecified,
110 "trust is kSecTrustResultUnspecified");
111
112 CFReleaseNull(leaf);
113 CFReleaseNull(subCA);
114 CFReleaseNull(responderCert);
115 CFReleaseNull(certs);
116 CFReleaseNull(trust);
117 CFReleaseSafe(ocspSignerPolicy);
118 CFReleaseNull(date);
119 }
120
121 static void test_revocation() {
122 SecTrustRef trust;
123 SecCertificateRef rcert0, rcert1;
124 isnt(rcert0 = SecCertificateCreateWithBytes(NULL,
125 revoked_ist_certificate, sizeof(revoked_ist_certificate)),
126 NULL, "create rcert0");
127 isnt(rcert1 = SecCertificateCreateWithBytes(NULL,
128 ist_intermediate_certificate, sizeof(ist_intermediate_certificate)),
129 NULL, "create rcert1");
130 CFMutableArrayRef rcerts = CFArrayCreateMutable(kCFAllocatorDefault, 0,
131 &kCFTypeArrayCallBacks);
132 CFArrayAppendValue(rcerts, rcert0);
133 CFArrayAppendValue(rcerts, rcert1);
134
135 SecPolicyRef sslPolicy = SecPolicyCreateSSL(true, CFSTR("revoked.geotrust-global-ca.test-pages.certificatemanager.apple.com"));
136 SecPolicyRef ocspPolicy = SecPolicyCreateRevocation(kSecRevocationOCSPMethod);
137 const void *v_policies[] = { sslPolicy, ocspPolicy };
138 CFArrayRef policies = CFArrayCreate(NULL, v_policies,
139 array_size(v_policies), &kCFTypeArrayCallBacks);
140 CFRelease(sslPolicy);
141 CFRelease(ocspPolicy);
142 ok_status(SecTrustCreateWithCertificates(rcerts, policies, &trust),
143 "create trust");
144 /* Feb 5th 2015. */
145 CFDateRef date = CFDateCreate(NULL, 444900000);
146 ok_status(SecTrustSetVerifyDate(trust, date), "set date");
147 CFReleaseSafe(date);
148
149 is(SecTrustGetVerifyTime(trust), 444900000, "get date");
150
151 SecTrustResultType trustResult;
152 ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
153 is((trustResult > kSecTrustResultUnspecified), true,
154 "trust is %d, expected value greater than 4", (int)trustResult);
155 CFDictionaryRef results = SecTrustCopyResult(trust);
156 CFTypeRef revoked = NULL;
157 if (results) {
158 CFArrayRef perCertResults = CFDictionaryGetValue(results, CFSTR("TrustResultDetails"));
159 if (perCertResults) {
160 CFDictionaryRef leafResults = CFArrayGetValueAtIndex(perCertResults, 0);
161 if (leafResults) {
162 revoked = CFDictionaryGetValue(leafResults, CFSTR("Revocation"));
163 }
164 }
165 }
166 is(revoked != NULL, true, "revoked result is %@", revoked);
167 CFReleaseSafe(results);
168
169
170 /* Now verify the cert at a date in the past relative to the previous
171 date, but still within the cert's validity period. Although the
172 cached response from our prior attempt will appear to have been
173 produced in the future, it should still be honored since it's
174 validly signed.
175 */
176 /* Dec 11th 2014. */
177 date = CFDateCreate(NULL, 440000000);
178 ok_status(SecTrustSetVerifyDate(trust, date), "set date");
179 CFReleaseSafe(date);
180
181 is(SecTrustGetVerifyTime(trust), 440000000, "get date");
182
183 ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
184 is((trustResult > kSecTrustResultUnspecified), true,
185 "trust is %d, expected value greater than 4", (int)trustResult);
186 results = SecTrustCopyResult(trust);
187 revoked = NULL;
188 if (results) {
189 CFArrayRef perCertResults = CFDictionaryGetValue(results, CFSTR("TrustResultDetails"));
190 if (perCertResults) {
191 CFDictionaryRef leafResults = CFArrayGetValueAtIndex(perCertResults, 0);
192 if (leafResults) {
193 revoked = CFDictionaryGetValue(leafResults, CFSTR("Revocation"));
194 }
195 }
196 }
197 is(revoked != NULL, true, "revoked result is %@", revoked);
198 CFReleaseSafe(results);
199
200 CFReleaseSafe(trust);
201 CFReleaseSafe(policies);
202 CFReleaseSafe(rcerts);
203 CFReleaseSafe(rcert0);
204 CFReleaseSafe(rcert1);
205 }
206
207 static void test_forced_revocation()
208 {
209 /*
210 * Test verification requiring a positive response from the revocation server
211 */
212
213 OSStatus status;
214 SecCertificateRef smime_leaf_cert;
215 SecCertificateRef smime_CA_cert;
216 SecCertificateRef smime_root_cert;
217
218 // Import certificates from byte array above
219 isnt(smime_leaf_cert = SecCertificateCreateWithBytes(NULL, ocsp_smime_leaf_certificate, sizeof(ocsp_smime_leaf_certificate)),
220 NULL, "SMIME Leaf Cert");
221 isnt(smime_CA_cert = SecCertificateCreateWithBytes(NULL, ocsp_smime_CA_certificate, sizeof(ocsp_smime_CA_certificate)),
222 NULL, "SMIME CA Cert");
223 isnt(smime_root_cert = SecCertificateCreateWithBytes(NULL, ocsp_smime_root_certificate, sizeof(ocsp_smime_root_certificate)),
224 NULL, "SMIME Root Cert");
225
226 SecPolicyRef smimePolicy = SecPolicyCreateWithProperties(kSecPolicyAppleSMIME, NULL);
227 SecPolicyRef revocPolicy = SecPolicyCreateRevocation(kSecRevocationUseAnyAvailableMethod | kSecRevocationRequirePositiveResponse);
228 isnt(smimePolicy, NULL, "SMIME Policy");
229 isnt(revocPolicy, NULL, "SMIME Revocation Policy");
230
231 // Default Policies
232 CFMutableArrayRef SMIMEDefaultPolicy = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
233 CFArrayAppendValue(SMIMEDefaultPolicy, smimePolicy);
234
235 // Default Policies + explicit revocation
236 CFMutableArrayRef SMIMEDefaultPolicyWithRevocation = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
237 CFArrayAppendValue(SMIMEDefaultPolicyWithRevocation, smimePolicy);
238 CFArrayAppendValue(SMIMEDefaultPolicyWithRevocation, revocPolicy);
239
240 // Valid chain of Cert (leaf + CA)
241 CFMutableArrayRef SMIMECertChain = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
242 CFArrayAppendValue(SMIMECertChain, smime_leaf_cert);
243 CFArrayAppendValue(SMIMECertChain, smime_CA_cert);
244
245 // Valid anchor certs
246 CFMutableArrayRef SMIMEAnchors = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
247 CFArrayAppendValue(SMIMEAnchors, smime_root_cert);
248
249 // Free Resources contained in arrays
250 CFReleaseSafe(smime_leaf_cert);
251 CFReleaseSafe(smime_CA_cert);
252 CFReleaseSafe(smime_root_cert);
253 CFReleaseSafe(smimePolicy);
254 CFReleaseSafe(revocPolicy);
255
256 CFDateRef VerifyDate;
257 isnt(VerifyDate = CFDateCreate(NULL, 332900000.0), NULL, "Create verify date");
258 if (!VerifyDate) { goto errOut; }
259
260 // Standard evaluation for the given verify date
261 {
262 SecTrustRef trust = NULL;
263 SecTrustResultType trust_result;
264
265 ok_status(status = SecTrustCreateWithCertificates(SMIMECertChain, SMIMEDefaultPolicy, &trust),
266 "SecTrustCreateWithCertificates");
267 ok_status(SecTrustSetVerifyDate(trust, VerifyDate), "Set date");
268 ok_status(SecTrustSetAnchorCertificates(trust, SMIMEAnchors), "Set anchors");
269
270 ok_status(status = SecTrustEvaluate(trust, &trust_result), "SecTrustEvaluate");
271
272 // Check results
273 // NOTE: We now expect a fatal error, since the "TC TrustCenter Class 1 L1 CA IX" CA
274 // is revoked. That CA is no longer present in Valid since the TC root was removed
275 // from the trust store, and as of May 2018, its OCSP server no longer resolves in DNS.
276 // However, the OCSP URI for the CA's issuer is still active and reports the CA as revoked.
277 //
278 is_status(trust_result, kSecTrustResultFatalTrustFailure, "trust is kSecTrustResultFatalTrustFailure");
279
280 CFReleaseNull(trust);
281 }
282
283 // Revocation-required evaluation should fail, since this CA's servers no longer exist
284 // and no valid responses are available
285 {
286 SecTrustRef trust = NULL;
287 SecTrustResultType trust_result;
288
289 ok_status(status = SecTrustCreateWithCertificates(SMIMECertChain, SMIMEDefaultPolicyWithRevocation, &trust),
290 "SecTrustCreateWithCertificates");
291 ok_status(SecTrustSetVerifyDate(trust, VerifyDate), "Set date");
292 ok_status(SecTrustSetAnchorCertificates(trust, SMIMEAnchors), "Set anchors");
293
294 ok_status(status = SecTrustEvaluate(trust, &trust_result), "SecTrustEvaluate");
295
296 // Check results
297 // NOTE: We now expect a fatal error, since the "TC TrustCenter Class 1 L1 CA IX" CA
298 // is revoked. That CA is no longer present in Valid since the TC root was removed
299 // from the trust store, and as of May 2018, its OCSP server no longer resolves in DNS.
300 // However, the OCSP URI for the CA's issuer is still active and reports the CA as revoked.
301 //
302 is_status(trust_result, kSecTrustResultFatalTrustFailure, "trust is kSecTrustResultFatalTrustFailure");
303
304 CFReleaseNull(trust);
305 }
306
307 // Free remaining resources
308 errOut:
309 CFReleaseSafe(VerifyDate);
310 CFReleaseSafe(SMIMEDefaultPolicy);
311 CFReleaseSafe(SMIMEDefaultPolicyWithRevocation);
312 CFReleaseSafe(SMIMECertChain);
313 CFReleaseSafe(SMIMEAnchors);
314 }
315
316 #if 0
317 static void hexdump(const uint8_t *bytes, size_t len) {
318 size_t ix;
319 printf("#anchor-sha1: ");
320 for (ix = 0; ix < len; ++ix) {
321 printf("%02X", bytes[ix]);
322 }
323 printf("\n");
324 }
325
326 static void datadump(const uint8_t *bytes, size_t len) {
327 size_t ix;
328 printf("#anchor-sha1: ");
329 for (ix = 0; ix < len; ++ix) {
330 printf("%c", bytes[ix]);
331 }
332 printf("\n");
333 }
334
335 static void display_anchor_digest(SecTrustRef trust) {
336 CFIndex count = SecTrustGetCertificateCount(trust);
337 SecCertificateRef anchor = SecTrustGetCertificateAtIndex(trust, count - 1);
338 CFDataRef digest = SecCertificateGetSHA1Digest(anchor);
339 CFDataRef xml = CFPropertyListCreateXMLData(NULL, digest);
340 datadump(CFDataGetBytePtr(xml), CFDataGetLength(xml));
341 }
342 #endif
343
344 static void test_aia(void) {
345 SecCertificateRef ovh = NULL, comodo_ev = NULL, comodo_aia = NULL;
346 CFMutableArrayRef certs = NULL, policies = NULL;
347 SecPolicyRef sslPolicy = NULL, revPolicy = NULL;
348 CFDateRef verifyDate = NULL;
349 CFDictionaryRef info = NULL;
350 SecTrustRef trust = NULL;
351 SecTrustResultType trustResult = kSecTrustResultInvalid;
352 CFBooleanRef ev = NULL;
353
354 /* Initialize common variables */
355 isnt(ovh = SecCertificateCreateWithBytes(NULL, ovh_certificate,
356 sizeof(ovh_certificate)), NULL, "create ovh cert");
357 isnt(comodo_ev = SecCertificateCreateWithBytes(NULL, comodo_ev_certificate,
358 sizeof(comodo_ev_certificate)), NULL, "create comodo_ev cert");
359 isnt(comodo_aia = SecCertificateCreateWithBytes(NULL,
360 comodo_aia_certificate, sizeof(comodo_aia_certificate)), NULL,
361 "create comodo_aia cert");
362 certs = CFArrayCreateMutable(kCFAllocatorDefault, 0,
363 &kCFTypeArrayCallBacks);
364 policies = CFArrayCreateMutable(kCFAllocatorDefault, 0,
365 &kCFTypeArrayCallBacks);
366 sslPolicy = SecPolicyCreateSSL(false, NULL); // For now, use SSL client policy to avoid SHA-1 deprecation
367 revPolicy = SecPolicyCreateRevocation(kSecRevocationUseAnyAvailableMethod);
368 CFArrayAppendValue(policies, sslPolicy);
369 CFArrayAppendValue(policies, revPolicy);
370 /* May 9th 2018. */
371 verifyDate = CFDateCreate(NULL, 547600500);
372
373 /* First run with no intermediate and disallow network fetching.
374 * Evaluation should fail because it couldn't get the intermediate. */
375 CFArrayAppendValue(certs, ovh);
376 ok_status(SecTrustCreateWithCertificates(certs, policies, &trust),
377 "create trust");
378 ok_status(SecTrustSetVerifyDate(trust, verifyDate), "set date");
379 ok_status(SecTrustSetNetworkFetchAllowed(trust, false), "set no network");
380 ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
381 is_status(trustResult, kSecTrustResultRecoverableTrustFailure,
382 "trust is kSecTrustResultRecoverableTrustFailure");
383
384 /* Now allow networking. Evaluation should succeed after fetching
385 * the intermediate. */
386 ok_status(SecTrustSetNetworkFetchAllowed(trust, true), "set allow network");
387 ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
388 is_status(trustResult, kSecTrustResultUnspecified,
389 "trust is kSecTrustResultUnspecified");
390 CFReleaseNull(trust);
391
392 /* Now run with the intermediate returned by the ssl server. */
393 CFArrayAppendValue(certs, comodo_ev);
394 ok_status(SecTrustCreateWithCertificates(certs, sslPolicy, &trust),
395 "create trust");
396 ok_status(SecTrustSetVerifyDate(trust, verifyDate), "set date");
397 ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
398 is_status(trustResult, kSecTrustResultUnspecified,
399 "trust is kSecTrustResultUnspecified");
400 info = SecTrustCopyInfo(trust);
401 ev = (CFBooleanRef)CFDictionaryGetValue(info,
402 kSecTrustInfoExtendedValidationKey);
403 ok(ev, "extended validation succeeded due to caissuers fetch");
404 //display_anchor_digest(trust);
405 CFReleaseSafe(info);
406 CFReleaseSafe(trust);
407
408 /* Now run with the intermediate returned by following the url in the
409 Certificate Access Information Authority (AIA) extension of the ovh
410 leaf certificate. */
411 CFArrayAppendValue(certs, comodo_aia);
412 ok_status(SecTrustCreateWithCertificates(certs, sslPolicy, &trust),
413 "re-create trust with aia intermediate");
414 ok_status(SecTrustSetVerifyDate(trust, verifyDate), "set date");
415 ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
416 is_status(trustResult, kSecTrustResultUnspecified,
417 "trust is kSecTrustResultUnspecified");
418 info = SecTrustCopyInfo(trust);
419 ev = (CFBooleanRef)CFDictionaryGetValue(info,
420 kSecTrustInfoExtendedValidationKey);
421 ok(ev, "extended validation succeeded");
422 //display_anchor_digest(trust);
423 CFReleaseSafe(info);
424 CFReleaseSafe(trust);
425
426 /* Now run with the intermediate returned by following the url in the
427 Certificate Access Information Authority (AIA) extension of the ovh
428 leaf certificate. */
429 CFArrayRemoveValueAtIndex(certs, 1);
430 ok_status(SecTrustCreateWithCertificates(certs, sslPolicy, &trust),
431 "re-create trust with aia intermediate");
432 ok_status(SecTrustSetVerifyDate(trust, verifyDate), "set date");
433 ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
434 is_status(trustResult, kSecTrustResultUnspecified,
435 "trust is kSecTrustResultUnspecified");
436 info = SecTrustCopyInfo(trust);
437 ev = (CFBooleanRef)CFDictionaryGetValue(info,
438 kSecTrustInfoExtendedValidationKey);
439 ok(ev, "extended validation succeeded");
440 //display_anchor_digest(trust);
441 CFReleaseSafe(info);
442 CFReleaseSafe(trust);
443
444 /* Common variable cleanup. */
445 CFReleaseSafe(sslPolicy);
446 CFReleaseSafe(revPolicy);
447 CFReleaseSafe(certs);
448 CFReleaseSafe(policies);
449 CFReleaseSafe(comodo_aia);
450 CFReleaseSafe(comodo_ev);
451 CFReleaseSafe(ovh);
452 CFReleaseSafe(verifyDate);
453 }
454
455 static void test_aia_https(void) {
456 SecCertificateRef leaf = NULL;
457 SecPolicyRef policy = NULL;
458 SecTrustRef trust = NULL;
459 CFArrayRef certs = NULL;
460 CFDateRef verifyDate = NULL;
461 CFErrorRef error = NULL;
462
463 leaf = SecCertificateCreateWithBytes(NULL, _caissuer_https, sizeof(_caissuer_https));
464 const void *v_certs[] = { leaf };
465
466 certs = CFArrayCreate(NULL, v_certs, 1, &kCFTypeArrayCallBacks);
467 policy = SecPolicyCreateSSL(true, CFSTR("example.com"));
468 require_noerr_action(SecTrustCreateWithCertificates(certs, policy, &trust), errOut, fail("failed to create trust object"));
469
470 verifyDate = CFDateCreate(NULL, 546700000.0); // April 29, 2018 at 6:06:40 AM PDT
471 require_noerr_action(SecTrustSetVerifyDate(trust, verifyDate), errOut, fail("failed to set verify date"));
472
473 #pragma clang diagnostic push
474 #pragma clang diagnostic ignored "-Wunguarded-availability-new"
475 /* Evaluate trust. This cert does not chain to anything trusted and we can't fetch an
476 * intermediate because the URI is https. */
477 is(SecTrustEvaluateWithError(trust, &error), false, "leaf with missing intermediate and https CAIssuer URI succeeded");
478 if (error) {
479 is(CFErrorGetCode(error), errSecCreateChainFailed, "got wrong error code for revoked cert, got %ld, expected %d",
480 (long)CFErrorGetCode(error), errSecCreateChainFailed);
481 } else {
482 fail("expected trust evaluation to fail and it did not.");
483 }
484 #pragma clang diagnostic pop
485
486 errOut:
487 CFReleaseNull(leaf);
488 CFReleaseNull(policy);
489 CFReleaseNull(trust);
490 CFReleaseNull(certs);
491 CFReleaseNull(verifyDate);
492 CFReleaseNull(error);
493 }
494
495 static void test_results_dictionary_revocation_reason(void) {
496 SecCertificateRef leaf = NULL, subCA = NULL, root = NULL;
497 SecPolicyRef policy = NULL;
498 SecTrustRef trust = NULL;
499 CFArrayRef certs = NULL, anchors = NULL;
500 CFDateRef verifyDate = NULL;
501 CFErrorRef error = NULL;
502 CFDataRef ocspResponse = NULL;
503
504 leaf = SecCertificateCreateWithBytes(NULL, _probablyRevokedLeaf, sizeof(_probablyRevokedLeaf));
505 subCA = SecCertificateCreateWithBytes(NULL, _digiCertSha2SubCA, sizeof(_digiCertSha2SubCA));
506 root = SecCertificateCreateWithBytes(NULL, _digiCertGlobalRoot, sizeof(_digiCertGlobalRoot));
507
508 const void *v_certs[] = { leaf, subCA };
509 const void *v_anchors[] = { root };
510
511 certs = CFArrayCreate(NULL, v_certs, 2, &kCFTypeArrayCallBacks);
512 policy = SecPolicyCreateSSL(true, CFSTR("revoked.badssl.com"));
513 require_noerr_action(SecTrustCreateWithCertificates(certs, policy, &trust), errOut, fail("failed to create trust object"));
514
515 anchors = CFArrayCreate(NULL, v_anchors, 1, &kCFTypeArrayCallBacks);
516 require_noerr_action(SecTrustSetAnchorCertificates(trust, anchors), errOut, fail("failed to set anchors"));
517
518 verifyDate = CFDateCreate(NULL, 543000000.0); // March 17, 2018 at 10:20:00 AM PDT
519 require_noerr_action(SecTrustSetVerifyDate(trust, verifyDate), errOut, fail("failed to set verify date"));
520
521 /* Set the stapled response */
522 ocspResponse = CFDataCreate(NULL, _digicertOCSPResponse, sizeof(_digicertOCSPResponse));
523 ok_status(SecTrustSetOCSPResponse(trust, ocspResponse), "failed to set OCSP response");
524
525 #pragma clang diagnostic push
526 #pragma clang diagnostic ignored "-Wunguarded-availability-new"
527 /* Evaluate trust. This cert is revoked, but is only listed as "probably revoked" by valid.apple.com.
528 * This cert should come back as revoked. */
529 is(SecTrustEvaluateWithError(trust, &error), false, "revoked cert succeeded");
530 if (error) {
531 is(CFErrorGetCode(error), errSecCertificateRevoked, "got wrong error code for revoked cert, got %ld, expected %d",
532 (long)CFErrorGetCode(error), errSecCertificateRevoked);
533
534 /* Verify that the results dictionary contains all the right keys for a revoked cert */
535 CFDictionaryRef result = SecTrustCopyResult(trust);
536 isnt(result, NULL, "failed to copy result dictionary");
537 if (result) {
538 int64_t reason = -1;
539 CFNumberRef cfreason = CFNumberCreate(NULL, kCFNumberSInt64Type, &reason);
540 is(CFNumberCompare(cfreason, CFDictionaryGetValue(result, kSecTrustRevocationReason), NULL), kCFCompareEqualTo, "expected revocation reason -1");
541 CFReleaseNull(cfreason);
542 }
543 CFReleaseNull(result);
544 } else {
545 fail("expected trust evaluation to fail and it did not.");
546 }
547 #pragma clang diagnostic pop
548
549 errOut:
550 CFReleaseNull(leaf);
551 CFReleaseNull(subCA);
552 CFReleaseNull(root);
553 CFReleaseNull(policy);
554 CFReleaseNull(trust);
555 CFReleaseNull(certs);
556 CFReleaseNull(anchors);
557 CFReleaseNull(verifyDate);
558 CFReleaseNull(error);
559 CFReleaseNull(ocspResponse);
560 }
561
562 static void test_results_dictionary_revocation_checked(void) {
563 SecCertificateRef leaf = NULL, subCA = NULL, root = NULL;
564 SecPolicyRef sslPolicy = NULL, ocspPolicy = NULL;
565 SecTrustRef trust = NULL;
566 CFArrayRef certs = NULL, anchors = NULL, policies = NULL;
567 CFDateRef verifyDate = NULL;
568 CFErrorRef error = NULL;
569
570 leaf = SecCertificateCreateWithBytes(NULL, _ocsp_c0, sizeof(_ocsp_c0));
571 subCA = SecCertificateCreateWithBytes(NULL, _ocsp_c1, sizeof(_ocsp_c1));
572 root = SecCertificateCreateWithBytes(NULL, _ocsp_c2, sizeof(_ocsp_c2));
573
574 sslPolicy = SecPolicyCreateSSL(true, CFSTR("www.apple.com"));
575 ocspPolicy = SecPolicyCreateRevocation(kSecRevocationOCSPMethod);
576
577 const void *v_certs[] = { leaf, subCA };
578 const void *v_anchors[] = { root };
579 const void *v_policies[] = { sslPolicy, ocspPolicy };
580
581 certs = CFArrayCreate(NULL, v_certs, 2, &kCFTypeArrayCallBacks);
582 policies = CFArrayCreate(NULL, v_policies, 2, &kCFTypeArrayCallBacks);
583 require_noerr_action(SecTrustCreateWithCertificates(certs, policies, &trust), errOut, fail("failed to create trust object"));
584
585 anchors = CFArrayCreate(NULL, v_anchors, 1, &kCFTypeArrayCallBacks);
586 require_noerr_action(SecTrustSetAnchorCertificates(trust, anchors), errOut, fail("failed to set anchors"));
587
588 verifyDate = CFDateCreate(NULL, 577000000.0); // April 14, 2019 at 10:46:40 PM PDT
589 require_noerr_action(SecTrustSetVerifyDate(trust, verifyDate), errOut, fail("failed to set verify date"));
590
591 #pragma clang diagnostic push
592 #pragma clang diagnostic ignored "-Wunguarded-availability-new"
593 is(SecTrustEvaluateWithError(trust, &error), true, "valid cert failed");
594
595 /* Verify that the results dictionary contains all the right keys for a valid cert where revocation checked */
596 CFDictionaryRef result = SecTrustCopyResult(trust);
597 isnt(result, NULL, "failed to copy result dictionary");
598 if (result) {
599 is(CFDictionaryGetValue(result, kSecTrustRevocationChecked), kCFBooleanTrue, "expected revocation checked flag");
600 CFDateRef validUntil = CFDictionaryGetValue(result, kSecTrustRevocationValidUntilDate);
601 isnt(validUntil, NULL, "expected revocation valid until date");
602 if (validUntil) {
603 ok(CFDateGetAbsoluteTime(validUntil) > CFAbsoluteTimeGetCurrent(), "expected valid until date in the future");
604 } else {
605 fail("did not get valid until date");
606 }
607 }
608 CFReleaseNull(result);
609 #pragma clang diagnostic pop
610
611 errOut:
612 CFReleaseNull(leaf);
613 CFReleaseNull(subCA);
614 CFReleaseNull(root);
615 CFReleaseNull(ocspPolicy);
616 CFReleaseNull(sslPolicy);
617 CFReleaseNull(trust);
618 CFReleaseNull(certs);
619 CFReleaseNull(anchors);
620 CFReleaseNull(policies);
621 CFReleaseNull(verifyDate);
622 CFReleaseNull(error);
623 }
624
625 static int ping_host(char *host_name){
626
627 struct sockaddr_in pin;
628 struct hostent *nlp_host;
629 int sd;
630 int port;
631 int retries = 5;
632
633 port=80;
634
635 //tries 5 times then give up
636 while ((nlp_host=gethostbyname(host_name))==0 && retries--){
637 printf("Resolve Error! (%s) %d\n", host_name, h_errno);
638 sleep(1);
639 }
640
641 if(nlp_host==0)
642 return 0;
643
644 bzero(&pin,sizeof(pin));
645 pin.sin_family=AF_INET;
646 pin.sin_addr.s_addr=htonl(INADDR_ANY);
647 pin.sin_addr.s_addr=((struct in_addr *)(nlp_host->h_addr))->s_addr;
648 pin.sin_port=htons(port);
649
650 sd=socket(AF_INET,SOCK_STREAM,0);
651
652 if (connect(sd,(struct sockaddr*)&pin,sizeof(pin))==-1){
653 printf("connect error! (%s) %d\n", host_name, errno);
654 close(sd);
655 return 0;
656 }
657 else{
658 close(sd);
659 return 1;
660 }
661 }
662
663 int si_23_sectrust_ocsp(int argc, char *const *argv)
664 {
665 char *hosts[] = {
666 "EVSecure-ocsp.verisign.com",
667 "EVIntl-ocsp.verisign.com",
668 "EVIntl-aia.verisign.com",
669 "ocsp.comodoca.com",
670 "crt.comodoca.com",
671 "ocsp.entrust.net",
672 "ocsp.digicert.com",
673 };
674
675 unsigned host_cnt = 0;
676
677 plan_tests(105);
678
679 for (host_cnt = 0; host_cnt < sizeof(hosts)/sizeof(hosts[0]); host_cnt ++) {
680 if(!ping_host(hosts[host_cnt])) {
681 printf("Accessing specific server (%s) failed, check the network!\n", hosts[host_cnt]);
682 return 0;
683 }
684 }
685
686 tests();
687 test_ocsp_responder_policy();
688 test_aia();
689 test_aia_https();
690 test_revocation();
691 test_forced_revocation();
692 test_results_dictionary_revocation_reason();
693 test_results_dictionary_revocation_checked();
694
695 return 0;
696 }