]> git.saurik.com Git - apple/security.git/blob - OSX/sec/Security/Regressions/secitem/si-32-sectrust-pinning-required.m
Security-59754.41.1.tar.gz
[apple/security.git] / OSX / sec / Security / Regressions / secitem / si-32-sectrust-pinning-required.m
1 /*
2 * Copyright (c) 2017-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 #include <AssertMacros.h>
25 #import <Foundation/Foundation.h>
26
27 #include <utilities/SecCFRelease.h>
28 #include <Security/SecPolicyInternal.h>
29 #include <Security/SecPolicyPriv.h>
30 #include <Security/SecCertificatePriv.h>
31 #include <Security/SecTrust.h>
32 #include <Security/SecTrustPriv.h>
33
34 #include "shared_regressions.h"
35
36 #include "si-32-sectrust-pinning-required.h"
37
38
39 static NSArray *certs = nil;
40 static NSArray *root = nil;
41 static NSDate *verifyDate = nil;
42
43 static void setup_globals(void) {
44 SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _ids_test, sizeof(_ids_test));
45 SecCertificateRef intermediate = SecCertificateCreateWithBytes(NULL, _TestAppleServerAuth, sizeof(_TestAppleServerAuth));
46 SecCertificateRef rootcert = SecCertificateCreateWithBytes(NULL, _TestAppleRootCA, sizeof(_TestAppleRootCA));
47
48 certs = @[(__bridge id)leaf,(__bridge id)intermediate];
49 root = @[(__bridge id)rootcert];
50 verifyDate = [NSDate dateWithTimeIntervalSinceReferenceDate:622000000.0]; //September 16, 2020 at 6:46:40 PM PDT
51
52 CFReleaseNull(leaf);
53 CFReleaseNull(intermediate);
54 CFReleaseNull(rootcert);
55 }
56
57 static SecTrustResultType test_with_policy_exception(SecPolicyRef CF_CONSUMED policy, bool set_exception)
58 {
59 SecTrustRef trust = NULL;
60 SecTrustResultType trustResult = kSecTrustResultInvalid;
61
62 require_noerr_quiet(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trust), cleanup);
63 require_noerr_quiet(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)root), cleanup);
64 require_noerr_quiet(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)verifyDate), cleanup);
65 if (set_exception) {
66 SecTrustSetPinningException(trust);
67 }
68 require_noerr_quiet(SecTrustEvaluate(trust, &trustResult), cleanup);
69
70 cleanup:
71 CFReleaseNull(policy);
72 CFReleaseNull(trust);
73 return trustResult;
74 }
75
76 static SecTrustResultType test_with_policy(SecPolicyRef CF_CONSUMED policy) {
77 return test_with_policy_exception(policy, false);
78 }
79
80
81 /* Technically, this feature works by reading the info plist of the caller. We'll fake it here by
82 * setting the policy option for requiring pinning. */
83 static void tests(void)
84 {
85 SecPolicyRef policy = NULL;
86
87 // init domains are excluded from IDS pinning rules
88 policy = SecPolicyCreateSSL(true, CFSTR("init.ess.apple.com"));
89 SecPolicySetOptionsValue(policy, kSecPolicyCheckPinningRequired, kCFBooleanTrue);
90 is(test_with_policy(policy), kSecTrustResultRecoverableTrustFailure, "Unpinned connection succeeeded when pinning required");
91
92 policy = SecPolicyCreateAppleIDSServiceContext(CFSTR("init.ess.apple.com"), NULL);
93 SecPolicySetOptionsValue(policy, kSecPolicyCheckPinningRequired, kCFBooleanTrue);
94 is(test_with_policy(policy), kSecTrustResultUnspecified, "Policy pinned connection failed when pinning required");
95
96 policy = SecPolicyCreateSSL(true, CFSTR("profile.ess.apple.com"));
97 SecPolicySetOptionsValue(policy, kSecPolicyCheckPinningRequired, kCFBooleanTrue);
98 is(test_with_policy(policy), kSecTrustResultUnspecified, "Systemwide hostname pinned connection failed when pinning required");
99
100 NSDictionary *policy_properties = @{
101 (__bridge NSString *)kSecPolicyName : @"init.ess.apple.com",
102 (__bridge NSString *)kSecPolicyPolicyName : @"IDS",
103 };
104 policy = SecPolicyCreateWithProperties(kSecPolicyAppleSSL, (__bridge CFDictionaryRef)policy_properties);
105 SecPolicySetOptionsValue(policy, kSecPolicyCheckPinningRequired, kCFBooleanTrue);
106 is(test_with_policy(policy), kSecTrustResultUnspecified, "Systemwide policy name pinned connection failed when pinning required");
107
108 policy = SecPolicyCreateSSL(true, CFSTR("init.ess.apple.com"));
109 SecPolicySetOptionsValue(policy, kSecPolicyCheckPinningRequired, kCFBooleanTrue);
110 is(test_with_policy_exception(policy, true), kSecTrustResultUnspecified, "Unpinned connection failed when pinning exception set");
111
112 /* can I write an effective test for charles?? */
113 }
114
115 int si_32_sectrust_pinning_required(int argc, char *const *argv)
116 {
117 plan_tests(5);
118 setup_globals();
119 tests();
120 return 0;
121 }