2 * Copyright (c) 2008-2010,2012,2016 Apple Inc. All Rights Reserved.
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>
20 #include <Security/SecTrustStore.h>
22 #include <Security/SecKeychain.h>
25 #include "shared_regressions.h"
27 #include "si-28-sectrustsettings.h"
29 /* Of course, the interface is different for OS X and iOS. */
30 /* each call is 1 test */
32 #define setTS(cert, settings) \
34 ok_status(SecTrustStoreSetTrustSettings(defaultStore, cert, settings), \
35 "set trust settings"); \
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) \
42 ok_status(SecTrustSettingsSetTrustSettings(cert, kSecTrustSettingsDomainAdmin, \
43 settings), "set trust settings"); \
49 #define setTSFail(cert, settings) \
51 is(SecTrustStoreSetTrustSettings(defaultStore, cert, settings), errSecParam, \
52 "set trust settings"); \
55 #define setTSFail(cert, settings) \
57 is(SecTrustSettingsSetTrustSettings(cert, kSecTrustSettingsDomainAdmin, \
58 settings), errSecParam, "set trust settings"); \
62 /* each call is 1 test */
64 #define removeTS(cert) \
66 ok_status(SecTrustStoreRemoveCertificate(defaultStore, cert), \
67 "remove trust settings"); \
70 #define removeTS(cert) \
72 ok_status(SecTrustSettingsRemoveTrustSettings(cert, kSecTrustSettingsDomainAdmin), \
73 "remove trust settings"); \
77 /* each call is 4 tests */
78 #define check_trust(certs, policy, valid_date, expected) \
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); \
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;
104 static SecTrustStoreRef defaultStore = NULL;
106 #define kSystemLoginKeychainPath "/Library/Keychains/System.keychain"
107 static NSMutableArray *deleteMeCertificates = NULL;
111 static void setup_globals(void) {
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));
118 sslPolicy = SecPolicyCreateSSL(true, CFSTR("testserver.apple.com"));
119 smimePolicy = SecPolicyCreateSMIME(kSecAnyEncryptSMIME, CFSTR("username@apple.com"));
120 basicPolicy = SecPolicyCreateBasicX509();
122 const void *v_certs1[] = { cert2, cert1, cert0 };
123 sslChain = CFArrayCreate(NULL, v_certs1, sizeof(v_certs1)/sizeof(*v_certs1), &kCFTypeArrayCallBacks);
125 const void *v_certs2[] = { cert3, cert1, cert0 };
126 smimeChain = CFArrayCreate(NULL, v_certs2, sizeof(v_certs2)/sizeof(*v_certs2), &kCFTypeArrayCallBacks);
128 verify_date = [NSDate dateWithTimeIntervalSinceReferenceDate:482000000.0]; // Apr 10 2016
131 defaultStore = SecTrustStoreForDomain(kSecTrustStoreDomainUser);
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;
139 SecKeychainOpen(kSystemLoginKeychainPath, &kcRef);
144 deleteMeCertificates = [[NSMutableArray alloc] init];
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);
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);
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);
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);
175 CFReleaseNull(kcRef);
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]});
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);
197 #define kNumberNoConstraintsTests (17+7*4)
198 static void test_no_constraints(void) {
199 /* root with the default TrustRoot result succeeds */
201 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultUnspecified);
204 /* intermediate with the default TrustRoot result fails */
205 setTSFail(cert1, NULL);
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);
213 /* intermediate with TrustRoot fails to set */
214 setTSFail(cert1, (__bridge CFDictionaryRef)trustRoot);
216 /* root with TrustAsRoot fails to set */
217 NSDictionary *trustAsRoot = @{ (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustAsRoot)};
218 setTSFail(cert0, (__bridge CFDictionaryRef)trustAsRoot);
220 /* intermediate with TrustAsRoot result succeeds */
221 setTS(cert1, (__bridge CFDictionaryRef)trustAsRoot);
222 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultUnspecified);
225 /* trusting the root but denying the intermediate fails */
226 NSDictionary *deny = @{ (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultDeny)};
228 setTS(cert1, (__bridge CFDictionaryRef)deny);
229 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultDeny);
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);
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);
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);
254 /* SSL client policy fails. */
255 SecPolicyRef sslClient = SecPolicyCreateSSL(false, NULL);
256 check_trust(sslChain, sslClient, verify_date, kSecTrustResultRecoverableTrustFailure);
257 CFReleaseNull(sslClient);
259 /* Basic policy fails */
260 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultRecoverableTrustFailure);
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) }
273 setTS(cert2, (__bridge CFArrayRef)hostnameAllowed);
274 /* evaluating against trusted hostname passes */
275 check_trust(sslChain, sslPolicy, verify_date, kSecTrustResultUnspecified);
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);
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);
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) }
295 setTS(cert3, (__bridge CFArrayRef)emailAllowed);
296 /* evaluating against trusted email passes */
297 check_trust(smimeChain, smimePolicy, verify_date, kSecTrustResultUnspecified);
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);
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);
312 #define kNumberApplicationsConstraintsTests 0
313 static void test_application_constraints(void) {}
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;
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");
325 NSDictionary *thisAppTS = @{ (__bridge NSString*)kSecTrustSettingsApplication: (__bridge id)thisApp,
326 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustRoot)};
328 NSDictionary *someOtherAppTS = @{ (__bridge NSString*)kSecTrustSettingsApplication: (__bridge id)someOtherApp,
329 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustRoot)};
331 /* This application Trust Setting succeeds */
332 setTS(cert0, (__bridge CFDictionaryRef)thisAppTS);
333 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultUnspecified);
336 /* Some other application Trust Setting fails */
337 setTS(cert0, (__bridge CFDictionaryRef)someOtherAppTS);
338 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultRecoverableTrustFailure);
341 CFReleaseNull(thisApp);
342 CFReleaseNull(someOtherApp);
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);
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);
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);
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);
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"));
383 /* signature smime policy passes for signature use TS*/
384 setTS(cert3, (__bridge CFDictionaryRef)signatureUse);
385 check_trust(smimeChain, smimeSignature, verify_date, kSecTrustResultUnspecified);
387 /* any use policy fails for signature use TS */
388 check_trust(smimeChain, smimePolicy, verify_date, kSecTrustResultRecoverableTrustFailure);
390 /* multiple use smime policy against signature use */
391 check_trust(smimeChain, smimeMultiple, verify_date, kSecTrustResultRecoverableTrustFailure);
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);
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);
408 /* signature smime policy against multiple uses */
409 check_trust(smimeChain, smimeSignature, verify_date, kSecTrustResultRecoverableTrustFailure);
411 /* any use smime policy against multiple uses */
412 check_trust(smimeChain, smimePolicy, verify_date, kSecTrustResultRecoverableTrustFailure);
415 CFReleaseNull(smimeSignature);
416 CFReleaseNull(smimeDataEncrypt);
417 CFReleaseNull(smimeKeyEncrypt);
418 CFReleaseNull(smimeKeyExchange);
419 CFReleaseNull(smimeMultiple);
422 #define kNumberAllowedErrorsTests (14+8*4)
423 static void test_allowed_errors(void) {
426 /* allow expired errors */
427 NSDate *expired_date = [NSDate dateWithTimeIntervalSinceReferenceDate:520000000.0]; // Jun 24 2017
428 check_trust(sslChain, basicPolicy, expired_date, kSecTrustResultRecoverableTrustFailure);
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);
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);
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);
449 CFReleaseNull(wrongNameSSL);
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);
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);
462 CFReleaseNull(wrongNameSMIME);
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);
478 #define kNumberMultipleConstraintsTests (8+9*4)
479 static void test_multiple_constraints(void) {
481 NSArray *denyAllBut = @[
482 @{(__bridge NSString*)kSecTrustSettingsPolicy: (__bridge id)sslPolicy ,
483 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustRoot)},
484 @{(__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultDeny) }
486 setTS(cert0, (__bridge CFArrayRef)denyAllBut);
487 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultDeny);
488 check_trust(sslChain, sslPolicy, verify_date, kSecTrustResultUnspecified);
492 NSArray *allowAllBut = @[
493 @{(__bridge NSString*)kSecTrustSettingsPolicy: (__bridge id)sslPolicy ,
494 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultUnspecified)},
495 @{(__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustRoot) }
497 setTS(cert0, (__bridge CFArrayRef)allowAllBut);
498 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultUnspecified);
499 check_trust(sslChain, sslPolicy, verify_date, kSecTrustResultRecoverableTrustFailure);
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) }
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);
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) }
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);
531 CFReleaseNull(wrongNameSSL);
535 int si_28_sectrustsettings(int argc, char *const *argv)
537 plan_tests(kNumberNoConstraintsTests +
538 kNumberPolicyConstraintsTests +
539 kNumberPolicyStringConstraintsTests +
540 kNumberApplicationsConstraintsTests +
541 kNumberKeyUsageConstraintsTests +
542 kNumberAllowedErrorsTests +
543 kNumberMultipleConstraintsTests);
545 #if !TARGET_OS_IPHONE
547 printf("Test must be run as root on OS X");
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();