2 * Copyright (c) 2016 Apple Inc. All Rights Reserved.
5 #include <AssertMacros.h>
6 #import <Foundation/Foundation.h>
7 #include <Security/SecCertificate.h>
8 #include <Security/SecCertificatePriv.h>
9 #include <Security/SecPolicyPriv.h>
10 #include <Security/SecTrust.h>
11 #include <utilities/SecCFRelease.h>
12 #include <Security/SecTrustSettings.h>
13 #include <Security/SecTrustSettingsPriv.h>
16 #include <Security/SecTrustStore.h>
18 #include <Security/SecKeychain.h>
21 #include "shared_regressions.h"
23 #include "si-29-sectrust-sha1-deprecation.h"
25 #import <Foundation/Foundation.h>
27 static SecCertificateRef sha1_root = NULL;
30 static SecTrustStoreRef defaultStore = NULL;
32 #define kSystemLoginKeychainPath "/Library/Keychains/System.keychain"
33 static NSMutableArray *deleteMeCertificates = NULL;
37 static void setup_globals(void) {
39 sha1_root = SecCertificateCreateWithBytes(NULL, _digiCertRoot, sizeof(_digiCertRoot));
42 defaultStore = SecTrustStoreForDomain(kSecTrustStoreDomainUser);
44 /* Since we're putting trust settings in the admin domain,
45 * we need to add the certs to the system keychain. */
46 SecKeychainRef kcRef = NULL;
47 CFArrayRef certRef = NULL;
48 NSDictionary *attrs = nil;
50 SecKeychainOpen(kSystemLoginKeychainPath, &kcRef);
55 deleteMeCertificates = [[NSMutableArray alloc] init];
57 attrs = @{(__bridge NSString*)kSecValueRef: (__bridge id)sha1_root,
58 (__bridge NSString*)kSecUseKeychain: (__bridge id)kcRef,
59 (__bridge NSString*)kSecReturnPersistentRef: @YES};
60 if (SecItemAdd((CFDictionaryRef)attrs, (void *)&certRef) == 0)
61 [deleteMeCertificates addObject:(__bridge NSArray *)certRef];
62 CFReleaseNull(certRef);
69 static void cleanup_globals(void) {
71 [deleteMeCertificates enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
72 SecItemDelete((CFDictionaryRef)@{ (__bridge NSString*)kSecValuePersistentRef: [obj objectAtIndex:0]});
76 CFReleaseNull(sha1_root);
80 static void setTrust(SecTrustRef *trust, NSArray *certs, SecPolicyRef policy)
82 // November 4, 2016 at 5:53:20 PM PDT
83 NSDate *verifyDate = [NSDate dateWithTimeIntervalSinceReferenceDate:500000000.0];
84 CFReleaseNull(*trust);
85 require_noerr_string(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, trust), cleanup, "failed to create trust");
86 require_noerr_string(SecTrustSetVerifyDate(*trust, (__bridge CFDateRef)verifyDate),
87 cleanup, "failed to set verify date");
92 static void tests(void)
94 SecCertificateRef sha1_leaf = NULL, sha1_int = NULL,
95 sha2_leaf = NULL, sha2_int = NULL;
96 NSArray *anchors = nil, *sha1_certs = nil, *sha2_certs = nil;
97 SecPolicyRef serverPolicy = NULL, clientPolicy = NULL;
98 SecTrustRef trust = NULL;
99 SecTrustResultType trustResult = kSecTrustResultInvalid;
101 sha1_leaf = SecCertificateCreateWithBytes(NULL, _badssl_sha1, sizeof(_badssl_sha1));
102 sha1_int = SecCertificateCreateWithBytes(NULL, _digiCertSSCA, sizeof(_digiCertSSCA));
103 sha2_leaf = SecCertificateCreateWithBytes(NULL, _badssl_sha2, sizeof(_badssl_sha2));
104 sha2_int = SecCertificateCreateWithBytes(NULL, _COMODO_DV, sizeof(_COMODO_DV));
106 /* SHA1 cert from system roots fails SSL server policy*/
107 sha1_certs = @[ (__bridge id)sha1_leaf, (__bridge id)sha1_int];
108 serverPolicy = SecPolicyCreateSSL(true, CFSTR("www.badssl.com"));
109 setTrust(&trust, sha1_certs, serverPolicy);
110 require_noerr_string(SecTrustEvaluate(trust, &trustResult), cleanup, "failed to evaluate trust");
111 is(trustResult, kSecTrustResultRecoverableTrustFailure, "reject test: system-trusted SHA-1 SSL server");
113 /* Add trust setting for root */
115 require_noerr_string(SecTrustStoreSetTrustSettings(defaultStore, sha1_root, NULL),
116 cleanup, "failed to set trust settings");
118 require_noerr_string(SecTrustSettingsSetTrustSettings(sha1_root, kSecTrustSettingsDomainAdmin,
120 cleanup, "failed to set trust settings");
124 /* SHA1 cert now passes SSL server*/
125 setTrust(&trust, sha1_certs, serverPolicy);
126 require_noerr_string(SecTrustEvaluate(trust, &trustResult), cleanup, "failed to evaluate trust");
127 is(trustResult, kSecTrustResultProceed, "accept test: user-trusted SHA-1 SSL server");
129 /* Remove trust setting for root */
131 require_noerr_string(SecTrustStoreRemoveCertificate(defaultStore, sha1_root),
132 cleanup, "failed to remove trust settings");
134 require_noerr_string(SecTrustSettingsRemoveTrustSettings(sha1_root, kSecTrustSettingsDomainAdmin),
135 cleanup, "failed to remove trust settings");
138 /* SHA1 cert fails SSL server */
139 setTrust(&trust, sha1_certs, serverPolicy);
140 require_noerr_string(SecTrustEvaluate(trust, &trustResult), cleanup, "failed to evaluate trust");
141 is(trustResult, kSecTrustResultRecoverableTrustFailure, "reject test: system-trusted SHA-1 SSL server");
143 /* Set anchor for root */
144 require_quiet(sha1_root, cleanup);
145 anchors = @[(__bridge id)sha1_root];
146 require_noerr_string(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)anchors), cleanup, "failed to set anchors");
148 /* SHA1 cert passes SSL server */
149 require_noerr_string(SecTrustEvaluate(trust, &trustResult), cleanup, "failed to evaluate trust");
150 is(trustResult, kSecTrustResultUnspecified, "accept test: app-trusted SHA-1 SSL server");
152 /* SHA1 cert from system root passes SSL client */
153 clientPolicy = SecPolicyCreateSSL(false, NULL);
154 setTrust(&trust, sha1_certs, clientPolicy);
155 require_noerr_string(SecTrustEvaluate(trust, &trustResult), cleanup, "failed to evaluate trust");
156 is(trustResult, kSecTrustResultUnspecified, "accept test: system-trusted SHA-1 SSL client");
158 /* SHA256 cert from system root passes SSL server */
159 sha2_certs = @[ (__bridge id)sha2_leaf, (__bridge id)sha2_int];
160 setTrust(&trust, sha2_certs, serverPolicy);
161 require_noerr_string(SecTrustEvaluate(trust, &trustResult), cleanup, "failed to evaluate trust");
162 is(trustResult, kSecTrustResultUnspecified, "accept test: system-trusted SHA2 SSL server");
165 CFReleaseNull(sha1_leaf);
166 CFReleaseNull(sha1_int);
167 CFReleaseNull(sha2_leaf);
168 CFReleaseNull(sha2_int);
169 CFReleaseNull(serverPolicy);
170 CFReleaseNull(clientPolicy);
171 CFReleaseNull(trust);
174 int si_29_sectrust_sha1_deprecation(int argc, char *const *argv)