]> git.saurik.com Git - apple/security.git/blob - OSX/sec/Security/Regressions/secitem/si-29-sectrust-sha1-deprecation.m
Security-58286.260.20.tar.gz
[apple/security.git] / OSX / sec / Security / Regressions / secitem / si-29-sectrust-sha1-deprecation.m
1 /*
2 * Copyright (c) 2016 Apple Inc. All Rights Reserved.
3 */
4
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>
14
15 #if TARGET_OS_IPHONE
16 #include <Security/SecTrustStore.h>
17 #else
18 #include <Security/SecKeychain.h>
19 #endif
20
21 #include "shared_regressions.h"
22
23 #include "si-29-sectrust-sha1-deprecation.h"
24
25 #import <Foundation/Foundation.h>
26
27 static SecCertificateRef sha1_root = NULL;
28
29 #if TARGET_OS_IPHONE
30 static SecTrustStoreRef defaultStore = NULL;
31 #else
32 #define kSystemLoginKeychainPath "/Library/Keychains/System.keychain"
33 static NSMutableArray *deleteMeCertificates = NULL;
34 #endif
35
36
37 static void setup_globals(void) {
38
39 sha1_root = SecCertificateCreateWithBytes(NULL, _digiCertRoot, sizeof(_digiCertRoot));
40
41 #if TARGET_OS_IPHONE
42 defaultStore = SecTrustStoreForDomain(kSecTrustStoreDomainUser);
43 #else
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;
49
50 SecKeychainOpen(kSystemLoginKeychainPath, &kcRef);
51 if (!kcRef) {
52 goto out;
53 }
54
55 deleteMeCertificates = [[NSMutableArray alloc] init];
56
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);
63
64 out:
65 CFReleaseNull(kcRef);
66 #endif
67 }
68
69 static void cleanup_globals(void) {
70 #if !TARGET_OS_IPHONE
71 [deleteMeCertificates enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
72 SecItemDelete((CFDictionaryRef)@{ (__bridge NSString*)kSecValuePersistentRef: [obj objectAtIndex:0]});
73 }];
74 #endif
75
76 CFReleaseNull(sha1_root);
77 }
78
79
80 static void setTrust(SecTrustRef *trust, NSArray *certs, SecPolicyRef policy)
81 {
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");
88 cleanup:
89 return;
90 }
91
92 static void tests(void)
93 {
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;
100
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));
105
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");
112
113 /* Add trust setting for root */
114 #if TARGET_OS_IPHONE
115 require_noerr_string(SecTrustStoreSetTrustSettings(defaultStore, sha1_root, NULL),
116 cleanup, "failed to set trust settings");
117 #else
118 require_noerr_string(SecTrustSettingsSetTrustSettings(sha1_root, kSecTrustSettingsDomainAdmin,
119 NULL),
120 cleanup, "failed to set trust settings");
121 usleep(20000);
122 #endif
123
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");
128
129 /* Remove trust setting for root */
130 #if TARGET_OS_IPHONE
131 require_noerr_string(SecTrustStoreRemoveCertificate(defaultStore, sha1_root),
132 cleanup, "failed to remove trust settings");
133 #else
134 require_noerr_string(SecTrustSettingsRemoveTrustSettings(sha1_root, kSecTrustSettingsDomainAdmin),
135 cleanup, "failed to remove trust settings");
136 #endif
137
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");
142
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");
147
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");
151
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");
157
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");
163
164 cleanup:
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);
172 }
173
174 int si_29_sectrust_sha1_deprecation(int argc, char *const *argv)
175 {
176 plan_tests(6);
177
178 @autoreleasepool {
179 setup_globals();
180 tests();
181 cleanup_globals();
182 }
183
184 return 0;
185 }