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