2 * Copyright (c) 2006-2010,2012-2019 Apple Inc. All Rights Reserved.
5 #include <AssertMacros.h>
6 #import <XCTest/XCTest.h>
7 #import <Security/SecCertificatePriv.h>
8 #include <Security/SecTrustPriv.h>
9 #include <Security/SecPolicyPriv.h>
10 #include "OSX/utilities/array_size.h"
11 #include "OSX/utilities/SecCFWrappers.h"
13 #import "../TestMacroConversions.h"
14 #import "TrustEvaluationTestCase.h"
16 #import "ExceptionTests_data.h"
18 @interface TrustExceptionTests : TrustEvaluationTestCase
21 @implementation TrustExceptionTests
23 static NSArray *certs = nil;
24 static NSDate *date = nil;
29 SecCertificateRef cert0 = SecCertificateCreateWithBytes(NULL, _exception_cert0, sizeof(_exception_cert0));
30 SecCertificateRef cert1 = SecCertificateCreateWithBytes(NULL, _exception_cert1, sizeof(_exception_cert1));
31 certs = @[ (__bridge id)cert0, (__bridge id)cert1 ];
32 date = [NSDate dateWithTimeIntervalSinceReferenceDate:545000000.0]; /* April 9, 2018 at 1:53:20 PM PDT */
39 // bridgeOS doesn't have a system root store
40 - (void)testPassingTrust
42 SecTrustRef trust = NULL;
43 SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("store.apple.com"));
44 ok_status(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trust), "create trust");
45 ok_status(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), "set date");
47 SecTrustResultType trustResult;
48 ok(SecTrustEvaluateWithError(trust, NULL), "evaluate trust");
49 ok_status(SecTrustGetTrustResult(trust, &trustResult));
50 is_status(trustResult, kSecTrustResultUnspecified,
51 "trust is kSecTrustResultUnspecified");
53 ok(exceptions = SecTrustCopyExceptions(trust), "create exceptions");
54 ok(SecTrustSetExceptions(trust, exceptions), "set exceptions");
55 ok_status(SecTrustGetTrustResult(trust, &trustResult), "evaluate trust");
56 is_status(trustResult, kSecTrustResultProceed, "trust is kSecTrustResultProceed");
59 CFReleaseNull(policy);
60 CFReleaseNull(exceptions);
64 - (void)testFailingTrust
66 SecTrustRef trust = NULL;
67 SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("badstore.apple.com"));
68 ok_status(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trust), "create trust");
69 ok_status(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), "set date");
71 SecTrustResultType trustResult;
72 XCTAssertFalse(SecTrustEvaluateWithError(trust, NULL), "evaluate trust");
73 ok_status(SecTrustGetTrustResult(trust, &trustResult));
74 is_status(trustResult, kSecTrustResultRecoverableTrustFailure);
76 ok(exceptions = SecTrustCopyExceptions(trust), "create exceptions");
77 ok(SecTrustSetExceptions(trust, exceptions), "set exceptions");
78 ok_status(SecTrustGetTrustResult(trust, &trustResult), "evaluate trust");
79 is_status(trustResult, kSecTrustResultProceed, "trust is kSecTrustResultProceed");
82 CFReleaseNull(policy);
83 CFReleaseNull(exceptions);
86 - (void)testNewTrustObjectSameFailure
88 SecTrustRef trust = NULL;
89 SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("badstore.apple.com"));
90 ok_status(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trust), "create trust");
91 ok_status(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), "set date");
93 SecTrustResultType trustResult;
94 XCTAssertFalse(SecTrustEvaluateWithError(trust, NULL), "evaluate trust");
95 ok_status(SecTrustGetTrustResult(trust, &trustResult));
96 is_status(trustResult, kSecTrustResultRecoverableTrustFailure);
98 ok(exceptions = SecTrustCopyExceptions(trust), "create exceptions");
99 ok(SecTrustSetExceptions(trust, exceptions), "set exceptions");
100 ok_status(SecTrustGetTrustResult(trust, &trustResult), "evaluate trust");
101 is_status(trustResult, kSecTrustResultProceed, "trust is kSecTrustResultProceed");
103 /* new trust with the same failing policy and certs should pass */
104 CFReleaseNull(trust);
105 ok_status(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trust), "create trust");
106 ok_status(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), "set date");
107 ok(SecTrustSetExceptions(trust, exceptions), "set exceptions");
108 ok_status(SecTrustGetTrustResult(trust, &trustResult), "evaluate trust");
109 is_status(trustResult, kSecTrustResultProceed, "trust is kSecTrustResultProceed");
111 CFReleaseNull(trust);
112 CFReleaseNull(policy);
113 CFReleaseNull(exceptions);
116 #if !TARGET_OS_BRIDGE
117 // bridgeOS always has an AnchorTrusted error due to lack of a system root store
118 - (void)testIntroduceNewAnchorTrustedFailure
120 SecTrustRef trust = NULL;
121 SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("badstore.apple.com"));
122 ok_status(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trust), "create trust");
123 ok_status(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), "set date");
125 SecTrustResultType trustResult;
126 XCTAssertFalse(SecTrustEvaluateWithError(trust, NULL), "evaluate trust");
127 ok_status(SecTrustGetTrustResult(trust, &trustResult));
128 is_status(trustResult, kSecTrustResultRecoverableTrustFailure);
129 CFDataRef exceptions;
130 ok(exceptions = SecTrustCopyExceptions(trust), "create exceptions");
131 ok(SecTrustSetExceptions(trust, exceptions), "set exceptions");
132 ok_status(SecTrustGetTrustResult(trust, &trustResult), "evaluate trust");
133 is_status(trustResult, kSecTrustResultProceed, "trust is kSecTrustResultProceed");
135 // new AnchorTrusted failure
136 ok_status(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)@[]), "set empty anchor list");
137 ok_status(SecTrustGetTrustResult(trust, &trustResult), "evaluate trust");
138 is_status(trustResult, kSecTrustResultRecoverableTrustFailure, "trust is kSecTrustResultRecoverableTrustFailure");
140 // fix AnchorTrusted failure
141 ok_status(SecTrustSetAnchorCertificatesOnly(trust, false), "trust passed in anchors and system anchors");
142 ok_status(SecTrustGetTrustResult(trust, &trustResult), "evaluate trust");
143 is_status(trustResult, kSecTrustResultProceed, "trust is kSecTrustResultProceed");
145 CFReleaseNull(trust);
146 CFReleaseNull(policy);
147 CFReleaseNull(exceptions);
151 - (void)testIntroduceNewExpiredFailure
153 SecTrustRef trust = NULL;
154 SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("badstore.apple.com"));
155 ok_status(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trust), "create trust");
156 ok_status(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), "set date");
158 SecTrustResultType trustResult;
159 XCTAssertFalse(SecTrustEvaluateWithError(trust, NULL), "evaluate trust");
160 ok_status(SecTrustGetTrustResult(trust, &trustResult));
161 is_status(trustResult, kSecTrustResultRecoverableTrustFailure);
162 CFDataRef exceptions;
163 ok(exceptions = SecTrustCopyExceptions(trust), "create exceptions");
164 ok(SecTrustSetExceptions(trust, exceptions), "set exceptions");
165 ok_status(SecTrustGetTrustResult(trust, &trustResult), "evaluate trust");
166 is_status(trustResult, kSecTrustResultProceed, "trust is kSecTrustResultProceed");
168 // new expiry failure
169 ok_status(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)[NSDate dateWithTimeIntervalSinceReferenceDate:667680000.0]),
170 "set date to far future so certs are expired");
171 ok_status(SecTrustGetTrustResult(trust, &trustResult), "evaluate trust");
172 is_status(trustResult, kSecTrustResultRecoverableTrustFailure, "trust is kSecTrustResultRecoverableTrustFailure");
174 CFReleaseNull(trust);
175 CFReleaseNull(policy);
176 CFReleaseNull(exceptions);
179 - (void)testNewTrustObjectNewHostnameFailure
181 SecTrustRef trust = NULL;
182 SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("store.apple.com"));
183 ok_status(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trust), "create trust");
184 ok_status(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), "set date");
185 CFDataRef exceptions;
186 ok(exceptions = SecTrustCopyExceptions(trust), "create exceptions");
188 CFReleaseNull(trust);
189 CFReleaseNull(policy);
190 policy = SecPolicyCreateSSL(true, CFSTR("badstore.apple.com"));
191 ok_status(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trust), "create trust with hostname mismatch");
192 ok_status(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), "set date");
194 /* exceptions from the old trust evaluation should fail */
195 SecTrustResultType trustResult;
196 ok(SecTrustSetExceptions(trust, exceptions), "set old exceptions");
197 XCTAssertFalse(SecTrustEvaluateWithError(trust, NULL), "evaluate trust");
198 ok_status(SecTrustGetTrustResult(trust, &trustResult));
199 is_status(trustResult, kSecTrustResultRecoverableTrustFailure);
201 /* we should be able to get new exceptions and pass */
202 CFReleaseNull(exceptions);
203 ok(exceptions = SecTrustCopyExceptions(trust), "create exceptions");
204 ok(SecTrustSetExceptions(trust, exceptions), "set exceptions");
205 ok_status(SecTrustGetTrustResult(trust, &trustResult), "evaluate trust");
206 is_status(trustResult, kSecTrustResultProceed, "trust is kSecTrustResultProceed");
208 CFReleaseNull(trust);
209 CFReleaseNull(policy);
210 CFReleaseNull(exceptions);
213 - (void)testClearExceptions
215 SecTrustRef trust = NULL;
216 SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("badstore.apple.com"));
217 ok_status(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trust), "create trust");
218 ok_status(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), "set date");
220 SecTrustResultType trustResult;
221 XCTAssertFalse(SecTrustEvaluateWithError(trust, NULL), "evaluate trust");
222 ok_status(SecTrustGetTrustResult(trust, &trustResult));
223 is_status(trustResult, kSecTrustResultRecoverableTrustFailure);
224 CFDataRef exceptions;
225 ok(exceptions = SecTrustCopyExceptions(trust), "create exceptions");
226 ok(SecTrustSetExceptions(trust, exceptions), "set exceptions");
227 ok_status(SecTrustGetTrustResult(trust, &trustResult), "evaluate trust");
228 is_status(trustResult, kSecTrustResultProceed, "trust is kSecTrustResultProceed");
230 XCTAssertFalse(SecTrustSetExceptions(trust, NULL));
231 ok_status(SecTrustGetTrustResult(trust, &trustResult));
232 is_status(trustResult, kSecTrustResultRecoverableTrustFailure);
234 CFReleaseNull(trust);
235 CFReleaseNull(policy);
236 CFReleaseNull(exceptions);
239 - (void)testWrongCertForExceptions
241 SecTrustRef trust = NULL;
242 SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("badstore.apple.com"));
243 ok_status(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trust), "create trust");
244 ok_status(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), "set date");
246 SecTrustResultType trustResult;
247 XCTAssertFalse(SecTrustEvaluateWithError(trust, NULL), "evaluate trust");
248 ok_status(SecTrustGetTrustResult(trust, &trustResult));
249 is_status(trustResult, kSecTrustResultRecoverableTrustFailure);
250 CFDataRef exceptions;
251 ok(exceptions = SecTrustCopyExceptions(trust), "create exceptions");
252 ok(SecTrustSetExceptions(trust, exceptions), "set exceptions");
253 ok_status(SecTrustGetTrustResult(trust, &trustResult), "evaluate trust");
254 is_status(trustResult, kSecTrustResultProceed, "trust is kSecTrustResultProceed");
256 /* new trust with the same failing policy and certs should pass */
257 CFReleaseNull(trust);
258 CFReleaseNull(policy);
259 SecCertificateRef sscert0 = SecCertificateCreateWithBytes(NULL, _exception_self_signed, sizeof(_exception_self_signed));
260 policy = SecPolicyCreateSSL(false, CFSTR("self-signed.ssltest.apple.com"));
261 ok_status(SecTrustCreateWithCertificates(sscert0, policy, &trust), "create trust");
262 ok_status(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), "set date");
263 XCTAssertFalse(SecTrustSetExceptions(trust, exceptions), "set exceptions fails for other cert");
264 ok_status(SecTrustGetTrustResult(trust, &trustResult), "evaluate trust");
265 is_status(trustResult, kSecTrustResultRecoverableTrustFailure);
267 CFReleaseNull(trust);
268 CFReleaseNull(policy);
269 CFReleaseNull(exceptions);
273 - (void)testExtensionsEpoch
275 SecTrustRef trust = NULL;
276 SecTrustResultType trustResult;
277 CFDataRef exceptions = NULL;
279 SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("badstore.apple.com"));
280 ok_status(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trust), "create trust");
281 ok_status(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), "set date");
282 ok(exceptions = SecTrustCopyExceptions(trust), "create exceptions");
284 /* Test the uninitialized extensions epoch. */
285 CFErrorRef exceptionResetCountError = NULL;
286 uint64_t exceptionResetCount = SecTrustGetExceptionResetCount(&exceptionResetCountError);
287 ok(exceptionResetCount == 0, "exception reset count is uninitialized");
288 is(SecTrustGetExceptionResetCount(&exceptionResetCountError), exceptionResetCount, "SecTrustGetExceptionResetCount is idempotent");
289 ok(SecTrustSetExceptions(trust, exceptions), "set exceptions");
290 ok_status(SecTrustGetTrustResult(trust, &trustResult), "evaluate trust");
291 is_status(trustResult, kSecTrustResultProceed, "trust is kSecTrustResultProceed");
293 /* Test increasing the extensions epoch. */
294 exceptionResetCountError = NULL;
295 ok_status(SecTrustIncrementExceptionResetCount(&exceptionResetCountError), "increase exception reset count");
296 exceptionResetCountError = NULL;
297 is(SecTrustGetExceptionResetCount(&exceptionResetCountError), 1 + exceptionResetCount, "exception reset count is 1 + previous count");
299 /* Test trust evaluation under a future extensions epoch. */
300 ok(!SecTrustSetExceptions(trust, exceptions), "set exceptions");
301 ok_status(SecTrustGetTrustResult(trust, &trustResult), "evaluate trust");
302 is_status(trustResult, kSecTrustResultRecoverableTrustFailure, "trust is kSecTrustResultRecoverableTrustFailure");
304 CFReleaseNull(trust);
305 CFReleaseNull(policy);
306 CFReleaseNull(exceptions);
310 #if !TARGET_OS_BRIDGE
311 // bridgeOS doesn't support Valid
312 - (void)testFatalResultsNonOverride
314 id root = [self SecCertificateCreateFromPEMResource:@"ca-ki" subdirectory:@"si-88-sectrust-valid-data"];
315 id revokedLeaf = [self SecCertificateCreateFromPEMResource:@"leaf-ki-revoked1" subdirectory:@"si-88-sectrust-valid-data"];
316 TestTrustEvaluation *eval = [[TestTrustEvaluation alloc] initWithCertificates:@[revokedLeaf, root] policies:nil];
317 [eval setVerifyDate:[NSDate dateWithTimeIntervalSinceReferenceDate:542400000.0]]; // March 10, 2018 at 10:40:00 AM PST
318 [eval setAnchors:@[root]];
319 XCTAssertFalse([eval evaluate:nil]);
320 XCTAssertEqual(eval.trustResult, kSecTrustResultFatalTrustFailure);
322 /* try to set exceptions on the trust and ensure it still fails */
323 NSData *exceptions = CFBridgingRelease(SecTrustCopyExceptions(eval.trust));
324 XCTAssertNotNil(exceptions);
325 XCTAssert(SecTrustSetExceptions(eval.trust, (__bridge CFDataRef)exceptions));
326 XCTAssertFalse([eval evaluate:nil]);
327 XCTAssertEqual(eval.trustResult, kSecTrustResultFatalTrustFailure);