]> git.saurik.com Git - apple/security.git/blob - tests/TrustTests/EvaluationTests/CTTests.m
Security-59306.41.2.tar.gz
[apple/security.git] / tests / TrustTests / EvaluationTests / CTTests.m
1 /*
2 * Copyright (c) 2018 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 *
23 */
24
25 #include <AssertMacros.h>
26 #import <XCTest/XCTest.h>
27 #include <Security/SecCertificatePriv.h>
28 #include <Security/SecPolicyPriv.h>
29 #include <Security/SecTrustPriv.h>
30 #include "OSX/utilities/SecCFWrappers.h"
31 #include <Security/SecTrustSettings.h>
32 #include <Security/SecTrustSettingsPriv.h>
33 #include <Security/SecFramework.h>
34 #include "trust/trustd/OTATrustUtilities.h"
35
36 #if !TARGET_OS_BRIDGE
37 #import <OCMock/OCMock.h>
38 #endif
39
40 #if TARGET_OS_IPHONE
41 #include <Security/SecTrustStore.h>
42 #else
43 #include <Security/SecKeychain.h>
44 #endif
45
46 #if !TARGET_OS_BRIDGE
47 #import <MobileAsset/MAAsset.h>
48 #import <MobileAsset/MAAssetQuery.h>
49 #endif
50
51 #import "TrustEvaluationTestCase.h"
52 #import "CTTests_data.h"
53 #include "../TestMacroConversions.h"
54
55 @interface CTTests : TrustEvaluationTestCase
56
57 @end
58
59 @implementation CTTests
60
61 + (id) CF_RETURNS_RETAINED SecCertificateCreateFromResource:(NSString *)name {
62 NSURL *url = [[NSBundle bundleForClass:[self class]] URLForResource:name withExtension:@".cer" subdirectory:@"si-82-sectrust-ct-data"];
63 NSData *certData = [NSData dataWithContentsOfURL:url];
64 SecCertificateRef cert = SecCertificateCreateWithData(kCFAllocatorDefault, (CFDataRef)certData);
65 return (__bridge id)cert;
66 }
67
68 + (NSData *)DataFromResource:(NSString *)name {
69 NSURL *url = [[NSBundle bundleForClass:[self class]] URLForResource:name withExtension:@".bin" subdirectory:@"si-82-sectrust-ct-data"];
70 return [NSData dataWithContentsOfURL:url];
71 }
72
73 - (NSDictionary *)eval_ct_trust:(NSArray *)certs
74 sCTs:(NSArray *)scts
75 ocspResponses:(NSArray *)ocsps
76 anchors:(NSArray *)anchors
77 trustedCTLogs:(NSArray *)trustedLogs
78 hostname:(NSString *)hostname
79 verifyDate:(NSDate *)date {
80
81 /* Create the trust object */
82 TestTrustEvaluation *trust = nil;
83 SecPolicyRef policy = SecPolicyCreateBasicX509(); // <rdar://problem/50066309> Need to generate new certs for CTTests
84 XCTAssertNotNil(trust = [[TestTrustEvaluation alloc] initWithCertificates:certs policies:@[(__bridge id)policy]],
85 "create trust failed");
86 CFReleaseNull(policy);
87 if (!trust) { return nil; }
88
89 /* Set the optional properties */
90 if (scts) { trust.presentedSCTs = scts; }
91 if (ocsps) { trust.ocspResponses = ocsps; }
92 if (anchors) { trust.anchors = anchors; }
93 if (trustedLogs) { trust.trustedCTLogs = trustedLogs; }
94 if (date) { trust.verifyDate = date; }
95
96 /* Evaluate */
97 NSError *error = nil;
98 XCTAssert([trust evaluate:&error], "failed trust evaluation: %@", error);
99 return trust.resultDictionary;
100 }
101
102 static NSArray *anchors = nil;
103 static NSDate *date_20150307 = nil;
104 static NSDate *date_20160422 = nil;
105 static NSArray *trustedCTLogs = nil;
106
107 + (void)setUp {
108 [super setUp];
109 SecCertificateRef anchor1 = (__bridge SecCertificateRef)[self SecCertificateCreateFromResource:@"CA_alpha"];
110 SecCertificateRef anchor2 = (__bridge SecCertificateRef)[self SecCertificateCreateFromResource:@"CA_beta"];
111 anchors = @[ (__bridge id)anchor1, (__bridge id)anchor2];
112 CFReleaseNull(anchor1);
113 CFReleaseNull(anchor2);
114 date_20150307 = [NSDate dateWithTimeIntervalSinceReferenceDate:447450000.0]; // March 7, 2015 at 11:40:00 AM PST
115 date_20160422 = [NSDate dateWithTimeIntervalSinceReferenceDate:483050000.0]; // April 22, 2016 at 1:33:20 PM PDT
116
117 NSURL *trustedLogsURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"CTlogs"
118 withExtension:@"plist"
119 subdirectory:@"si-82-sectrust-ct-data"];
120 trustedCTLogs = [NSArray arrayWithContentsOfURL:trustedLogsURL];
121
122 #if !TARGET_OS_BRIDGE
123 /* Mock a successful mobile asset check-in so that we enforce CT */
124 UpdateOTACheckInDate();
125 #endif
126 }
127
128 - (void)testOneEmbeddedSCT {
129 NSDictionary *results = nil;
130 SecCertificateRef certF = nil;
131 isnt(certF = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"serverF"], NULL, "create certF");
132 XCTAssertNotNil(results = [self eval_ct_trust:@[(__bridge id)certF] sCTs:nil ocspResponses:nil anchors:anchors
133 trustedCTLogs:trustedCTLogs hostname:nil verifyDate:date_20150307]);
134 XCTAssertNil(results[(__bridge NSString*)kSecTrustCertificateTransparency], "got CT result when no CT expected");
135 XCTAssertNil(results[(__bridge NSString*)kSecTrustExtendedValidation], "got EV result when no EV expected");
136 CFReleaseNull(certF);
137 }
138
139 - (void)testOnePresentedSCT {
140 NSDictionary *results = nil;
141 SecCertificateRef certD = nil;
142 NSData *proofD = nil;
143 isnt(certD = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"serverD"], NULL, "create certD");
144 XCTAssertNotNil(proofD = [CTTests DataFromResource:@"serverD_proof"], "create proofD");
145 XCTAssertNotNil(results = [self eval_ct_trust:@[(__bridge id)certD] sCTs:@[proofD] ocspResponses:nil anchors:anchors
146 trustedCTLogs:trustedCTLogs hostname:nil verifyDate:date_20150307]);
147 XCTAssertNil(results[(__bridge NSString*)kSecTrustCertificateTransparency], "got CT result when no CT expected");
148 XCTAssertNil(results[(__bridge NSString*)kSecTrustExtendedValidation], "got EV result when no EV expected");
149 CFReleaseNull(certD);
150 }
151
152 - (void)testTooFewEmbeddedSCTsForLifetime {
153 NSDictionary *results = nil;
154 SecCertificateRef leaf = nil, subCA = nil, root = nil;
155 isnt(leaf = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"www_digicert_com_2015"], NULL, "create leaf");
156 isnt(subCA = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"digicert_sha2_ev_server_ca"], NULL, "create subCA");
157 isnt(root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"digicert_ev_root_ca"], NULL, "create root");
158 NSArray *certs = @[(__bridge id)leaf, (__bridge id)subCA];
159 XCTAssertNotNil(results = [self eval_ct_trust:certs
160 sCTs:nil ocspResponses:nil anchors:@[(__bridge id)root]
161 trustedCTLogs:nil hostname:@"www.digicert.com" verifyDate:date_20150307]);
162 XCTAssertNil(results[(__bridge NSString*)kSecTrustCertificateTransparency], "got CT result when no CT expected");
163 XCTAssertNil(results[(__bridge NSString*)kSecTrustExtendedValidation], "got EV result when no EV expected");
164 CFReleaseNull(leaf);
165 CFReleaseNull(subCA);
166 CFReleaseNull(root);
167 }
168
169 - (void)testInvalidOCSPResponse {
170 NSDictionary *results = nil;
171 SecCertificateRef certA = nil;
172 NSData *proofA_1 = nil, *invalid_ocsp = nil;
173 isnt(certA = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"serverA"], NULL, "create certA");
174 XCTAssertNotNil(proofA_1 = [CTTests DataFromResource:@"serverA_proof_Alfa_3"], "create proofA_1");
175 XCTAssertNotNil(invalid_ocsp = [CTTests DataFromResource:@"invalid_ocsp_response"], "create invalid ocsp response");
176 XCTAssertNotNil(results = [self eval_ct_trust:@[(__bridge id)certA] sCTs:@[proofA_1] ocspResponses:@[invalid_ocsp] anchors:anchors
177 trustedCTLogs:trustedCTLogs hostname:nil verifyDate:date_20150307]);
178 XCTAssertNil(results[(__bridge NSString*)kSecTrustCertificateTransparency], "got CT result when no CT expected");
179 XCTAssertNil(results[(__bridge NSString*)kSecTrustExtendedValidation], "got EV result when no EV expected");
180 CFReleaseNull(certA);
181 }
182
183 - (void)testOCSPResponseWithBadHash {
184 NSDictionary *results = nil;
185 SecCertificateRef certA = nil;
186 NSData *proofA_1 = nil, *invalid_ocsp = nil;
187 isnt(certA = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"serverA"], NULL, "create certA");
188 XCTAssertNotNil(proofA_1 = [CTTests DataFromResource:@"serverA_proof_Alfa_3"], "create proofA_1");
189 XCTAssertNotNil(invalid_ocsp = [CTTests DataFromResource:@"bad_hash_ocsp_response"], "create ocsp response with bad hash");
190 XCTAssertNotNil(results = [self eval_ct_trust:@[(__bridge id)certA] sCTs:@[proofA_1] ocspResponses:@[invalid_ocsp] anchors:anchors
191 trustedCTLogs:trustedCTLogs hostname:nil verifyDate:date_20150307]);
192 XCTAssertNil(results[(__bridge NSString*)kSecTrustCertificateTransparency], "got CT result when no CT expected");
193 XCTAssertNil(results[(__bridge NSString*)kSecTrustExtendedValidation], "got EV result when no EV expected");
194 CFReleaseNull(certA);
195 }
196
197 - (void)testValidOCSPResponse {
198 NSDictionary *results = nil;
199 SecCertificateRef certA = nil;
200 NSData *proofA_1 = nil, *valid_ocsp = nil;
201 isnt(certA = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"serverA"], NULL, "create certA");
202 XCTAssertNotNil(proofA_1 = [CTTests DataFromResource:@"serverA_proof_Alfa_3"], "create proofA_1");
203 XCTAssertNotNil(valid_ocsp = [CTTests DataFromResource:@"valid_ocsp_response"], "create invalid ocsp response");
204 XCTAssertNotNil(results = [self eval_ct_trust:@[(__bridge id)certA] sCTs:@[proofA_1] ocspResponses:@[valid_ocsp] anchors:anchors
205 trustedCTLogs:trustedCTLogs hostname:nil verifyDate:date_20150307]);
206 XCTAssertNil(results[(__bridge NSString*)kSecTrustCertificateTransparency], "got CT result when no CT expected");
207 XCTAssertNil(results[(__bridge NSString*)kSecTrustExtendedValidation], "got EV result when no EV expected");
208 CFReleaseNull(certA);
209 }
210
211 - (void)testTwoPresentedSCTs {
212 NSDictionary *results = nil;
213 SecCertificateRef certA = nil;
214 NSData *proofA_1 = nil, *proofA_2 = nil;
215 isnt(certA = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"serverA"], NULL, "create certA");
216 XCTAssertNotNil(proofA_1 = [CTTests DataFromResource:@"serverA_proof_Alfa_3"], "create proofA_1");
217 XCTAssertNotNil(proofA_2 = [CTTests DataFromResource:@"serverA_proof_Bravo_3"], "create proofA_2");
218 NSArray *scts = @[proofA_1, proofA_2];
219 XCTAssertNotNil(results = [self eval_ct_trust:@[(__bridge id)certA] sCTs:scts ocspResponses:nil anchors:anchors
220 trustedCTLogs:trustedCTLogs hostname:nil verifyDate:date_20150307]);
221 XCTAssertEqualObjects(results[(__bridge NSString*)kSecTrustCertificateTransparency], @YES, "expected CT result");
222 XCTAssertNil(results[(__bridge NSString*)kSecTrustExtendedValidation], "got EV result when no EV expected");
223 CFReleaseNull(certA);
224 }
225
226 - (void)testThreeEmbeddedSCTs {
227 NSDictionary *results = nil;
228 SecCertificateRef leaf = nil, subCA = nil, root = nil;
229 isnt(leaf = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"www_digicert_com_2016"], NULL, "create leaf");
230 isnt(subCA = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"digicert_sha2_ev_server_ca"], NULL, "create subCA");
231 isnt(root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"digicert_ev_root_ca"], NULL, "create subCA");
232 NSArray *certs = @[(__bridge id)leaf, (__bridge id)subCA];
233 XCTAssertNotNil(results = [self eval_ct_trust:certs
234 sCTs:nil ocspResponses:nil anchors:@[(__bridge id)root]
235 trustedCTLogs:nil hostname:@"www.digicert.com" verifyDate:date_20160422]);
236 #if TARGET_OS_BRIDGE
237 /* BridgeOS doesn't have a root store or CT log list so default CT behavior (without input logs as above) is failed CT validation. */
238 XCTAssertNil(results[(__bridge NSString*)kSecTrustCertificateTransparency], "got CT result when no CT expected");
239 #else
240 XCTAssertEqualObjects(results[(__bridge NSString*)kSecTrustCertificateTransparency], @YES, "expected CT result");
241 #endif
242 #if TARGET_OS_WATCH
243 /* WatchOS doesn't require OCSP for EV flag, so even though the OCSP responder no longer responds for this cert, it is EV on watchOS. */
244 XCTAssertEqualObjects(results[(__bridge NSString*)kSecTrustExtendedValidation], @YES, "expected EV result");
245 #else
246 XCTAssertNil(results[(__bridge NSString*)kSecTrustExtendedValidation], "got EV result when no EV expected");
247 #endif
248 CFReleaseNull(leaf);
249 CFReleaseNull(subCA);
250 CFReleaseNull(root);
251 }
252
253 - (void)testOtherCTCerts {
254 SecCertificateRef cfCert = NULL;
255 NSDictionary *results = nil;
256
257 #define TEST_CASE(x) \
258 do { \
259 isnt(cfCert = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@#x], NULL, "create cfCert from " #x); \
260 XCTAssertNotNil(results = [self eval_ct_trust:@[(__bridge id)cfCert] \
261 sCTs:nil ocspResponses:nil anchors:anchors \
262 trustedCTLogs:trustedCTLogs hostname:nil verifyDate:date_20150307]); \
263 XCTAssertEqualObjects(results[(__bridge NSString*)kSecTrustCertificateTransparency], @YES, "expected CT result"); \
264 XCTAssertNil(results[(__bridge NSString*)kSecTrustExtendedValidation], "got EV result when no EV expected"); \
265 CFReleaseNull(cfCert); \
266 results = nil; \
267 } while (0)
268
269 TEST_CASE(server_1601);
270 TEST_CASE(server_1603);
271 TEST_CASE(server_1604);
272 TEST_CASE(server_1701);
273 TEST_CASE(server_1704);
274 TEST_CASE(server_1705);
275 TEST_CASE(server_1801);
276 TEST_CASE(server_1804);
277 TEST_CASE(server_1805);
278 TEST_CASE(server_2001);
279
280 #undef TEST_CASE
281 }
282
283 - (void)testLogListParsing {
284 NSDictionary *results = nil;
285 SecCertificateRef certF = nil;
286 isnt(certF = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"serverF"], NULL, "create certF");
287
288 /* Empty Log List */
289 NSArray *testLogList = @[];
290 XCTAssertNotNil(results = [self eval_ct_trust:@[(__bridge id)certF] sCTs:nil ocspResponses:nil anchors:anchors
291 trustedCTLogs:testLogList hostname:nil verifyDate:date_20150307]);
292 XCTAssertNil(results[(__bridge NSString*)kSecTrustCertificateTransparency], "got CT result when no CT expected");
293
294 /* Log not a dictionary */
295 testLogList = @[@[]];
296 XCTAssertNotNil(results = [self eval_ct_trust:@[(__bridge id)certF] sCTs:nil ocspResponses:nil anchors:anchors
297 trustedCTLogs:testLogList hostname:nil verifyDate:date_20150307]);
298 XCTAssertNil(results[(__bridge NSString*)kSecTrustCertificateTransparency], "got CT result when no CT expected");
299
300 /* Log list missing "key" key */
301 testLogList = @[@{@"test":@"test"}];
302 XCTAssertNotNil(results = [self eval_ct_trust:@[(__bridge id)certF] sCTs:nil ocspResponses:nil anchors:anchors
303 trustedCTLogs:testLogList hostname:nil verifyDate:date_20150307]);
304 XCTAssertNil(results[(__bridge NSString*)kSecTrustCertificateTransparency], "got CT result when no CT expected");
305
306 /* Value for "key" isn't a data object */
307 testLogList = @[@{@"key":@"test"}];
308 XCTAssertNotNil(results = [self eval_ct_trust:@[(__bridge id)certF] sCTs:nil ocspResponses:nil anchors:anchors
309 trustedCTLogs:testLogList hostname:nil verifyDate:date_20150307]);
310 XCTAssertNil(results[(__bridge NSString*)kSecTrustCertificateTransparency], "got CT result when no CT expected");
311
312 CFReleaseNull(certF);
313 }
314
315 - (void) testPrecertsFail {
316 SecCertificateRef precert = NULL, system_root = NULL;
317 SecTrustRef trust = NULL;
318 NSArray *precert_anchors = nil;
319 NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:561540800.0]; // October 18, 2018 at 12:33:20 AM PDT
320 CFErrorRef error = NULL;
321
322 require_action(system_root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_root"],
323 errOut, fail("failed to create system root"));
324 require_action(precert = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"precert"],
325 errOut, fail("failed to create precert"));
326
327 precert_anchors = @[(__bridge id)system_root];
328 require_noerr_action(SecTrustCreateWithCertificates(precert, NULL, &trust), errOut, fail("failed to create trust object"));
329 require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)precert_anchors), errOut, fail("failed to set anchor certificate"));
330 require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date"));
331
332 is(SecTrustEvaluateWithError(trust, &error), false, "SECURITY: trust evaluation of precert succeeded");
333 if (error) {
334 is(CFErrorGetCode(error), errSecUnknownCriticalExtensionFlag, "got wrong error code for precert, got %ld, expected %d",
335 (long)CFErrorGetCode(error), (int)errSecUnknownCriticalExtensionFlag);
336 } else {
337 fail("expected trust evaluation to fail and it did not.");
338 }
339
340
341 errOut:
342 CFReleaseNull(system_root);
343 CFReleaseNull(precert);
344 CFReleaseNull(error);
345 }
346
347 + (NSArray <NSDictionary *>*)setShardedTrustedLogs:(NSArray <NSDictionary *>*)trustedLogs startTime:(CFAbsoluteTime)startTime endTime:(CFAbsoluteTime)endTime {
348 NSMutableArray <NSDictionary *>* shardedLogs = [trustedLogs mutableCopy];
349 [trustedLogs enumerateObjectsUsingBlock:^(NSDictionary * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
350 NSMutableDictionary *shardedLogData = [obj mutableCopy];
351 shardedLogData[@"start_inclusive"] = [NSDate dateWithTimeIntervalSinceReferenceDate:startTime];
352 shardedLogData[@"end_exclusive"] = [NSDate dateWithTimeIntervalSinceReferenceDate:endTime];
353 [shardedLogs replaceObjectAtIndex:idx withObject:shardedLogData];
354 }];
355 return shardedLogs;
356 }
357
358 - (void)testShardedLogs {
359 NSDictionary *results = nil;
360 SecCertificateRef certA = nil;
361 NSData *proofA_1 = nil, *proofA_2 = nil;
362 isnt(certA = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"serverA"], NULL, "create certA");
363 XCTAssertNotNil(proofA_1 = [CTTests DataFromResource:@"serverA_proof_Alfa_3"], "create proofA_1");
364 XCTAssertNotNil(proofA_2 = [CTTests DataFromResource:@"serverA_proof_Bravo_3"], "create proofA_2");
365 NSArray *scts = @[proofA_1, proofA_2];
366
367 /* Certificate expiry within temporal shard window */
368 NSArray <NSDictionary *> *shardedCTLogs= [CTTests setShardedTrustedLogs:trustedCTLogs startTime:0.0 endTime:CFAbsoluteTimeGetCurrent()];
369 XCTAssertNotNil(results = [self eval_ct_trust:@[(__bridge id)certA] sCTs:scts ocspResponses:nil anchors:anchors
370 trustedCTLogs:shardedCTLogs hostname:nil verifyDate:date_20150307]);
371 XCTAssertEqualObjects(results[(__bridge NSString*)kSecTrustCertificateTransparency], @YES, "expected CT result");
372
373 /* Certificate expiry before temporal shard window */
374 shardedCTLogs= [CTTests setShardedTrustedLogs:trustedCTLogs startTime:CFAbsoluteTimeGetCurrent() endTime:(CFAbsoluteTimeGetCurrent() + 24*3600)];
375 XCTAssertNotNil(results = [self eval_ct_trust:@[(__bridge id)certA] sCTs:scts ocspResponses:nil anchors:anchors
376 trustedCTLogs:shardedCTLogs hostname:nil verifyDate:date_20150307]);
377 XCTAssertNil(results[(__bridge NSString*)kSecTrustCertificateTransparency], "got CT result when no CT expected");
378
379 /* Certificate expiry after temporal shard window */
380 shardedCTLogs= [CTTests setShardedTrustedLogs:trustedCTLogs startTime:0.0 endTime:(24*3600)];
381 XCTAssertNotNil(results = [self eval_ct_trust:@[(__bridge id)certA] sCTs:scts ocspResponses:nil anchors:anchors
382 trustedCTLogs:shardedCTLogs hostname:nil verifyDate:date_20150307]);
383 XCTAssertNil(results[(__bridge NSString*)kSecTrustCertificateTransparency], "got CT result when no CT expected");
384
385 CFReleaseNull(certA);
386 }
387
388 + (NSArray <NSDictionary *>*)setReadOnlyTrustedLogs:(NSArray <NSDictionary *>*)trustedLogs readOnlyTime:(CFAbsoluteTime)readOnlyTime
389 {
390 NSMutableArray <NSDictionary *>*readOnlyLogs = [trustedLogs mutableCopy];
391 [trustedLogs enumerateObjectsUsingBlock:^(NSDictionary * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
392 NSMutableDictionary *logData = [obj mutableCopy];
393 logData[@"frozen"] = [NSDate dateWithTimeIntervalSinceReferenceDate:readOnlyTime];
394 [readOnlyLogs replaceObjectAtIndex:idx withObject:logData];
395 }];
396 return readOnlyLogs;
397 }
398
399 - (void)testReadOnlyLogs {
400 NSDictionary *results = nil;
401 SecCertificateRef certA = nil;
402 NSData *proofA_1 = nil, *proofA_2 = nil;
403 isnt(certA = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"serverA"], NULL, "create certA");
404 XCTAssertNotNil(proofA_1 = [CTTests DataFromResource:@"serverA_proof_Alfa_3"], "create proofA_1");
405 XCTAssertNotNil(proofA_2 = [CTTests DataFromResource:@"serverA_proof_Bravo_3"], "create proofA_2");
406 NSArray *scts = @[proofA_1, proofA_2];
407
408 /* SCTs before read-only date */
409 NSArray <NSDictionary *> *readOnlyCTLogs = [CTTests setReadOnlyTrustedLogs:trustedCTLogs readOnlyTime:CFAbsoluteTimeGetCurrent()];
410 XCTAssertNotNil(readOnlyCTLogs);
411 XCTAssertNotNil(results = [self eval_ct_trust:@[(__bridge id)certA] sCTs:scts ocspResponses:nil anchors:anchors
412 trustedCTLogs:readOnlyCTLogs hostname:nil verifyDate:date_20150307]);
413 XCTAssertEqualObjects(results[(__bridge NSString*)kSecTrustCertificateTransparency], @YES, "expected CT result");
414
415 /* SCTs after read-only date */
416 readOnlyCTLogs = [CTTests setReadOnlyTrustedLogs:trustedCTLogs readOnlyTime:0.0];
417 XCTAssertNotNil(readOnlyCTLogs);
418 XCTAssertNotNil(results = [self eval_ct_trust:@[(__bridge id)certA] sCTs:scts ocspResponses:nil anchors:anchors
419 trustedCTLogs:readOnlyCTLogs hostname:nil verifyDate:date_20150307]);
420 XCTAssertNil(results[(__bridge NSString*)kSecTrustCertificateTransparency], "got CT result when no CT expected");
421
422 CFReleaseNull(certA);
423 }
424
425 + (NSArray <NSDictionary *>*)setRetiredTrustedLogs:(NSArray <NSDictionary *>*)trustedLogs retirementTime:(CFAbsoluteTime)retirementTime indexSet:(NSIndexSet *)indexSet
426 {
427 __block NSMutableArray <NSDictionary *>*retiredLogs = [trustedLogs mutableCopy];
428 [trustedLogs enumerateObjectsAtIndexes:indexSet options:0.0 usingBlock:^(NSDictionary * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
429 NSMutableDictionary *logData = [obj mutableCopy];
430 logData[@"expiry"] = [NSDate dateWithTimeIntervalSinceReferenceDate:retirementTime];
431 [retiredLogs replaceObjectAtIndex:idx withObject:logData];
432 }];
433 return retiredLogs;
434 }
435
436 - (void)testRetiredLogs {
437 NSDictionary *results = nil;
438 SecCertificateRef certA = nil, server1601 = nil;
439 NSData *proofA_1 = nil, *proofA_2 = nil;
440 isnt(certA = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"serverA"], NULL, "create certA");
441 isnt(server1601 = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"server_1601"], NULL, "create server1601");
442 XCTAssertNotNil(proofA_1 = [CTTests DataFromResource:@"serverA_proof_Alfa_3"], "create proofA_1");
443 XCTAssertNotNil(proofA_2 = [CTTests DataFromResource:@"serverA_proof_Bravo_3"], "create proofA_2");
444 NSArray *scts = @[proofA_1, proofA_2];
445
446 NSArray <NSDictionary *> *retiredCTLogs = [CTTests setRetiredTrustedLogs:trustedCTLogs
447 retirementTime:CFAbsoluteTimeGetCurrent()
448 indexSet:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, trustedCTLogs.count)]];
449 /* presented SCTs from retired logs */
450 XCTAssertNotNil(results = [self eval_ct_trust:@[(__bridge id)certA] sCTs:scts ocspResponses:nil anchors:anchors
451 trustedCTLogs:retiredCTLogs hostname:nil verifyDate:date_20150307]);
452 XCTAssertNil(results[(__bridge NSString*)kSecTrustCertificateTransparency], "got CT result when no CT expected");
453
454 /* all embedded SCTs from retired logs */
455 XCTAssertNotNil(results = [self eval_ct_trust:@[(__bridge id)server1601] sCTs:nil ocspResponses:nil anchors:anchors
456 trustedCTLogs:retiredCTLogs hostname:nil verifyDate:date_20150307]);
457 XCTAssertNil(results[(__bridge NSString*)kSecTrustCertificateTransparency], "got CT result when no CT expected");
458
459 /* one embedded SCTs from retired log, before log retirement date (one once or currently qualified SCT) */
460 retiredCTLogs = [CTTests setRetiredTrustedLogs:trustedCTLogs
461 retirementTime:CFAbsoluteTimeGetCurrent()
462 indexSet:[NSIndexSet indexSetWithIndex:0]];
463 XCTAssertNotNil(results = [self eval_ct_trust:@[(__bridge id)server1601] sCTs:nil ocspResponses:nil anchors:anchors
464 trustedCTLogs:retiredCTLogs hostname:nil verifyDate:date_20150307]);
465 XCTAssertEqualObjects(results[(__bridge NSString*)kSecTrustCertificateTransparency], @YES, "expected CT result");
466
467 /* one embedded SCT from retired log, after retirement date */
468 retiredCTLogs = [CTTests setRetiredTrustedLogs:trustedCTLogs
469 retirementTime:0.0
470 indexSet:[NSIndexSet indexSetWithIndex:0]];
471 XCTAssertNotNil(results = [self eval_ct_trust:@[(__bridge id)server1601] sCTs:nil ocspResponses:nil anchors:anchors
472 trustedCTLogs:retiredCTLogs hostname:nil verifyDate:date_20150307]);
473 XCTAssertNil(results[(__bridge NSString*)kSecTrustCertificateTransparency], "got CT result when no CT expected");
474
475 /* one embedded SCT before retirement date, one embedded SCT before read-only date */
476 retiredCTLogs = [CTTests setReadOnlyTrustedLogs:trustedCTLogs readOnlyTime:CFAbsoluteTimeGetCurrent()];
477 retiredCTLogs = [CTTests setRetiredTrustedLogs:retiredCTLogs retirementTime:CFAbsoluteTimeGetCurrent() indexSet:[NSIndexSet indexSetWithIndex:0]];
478 XCTAssertNotNil(results = [self eval_ct_trust:@[(__bridge id)server1601] sCTs:nil ocspResponses:nil anchors:anchors
479 trustedCTLogs:retiredCTLogs hostname:nil verifyDate:date_20150307]);
480 XCTAssertEqualObjects(results[(__bridge NSString*)kSecTrustCertificateTransparency], @YES, "expected CT result");
481
482 CFReleaseNull(certA);
483 CFReleaseNull(server1601);
484 }
485
486 //TODO: add more tests
487 // <rdar://problem/23849697> Expand unit tests for CT
488 // missing coverage:
489 // -other signing algorithms
490 // -v2 SCTs
491 // -future timestamps
492 // -SCT signature doesn't verify
493 // -OCSP-delivered SCTs
494 // -unknown logs (embedded, TLS, and OCSP)
495 // -two SCTs from the same log (different timestamps)
496
497 @end
498
499 // MARK: -
500 // MARK: CT Enforcement Exceptions tests
501 @interface CTExceptionsTests : TrustEvaluationTestCase
502 @end
503
504 @implementation CTExceptionsTests
505 #if !TARGET_OS_BRIDGE // bridgeOS doesn't permit CT exceptions
506 + (void)setUp {
507 [super setUp];
508 NSURL *trustedLogsURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"CTlogs"
509 withExtension:@"plist"
510 subdirectory:@"si-82-sectrust-ct-data"];
511 trustedCTLogs = [NSArray arrayWithContentsOfURL:trustedLogsURL];
512 NSData *rootHash = [NSData dataWithBytes:_system_root_hash length:sizeof(_system_root_hash)];
513 CFPreferencesSetAppValue(CFSTR("TestCTRequiredSystemRoot"), (__bridge CFDataRef)rootHash, CFSTR("com.apple.security"));
514 CFPreferencesAppSynchronize(CFSTR("com.apple.security"));
515 }
516
517 - (void)testSetCTExceptions {
518 CFErrorRef error = NULL;
519 const CFStringRef TrustTestsAppID = CFSTR("com.apple.trusttests");
520 const CFStringRef AnotherAppID = CFSTR("com.apple.security.not-this-one");
521 CFDictionaryRef copiedExceptions = NULL;
522
523 /* Verify no exceptions set */
524 is(copiedExceptions = SecTrustStoreCopyCTExceptions(NULL, NULL), NULL, "no exceptions set");
525 if (copiedExceptions) {
526 /* If we're starting out with exceptions set, a lot of the following will also fail, so just skip them */
527 CFReleaseNull(copiedExceptions);
528 return;
529 }
530
531 /* Set exceptions with specified AppID */
532 NSDictionary *exceptions1 = @{
533 (__bridge NSString*)kSecCTExceptionsDomainsKey: @[@"test.apple.com", @".test.apple.com"],
534 };
535 ok(SecTrustStoreSetCTExceptions(TrustTestsAppID, (__bridge CFDictionaryRef)exceptions1, &error),
536 "failed to set exceptions for TrustTests: %@", error);
537
538 /* Copy all exceptions (with only one set) */
539 ok(copiedExceptions = SecTrustStoreCopyCTExceptions(NULL, &error),
540 "failed to copy all exceptions: %@", error);
541 ok([exceptions1 isEqualToDictionary:(__bridge NSDictionary*)copiedExceptions],
542 "got the wrong exceptions back");
543 CFReleaseNull(copiedExceptions);
544
545 /* Copy this app's exceptions */
546 ok(copiedExceptions = SecTrustStoreCopyCTExceptions(TrustTestsAppID, &error),
547 "failed to copy TrustTests' exceptions: %@", error);
548 ok([exceptions1 isEqualToDictionary:(__bridge NSDictionary*)copiedExceptions],
549 "got the wrong exceptions back");
550 CFReleaseNull(copiedExceptions);
551
552 /* Copy a different app's exceptions */
553 is(copiedExceptions = SecTrustStoreCopyCTExceptions(AnotherAppID, &error), NULL,
554 "failed to copy different app's exceptions: %@", error);
555 CFReleaseNull(copiedExceptions);
556
557 /* Set different exceptions with implied AppID */
558 CFDataRef leafHash = SecSHA256DigestCreate(NULL, _system_after_leafSPKI, sizeof(_system_after_leafSPKI));
559 NSDictionary *leafException = @{
560 (__bridge NSString*)kSecCTExceptionsHashAlgorithmKey : @"sha256",
561 (__bridge NSString*)kSecCTExceptionsSPKIHashKey : (__bridge NSData*)leafHash,
562 };
563 NSDictionary *exceptions2 = @{
564 (__bridge NSString*)kSecCTExceptionsDomainsKey: @[@".test.apple.com"],
565 (__bridge NSString*)kSecCTExceptionsCAsKey : @[ leafException ]
566 };
567 ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions2, &error),
568 "failed to set exceptions for this app: %@", error);
569
570 /* Ensure exceptions are replaced for TrustTests */
571 ok(copiedExceptions = SecTrustStoreCopyCTExceptions(TrustTestsAppID, &error),
572 "failed to copy TrustTests' exceptions: %@", error);
573 ok([exceptions2 isEqualToDictionary:(__bridge NSDictionary*)copiedExceptions],
574 "got the wrong exceptions back");
575 CFReleaseNull(copiedExceptions);
576
577 /* Set exceptions with a different AppID */
578 CFDataRef rootHash = SecSHA256DigestCreate(NULL, _system_rootSPKI, sizeof(_system_rootSPKI));
579 NSDictionary *rootExceptions = @{
580 (__bridge NSString*)kSecCTExceptionsHashAlgorithmKey : @"sha256",
581 (__bridge NSString*)kSecCTExceptionsSPKIHashKey : (__bridge NSData*)rootHash,
582 };
583 NSDictionary *exceptions3 = @{ (__bridge NSString*)kSecCTExceptionsCAsKey : @[ rootExceptions ] };
584 ok(SecTrustStoreSetCTExceptions(AnotherAppID, (__bridge CFDictionaryRef)exceptions3, &error),
585 "failed to set exceptions for different app: %@", error);
586
587 /* Copy only one of the app's exceptions */
588 ok(copiedExceptions = SecTrustStoreCopyCTExceptions(TrustTestsAppID, &error),
589 "failed to copy TrustTests' exceptions: %@", error);
590 ok([exceptions2 isEqualToDictionary:(__bridge NSDictionary*)copiedExceptions],
591 "got the wrong exceptions back");
592 CFReleaseNull(copiedExceptions);
593
594 /* Set empty exceptions */
595 NSDictionary *empty = @{};
596 ok(SecTrustStoreSetCTExceptions(TrustTestsAppID, (__bridge CFDictionaryRef)empty, &error),
597 "failed to set empty exceptions");
598
599 /* Copy exceptiosn to ensure no change */
600 ok(copiedExceptions = SecTrustStoreCopyCTExceptions(TrustTestsAppID, &error),
601 "failed to copy TrustTests' exceptions: %@", error);
602 ok([exceptions2 isEqualToDictionary:(__bridge NSDictionary*)copiedExceptions],
603 "got the wrong exceptions back");
604 CFReleaseNull(copiedExceptions);
605
606 /* Copy all exceptions */
607 ok(copiedExceptions = SecTrustStoreCopyCTExceptions(NULL, &error),
608 "failed to copy all exceptions: %@", error);
609 is(CFDictionaryGetCount(copiedExceptions), 2, "Got the wrong number of all exceptions");
610 NSDictionary *nsCopiedExceptions = CFBridgingRelease(copiedExceptions);
611 NSArray *domainExceptions = nsCopiedExceptions[(__bridge NSString*)kSecCTExceptionsDomainsKey];
612 NSArray *caExceptions = nsCopiedExceptions[(__bridge NSString*)kSecCTExceptionsCAsKey];
613 ok(domainExceptions && caExceptions, "Got both domain and CA exceptions");
614 ok([domainExceptions count] == 1, "Got 1 domain exception");
615 ok([caExceptions count] == 2, "Got 2 CA exceptions");
616 ok([domainExceptions[0] isEqualToString:@".test.apple.com"], "domain exception is .test.apple.com");
617 ok([caExceptions containsObject:leafException] && [caExceptions containsObject:rootExceptions], "got expected leaf and root CA exceptions");
618
619 /* Reset other app's exceptions */
620 ok(SecTrustStoreSetCTExceptions(AnotherAppID, NULL, &error),
621 "failed to reset exceptions for different app: %@", error);
622 ok(copiedExceptions = SecTrustStoreCopyCTExceptions(NULL, &error),
623 "failed to copy all exceptions: %@", error);
624 ok([exceptions2 isEqualToDictionary:(__bridge NSDictionary*)copiedExceptions],
625 "got the wrong exceptions back");
626 CFReleaseNull(copiedExceptions);
627
628 #define check_errSecParam \
629 if (error) { \
630 is(CFErrorGetCode(error), errSecParam, "bad input produced unxpected error code: %ld", (long)CFErrorGetCode(error)); \
631 } else { \
632 fail("expected failure to set NULL exceptions"); \
633 }
634
635 /* Set exceptions with bad inputs */
636 NSDictionary *badExceptions = @{
637 (__bridge NSString*)kSecCTExceptionsDomainsKey: @[@"test.apple.com", @".test.apple.com"],
638 @"not a key": @"not a value",
639 };
640 is(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)badExceptions, &error), false,
641 "set exceptions with unknown key");
642 check_errSecParam
643
644 badExceptions = @{ (__bridge NSString*)kSecCTExceptionsDomainsKey:@"test.apple.com" };
645 is(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)badExceptions, &error), false,
646 "set exceptions with bad value");
647 check_errSecParam
648
649 badExceptions = @{ (__bridge NSString*)kSecCTExceptionsDomainsKey: @[ @{} ] };
650 is(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)badExceptions, &error), false,
651 "set exceptions with bad array value");
652 check_errSecParam
653
654 badExceptions = @{ (__bridge NSString*)kSecCTExceptionsCAsKey: @[ @"test.apple.com" ] };
655 is(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)badExceptions, &error), false,
656 "set exceptions with bad array value");
657 check_errSecParam
658
659 badExceptions = @{ (__bridge NSString*)kSecCTExceptionsCAsKey: @[ @{
660 (__bridge NSString*)kSecCTExceptionsHashAlgorithmKey : @"sha256",
661 @"not-a-key" : (__bridge NSData*)rootHash,
662 }] };
663 is(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)badExceptions, &error), false,
664 "set exceptions with bad CA dictionary value");
665 check_errSecParam
666
667 badExceptions = @{ (__bridge NSString*)kSecCTExceptionsCAsKey: @[ @{
668 (__bridge NSString*)kSecCTExceptionsHashAlgorithmKey : @"sha256",
669 }] };
670 is(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)badExceptions, &error), false,
671 "set exceptions with bad CA dictionary value");
672 check_errSecParam
673
674 badExceptions = @{ (__bridge NSString*)kSecCTExceptionsCAsKey: @[ @{
675 (__bridge NSString*)kSecCTExceptionsHashAlgorithmKey : @"sha256",
676 (__bridge NSString*)kSecCTExceptionsSPKIHashKey : (__bridge NSData*)rootHash,
677 @"not-a-key":@"not-a-value"
678 }] };
679 is(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)badExceptions, &error), false,
680 "set exceptions with bad CA dictionary value");
681 check_errSecParam
682
683 badExceptions = @{ (__bridge NSString*)kSecCTExceptionsDomainsKey: @[ @".com" ] };
684 is(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)badExceptions, &error), false,
685 "set exceptions with TLD value");
686 check_errSecParam
687 #undef check_errSecParam
688
689 /* Remove exceptions using empty arrays */
690 NSDictionary *emptyArrays = @{
691 (__bridge NSString*)kSecCTExceptionsDomainsKey: @[],
692 (__bridge NSString*)kSecCTExceptionsCAsKey : @[]
693 };
694 ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)emptyArrays, &error),
695 "failed to set empty array exceptions for this app: %@", error);
696 is(copiedExceptions = SecTrustStoreCopyCTExceptions(NULL, NULL), NULL, "no exceptions set");
697
698 CFReleaseNull(leafHash);
699 CFReleaseNull(rootHash);
700 }
701
702 #define evalTrustExpectingError(errCode, ...) \
703 is(SecTrustEvaluateWithError(trust, &error), false, __VA_ARGS__); \
704 if (error) { \
705 is(CFErrorGetCode(error), errCode, "got wrong error code, got %ld, expected %d", \
706 (long)CFErrorGetCode(error), (int)errCode); \
707 } else { \
708 fail("expected trust evaluation to fail and it did not."); \
709 } \
710 CFReleaseNull(error);
711
712 - (void) testSpecificDomainExceptions {
713 SecCertificateRef system_root = NULL, system_server_after = NULL, system_server_after_with_CT = NULL;
714 SecTrustRef trust = NULL;
715 SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com"));
716 NSArray *exceptions_anchors = nil;
717 NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT
718 CFErrorRef error = nil;
719 NSDictionary *exceptions = nil;
720
721 require_action(system_root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_root"],
722 errOut, fail("failed to create system root"));
723 require_action(system_server_after = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_after"],
724 errOut, fail("failed to create system server cert issued after flag day"));
725 require_action(system_server_after_with_CT = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_after_scts"],
726 errOut, fail("failed to create system server cert issued after flag day with SCTs"));
727
728 exceptions_anchors = @[ (__bridge id)system_root ];
729 require_noerr_action(SecTrustCreateWithCertificates(system_server_after, policy, &trust), errOut, fail("failed to create trust"));
730 require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)exceptions_anchors), errOut, fail("failed to set anchors"));
731 require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date"));
732 require_noerr_action(SecTrustSetTrustedLogs(trust, (__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs")); // set trusted logs to trigger enforcing behavior
733
734 /* superdomain exception without CT fails */
735 exceptions = @{ (__bridge NSString*)kSecCTExceptionsDomainsKey : @[@"test.apple.com"] };
736 ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error), "failed to set exceptions: %@", error);
737 evalTrustExpectingError(errSecVerifyActionFailed, "superdomain exception unexpectedly succeeded");
738
739 /* subdomain exceptions without CT fails */
740 exceptions = @{ (__bridge NSString*)kSecCTExceptionsDomainsKey : @[@"one.ct.test.apple.com"] };
741 ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error), "failed to set exceptions: %@", error);
742 SecTrustSetNeedsEvaluation(trust);
743 evalTrustExpectingError(errSecVerifyActionFailed, "subdomain exception unexpectedly succeeded")
744
745 /* no match without CT fails */
746 exceptions = @{ (__bridge NSString*)kSecCTExceptionsDomainsKey : @[@"example.com"] };
747 ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error), "failed to set exceptions: %@", error);
748 SecTrustSetNeedsEvaluation(trust);
749 evalTrustExpectingError(errSecVerifyActionFailed, "unrelated domain exception unexpectedly succeeded");
750
751 /* matching domain without CT succeeds */
752 exceptions = @{ (__bridge NSString*)kSecCTExceptionsDomainsKey : @[@"ct.test.apple.com"] };
753 ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error), "failed to set exceptions: %@", error);
754 SecTrustSetNeedsEvaluation(trust);
755 is(SecTrustEvaluateWithError(trust, &error), true, "exact match domain exception did not apply");
756
757 /* matching domain with CT succeeds */
758 CFReleaseNull(trust);
759 require_noerr_action(SecTrustCreateWithCertificates(system_server_after_with_CT, policy, &trust), errOut, fail("failed to create trust"));
760 require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)exceptions_anchors), errOut, fail("failed to set anchors"));
761 require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date"));
762 require_noerr_action(SecTrustSetTrustedLogs(trust, (__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs")); // set trusted logs to trigger enforcing behavior
763 is(SecTrustEvaluateWithError(trust, &error), true, "ct cert should always pass");
764
765 ok(SecTrustStoreSetCTExceptions(NULL, NULL, &error), "failed to reset exceptions: %@", error);
766
767 errOut:
768 CFReleaseNull(system_root);
769 CFReleaseNull(system_server_after);
770 CFReleaseNull(system_server_after_with_CT);
771 CFReleaseNull(trust);
772 CFReleaseNull(policy);
773 CFReleaseNull(error);
774 }
775
776 - (void) testSubdomainExceptions {
777 SecCertificateRef system_root = NULL, system_server_after = NULL, system_server_after_with_CT = NULL;
778 SecTrustRef trust = NULL;
779 SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com"));
780 NSArray *exceptions_anchors = nil;
781 NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT
782 CFErrorRef error = nil;
783 NSDictionary *exceptions = nil;
784
785 require_action(system_root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_root"],
786 errOut, fail("failed to create system root"));
787 require_action(system_server_after = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_after"],
788 errOut, fail("failed to create system server cert issued after flag day"));
789 require_action(system_server_after_with_CT = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_after_scts"],
790 errOut, fail("failed to create system server cert issued after flag day with SCTs"));
791
792 exceptions_anchors = @[ (__bridge id)system_root ];
793 require_noerr_action(SecTrustCreateWithCertificates(system_server_after, policy, &trust), errOut, fail("failed to create trust"));
794 require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)exceptions_anchors), errOut, fail("failed to set anchors"));
795 require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date"));
796 require_noerr_action(SecTrustSetTrustedLogs(trust, (__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs")); // set trusted logs to trigger enforcing behavior
797
798 /* superdomain exception without CT succeeds */
799 exceptions = @{ (__bridge NSString*)kSecCTExceptionsDomainsKey : @[@".test.apple.com"] };
800 ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error), "failed to set exceptions: %@", error);
801 is(SecTrustEvaluateWithError(trust, &error), true, "superdomain exception did not apply");
802
803 /* exact domain exception without CT succeeds */
804 exceptions = @{ (__bridge NSString*)kSecCTExceptionsDomainsKey : @[@".ct.test.apple.com"] };
805 ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error), "failed to set exceptions: %@", error);
806 SecTrustSetNeedsEvaluation(trust);
807 is(SecTrustEvaluateWithError(trust, &error), true, "exact domain exception did not apply");
808
809 /* no match without CT fails */
810 exceptions = @{ (__bridge NSString*)kSecCTExceptionsDomainsKey : @[@".example.com"] };
811 ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error), "failed to set exceptions: %@", error);
812 SecTrustSetNeedsEvaluation(trust);
813 evalTrustExpectingError(errSecVerifyActionFailed, "unrelated domain exception unexpectedly succeeded");
814
815 /* subdomain without CT fails */
816 exceptions = @{ (__bridge NSString*)kSecCTExceptionsDomainsKey : @[@".one.ct.test.apple.com"] };
817 ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error), "failed to set exceptions: %@", error);
818 SecTrustSetNeedsEvaluation(trust);
819 evalTrustExpectingError(errSecVerifyActionFailed, "subdomain exception unexpectedly succeeded");
820
821 ok(SecTrustStoreSetCTExceptions(NULL, NULL, &error), "failed to reset exceptions: %@", error);
822
823 errOut:
824 CFReleaseNull(system_root);
825 CFReleaseNull(system_server_after);
826 CFReleaseNull(system_server_after_with_CT);
827 CFReleaseNull(trust);
828 CFReleaseNull(policy);
829 CFReleaseNull(error);
830 }
831
832 - (void) testMixedDomainExceptions {
833 SecCertificateRef system_root = NULL, system_server_after = NULL, system_server_after_with_CT = NULL;
834 SecTrustRef trust = NULL;
835 SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com"));
836 NSArray *exceptions_anchors = nil;
837 NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT
838 CFErrorRef error = nil;
839 NSDictionary *exceptions = nil;
840
841 require_action(system_root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_root"],
842 errOut, fail("failed to create system root"));
843 require_action(system_server_after = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_after"],
844 errOut, fail("failed to create system server cert issued after flag day"));
845 require_action(system_server_after_with_CT = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_after_scts"],
846 errOut, fail("failed to create system server cert issued after flag day with SCTs"));
847
848 exceptions_anchors = @[ (__bridge id)system_root ];
849 require_noerr_action(SecTrustCreateWithCertificates(system_server_after, policy, &trust), errOut, fail("failed to create trust"));
850 require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)exceptions_anchors), errOut, fail("failed to set anchors"));
851 require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date"));
852 require_noerr_action(SecTrustSetTrustedLogs(trust, (__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs")); // set trusted logs to trigger enforcing behavior
853
854 /* specific domain exception without CT succeeds */
855 exceptions = @{ (__bridge NSString*)kSecCTExceptionsDomainsKey : @[@"ct.test.apple.com", @".example.com" ] };
856 ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error), "failed to set exceptions: %@", error);
857 is(SecTrustEvaluateWithError(trust, &error), true, "one of exact domain exception did not apply");
858
859 /* super domain exception without CT succeeds */
860 exceptions = @{ (__bridge NSString*)kSecCTExceptionsDomainsKey : @[@".apple.com", @"example.com" ] };
861 ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error), "failed to set exceptions: %@", error);
862 SecTrustSetNeedsEvaluation(trust);
863 is(SecTrustEvaluateWithError(trust, &error), true, "one of superdomain exception did not apply");
864
865 /* both super domain and specific domain exceptions without CT succeeds */
866 exceptions = @{ (__bridge NSString*)kSecCTExceptionsDomainsKey : @[@"ct.test.apple.com", @".apple.com" ] };
867 ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error), "failed to set exceptions: %@", error);
868 SecTrustSetNeedsEvaluation(trust);
869 is(SecTrustEvaluateWithError(trust, &error), true, "both domain exception did not apply");
870
871 /* neither specific domain nor super domain exceptions without CT fails */
872 exceptions = @{ (__bridge NSString*)kSecCTExceptionsDomainsKey : @[@"apple.com", @".example.com" ] };
873 ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error), "failed to set exceptions: %@", error);
874 SecTrustSetNeedsEvaluation(trust);
875 evalTrustExpectingError(errSecVerifyActionFailed, "no match domain unexpectedly succeeded");
876
877 ok(SecTrustStoreSetCTExceptions(NULL, NULL, &error), "failed to reset exceptions: %@", error);
878
879 errOut:
880 CFReleaseNull(system_root);
881 CFReleaseNull(system_server_after);
882 CFReleaseNull(system_server_after_with_CT);
883 CFReleaseNull(trust);
884 CFReleaseNull(policy);
885 CFReleaseNull(error);
886 }
887
888 - (void) test_ct_leaf_exceptions {
889 SecCertificateRef system_root = NULL, system_server_after = NULL, system_server_after_with_CT = NULL;
890 SecTrustRef trust = NULL;
891 SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com"));
892 NSArray *exceptions_anchors = nil;
893 NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT
894 CFErrorRef error = nil;
895 NSDictionary *leafException = nil, *exceptions = nil;
896 NSData *leafHash = nil;
897
898 require_action(system_root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_root"],
899 errOut, fail("failed to create system root"));
900 require_action(system_server_after = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_after"],
901 errOut, fail("failed to create system server cert issued after flag day"));
902 require_action(system_server_after_with_CT = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_after_scts"],
903 errOut, fail("failed to create system server cert issued after flag day with SCTs"));
904
905 exceptions_anchors = @[ (__bridge id)system_root ];
906 require_noerr_action(SecTrustCreateWithCertificates(system_server_after, policy, &trust), errOut, fail("failed to create trust"));
907 require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)exceptions_anchors), errOut, fail("failed to set anchors"));
908 require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date"));
909 require_noerr_action(SecTrustSetTrustedLogs(trust, (__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs")); // set trusted logs to trigger enforcing behavior
910
911 /* set exception on leaf cert without CT */
912 leafHash = CFBridgingRelease(SecCertificateCopySubjectPublicKeyInfoSHA256Digest(system_server_after));
913 leafException = @{ (__bridge NSString*)kSecCTExceptionsHashAlgorithmKey : @"sha256",
914 (__bridge NSString*)kSecCTExceptionsSPKIHashKey : leafHash,
915 };
916 exceptions = @{ (__bridge NSString*)kSecCTExceptionsCAsKey : @[ leafException ] };
917 ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error),
918 "failed to set exceptions: %@", error);
919 is(SecTrustEvaluateWithError(trust, &error), true, "leaf public key exception did not apply");
920
921 /* set exception on leaf cert with CT */
922 leafHash = CFBridgingRelease(SecCertificateCopySubjectPublicKeyInfoSHA256Digest(system_server_after_with_CT));
923 leafException = @{ (__bridge NSString*)kSecCTExceptionsHashAlgorithmKey : @"sha256",
924 (__bridge NSString*)kSecCTExceptionsSPKIHashKey : leafHash,
925 };
926 exceptions = @{ (__bridge NSString*)kSecCTExceptionsCAsKey : @[ leafException ] };
927 ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error),
928 "failed to set exceptions: %@", error);
929 SecTrustSetNeedsEvaluation(trust);
930 evalTrustExpectingError(errSecVerifyActionFailed, "leaf cert with no public key exceptions succeeded");
931
932 /* matching public key with CT succeeds */
933 CFReleaseNull(trust);
934 require_noerr_action(SecTrustCreateWithCertificates(system_server_after_with_CT, policy, &trust), errOut, fail("failed to create trust"));
935 require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)exceptions_anchors), errOut, fail("failed to set anchors"));
936 require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date"));
937 require_noerr_action(SecTrustSetTrustedLogs(trust, (__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs")); // set trusted logs to trigger enforcing behavior
938 is(SecTrustEvaluateWithError(trust, &error), true, "ct cert should always pass");
939
940 ok(SecTrustStoreSetCTExceptions(NULL, NULL, &error), "failed to reset exceptions: %@", error);
941
942 errOut:
943 CFReleaseNull(system_root);
944 CFReleaseNull(system_server_after);
945 CFReleaseNull(system_server_after_with_CT);
946 CFReleaseNull(trust);
947 CFReleaseNull(policy);
948 CFReleaseNull(error);
949 }
950
951 - (void) test_ct_unconstrained_ca_exceptions {
952 SecCertificateRef root = NULL, subca = NULL;
953 SecCertificateRef server_matching = NULL, server_matching_with_CT = NULL, server_partial = NULL, server_no_match = NULL, server_no_org = NULL;
954 SecTrustRef trust = NULL;
955 SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com"));
956 NSArray *exceptions_anchors = nil, *certs = nil;
957 NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT
958 CFErrorRef error = nil;
959 NSDictionary *caException = nil, *exceptions = nil;
960 NSData *caHash = nil;
961
962 require_action(root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_root"],
963 errOut, fail("failed to create system root"));
964 require_action(subca = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_unconstrained_subca"],
965 errOut, fail("failed to create subca"));
966 require_action(server_matching = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_matching_orgs"],
967 errOut, fail("failed to create server cert with matching orgs"));
968 require_action(server_matching_with_CT = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_matching_orgs_scts"],
969 errOut, fail("failed to create server cert with matching orgs and scts"));
970 require_action(server_partial = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_partial_orgs"],
971 errOut, fail("failed to create server cert with partial orgs"));
972 require_action(server_no_match = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_nonmatching_orgs"],
973 errOut, fail("failed to create server cert with non-matching orgs"));
974 require_action(server_no_org = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_no_orgs"],
975 errOut, fail("failed to create server cert with no orgs"));
976
977 exceptions_anchors = @[ (__bridge id)root ];
978
979 #define createTrust(certs) \
980 CFReleaseNull(trust); \
981 require_noerr_action(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trust), errOut, fail("failed to create trust")); \
982 require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)exceptions_anchors), errOut, fail("failed to set anchors")); \
983 require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date")); \
984 require_noerr_action(SecTrustSetTrustedLogs(trust, (__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs"));
985
986 /* Set exception on the subCA */
987 caHash = CFBridgingRelease(SecCertificateCopySubjectPublicKeyInfoSHA256Digest(subca));
988 caException = @{ (__bridge NSString*)kSecCTExceptionsHashAlgorithmKey : @"sha256",
989 (__bridge NSString*)kSecCTExceptionsSPKIHashKey : caHash,
990 };
991 exceptions = @{ (__bridge NSString*)kSecCTExceptionsCAsKey : @[ caException ] };
992 ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error),
993 "failed to set exceptions: %@", error);
994
995 /* Verify that non-CT cert with Orgs matching subCA passes */
996 certs = @[ (__bridge id)server_matching, (__bridge id)subca];
997 createTrust(certs);
998 is(SecTrustEvaluateWithError(trust, &error), true, "matching org subca exception did not apply: %@", error);
999
1000 /* Verify that CT cert with Orgs matching subCA passes */
1001 certs = @[ (__bridge id)server_matching_with_CT, (__bridge id)subca];
1002 createTrust(certs);
1003 is(SecTrustEvaluateWithError(trust, &error), true, "CT matching org subca exception did not apply: %@", error);
1004
1005 /* Verify that non-CT cert with partial Org match fails */
1006 certs = @[ (__bridge id)server_partial, (__bridge id)subca];
1007 createTrust(certs);
1008 evalTrustExpectingError(errSecVerifyActionFailed, "partial matching org leaf succeeded");
1009
1010 /* Verify that a non-CT cert with non-matching Org fails */
1011 certs = @[ (__bridge id)server_no_match, (__bridge id)subca];
1012 createTrust(certs);
1013 evalTrustExpectingError(errSecVerifyActionFailed, "non-matching org leaf succeeded");
1014
1015 /* Verify that a non-CT cert with no Org fails */
1016 certs = @[ (__bridge id)server_no_org, (__bridge id)subca];
1017 createTrust(certs);
1018 evalTrustExpectingError(errSecVerifyActionFailed, "no org leaf succeeded");
1019
1020 ok(SecTrustStoreSetCTExceptions(NULL, NULL, &error), "failed to reset exceptions: %@", error);
1021
1022 #undef createTrust
1023
1024 errOut:
1025 CFReleaseNull(root);
1026 CFReleaseNull(subca);
1027 CFReleaseNull(server_matching);
1028 CFReleaseNull(server_matching_with_CT);
1029 CFReleaseNull(server_partial);
1030 CFReleaseNull(server_no_match);
1031 CFReleaseNull(server_no_org);
1032 CFReleaseNull(trust);
1033 CFReleaseNull(policy);
1034 CFReleaseNull(error);
1035 }
1036
1037 - (void) test_ct_constrained_ca_exceptions {
1038 SecCertificateRef root = NULL, org_constrained_subca = NULL;
1039 SecCertificateRef constraint_pass_server = NULL, constraint_pass_server_ct = NULL, constraint_fail_server = NULL;
1040 SecCertificateRef dn_constrained_subca = NULL, dn_constrained_server = NULL, dn_constrained_server_mismatch = NULL;
1041 SecCertificateRef dns_constrained_subca = NULL, dns_constrained_server = NULL, dns_constrained_server_mismatch = NULL;
1042 SecTrustRef trust = NULL;
1043 SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com"));
1044 NSArray *exceptions_anchors = nil, *certs = nil;
1045 NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT
1046 CFErrorRef error = nil;
1047 NSDictionary *caException = nil, *exceptions = nil;
1048 NSMutableArray *caExceptions = [NSMutableArray array];
1049 NSData *caHash = nil;
1050
1051 require_action(root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_root"],
1052 errOut, fail("failed to create system root"));
1053 require_action(org_constrained_subca = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_constrained_subca"],
1054 errOut, fail("failed to create org-constrained subca"));
1055 require_action(constraint_pass_server = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_constrained_server"],
1056 errOut, fail("failed to create constrained non-CT leaf"));
1057 require_action(constraint_pass_server_ct = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_constrained_server_scts"],
1058 errOut, fail("failed to create constrained CT leaf"));
1059 require_action(constraint_fail_server= (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_constrained_fail_server"],
1060 errOut, fail("failed to create constraint failure leaf"));
1061 require_action(dn_constrained_subca = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_constrained_no_org_subca"],
1062 errOut, fail("failed to create dn-constrained subca"));
1063 require_action(dn_constrained_server = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_constrained_no_org_server"],
1064 errOut, fail("failed to create dn-constrained leaf"));
1065 require_action(dn_constrained_server_mismatch = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_constrained_no_org_server_mismatch"],
1066 errOut, fail("failed to create dn-constrained leaf with mismatched orgs"));
1067 require_action(dns_constrained_subca = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_constrained_no_dn_subca"],
1068 errOut, fail("failed to create dns-constrained subca"));
1069 require_action(dns_constrained_server = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_constrained_no_dn_server"],
1070 errOut, fail("failed to create dns-constrained leaf"));
1071 require_action(dns_constrained_server_mismatch = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_constrained_no_dn_server_mismatch"],
1072 errOut, fail("failed to create dns-constrained leaf with mismatched orgs"));
1073
1074 exceptions_anchors = @[ (__bridge id)root ];
1075
1076 /* Set exception on the subCAs */
1077 caHash = CFBridgingRelease(SecCertificateCopySubjectPublicKeyInfoSHA256Digest(org_constrained_subca));
1078 caException = @{ (__bridge NSString*)kSecCTExceptionsHashAlgorithmKey : @"sha256",
1079 (__bridge NSString*)kSecCTExceptionsSPKIHashKey : caHash,
1080 };
1081 [caExceptions addObject:caException];
1082
1083 caHash = CFBridgingRelease(SecCertificateCopySubjectPublicKeyInfoSHA256Digest(dn_constrained_subca));
1084 caException = @{ (__bridge NSString*)kSecCTExceptionsHashAlgorithmKey : @"sha256",
1085 (__bridge NSString*)kSecCTExceptionsSPKIHashKey : caHash,
1086 };
1087 [caExceptions addObject:caException];
1088
1089 caHash = CFBridgingRelease(SecCertificateCopySubjectPublicKeyInfoSHA256Digest(dns_constrained_subca));
1090 caException = @{ (__bridge NSString*)kSecCTExceptionsHashAlgorithmKey : @"sha256",
1091 (__bridge NSString*)kSecCTExceptionsSPKIHashKey : caHash,
1092 };
1093 [caExceptions addObject:caException];
1094 exceptions = @{ (__bridge NSString*)kSecCTExceptionsCAsKey : caExceptions };
1095 ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error),
1096 "failed to set exceptions: %@", error);
1097
1098 #define createTrust(certs) \
1099 CFReleaseNull(trust); \
1100 require_noerr_action(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trust), errOut, fail("failed to create trust")); \
1101 require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)exceptions_anchors), errOut, fail("failed to set anchors")); \
1102 require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date")); \
1103 require_noerr_action(SecTrustSetTrustedLogs(trust, (__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs"));
1104
1105 /* Verify org-constrained non-CT leaf passes */
1106 certs = @[ (__bridge id)constraint_pass_server, (__bridge id)org_constrained_subca ];
1107 createTrust(certs);
1108 is(SecTrustEvaluateWithError(trust, &error), true, "org constrained exception did not apply: %@", error);
1109
1110 /* Verify org-constrained CT leaf passes */
1111 certs = @[ (__bridge id)constraint_pass_server_ct, (__bridge id)org_constrained_subca ];
1112 createTrust(certs);
1113 is(SecTrustEvaluateWithError(trust, &error), true, "org constrained exception did not apply: %@", error);
1114
1115 /* Verify org-constrained non-CT leaf with wrong org fails */
1116 certs = @[ (__bridge id)constraint_fail_server, (__bridge id)org_constrained_subca ];
1117 createTrust(certs);
1118 evalTrustExpectingError(errSecInvalidName, "leaf failing name constraints succeeded");
1119
1120 /* Verify dn-constrained (but not with org) non-CT leaf with matching orgs succeeds */
1121 certs = @[ (__bridge id)dn_constrained_server, (__bridge id)dn_constrained_subca ];
1122 createTrust(certs);
1123 is(SecTrustEvaluateWithError(trust, &error), true, "org match exception did not apply: %@", error);
1124
1125 /* Verify dn-constrained (but not with org) non-CT leaf without matching orgs fails */
1126 certs = @[ (__bridge id)dn_constrained_server_mismatch, (__bridge id)dn_constrained_subca ];
1127 createTrust(certs);
1128 evalTrustExpectingError(errSecVerifyActionFailed, "dn name constraints with no org succeeded");
1129
1130 /* Verify dns-constrained (no DN constraints) non-CT leaf with matching orgs succeeds */
1131 certs = @[ (__bridge id)dns_constrained_server, (__bridge id)dns_constrained_subca ];
1132 createTrust(certs);
1133 is(SecTrustEvaluateWithError(trust, &error), true, "org match exception did not apply: %@", error);
1134
1135 /* Verify dns-constrained (no DN constraints) non-CT leaf without matching orgs fails*/
1136 certs = @[ (__bridge id)dns_constrained_server_mismatch, (__bridge id)dns_constrained_subca ];
1137 createTrust(certs);
1138 evalTrustExpectingError(errSecVerifyActionFailed, "dns name constraints with no DN constraint succeeded");
1139
1140 ok(SecTrustStoreSetCTExceptions(NULL, NULL, &error), "failed to reset exceptions: %@", error);
1141
1142 #undef createTrust
1143
1144 errOut:
1145 CFReleaseNull(root);
1146 CFReleaseNull(org_constrained_subca);
1147 CFReleaseNull(constraint_pass_server);
1148 CFReleaseNull(constraint_pass_server_ct);
1149 CFReleaseNull(constraint_fail_server);
1150 CFReleaseNull(dn_constrained_subca);
1151 CFReleaseNull(dn_constrained_server);
1152 CFReleaseNull(dn_constrained_server_mismatch);
1153 CFReleaseNull(dns_constrained_subca);
1154 CFReleaseNull(dns_constrained_server);
1155 CFReleaseNull(dns_constrained_server_mismatch);
1156 CFReleaseNull(trust);
1157 CFReleaseNull(policy);
1158 CFReleaseNull(error);
1159 }
1160
1161 #else // TARGET_OS_BRIDGE
1162 - (void)testSkipTests
1163 {
1164 XCTAssert(true);
1165 }
1166 #endif // TARGET_OS_BRIDGE
1167 @end
1168
1169 // MARK: -
1170 // MARK: CT Enforcement tests
1171
1172 @interface CTEnforcementTests : TrustEvaluationTestCase
1173 @end
1174
1175 static NSArray *keychainCerts = nil;
1176
1177 @implementation CTEnforcementTests
1178 + (void)setUp {
1179 [super setUp];
1180 NSURL *trustedLogsURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"CTlogs"
1181 withExtension:@"plist"
1182 subdirectory:@"si-82-sectrust-ct-data"];
1183 trustedCTLogs = [NSArray arrayWithContentsOfURL:trustedLogsURL];
1184
1185 // set test root to be a fake system root
1186 SecCertificateRef system_root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_root"];
1187 NSData *rootHash = [NSData dataWithBytes:_system_root_hash length:sizeof(_system_root_hash)];
1188 CFPreferencesSetAppValue(CFSTR("TestCTRequiredSystemRoot"), (__bridge CFDataRef)rootHash, CFSTR("com.apple.security"));
1189 CFPreferencesAppSynchronize(CFSTR("com.apple.security"));
1190 CFReleaseNull(system_root);
1191 }
1192
1193 #if !TARGET_OS_BRIDGE
1194 /* Skip tests on bridgeOS where we don't do MobileAsset updates */
1195 - (void)testNoMACheckIn {
1196 SecCertificateRef system_root = NULL, system_server_after = NULL;
1197 SecTrustRef trust = NULL;
1198 SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com"));
1199 NSArray *enforce_anchors = nil;
1200 NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT
1201
1202 /* Mock a failing MobileAsset so we don't enforce via MobileAsset */
1203 id mockFailedMA = OCMClassMock([MAAsset class]);
1204 OCMStub([mockFailedMA startCatalogDownload:[OCMArg any]
1205 options:[OCMArg any]
1206 then:([OCMArg invokeBlockWithArgs:OCMOCK_VALUE((NSInteger){MADownloadFailed}), nil])]);
1207 SecOTAPKIResetCurrentAssetVersion(NULL);
1208
1209 require_action(system_root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_root"],
1210 errOut, fail("failed to create system root"));
1211 require_action(system_server_after = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_after"],
1212 errOut, fail("failed to create system server cert issued after flag day"));
1213
1214 enforce_anchors = @[ (__bridge id)system_root ];
1215 require_noerr_action(SecTrustCreateWithCertificates(system_server_after, policy, &trust), errOut, fail("failed to create trust"));
1216 require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)enforce_anchors), errOut, fail("failed to set anchors"));
1217 require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date"));
1218
1219 // Out-of-date asset, test system cert after date without CT passes
1220 ok(SecTrustEvaluateWithError(trust, NULL), "system post-flag-date non-CT cert failed with out-of-date asset");
1221
1222 errOut:
1223 CFReleaseNull(system_root);
1224 CFReleaseNull(system_server_after);
1225 CFReleaseNull(policy);
1226 CFReleaseNull(trust);
1227 }
1228
1229 - (void)testKillSwitch {
1230 SecCertificateRef system_root = NULL, system_server_after = NULL;
1231 SecTrustRef trust = NULL;
1232 SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com"));
1233 NSArray *enforce_anchors = nil;
1234 NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT
1235
1236 /* Mock setting a kill switch */
1237 UpdateKillSwitch((__bridge NSString *)kOTAPKIKillSwitchCT, true);
1238
1239 require_action(system_root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_root"],
1240 errOut, fail("failed to create system root"));
1241 require_action(system_server_after = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_after"],
1242 errOut, fail("failed to create system server cert issued after flag day"));
1243
1244 enforce_anchors = @[ (__bridge id)system_root ];
1245 require_noerr_action(SecTrustCreateWithCertificates(system_server_after, policy, &trust), errOut, fail("failed to create trust"));
1246 require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)enforce_anchors), errOut, fail("failed to set anchors"));
1247 require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date"));
1248
1249 // CT kill switch enabled so test system cert after date without CT passes
1250 ok(SecTrustEvaluateWithError(trust, NULL), "system post-flag-date non-CT cert failed with out-of-date asset");
1251
1252 /* Remove the kill switch */
1253 UpdateKillSwitch((__bridge NSString *)kOTAPKIKillSwitchCT, false);
1254
1255 errOut:
1256 CFReleaseNull(system_root);
1257 CFReleaseNull(system_server_after);
1258 CFReleaseNull(policy);
1259 CFReleaseNull(trust);
1260 }
1261
1262 - (void) testWithMACheckIn {
1263 SecCertificateRef system_root = NULL, system_server_after = NULL;
1264 SecTrustRef trust = NULL;
1265 SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com"));
1266 NSArray *enforce_anchors = nil;
1267 NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT
1268 CFErrorRef error = nil;
1269
1270 /* Mock a successful mobile asset check-in so that we enforce CT */
1271 XCTAssertTrue(UpdateOTACheckInDate(), "failed to set check-in date as now");
1272
1273 require_action(system_root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_root"],
1274 errOut, fail("failed to create system root"));
1275 require_action(system_server_after = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_after"],
1276 errOut, fail("failed to create system server cert issued after flag day"));
1277
1278 enforce_anchors = @[ (__bridge id)system_root ];
1279 require_noerr_action(SecTrustCreateWithCertificates(system_server_after, policy, &trust), errOut, fail("failed to create trust"));
1280 require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)enforce_anchors), errOut, fail("failed to set anchors"));
1281 require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date"));
1282
1283 // test system cert after date without CT fails (with check-in)
1284 is(SecTrustEvaluateWithError(trust, &error), false, "system post-flag-date non-CT cert with in-date asset succeeded");
1285 if (error) {
1286 is(CFErrorGetCode(error), errSecVerifyActionFailed, "got wrong error code for non-ct cert, got %ld, expected %d",
1287 (long)CFErrorGetCode(error), (int)errSecVerifyActionFailed);
1288 } else {
1289 fail("expected trust evaluation to fail and it did not.");
1290 }
1291
1292 errOut:
1293 CFReleaseNull(system_root);
1294 CFReleaseNull(system_server_after);
1295 CFReleaseNull(policy);
1296 CFReleaseNull(trust);
1297 CFReleaseNull(error);
1298 }
1299 #endif // !TARGET_OS_BRIDGE
1300
1301 - (void)testWithTrustedLogs {
1302 SecCertificateRef system_root = NULL, system_server_after = NULL;
1303 SecTrustRef trust = NULL;
1304 SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com"));
1305 NSArray *enforce_anchors = nil;
1306 NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT
1307 CFErrorRef error = nil;
1308
1309 require_action(system_root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_root"],
1310 errOut, fail("failed to create system root"));
1311 require_action(system_server_after = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_after"],
1312 errOut, fail("failed to create system server cert issued after flag day"));
1313
1314 enforce_anchors = @[ (__bridge id)system_root ];
1315 require_noerr_action(SecTrustCreateWithCertificates(system_server_after, policy, &trust), errOut, fail("failed to create trust"));
1316 require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)enforce_anchors), errOut, fail("failed to set anchors"));
1317 require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date"));
1318
1319 // set trusted logs to trigger enforcing behavior
1320 require_noerr_action(SecTrustSetTrustedLogs(trust, (__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs"));
1321
1322 // test system cert after date without CT fails (with trusted logs)
1323 #if !TARGET_OS_BRIDGE
1324 is(SecTrustEvaluateWithError(trust, &error), false, "system post-flag-date non-CT cert with trusted logs succeeded");
1325 if (error) {
1326 is(CFErrorGetCode(error), errSecVerifyActionFailed, "got wrong error code for non-ct cert, got %ld, expected %d",
1327 (long)CFErrorGetCode(error), (int)errSecVerifyActionFailed);
1328 } else {
1329 fail("expected trust evaluation to fail and it did not.");
1330 }
1331 #else
1332 /* BridgeOS doesn't enforce */
1333 ok(SecTrustEvaluateWithError(trust, NULL), "system post-flag-date non-CT cert with trusted logs failed");
1334 #endif
1335
1336 errOut:
1337 CFReleaseNull(system_root);
1338 CFReleaseNull(system_server_after);
1339 CFReleaseNull(policy);
1340 CFReleaseNull(trust);
1341 CFReleaseNull(error);
1342 }
1343
1344 - (void)testExpiredCert {
1345 SecCertificateRef system_root = NULL, system_server_after = NULL;
1346 SecTrustRef trust = NULL;
1347 SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com"));
1348 NSArray *enforce_anchors = nil;
1349 NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:570000000.0]; // January 24, 2019 at 12:20:00 AM EST
1350 CFErrorRef error = nil;
1351
1352 require_action(system_root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_root"],
1353 errOut, fail("failed to create system root"));
1354 require_action(system_server_after = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_after"],
1355 errOut, fail("failed to create system server cert issued after flag day"));
1356
1357 enforce_anchors = @[ (__bridge id)system_root ];
1358 require_noerr_action(SecTrustCreateWithCertificates(system_server_after, policy, &trust), errOut, fail("failed to create trust"));
1359 require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)enforce_anchors), errOut, fail("failed to set anchors"));
1360 require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date"));
1361
1362 // set trusted logs to trigger enforcing behavior
1363 require_noerr_action(SecTrustSetTrustedLogs(trust, (__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs"));
1364
1365 // test expired system cert after date without CT passes with only expired error
1366 ok(SecTrustIsExpiredOnly(trust), "expired non-CT cert had non-expiration errors");
1367
1368 errOut:
1369 CFReleaseNull(system_root);
1370 CFReleaseNull(system_server_after);
1371 CFReleaseNull(policy);
1372 CFReleaseNull(trust);
1373 CFReleaseNull(error);
1374 }
1375
1376 - (void)testTrustExceptions {
1377 SecCertificateRef system_root = NULL, system_server_after = NULL;
1378 SecTrustRef trust = NULL;
1379 SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com"));
1380 NSArray *enforce_anchors = nil;
1381 NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT
1382 CFErrorRef error = nil;
1383 CFDataRef exceptions = nil;
1384
1385 require_action(system_root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_root"],
1386 errOut, fail("failed to create system root"));
1387 require_action(system_server_after = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_after"],
1388 errOut, fail("failed to create system server cert issued after flag day"));
1389
1390 enforce_anchors = @[ (__bridge id)system_root ];
1391 require_noerr_action(SecTrustCreateWithCertificates(system_server_after, policy, &trust), errOut, fail("failed to create trust"));
1392 require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)enforce_anchors), errOut, fail("failed to set anchors"));
1393 require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date"));
1394
1395 // set trusted logs to trigger enforcing behavior
1396 require_noerr_action(SecTrustSetTrustedLogs(trust, (__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs"));
1397
1398 // test system cert after date without CT fails (with check-in)
1399 #if !TARGET_OS_BRIDGE
1400 is(SecTrustEvaluateWithError(trust, &error), false, "system post-flag-date non-CT cert with trusted logs succeeded");
1401 if (error) {
1402 is(CFErrorGetCode(error), errSecVerifyActionFailed, "got wrong error code for non-ct cert, got %ld, expected %d",
1403 (long)CFErrorGetCode(error), (int)errSecVerifyActionFailed);
1404 } else {
1405 fail("expected trust evaluation to fail and it did not.");
1406 }
1407 #else
1408 /* BridgeOS doesn't enforce */
1409 ok(SecTrustEvaluateWithError(trust, NULL), "system post-flag-date non-CT cert with trusted logs failed");
1410 #endif
1411
1412 // test exceptions for failing cert passes
1413 exceptions = SecTrustCopyExceptions(trust);
1414 ok(SecTrustSetExceptions(trust, exceptions), "failed to set exceptions for failing non-CT cert");
1415 CFReleaseNull(exceptions);
1416 ok(SecTrustEvaluateWithError(trust, NULL), "system post-flag-date non-CT cert failed with exceptions set");
1417 SecTrustSetExceptions(trust, NULL);
1418
1419 errOut:
1420 CFReleaseNull(system_root);
1421 CFReleaseNull(system_server_after);
1422 CFReleaseNull(policy);
1423 CFReleaseNull(trust);
1424 CFReleaseNull(error);
1425 CFReleaseNull(exceptions);
1426 }
1427
1428 - (void) testCATrustSettings {
1429 SecCertificateRef system_root = NULL, system_server_after = NULL;
1430 SecTrustRef trust = NULL;
1431 SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com"));
1432 NSArray *enforce_anchors = nil;
1433 NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT
1434 CFErrorRef error = nil;
1435 id persistentRef = nil;
1436
1437 require_action(system_root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_root"],
1438 errOut, fail("failed to create system root"));
1439 require_action(system_server_after = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_after"],
1440 errOut, fail("failed to create system server cert issued after flag day"));
1441
1442 enforce_anchors = @[ (__bridge id)system_root ];
1443 require_noerr_action(SecTrustCreateWithCertificates(system_server_after, policy, &trust), errOut, fail("failed to create trust"));
1444 require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date"));
1445
1446 // set trusted logs to trigger enforcing behavior
1447 require_noerr_action(SecTrustSetTrustedLogs(trust, (__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs"));
1448
1449 // test system cert + enterprise anchor after date without CT fails
1450 #if !TARGET_OS_BRIDGE
1451 persistentRef = [self addTrustSettingsForCert:system_root];
1452 is(SecTrustEvaluateWithError(trust, &error), false, "system post-flag date non-CT cert with enterprise root trust succeeded");
1453 if (error) {
1454 is(CFErrorGetCode(error), errSecVerifyActionFailed, "got wrong error code for non-ct cert, got %ld, expected %d",
1455 (long)CFErrorGetCode(error), (int)errSecVerifyActionFailed);
1456 } else {
1457 fail("expected trust evaluation to fail and it did not.");
1458 }
1459 [self removeTrustSettingsForCert:system_root persistentRef:persistentRef];
1460 #else
1461 /* BridgeOS doesn't enforce (and doesn't use trust settings) */
1462 require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)enforce_anchors), errOut, fail("failed to set anchors"));
1463 ok(SecTrustEvaluateWithError(trust, NULL), "system post-flag-date non-CT cert with trusted logs failed");
1464 #endif
1465
1466 errOut:
1467 CFReleaseNull(system_root);
1468 CFReleaseNull(system_server_after);
1469 CFReleaseNull(policy);
1470 CFReleaseNull(trust);
1471 CFReleaseNull(error);
1472 }
1473
1474 - (void) testAppSystem {
1475 SecCertificateRef system_root = NULL, system_server_after = NULL;
1476 SecTrustRef trust = NULL;
1477 SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com"));
1478 NSArray *enforce_anchors = nil;
1479 NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT
1480 CFErrorRef error = nil;
1481
1482 require_action(system_root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_root"],
1483 errOut, fail("failed to create system root"));
1484 require_action(system_server_after = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_after"],
1485 errOut, fail("failed to create system server cert issued after flag day"));
1486
1487 enforce_anchors = @[ (__bridge id)system_root ];
1488 require_noerr_action(SecTrustCreateWithCertificates(system_server_after, policy, &trust), errOut, fail("failed to create trust"));
1489 require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)enforce_anchors), errOut, fail("failed to set anchors"));
1490 require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date"));
1491
1492 // set trusted logs to trigger enforcing behavior
1493 require_noerr_action(SecTrustSetTrustedLogs(trust, (__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs"));
1494
1495 // test app anchor for failing cert passes
1496 enforce_anchors = @[ (__bridge id)system_server_after ];
1497 require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)enforce_anchors), errOut, fail("failed to set anchors"));
1498 ok(SecTrustEvaluateWithError(trust, NULL), "system post-flag-date non-CT cert failed with server cert app anchor");
1499 errOut:
1500 CFReleaseNull(system_root);
1501 CFReleaseNull(system_server_after);
1502 CFReleaseNull(policy);
1503 CFReleaseNull(trust);
1504 CFReleaseNull(error);
1505 }
1506
1507 #if !TARGET_OS_BRIDGE
1508 /* bridgeOS doens't have trust settings */
1509 - (void) testLeafTrustSettings {
1510 SecCertificateRef system_root = NULL, system_server_after = NULL;
1511 SecTrustRef trust = NULL;
1512 SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com"));
1513 NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT
1514 CFErrorRef error = nil;
1515 id persistentRef = nil;
1516
1517 require_action(system_root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_root"],
1518 errOut, fail("failed to create system root"));
1519 require_action(system_server_after = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_after"],
1520 errOut, fail("failed to create system server cert issued after flag day"));
1521
1522 require_noerr_action(SecTrustCreateWithCertificates(system_server_after, policy, &trust), errOut, fail("failed to create trust"));
1523 require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date"));
1524
1525 // set trusted logs to trigger enforcing behavior
1526 require_noerr_action(SecTrustSetTrustedLogs(trust, (__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs"));
1527
1528 // test trust settings for failing cert passes
1529 persistentRef = [self addTrustSettingsForCert:system_server_after];
1530 ok(SecTrustEvaluateWithError(trust, NULL), "system post-flag-date non-CT cert failed with server cert enterprise anchor");
1531 [self removeTrustSettingsForCert:system_server_after persistentRef:persistentRef];
1532
1533 errOut:
1534 CFReleaseNull(system_root);
1535 CFReleaseNull(system_server_after);
1536 CFReleaseNull(policy);
1537 CFReleaseNull(trust);
1538 CFReleaseNull(error);
1539 }
1540 #endif // !TARGET_OS_BRIDGE
1541
1542 - (void) testEAPPolicy {
1543 SecCertificateRef system_root = NULL, system_server_after = NULL;
1544 SecTrustRef trust = NULL;
1545 SecPolicyRef policy = SecPolicyCreateEAP(true, NULL);
1546 NSArray *enforce_anchors = nil;
1547 NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT
1548
1549 require_action(system_root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_root"],
1550 errOut, fail("failed to create system root"));
1551 require_action(system_server_after = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_after"],
1552 errOut, fail("failed to create system server cert issued after flag day"));
1553
1554 enforce_anchors = @[ (__bridge id)system_root ];
1555 require_noerr_action(SecTrustCreateWithCertificates(system_server_after, policy, &trust), errOut, fail("failed to create trust"));
1556 require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)enforce_anchors), errOut, fail("failed to set anchors"));
1557 require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date"));
1558
1559 // set trusted logs to trigger enforcing behavior
1560 require_noerr_action(SecTrustSetTrustedLogs(trust, (__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs"));
1561
1562 // EAP, test system cert after date without CT passes
1563 ok(SecTrustEvaluateWithError(trust, NULL), "system post-flag-date non-CT cert failed with EAP cert");
1564
1565 errOut:
1566 CFReleaseNull(system_root);
1567 CFReleaseNull(system_server_after);
1568 CFReleaseNull(policy);
1569 CFReleaseNull(trust);
1570 }
1571
1572 // Test pinning policy name
1573 - (void) testPinningPolicy {
1574 SecCertificateRef system_root = NULL, system_server_after = NULL;
1575 SecTrustRef trust = NULL;
1576 SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com"));
1577 NSArray *enforce_anchors = nil;
1578 NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT
1579
1580 require_action(system_root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_root"],
1581 errOut, fail("failed to create system root"));
1582 require_action(system_server_after = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_after"],
1583 errOut, fail("failed to create system server cert issued after flag day"));
1584
1585 enforce_anchors = @[ (__bridge id)system_root ];
1586 require_noerr_action(SecTrustCreateWithCertificates(system_server_after, policy, &trust), errOut, fail("failed to create trust"));
1587 require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)enforce_anchors), errOut, fail("failed to set anchors"));
1588 require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date"));
1589
1590 // set policy name
1591 require_noerr_action(SecTrustSetPinningPolicyName(trust, CFSTR("a-policy-name")), errOut, fail("failed to set policy name"));
1592
1593 // set trusted logs to trigger enforcing behavior
1594 require_noerr_action(SecTrustSetTrustedLogs(trust, (__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs"));
1595
1596 // pinning policy, test system cert after date without CT passes
1597 ok(SecTrustEvaluateWithError(trust, NULL), "system post-flag-date non-CT cert failed with EAP cert");
1598
1599 errOut:
1600 CFReleaseNull(system_root);
1601 CFReleaseNull(system_server_after);
1602 CFReleaseNull(policy);
1603 CFReleaseNull(trust);
1604 }
1605
1606 // test system cert after date with CT passes
1607 - (void) testAfterWithCT {
1608 SecCertificateRef system_root = NULL, system_server_after_with_CT = NULL;
1609 SecTrustRef trust = NULL;
1610 SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com"));
1611 NSArray *enforce_anchors = nil;
1612 NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT
1613
1614 require_action(system_root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_root"],
1615 errOut, fail("failed to create system root"));
1616 require_action(system_server_after_with_CT = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_after_scts"],
1617 errOut, fail("failed to create system server cert issued after flag day with SCTs"));
1618
1619 enforce_anchors = @[ (__bridge id)system_root ];
1620 require_noerr_action(SecTrustCreateWithCertificates(system_server_after_with_CT, policy, &trust), errOut, fail("failed to create trust"));
1621 require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)enforce_anchors), errOut, fail("failed to set anchors"));
1622 require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date"));
1623 require_noerr_action(SecTrustSetTrustedLogs(trust, (__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs"));
1624 ok(SecTrustEvaluateWithError(trust, NULL), "system post-flag-date CT cert failed");
1625
1626 errOut:
1627 CFReleaseNull(system_root);
1628 CFReleaseNull(system_server_after_with_CT);
1629 CFReleaseNull(policy);
1630 CFReleaseNull(trust);
1631 }
1632
1633 // test system cert before date without CT passes
1634 - (void) testBefore {
1635 SecCertificateRef system_root = NULL, system_server_before = NULL;
1636 SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com"));
1637 SecTrustRef trust = NULL;
1638 NSArray *enforce_anchors = nil;
1639 NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT
1640
1641 require_action(system_root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_root"],
1642 errOut, fail("failed to create system root"));
1643 require_action(system_server_before = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_before"],
1644 errOut, fail("failed to create system server cert issued before flag day"));
1645
1646 enforce_anchors = @[ (__bridge id)system_root ];
1647 require_noerr_action(SecTrustCreateWithCertificates(system_server_before, policy, &trust), errOut, fail("failed to create trust"));
1648 require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)enforce_anchors), errOut, fail("failed to set anchors"));
1649 require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date"));
1650 require_noerr_action(SecTrustSetTrustedLogs(trust, (__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs"));
1651 ok(SecTrustEvaluateWithError(trust, NULL), "system pre-flag-date non-CT cert failed");
1652
1653 errOut:
1654 CFReleaseNull(system_root);
1655 CFReleaseNull(system_server_before);
1656 CFReleaseNull(policy);
1657 CFReleaseNull(trust);
1658 }
1659
1660 #if !TARGET_OS_BRIDGE
1661 // test enterprise (non-public) after date without CT passes, except on bridgeOS which doesn't have trust settings
1662 - (void) testEnterpriseCA {
1663 SecCertificateRef user_root = NULL, user_server_after = NULL;
1664 SecTrustRef trust = NULL;
1665 SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com"));
1666 NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT
1667 id persistentRef = nil;
1668
1669 require_action(user_root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_user_root"],
1670 errOut, fail("failed to create user root"));
1671 require_action(user_server_after = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_user_server_after"],
1672 errOut, fail("failed to create user server cert issued after flag day"));
1673
1674 persistentRef = [self addTrustSettingsForCert:user_root];
1675 require_noerr_action(SecTrustCreateWithCertificates(user_server_after, policy, &trust), errOut, fail("failed to create trust"));
1676 require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date"));
1677 require_noerr_action(SecTrustSetTrustedLogs(trust,(__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs"));
1678 ok(SecTrustEvaluateWithError(trust, NULL), "non-system post-flag-date non-CT cert failed with enterprise anchor");
1679 [self removeTrustSettingsForCert:user_root persistentRef:persistentRef];
1680
1681 errOut:
1682 CFReleaseNull(user_root);
1683 CFReleaseNull(user_server_after);
1684 CFReleaseNull(policy);
1685 CFReleaseNull(trust);
1686 }
1687 #endif // !TARGET_OS_BRIDGE
1688
1689 // test app anchor (non-public) after date without CT passes
1690 - (void) testAppCA {
1691 SecCertificateRef user_root = NULL, user_server_after = NULL;
1692 SecTrustRef trust = NULL;
1693 SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com"));
1694 NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT
1695 NSArray *enforce_anchors = nil;
1696
1697 require_action(user_root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_user_root"],
1698 errOut, fail("failed to create user root"));
1699 require_action(user_server_after = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_user_server_after"],
1700 errOut, fail("failed to create user server cert issued after flag day"));
1701
1702 enforce_anchors = @[ (__bridge id)user_root ];
1703 require_noerr_action(SecTrustCreateWithCertificates(user_server_after, policy, &trust), errOut, fail("failed to create trust"));
1704 require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)enforce_anchors), errOut, fail("failed to set anchors"));
1705 require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date"));
1706 require_noerr_action(SecTrustSetTrustedLogs(trust,(__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs"));
1707 ok(SecTrustEvaluateWithError(trust, NULL), "non-system post-flag-date non-CT cert failed with enterprise anchor");
1708
1709 errOut:
1710 CFReleaseNull(user_root);
1711 CFReleaseNull(user_server_after);
1712 CFReleaseNull(policy);
1713 CFReleaseNull(trust);
1714 }
1715
1716 // test apple anchor after date without CT passes
1717 - (void) testAppleAnchor {
1718 SecCertificateRef appleServerAuthCA = NULL, apple_server_after = NULL;
1719 SecTrustRef trust = NULL;
1720 SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("bbasile-test.scv.apple.com"));
1721 NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT
1722 NSArray *certs = nil;
1723
1724 require_action(appleServerAuthCA = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_apple_ca"],
1725 errOut, fail("failed to create apple server auth CA"));
1726 require_action(apple_server_after = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_apple_server_after"],
1727 errOut, fail("failed to create apple server cert issued after flag day"));
1728
1729 certs = @[ (__bridge id)apple_server_after, (__bridge id)appleServerAuthCA ];
1730 require_noerr_action(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trust), errOut, fail("failed to create trust"));
1731 require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date"));
1732 require_noerr_action(SecTrustSetTrustedLogs(trust, (__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs"));
1733 ok(SecTrustEvaluateWithError(trust, NULL), "apple post-flag-date non-CT cert failed");
1734
1735 errOut:
1736 CFReleaseNull(appleServerAuthCA);
1737 CFReleaseNull(apple_server_after);
1738 CFReleaseNull(policy);
1739 CFReleaseNull(trust);
1740 }
1741
1742 // test apple subCA after date without CT fails
1743 - (void) testAppleSubCAException {
1744 SecCertificateRef geoTrustRoot = NULL, appleISTCA8G1 = NULL, deprecatedSSLServer = NULL;
1745 SecTrustRef trust = NULL;
1746 SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("bbasile-test.scv.apple.com"));
1747 NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:576000000.0]; // April 3, 2019 at 9:00:00 AM PDT
1748 NSArray *certs = nil, *enforcement_anchors = nil;
1749
1750 require_action(geoTrustRoot = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"GeoTrustPrimaryCAG2"],
1751 errOut, fail("failed to create geotrust root"));
1752 require_action(appleISTCA8G1 = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"AppleISTCA8G1"],
1753 errOut, fail("failed to create apple IST CA"));
1754 require_action(deprecatedSSLServer = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"deprecatedSSLServer"],
1755 errOut, fail("failed to create deprecated SSL Server cert"));
1756
1757 certs = @[ (__bridge id)deprecatedSSLServer, (__bridge id)appleISTCA8G1 ];
1758 enforcement_anchors = @[ (__bridge id)geoTrustRoot ];
1759 require_noerr_action(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trust), errOut, fail("failed to create trust"));
1760 require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date"));
1761 require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)enforcement_anchors), errOut, fail("failed to set anchors"));
1762 require_noerr_action(SecTrustSetTrustedLogs(trust, (__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs"));
1763 #if !TARGET_OS_BRIDGE
1764 XCTAssertFalse(SecTrustEvaluateWithError(trust, NULL), "apple public post-flag-date non-CT cert passed");
1765 #endif
1766
1767 errOut:
1768 CFReleaseNull(geoTrustRoot);
1769 CFReleaseNull(appleISTCA8G1);
1770 CFReleaseNull(deprecatedSSLServer);
1771 CFReleaseNull(policy);
1772 CFReleaseNull(trust);
1773 }
1774
1775 - (void) testBasejumper {
1776 SecCertificateRef baltimoreRoot = NULL, appleISTCA2 = NULL, deprecatedSSLServer = NULL;
1777 SecTrustRef trust = NULL;
1778 SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("basejumper.apple.com"));
1779 NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:576000000.0]; // April 3, 2019 at 9:00:00 AM PDT
1780 NSArray *certs = nil, *enforcement_anchors = nil;
1781
1782 require_action(baltimoreRoot = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"BaltimoreCyberTrustRoot"],
1783 errOut, fail("failed to create geotrust root"));
1784 require_action(appleISTCA2 = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"AppleISTCA2_Baltimore"],
1785 errOut, fail("failed to create apple IST CA"));
1786 require_action(deprecatedSSLServer = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"basejumper"],
1787 errOut, fail("failed to create deprecated SSL Server cert"));
1788
1789 certs = @[ (__bridge id)deprecatedSSLServer, (__bridge id)appleISTCA2 ];
1790 enforcement_anchors = @[ (__bridge id)baltimoreRoot ];
1791 require_noerr_action(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trust), errOut, fail("failed to create trust"));
1792 require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date"));
1793 require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)enforcement_anchors), errOut, fail("failed to set anchors"));
1794 require_noerr_action(SecTrustSetTrustedLogs(trust, (__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs"));
1795 XCTAssert(SecTrustEvaluateWithError(trust, NULL), "non-CT basejumper cert failed");
1796
1797 #if !TARGET_OS_BRIDGE
1798 // bridgeOS doesn't ever enforce CT
1799 // Test with generic CT allowlist disable
1800 CFPreferencesSetAppValue(CFSTR("DisableCTAllowlist"), kCFBooleanTrue, CFSTR("com.apple.security"));
1801 CFPreferencesAppSynchronize(CFSTR("com.apple.security"));
1802 SecTrustSetNeedsEvaluation(trust);
1803 XCTAssertFalse(SecTrustEvaluateWithError(trust, NULL), "non-CT basejumper succeeded with allowlist disabled");
1804 CFPreferencesSetAppValue(CFSTR("DisableCTAllowlist"), kCFBooleanFalse, CFSTR("com.apple.security"));
1805 CFPreferencesAppSynchronize(CFSTR("com.apple.security"));
1806
1807 // Test with Apple allowlist disable
1808 CFPreferencesSetAppValue(CFSTR("DisableCTAllowlistApple"), kCFBooleanTrue, CFSTR("com.apple.security"));
1809 CFPreferencesAppSynchronize(CFSTR("com.apple.security"));
1810 SecTrustSetNeedsEvaluation(trust);
1811 XCTAssertFalse(SecTrustEvaluateWithError(trust, NULL), "non-CT basejumper succeeded with Apple allowlist disabled");
1812 CFPreferencesSetAppValue(CFSTR("DisableCTAllowlistApple"), kCFBooleanFalse, CFSTR("com.apple.security"));
1813 CFPreferencesAppSynchronize(CFSTR("com.apple.security"));
1814 #endif // !TARGET_OS_BRIDGE
1815
1816 errOut:
1817 CFReleaseNull(baltimoreRoot);
1818 CFReleaseNull(appleISTCA2);
1819 CFReleaseNull(deprecatedSSLServer);
1820 CFReleaseNull(policy);
1821 CFReleaseNull(trust);
1822 }
1823
1824 // test google subCA after date without CT fails
1825 - (void) testGoogleSubCAException {
1826 SecCertificateRef globalSignRoot = NULL, googleIAG3 = NULL, google = NULL;
1827 SecTrustRef trust = NULL;
1828 SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("www.google.com"));
1829 NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT
1830 NSArray *certs = nil, *enforcement_anchors = nil;
1831
1832 require_action(globalSignRoot = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"GlobalSignRootCAR2"],
1833 errOut, fail("failed to create geotrust root"));
1834 require_action(googleIAG3 = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"GoogleIAG3"],
1835 errOut, fail("failed to create apple IST CA"));
1836 require_action(google = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"google"],
1837 errOut, fail("failed to create livability cert"));
1838
1839 certs = @[ (__bridge id)google, (__bridge id)googleIAG3 ];
1840 enforcement_anchors = @[ (__bridge id)globalSignRoot ];
1841 require_noerr_action(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trust), errOut, fail("failed to create trust"));
1842 require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date"));
1843 require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)enforcement_anchors), errOut, fail("failed to set anchors"));
1844 require_noerr_action(SecTrustSetTrustedLogs(trust, (__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs"));
1845 #if !TARGET_OS_BRIDGE
1846 XCTAssertFalse(SecTrustEvaluateWithError(trust, NULL), "google public post-flag-date non-CT cert passed");
1847 #endif
1848
1849 errOut:
1850 CFReleaseNull(globalSignRoot);
1851 CFReleaseNull(googleIAG3);
1852 CFReleaseNull(google);
1853 CFReleaseNull(policy);
1854 CFReleaseNull(trust);
1855 }
1856
1857 // If pinning is disabled, pinned hostnames should continue to be exempt from CT
1858 - (void) testSystemwidePinningDisable {
1859 SecCertificateRef baltimoreRoot = NULL, appleISTCA2 = NULL, pinnedNonCT = NULL;
1860 SecTrustRef trust = NULL;
1861 SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("iphonesubmissions.apple.com"));
1862 NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:580000000.0]; // May 19, 2019 at 4:06:40 PM PDT
1863 NSArray *certs = nil, *enforcement_anchors = nil;
1864 NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:@"com.apple.security"];
1865
1866 require_action(baltimoreRoot = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"BaltimoreCyberTrustRoot"],
1867 errOut, fail("failed to create geotrust root"));
1868 require_action(appleISTCA2 = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"AppleISTCA2_Baltimore"],
1869 errOut, fail("failed to create apple IST CA"));
1870 require_action(pinnedNonCT = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"iphonesubmissions"],
1871 errOut, fail("failed to create deprecated SSL Server cert"));
1872
1873 certs = @[ (__bridge id)pinnedNonCT, (__bridge id)appleISTCA2 ];
1874 enforcement_anchors = @[ (__bridge id)baltimoreRoot ];
1875 require_noerr_action(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trust), errOut, fail("failed to create trust"));
1876 require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date"));
1877 require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)enforcement_anchors), errOut, fail("failed to set anchors"));
1878 require_noerr_action(SecTrustSetTrustedLogs(trust, (__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs"));
1879 XCTAssert(SecTrustEvaluateWithError(trust, NULL), "pinned non-CT cert failed");
1880
1881 // Test with pinning disabled
1882 [defaults setBool:YES forKey:@"AppleServerAuthenticationNoPinning"];
1883 [defaults synchronize];
1884 SecTrustSetNeedsEvaluation(trust);
1885 XCTAssert(SecTrustEvaluateWithError(trust, NULL), "pinned non-CT failed with pinning disabled");
1886 [defaults setBool:NO forKey:@"AppleServerAuthenticationNoPinning"];
1887 [defaults synchronize];
1888
1889 errOut:
1890 CFReleaseNull(baltimoreRoot);
1891 CFReleaseNull(appleISTCA2);
1892 CFReleaseNull(pinnedNonCT);
1893 CFReleaseNull(policy);
1894 CFReleaseNull(trust);
1895 }
1896
1897 @end