]> git.saurik.com Git - apple/security.git/blob - OSX/sec/Security/Regressions/secitem/si-84-sectrust-allowlist.m
Security-58286.200.222.tar.gz
[apple/security.git] / OSX / sec / Security / Regressions / secitem / si-84-sectrust-allowlist.m
1 /*
2 * si-84-sectrust-allowlist.c
3 * Security
4 *
5 * Copyright (c) 2015-2017 Apple Inc. All Rights Reserved.
6 */
7
8 #include <AssertMacros.h>
9 #import <Foundation/Foundation.h>
10 #include <CoreFoundation/CoreFoundation.h>
11 #include <Security/Security.h>
12 #include <Security/SecCertificatePriv.h>
13 #include <Security/SecPolicyPriv.h>
14 #include <utilities/SecCFRelease.h>
15 #include <AssertMacros.h>
16
17 #include "shared_regressions.h"
18
19 #include "si-84-sectrust-allowlist/cnnic_certs.h"
20 #include "si-84-sectrust-allowlist/wosign_certs.h"
21 #include "si-84-sectrust-allowlist/date_testing_certs.h"
22
23 /* Define this symbol for testing updated allowlist workaround. */
24 #define RADAR_32792206 1
25
26
27 static SecCertificateRef createCertFromStaticData(const UInt8 *certData, CFIndex certLength)
28 {
29 SecCertificateRef cert = NULL;
30 CFDataRef data = CFDataCreateWithBytesNoCopy(NULL, certData, certLength, kCFAllocatorNull);
31 if (data) {
32 cert = SecCertificateCreateWithData(NULL, data);
33 CFRelease(data);
34 }
35 return cert;
36 }
37
38 static void TestLeafOnAllowList()
39 {
40 SecCertificateRef certs[4];
41 SecPolicyRef policy = NULL;
42 SecTrustRef trust = NULL;
43 CFDateRef date = NULL;
44 CFArrayRef certArray = NULL;
45 CFArrayRef anchorsArray = NULL;
46
47 isnt(certs[0] = createCertFromStaticData(leafOnAllowList_Cert, sizeof(leafOnAllowList_Cert)),
48 NULL, "allowlist: create leaf cert");
49 isnt(certs[1] = createCertFromStaticData(ca1_Cert, sizeof(ca1_Cert)),
50 NULL, "allowlist: create intermediate ca 1");
51 isnt(certs[2] = createCertFromStaticData(ca2_Cert, sizeof(ca2_Cert)),
52 NULL, "allowlist: create intermediate ca 2");
53 isnt(certs[3] = createCertFromStaticData(root_Cert, sizeof(root_Cert)),
54 NULL, "allowlist: create root");
55
56 isnt(certArray = CFArrayCreate(kCFAllocatorDefault, (const void **)&certs[0], 4, &kCFTypeArrayCallBacks),
57 NULL, "allowlist: create cert array");
58
59 /* create a trust reference with ssl policy */
60 isnt(policy = SecPolicyCreateSSL(true, CFSTR("telegram.im")), NULL, "allowlist: create policy");
61 ok_status(SecTrustCreateWithCertificates(certArray, policy, &trust), "allowlist: create trust");
62
63 /* set evaluate date: September 12, 2016 at 1:30:00 PM PDT */
64 isnt(date = CFDateCreate(NULL, 495405000.0), NULL, "allowlist: create date");
65 ok_status((date) ? SecTrustSetVerifyDate(trust, date) : errSecParam, "allowlist: set verify date");
66
67 /* use a known root CA at this point in time to anchor the chain */
68 isnt(anchorsArray = CFArrayCreate(NULL, (const void **)&certs[3], 1, &kCFTypeArrayCallBacks),
69 NULL, "allowlist: create anchors array");
70 ok_status((anchorsArray) ? SecTrustSetAnchorCertificates(trust, anchorsArray) : errSecParam, "allowlist: set anchors");
71
72 SecTrustResultType trustResult = kSecTrustResultInvalid;
73 ok_status(SecTrustEvaluate(trust, &trustResult), "allowlist: evaluate");
74
75 #if 0
76 /* expected result is kSecTrustResultUnspecified since cert is on allow list and its issuer chains to a trusted root */
77 ok(trustResult == kSecTrustResultUnspecified, "trustResult 4 expected (got %d)",
78 (int)trustResult);
79 #else
80 #if RADAR_32792206
81 /* this certificate was on the allow list prior to v5, and list hasn't yet updated. */
82 if (trustResult == kSecTrustResultUnspecified) {
83 trustResult = kSecTrustResultRecoverableTrustFailure;
84 }
85 #endif
86 /* this certificate is no longer on the allow list: <rdar://32792206> */
87 /* expected result is kSecTrustResultRecoverableTrustFailure (if issuer is distrusted)
88 or kSecTrustResultFatalTrustFailure (if issuer is revoked), since cert is not on allow list */
89 ok(trustResult == kSecTrustResultRecoverableTrustFailure ||
90 trustResult == kSecTrustResultFatalTrustFailure,
91 "trustResult 5 or 6 expected (got %d)", (int)trustResult);
92 #endif
93
94 /* clean up */
95 for(CFIndex idx=0; idx < 4; idx++) {
96 if (certs[idx]) { CFRelease(certs[idx]); }
97 }
98 if (policy) { CFRelease(policy); }
99 if (trust) { CFRelease(trust); }
100 if (date) { CFRelease(date); }
101 if (certArray) { CFRelease(certArray); }
102 if (anchorsArray) { CFRelease(anchorsArray); }
103 }
104
105 static void TestLeafNotOnAllowList()
106 {
107 SecCertificateRef certs[4];
108 SecPolicyRef policy = NULL;
109 SecTrustRef trust = NULL;
110 CFDateRef date = NULL;
111 CFArrayRef certArray = NULL;
112 CFArrayRef anchorsArray = NULL;
113
114 isnt(certs[0] = createCertFromStaticData(leafNotOnAllowList_Cert, sizeof(leafNotOnAllowList_Cert)),
115 NULL, "!allowlist: create leaf cert");
116 isnt(certs[1] = createCertFromStaticData(ca1_Cert, sizeof(ca1_Cert)),
117 NULL, "!allowlist: create intermediate ca 1");
118 isnt(certs[2] = createCertFromStaticData(ca2_Cert, sizeof(ca2_Cert)),
119 NULL, "!allowlist: create intermediate ca 2");
120 isnt(certs[3] = createCertFromStaticData(root_Cert, sizeof(root_Cert)),
121 NULL, "!allowlist: create root");
122
123 isnt(certArray = CFArrayCreate(kCFAllocatorDefault, (const void **)&certs[0], 4, &kCFTypeArrayCallBacks),
124 NULL, "!allowlist: create cert array");
125
126 /* create a trust reference with basic policy */
127 isnt(policy = SecPolicyCreateBasicX509(), NULL, "!allowlist: create policy");
128 ok_status(SecTrustCreateWithCertificates(certArray, policy, &trust), "!allowlist: create trust");
129
130 /* set evaluate date: September 7, 2016 at 9:00:00 PM PDT */
131 isnt(date = CFDateCreate(NULL, 495000000.0), NULL, "!allowlist: create date");
132 ok_status((date) ? SecTrustSetVerifyDate(trust, date) : errSecParam, "!allowlist: set verify date");
133
134 /* use a known root CA at this point in time to anchor the chain */
135 isnt(anchorsArray = CFArrayCreate(NULL, (const void **)&certs[3], 1, &kCFTypeArrayCallBacks),
136 NULL, "allowlist: create anchors array");
137 ok_status((anchorsArray) ? SecTrustSetAnchorCertificates(trust, anchorsArray) : errSecParam, "!allowlist: set anchors");
138
139 SecTrustResultType trustResult = kSecTrustResultInvalid;
140 ok_status(SecTrustEvaluate(trust, &trustResult), "!allowlist: evaluate");
141
142 /* expected result is kSecTrustResultRecoverableTrustFailure (if issuer is distrusted)
143 or kSecTrustResultFatalTrustFailure (if issuer is revoked), since cert is not on allow list */
144 ok(trustResult == kSecTrustResultRecoverableTrustFailure ||
145 trustResult == kSecTrustResultFatalTrustFailure,
146 "trustResult 5 or 6 expected (got %d)", (int)trustResult);
147
148 /* clean up */
149 for(CFIndex idx=0; idx < 4; idx++) {
150 if (certs[idx]) { CFRelease(certs[idx]); }
151 }
152 if (policy) { CFRelease(policy); }
153 if (trust) { CFRelease(trust); }
154 if (date) { CFRelease(date); }
155 if (certArray) { CFRelease(certArray); }
156 if (anchorsArray) { CFRelease(anchorsArray); }
157 }
158
159 static void TestAllowListForRootCA(void)
160 {
161 SecCertificateRef test0[2] = {NULL,NULL};
162 SecCertificateRef test1[2] = {NULL,NULL};
163 SecCertificateRef test1e[2] = {NULL,NULL};
164 SecCertificateRef test2[2] = {NULL,NULL};
165 SecPolicyRef policy = NULL;
166 SecTrustRef trust = NULL;
167 CFDateRef date = NULL;
168 SecTrustResultType trustResult;
169
170 isnt(test0[0] = createCertFromStaticData(cert0, sizeof(cert0)),
171 NULL, "create first leaf");
172 isnt(test1[0] = createCertFromStaticData(cert1, sizeof(cert1)),
173 NULL, "create second leaf");
174 isnt(test1e[0] = createCertFromStaticData(cert1_expired, sizeof(cert1_expired)),
175 NULL, "create second leaf (expired)");
176 isnt(test2[0] = createCertFromStaticData(cert2, sizeof(cert2)),
177 NULL, "create third leaf");
178
179 isnt(test0[1] = createCertFromStaticData(intermediate0, sizeof(intermediate0)),
180 NULL, "create intermediate");
181 isnt(test1[1] = createCertFromStaticData(intermediate1, sizeof(intermediate1)),
182 NULL, "create intermediate");
183 isnt(test1e[1] = createCertFromStaticData(intermediate1, sizeof(intermediate1)),
184 NULL, "create intermediate");
185 isnt(test2[1] = createCertFromStaticData(intermediate2, sizeof(intermediate2)),
186 NULL, "create intermediate");
187
188 CFArrayRef certs0 = CFArrayCreate(kCFAllocatorDefault, (const void **)test0, 2, &kCFTypeArrayCallBacks);
189 CFArrayRef certs1 = CFArrayCreate(kCFAllocatorDefault, (const void **)test1, 2, &kCFTypeArrayCallBacks);
190 CFArrayRef certs1e = CFArrayCreate(kCFAllocatorDefault, (const void **)test1e, 2, &kCFTypeArrayCallBacks);
191 CFArrayRef certs2 = CFArrayCreate(kCFAllocatorDefault, (const void **)test2, 2, &kCFTypeArrayCallBacks);
192
193 /*
194 * Allowlisted certificates issued by untrusted root CA.
195 */
196 isnt(policy = SecPolicyCreateBasicX509(), NULL, "create policy");
197 ok_status(SecTrustCreateWithCertificates(certs0, policy, &trust), "create trust");
198 /* set evaluate date within validity range: September 12, 2016 at 1:30:00 PM PDT */
199 isnt(date = CFDateCreate(NULL, 495405000.0), NULL, "create date");
200 ok_status((date) ? SecTrustSetVerifyDate(trust, date) : errSecParam, "set verify date");
201 ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
202 #if 0
203 /* successful trust result expected since this is on the allow list */
204 ok(trustResult == kSecTrustResultUnspecified, "trustResult 4 expected (got %d)",
205 (int)trustResult);
206 #else
207 #if RADAR_32792206
208 /* this certificate was on the allow list prior to v5, and list hasn't yet updated. */
209 if (trustResult == kSecTrustResultUnspecified) {
210 trustResult = kSecTrustResultRecoverableTrustFailure;
211 }
212 #endif
213 /* this certificate is no longer on the allow list: <rdar://32792206> */
214 /* expected result is kSecTrustResultRecoverableTrustFailure (if issuer is distrusted)
215 or kSecTrustResultFatalTrustFailure (if issuer is revoked), since cert is not on allow list */
216 ok(trustResult == kSecTrustResultRecoverableTrustFailure ||
217 trustResult == kSecTrustResultFatalTrustFailure,
218 "trustResult 5 or 6 expected (got %d)", (int)trustResult);
219 #endif
220 if (trust) { CFRelease(trust); }
221 if (date) { CFRelease(date); }
222
223 ok_status(SecTrustCreateWithCertificates(certs1, policy, &trust), "create trust");
224 /* set evaluate date within validity range: September 12, 2016 at 1:30:00 PM PDT */
225 isnt(date = CFDateCreate(NULL, 495405000.0), NULL, "create date");
226 ok_status((date) ? SecTrustSetVerifyDate(trust, date) : errSecParam, "set verify date");
227 ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
228 #if 0
229 /* Note: this certificate has expired and was removed from the allowlist,
230 so we currently expect a revoked trust failure despite the verify date. */
231 ok(trustResult == kSecTrustResultFatalTrustFailure, "trustResult 6 expected (got %d)",
232 (int)trustResult);
233 #else
234 /* there is no longer an allowlist: <rdar://32792206> */
235 /* expected result is kSecTrustResultRecoverableTrustFailure (if issuer is distrusted)
236 or kSecTrustResultFatalTrustFailure (if issuer is revoked), since cert is not on allow list */
237 ok(trustResult == kSecTrustResultRecoverableTrustFailure ||
238 trustResult == kSecTrustResultFatalTrustFailure,
239 "trustResult 5 or 6 expected (got %d)", (int)trustResult);
240 #endif
241 if (trust) { CFRelease(trust); }
242 if (date) { CFRelease(date); }
243
244 ok_status(SecTrustCreateWithCertificates(certs2, policy, &trust), "create trust");
245 /* set evaluate date within validity range: September 12, 2016 at 1:30:00 PM PDT */
246 isnt(date = CFDateCreate(NULL, 495405000.0), NULL, "create date");
247 ok_status((date) ? SecTrustSetVerifyDate(trust, date) : errSecParam, "set verify date");
248 ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
249 #if 0
250 /* successful trust result expected since this is on the allow list */
251 ok(trustResult == kSecTrustResultUnspecified, "trustResult 4 expected (got %d)",
252 (int)trustResult);
253 #else
254 #if RADAR_32792206
255 /* this certificate was on the allow list prior to v5, and list hasn't yet updated. */
256 if (trustResult == kSecTrustResultUnspecified) {
257 trustResult = kSecTrustResultRecoverableTrustFailure;
258 }
259 #endif
260 /* this certificate is no longer on the allow list: <rdar://32792206> */
261 /* expected result is kSecTrustResultRecoverableTrustFailure (if issuer is distrusted)
262 or kSecTrustResultFatalTrustFailure (if issuer is revoked), since cert is not on allow list */
263 ok(trustResult == kSecTrustResultRecoverableTrustFailure ||
264 trustResult == kSecTrustResultFatalTrustFailure,
265 "trustResult 5 or 6 expected (got %d)", (int)trustResult);
266 #endif
267
268 /*
269 * Same certificate, on allow list but past expiration. Expect to fail.
270 */
271 if (date) { CFRelease(date); }
272 isnt(date = CFDateCreate(NULL, 667680000.0), NULL, "create date");
273 ok_status((date) ? SecTrustSetVerifyDate(trust, date) : errSecParam, "set date to far future so certs are expired");
274 ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
275 #if 0
276 ok(trustResult == kSecTrustResultRecoverableTrustFailure, "trustResult 5 expected (got %d)",
277 (int)trustResult);
278 #else
279 /* expected result is kSecTrustResultRecoverableTrustFailure (if issuer is distrusted)
280 or kSecTrustResultFatalTrustFailure (if issuer is revoked), since cert is not on allow list */
281 ok(trustResult == kSecTrustResultRecoverableTrustFailure ||
282 trustResult == kSecTrustResultFatalTrustFailure,
283 "trustResult 5 or 6 expected (got %d)", (int)trustResult);
284 #endif
285 if (trust) { CFRelease(trust); }
286 if (date) { CFRelease(date); }
287
288 /*
289 * Expired certificate not on allow list. Expect to fail.
290 */
291 ok_status(SecTrustCreateWithCertificates(certs1e, policy, &trust), "create trust");
292 /* set evaluate date within validity range: September 12, 2016 at 1:30:00 PM PDT */
293 isnt(date = CFDateCreate(NULL, 495405000.0), NULL, "create date");
294 ok_status((date) ? SecTrustSetVerifyDate(trust, date) : errSecParam, "set verify date");
295 ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
296 #if 0
297 /* Note: because this certificate is not on the allow list, and the allow list is complete,
298 we now expect it to be treated as revoked regardless of expiration status. */
299 ok(trustResult == kSecTrustResultFatalTrustFailure, "trustResult 6 expected (got %d)",
300 (int)trustResult);
301 #else
302 /* there is no longer an allowlist: <rdar://32792206> */
303 /* expected result is kSecTrustResultRecoverableTrustFailure (if issuer is distrusted)
304 or kSecTrustResultFatalTrustFailure (if issuer is revoked), since cert is not on allow list */
305 ok(trustResult == kSecTrustResultRecoverableTrustFailure ||
306 trustResult == kSecTrustResultFatalTrustFailure,
307 "trustResult 5 or 6 expected (got %d)", (int)trustResult);
308 #endif
309 if (trust) { CFRelease(trust); }
310 if (date) { CFRelease(date); }
311
312
313 /* Clean up. */
314 if (policy) { CFRelease(policy); }
315 if (certs0) { CFRelease(certs0); }
316 if (certs1) { CFRelease(certs1); }
317 if (certs1e) { CFRelease(certs1e); }
318 if (certs2) { CFRelease(certs2); }
319
320 if (test0[0]) { CFRelease(test0[0]); }
321 if (test0[1]) { CFRelease(test0[1]); }
322 if (test1[0]) { CFRelease(test1[0]); }
323 if (test1[1]) { CFRelease(test1[1]); }
324 if (test1e[0]) { CFRelease(test1e[0]); }
325 if (test1e[1]) { CFRelease(test1e[1]); }
326 if (test2[0]) { CFRelease(test2[0]); }
327 if (test2[1]) { CFRelease(test2[1]); }
328 }
329
330 static void TestDateBasedAllowListForRootCA(void) {
331 SecCertificateRef root = NULL, beforeInt = NULL, afterInt = NULL,
332 beforeLeaf = NULL, afterLeaf = NULL;
333 SecPolicyRef policy = NULL;
334 SecTrustRef trust = NULL;
335 NSArray *anchors = nil, *certs = nil;
336 NSDate *verifyDate = nil;
337 SecTrustResultType trustResult = kSecTrustResultInvalid;
338
339 require(root = SecCertificateCreateWithBytes(NULL, _datetest_root, sizeof(_datetest_root)), out);
340 require(beforeInt = SecCertificateCreateWithBytes(NULL, _datetest_before_int, sizeof(_datetest_before_int)), out);
341 require(afterInt = SecCertificateCreateWithBytes(NULL, _datetest_after_int, sizeof(_datetest_after_int)), out);
342 require(beforeLeaf = SecCertificateCreateWithBytes(NULL, _datetest_before_leaf, sizeof(_datetest_before_leaf)), out);
343 require(afterLeaf = SecCertificateCreateWithBytes(NULL, _datetest_after_leaf, sizeof(_datetest_after_leaf)), out);
344
345 anchors = @[(__bridge id)root];
346 require(policy = SecPolicyCreateSSL(true, CFSTR("testserver.apple.com")), out);
347 verifyDate = [NSDate dateWithTimeIntervalSinceReferenceDate:504000000.0]; /* 21 Dec 2016 */
348
349 /* Leaf issued before cutoff should pass */
350 certs = @[(__bridge id)beforeLeaf, (__bridge id)beforeInt];
351 require_noerr(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trust), out);
352 require_noerr(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)anchors), out);
353 require_noerr(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)verifyDate), out);
354 require_noerr(SecTrustEvaluate(trust, &trustResult), out);
355 is(trustResult, kSecTrustResultUnspecified, "leaf issued before cutoff failed evaluation");
356 CFReleaseNull(trust);
357 trustResult = kSecTrustResultInvalid;
358
359 /* Leaf issued after cutoff should fail */
360 certs = @[(__bridge id)afterLeaf, (__bridge id)beforeInt];
361 require_noerr(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trust), out);
362 require_noerr(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)anchors), out);
363 require_noerr(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)verifyDate), out);
364 require_noerr(SecTrustEvaluate(trust, &trustResult), out);
365 is(trustResult, kSecTrustResultFatalTrustFailure, "leaf issued after cutoff succeeded evaluation");
366 CFReleaseNull(trust);
367 trustResult = kSecTrustResultInvalid;
368
369 /* Intermediate issued after cutoff should fail (even for leaf issued before) */
370 certs = @[(__bridge id)beforeLeaf, (__bridge id)afterInt];
371 require_noerr(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trust), out);
372 require_noerr(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)anchors), out);
373 require_noerr(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)verifyDate), out);
374 require_noerr(SecTrustEvaluate(trust, &trustResult), out);
375 is(trustResult, kSecTrustResultFatalTrustFailure, "intermediate issued after cutoff succeeded evaluation");
376 CFReleaseNull(trust);
377 trustResult = kSecTrustResultInvalid;
378
379 /* Intermediate issued after cutoff should fail */
380 certs = @[(__bridge id)afterLeaf, (__bridge id)afterInt];
381 require_noerr(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trust), out);
382 require_noerr(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)anchors), out);
383 require_noerr(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)verifyDate), out);
384 require_noerr(SecTrustEvaluate(trust, &trustResult), out);
385 is(trustResult, kSecTrustResultFatalTrustFailure, "intermediate issued before cutoff succeeded evaluation");
386 CFReleaseNull(trust);
387 trustResult = kSecTrustResultInvalid;
388
389 /* Leaf issued before cutoff should choose acceptable path */
390 certs = @[(__bridge id)beforeLeaf, (__bridge id) afterInt, (__bridge id)beforeInt];
391 require_noerr(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trust), out);
392 require_noerr(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)anchors), out);
393 require_noerr(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)verifyDate), out);
394 require_noerr(SecTrustEvaluate(trust, &trustResult), out);
395 is(trustResult, kSecTrustResultUnspecified, "leaf issued before cutoff failed evaluation (multi-path)");
396 CFReleaseNull(trust);
397 trustResult = kSecTrustResultInvalid;
398
399 /* No good path for leaf issued after cutoff */
400 certs = @[(__bridge id)afterLeaf, (__bridge id)beforeInt, (__bridge id)afterInt];
401 require_noerr(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trust), out);
402 require_noerr(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)anchors), out);
403 require_noerr(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)verifyDate), out);
404 require_noerr(SecTrustEvaluate(trust, &trustResult), out);
405 is(trustResult, kSecTrustResultFatalTrustFailure, "leaf issued after cutoff succeeded evaluation (multi-path)");
406
407 out:
408 CFReleaseNull(root);
409 CFReleaseNull(beforeInt);
410 CFReleaseNull(afterInt);
411 CFReleaseNull(beforeLeaf);
412 CFReleaseNull(afterLeaf);
413 CFReleaseNull(policy);
414 CFReleaseNull(trust);
415 }
416
417 static void TestLeafOnAllowListOtherFailures(void)
418 {
419 SecCertificateRef certs[4];
420 SecPolicyRef policy = NULL;
421 SecTrustRef trust = NULL;
422 NSArray *anchors = nil, *certArray = nil;
423 NSDate *verifyDate = nil;
424 SecTrustResultType trustResult = kSecTrustResultInvalid;
425
426 memset(certs, 0, 4 * sizeof(SecCertificateRef));
427
428 require(certs[0] = SecCertificateCreateWithBytes(NULL, leafOnAllowList_Cert, sizeof(leafOnAllowList_Cert)), out);
429 require(certs[1] = SecCertificateCreateWithBytes(NULL, ca1_Cert, sizeof(ca1_Cert)), out);
430 require(certs[2] = SecCertificateCreateWithBytes(NULL, ca2_Cert, sizeof(ca2_Cert)), out);
431 require(certs[3] = SecCertificateCreateWithBytes(NULL, root_Cert, sizeof(root_Cert)), out);
432
433 anchors = @[(__bridge id)certs[3]];
434 certArray = @[(__bridge id)certs[0], (__bridge id)certs[1], (__bridge id)certs[2], (__bridge id)certs[3]];
435 verifyDate = [NSDate dateWithTimeIntervalSinceReferenceDate:495405000.0];
436
437 /* Mismatched hostname, should fail */
438 require(policy = SecPolicyCreateSSL(true, (__bridge CFStringRef)@"wrong.hostname.com"), out);
439 require_noerr(SecTrustCreateWithCertificates((__bridge CFArrayRef)certArray, policy, &trust), out);
440 require_noerr(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)anchors), out);
441 require_noerr(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)verifyDate), out);
442 require_noerr(SecTrustEvaluate(trust, &trustResult), out);
443 ok(trustResult == kSecTrustResultRecoverableTrustFailure || trustResult == kSecTrustResultFatalTrustFailure,
444 "hostname failure with cert on allow list succeeded evaluation");
445 CFReleaseNull(policy);
446 trustResult = kSecTrustResultInvalid;
447
448 /* Wrong EKU, should fail */
449 require(policy = SecPolicyCreateCodeSigning(), out);
450 require_noerr(SecTrustSetPolicies(trust, policy), out);
451 require_noerr(SecTrustEvaluate(trust, &trustResult), out);
452 ok(trustResult == kSecTrustResultRecoverableTrustFailure || trustResult == kSecTrustResultFatalTrustFailure,
453 "EKU failure with cert on allow list succeeded evaluation");
454 CFReleaseNull(policy);
455 trustResult = kSecTrustResultInvalid;
456
457 /* Apple pinning policy, should fail */
458 require(policy = SecPolicyCreateAppleSSLPinned((__bridge CFStringRef)@"aPolicy",
459 (__bridge CFStringRef)@"telegram.im", NULL,
460 (__bridge CFStringRef)@"1.2.840.113635.100.6.27.12"), out);
461 require_noerr(SecTrustSetPolicies(trust, policy), out);
462 require_noerr(SecTrustEvaluate(trust, &trustResult), out);
463 ok(trustResult == kSecTrustResultRecoverableTrustFailure || trustResult == kSecTrustResultFatalTrustFailure,
464 "Apple pinning policy with cert on allow list succeeded evaluation");
465
466 out:
467 CFReleaseNull(certs[0]);
468 CFReleaseNull(certs[1]);
469 CFReleaseNull(certs[2]);
470 CFReleaseNull(certs[3]);
471 CFReleaseNull(policy);
472 CFReleaseNull(trust);
473 }
474
475 static void tests(void)
476 {
477 TestAllowListForRootCA();
478 TestLeafOnAllowList();
479 TestLeafNotOnAllowList();
480 TestDateBasedAllowListForRootCA();
481 TestLeafOnAllowListOtherFailures();
482 }
483
484 int si_84_sectrust_allowlist(int argc, char *const *argv)
485 {
486 plan_tests(68);
487 tests();
488
489 return 0;
490 }