]> git.saurik.com Git - apple/security.git/blob - OSX/shared_regressions/si-82-sectrust-ct.m
Security-58286.200.222.tar.gz
[apple/security.git] / OSX / shared_regressions / si-82-sectrust-ct.m
1 /*
2 * si-82-sectrust-ct.c
3 * Security
4 *
5 * Copyright (c) 2014 Apple Inc. All Rights Reserved.
6 *
7 */
8
9 #include <CoreFoundation/CoreFoundation.h>
10 #include <Security/SecCertificatePriv.h>
11 #include <Security/SecTrustPriv.h>
12 #include <Security/SecPolicy.h>
13 #include <stdlib.h>
14 #include <unistd.h>
15 #include <utilities/SecCFWrappers.h>
16
17 #include "shared_regressions.h"
18
19 //define this if you want to print clock time of SecTrustEvaluate call.
20 //define PRINT_SECTRUST_EVALUATE_TIME
21
22 static bool isCFTrue(CFTypeRef cf)
23 {
24 return (cf == kCFBooleanTrue);
25 }
26
27 static void test_ct_trust(CFArrayRef certs, CFArrayRef scts, CFTypeRef ocspresponses, CFArrayRef anchors,
28 CFArrayRef trustedLogs, CFStringRef hostname, CFDateRef date,
29 bool ct_expected, bool ev_expected, bool ct_whitelist_expected,
30 const char *test_name)
31 {
32 CFArrayRef policies=NULL;
33 SecPolicyRef policy=NULL;
34 SecTrustRef trust=NULL;
35 SecTrustResultType trustResult;
36 CFDictionaryRef results=NULL;
37 CFArrayRef properties=NULL;
38
39
40
41 isnt(policy = SecPolicyCreateSSL(true, hostname), NULL, "create policy");
42 isnt(policies = CFArrayCreate(kCFAllocatorDefault, (const void **)&policy, 1, &kCFTypeArrayCallBacks), NULL, "create policies");
43 ok_status(SecTrustCreateWithCertificates(certs, policies, &trust), "create trust");
44
45 assert(trust); // silence analyzer
46 if(anchors) {
47 ok_status(SecTrustSetAnchorCertificates(trust, anchors), "set anchors");
48 }
49
50 if(scts) {
51 ok_status(SecTrustSetSignedCertificateTimestamps(trust, scts), "set standalone SCTs");;
52 }
53
54 if(trustedLogs) {
55 ok_status(SecTrustSetTrustedLogs(trust, trustedLogs), "set trusted logs");
56 }
57
58 if(ocspresponses) {
59 ok_status(SecTrustSetOCSPResponse(trust, ocspresponses), "set ocsp responses");
60 }
61
62 if (!date) { goto errOut; }
63 ok_status(SecTrustSetVerifyDate(trust, date), "set date");
64 #ifdef PRINT_SECTRUST_EVALUATE_TIME
65 clock_t t0 = clock();
66 #endif
67 ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
68 #ifdef PRINT_SECTRUST_EVALUATE_TIME
69 clock_t t1 = clock() - t0;
70 #endif
71 ok(trustResult == kSecTrustResultUnspecified, "trustResult 4 expected (got %d)",
72 (int)trustResult);
73
74 results = SecTrustCopyResult(trust);
75
76 CFTypeRef ct = CFDictionaryGetValue(results, kSecTrustCertificateTransparency);
77 CFTypeRef ev = CFDictionaryGetValue(results, kSecTrustExtendedValidation);
78 CFTypeRef ct_whitelist = CFDictionaryGetValue(results, kSecTrustCertificateTransparencyWhiteList);
79
80
81 ok((isCFTrue(ct) == ct_expected), "unexpected CT result (%s)", test_name);
82 ok((isCFTrue(ev) == ev_expected), "unexpected EV result (%s)", test_name);
83 ok((isCFTrue(ct_whitelist) == ct_whitelist_expected), "unexpected CT WhiteList result (%s)", test_name);
84 /* Note that the CT whitelist has been removed due to the expiration of all contents. */
85
86 #ifdef PRINT_SECTRUST_EVALUATE_TIME
87 printf("%s: %lu\n", test_name, t1);
88 #endif
89
90 properties = SecTrustCopyProperties(trust);
91
92 errOut:
93 CFReleaseSafe(policy);
94 CFReleaseSafe(policies);
95 CFReleaseSafe(trust);
96 CFReleaseSafe(results);
97 CFReleaseSafe(properties);
98 }
99
100 #import <Foundation/Foundation.h>
101
102 static
103 SecCertificateRef SecCertificateCreateFromResource(NSString *name)
104 {
105 NSURL *url = [[NSBundle mainBundle] URLForResource:name withExtension:@".cer" subdirectory:@"si-82-sectrust-ct-data"];
106
107 NSData *certData = [NSData dataWithContentsOfURL:url];
108
109 SecCertificateRef cert = SecCertificateCreateWithData(kCFAllocatorDefault, (CFDataRef)certData);
110
111 return cert;
112 }
113
114 static
115 CFDataRef CFDataCreateFromResource(NSString *name)
116 {
117 NSURL *url = [[NSBundle mainBundle] URLForResource:name withExtension:@".bin" subdirectory:@"si-82-sectrust-ct-data"];
118
119 NSData *binData = [[NSData alloc] initWithContentsOfURL:url];
120
121 return (__bridge_retained CFDataRef) binData;
122 }
123
124 static void tests()
125 {
126 SecCertificateRef certA=NULL, certD=NULL, certF=NULL, certCA_alpha=NULL, certCA_beta=NULL;
127 CFDataRef proofD=NULL, proofA_1=NULL, proofA_2=NULL;
128 SecCertificateRef www_digicert_com_2015_cert=NULL, www_digicert_com_2016_cert=NULL, digicert_sha2_ev_server_ca=NULL;
129 SecCertificateRef www_paypal_com_cert=NULL, www_paypal_com_issuer_cert=NULL;
130 SecCertificateRef pilot_cert_3055998=NULL, pilot_cert_3055998_issuer=NULL;
131 SecCertificateRef whitelist_00008013=NULL, whitelist_5555bc4f=NULL, whitelist_aaaae152=NULL, whitelist_fff9b5f6=NULL;
132 SecCertificateRef whitelist_00008013_issuer=NULL, whitelist_5555bc4f_issuer=NULL, whitelist_fff9b5f6_issuer=NULL;
133 SecCertificateRef cfCert = NULL;
134 CFMutableArrayRef certs=NULL;
135 CFMutableArrayRef scts=NULL;
136 CFMutableArrayRef anchors=NULL;
137 CFDataRef valid_ocsp=NULL;
138 CFDataRef invalid_ocsp=NULL;
139 CFDataRef bad_hash_ocsp=NULL;
140
141 CFArrayRef trustedLogs=NULL;
142 CFURLRef trustedLogsURL=NULL;
143
144 trustedLogsURL = CFBundleCopyResourceURL(CFBundleGetMainBundle(),
145 CFSTR("CTlogs"),
146 CFSTR("plist"),
147 CFSTR("si-82-sectrust-ct-data"));
148 isnt(trustedLogsURL, NULL, "trustedLogsURL");
149 trustedLogs = (CFArrayRef) CFPropertyListReadFromFile(trustedLogsURL);
150 isnt(trustedLogs, NULL, "trustedLogs");
151
152 isnt(certCA_alpha = SecCertificateCreateFromResource(@"CA_alpha"), NULL, "create ca-alpha cert");
153 isnt(certCA_beta = SecCertificateCreateFromResource(@"CA_beta"), NULL, "create ca-beta cert");
154 isnt(anchors = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create anchors array");
155 CFArrayAppendValue(anchors, certCA_alpha);
156 CFArrayAppendValue(anchors, certCA_beta);
157 isnt(certA = SecCertificateCreateFromResource(@"serverA"), NULL, "create certA");
158 isnt(certD = SecCertificateCreateFromResource(@"serverD"), NULL, "create certD");
159 isnt(certF = SecCertificateCreateFromResource(@"serverF"), NULL, "create certF");
160 isnt(proofD = CFDataCreateFromResource(@"serverD_proof"), NULL, "creat proofD");
161 isnt(proofA_1 = CFDataCreateFromResource(@"serverA_proof_Alfa_3"), NULL, "creat proofA_1");
162 isnt(proofA_2 = CFDataCreateFromResource(@"serverA_proof_Bravo_3"), NULL, "creat proofA_2");
163 isnt(www_digicert_com_2015_cert = SecCertificateCreateFromResource(@"www_digicert_com_2015"), NULL, "create www.digicert.com 2015 cert");
164 isnt(www_digicert_com_2016_cert = SecCertificateCreateFromResource(@"www_digicert_com_2016"), NULL, "create www.digicert.com 2016 cert");
165 isnt(digicert_sha2_ev_server_ca = SecCertificateCreateFromResource(@"digicert_sha2_ev_server_ca"), NULL, "create digicert.com subCA cert");
166 isnt(www_paypal_com_cert = SecCertificateCreateFromResource(@"www_paypal_com"), NULL, "create www.paypal.com cert");
167 isnt(www_paypal_com_issuer_cert = SecCertificateCreateFromResource(@"www_paypal_com_issuer"), NULL, "create www.paypal.com issuer cert");
168 isnt(valid_ocsp = CFDataCreateFromResource(@"valid_ocsp_response"), NULL, "create valid_ocsp");
169 isnt(invalid_ocsp = CFDataCreateFromResource(@"invalid_ocsp_response"), NULL, "create invalid_ocsp");
170 isnt(bad_hash_ocsp = CFDataCreateFromResource(@"bad_hash_ocsp_response"), NULL, "create bad_hash_ocsp");
171 isnt(pilot_cert_3055998 = SecCertificateCreateFromResource(@"pilot_3055998"), NULL, "create pilot_cert_3055998 cert");
172 isnt(pilot_cert_3055998_issuer = SecCertificateCreateFromResource(@"pilot_3055998_issuer"), NULL, "create pilot_cert_3055998 issuer cert");
173
174 isnt(whitelist_00008013 = SecCertificateCreateFromResource(@"whitelist_00008013"), NULL, "create whitelist_00008013 cert");
175 isnt(whitelist_5555bc4f = SecCertificateCreateFromResource(@"whitelist_5555bc4f"), NULL, "create whitelist_5555bc4f cert");
176 isnt(whitelist_aaaae152 = SecCertificateCreateFromResource(@"whitelist_aaaae152"), NULL, "create whitelist_aaaae152 cert");
177 isnt(whitelist_fff9b5f6 = SecCertificateCreateFromResource(@"whitelist_fff9b5f6"), NULL, "create whitelist_fff9b5f6 cert");
178 isnt(whitelist_00008013_issuer = SecCertificateCreateFromResource(@"whitelist_00008013_issuer"), NULL, "create whitelist_00008013_issuer cert");
179 isnt(whitelist_5555bc4f_issuer = SecCertificateCreateFromResource(@"whitelist_5555bc4f_issuer"), NULL, "create whitelist_5555bc4f_issuer cert");
180 isnt(whitelist_fff9b5f6_issuer = SecCertificateCreateFromResource(@"whitelist_fff9b5f6_issuer"), NULL, "create whitelist_fff9b5f6_issuer cert");
181
182 CFCalendarRef cal = NULL;
183 CFAbsoluteTime at;
184 CFDateRef date_20150307 = NULL; // Date for older set of tests.
185 CFDateRef date_20160422 = NULL; // Date for newer set of tests.
186
187 isnt(cal = CFCalendarCreateWithIdentifier(kCFAllocatorDefault, kCFGregorianCalendar), NULL, "create calendar");
188 ok(CFCalendarComposeAbsoluteTime(cal, &at, "yMd", 2015, 3, 7), "create verify absolute time 20150307");
189 isnt(date_20150307 = CFDateCreate(kCFAllocatorDefault, at), NULL, "create verify date 20150307");
190 ok(CFCalendarComposeAbsoluteTime(cal, &at, "yMd", 2016, 4, 22), "create verify absolute time 20160422");
191 isnt(date_20160422 = CFDateCreate(kCFAllocatorDefault, at), NULL, "create verify date 20160422");
192
193
194 /* Case 1: coreos-ct-test embedded SCT - only 1 SCT - so not CT qualified */
195 isnt(certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create cert array");
196 CFArrayAppendValue(certs, certF);
197 test_ct_trust(certs, NULL, NULL, anchors, trustedLogs, NULL, date_20150307,
198 false, false, false, "coreos-ct-test 1");
199 CFReleaseNull(certs);
200
201 /* Case 2: coreos-ct-test standalone SCT - only 1 SCT - so not CT qualified */
202 isnt(certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create cert array");
203 CFArrayAppendValue(certs, certD);
204 isnt(scts = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create SCT array");
205 CFArrayAppendValue(scts, proofD);
206 test_ct_trust(certs, scts, NULL, anchors, trustedLogs, NULL, date_20150307,
207 false, false, false, "coreos-ct-test 2");
208 CFReleaseNull(certs);
209 CFReleaseNull(scts);
210
211 /* case 3: digicert : 2 embedded SCTs, but lifetime of cert is 24 month, so not CT qualified */
212 isnt(certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create cert array");
213 CFArrayAppendValue(certs, www_digicert_com_2015_cert);
214 CFArrayAppendValue(certs, digicert_sha2_ev_server_ca);
215 test_ct_trust(certs, NULL, NULL, NULL, NULL, CFSTR("www.digicert.com"), date_20150307,
216 false, false, false, "digicert 2015");
217 CFReleaseNull(certs);
218
219 /* Case 4: coreos-ct-test standalone SCT - 2 SCTs - CT qualified */
220 isnt(certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create cert array");
221 CFArrayAppendValue(certs, certA);
222 isnt(scts = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create SCT array");
223 CFArrayAppendValue(scts, proofA_1);
224 CFArrayAppendValue(scts, proofA_2);
225 test_ct_trust(certs, scts, NULL, anchors, trustedLogs, NULL, date_20150307,
226 true, false, false, "coreos-ct-test 3");
227 CFReleaseNull(certs);
228 CFReleaseNull(scts);
229
230 /* Case 5: Test with an invalid OCSP response */
231 isnt(certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create cert array");
232 CFArrayAppendValue(certs, certA);
233 isnt(scts = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create SCT array");
234 CFArrayAppendValue(scts, proofA_1);
235 test_ct_trust(certs, scts, invalid_ocsp, anchors, trustedLogs, NULL, date_20150307,
236 false, false, false, "coreos-ct-test 4");
237 CFReleaseNull(certs);
238 CFReleaseNull(scts);
239
240 /* Case 6: Test with a valid OCSP response */
241 isnt(certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create cert array");
242 CFArrayAppendValue(certs, certA);
243 isnt(scts = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create SCT array");
244 CFArrayAppendValue(scts, proofA_1);
245 test_ct_trust(certs, scts, valid_ocsp, anchors, trustedLogs, NULL, date_20150307,
246 false, false, false, "coreos-ct-test 5");
247 CFReleaseNull(certs);
248 CFReleaseNull(scts);
249
250 /* Case 7: Test with a bad hash OCSP response */
251 isnt(certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create cert array");
252 CFArrayAppendValue(certs, certA);
253 isnt(scts = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create SCT array");
254 CFArrayAppendValue(scts, proofA_1);
255 test_ct_trust(certs, scts, bad_hash_ocsp, anchors, trustedLogs, NULL, date_20150307,
256 false, false, false, "coreos-ct-test 6");
257 CFReleaseNull(certs);
258 CFReleaseNull(scts);
259
260 /* case 8: Current (April 2016) www.digicert.com cert: 3 embedded SCTs, CT qualified */
261 isnt(certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create cert array");
262 CFArrayAppendValue(certs, www_digicert_com_2016_cert);
263 CFArrayAppendValue(certs, digicert_sha2_ev_server_ca);
264 test_ct_trust(certs, NULL, NULL, NULL, NULL, CFSTR("www.digicert.com"), date_20160422,
265 true, true, false, "digicert 2016");
266 CFReleaseNull(certs);
267
268
269
270 #define TEST_CASE(x) \
271 do { \
272 isnt(certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create cert array for " #x); \
273 isnt(cfCert = SecCertificateCreateFromResource(@#x), NULL, "create cfCert from " #x); \
274 CFArrayAppendValue(certs, cfCert); \
275 test_ct_trust(certs, NULL, NULL, anchors, trustedLogs, NULL, date_20150307, true, false, false, #x); \
276 CFReleaseNull(certs); \
277 CFReleaseNull(cfCert); \
278 } while (0)
279
280
281 TEST_CASE(server_1601);
282 TEST_CASE(server_1603);
283 TEST_CASE(server_1604);
284 TEST_CASE(server_1701);
285 TEST_CASE(server_1704);
286 TEST_CASE(server_1705);
287 TEST_CASE(server_1801);
288 TEST_CASE(server_1804);
289 TEST_CASE(server_1805);
290 TEST_CASE(server_2001);
291
292
293 CFReleaseSafe(certCA_alpha);
294 CFReleaseSafe(certCA_beta);
295 CFReleaseSafe(anchors);
296 CFReleaseSafe(certA);
297 CFReleaseSafe(certD);
298 CFReleaseSafe(certF);
299 CFReleaseSafe(proofD);
300 CFReleaseSafe(proofA_1);
301 CFReleaseSafe(proofA_2);
302 CFReleaseSafe(www_digicert_com_2015_cert);
303 CFReleaseSafe(www_digicert_com_2016_cert);
304 CFReleaseSafe(digicert_sha2_ev_server_ca);
305 CFReleaseSafe(www_paypal_com_cert);
306 CFReleaseSafe(www_paypal_com_issuer_cert);
307 CFReleaseSafe(pilot_cert_3055998);
308 CFReleaseSafe(pilot_cert_3055998_issuer);
309 CFReleaseSafe(whitelist_00008013);
310 CFReleaseSafe(whitelist_5555bc4f);
311 CFReleaseSafe(whitelist_aaaae152);
312 CFReleaseSafe(whitelist_fff9b5f6);
313 CFReleaseSafe(whitelist_00008013_issuer);
314 CFReleaseSafe(whitelist_5555bc4f_issuer);
315 CFReleaseSafe(whitelist_fff9b5f6_issuer);
316 CFReleaseSafe(trustedLogsURL);
317 CFReleaseSafe(trustedLogs);
318 CFReleaseSafe(valid_ocsp);
319 CFReleaseSafe(invalid_ocsp);
320 CFReleaseSafe(bad_hash_ocsp);
321 CFReleaseSafe(cal);
322 CFReleaseSafe(date_20150307);
323 CFReleaseSafe(date_20160422);
324
325 }
326
327
328 int si_82_sectrust_ct(int argc, char *const *argv)
329 {
330 plan_tests(268);
331
332 tests();
333
334 return 0;
335 }