2 * Copyright (c) 2006-2017 Apple Inc. All Rights Reserved.
5 #include <AssertMacros.h>
6 #include <CoreFoundation/CoreFoundation.h>
7 #include <Security/SecCertificate.h>
8 #include <Security/SecCertificatePriv.h>
9 #include <Security/SecPolicyPriv.h>
10 #include <Security/SecTrust.h>
11 #include <utilities/array_size.h>
12 #include <utilities/SecCFRelease.h>
16 #include "shared_regressions.h"
18 #include "si-22-sectrust-iap.h"
20 static void test_v1(void)
23 SecCertificateRef iAP1CA
, iAP2CA
, leaf0
, leaf1
;
24 isnt(iAP1CA
= SecCertificateCreateWithBytes(NULL
, _iAP1CA
, sizeof(_iAP1CA
)),
25 NULL
, "create iAP1CA");
26 isnt(iAP2CA
= SecCertificateCreateWithBytes(NULL
, _iAP2CA
, sizeof(_iAP2CA
)),
27 NULL
, "create iAP2CA");
28 isnt(leaf0
= SecCertificateCreateWithBytes(NULL
, _leaf0
, sizeof(_leaf0
)),
29 NULL
, "create leaf0");
30 isnt(leaf1
= SecCertificateCreateWithBytes(NULL
, _leaf1
, sizeof(_leaf1
)),
31 NULL
, "create leaf1");
33 // temporarily grab some stack space and fill it with 0xFF;
34 // when we exit this scope, the stack pointer should shrink but leave the memory filled.
35 // this tests for a stack overflow bug inside SecPolicyCreateiAP (rdar://16056248)
37 memset(buf
, 0xFF, sizeof(buf
));
39 SecPolicyRef policy
= SecPolicyCreateiAP();
40 const void *v_anchors
[] = {
44 CFArrayRef anchors
= CFArrayCreate(NULL
, v_anchors
,
45 array_size(v_anchors
), NULL
);
46 CFArrayRef certs0
= CFArrayCreate(NULL
, (const void **)&leaf0
, 1, &kCFTypeArrayCallBacks
);
47 CFArrayRef certs1
= CFArrayCreate(NULL
, (const void **)&leaf1
, 1, &kCFTypeArrayCallBacks
);
48 ok_status(SecTrustCreateWithCertificates(certs0
, policy
, &trust
), "create trust for leaf0");
49 ok_status(SecTrustSetAnchorCertificates(trust
, anchors
), "set anchors");
52 CFDateRef date
= CFDateCreate(NULL
, 220752000.0);
53 ok_status(SecTrustSetVerifyDate(trust
, date
), "set date");
55 SecTrustResultType trustResult
;
56 ok_status(SecTrustEvaluate(trust
, &trustResult
), "evaluate trust");
57 is_status(trustResult
, kSecTrustResultUnspecified
,
58 "trust is kSecTrustResultUnspecified");
60 is(SecTrustGetCertificateCount(trust
), 2, "cert count is 2");
63 ok_status(SecTrustCreateWithCertificates(certs1
, policy
, &trust
), "create trust for leaf1");
64 ok_status(SecTrustSetAnchorCertificates(trust
, anchors
), "set anchors");
65 ok_status(SecTrustEvaluate(trust
, &trustResult
), "evaluate trust");
66 is_status(trustResult
, kSecTrustResultUnspecified
, "trust is kSecTrustResultUnspecified");
68 CFReleaseSafe(anchors
);
69 CFReleaseSafe(certs1
);
70 CFReleaseSafe(certs0
);
72 CFReleaseSafe(policy
);
75 CFReleaseSafe(iAP1CA
);
76 CFReleaseSafe(iAP2CA
);
80 static void test_v3(void) {
81 SecCertificateRef v3CA
= NULL
, v3leaf
= NULL
;
82 isnt(v3CA
= SecCertificateCreateWithBytes(NULL
, _v3ca
, sizeof(_v3ca
)),
83 NULL
, "create v3 CA");
84 isnt(v3leaf
= SecCertificateCreateWithBytes(NULL
, _v3leaf
, sizeof(_v3leaf
)),
85 NULL
, "create v3leaf");
87 /* Test v3 certs meet iAP policy */
88 SecPolicyRef policy
= NULL
;
89 SecTrustRef trust
= NULL
;
90 CFArrayRef certs
= NULL
, anchors
= NULL
;
91 CFDateRef date
= NULL
;
92 SecTrustResultType trustResult
;
94 certs
= CFArrayCreate(NULL
, (const void **)&v3leaf
, 1, &kCFTypeArrayCallBacks
);
95 anchors
= CFArrayCreate(NULL
, (const void **)&v3CA
, 1, &kCFTypeArrayCallBacks
);
96 policy
= SecPolicyCreateiAP();
97 ok_status(SecTrustCreateWithCertificates(certs
, policy
, &trust
), "create trust ref");
98 ok_status(SecTrustSetAnchorCertificates(trust
, anchors
), "set anchor");
99 ok(date
= CFDateCreate(NULL
, 484000000.0), "create date"); /* 3 May 2016 */
100 if (!date
) { goto trustFail
; }
101 ok_status(SecTrustSetVerifyDate(trust
, date
), "set verify date");
102 ok_status(SecTrustEvaluate(trust
, &trustResult
), "evaluate");
103 is_status(trustResult
, kSecTrustResultUnspecified
, "trust is kSecTrustResultUnspecified");
105 /* Test v3 certs fail iAP SW Auth policy */
106 CFReleaseNull(policy
);
107 CFReleaseNull(trust
);
108 policy
= SecPolicyCreateiAPSWAuth();
109 require_noerr(SecTrustCreateWithCertificates(certs
, policy
, &trust
), trustFail
);
110 require_noerr(SecTrustSetAnchorCertificates(trust
, anchors
), trustFail
);
111 require_noerr(SecTrustSetVerifyDate(trust
, date
), trustFail
);
112 require_noerr(SecTrustEvaluate(trust
, &trustResult
), trustFail
);
113 is_status(trustResult
, kSecTrustResultRecoverableTrustFailure
, "trust is kSecTrustResultRecoverableTrustFailure");
116 CFReleaseSafe(policy
);
117 CFReleaseSafe(trust
);
118 CFReleaseSafe(certs
);
119 CFReleaseSafe(anchors
);
122 /* Test interface for determining iAuth version */
123 SecCertificateRef leaf0
= NULL
, leaf1
= NULL
;
124 isnt(leaf0
= SecCertificateCreateWithBytes(NULL
, _leaf0
, sizeof(_leaf0
)),
125 NULL
, "create leaf0");
126 isnt(leaf1
= SecCertificateCreateWithBytes(NULL
, _leaf1
, sizeof(_leaf1
)),
127 NULL
, "create leaf1");
129 is_status(SecCertificateGetiAuthVersion(leaf0
), kSeciAuthVersion2
, "v2 certificate");
130 is_status(SecCertificateGetiAuthVersion(leaf1
), kSeciAuthVersion2
, "v2 certificate");
131 is_status(SecCertificateGetiAuthVersion(v3leaf
), kSeciAuthVersion3
, "v3 certificate");
133 CFReleaseSafe(leaf0
);
134 CFReleaseSafe(leaf1
);
136 /* Test the extension-copying interface */
137 CFDataRef extensionData
= NULL
;
138 uint8_t extensionValue
[32] = {
139 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
140 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0A,
142 ok(extensionData
= SecCertificateCopyiAPAuthCapabilities(v3leaf
),
143 "copy iAuthv3 extension data");
144 is(CFDataGetLength(extensionData
), 32, "compare expected size");
145 is(memcmp(extensionValue
, CFDataGetBytePtr(extensionData
), 32), 0,
146 "compare expected output");
147 CFReleaseNull(extensionData
);
149 /* Test extension-copying interface with a malformed extension. */
150 uint8_t extensionValue2
[32] = {
151 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
152 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,
154 SecCertificateRef malformedV3leaf
= NULL
;
155 isnt(malformedV3leaf
= SecCertificateCreateWithBytes(NULL
, _malformedV3Leaf
, sizeof(_malformedV3Leaf
)),
156 NULL
, "create malformed v3 leaf");
157 ok(extensionData
= SecCertificateCopyiAPAuthCapabilities(malformedV3leaf
),
158 "copy iAuthv3 extension data for malformed leaf");
159 is(CFDataGetLength(extensionData
), 32, "compare expected size");
160 is(memcmp(extensionValue2
, CFDataGetBytePtr(extensionData
), 32), 0,
161 "compare expected output");
162 CFReleaseNull(extensionData
);
163 CFReleaseNull(malformedV3leaf
);
164 CFReleaseSafe(v3leaf
);
168 static void test_sw_auth_trust(void) {
169 SecCertificateRef sw_auth_test_CA
= NULL
, sw_auth_test_leaf
= NULL
;
170 isnt(sw_auth_test_CA
= SecCertificateCreateWithBytes(NULL
, _iAPSWAuthTestRoot
, sizeof(_iAPSWAuthTestRoot
)),
171 NULL
, "create sw auth test ca");
172 isnt(sw_auth_test_leaf
= SecCertificateCreateWithBytes(NULL
, _iAPSWAuth_leaf
, sizeof(_iAPSWAuth_leaf
)),
173 NULL
, "create sw auth leaf");
175 /* Test SW Auth certs meet iAP SW Auth policy */
176 SecPolicyRef policy
= NULL
;
177 SecTrustRef trust
= NULL
;
178 CFArrayRef certs
= NULL
, anchors
= NULL
;
179 CFDateRef date
= NULL
;
180 SecTrustResultType trustResult
;
182 certs
= CFArrayCreate(NULL
, (const void **)&sw_auth_test_leaf
, 1, &kCFTypeArrayCallBacks
);
183 anchors
= CFArrayCreate(NULL
, (const void **)&sw_auth_test_CA
, 1, &kCFTypeArrayCallBacks
);
184 policy
= SecPolicyCreateiAPSWAuth();
185 require_noerr(SecTrustCreateWithCertificates(certs
, policy
, &trust
), trustFail
);
186 require_noerr(SecTrustSetAnchorCertificates(trust
, anchors
), trustFail
);
187 require(date
= CFDateCreate(NULL
, 530000000.0), trustFail
); /* 17 Oct 2017, BEFORE issuance */
188 require_noerr(SecTrustSetVerifyDate(trust
, date
), trustFail
);
189 require_noerr(SecTrustEvaluate(trust
, &trustResult
), trustFail
);
190 is_status(trustResult
, kSecTrustResultUnspecified
, "trust is kSecTrustResultUnspecified");
192 /* Test SW Auth certs fail iAP policy */
193 CFReleaseNull(policy
);
194 CFReleaseNull(trust
);
195 policy
= SecPolicyCreateiAP();
196 require_noerr(SecTrustCreateWithCertificates(certs
, policy
, &trust
), trustFail
);
197 require_noerr(SecTrustSetAnchorCertificates(trust
, anchors
), trustFail
);
198 require_noerr(SecTrustSetVerifyDate(trust
, date
), trustFail
);
199 require_noerr(SecTrustEvaluate(trust
, &trustResult
), trustFail
);
200 is_status(trustResult
, kSecTrustResultRecoverableTrustFailure
, "trust is kSecTrustResultRecoverableTrustFailure");
202 /* Test SW Auth certs fail when not-yet-valid with expiration check */
203 CFReleaseNull(policy
);
204 CFReleaseNull(trust
);
205 policy
= SecPolicyCreateiAPSWAuthWithExpiration(true);
206 require_noerr(SecTrustCreateWithCertificates(certs
, policy
, &trust
), trustFail
);
207 require_noerr(SecTrustSetAnchorCertificates(trust
, anchors
), trustFail
);
208 require_noerr(SecTrustSetVerifyDate(trust
, date
), trustFail
);
209 require_noerr(SecTrustEvaluate(trust
, &trustResult
), trustFail
);
210 is_status(trustResult
, kSecTrustResultRecoverableTrustFailure
, "trust is kSecTrustResultRecoverableTrustFailure");
213 CFReleaseSafe(policy
);
214 CFReleaseSafe(trust
);
215 CFReleaseSafe(certs
);
216 CFReleaseSafe(anchors
);
218 CFReleaseSafe(sw_auth_test_CA
);
219 CFReleaseSafe(sw_auth_test_leaf
);
222 static void test_sw_auth_cert(void) {
223 SecCertificateRef good_leaf
= NULL
, bad_leaf
= NULL
;
224 isnt(good_leaf
= SecCertificateCreateWithBytes(NULL
, _iAPSWAuth_leaf
, sizeof(_iAPSWAuth_leaf
)),
225 NULL
, "create good iAP SW Auth cert");
226 isnt(bad_leaf
= SecCertificateCreateWithBytes(NULL
, _malformed_iAPSWAuth_leaf
, sizeof(_malformed_iAPSWAuth_leaf
)),
227 NULL
, "create bad iAP SW Auth cert");
229 /* Test Auth version interface */
230 ok(SecCertificateGetiAuthVersion(good_leaf
) == kSeciAuthVersionSW
, "Get version of well-formed SW Auth cert");
231 ok(SecCertificateGetiAuthVersion(bad_leaf
) == kSeciAuthVersionSW
, "Get version of malformed SW Auth cert");
233 /* Test extension copying with malformed extensions */
234 is(SecCertificateCopyiAPSWAuthCapabilities(bad_leaf
, kSeciAPSWAuthGeneralCapabilities
), NULL
,
235 "Fail to get capabilities of malformed SW auth cert");
236 is(SecCertificateCopyiAPSWAuthCapabilities(bad_leaf
, kSeciAPSWAuthAirPlayCapabilities
), NULL
,
237 "Fail to get AirPlay capabilities of malformed SW auth cert");
238 is(SecCertificateCopyiAPSWAuthCapabilities(bad_leaf
, kSeciAPSWAuthHomeKitCapabilities
), NULL
,
239 "Fail to get HomeKit capabilities of malformed SW auth cert");
241 uint8_t byte0
= 0x00;
242 uint8_t byte1
= 0x01;
243 CFDataRef data0
= CFDataCreate(NULL
, &byte0
, 1);
244 CFDataRef data1
= CFDataCreate(NULL
, &byte1
, 1);
246 /* Test extension copying with well-formed extensions */
247 CFDataRef extensionValue
= NULL
;
248 isnt(extensionValue
= SecCertificateCopyiAPSWAuthCapabilities(good_leaf
, kSeciAPSWAuthGeneralCapabilities
), NULL
,
249 "Get capabilities of well-formed SW auth cert");
250 ok(CFEqual(extensionValue
, data1
), "Got correct general extension value");
251 CFReleaseNull(extensionValue
);
253 isnt(extensionValue
= SecCertificateCopyiAPSWAuthCapabilities(good_leaf
, kSeciAPSWAuthAirPlayCapabilities
), NULL
,
254 "Get AirPlay capabilities of well-formed SW auth cert");
255 ok(CFEqual(extensionValue
, data0
), "Got correct AirPlay extension value");
256 CFReleaseNull(extensionValue
);
258 isnt(extensionValue
= SecCertificateCopyiAPSWAuthCapabilities(good_leaf
, kSeciAPSWAuthHomeKitCapabilities
), NULL
,
259 "Get capabilities of well-formed SW auth cert");
260 ok(CFEqual(extensionValue
, data1
), "Got correct HomeKit extension value");
261 CFReleaseNull(extensionValue
);
263 CFReleaseNull(good_leaf
);
264 CFReleaseNull(bad_leaf
);
265 CFReleaseNull(data0
);
266 CFReleaseNull(data1
);
269 static void test_component_type_cert(void) {
270 SecCertificateRef batteryCA
= NULL
, nonComponent
= NULL
;
271 isnt(batteryCA
= SecCertificateCreateWithBytes(NULL
, _componentCABattery
, sizeof(_componentCABattery
)),
272 NULL
, "create battery component CA cert");
273 isnt(nonComponent
= SecCertificateCreateWithBytes(NULL
, _iAP2CA
, sizeof(_iAP2CA
)),
274 NULL
, "create non-component cert");
276 CFStringRef componentType
= NULL
;
277 isnt(componentType
= SecCertificateCopyComponentType(batteryCA
), NULL
, "Get component type");
278 ok(CFEqual(componentType
, CFSTR("Battery")), "Got correct component type");
279 CFReleaseNull(componentType
);
281 is(componentType
= SecCertificateCopyComponentType(nonComponent
), NULL
, "Get component type");
283 CFReleaseNull(batteryCA
);
284 CFReleaseNull(nonComponent
);
287 static void test_component_type_trust(void) {
288 SecCertificateRef leaf
= NULL
, subCA
= NULL
, root
= NULL
;
289 SecPolicyRef policy
= NULL
;
290 SecTrustRef trust
= NULL
;
291 CFMutableArrayRef certs
= NULL
;
292 CFArrayRef anchors
= NULL
;
293 CFDateRef date
= NULL
;
294 SecTrustResultType trustResult
;
296 isnt(leaf
= SecCertificateCreateWithBytes(NULL
, _batteryLeaf
, sizeof(_batteryLeaf
)),
297 NULL
, "create battery leaf");
298 isnt(subCA
= SecCertificateCreateWithBytes(NULL
, _componentCABattery
, sizeof(_componentCABattery
)),
299 NULL
, "create battery subCA");
300 isnt(root
= SecCertificateCreateWithBytes(NULL
, _componentRoot
, sizeof(_componentRoot
)),
301 NULL
, "create component root");
303 /* Test Battery component certs meet component policy */
304 certs
= CFArrayCreateMutable(NULL
, 2, &kCFTypeArrayCallBacks
);
305 CFArrayAppendValue(certs
, leaf
);
306 CFArrayAppendValue(certs
, subCA
);
307 anchors
= CFArrayCreate(NULL
, (const void **)&root
, 1, &kCFTypeArrayCallBacks
);
308 policy
= SecPolicyCreateAppleComponentCertificate(NULL
);
309 require_noerr(SecTrustCreateWithCertificates(certs
, policy
, &trust
), trustFail
);
310 require_noerr(SecTrustSetAnchorCertificates(trust
, anchors
), trustFail
);
311 require(date
= CFDateCreate(NULL
, 576000000.0), trustFail
); /* April 3, 2019 at 9:00:00 AM PDT */
312 require_noerr(SecTrustSetVerifyDate(trust
, date
), trustFail
);
313 require_noerr(SecTrustEvaluate(trust
, &trustResult
), trustFail
);
314 is_status(trustResult
, kSecTrustResultUnspecified
, "trust is kSecTrustResultUnspecified");
318 CFReleaseNull(subCA
);
321 CFReleaseNull(policy
);
322 CFReleaseNull(trust
);
326 int si_22_sectrust_iap(int argc
, char *const *argv
)
328 plan_tests(14+21+5+13+5+4);
332 test_sw_auth_trust();
334 test_component_type_cert();
335 test_component_type_trust();