]> git.saurik.com Git - apple/security.git/blob - OSX/sec/Security/Regressions/secitem/si-28-sectrustsettings.m
Security-59306.140.5.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 <Security/SecTrustPriv.h>
16 #include <utilities/SecCFRelease.h>
17 #include <stdlib.h>
18 #include <unistd.h>
19
20 #if TARGET_OS_IPHONE
21 #include <Security/SecTrustStore.h>
22 #else
23 #include <Security/SecKeychain.h>
24 #endif
25
26 #include "shared_regressions.h"
27
28 #include "si-28-sectrustsettings.h"
29
30 /* Of course, the interface is different for OS X and iOS. */
31 /* each call is 1 test */
32 #define kNumberSetTSTests 1
33 #if TARGET_OS_IPHONE
34 #define setTS(cert, settings) \
35 { \
36 ok_status(SecTrustStoreSetTrustSettings(defaultStore, cert, settings), \
37 "set trust settings"); \
38 }
39 #else
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) \
43 { \
44 ok_status(SecTrustSettingsSetTrustSettings(cert, kSecTrustSettingsDomainAdmin, \
45 settings), "set trust settings"); \
46 usleep(20000); \
47 }
48 #endif
49
50 #if TARGET_OS_IPHONE
51 #define setTSFail(cert, settings) \
52 { \
53 is(SecTrustStoreSetTrustSettings(defaultStore, cert, settings), errSecParam, \
54 "set trust settings"); \
55 }
56 #else
57 #define setTSFail(cert, settings) \
58 { \
59 is(SecTrustSettingsSetTrustSettings(cert, kSecTrustSettingsDomainAdmin, \
60 settings), errSecParam, "set trust settings"); \
61 }
62 #endif
63
64 /* each call is 1 test */
65 #define kNumberRemoveTSTests 1
66 #if TARGET_OS_IPHONE
67 #define removeTS(cert) \
68 { \
69 ok_status(SecTrustStoreRemoveCertificate(defaultStore, cert), \
70 "remove trust settings"); \
71 }
72 #else
73 #define removeTS(cert) \
74 { \
75 ok_status(SecTrustSettingsRemoveTrustSettings(cert, kSecTrustSettingsDomainAdmin), \
76 "remove trust settings"); \
77 }
78 #endif
79
80 /* each call is 4 tests */
81 #define kNumberCheckTrustTests 4
82 #define check_trust(certs, policy, valid_date, expected) \
83 { \
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); \
94 }
95
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;
106
107 #if TARGET_OS_IPHONE
108 static SecTrustStoreRef defaultStore = NULL;
109 #else
110 #define kSystemLoginKeychainPath "/Library/Keychains/System.keychain"
111 static NSMutableArray *deleteMeCertificates = NULL;
112 #endif
113
114
115 static void setup_globals(void) {
116
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));
121
122 sslPolicy = SecPolicyCreateSSL(true, CFSTR("testserver.apple.com"));
123 smimePolicy = SecPolicyCreateSMIME(kSecAnyEncryptSMIME, CFSTR("username@apple.com"));
124 basicPolicy = SecPolicyCreateBasicX509();
125
126 const void *v_certs1[] = { cert2, cert1, cert0 };
127 sslChain = CFArrayCreate(NULL, v_certs1, sizeof(v_certs1)/sizeof(*v_certs1), &kCFTypeArrayCallBacks);
128
129 const void *v_certs2[] = { cert3, cert1, cert0 };
130 smimeChain = CFArrayCreate(NULL, v_certs2, sizeof(v_certs2)/sizeof(*v_certs2), &kCFTypeArrayCallBacks);
131
132 verify_date = [NSDate dateWithTimeIntervalSinceReferenceDate:482000000.0]; // Apr 10 2016
133
134 #if TARGET_OS_IPHONE
135 defaultStore = SecTrustStoreForDomain(kSecTrustStoreDomainUser);
136 #else
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;
142
143 SecKeychainOpen(kSystemLoginKeychainPath, &kcRef);
144 if (!kcRef) {
145 goto out;
146 }
147
148 deleteMeCertificates = [[NSMutableArray alloc] init];
149
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);
156
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);
163
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);
170
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);
177
178 out:
179 CFReleaseNull(kcRef);
180 #endif
181 }
182
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]});
187 }];
188 #endif
189
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);
199 }
200
201 #define kNumberNoConstraintsTests (17+7*4)
202 static void test_no_constraints(void) {
203 /* root with the default TrustRoot result succeeds */
204 setTS(cert0, NULL);
205 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultProceed);
206 removeTS(cert0);
207
208 /* intermediate with the default TrustRoot result fails */
209 setTSFail(cert1, NULL);
210
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);
215 removeTS(cert0);
216
217 /* intermediate with TrustRoot fails to set */
218 setTSFail(cert1, (__bridge CFDictionaryRef)trustRoot);
219
220 /* root with TrustAsRoot fails to set */
221 NSDictionary *trustAsRoot = @{ (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustAsRoot)};
222 setTSFail(cert0, (__bridge CFDictionaryRef)trustAsRoot);
223
224 /* intermediate with TrustAsRoot result succeeds */
225 setTS(cert1, (__bridge CFDictionaryRef)trustAsRoot);
226 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultProceed);
227 removeTS(cert1);
228
229 /* trusting the root but denying the intermediate fails */
230 NSDictionary *deny = @{ (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultDeny)};
231 setTS(cert0, NULL);
232 setTS(cert1, (__bridge CFDictionaryRef)deny);
233 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultDeny);
234 removeTS(cert1);
235 removeTS(cert0);
236
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);
241 removeTS(cert1);
242
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);
247 removeTS(cert2);
248 }
249
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);
257
258 /* SSL client policy fails. */
259 SecPolicyRef sslClient = SecPolicyCreateSSL(false, NULL);
260 check_trust(sslChain, sslClient, verify_date, kSecTrustResultRecoverableTrustFailure);
261 CFReleaseNull(sslClient);
262
263 /* Basic policy fails */
264 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultRecoverableTrustFailure);
265 removeTS(cert1);
266 }
267
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) }
276 ];
277 setTS(cert2, (__bridge CFArrayRef)hostnameAllowed);
278 /* evaluating against trusted hostname passes */
279 check_trust(sslChain, sslPolicy, verify_date, kSecTrustResultProceed);
280
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);
285
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);
290 removeTS(cert2);
291
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) }
298 ];
299 setTS(cert3, (__bridge CFArrayRef)emailAllowed);
300 /* evaluating against trusted email passes */
301 check_trust(smimeChain, smimePolicy, verify_date, kSecTrustResultProceed);
302
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);
307
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);
312 removeTS(cert3);
313 }
314
315 #if TARGET_OS_IPHONE
316 #define kNumberApplicationsConstraintsTests 0
317 static void test_application_constraints(void) {}
318 #else
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;
323
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");
328
329 NSDictionary *thisAppTS = @{ (__bridge NSString*)kSecTrustSettingsApplication: (__bridge id)thisApp,
330 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustRoot)};
331
332 NSDictionary *someOtherAppTS = @{ (__bridge NSString*)kSecTrustSettingsApplication: (__bridge id)someOtherApp,
333 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustRoot)};
334
335 /* This application Trust Setting succeeds */
336 setTS(cert0, (__bridge CFDictionaryRef)thisAppTS);
337 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultProceed);
338 removeTS(cert0);
339
340 /* Some other application Trust Setting fails */
341 setTS(cert0, (__bridge CFDictionaryRef)someOtherAppTS);
342 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultRecoverableTrustFailure);
343 removeTS(cert0);
344
345 CFReleaseNull(thisApp);
346 CFReleaseNull(someOtherApp);
347 }
348 #endif
349
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);
357 removeTS(cert0);
358
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);
364 removeTS(cert0)
365
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);
370 removeTS(cert1);
371
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);
377 removeTS(cert1);
378
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"));
386
387 /* signature smime policy passes for signature use TS*/
388 setTS(cert3, (__bridge CFDictionaryRef)signatureUse);
389 check_trust(smimeChain, smimeSignature, verify_date, kSecTrustResultProceed);
390
391 /* any use policy fails for signature use TS */
392 check_trust(smimeChain, smimePolicy, verify_date, kSecTrustResultRecoverableTrustFailure);
393
394 /* multiple use smime policy against signature use */
395 check_trust(smimeChain, smimeMultiple, verify_date, kSecTrustResultRecoverableTrustFailure);
396 removeTS(cert3);
397
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);
403 removeTS(cert3);
404
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);
411
412 /* signature smime policy against multiple uses */
413 check_trust(smimeChain, smimeSignature, verify_date, kSecTrustResultRecoverableTrustFailure);
414
415 /* any use smime policy against multiple uses */
416 check_trust(smimeChain, smimePolicy, verify_date, kSecTrustResultRecoverableTrustFailure);
417 removeTS(cert3);
418
419 CFReleaseNull(smimeSignature);
420 CFReleaseNull(smimeDataEncrypt);
421 CFReleaseNull(smimeKeyEncrypt);
422 CFReleaseNull(smimeKeyExchange);
423 CFReleaseNull(smimeMultiple);
424 }
425
426 #define kNumberAllowedErrorsTests (14+8*4)
427 static void test_allowed_errors(void) {
428 setTS(cert0, NULL);
429
430 /* allow expired errors */
431 NSDate *expired_date = [NSDate dateWithTimeIntervalSinceReferenceDate:520000000.0]; // Jun 24 2017
432 check_trust(sslChain, basicPolicy, expired_date, kSecTrustResultRecoverableTrustFailure);
433
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);
439 removeTS(cert2);
440 removeTS(cert1);
441
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);
446
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);
452 removeTS(cert2);
453 CFReleaseNull(wrongNameSSL);
454
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);
459
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);
465 removeTS(cert3);
466 CFReleaseNull(wrongNameSMIME);
467
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);
476 removeTS(cert2);
477 removeTS(cert1);
478
479 removeTS(cert0);
480 }
481
482 #define kNumberMultipleConstraintsTests (8+9*4)
483 static void test_multiple_constraints(void) {
484 /* deny all but */
485 NSArray *denyAllBut = @[
486 @{(__bridge NSString*)kSecTrustSettingsPolicy: (__bridge id)sslPolicy ,
487 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustRoot)},
488 @{(__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultDeny) }
489 ];
490 setTS(cert0, (__bridge CFArrayRef)denyAllBut);
491 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultDeny);
492 check_trust(sslChain, sslPolicy, verify_date, kSecTrustResultProceed);
493 removeTS(cert0);
494
495 /* allow all but */
496 NSArray *allowAllBut = @[
497 @{(__bridge NSString*)kSecTrustSettingsPolicy: (__bridge id)sslPolicy ,
498 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultUnspecified)},
499 @{(__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustRoot) }
500 ];
501 setTS(cert0, (__bridge CFArrayRef)allowAllBut);
502 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultProceed);
503 check_trust(sslChain, sslPolicy, verify_date, kSecTrustResultRecoverableTrustFailure);
504 removeTS(cert0);
505
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) }
512 ];
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);
517 removeTS(cert0);
518
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) }
527 ];
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);
534 removeTS(cert2);
535 CFReleaseNull(wrongNameSSL);
536
537 }
538
539 #define kNumberChangeConstraintsTests (2*kNumberSetTSTests + kNumberRemoveTSTests + 4*kNumberCheckTrustTests)
540 static void test_change_constraints(void) {
541 /* allow all but */
542 NSArray *allowAllBut = @[
543 @{(__bridge NSString*)kSecTrustSettingsPolicy: (__bridge id)sslPolicy ,
544 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultUnspecified)},
545 @{(__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustRoot) }
546 ];
547 setTS(cert0, (__bridge CFArrayRef)allowAllBut);
548 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultProceed);
549 check_trust(sslChain, sslPolicy, verify_date, kSecTrustResultRecoverableTrustFailure);
550
551 /* Don't clear trust settings. Just change them. */
552
553 /* root with the default TrustRoot result succeeds */
554 setTS(cert0, NULL);
555 check_trust(sslChain, basicPolicy, verify_date, kSecTrustResultProceed);
556 check_trust(sslChain, sslPolicy, verify_date, kSecTrustResultProceed);
557 removeTS(cert0);
558 }
559
560 #define kNumberPolicyNamePinnningConstraintsTests (kNumberSetTSTests + kNumberRemoveTSTests + 5)
561 static void test_policy_name_pinning_constraints(void) {
562 /* allow all but */
563 NSArray *allowAllBut = @[
564 @{(__bridge NSString*)kSecTrustSettingsPolicy: (__bridge id)sslPolicy ,
565 (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultUnspecified)},
566 @{(__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustRoot) }
567 ];
568 setTS(cert0, (__bridge CFArrayRef)allowAllBut);
569
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);
578
579 removeTS(cert0);
580 }
581
582
583 int si_28_sectrustsettings(int argc, char *const *argv)
584 {
585 plan_tests(kNumberNoConstraintsTests
586 + kNumberPolicyConstraintsTests
587 + kNumberPolicyStringConstraintsTests
588 + kNumberApplicationsConstraintsTests
589 + kNumberKeyUsageConstraintsTests
590 + kNumberAllowedErrorsTests
591 + kNumberMultipleConstraintsTests
592 + kNumberChangeConstraintsTests
593 + kNumberPolicyNamePinnningConstraintsTests
594 );
595
596 #if !TARGET_OS_IPHONE
597 if (getuid() != 0) {
598 printf("Test must be run as root on OS X");
599 return 0;
600 }
601 #endif
602
603 @autoreleasepool {
604 setup_globals();
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();
614 cleanup_globals();
615 }
616
617 return 0;
618 }