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 <Security/SecTrustPriv.h>
16 #include <utilities/SecCFRelease.h>
21 #include <Security/SecTrustStore.h>
23 #include <Security/SecKeychain.h>
26 #include "shared_regressions.h"
28 #include "si-28-sectrustsettings.h"
30 /* Of course, the interface is different for OS X and iOS. */
31 /* each call is 1 test */
32 #define kNumberSetTSTests 1
34 #define setTS(cert, settings) \
36 ok_status(SecTrustStoreSetTrustSettings(defaultStore, cert, settings), \
37 "set trust settings"); \
40 /* Use admin store on OS X to avoid user prompts.
41 * Sleep a little so trustd has time to get the KeychainEvent. */
42 #define setTS(cert, settings) \
44 ok_status(SecTrustSettingsSetTrustSettings(cert, kSecTrustSettingsDomainAdmin, \
45 settings), "set trust settings"); \
51 #define setTSFail(cert, settings) \
53 is(SecTrustStoreSetTrustSettings(defaultStore, cert, settings), errSecParam, \
54 "set trust settings"); \
57 #define setTSFail(cert, settings) \
59 is(SecTrustSettingsSetTrustSettings(cert, kSecTrustSettingsDomainAdmin, \
60 settings), errSecParam, "set trust settings"); \
64 /* each call is 1 test */
65 #define kNumberRemoveTSTests 1
67 #define removeTS(cert) \
69 ok_status(SecTrustStoreRemoveCertificate(defaultStore, cert), \
70 "remove trust settings"); \
73 #define removeTS(cert) \
75 ok_status(SecTrustSettingsRemoveTrustSettings(cert, kSecTrustSettingsDomainAdmin), \
76 "remove trust settings"); \
80 /* each call is 4 tests */
81 #define kNumberCheckTrustTests 4
82 #define check_trust(certs, policy, valid_date, expected) \
84 SecTrustRef trust = NULL; \
85 SecTrustResultType trust_result; \
86 ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), \
87 "create trust with " #policy " policy"); \
88 ok_status(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)valid_date), \
89 "set trust verify date"); \
90 ok_status(SecTrustEvaluate(trust, &trust_result), "evaluate trust"); \
91 is(trust_result, expected, \
92 "check trust result for " #policy " policy"); \
93 CFReleaseSafe(trust); \
96 static SecCertificateRef cert0 = NULL;
97 static SecCertificateRef cert1 = NULL;
98 static SecCertificateRef cert2 = NULL;
99 static SecCertificateRef cert3 = NULL;
100 static SecPolicyRef sslPolicy = NULL;
101 static SecPolicyRef smimePolicy = NULL;
102 static SecPolicyRef basicPolicy = NULL;
103 static CFArrayRef sslChain = NULL;
104 static CFArrayRef smimeChain = NULL;
105 static NSDate *verify_date = nil;
108 static SecTrustStoreRef defaultStore = NULL;
110 #define kSystemLoginKeychainPath "/Library/Keychains/System.keychain"
111 static NSMutableArray *deleteMeCertificates = NULL;
115 static void setup_globals(void) {
117 cert0 = SecCertificateCreateWithBytes(NULL, _trustSettingsRoot, sizeof(_trustSettingsRoot));
118 cert1 = SecCertificateCreateWithBytes(NULL, _trustSettingsInt, sizeof(_trustSettingsInt));
119 cert2 = SecCertificateCreateWithBytes(NULL, _trustSettingsSSLLeaf, sizeof(_trustSettingsSSLLeaf));
120 cert3 = SecCertificateCreateWithBytes(NULL, _trustSettingsSMIMELeaf, sizeof(_trustSettingsSMIMELeaf));
122 sslPolicy = SecPolicyCreateSSL(true, CFSTR("testserver.apple.com"));
123 smimePolicy = SecPolicyCreateSMIME(kSecAnyEncryptSMIME, CFSTR("username@apple.com"));
124 basicPolicy = SecPolicyCreateBasicX509();
126 const void *v_certs1[] = { cert2, cert1, cert0 };
127 sslChain = CFArrayCreate(NULL, v_certs1, sizeof(v_certs1)/sizeof(*v_certs1), &kCFTypeArrayCallBacks);
129 const void *v_certs2[] = { cert3, cert1, cert0 };
130 smimeChain = CFArrayCreate(NULL, v_certs2, sizeof(v_certs2)/sizeof(*v_certs2), &kCFTypeArrayCallBacks);
132 verify_date = [NSDate dateWithTimeIntervalSinceReferenceDate:482000000.0]; // Apr 10 2016
135 defaultStore = SecTrustStoreForDomain(kSecTrustStoreDomainUser);
137 /* Since we're putting trust settings in the admin domain,
138 * we need to add the certs to the system keychain. */
139 SecKeychainRef kcRef = NULL;
140 CFArrayRef certRef = NULL;
141 NSDictionary *attrs = nil;
143 SecKeychainOpen(kSystemLoginKeychainPath, &kcRef);
148 deleteMeCertificates = [[NSMutableArray alloc] init];
150 attrs = @{(__bridge NSString*)kSecValueRef: (__bridge id)cert0,
151 (__bridge NSString*)kSecUseKeychain: (__bridge id)kcRef,
152 (__bridge NSString*)kSecReturnPersistentRef: @YES};
153 if (SecItemAdd((CFDictionaryRef)attrs, (void *)&certRef) == 0)
154 [deleteMeCertificates addObject:(__bridge NSArray *)certRef];
155 CFReleaseNull(certRef);
157 attrs = @{(__bridge NSString*)kSecValueRef: (__bridge id)cert1,
158 (__bridge NSString*)kSecUseKeychain: (__bridge id)kcRef,
159 (__bridge NSString*)kSecReturnPersistentRef: @YES};
160 if (SecItemAdd((CFDictionaryRef)attrs, (void *)&certRef) == 0)
161 [deleteMeCertificates addObject:(__bridge NSArray *)certRef];
162 CFReleaseNull(certRef);
164 attrs = @{(__bridge NSString*)kSecValueRef: (__bridge id)cert2,
165 (__bridge NSString*)kSecUseKeychain: (__bridge id)kcRef,
166 (__bridge NSString*)kSecReturnPersistentRef: @YES};
167 if (SecItemAdd((CFDictionaryRef)attrs, (void *)&certRef) == 0)
168 [deleteMeCertificates addObject:(__bridge NSArray *)certRef];
169 CFReleaseNull(certRef);
171 attrs = @{(__bridge NSString*)kSecValueRef: (__bridge id)cert3,
172 (__bridge NSString*)kSecUseKeychain: (__bridge id)kcRef,
173 (__bridge NSString*)kSecReturnPersistentRef: @YES};
174 if (SecItemAdd((CFDictionaryRef)attrs, (void *)&certRef) == 0)
175 [deleteMeCertificates addObject:(__bridge NSArray *)certRef];
176 CFReleaseNull(certRef);
179 CFReleaseNull(kcRef);
183 static void cleanup_globals(void) {
184 #if !TARGET_OS_IPHONE
185 [deleteMeCertificates enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
186 SecItemDelete((CFDictionaryRef)@{ (__bridge NSString*)kSecValuePersistentRef: [obj objectAtIndex:0]});
190 CFReleaseNull(cert0);
191 CFReleaseNull(cert1);
192 CFReleaseNull(cert2);
193 CFReleaseNull(cert3);
194 CFReleaseNull(sslPolicy);
195 CFReleaseNull(smimePolicy);
196 CFReleaseNull(basicPolicy);
197 CFReleaseNull(sslChain);
198 CFReleaseNull(smimeChain);
201 #define kNumberNoConstraintsTests (17+7*4)
202 static void test_no_constraints(void) {
203 /* root with the default TrustRoot result succeeds */
205 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultProceed);
208 /* intermediate with the default TrustRoot result fails */
209 setTSFail(cert1, NULL);
211 /* root with TrustRoot result succeeds */
212 NSDictionary *trustRoot = @{ (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustRoot)};
213 setTS(cert0, (__bridge CFDictionaryRef)trustRoot);
214 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultProceed);
217 /* intermediate with TrustRoot fails to set */
218 setTSFail(cert1, (__bridge CFDictionaryRef)trustRoot);
220 /* root with TrustAsRoot fails to set */
221 NSDictionary *trustAsRoot = @{ (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustAsRoot)};
222 setTSFail(cert0, (__bridge CFDictionaryRef)trustAsRoot);
224 /* intermediate with TrustAsRoot result succeeds */
225 setTS(cert1, (__bridge CFDictionaryRef)trustAsRoot);
226 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultProceed);
229 /* trusting the root but denying the intermediate fails */
230 NSDictionary *deny = @{ (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultDeny)};
232 setTS(cert1, (__bridge CFDictionaryRef)deny);
233 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultDeny);
237 /* the unspecified result gives us default behavior */
238 NSDictionary *unspecified = @{ (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultUnspecified)};
239 setTS(cert1, (__bridge CFDictionaryRef)unspecified);
240 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultRecoverableTrustFailure);
243 /* trusting one leaf doesn't make other leaf trusted */
244 setTS(cert2, (__bridge CFDictionaryRef)trustAsRoot);
245 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultProceed);
246 check_trust(smimeChain, basicPolicy, verify_date, kSecTrustResultRecoverableTrustFailure);
250 #define kNumberPolicyConstraintsTests (2+3*4)
251 static void test_policy_constraints(void) {
252 /* Trust only for SSL server. SSL server policy succeeds. */
253 NSDictionary *sslServerAllowed = @{ (__bridge NSString*)kSecTrustSettingsPolicy: (__bridge id)sslPolicy,
254 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustAsRoot) };
255 setTS(cert1, (__bridge CFDictionaryRef)sslServerAllowed);
256 check_trust(sslChain, sslPolicy, verify_date, kSecTrustResultProceed);
258 /* SSL client policy fails. */
259 SecPolicyRef sslClient = SecPolicyCreateSSL(false, NULL);
260 check_trust(sslChain, sslClient, verify_date, kSecTrustResultRecoverableTrustFailure);
261 CFReleaseNull(sslClient);
263 /* Basic policy fails */
264 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultRecoverableTrustFailure);
268 #define kNumberPolicyStringConstraintsTests (4+6*4)
269 static void test_policy_string_constraints(void) {
270 NSArray *hostnameAllowed = @[ @{ (__bridge NSString*)kSecTrustSettingsPolicy: (__bridge id)sslPolicy,
271 (__bridge NSString*)kSecTrustSettingsPolicyString: @("wrongname.apple.com"),
272 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultDeny) },
273 @{ (__bridge NSString*)kSecTrustSettingsPolicy: (__bridge id)sslPolicy,
274 (__bridge NSString*)kSecTrustSettingsPolicyString: @("testserver.apple.com"),
275 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustAsRoot) }
277 setTS(cert2, (__bridge CFArrayRef)hostnameAllowed);
278 /* evaluating against trusted hostname passes */
279 check_trust(sslChain, sslPolicy, verify_date, kSecTrustResultProceed);
281 /* evaluating against hostname not in trust settings is recoverable failure */
282 SecPolicyRef weirdnamePolicy = SecPolicyCreateSSL(true, CFSTR("weirdname.apple.com"));
283 check_trust(sslChain, weirdnamePolicy, verify_date, kSecTrustResultRecoverableTrustFailure);
284 CFReleaseNull(weirdnamePolicy);
286 /* evaluating against hostname denied by trust settings is denied */
287 SecPolicyRef wrongnamePolicy = SecPolicyCreateSSL(true, CFSTR("wrongname.apple.com"));
288 check_trust(sslChain, wrongnamePolicy, verify_date, kSecTrustResultDeny);
289 CFReleaseNull(wrongnamePolicy);
292 NSArray *emailAllowed = @[ @{ (__bridge NSString*)kSecTrustSettingsPolicy: (__bridge id)smimePolicy,
293 (__bridge NSString*)kSecTrustSettingsPolicyString: @("wrongemail@apple.com"),
294 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultDeny) },
295 @{ (__bridge NSString*)kSecTrustSettingsPolicy: (__bridge id)smimePolicy,
296 (__bridge NSString*)kSecTrustSettingsPolicyString: @("username@apple.com"),
297 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustAsRoot) }
299 setTS(cert3, (__bridge CFArrayRef)emailAllowed);
300 /* evaluating against trusted email passes */
301 check_trust(smimeChain, smimePolicy, verify_date, kSecTrustResultProceed);
303 /* evaluating against hostname not in trust settings is recoverable failure */
304 SecPolicyRef weirdemailPolicy = SecPolicyCreateSMIME(kSecAnyEncryptSMIME, CFSTR("weirdemail@apple.com"));
305 check_trust(smimeChain, weirdemailPolicy, verify_date, kSecTrustResultRecoverableTrustFailure);
306 CFReleaseNull(weirdemailPolicy);
308 /* evaluating against hostname denied by trust settings is denied */
309 SecPolicyRef wrongemailPolicy = SecPolicyCreateSMIME(kSecAnyEncryptSMIME, CFSTR("wrongemail@apple.com"));
310 check_trust(smimeChain, wrongemailPolicy, verify_date, kSecTrustResultDeny);
311 CFReleaseNull(wrongemailPolicy);
316 #define kNumberApplicationsConstraintsTests 0
317 static void test_application_constraints(void) {}
319 #include <Security/SecTrustedApplicationPriv.h>
320 #define kNumberApplicationsConstraintsTests (2+4+2*4)
321 static void test_application_constraints(void) {
322 SecTrustedApplicationRef thisApp = NULL, someOtherApp = NULL;
324 ok_status(SecTrustedApplicationCreateFromPath(NULL, &thisApp),
325 "create TrustedApplicationRef for this app");
326 ok_status(SecTrustedApplicationCreateFromPath("/Applications/Safari.app", &someOtherApp),
327 "create TrustedApplicationRef for Safari");
329 NSDictionary *thisAppTS = @{ (__bridge NSString*)kSecTrustSettingsApplication: (__bridge id)thisApp,
330 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustRoot)};
332 NSDictionary *someOtherAppTS = @{ (__bridge NSString*)kSecTrustSettingsApplication: (__bridge id)someOtherApp,
333 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustRoot)};
335 /* This application Trust Setting succeeds */
336 setTS(cert0, (__bridge CFDictionaryRef)thisAppTS);
337 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultProceed);
340 /* Some other application Trust Setting fails */
341 setTS(cert0, (__bridge CFDictionaryRef)someOtherAppTS);
342 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultRecoverableTrustFailure);
345 CFReleaseNull(thisApp);
346 CFReleaseNull(someOtherApp);
350 #define kNumberKeyUsageConstraintsTests (14+11*4)
351 static void test_key_usage_constraints(void) {
352 /* any key usage succeeds */
353 NSDictionary *anyKeyUse = @{ (__bridge NSString*)kSecTrustSettingsKeyUsage: @(kSecTrustSettingsKeyUseAny),
354 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustRoot)};
355 setTS(cert0, (__bridge CFDictionaryRef)anyKeyUse);
356 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultProceed);
359 /* signCert key usage on an intermediate or root succeeds */
360 NSDictionary *signCertUseRoot = @{ (__bridge NSString*)kSecTrustSettingsKeyUsage: @(kSecTrustSettingsKeyUseSignCert),
361 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustRoot)};
362 setTS(cert0, (__bridge CFDictionaryRef)signCertUseRoot);
363 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultProceed);
366 NSDictionary *signCertUseInt = @{ (__bridge NSString*)kSecTrustSettingsKeyUsage: @(kSecTrustSettingsKeyUseSignCert),
367 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustAsRoot)};
368 setTS(cert1, (__bridge CFDictionaryRef)signCertUseInt);
369 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultProceed);
372 /* intermediate without signCert key usage fails */
373 NSDictionary *signatureUse = @{ (__bridge NSString*)kSecTrustSettingsKeyUsage: @(kSecTrustSettingsKeyUseSignature),
374 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustAsRoot)};
375 setTS(cert1, (__bridge CFDictionaryRef)signatureUse);
376 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultRecoverableTrustFailure);
379 /* brief interlude to create a bunch of SMIME policies with different key usages */
380 SecPolicyRef smimeSignature = SecPolicyCreateSMIME(kSecSignSMIMEUsage, CFSTR("username@apple.com"));
381 SecPolicyRef smimeDataEncrypt = SecPolicyCreateSMIME(kSecDataEncryptSMIMEUsage, CFSTR("username@apple.com"));
382 SecPolicyRef smimeKeyEncrypt = SecPolicyCreateSMIME(kSecKeyEncryptSMIMEUsage, CFSTR("username@apple.com"));
383 SecPolicyRef smimeKeyExchange = SecPolicyCreateSMIME(kSecKeyExchangeBothSMIMEUsage, CFSTR("username@apple.com"));
384 SecPolicyRef smimeMultiple = SecPolicyCreateSMIME((kSecSignSMIMEUsage | kSecKeyEncryptSMIMEUsage),
385 CFSTR("username@apple.com"));
387 /* signature smime policy passes for signature use TS*/
388 setTS(cert3, (__bridge CFDictionaryRef)signatureUse);
389 check_trust(smimeChain, smimeSignature, verify_date, kSecTrustResultProceed);
391 /* any use policy fails for signature use TS */
392 check_trust(smimeChain, smimePolicy, verify_date, kSecTrustResultRecoverableTrustFailure);
394 /* multiple use smime policy against signature use */
395 check_trust(smimeChain, smimeMultiple, verify_date, kSecTrustResultRecoverableTrustFailure);
398 /* key encrypt smime policy passes for key encrypt use */
399 NSDictionary *keyEncryptUse = @{ (__bridge NSString*)kSecTrustSettingsKeyUsage: @(kSecTrustSettingsKeyUseEnDecryptKey),
400 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustAsRoot)};
401 setTS(cert3, (__bridge CFDictionaryRef)keyEncryptUse);
402 check_trust(smimeChain, smimeKeyEncrypt, verify_date, kSecTrustResultProceed);
405 /* multiple use smime policy against multiple uses */
406 NSDictionary *multipleUse = @{ (__bridge NSString*)kSecTrustSettingsKeyUsage: @(kSecTrustSettingsKeyUseEnDecryptKey |
407 kSecTrustSettingsKeyUseSignature),
408 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustAsRoot)};
409 setTS(cert3, (__bridge CFDictionaryRef)multipleUse)
410 check_trust(smimeChain, smimeMultiple, verify_date, kSecTrustResultProceed);
412 /* signature smime policy against multiple uses */
413 check_trust(smimeChain, smimeSignature, verify_date, kSecTrustResultRecoverableTrustFailure);
415 /* any use smime policy against multiple uses */
416 check_trust(smimeChain, smimePolicy, verify_date, kSecTrustResultRecoverableTrustFailure);
419 CFReleaseNull(smimeSignature);
420 CFReleaseNull(smimeDataEncrypt);
421 CFReleaseNull(smimeKeyEncrypt);
422 CFReleaseNull(smimeKeyExchange);
423 CFReleaseNull(smimeMultiple);
426 #define kNumberAllowedErrorsTests (14+8*4)
427 static void test_allowed_errors(void) {
430 /* allow expired errors */
431 NSDate *expired_date = [NSDate dateWithTimeIntervalSinceReferenceDate:520000000.0]; // Jun 24 2017
432 check_trust(sslChain, basicPolicy, expired_date, kSecTrustResultRecoverableTrustFailure);
434 NSDictionary *allowExpired = @{ (__bridge NSString*)kSecTrustSettingsAllowedError: @(-2147409654),
435 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultUnspecified)};
436 setTS(cert1, (__bridge CFDictionaryRef)allowExpired)
437 setTS(cert2, (__bridge CFDictionaryRef)allowExpired);
438 check_trust(sslChain, basicPolicy, expired_date, kSecTrustResultProceed);
442 /* allow hostname mismatch errors */
443 SecPolicyRef wrongNameSSL = NULL;
444 wrongNameSSL = SecPolicyCreateSSL(true, CFSTR("wrongname.apple.com"));
445 check_trust(sslChain, wrongNameSSL, verify_date, kSecTrustResultRecoverableTrustFailure);
447 NSDictionary *allowHostnameMismatch = @{ (__bridge NSString*)kSecTrustSettingsAllowedError: @(-2147408896),
448 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultUnspecified) };
449 setTS(cert2, (__bridge CFDictionaryRef)allowHostnameMismatch);
450 sleep(1); // sleep a little extra so trustd gets trust settings event before evaluating leaf
451 check_trust(sslChain, wrongNameSSL, verify_date, kSecTrustResultProceed);
453 CFReleaseNull(wrongNameSSL);
455 /* allow email mismatch errors */
456 SecPolicyRef wrongNameSMIME = NULL;
457 wrongNameSMIME = SecPolicyCreateSMIME(kSecAnyEncryptSMIME, CFSTR("test@apple.com"));
458 check_trust(smimeChain, wrongNameSMIME, verify_date, kSecTrustResultRecoverableTrustFailure);
460 NSDictionary *allowEmailMismatch = @{ (__bridge NSString*)kSecTrustSettingsAllowedError: @(-2147408872),
461 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultUnspecified) };
462 setTS(cert3, (__bridge CFDictionaryRef)allowEmailMismatch);
463 sleep(1); // sleep a little extra so trustd gets trust settings event before evaluating leaf
464 check_trust(smimeChain, wrongNameSMIME, verify_date, kSecTrustResultProceed);
466 CFReleaseNull(wrongNameSMIME);
468 /* allowed error with a policy constraint */
469 NSDictionary *allowExpiredConstrained = @{ (__bridge NSString*)kSecTrustSettingsAllowedError: @(-2147409654),
470 (__bridge NSString*)kSecTrustSettingsPolicy: (__bridge id)sslPolicy,
471 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultUnspecified)};
472 setTS(cert1, (__bridge CFDictionaryRef)allowExpiredConstrained)
473 setTS(cert2, (__bridge CFDictionaryRef)allowExpiredConstrained);
474 check_trust(sslChain, sslPolicy, expired_date, kSecTrustResultProceed);
475 check_trust(sslChain, basicPolicy, expired_date, kSecTrustResultRecoverableTrustFailure);
482 #define kNumberMultipleConstraintsTests (8+9*4)
483 static void test_multiple_constraints(void) {
485 NSArray *denyAllBut = @[
486 @{(__bridge NSString*)kSecTrustSettingsPolicy: (__bridge id)sslPolicy ,
487 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustRoot)},
488 @{(__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultDeny) }
490 setTS(cert0, (__bridge CFArrayRef)denyAllBut);
491 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultDeny);
492 check_trust(sslChain, sslPolicy, verify_date, kSecTrustResultProceed);
496 NSArray *allowAllBut = @[
497 @{(__bridge NSString*)kSecTrustSettingsPolicy: (__bridge id)sslPolicy ,
498 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultUnspecified)},
499 @{(__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustRoot) }
501 setTS(cert0, (__bridge CFArrayRef)allowAllBut);
502 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultProceed);
503 check_trust(sslChain, sslPolicy, verify_date, kSecTrustResultRecoverableTrustFailure);
506 /* different results for specific policies */
507 NSArray *specifyPolicyResult = @[
508 @{(__bridge NSString*)kSecTrustSettingsPolicy: (__bridge id)sslPolicy,
509 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultDeny)},
510 @{(__bridge NSString*)kSecTrustSettingsPolicy: (__bridge id)basicPolicy,
511 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustRoot) }
513 setTS(cert0, (__bridge CFArrayRef)specifyPolicyResult);
514 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultProceed);
515 check_trust(sslChain, sslPolicy, verify_date, kSecTrustResultDeny);
516 check_trust(smimeChain, smimePolicy, verify_date, kSecTrustResultRecoverableTrustFailure);
519 /* different results for additional constraint with same policy */
520 NSArray *policyConstraintResult = @[
521 @{(__bridge NSString*)kSecTrustSettingsPolicy: (__bridge id)sslPolicy,
522 (__bridge NSString*)kSecTrustSettingsPolicyString: @("wrongname.apple.com"),
523 (__bridge NSString*)kSecTrustSettingsAllowedError: @(-2147408896),
524 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustAsRoot)},
525 @{(__bridge NSString*)kSecTrustSettingsPolicy: (__bridge id)sslPolicy,
526 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultUnspecified) }
528 SecPolicyRef wrongNameSSL = NULL;
529 wrongNameSSL = SecPolicyCreateSSL(true, CFSTR("wrongname.apple.com"));
530 setTS(cert2, (__bridge CFArrayRef)policyConstraintResult);
531 sleep(1); // sleep a little extra so trustd gets trust settings event before evaluating leaf
532 check_trust(sslChain, wrongNameSSL, verify_date, kSecTrustResultProceed);
533 check_trust(sslChain, sslPolicy, verify_date, kSecTrustResultRecoverableTrustFailure);
535 CFReleaseNull(wrongNameSSL);
539 #define kNumberChangeConstraintsTests (2*kNumberSetTSTests + kNumberRemoveTSTests + 4*kNumberCheckTrustTests)
540 static void test_change_constraints(void) {
542 NSArray *allowAllBut = @[
543 @{(__bridge NSString*)kSecTrustSettingsPolicy: (__bridge id)sslPolicy ,
544 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultUnspecified)},
545 @{(__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustRoot) }
547 setTS(cert0, (__bridge CFArrayRef)allowAllBut);
548 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultProceed);
549 check_trust(sslChain, sslPolicy, verify_date, kSecTrustResultRecoverableTrustFailure);
551 /* Don't clear trust settings. Just change them. */
553 /* root with the default TrustRoot result succeeds */
555 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultProceed);
556 check_trust(sslChain, sslPolicy, verify_date, kSecTrustResultProceed);
560 #define kNumberPolicyNamePinnningConstraintsTests (kNumberSetTSTests + kNumberRemoveTSTests + 5)
561 static void test_policy_name_pinning_constraints(void) {
563 NSArray *allowAllBut = @[
564 @{(__bridge NSString*)kSecTrustSettingsPolicy: (__bridge id)sslPolicy ,
565 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultUnspecified)},
566 @{(__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustRoot) }
568 setTS(cert0, (__bridge CFArrayRef)allowAllBut);
570 SecTrustRef trust = NULL;
571 SecTrustResultType trust_result;
572 ok_status(SecTrustCreateWithCertificates(sslChain, sslPolicy, &trust), "create trust with ssl policy");
573 ok_status(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)verify_date), "set trust verify date");
574 ok_status(SecTrustSetPinningPolicyName(trust, CFSTR("not-a-db-policy-name")), "set policy name");
575 ok_status(SecTrustEvaluate(trust, &trust_result), "evaluate trust");
576 is(trust_result, kSecTrustResultRecoverableTrustFailure, "check trust result for sslServer policy with policy name");
577 CFReleaseSafe(trust);
583 int si_28_sectrustsettings(int argc, char *const *argv)
585 plan_tests(kNumberNoConstraintsTests
586 + kNumberPolicyConstraintsTests
587 + kNumberPolicyStringConstraintsTests
588 + kNumberApplicationsConstraintsTests
589 + kNumberKeyUsageConstraintsTests
590 + kNumberAllowedErrorsTests
591 + kNumberMultipleConstraintsTests
592 + kNumberChangeConstraintsTests
593 + kNumberPolicyNamePinnningConstraintsTests
596 #if !TARGET_OS_IPHONE
598 printf("Test must be run as root on OS X");
605 test_no_constraints();
606 test_policy_constraints();
607 test_policy_string_constraints();
608 test_application_constraints();
609 test_key_usage_constraints();
610 test_allowed_errors();
611 test_multiple_constraints();
612 test_change_constraints();
613 test_policy_name_pinning_constraints();