]> git.saurik.com Git - apple/security.git/blob - tests/TrustTests/EvaluationTests/SSLPolicyTests.m
Security-59306.80.4.tar.gz
[apple/security.git] / tests / TrustTests / EvaluationTests / SSLPolicyTests.m
1 /*
2 * Copyright (c) 2015-2019 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 <Foundation/Foundation.h>
27 #import <XCTest/XCTest.h>
28
29 #include <Security/SecPolicyPriv.h>
30 #include <Security/SecTrust.h>
31 #include <Security/SecTrustPriv.h>
32 #include <Security/SecCertificatePriv.h>
33 #include <utilities/SecCFWrappers.h>
34
35 #include "../TestMacroConversions.h"
36 #include "SSLPolicyTests_data.h"
37 #import "TrustEvaluationTestCase.h"
38
39 @interface SSLPolicyTests : TrustEvaluationTestCase
40 @end
41
42 @implementation SSLPolicyTests
43
44 - (void)testSSLPolicyCerts
45 {
46 NSArray *testPlistURLs = [[NSBundle bundleForClass:[self class]] URLsForResourcesWithExtension:@"plist" subdirectory:@"ssl-policy-certs"];
47 if (testPlistURLs.count != 1) {
48 fail("failed to find the test plist");
49 return;
50 }
51
52 NSDictionary <NSString *,NSDictionary *>*tests_dictionary = [NSDictionary dictionaryWithContentsOfURL:testPlistURLs[0]];
53 if (!tests_dictionary) {
54 fail("failed to create test driver dictionary");
55 return;
56 }
57
58 [tests_dictionary enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, NSDictionary * _Nonnull obj, BOOL * _Nonnull stop) {
59 CFDictionaryRef test_info = (__bridge CFDictionaryRef)obj;
60 CFStringRef test_name = (__bridge CFStringRef)key, file = NULL, reason = NULL, expectedResult = NULL, failureReason = NULL;
61 CFErrorRef trustError = NULL;
62 NSURL *cert_file_url = NULL;
63 NSData *cert_data = nil;
64 bool expectTrustSuccess = false;
65
66 SecCertificateRef leaf = NULL, root = NULL;
67 CFStringRef hostname = NULL;
68 SecPolicyRef policy = NULL;
69 SecTrustRef trust = NULL;
70 CFArrayRef anchor_array = NULL;
71 CFDateRef date = NULL;
72
73 /* get filename in test dictionary */
74 file = CFDictionaryGetValue(test_info, CFSTR("Filename"));
75 require_action_quiet(file, cleanup, fail("%@: Unable to load filename from plist", test_name));
76
77 /* get leaf certificate from file */
78 cert_file_url = [[NSBundle bundleForClass:[self class]] URLForResource:(__bridge NSString *)file withExtension:@"cer" subdirectory:@"ssl-policy-certs"];
79 require_action_quiet(cert_file_url, cleanup, fail("%@: Unable to get url for cert file %@",
80 test_name, file));
81
82 cert_data = [NSData dataWithContentsOfURL:cert_file_url];
83
84 /* create certificates */
85 leaf = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)cert_data);
86 root = SecCertificateCreateWithBytes(NULL, _SSLTrustPolicyTestRootCA, sizeof(_SSLTrustPolicyTestRootCA));
87 require_action_quiet(leaf && root, cleanup, fail("%@: Unable to create certificates", test_name));
88
89 /* create policy */
90 hostname = CFDictionaryGetValue(test_info, CFSTR("Hostname"));
91 require_action_quiet(hostname, cleanup, fail("%@: Unable to load hostname from plist", test_name));
92
93 policy = SecPolicyCreateSSL(true, hostname);
94 require_action_quiet(policy, cleanup, fail("%@: Unable to create SSL policy with hostname %@",
95 test_name, hostname));
96
97 /* create trust ref */
98 OSStatus err = SecTrustCreateWithCertificates(leaf, policy, &trust);
99 CFRelease(policy);
100 require_noerr_action(err, cleanup, ok_status(err, "SecTrustCreateWithCertificates"));
101
102 /* set anchor in trust ref */
103 anchor_array = CFArrayCreate(NULL, (const void **)&root, 1, &kCFTypeArrayCallBacks);
104 require_action_quiet(anchor_array, cleanup, fail("%@: Unable to create anchor array", test_name));
105 err = SecTrustSetAnchorCertificates(trust, anchor_array);
106 require_noerr_action(err, cleanup, ok_status(err, "SecTrustSetAnchorCertificates"));
107
108 /* set date in trust ref to 4 Sep 2015 */
109 date = CFDateCreate(NULL, 463079909.0);
110 require_action_quiet(date, cleanup, fail("%@: Unable to create verify date", test_name));
111 err = SecTrustSetVerifyDate(trust, date);
112 CFRelease(date);
113 require_noerr_action(err, cleanup, ok_status(err, "SecTrustSetVerifyDate"));
114
115 /* evaluate */
116 bool is_valid = SecTrustEvaluateWithError(trust, &trustError);
117 if (!is_valid) {
118 failureReason = CFErrorCopyDescription(trustError);
119 }
120
121 /* get expected result for test */
122 expectedResult = CFDictionaryGetValue(test_info, CFSTR("Result"));
123 require_action_quiet(expectedResult, cleanup, fail("%@: Unable to get expected result",test_name));
124 if (!CFStringCompare(expectedResult, CFSTR("kSecTrustResultUnspecified"), 0) ||
125 !CFStringCompare(expectedResult, CFSTR("kSecTrustResultProceed"), 0)) {
126 expectTrustSuccess = true;
127 }
128
129 /* process results */
130 if (!CFDictionaryGetValueIfPresent(test_info, CFSTR("Reason"), (const void **)&reason)) {
131 /* not a known failure */
132 ok(is_valid == expectTrustSuccess, "%s %@%@",
133 expectTrustSuccess ? "REGRESSION" : "SECURITY",
134 test_name,
135 trustError);
136 } else if (reason) {
137 /* known failure */
138 XCTAssertTrue(true, "TODO test: %@", reason);
139 ok(is_valid == expectTrustSuccess, "%@%@",
140 test_name, expectTrustSuccess ? failureReason : CFSTR(" valid"));
141 } else {
142 fail("%@: unable to get reason for known failure", test_name);
143 }
144
145 cleanup:
146 CFReleaseNull(leaf);
147 CFReleaseNull(root);
148 CFReleaseNull(trust);
149 CFReleaseNull(anchor_array);
150 CFReleaseNull(failureReason);
151 CFReleaseNull(trustError);
152 }];
153 }
154
155 - (BOOL)runTrustEvaluation:(NSArray *)certs anchors:(NSArray *)anchors error:(NSError **)error
156 {
157 SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("example.com"));
158 NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:590000000.0]; // September 12, 2019 at 9:53:20 AM PDT
159 SecTrustRef trustRef = NULL;
160 BOOL result = NO;
161 CFErrorRef cferror = NULL;
162
163 require_noerr(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trustRef), errOut);
164 require_noerr(SecTrustSetVerifyDate(trustRef, (__bridge CFDateRef)date), errOut);
165
166 if (anchors) {
167 require_noerr(SecTrustSetAnchorCertificates(trustRef, (__bridge CFArrayRef)anchors), errOut);
168 }
169
170 result = SecTrustEvaluateWithError(trustRef, &cferror);
171 if (error && cferror) {
172 *error = (__bridge NSError*)cferror;
173 }
174
175 errOut:
176 CFReleaseNull(policy);
177 CFReleaseNull(trustRef);
178 CFReleaseNull(cferror);
179 return result;
180 }
181
182 - (void)testSystemTrust_MissingEKU
183 {
184 [self setTestRootAsSystem:_EKUTestSSLRootHash];
185 SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _noEKU_BeforeJul2019, sizeof(_noEKU_BeforeJul2019));
186 SecCertificateRef root = SecCertificateCreateWithBytes(NULL, _EKUTestSSLRoot, sizeof(_EKUTestSSLRoot));
187 NSArray *certs = @[(__bridge id)leaf, (__bridge id)root];
188
189 NSError *error = nil;
190 XCTAssertFalse([self runTrustEvaluation:certs anchors:@[(__bridge id)root] error:&error], "system-trusted missing EKU cert succeeded");
191
192 [self removeTestRootAsSystem];
193 CFReleaseNull(leaf);
194 CFReleaseNull(root);
195 }
196
197 - (void)testSystemTrust_AnyEKU
198 {
199 [self setTestRootAsSystem:_EKUTestSSLRootHash];
200 SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _anyEKU_BeforeJul2019, sizeof(_anyEKU_BeforeJul2019));
201 SecCertificateRef root = SecCertificateCreateWithBytes(NULL, _EKUTestSSLRoot, sizeof(_EKUTestSSLRoot));
202 NSArray *certs = @[(__bridge id)leaf, (__bridge id)root];
203
204 NSError *error = nil;
205 XCTAssertFalse([self runTrustEvaluation:certs anchors:@[(__bridge id)root] error:&error], "system-trusted Any EKU cert succeeded");
206
207 [self removeTestRootAsSystem];
208 CFReleaseNull(leaf);
209 CFReleaseNull(root);
210 }
211
212 - (void)testSystemTrust_ServerAuthEKU
213 {
214 [self setTestRootAsSystem:_EKUTestSSLRootHash];
215 SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _serverEKU_BeforeJul2019, sizeof(_serverEKU_BeforeJul2019));
216 SecCertificateRef root = SecCertificateCreateWithBytes(NULL, _EKUTestSSLRoot, sizeof(_EKUTestSSLRoot));
217 NSArray *certs = @[(__bridge id)leaf, (__bridge id)root];
218
219 NSError *error = nil;
220 XCTAssertTrue([self runTrustEvaluation:certs anchors:@[(__bridge id)root] error:&error], "system-trusted ServerAuth EKU cert failed: %@", error);
221
222 [self removeTestRootAsSystem];
223 CFReleaseNull(leaf);
224 CFReleaseNull(root);
225 }
226
227 // Other app trust of root SSL EKU tests of certs issued before July 2019 occur in testSSLPolicyCerts (Test4, Test17)
228
229 - (void)testAppTrustRoot_AnyEKU_BeforeJul2019
230 {
231 SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _anyEKU_BeforeJul2019, sizeof(_anyEKU_BeforeJul2019));
232 SecCertificateRef root = SecCertificateCreateWithBytes(NULL, _EKUTestSSLRoot, sizeof(_EKUTestSSLRoot));
233 NSArray *certs = @[(__bridge id)leaf, (__bridge id)root];
234
235 NSError *error = nil;
236 XCTAssertTrue([self runTrustEvaluation:certs anchors:@[(__bridge id)root] error:&error], "app-trusted root, anyEKU leaf failed: %@", error);
237
238 CFReleaseNull(leaf);
239 CFReleaseNull(root);
240 }
241
242 - (void)testAppTrustRoot_MissingEKU_AfterJul2019
243 {
244 SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _noEKU_AfterJul2019, sizeof(_noEKU_AfterJul2019));
245 SecCertificateRef root = SecCertificateCreateWithBytes(NULL, _EKUTestSSLRoot, sizeof(_EKUTestSSLRoot));
246 NSArray *certs = @[(__bridge id)leaf, (__bridge id)root];
247
248 NSError *error = nil;
249 XCTAssertFalse([self runTrustEvaluation:certs anchors:@[(__bridge id)root] error:&error], "app-trusted root, missing EKU leaf succeeded");
250
251 CFReleaseNull(leaf);
252 CFReleaseNull(root);
253 }
254
255 - (void)testAppTrustLegacy_MissingEKU_AfterJul2019
256 {
257 SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _noEKU_AfterJul2019, sizeof(_noEKU_AfterJul2019));
258 SecCertificateRef root = SecCertificateCreateWithBytes(NULL, _EKUTestSSLRoot, sizeof(_EKUTestSSLRoot));
259 NSArray *certs = @[(__bridge id)leaf, (__bridge id)root];
260
261 SecPolicyRef policy = SecPolicyCreateLegacySSL(true, CFSTR("example.com"));
262 NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:590000000.0]; // September 12, 2019 at 9:53:20 AM PDT
263 SecTrustRef trustRef = NULL;
264 CFErrorRef cferror = NULL;
265
266 require_noerr(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trustRef), errOut);
267 require_noerr(SecTrustSetVerifyDate(trustRef, (__bridge CFDateRef)date), errOut);
268 require_noerr(SecTrustSetAnchorCertificates(trustRef, (__bridge CFArrayRef)@[(__bridge id)root]), errOut);
269
270 XCTAssertTrue(SecTrustEvaluateWithError(trustRef, &cferror));
271
272 errOut:
273 CFReleaseNull(policy);
274 CFReleaseNull(trustRef);
275 CFReleaseNull(cferror);
276 CFReleaseNull(leaf);
277 CFReleaseNull(root);
278 }
279
280 - (void)testAppTrustRoot_AnyEKU_AfterJul2019
281 {
282 SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _anyEKU_AfterJul2019, sizeof(_anyEKU_AfterJul2019));
283 SecCertificateRef root = SecCertificateCreateWithBytes(NULL, _EKUTestSSLRoot, sizeof(_EKUTestSSLRoot));
284 NSArray *certs = @[(__bridge id)leaf, (__bridge id)root];
285
286 NSError *error = nil;
287 XCTAssertFalse([self runTrustEvaluation:certs anchors:@[(__bridge id)root] error:&error], "app-trusted root, anyEKU leaf succeeded");
288
289 CFReleaseNull(leaf);
290 CFReleaseNull(root);
291 }
292
293 - (void)testAppTrustRoot_ServerAuthEKU_AfterJul2019
294 {
295 SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _serverEKU_AfterJul2019, sizeof(_serverEKU_AfterJul2019));
296 SecCertificateRef root = SecCertificateCreateWithBytes(NULL, _EKUTestSSLRoot, sizeof(_EKUTestSSLRoot));
297 NSArray *certs = @[(__bridge id)leaf, (__bridge id)root];
298
299 NSError *error = nil;
300 XCTAssertTrue([self runTrustEvaluation:certs anchors:@[(__bridge id)root] error:&error], "app-trusted root, serverAuth EKU leaf failed: %@", error);
301
302 CFReleaseNull(leaf);
303 CFReleaseNull(root);
304 }
305
306 - (void)testAppTrustLeaf_MissingEKU_AfterJul2019
307 {
308 SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _noEKU_AfterJul2019, sizeof(_noEKU_AfterJul2019));
309
310 NSError *error = nil;
311 XCTAssertFalse([self runTrustEvaluation:@[(__bridge id)leaf] anchors:@[(__bridge id)leaf] error:&error], "app-trusted missing EKU leaf succeeded");
312
313 CFReleaseNull(leaf);
314 }
315
316 #if !TARGET_OS_BRIDGE // bridgeOS doesn't support trust settings
317 - (void)testUserTrustRoot_MissingEKU_AfterJul2019
318 {
319 SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _noEKU_AfterJul2019, sizeof(_noEKU_AfterJul2019));
320 SecCertificateRef root = SecCertificateCreateWithBytes(NULL, _EKUTestSSLRoot, sizeof(_EKUTestSSLRoot));
321 id persistentRef = [self addTrustSettingsForCert:root];
322 NSArray *certs = @[(__bridge id)leaf, (__bridge id)root];
323
324 NSError *error = nil;
325 XCTAssertTrue([self runTrustEvaluation:certs anchors:nil error:&error], "user-trusted root, missing EKU leaf failed: %@", error);
326
327 [self removeTrustSettingsForCert:root persistentRef:persistentRef];
328 CFReleaseNull(leaf);
329 CFReleaseNull(root);
330 }
331
332 - (void)testUserTrustRoot_AnyEKU_AfterJul2019
333 {
334 SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _anyEKU_AfterJul2019, sizeof(_anyEKU_AfterJul2019));
335 SecCertificateRef root = SecCertificateCreateWithBytes(NULL, _EKUTestSSLRoot, sizeof(_EKUTestSSLRoot));
336 id persistentRef = [self addTrustSettingsForCert:root];
337 NSArray *certs = @[(__bridge id)leaf, (__bridge id)root];
338
339 NSError *error = nil;
340 XCTAssertTrue([self runTrustEvaluation:certs anchors:nil error:&error], "user-trusted root, anyEKU leaf failed: %@", error);
341
342 [self removeTrustSettingsForCert:root persistentRef:persistentRef];
343 CFReleaseNull(leaf);
344 CFReleaseNull(root);
345 }
346
347 - (void)testUserTrustRoot_ServerAuthEKU_AfterJul2019
348 {
349 SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _serverEKU_AfterJul2019, sizeof(_serverEKU_AfterJul2019));
350 SecCertificateRef root = SecCertificateCreateWithBytes(NULL, _EKUTestSSLRoot, sizeof(_EKUTestSSLRoot));
351 id persistentRef = [self addTrustSettingsForCert:root];
352 NSArray *certs = @[(__bridge id)leaf, (__bridge id)root];
353
354 NSError *error = nil;
355 XCTAssertTrue([self runTrustEvaluation:certs anchors:nil error:&error], "user-trusted root, serverAuth EKU leaf failed: %@", error);
356
357 [self removeTrustSettingsForCert:root persistentRef:persistentRef];
358 CFReleaseNull(leaf);
359 CFReleaseNull(root);
360 }
361
362 - (void)testUserTrustLeaf_MissingEKU_AfterJul2019
363 {
364 SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _noEKU_AfterJul2019, sizeof(_noEKU_AfterJul2019));
365 id persistentRef = [self addTrustSettingsForCert:leaf];
366
367 NSError *error = nil;
368 XCTAssertTrue([self runTrustEvaluation:@[(__bridge id)leaf] anchors:nil error:&error], "user-trusted missing EKU leaf failed: %@", error);
369
370 [self removeTrustSettingsForCert:leaf persistentRef:persistentRef];
371 CFReleaseNull(leaf);
372 }
373
374 - (void)testUserTrustLeaf_AnyEKU_AfterJul2019
375 {
376 SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _anyEKU_AfterJul2019, sizeof(_anyEKU_AfterJul2019));
377 id persistentRef = [self addTrustSettingsForCert:leaf];
378
379 NSError *error = nil;
380 XCTAssertTrue([self runTrustEvaluation:@[(__bridge id)leaf] anchors:nil error:&error], "user-trusted anyEKU leaf failed: %@", error);
381
382 [self removeTrustSettingsForCert:leaf persistentRef:persistentRef];
383 CFReleaseNull(leaf);
384 }
385
386 - (void)testUserTrustLeaf_ServerAuthEKU_AfterJul2019
387 {
388 SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _serverEKU_AfterJul2019, sizeof(_serverEKU_AfterJul2019));
389 id persistentRef = [self addTrustSettingsForCert:leaf];
390
391 NSError *error = nil;
392 XCTAssertTrue([self runTrustEvaluation:@[(__bridge id)leaf] anchors:nil error:&error], "user-trusted serverAuth EKU leaf failed: %@", error);
393
394 [self removeTrustSettingsForCert:leaf persistentRef:persistentRef];
395 CFReleaseNull(leaf);
396 }
397 #endif // !TARGET_OS_BRIDGE
398
399 @end