]> git.saurik.com Git - apple/security.git/blob - OSX/shared_regressions/si-88-sectrust-valid.m
Security-59306.140.5.tar.gz
[apple/security.git] / OSX / shared_regressions / si-88-sectrust-valid.m
1 /*
2 * si-88-sectrust-valid.m
3 * Security
4 *
5 * Copyright (c) 2017-2019 Apple Inc. All Rights Reserved.
6 *
7 */
8
9 #include <CoreFoundation/CoreFoundation.h>
10 #include <Security/Security.h>
11 #include <Security/SecTrust.h>
12 #include <Security/SecPolicy.h>
13 #include <stdlib.h>
14 #include <unistd.h>
15 #include <utilities/SecCFWrappers.h>
16
17 #include <sys/socket.h>
18 #include <sys/types.h>
19 #include <netinet/in.h>
20 #include <arpa/inet.h>
21 #include <netdb.h>
22
23 #include "shared_regressions.h"
24
25 enum {
26 kBasicPolicy = 0,
27 kSSLServerPolicy = 1,
28 };
29
30 /* number of tests in the test_valid_trust function */
31 #define TVT_COUNT 8
32
33 static void test_valid_trust(SecCertificateRef leaf, SecCertificateRef ca, SecCertificateRef subca,
34 CFArrayRef anchors, CFDateRef date, CFIndex policyID,
35 SecTrustResultType expected, const char *test_name)
36 {
37 CFArrayRef policies=NULL;
38 SecPolicyRef policy=NULL;
39 SecTrustRef trust=NULL;
40 SecTrustResultType trustResult;
41 CFMutableArrayRef certs=NULL;
42
43 printf("Starting %s\n", test_name);
44 isnt(certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create cert array");
45 if (certs) {
46 if (leaf) {
47 CFArrayAppendValue(certs, leaf);
48 }
49 if (ca) {
50 CFArrayAppendValue(certs, ca);
51 }
52 if (subca) {
53 CFArrayAppendValue(certs, subca);
54 }
55 }
56
57 if (policyID == kSSLServerPolicy) {
58 isnt(policy = SecPolicyCreateSSL(true, NULL), NULL, "create ssl policy");
59 } else {
60 isnt(policy = SecPolicyCreateBasicX509(), NULL, "create basic policy");
61 }
62 isnt(policies = CFArrayCreate(kCFAllocatorDefault, (const void **)&policy, 1, &kCFTypeArrayCallBacks), NULL, "create policies");
63 ok_status(SecTrustCreateWithCertificates(certs, policies, &trust), "create trust");
64
65 assert(trust); // silence analyzer
66 ok_status(SecTrustSetAnchorCertificates(trust, anchors), "set anchors");
67 ok_status(SecTrustSetVerifyDate(trust, date), "set date");
68 ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
69 ok(trustResult == expected, "trustResult %d expected (got %d)",
70 (int)expected, (int)trustResult);
71
72 CFReleaseSafe(certs);
73 CFReleaseSafe(policy);
74 CFReleaseSafe(policies);
75 CFReleaseSafe(trust);
76 }
77
78 #import <Foundation/Foundation.h>
79 SecCertificateRef SecCertificateCreateWithPEM(CFAllocatorRef allocator, CFDataRef pem_certificate);
80
81 static SecCertificateRef SecCertificateCreateFromResource(NSString *name)
82 {
83 NSString *resources = @"si-88-sectrust-valid-data";
84 NSString *extension = @"pem";
85
86 NSURL *url = [[NSBundle mainBundle] URLForResource:name withExtension:extension subdirectory:resources];
87 if (!url) {
88 printf("No URL for resource \"%s.pem\"\n", [name UTF8String]);
89 return NULL;
90 }
91
92 NSData *certData = [NSData dataWithContentsOfURL:url];
93 if (!certData) {
94 printf("No cert data for resource \"%s.pem\"\n", [name UTF8String]);
95 return NULL;
96 }
97
98 return SecCertificateCreateWithPEM(kCFAllocatorDefault, (__bridge CFDataRef)certData);
99 }
100
101 /* number of tests in date_constraints_tests function, plus calls to test_valid_trust */
102 #define DC_COUNT (12+(TVT_COUNT*6))
103
104 static void date_constraints_tests()
105 {
106 SecCertificateRef ca_na=NULL, ca_nb=NULL, root=NULL;
107 SecCertificateRef leaf_na_ok1=NULL, leaf_na_ok2=NULL;
108 SecCertificateRef leaf_nb_ok1=NULL, leaf_nb_ok2=NULL, leaf_nb_revoked1=NULL;
109
110 isnt(ca_na = SecCertificateCreateFromResource(@"ca-na"), NULL, "create ca-na cert");
111 isnt(ca_nb = SecCertificateCreateFromResource(@"ca-nb"), NULL, "create ca-nb cert");
112 isnt(root = SecCertificateCreateFromResource(@"root"), NULL, "create root cert");
113 isnt(leaf_na_ok1 = SecCertificateCreateFromResource(@"leaf-na-ok1"), NULL, "create leaf-na-ok1 cert");
114 isnt(leaf_na_ok2 = SecCertificateCreateFromResource(@"leaf-na-ok2"), NULL, "create leaf-na-ok2 cert");
115 isnt(leaf_nb_ok1 = SecCertificateCreateFromResource(@"leaf-nb-ok1"), NULL, "create leaf-nb-ok1 cert");
116 isnt(leaf_nb_ok2 = SecCertificateCreateFromResource(@"leaf-nb-ok2"), NULL, "create leaf-nb-ok2 cert");
117 isnt(leaf_nb_revoked1 = SecCertificateCreateFromResource(@"leaf-nb-revoked1"), NULL, "create leaf-nb-revoked1 cert");
118
119 CFMutableArrayRef anchors=NULL;
120 isnt(anchors = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create anchors array");
121 if (anchors && root) {
122 CFArrayAppendValue(anchors, root);
123 }
124 CFCalendarRef cal = NULL;
125 CFAbsoluteTime at;
126 CFDateRef date_20180102 = NULL; // a date when our test certs would all be valid, in the absence of Valid db info
127
128 isnt(cal = CFCalendarCreateWithIdentifier(kCFAllocatorDefault, kCFGregorianCalendar), NULL, "create calendar");
129 ok(CFCalendarComposeAbsoluteTime(cal, &at, "yMd", 2018, 1, 2), "create verify absolute time 20180102");
130 isnt(date_20180102 = CFDateCreate(kCFAllocatorDefault, at), NULL, "create verify date 20180102");
131
132 /* Case 0: leaf_na_ok1 (not revoked) */
133 /* -- OK: cert issued 2017-10-20, before the CA not-after date of 2017-10-21 */
134 /* test cert has no SCT, but is expected to be OK since we now only apply the CT restriction for SSL. */
135 test_valid_trust(leaf_na_ok1, ca_na, NULL, anchors, date_20180102,
136 kBasicPolicy, kSecTrustResultUnspecified,
137 "leaf_na_ok1 basic");
138
139 /* Case 1: leaf_na_ok1 (not revoked) */
140 /* -- BAD: since a not-after date now requires CT (for SSL) and the test cert has no SCT, this is fatal. */
141 test_valid_trust(leaf_na_ok1, ca_na, NULL, anchors, date_20180102,
142 kSSLServerPolicy, kSecTrustResultFatalTrustFailure,
143 "leaf_na_ok1 ssl");
144
145 /* Case 2: leaf_na_ok2 (revoked) */
146 /* -- BAD: cert issued 2017-10-26, after the CA not-after date of 2017-10-21 */
147 test_valid_trust(leaf_na_ok2, ca_na, NULL, anchors, date_20180102,
148 kBasicPolicy, kSecTrustResultFatalTrustFailure,
149 "leaf_na_ok2 basic");
150
151 /* Case 3: leaf_nb_ok1 (revoked) */
152 /* -- BAD: cert issued 2017-10-20, before the CA not-before date of 2017-10-22 */
153 test_valid_trust(leaf_nb_ok1, ca_nb, NULL, anchors, date_20180102,
154 kBasicPolicy, kSecTrustResultFatalTrustFailure,
155 "leaf_nb_ok1 basic");
156
157 /* Case 4: leaf_nb_ok2 (not revoked) */
158 /* -- OK: cert issued 2017-10-26, after the CA not-before date of 2017-10-22 */
159 test_valid_trust(leaf_nb_ok2, ca_nb, NULL, anchors, date_20180102,
160 kBasicPolicy, kSecTrustResultUnspecified,
161 "leaf_nb_ok2 basic");
162
163 /* Case 5: leaf_nb_revoked1 (revoked) */
164 /* -- BAD: cert issued 2017-10-20, before the CA not-before date of 2017-10-22 */
165 test_valid_trust(leaf_nb_revoked1, ca_nb, NULL, anchors, date_20180102,
166 kBasicPolicy, kSecTrustResultFatalTrustFailure,
167 "leaf_nb_revoked1 basic");
168
169 CFReleaseSafe(ca_na);
170 CFReleaseSafe(ca_nb);
171 CFReleaseSafe(leaf_na_ok1);
172 CFReleaseSafe(leaf_na_ok2);
173 CFReleaseSafe(leaf_nb_ok1);
174 CFReleaseSafe(leaf_nb_ok2);
175 CFReleaseSafe(leaf_nb_revoked1);
176 CFReleaseSafe(root);
177 CFReleaseSafe(anchors);
178 CFReleaseSafe(cal);
179 CFReleaseSafe(date_20180102);
180 }
181
182 /* number of tests in known_intermediate_tests function, plus calls to test_valid_trust */
183 #define KI_COUNT (10+(TVT_COUNT*3))
184
185 static void known_intermediate_tests()
186 {
187 SecCertificateRef ca_ki=NULL, root=NULL;
188 SecCertificateRef leaf_ki_ok1=NULL, leaf_ki_revoked1=NULL;
189 SecCertificateRef leaf_unknown=NULL, ca_unknown=NULL;
190
191 isnt(ca_ki = SecCertificateCreateFromResource(@"ca-ki"), NULL, "create ca-ki cert");
192 isnt(root = SecCertificateCreateFromResource(@"root"), NULL, "create root cert");
193 isnt(leaf_ki_ok1 = SecCertificateCreateFromResource(@"leaf-ki-ok1"), NULL, "create leaf-ki-ok1 cert");
194 isnt(leaf_ki_revoked1 = SecCertificateCreateFromResource(@"leaf-ki-revoked1"), NULL, "create leaf-ki-revoked1 cert");
195 isnt(ca_unknown = SecCertificateCreateFromResource(@"ca-unknown"), NULL, "create ca-unknown cert");
196 isnt(leaf_unknown = SecCertificateCreateFromResource(@"leaf-unknown"), NULL, "create leaf-unknown cert");
197
198 CFMutableArrayRef anchors=NULL;
199 isnt(anchors = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create anchors array");
200 if (anchors && root) {
201 CFArrayAppendValue(anchors, root);
202 }
203 CFCalendarRef cal = NULL;
204 CFAbsoluteTime at;
205 CFDateRef date_20180310 = NULL; // a date when our test certs would all be valid, in the absence of Valid db info
206
207 isnt(cal = CFCalendarCreateWithIdentifier(kCFAllocatorDefault, kCFGregorianCalendar), NULL, "create calendar");
208 ok(CFCalendarComposeAbsoluteTime(cal, &at, "yMd", 2018, 3, 10), "create verify absolute time 20180310");
209 isnt(date_20180310 = CFDateCreate(kCFAllocatorDefault, at), NULL, "create verify date 20180310");
210
211 /* Case 1: leaf_ki_ok1 */
212 /* -- OK: cert issued by a known intermediate */
213 test_valid_trust(leaf_ki_ok1, ca_ki, NULL, anchors, date_20180310,
214 kBasicPolicy, kSecTrustResultUnspecified,
215 "leaf_ki_ok1");
216
217 /* Case 2: leaf_ki_revoked1 */
218 /* -- BAD: CA specifies known-only+complete serial blocklist; this cert is on the blocklist. */
219 test_valid_trust(leaf_ki_revoked1, ca_ki, NULL, anchors, date_20180310,
220 kBasicPolicy, kSecTrustResultFatalTrustFailure,
221 "leaf_ki_revoked1");
222
223 /* Case 3: leaf_unknown */
224 /* -- BAD: ca_unknown issued from ca_ki, but is not a known intermediate.
225 * ca_ki has a path len of 0 which would normally result in kSecTrustResultRecoverableTrustFailure;
226 * however, since known-intermediates is asserted for ca_ki (non-overridable), we expect a fatal failure. */
227 test_valid_trust(leaf_unknown, ca_unknown, ca_ki, anchors, date_20180310,
228 kBasicPolicy, kSecTrustResultFatalTrustFailure,
229 "leaf_unknown test");
230
231 CFReleaseSafe(ca_ki);
232 CFReleaseSafe(leaf_ki_ok1);
233 CFReleaseSafe(leaf_ki_revoked1);
234 CFReleaseSafe(ca_unknown);
235 CFReleaseSafe(leaf_unknown);
236 CFReleaseSafe(root);
237 CFReleaseSafe(anchors);
238 CFReleaseSafe(cal);
239 CFReleaseSafe(date_20180310);
240 }
241
242 static int ping_host(char *host_name)
243 {
244 struct sockaddr_in pin;
245 struct hostent *nlp_host;
246 int sd = 0;
247 int port = 80;
248 int retries = 5; // we try 5 times, then give up
249
250 while ((nlp_host=gethostbyname(host_name))==0 && retries--) {
251 printf("Resolve Error! (%s) %d\n", host_name, h_errno);
252 sleep(1);
253 }
254 if (nlp_host==0) {
255 return 0;
256 }
257
258 bzero(&pin,sizeof(pin));
259 pin.sin_family=AF_INET;
260 pin.sin_addr.s_addr=htonl(INADDR_ANY);
261 pin.sin_addr.s_addr=((struct in_addr *)(nlp_host->h_addr))->s_addr;
262 pin.sin_port=htons(port);
263
264 sd=socket(AF_INET,SOCK_STREAM,0);
265
266 if (connect(sd,(struct sockaddr*)&pin,sizeof(pin))==-1) {
267 printf("connect error! (%s) %d\n", host_name, errno);
268 close(sd);
269 return 0;
270 }
271 close(sd);
272 return 1;
273 }
274
275 static int preflight_network()
276 {
277 char *hosts[] = {
278 "EVSecure-ocsp.verisign.com",
279 "EVIntl-ocsp.verisign.com",
280 "EVIntl-aia.verisign.com",
281 "ocsp.comodoca.com",
282 "crt.comodoca.com",
283 "ocsp.entrust.net",
284 "ocsp.digicert.com",
285 };
286
287 for (unsigned host_cnt = 0; host_cnt < sizeof(hosts)/sizeof(hosts[0]); host_cnt ++) {
288 if (!ping_host(hosts[host_cnt])) {
289 printf("Accessing specific server (%s) failed, check the network!\n", hosts[host_cnt]);
290 return 0;
291 }
292 }
293 return 1;
294 }
295
296 int si_88_sectrust_valid(int argc, char *const *argv)
297 {
298 plan_tests(DC_COUNT+KI_COUNT);
299
300 if (!preflight_network()) {
301 return 0;
302 }
303
304 date_constraints_tests();
305 known_intermediate_tests();
306
307 return 0;
308 }