2 * si-88-sectrust-valid.m
5 * Copyright (c) 2017-2018 Apple Inc. All Rights Reserved.
9 #include <CoreFoundation/CoreFoundation.h>
10 #include <Security/Security.h>
11 #include <Security/SecTrust.h>
12 #include <Security/SecPolicy.h>
15 #include <utilities/SecCFWrappers.h>
17 #include "shared_regressions.h"
24 /* number of tests in the test_valid_trust function */
27 static void test_valid_trust(SecCertificateRef leaf, SecCertificateRef ca, SecCertificateRef subca,
28 CFArrayRef anchors, CFDateRef date, CFIndex policyID,
29 SecTrustResultType expected, const char *test_name)
31 CFArrayRef policies=NULL;
32 SecPolicyRef policy=NULL;
33 SecTrustRef trust=NULL;
34 SecTrustResultType trustResult;
35 CFMutableArrayRef certs=NULL;
37 printf("Starting %s\n", test_name);
38 isnt(certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create cert array");
41 CFArrayAppendValue(certs, leaf);
44 CFArrayAppendValue(certs, ca);
47 CFArrayAppendValue(certs, subca);
51 if (policyID == kSSLServerPolicy) {
52 isnt(policy = SecPolicyCreateSSL(true, NULL), NULL, "create ssl policy");
54 isnt(policy = SecPolicyCreateBasicX509(), NULL, "create basic policy");
56 isnt(policies = CFArrayCreate(kCFAllocatorDefault, (const void **)&policy, 1, &kCFTypeArrayCallBacks), NULL, "create policies");
57 ok_status(SecTrustCreateWithCertificates(certs, policies, &trust), "create trust");
59 assert(trust); // silence analyzer
60 ok_status(SecTrustSetAnchorCertificates(trust, anchors), "set anchors");
61 ok_status(SecTrustSetVerifyDate(trust, date), "set date");
62 ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust");
63 ok(trustResult == expected, "trustResult %d expected (got %d)",
64 (int)expected, (int)trustResult);
67 CFReleaseSafe(policy);
68 CFReleaseSafe(policies);
72 #import <Foundation/Foundation.h>
73 SecCertificateRef SecCertificateCreateWithPEM(CFAllocatorRef allocator, CFDataRef pem_certificate);
75 static SecCertificateRef SecCertificateCreateFromResource(NSString *name)
77 NSString *resources = @"si-88-sectrust-valid-data";
78 NSString *extension = @"pem";
80 NSURL *url = [[NSBundle mainBundle] URLForResource:name withExtension:extension subdirectory:resources];
82 printf("No URL for resource \"%s.pem\"\n", [name UTF8String]);
86 NSData *certData = [NSData dataWithContentsOfURL:url];
88 printf("No cert data for resource \"%s.pem\"\n", [name UTF8String]);
92 return SecCertificateCreateWithPEM(kCFAllocatorDefault, (__bridge CFDataRef)certData);
95 /* number of tests in date_constraints_tests function, plus calls to test_valid_trust */
96 #define DC_COUNT (12+(TVT_COUNT*6))
98 static void date_constraints_tests()
100 SecCertificateRef ca_na=NULL, ca_nb=NULL, root=NULL;
101 SecCertificateRef leaf_na_ok1=NULL, leaf_na_ok2=NULL;
102 SecCertificateRef leaf_nb_ok1=NULL, leaf_nb_ok2=NULL, leaf_nb_revoked1=NULL;
104 isnt(ca_na = SecCertificateCreateFromResource(@"ca-na"), NULL, "create ca-na cert");
105 isnt(ca_nb = SecCertificateCreateFromResource(@"ca-nb"), NULL, "create ca-nb cert");
106 isnt(root = SecCertificateCreateFromResource(@"root"), NULL, "create root cert");
107 isnt(leaf_na_ok1 = SecCertificateCreateFromResource(@"leaf-na-ok1"), NULL, "create leaf-na-ok1 cert");
108 isnt(leaf_na_ok2 = SecCertificateCreateFromResource(@"leaf-na-ok2"), NULL, "create leaf-na-ok2 cert");
109 isnt(leaf_nb_ok1 = SecCertificateCreateFromResource(@"leaf-nb-ok1"), NULL, "create leaf-nb-ok1 cert");
110 isnt(leaf_nb_ok2 = SecCertificateCreateFromResource(@"leaf-nb-ok2"), NULL, "create leaf-nb-ok2 cert");
111 isnt(leaf_nb_revoked1 = SecCertificateCreateFromResource(@"leaf-nb-revoked1"), NULL, "create leaf-nb-revoked1 cert");
113 CFMutableArrayRef anchors=NULL;
114 isnt(anchors = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create anchors array");
115 if (anchors && root) {
116 CFArrayAppendValue(anchors, root);
118 CFCalendarRef cal = NULL;
120 CFDateRef date_20180102 = NULL; // a date when our test certs would all be valid, in the absence of Valid db info
122 isnt(cal = CFCalendarCreateWithIdentifier(kCFAllocatorDefault, kCFGregorianCalendar), NULL, "create calendar");
123 ok(CFCalendarComposeAbsoluteTime(cal, &at, "yMd", 2018, 1, 2), "create verify absolute time 20180102");
124 isnt(date_20180102 = CFDateCreate(kCFAllocatorDefault, at), NULL, "create verify date 20180102");
126 /* Case 0: leaf_na_ok1 (not revoked) */
127 /* -- OK: cert issued 2017-10-20, before the CA not-after date of 2017-10-21 */
128 /* test cert has no SCT, but is expected to be OK since we now only apply the CT restriction for SSL. */
129 test_valid_trust(leaf_na_ok1, ca_na, NULL, anchors, date_20180102,
130 kBasicPolicy, kSecTrustResultUnspecified,
131 "leaf_na_ok1 basic");
133 /* Case 1: leaf_na_ok1 (not revoked) */
134 /* -- BAD: since a not-after date now requires CT (for SSL) and the test cert has no SCT, this is fatal. */
135 test_valid_trust(leaf_na_ok1, ca_na, NULL, anchors, date_20180102,
136 kSSLServerPolicy, kSecTrustResultFatalTrustFailure,
139 /* Case 2: leaf_na_ok2 (revoked) */
140 /* -- BAD: cert issued 2017-10-26, after the CA not-after date of 2017-10-21 */
141 test_valid_trust(leaf_na_ok2, ca_na, NULL, anchors, date_20180102,
142 kBasicPolicy, kSecTrustResultFatalTrustFailure,
143 "leaf_na_ok2 basic");
145 /* Case 3: leaf_nb_ok1 (revoked) */
146 /* -- BAD: cert issued 2017-10-20, before the CA not-before date of 2017-10-22 */
147 test_valid_trust(leaf_nb_ok1, ca_nb, NULL, anchors, date_20180102,
148 kBasicPolicy, kSecTrustResultFatalTrustFailure,
149 "leaf_nb_ok1 basic");
151 /* Case 4: leaf_nb_ok2 (not revoked) */
152 /* -- OK: cert issued 2017-10-26, after the CA not-before date of 2017-10-22 */
153 test_valid_trust(leaf_nb_ok2, ca_nb, NULL, anchors, date_20180102,
154 kBasicPolicy, kSecTrustResultUnspecified,
155 "leaf_nb_ok2 basic");
157 /* Case 5: leaf_nb_revoked1 (revoked) */
158 /* -- BAD: cert issued 2017-10-20, before the CA not-before date of 2017-10-22 */
159 test_valid_trust(leaf_nb_revoked1, ca_nb, NULL, anchors, date_20180102,
160 kBasicPolicy, kSecTrustResultFatalTrustFailure,
161 "leaf_nb_revoked1 basic");
163 CFReleaseSafe(ca_na);
164 CFReleaseSafe(ca_nb);
165 CFReleaseSafe(leaf_na_ok1);
166 CFReleaseSafe(leaf_na_ok2);
167 CFReleaseSafe(leaf_nb_ok1);
168 CFReleaseSafe(leaf_nb_ok2);
169 CFReleaseSafe(leaf_nb_revoked1);
171 CFReleaseSafe(anchors);
173 CFReleaseSafe(date_20180102);
176 /* number of tests in known_intermediate_tests function, plus calls to test_valid_trust */
177 #define KI_COUNT (10+(TVT_COUNT*3))
179 static void known_intermediate_tests()
181 SecCertificateRef ca_ki=NULL, root=NULL;
182 SecCertificateRef leaf_ki_ok1=NULL, leaf_ki_revoked1=NULL;
183 SecCertificateRef leaf_unknown=NULL, ca_unknown=NULL;
185 isnt(ca_ki = SecCertificateCreateFromResource(@"ca-ki"), NULL, "create ca-ki cert");
186 isnt(root = SecCertificateCreateFromResource(@"root"), NULL, "create root cert");
187 isnt(leaf_ki_ok1 = SecCertificateCreateFromResource(@"leaf-ki-ok1"), NULL, "create leaf-ki-ok1 cert");
188 isnt(leaf_ki_revoked1 = SecCertificateCreateFromResource(@"leaf-ki-revoked1"), NULL, "create leaf-ki-revoked1 cert");
189 isnt(ca_unknown = SecCertificateCreateFromResource(@"ca-unknown"), NULL, "create ca-unknown cert");
190 isnt(leaf_unknown = SecCertificateCreateFromResource(@"leaf-unknown"), NULL, "create leaf-unknown cert");
192 CFMutableArrayRef anchors=NULL;
193 isnt(anchors = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create anchors array");
194 if (anchors && root) {
195 CFArrayAppendValue(anchors, root);
197 CFCalendarRef cal = NULL;
199 CFDateRef date_20180310 = NULL; // a date when our test certs would all be valid, in the absence of Valid db info
201 isnt(cal = CFCalendarCreateWithIdentifier(kCFAllocatorDefault, kCFGregorianCalendar), NULL, "create calendar");
202 ok(CFCalendarComposeAbsoluteTime(cal, &at, "yMd", 2018, 3, 10), "create verify absolute time 20180310");
203 isnt(date_20180310 = CFDateCreate(kCFAllocatorDefault, at), NULL, "create verify date 20180310");
205 /* Case 1: leaf_ki_ok1 */
206 /* -- OK: cert issued by a known intermediate */
207 test_valid_trust(leaf_ki_ok1, ca_ki, NULL, anchors, date_20180310,
208 kBasicPolicy, kSecTrustResultUnspecified,
211 /* Case 2: leaf_ki_revoked1 */
212 /* -- BAD: CA specifies known-only+complete serial blocklist; this cert is on the blocklist. */
213 test_valid_trust(leaf_ki_revoked1, ca_ki, NULL, anchors, date_20180310,
214 kBasicPolicy, kSecTrustResultFatalTrustFailure,
217 /* Case 3: leaf_unknown */
218 /* -- BAD: ca_unknown issued from ca_ki, but is not a known intermediate.
219 * ca_ki has a path len of 0 which would normally result in kSecTrustResultRecoverableTrustFailure;
220 * however, since known-intermediates is asserted for ca_ki (non-overridable), we expect a fatal failure. */
221 test_valid_trust(leaf_unknown, ca_unknown, ca_ki, anchors, date_20180310,
222 kBasicPolicy, kSecTrustResultFatalTrustFailure,
223 "leaf_unknown test");
225 CFReleaseSafe(ca_ki);
226 CFReleaseSafe(leaf_ki_ok1);
227 CFReleaseSafe(leaf_ki_revoked1);
228 CFReleaseSafe(ca_unknown);
229 CFReleaseSafe(leaf_unknown);
231 CFReleaseSafe(anchors);
233 CFReleaseSafe(date_20180310);
237 int si_88_sectrust_valid(int argc, char *const *argv)
239 plan_tests(DC_COUNT+KI_COUNT);
241 date_constraints_tests();
242 known_intermediate_tests();