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