2 * Copyright (c) 2017 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_prod, sizeof(_ids_prod));
45 SecCertificateRef intermediate = SecCertificateCreateWithBytes(NULL, _AppleServerAuth, sizeof(_AppleServerAuth));
46 SecCertificateRef rootcert = SecCertificateCreateWithBytes(NULL, _AppleRootCA, sizeof(_AppleRootCA));
48 certs = @[(__bridge id)leaf,(__bridge id)intermediate];
49 root = @[(__bridge id)rootcert];
50 verifyDate = [NSDate dateWithTimeIntervalSinceReferenceDate:508000000.0]; //February 5, 2017 at 7:06:40 AM PST
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 //%%% openmarket.ess.apple.com cert is now revoked, so expect a fatal result.
90 is(test_with_policy(policy), kSecTrustResultFatalTrustFailure, "Unpinned connection succeeeded when pinning required");
92 policy = SecPolicyCreateAppleIDSServiceContext(CFSTR("openmarket.ess.apple.com"), NULL);
93 SecPolicySetOptionsValue(policy, kSecPolicyCheckPinningRequired, kCFBooleanTrue);
94 //%%% openmarket.ess.apple.com cert is now revoked, so expect a fatal result.
95 is(test_with_policy(policy), kSecTrustResultFatalTrustFailure, "Policy pinned connection failed when pinning required");
97 policy = SecPolicyCreateSSL(true, CFSTR("profile.ess.apple.com"));
98 //%%% profile.ess.apple.com cert is now revoked, so expect a fatal result.
99 SecPolicySetOptionsValue(policy, kSecPolicyCheckPinningRequired, kCFBooleanTrue);
100 is(test_with_policy(policy), kSecTrustResultFatalTrustFailure, "Systemwide hostname pinned connection failed when pinning required");
102 NSDictionary *policy_properties = @{
103 (__bridge NSString *)kSecPolicyName : @"openmarket.ess.apple.com",
104 (__bridge NSString *)kSecPolicyPolicyName : @"IDS",
106 policy = SecPolicyCreateWithProperties(kSecPolicyAppleSSL, (__bridge CFDictionaryRef)policy_properties);
107 SecPolicySetOptionsValue(policy, kSecPolicyCheckPinningRequired, kCFBooleanTrue);
108 //%%% openmarket.ess.apple.com cert is now revoked, so expect a fatal result.
109 is(test_with_policy(policy), kSecTrustResultFatalTrustFailure, "Systemwide policy name pinned connection failed when pinning required");
111 policy = SecPolicyCreateSSL(true, CFSTR("openmarket.ess.apple.com"));
112 SecPolicySetOptionsValue(policy, kSecPolicyCheckPinningRequired, kCFBooleanTrue);
113 //%%% openmarket.ess.apple.com cert is now revoked, so expect a fatal result.
114 is(test_with_policy_exception(policy, true), kSecTrustResultFatalTrustFailure, "Unpinned connection failed when pinning exception set");
116 /* can I write an effective test for charles?? */
119 int si_32_sectrust_pinning_required(int argc, char *const *argv)