2 * Copyright (c) 2017-2018 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
24 #include <AssertMacros.h>
25 #import <Foundation/Foundation.h>
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>
34 #include "shared_regressions.h"
36 #include "si-32-sectrust-pinning-required.h"
39 static NSArray *certs = nil;
40 static NSArray *root = nil;
41 static NSDate *verifyDate = nil;
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));
48 certs = @[(__bridge id)leaf,(__bridge id)intermediate];
49 root = @[(__bridge id)rootcert];
50 verifyDate = [NSDate dateWithTimeIntervalSinceReferenceDate:560000000.0]; //September 30, 2018 at 4:33:20 AM PDT
53 CFReleaseNull(intermediate);
54 CFReleaseNull(rootcert);
57 static SecTrustResultType test_with_policy_exception(SecPolicyRef CF_CONSUMED policy, bool set_exception)
59 SecTrustRef trust = NULL;
60 SecTrustResultType trustResult = kSecTrustResultInvalid;
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);
66 SecTrustSetPinningException(trust);
68 require_noerr_quiet(SecTrustEvaluate(trust, &trustResult), cleanup);
71 CFReleaseNull(policy);
76 static SecTrustResultType test_with_policy(SecPolicyRef CF_CONSUMED policy) {
77 return test_with_policy_exception(policy, false);
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)
85 SecPolicyRef policy = NULL;
87 policy = SecPolicyCreateSSL(true, CFSTR("openmarket.ess.apple.com"));
88 SecPolicySetOptionsValue(policy, kSecPolicyCheckPinningRequired, kCFBooleanTrue);
89 is(test_with_policy(policy), kSecTrustResultRecoverableTrustFailure, "Unpinned connection succeeeded when pinning required");
91 policy = SecPolicyCreateAppleIDSServiceContext(CFSTR("openmarket.ess.apple.com"), NULL);
92 SecPolicySetOptionsValue(policy, kSecPolicyCheckPinningRequired, kCFBooleanTrue);
93 is(test_with_policy(policy), kSecTrustResultUnspecified, "Policy pinned connection failed when pinning required");
95 policy = SecPolicyCreateSSL(true, CFSTR("profile.ess.apple.com"));
96 SecPolicySetOptionsValue(policy, kSecPolicyCheckPinningRequired, kCFBooleanTrue);
97 is(test_with_policy(policy), kSecTrustResultUnspecified, "Systemwide hostname pinned connection failed when pinning required");
99 NSDictionary *policy_properties = @{
100 (__bridge NSString *)kSecPolicyName : @"openmarket.ess.apple.com",
101 (__bridge NSString *)kSecPolicyPolicyName : @"IDS",
103 policy = SecPolicyCreateWithProperties(kSecPolicyAppleSSL, (__bridge CFDictionaryRef)policy_properties);
104 SecPolicySetOptionsValue(policy, kSecPolicyCheckPinningRequired, kCFBooleanTrue);
105 is(test_with_policy(policy), kSecTrustResultUnspecified, "Systemwide policy name pinned connection failed when pinning required");
107 policy = SecPolicyCreateSSL(true, CFSTR("openmarket.ess.apple.com"));
108 SecPolicySetOptionsValue(policy, kSecPolicyCheckPinningRequired, kCFBooleanTrue);
109 is(test_with_policy_exception(policy, true), kSecTrustResultUnspecified, "Unpinned connection failed when pinning exception set");
111 /* can I write an effective test for charles?? */
114 int si_32_sectrust_pinning_required(int argc, char *const *argv)