]> git.saurik.com Git - apple/security.git/blob - OSX/sec/Security/Regressions/secitem/si-28-sectrustsettings.m
Security-57740.1.18.tar.gz
[apple/security.git] / OSX / sec / Security / Regressions / secitem / si-28-sectrustsettings.m
1 /*
2 * Copyright (c) 2008-2010,2012,2016 Apple Inc. All Rights Reserved.
3 */
4
5 #include <Foundation/Foundation.h>
6 #include <Security/SecCertificate.h>
7 #include <Security/SecCertificatePriv.h>
8 #include <Security/SecItem.h>
9 #include <Security/SecItemPriv.h>
10 #include <Security/SecPolicy.h>
11 #include <Security/SecPolicyPriv.h>
12 #include <Security/SecTrust.h>
13 #include <Security/SecTrustSettings.h>
14 #include <Security/SecTrustSettingsPriv.h>
15 #include <utilities/SecCFRelease.h>
16 #include <stdlib.h>
17 #include <unistd.h>
18
19 #if TARGET_OS_IPHONE
20 #include <Security/SecTrustStore.h>
21 #else
22 #include <Security/SecKeychain.h>
23 #endif
24
25 #include "shared_regressions.h"
26
27 #include "si-28-sectrustsettings.h"
28
29 /* Of course, the interface is different for OS X and iOS. */
30 /* each call is 1 test */
31 #if TARGET_OS_IPHONE
32 #define setTS(cert, settings) \
33 { \
34 ok_status(SecTrustStoreSetTrustSettings(defaultStore, cert, settings), \
35 "set trust settings"); \
36 }
37 #else
38 /* Use admin store on OS X to avoid user prompts.
39 * Sleep a little so trustd has time to get the KeychainEvent. */
40 #define setTS(cert, settings) \
41 { \
42 ok_status(SecTrustSettingsSetTrustSettings(cert, kSecTrustSettingsDomainAdmin, \
43 settings), "set trust settings"); \
44 usleep(20000); \
45 }
46 #endif
47
48 #if TARGET_OS_IPHONE
49 #define setTSFail(cert, settings) \
50 { \
51 is(SecTrustStoreSetTrustSettings(defaultStore, cert, settings), errSecParam, \
52 "set trust settings"); \
53 }
54 #else
55 #define setTSFail(cert, settings) \
56 { \
57 is(SecTrustSettingsSetTrustSettings(cert, kSecTrustSettingsDomainAdmin, \
58 settings), errSecParam, "set trust settings"); \
59 }
60 #endif
61
62 /* each call is 1 test */
63 #if TARGET_OS_IPHONE
64 #define removeTS(cert) \
65 { \
66 ok_status(SecTrustStoreRemoveCertificate(defaultStore, cert), \
67 "remove trust settings"); \
68 }
69 #else
70 #define removeTS(cert) \
71 { \
72 ok_status(SecTrustSettingsRemoveTrustSettings(cert, kSecTrustSettingsDomainAdmin), \
73 "remove trust settings"); \
74 }
75 #endif
76
77 /* each call is 4 tests */
78 #define check_trust(certs, policy, valid_date, expected) \
79 { \
80 SecTrustRef trust = NULL; \
81 SecTrustResultType trust_result; \
82 ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), \
83 "create trust with " #policy " policy"); \
84 ok_status(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)valid_date), \
85 "set trust verify date"); \
86 ok_status(SecTrustEvaluate(trust, &trust_result), "evaluate trust"); \
87 is(trust_result, expected, \
88 "check trust result for " #policy " policy"); \
89 CFReleaseSafe(trust); \
90 }
91
92 static SecCertificateRef cert0 = NULL;
93 static SecCertificateRef cert1 = NULL;
94 static SecCertificateRef cert2 = NULL;
95 static SecCertificateRef cert3 = NULL;
96 static SecPolicyRef sslPolicy = NULL;
97 static SecPolicyRef smimePolicy = NULL;
98 static SecPolicyRef basicPolicy = NULL;
99 static CFArrayRef sslChain = NULL;
100 static CFArrayRef smimeChain = NULL;
101 static NSDate *verify_date = nil;
102
103 #if TARGET_OS_IPHONE
104 static SecTrustStoreRef defaultStore = NULL;
105 #else
106 #define kSystemLoginKeychainPath "/Library/Keychains/System.keychain"
107 static NSMutableArray *deleteMeCertificates = NULL;
108 #endif
109
110
111 static void setup_globals(void) {
112
113 cert0 = SecCertificateCreateWithBytes(NULL, _trustSettingsRoot, sizeof(_trustSettingsRoot));
114 cert1 = SecCertificateCreateWithBytes(NULL, _trustSettingsInt, sizeof(_trustSettingsInt));
115 cert2 = SecCertificateCreateWithBytes(NULL, _trustSettingsSSLLeaf, sizeof(_trustSettingsSSLLeaf));
116 cert3 = SecCertificateCreateWithBytes(NULL, _trustSettingsSMIMELeaf, sizeof(_trustSettingsSMIMELeaf));
117
118 sslPolicy = SecPolicyCreateSSL(true, CFSTR("testserver.apple.com"));
119 smimePolicy = SecPolicyCreateSMIME(kSecAnyEncryptSMIME, CFSTR("username@apple.com"));
120 basicPolicy = SecPolicyCreateBasicX509();
121
122 const void *v_certs1[] = { cert2, cert1, cert0 };
123 sslChain = CFArrayCreate(NULL, v_certs1, sizeof(v_certs1)/sizeof(*v_certs1), &kCFTypeArrayCallBacks);
124
125 const void *v_certs2[] = { cert3, cert1, cert0 };
126 smimeChain = CFArrayCreate(NULL, v_certs2, sizeof(v_certs2)/sizeof(*v_certs2), &kCFTypeArrayCallBacks);
127
128 verify_date = [NSDate dateWithTimeIntervalSinceReferenceDate:482000000.0]; // Apr 10 2016
129
130 #if TARGET_OS_IPHONE
131 defaultStore = SecTrustStoreForDomain(kSecTrustStoreDomainUser);
132 #else
133 /* Since we're putting trust settings in the admin domain,
134 * we need to add the certs to the system keychain. */
135 SecKeychainRef kcRef = NULL;
136 CFArrayRef certRef = NULL;
137 NSDictionary *attrs = nil;
138
139 SecKeychainOpen(kSystemLoginKeychainPath, &kcRef);
140 if (!kcRef) {
141 goto out;
142 }
143
144 deleteMeCertificates = [[NSMutableArray alloc] init];
145
146 attrs = @{(__bridge NSString*)kSecValueRef: (__bridge id)cert0,
147 (__bridge NSString*)kSecUseKeychain: (__bridge id)kcRef,
148 (__bridge NSString*)kSecReturnPersistentRef: @YES};
149 if (SecItemAdd((CFDictionaryRef)attrs, (void *)&certRef) == 0)
150 [deleteMeCertificates addObject:(__bridge NSArray *)certRef];
151 CFReleaseNull(certRef);
152
153 attrs = @{(__bridge NSString*)kSecValueRef: (__bridge id)cert1,
154 (__bridge NSString*)kSecUseKeychain: (__bridge id)kcRef,
155 (__bridge NSString*)kSecReturnPersistentRef: @YES};
156 if (SecItemAdd((CFDictionaryRef)attrs, (void *)&certRef) == 0)
157 [deleteMeCertificates addObject:(__bridge NSArray *)certRef];
158 CFReleaseNull(certRef);
159
160 attrs = @{(__bridge NSString*)kSecValueRef: (__bridge id)cert2,
161 (__bridge NSString*)kSecUseKeychain: (__bridge id)kcRef,
162 (__bridge NSString*)kSecReturnPersistentRef: @YES};
163 if (SecItemAdd((CFDictionaryRef)attrs, (void *)&certRef) == 0)
164 [deleteMeCertificates addObject:(__bridge NSArray *)certRef];
165 CFReleaseNull(certRef);
166
167 attrs = @{(__bridge NSString*)kSecValueRef: (__bridge id)cert3,
168 (__bridge NSString*)kSecUseKeychain: (__bridge id)kcRef,
169 (__bridge NSString*)kSecReturnPersistentRef: @YES};
170 if (SecItemAdd((CFDictionaryRef)attrs, (void *)&certRef) == 0)
171 [deleteMeCertificates addObject:(__bridge NSArray *)certRef];
172 CFReleaseNull(certRef);
173
174 out:
175 CFReleaseNull(kcRef);
176 #endif
177 }
178
179 static void cleanup_globals(void) {
180 #if !TARGET_OS_IPHONE
181 [deleteMeCertificates enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
182 SecItemDelete((CFDictionaryRef)@{ (__bridge NSString*)kSecValuePersistentRef: [obj objectAtIndex:0]});
183 }];
184 #endif
185
186 CFReleaseNull(cert0);
187 CFReleaseNull(cert1);
188 CFReleaseNull(cert2);
189 CFReleaseNull(cert3);
190 CFReleaseNull(sslPolicy);
191 CFReleaseNull(smimePolicy);
192 CFReleaseNull(basicPolicy);
193 CFReleaseNull(sslChain);
194 CFReleaseNull(smimeChain);
195 }
196
197 #define kNumberNoConstraintsTests (17+7*4)
198 static void test_no_constraints(void) {
199 /* root with the default TrustRoot result succeeds */
200 setTS(cert0, NULL);
201 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultUnspecified);
202 removeTS(cert0);
203
204 /* intermediate with the default TrustRoot result fails */
205 setTSFail(cert1, NULL);
206
207 /* root with TrustRoot result succeeds */
208 NSDictionary *trustRoot = @{ (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustRoot)};
209 setTS(cert0, (__bridge CFDictionaryRef)trustRoot);
210 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultUnspecified);
211 removeTS(cert0);
212
213 /* intermediate with TrustRoot fails to set */
214 setTSFail(cert1, (__bridge CFDictionaryRef)trustRoot);
215
216 /* root with TrustAsRoot fails to set */
217 NSDictionary *trustAsRoot = @{ (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustAsRoot)};
218 setTSFail(cert0, (__bridge CFDictionaryRef)trustAsRoot);
219
220 /* intermediate with TrustAsRoot result succeeds */
221 setTS(cert1, (__bridge CFDictionaryRef)trustAsRoot);
222 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultUnspecified);
223 removeTS(cert1);
224
225 /* trusting the root but denying the intermediate fails */
226 NSDictionary *deny = @{ (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultDeny)};
227 setTS(cert0, NULL);
228 setTS(cert1, (__bridge CFDictionaryRef)deny);
229 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultDeny);
230 removeTS(cert1);
231 removeTS(cert0);
232
233 /* the unspecified result gives us default behavior */
234 NSDictionary *unspecified = @{ (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultUnspecified)};
235 setTS(cert1, (__bridge CFDictionaryRef)unspecified);
236 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultRecoverableTrustFailure);
237 removeTS(cert1);
238
239 /* trusting one leaf doesn't make other leaf trusted */
240 setTS(cert2, (__bridge CFDictionaryRef)trustAsRoot);
241 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultUnspecified);
242 check_trust(smimeChain, basicPolicy, verify_date, kSecTrustResultRecoverableTrustFailure);
243 removeTS(cert2);
244 }
245
246 #define kNumberPolicyConstraintsTests (2+3*4)
247 static void test_policy_constraints(void) {
248 /* Trust only for SSL server. SSL server policy succeeds. */
249 NSDictionary *sslServerAllowed = @{ (__bridge NSString*)kSecTrustSettingsPolicy: (__bridge id)sslPolicy,
250 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustAsRoot) };
251 setTS(cert1, (__bridge CFDictionaryRef)sslServerAllowed);
252 check_trust(sslChain, sslPolicy, verify_date, kSecTrustResultUnspecified);
253
254 /* SSL client policy fails. */
255 SecPolicyRef sslClient = SecPolicyCreateSSL(false, NULL);
256 check_trust(sslChain, sslClient, verify_date, kSecTrustResultRecoverableTrustFailure);
257 CFReleaseNull(sslClient);
258
259 /* Basic policy fails */
260 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultRecoverableTrustFailure);
261 removeTS(cert1);
262 }
263
264 #define kNumberPolicyStringConstraintsTests (4+6*4)
265 static void test_policy_string_constraints(void) {
266 NSArray *hostnameAllowed = @[ @{ (__bridge NSString*)kSecTrustSettingsPolicy: (__bridge id)sslPolicy,
267 (__bridge NSString*)kSecTrustSettingsPolicyString: @("wrongname.apple.com"),
268 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultDeny) },
269 @{ (__bridge NSString*)kSecTrustSettingsPolicy: (__bridge id)sslPolicy,
270 (__bridge NSString*)kSecTrustSettingsPolicyString: @("testserver.apple.com"),
271 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustAsRoot) }
272 ];
273 setTS(cert2, (__bridge CFArrayRef)hostnameAllowed);
274 /* evaluating against trusted hostname passes */
275 check_trust(sslChain, sslPolicy, verify_date, kSecTrustResultUnspecified);
276
277 /* evaluating against hostname not in trust settings is recoverable failure */
278 SecPolicyRef weirdnamePolicy = SecPolicyCreateSSL(true, CFSTR("weirdname.apple.com"));
279 check_trust(sslChain, weirdnamePolicy, verify_date, kSecTrustResultRecoverableTrustFailure);
280 CFReleaseNull(weirdnamePolicy);
281
282 /* evaluating against hostname denied by trust settings is denied */
283 SecPolicyRef wrongnamePolicy = SecPolicyCreateSSL(true, CFSTR("wrongname.apple.com"));
284 check_trust(sslChain, wrongnamePolicy, verify_date, kSecTrustResultDeny);
285 CFReleaseNull(wrongnamePolicy);
286 removeTS(cert2);
287
288 NSArray *emailAllowed = @[ @{ (__bridge NSString*)kSecTrustSettingsPolicy: (__bridge id)smimePolicy,
289 (__bridge NSString*)kSecTrustSettingsPolicyString: @("wrongemail@apple.com"),
290 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultDeny) },
291 @{ (__bridge NSString*)kSecTrustSettingsPolicy: (__bridge id)smimePolicy,
292 (__bridge NSString*)kSecTrustSettingsPolicyString: @("username@apple.com"),
293 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustAsRoot) }
294 ];
295 setTS(cert3, (__bridge CFArrayRef)emailAllowed);
296 /* evaluating against trusted email passes */
297 check_trust(smimeChain, smimePolicy, verify_date, kSecTrustResultUnspecified);
298
299 /* evaluating against hostname not in trust settings is recoverable failure */
300 SecPolicyRef weirdemailPolicy = SecPolicyCreateSMIME(kSecAnyEncryptSMIME, CFSTR("weirdemail@apple.com"));
301 check_trust(smimeChain, weirdemailPolicy, verify_date, kSecTrustResultRecoverableTrustFailure);
302 CFReleaseNull(weirdemailPolicy);
303
304 /* evaluating against hostname denied by trust settings is denied */
305 SecPolicyRef wrongemailPolicy = SecPolicyCreateSMIME(kSecAnyEncryptSMIME, CFSTR("wrongemail@apple.com"));
306 check_trust(smimeChain, wrongemailPolicy, verify_date, kSecTrustResultDeny);
307 CFReleaseNull(wrongemailPolicy);
308 removeTS(cert3);
309 }
310
311 #if TARGET_OS_IPHONE
312 #define kNumberApplicationsConstraintsTests 0
313 static void test_application_constraints(void) {}
314 #else
315 #include <Security/SecTrustedApplicationPriv.h>
316 #define kNumberApplicationsConstraintsTests (2+4+2*4)
317 static void test_application_constraints(void) {
318 SecTrustedApplicationRef thisApp = NULL, someOtherApp = NULL;
319
320 ok_status(SecTrustedApplicationCreateFromPath(NULL, &thisApp),
321 "create TrustedApplicationRef for this app");
322 ok_status(SecTrustedApplicationCreateFromPath("/Applications/Safari.app", &someOtherApp),
323 "create TrustedApplicationRef for Safari");
324
325 NSDictionary *thisAppTS = @{ (__bridge NSString*)kSecTrustSettingsApplication: (__bridge id)thisApp,
326 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustRoot)};
327
328 NSDictionary *someOtherAppTS = @{ (__bridge NSString*)kSecTrustSettingsApplication: (__bridge id)someOtherApp,
329 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustRoot)};
330
331 /* This application Trust Setting succeeds */
332 setTS(cert0, (__bridge CFDictionaryRef)thisAppTS);
333 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultUnspecified);
334 removeTS(cert0);
335
336 /* Some other application Trust Setting fails */
337 setTS(cert0, (__bridge CFDictionaryRef)someOtherAppTS);
338 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultRecoverableTrustFailure);
339 removeTS(cert0);
340
341 CFReleaseNull(thisApp);
342 CFReleaseNull(someOtherApp);
343 }
344 #endif
345
346 #define kNumberKeyUsageConstraintsTests (14+11*4)
347 static void test_key_usage_constraints(void) {
348 /* any key usage succeeds */
349 NSDictionary *anyKeyUse = @{ (__bridge NSString*)kSecTrustSettingsKeyUsage: @(kSecTrustSettingsKeyUseAny),
350 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustRoot)};
351 setTS(cert0, (__bridge CFDictionaryRef)anyKeyUse);
352 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultUnspecified);
353 removeTS(cert0);
354
355 /* signCert key usage on an intermediate or root succeeds */
356 NSDictionary *signCertUseRoot = @{ (__bridge NSString*)kSecTrustSettingsKeyUsage: @(kSecTrustSettingsKeyUseSignCert),
357 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustRoot)};
358 setTS(cert0, (__bridge CFDictionaryRef)signCertUseRoot);
359 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultUnspecified);
360 removeTS(cert0)
361
362 NSDictionary *signCertUseInt = @{ (__bridge NSString*)kSecTrustSettingsKeyUsage: @(kSecTrustSettingsKeyUseSignCert),
363 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustAsRoot)};
364 setTS(cert1, (__bridge CFDictionaryRef)signCertUseInt);
365 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultUnspecified);
366 removeTS(cert1);
367
368 /* intermediate without signCert key usage fails */
369 NSDictionary *signatureUse = @{ (__bridge NSString*)kSecTrustSettingsKeyUsage: @(kSecTrustSettingsKeyUseSignature),
370 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustAsRoot)};
371 setTS(cert1, (__bridge CFDictionaryRef)signatureUse);
372 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultRecoverableTrustFailure);
373 removeTS(cert1);
374
375 /* brief interlude to create a bunch of SMIME policies with different key usages */
376 SecPolicyRef smimeSignature = SecPolicyCreateSMIME(kSecSignSMIMEUsage, CFSTR("username@apple.com"));
377 SecPolicyRef smimeDataEncrypt = SecPolicyCreateSMIME(kSecDataEncryptSMIMEUsage, CFSTR("username@apple.com"));
378 SecPolicyRef smimeKeyEncrypt = SecPolicyCreateSMIME(kSecKeyEncryptSMIMEUsage, CFSTR("username@apple.com"));
379 SecPolicyRef smimeKeyExchange = SecPolicyCreateSMIME(kSecKeyExchangeBothSMIMEUsage, CFSTR("username@apple.com"));
380 SecPolicyRef smimeMultiple = SecPolicyCreateSMIME((kSecSignSMIMEUsage | kSecKeyEncryptSMIMEUsage),
381 CFSTR("username@apple.com"));
382
383 /* signature smime policy passes for signature use TS*/
384 setTS(cert3, (__bridge CFDictionaryRef)signatureUse);
385 check_trust(smimeChain, smimeSignature, verify_date, kSecTrustResultUnspecified);
386
387 /* any use policy fails for signature use TS */
388 check_trust(smimeChain, smimePolicy, verify_date, kSecTrustResultRecoverableTrustFailure);
389
390 /* multiple use smime policy against signature use */
391 check_trust(smimeChain, smimeMultiple, verify_date, kSecTrustResultRecoverableTrustFailure);
392 removeTS(cert3);
393
394 /* key encrypt smime policy passes for key encrypt use */
395 NSDictionary *keyEncryptUse = @{ (__bridge NSString*)kSecTrustSettingsKeyUsage: @(kSecTrustSettingsKeyUseEnDecryptKey),
396 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustAsRoot)};
397 setTS(cert3, (__bridge CFDictionaryRef)keyEncryptUse);
398 check_trust(smimeChain, smimeKeyEncrypt, verify_date, kSecTrustResultUnspecified);
399 removeTS(cert3);
400
401 /* multiple use smime policy against multiple uses */
402 NSDictionary *multipleUse = @{ (__bridge NSString*)kSecTrustSettingsKeyUsage: @(kSecTrustSettingsKeyUseEnDecryptKey |
403 kSecTrustSettingsKeyUseSignature),
404 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustAsRoot)};
405 setTS(cert3, (__bridge CFDictionaryRef)multipleUse)
406 check_trust(smimeChain, smimeMultiple, verify_date, kSecTrustResultUnspecified);
407
408 /* signature smime policy against multiple uses */
409 check_trust(smimeChain, smimeSignature, verify_date, kSecTrustResultRecoverableTrustFailure);
410
411 /* any use smime policy against multiple uses */
412 check_trust(smimeChain, smimePolicy, verify_date, kSecTrustResultRecoverableTrustFailure);
413 removeTS(cert3);
414
415 CFReleaseNull(smimeSignature);
416 CFReleaseNull(smimeDataEncrypt);
417 CFReleaseNull(smimeKeyEncrypt);
418 CFReleaseNull(smimeKeyExchange);
419 CFReleaseNull(smimeMultiple);
420 }
421
422 #define kNumberAllowedErrorsTests (14+8*4)
423 static void test_allowed_errors(void) {
424 setTS(cert0, NULL);
425
426 /* allow expired errors */
427 NSDate *expired_date = [NSDate dateWithTimeIntervalSinceReferenceDate:520000000.0]; // Jun 24 2017
428 check_trust(sslChain, basicPolicy, expired_date, kSecTrustResultRecoverableTrustFailure);
429
430 NSDictionary *allowExpired = @{ (__bridge NSString*)kSecTrustSettingsAllowedError: @(-2147409654),
431 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultUnspecified)};
432 setTS(cert1, (__bridge CFDictionaryRef)allowExpired)
433 setTS(cert2, (__bridge CFDictionaryRef)allowExpired);
434 check_trust(sslChain, basicPolicy, expired_date, kSecTrustResultUnspecified);
435 removeTS(cert2);
436 removeTS(cert1);
437
438 /* allow hostname mismatch errors */
439 SecPolicyRef wrongNameSSL = NULL;
440 wrongNameSSL = SecPolicyCreateSSL(true, CFSTR("wrongname.apple.com"));
441 check_trust(sslChain, wrongNameSSL, verify_date, kSecTrustResultRecoverableTrustFailure);
442
443 NSDictionary *allowHostnameMismatch = @{ (__bridge NSString*)kSecTrustSettingsAllowedError: @(-2147408896),
444 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultUnspecified) };
445 setTS(cert2, (__bridge CFDictionaryRef)allowHostnameMismatch);
446 sleep(1); // sleep a little extra so trustd gets trust settings event before evaluating leaf
447 check_trust(sslChain, wrongNameSSL, verify_date, kSecTrustResultUnspecified);
448 removeTS(cert2);
449 CFReleaseNull(wrongNameSSL);
450
451 /* allow email mismatch errors */
452 SecPolicyRef wrongNameSMIME = NULL;
453 wrongNameSMIME = SecPolicyCreateSMIME(kSecAnyEncryptSMIME, CFSTR("test@apple.com"));
454 check_trust(smimeChain, wrongNameSMIME, verify_date, kSecTrustResultRecoverableTrustFailure);
455
456 NSDictionary *allowEmailMismatch = @{ (__bridge NSString*)kSecTrustSettingsAllowedError: @(-2147408872),
457 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultUnspecified) };
458 setTS(cert3, (__bridge CFDictionaryRef)allowEmailMismatch);
459 sleep(1); // sleep a little extra so trustd gets trust settings event before evaluating leaf
460 check_trust(smimeChain, wrongNameSMIME, verify_date, kSecTrustResultUnspecified);
461 removeTS(cert3);
462 CFReleaseNull(wrongNameSMIME);
463
464 /* allowed error with a policy constraint */
465 NSDictionary *allowExpiredConstrained = @{ (__bridge NSString*)kSecTrustSettingsAllowedError: @(-2147409654),
466 (__bridge NSString*)kSecTrustSettingsPolicy: (__bridge id)sslPolicy,
467 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultUnspecified)};
468 setTS(cert1, (__bridge CFDictionaryRef)allowExpiredConstrained)
469 setTS(cert2, (__bridge CFDictionaryRef)allowExpiredConstrained);
470 check_trust(sslChain, sslPolicy, expired_date, kSecTrustResultUnspecified);
471 check_trust(sslChain, basicPolicy, expired_date, kSecTrustResultRecoverableTrustFailure);
472 removeTS(cert2);
473 removeTS(cert1);
474
475 removeTS(cert0);
476 }
477
478 #define kNumberMultipleConstraintsTests (8+9*4)
479 static void test_multiple_constraints(void) {
480 /* deny all but */
481 NSArray *denyAllBut = @[
482 @{(__bridge NSString*)kSecTrustSettingsPolicy: (__bridge id)sslPolicy ,
483 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustRoot)},
484 @{(__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultDeny) }
485 ];
486 setTS(cert0, (__bridge CFArrayRef)denyAllBut);
487 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultDeny);
488 check_trust(sslChain, sslPolicy, verify_date, kSecTrustResultUnspecified);
489 removeTS(cert0);
490
491 /* allow all but */
492 NSArray *allowAllBut = @[
493 @{(__bridge NSString*)kSecTrustSettingsPolicy: (__bridge id)sslPolicy ,
494 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultUnspecified)},
495 @{(__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustRoot) }
496 ];
497 setTS(cert0, (__bridge CFArrayRef)allowAllBut);
498 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultUnspecified);
499 check_trust(sslChain, sslPolicy, verify_date, kSecTrustResultRecoverableTrustFailure);
500 removeTS(cert0);
501
502 /* different results for specific policies */
503 NSArray *specifyPolicyResult = @[
504 @{(__bridge NSString*)kSecTrustSettingsPolicy: (__bridge id)sslPolicy,
505 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultDeny)},
506 @{(__bridge NSString*)kSecTrustSettingsPolicy: (__bridge id)basicPolicy,
507 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustRoot) }
508 ];
509 setTS(cert0, (__bridge CFArrayRef)specifyPolicyResult);
510 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultUnspecified);
511 check_trust(sslChain, sslPolicy, verify_date, kSecTrustResultDeny);
512 check_trust(smimeChain, smimePolicy, verify_date, kSecTrustResultRecoverableTrustFailure);
513 removeTS(cert0);
514
515 /* different results for additional constraint with same policy */
516 NSArray *policyConstraintResult = @[
517 @{(__bridge NSString*)kSecTrustSettingsPolicy: (__bridge id)sslPolicy,
518 (__bridge NSString*)kSecTrustSettingsPolicyString: @("wrongname.apple.com"),
519 (__bridge NSString*)kSecTrustSettingsAllowedError: @(-2147408896),
520 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustAsRoot)},
521 @{(__bridge NSString*)kSecTrustSettingsPolicy: (__bridge id)sslPolicy,
522 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultUnspecified) }
523 ];
524 SecPolicyRef wrongNameSSL = NULL;
525 wrongNameSSL = SecPolicyCreateSSL(true, CFSTR("wrongname.apple.com"));
526 setTS(cert2, (__bridge CFArrayRef)policyConstraintResult);
527 sleep(1); // sleep a little extra so trustd gets trust settings event before evaluating leaf
528 check_trust(sslChain, wrongNameSSL, verify_date, kSecTrustSettingsResultUnspecified);
529 check_trust(sslChain, sslPolicy, verify_date, kSecTrustResultRecoverableTrustFailure);
530 removeTS(cert2);
531 CFReleaseNull(wrongNameSSL);
532
533 }
534
535 int si_28_sectrustsettings(int argc, char *const *argv)
536 {
537 plan_tests(kNumberNoConstraintsTests +
538 kNumberPolicyConstraintsTests +
539 kNumberPolicyStringConstraintsTests +
540 kNumberApplicationsConstraintsTests +
541 kNumberKeyUsageConstraintsTests +
542 kNumberAllowedErrorsTests +
543 kNumberMultipleConstraintsTests);
544
545 #if !TARGET_OS_IPHONE
546 if (getuid() != 0) {
547 printf("Test must be run as root on OS X");
548 return 0;
549 }
550 #endif
551
552 @autoreleasepool {
553 setup_globals();
554 test_no_constraints();
555 test_policy_constraints();
556 test_policy_string_constraints();
557 test_application_constraints();
558 test_key_usage_constraints();
559 test_allowed_errors();
560 test_multiple_constraints();
561 cleanup_globals();
562 }
563
564 return 0;
565 }