5 // Created by Bailey Basile on 11/5/19.
8 #import <Foundation/Foundation.h>
10 #include <Security/SecPolicyPriv.h>
11 #include <utilities/SecCFWrappers.h>
13 #import "../TrustEvaluationTestHelpers.h"
14 #import "TrustEvaluationTestCase.h"
16 @interface SMIMEPolicyTests : TrustEvaluationTestCase
19 NSString *testDir = @"SMIMEPolicyTests-data";
20 const CFStringRef emailAddr = CFSTR("test@example.com");
22 @implementation SMIMEPolicyTests
26 id root = [self SecCertificateCreateFromResource:@"root" subdirectory:testDir];
27 NSArray *anchors = @[root];
28 CFRelease((SecCertificateRef)root);
32 - (NSDate *)verifyDate
34 return [NSDate dateWithTimeIntervalSinceReferenceDate:600000000.0]; // January 6, 2020 at 2:40:00 AM PST
37 - (bool)runTrustEvalForLeaf:(id)leaf policy:(SecPolicyRef)policy
39 TestTrustEvaluation *eval = [[TestTrustEvaluation alloc] initWithCertificates:@[leaf] policies:@[(__bridge id)policy]];
40 XCTAssertNotNil(eval);
41 [eval setAnchors:[self anchors]];
42 [eval setVerifyDate:[self verifyDate]];
43 return [eval evaluate:nil];
46 // MARK: Expiration tests
48 - (void)testCheckExpiration
50 SecPolicyRef policy = SecPolicyCreateSMIME(kSecAnyEncryptSMIME | kSecSignSMIMEUsage, emailAddr);
51 id leaf = [self SecCertificateCreateFromResource:@"email_protection" subdirectory:testDir];
52 XCTAssertNotNil(leaf);
55 TestTrustEvaluation *eval = [[TestTrustEvaluation alloc] initWithCertificates:@[leaf] policies:@[(__bridge id)policy]];
56 XCTAssertNotNil(eval);
57 [eval setAnchors:[self anchors]];
58 [eval setVerifyDate:[self verifyDate]];
59 XCTAssert([eval evaluate:nil]);
62 [eval setVerifyDate:[NSDate dateWithTimeIntervalSinceReferenceDate:630000000.0]]; // December 18, 2020 at 8:00:00 AM PST
63 XCTAssertFalse([eval evaluate:nil]);
65 CFReleaseNull(policy);
66 CFRelease((SecCertificateRef)leaf);
69 - (void)testIgnoreExpiration
71 SecPolicyRef policy = SecPolicyCreateSMIME(kSecAnyEncryptSMIME | kSecSignSMIMEUsage | kSecIgnoreExpirationSMIMEUsage, emailAddr);
72 id leaf = [self SecCertificateCreateFromResource:@"email_protection" subdirectory:testDir];
73 XCTAssertNotNil(leaf);
76 TestTrustEvaluation *eval = [[TestTrustEvaluation alloc] initWithCertificates:@[leaf] policies:@[(__bridge id)policy]];
77 XCTAssertNotNil(eval);
78 [eval setAnchors:[self anchors]];
79 [eval setVerifyDate:[self verifyDate]];
80 XCTAssert([eval evaluate:nil]);
83 [eval setVerifyDate:[NSDate dateWithTimeIntervalSinceReferenceDate:630000000.0]]; // December 18, 2020 at 8:00:00 AM PST
84 XCTAssert([eval evaluate:nil]);
86 CFReleaseNull(policy);
87 CFRelease((SecCertificateRef)leaf);
92 - (void)testNoEmailName
94 id leaf = [self SecCertificateCreateFromResource:@"no_name" subdirectory:testDir];
95 XCTAssertNotNil(leaf);
98 SecPolicyRef policy = SecPolicyCreateSMIME(kSecAnyEncryptSMIME | kSecSignSMIMEUsage, emailAddr);
99 XCTAssertFalse([self runTrustEvalForLeaf:leaf policy:policy]);
101 // Skip email name check
102 CFReleaseNull(policy);
103 policy = SecPolicyCreateSMIME(kSecAnyEncryptSMIME | kSecSignSMIMEUsage, NULL);
104 XCTAssert([self runTrustEvalForLeaf:leaf policy:policy]);
106 CFReleaseNull(policy);
107 CFRelease((SecCertificateRef)leaf);
110 - (void)testEmailNameSAN
112 id leaf = [self SecCertificateCreateFromResource:@"san_name" subdirectory:testDir];
113 XCTAssertNotNil(leaf);
116 SecPolicyRef policy = SecPolicyCreateSMIME(kSecAnyEncryptSMIME | kSecSignSMIMEUsage, emailAddr);
117 XCTAssert([self runTrustEvalForLeaf:leaf policy:policy]);
120 CFReleaseNull(policy);
121 policy = SecPolicyCreateSMIME(kSecAnyEncryptSMIME | kSecSignSMIMEUsage, CFSTR("wrong@example.com"));
122 XCTAssertFalse([self runTrustEvalForLeaf:leaf policy:policy]);
124 // Case-insensitive match
125 CFReleaseNull(policy);
126 policy = SecPolicyCreateSMIME(kSecAnyEncryptSMIME | kSecSignSMIMEUsage, CFSTR("TEST@example.com"));
127 XCTAssert([self runTrustEvalForLeaf:leaf policy:policy]);
129 CFReleaseNull(policy);
130 CFRelease((SecCertificateRef)leaf);
133 - (void)testEmailCommonName
135 id leaf = [self SecCertificateCreateFromResource:@"common_name" subdirectory:testDir];
136 XCTAssertNotNil(leaf);
138 // Address match but common name matches not supported
139 SecPolicyRef policy = SecPolicyCreateSMIME(kSecAnyEncryptSMIME | kSecSignSMIMEUsage, emailAddr);
140 XCTAssertFalse([self runTrustEvalForLeaf:leaf policy:policy]);
142 CFReleaseNull(policy);
143 CFRelease((SecCertificateRef)leaf);
146 - (void)testEmailAddressField
148 id leaf = [self SecCertificateCreateFromResource:@"email_field" subdirectory:testDir];
149 XCTAssertNotNil(leaf);
151 // Address match but subject name matches not supported
152 SecPolicyRef policy = SecPolicyCreateSMIME(kSecAnyEncryptSMIME | kSecSignSMIMEUsage, emailAddr);
153 XCTAssert([self runTrustEvalForLeaf:leaf policy:policy]);
156 CFReleaseNull(policy);
157 policy = SecPolicyCreateSMIME(kSecAnyEncryptSMIME | kSecSignSMIMEUsage, CFSTR("wrong@example.com"));
158 XCTAssertFalse([self runTrustEvalForLeaf:leaf policy:policy]);
160 // Case-insensitive match
161 CFReleaseNull(policy);
162 policy = SecPolicyCreateSMIME(kSecAnyEncryptSMIME | kSecSignSMIMEUsage, CFSTR("TEST@example.com"));
163 XCTAssert([self runTrustEvalForLeaf:leaf policy:policy]);
165 CFReleaseNull(policy);
166 CFRelease((SecCertificateRef)leaf);
172 id leaf = [self SecCertificateCreateFromResource:@"san_name" subdirectory:testDir];
173 XCTAssertNotNil(leaf);
175 // Look for sign KU (which allows unspecified KU)
176 SecPolicyRef policy = SecPolicyCreateSMIME(kSecSignSMIMEUsage, emailAddr);
177 XCTAssert([self runTrustEvalForLeaf:leaf policy:policy]);
179 // Look for sign KU or any encrypt KU
180 CFReleaseNull(policy);
181 policy = SecPolicyCreateSMIME(kSecSignSMIMEUsage | kSecAnyEncryptSMIME, emailAddr);
182 XCTAssert([self runTrustEvalForLeaf:leaf policy:policy]);
184 // Look for encrypt KU
185 CFReleaseNull(policy);
186 policy = SecPolicyCreateSMIME(kSecAnyEncryptSMIME, emailAddr);
187 XCTAssertFalse([self runTrustEvalForLeaf:leaf policy:policy]);
190 CFReleaseNull(policy);
191 policy = SecPolicyCreateSMIME(0, emailAddr);
192 XCTAssert([self runTrustEvalForLeaf:leaf policy:policy]);
194 CFReleaseNull(policy);
195 CFRelease((SecCertificateRef)leaf);
200 id leaf = [self SecCertificateCreateFromResource:@"digital_signature" subdirectory:testDir];
201 XCTAssertNotNil(leaf);
204 SecPolicyRef policy = SecPolicyCreateSMIME(kSecSignSMIMEUsage, emailAddr);
205 XCTAssert([self runTrustEvalForLeaf:leaf policy:policy]);
207 // Look for sign KU or any encrypt KU
208 CFReleaseNull(policy);
209 policy = SecPolicyCreateSMIME(kSecSignSMIMEUsage | kSecAnyEncryptSMIME, emailAddr);
210 XCTAssert([self runTrustEvalForLeaf:leaf policy:policy]);
212 // Look for encrypt KU
213 CFReleaseNull(policy);
214 policy = SecPolicyCreateSMIME(kSecAnyEncryptSMIME, emailAddr);
215 XCTAssertFalse([self runTrustEvalForLeaf:leaf policy:policy]);
217 CFReleaseNull(policy);
218 CFRelease((SecCertificateRef)leaf);
221 - (void)testNonRepudiationKU
223 id leaf = [self SecCertificateCreateFromResource:@"non_repudiation" subdirectory:testDir];
224 XCTAssertNotNil(leaf);
227 SecPolicyRef policy = SecPolicyCreateSMIME(kSecSignSMIMEUsage, emailAddr);
228 XCTAssertFalse([self runTrustEvalForLeaf:leaf policy:policy]);
230 // Look for sign KU or any encrypt KU
231 CFReleaseNull(policy);
232 policy = SecPolicyCreateSMIME(kSecSignSMIMEUsage | kSecAnyEncryptSMIME, emailAddr);
233 XCTAssertFalse([self runTrustEvalForLeaf:leaf policy:policy]);
236 CFReleaseNull(policy);
237 policy = SecPolicyCreateSMIME(0, emailAddr);
238 XCTAssert([self runTrustEvalForLeaf:leaf policy:policy]);
240 CFReleaseNull(policy);
241 CFRelease((SecCertificateRef)leaf);
244 - (void)testKeyEncipherKU
246 id leaf = [self SecCertificateCreateFromResource:@"key_encipher" subdirectory:testDir];
247 XCTAssertNotNil(leaf);
249 // Look for Key Encipher KU
250 SecPolicyRef policy = SecPolicyCreateSMIME(kSecKeyEncryptSMIMEUsage, emailAddr);
251 XCTAssert([self runTrustEvalForLeaf:leaf policy:policy]);
253 // Look for any encrypt KU
254 CFReleaseNull(policy);
255 policy = SecPolicyCreateSMIME(kSecAnyEncryptSMIME, emailAddr);
256 XCTAssert([self runTrustEvalForLeaf:leaf policy:policy]);
258 // Look for Data Encipher KU
259 CFReleaseNull(policy);
260 policy = SecPolicyCreateSMIME(kSecDataEncryptSMIMEUsage, emailAddr);
261 XCTAssertFalse([self runTrustEvalForLeaf:leaf policy:policy]);
263 CFReleaseNull(policy);
264 CFRelease((SecCertificateRef)leaf);
267 - (void)testDataEncipherKU
269 id leaf = [self SecCertificateCreateFromResource:@"data_encipher" subdirectory:testDir];
270 XCTAssertNotNil(leaf);
272 // Look for Data Encipher KU
273 SecPolicyRef policy = SecPolicyCreateSMIME(kSecDataEncryptSMIMEUsage, emailAddr);
274 XCTAssert([self runTrustEvalForLeaf:leaf policy:policy]);
276 // Look for any encrypt KU
277 CFReleaseNull(policy);
278 policy = SecPolicyCreateSMIME(kSecAnyEncryptSMIME, emailAddr);
279 XCTAssert([self runTrustEvalForLeaf:leaf policy:policy]);
281 // Look for Key Encipher KU
282 CFReleaseNull(policy);
283 policy = SecPolicyCreateSMIME(kSecKeyEncryptSMIMEUsage, emailAddr);
284 XCTAssertFalse([self runTrustEvalForLeaf:leaf policy:policy]);
286 CFReleaseNull(policy);
287 CFRelease((SecCertificateRef)leaf);
290 - (void)testKeyAgreementKU
292 id leaf = [self SecCertificateCreateFromResource:@"key_agreement" subdirectory:testDir];
293 XCTAssertNotNil(leaf);
295 // Look for Key Agreement Encrypt KU /* <rdar://57130017> */
296 SecPolicyRef policy = SecPolicyCreateSMIME(kSecKeyExchangeEncryptSMIMEUsage, emailAddr);
297 XCTAssert([self runTrustEvalForLeaf:leaf policy:policy]);
299 // Look for Key Agreement Decrypt KU /* <rdar://57130017> */
300 CFReleaseNull(policy);
301 policy = SecPolicyCreateSMIME(kSecKeyExchangeDecryptSMIMEUsage, emailAddr);
302 XCTAssert([self runTrustEvalForLeaf:leaf policy:policy]);
304 // Look for Key Agreement Both KU
305 CFReleaseNull(policy);
306 policy = SecPolicyCreateSMIME(kSecKeyExchangeBothSMIMEUsage, emailAddr);
307 XCTAssert([self runTrustEvalForLeaf:leaf policy:policy]);
309 // Look for Digital Signature KU
310 CFReleaseNull(policy);
311 policy = SecPolicyCreateSMIME(kSecSignSMIMEUsage, emailAddr);
312 XCTAssertFalse([self runTrustEvalForLeaf:leaf policy:policy]);
314 CFReleaseNull(policy);
315 CFRelease((SecCertificateRef)leaf);
318 - (void)testKeyAgreementEncipherOnlyKU
320 id leaf = [self SecCertificateCreateFromResource:@"key_agreement_encipher_only" subdirectory:testDir];
321 XCTAssertNotNil(leaf);
323 // Look for Key Agreement Encrypt KU
324 SecPolicyRef policy = SecPolicyCreateSMIME(kSecKeyExchangeEncryptSMIMEUsage, emailAddr);
325 XCTAssert([self runTrustEvalForLeaf:leaf policy:policy]);
327 // Look for Key Agreement Decrypt KU /* <rdar://57130017> */
328 CFReleaseNull(policy);
329 policy = SecPolicyCreateSMIME(kSecKeyExchangeDecryptSMIMEUsage, emailAddr);
330 XCTAssert([self runTrustEvalForLeaf:leaf policy:policy]);
332 // Look for Key Agreement Both KU
333 CFReleaseNull(policy);
334 policy = SecPolicyCreateSMIME(kSecKeyExchangeBothSMIMEUsage, emailAddr);
335 XCTAssert([self runTrustEvalForLeaf:leaf policy:policy]);
337 // Look for Digital Signature KU
338 CFReleaseNull(policy);
339 policy = SecPolicyCreateSMIME(kSecSignSMIMEUsage, emailAddr);
340 XCTAssertFalse([self runTrustEvalForLeaf:leaf policy:policy]);
342 CFReleaseNull(policy);
343 CFRelease((SecCertificateRef)leaf);
346 - (void)testKeyAgreementDecipherOnlyKU
348 id leaf = [self SecCertificateCreateFromResource:@"key_agreement_decipher_only" subdirectory:testDir];
349 XCTAssertNotNil(leaf);
351 // Look for Key Agreement Encrypt KU /* <rdar://57130017> */
352 SecPolicyRef policy = SecPolicyCreateSMIME(kSecKeyExchangeEncryptSMIMEUsage, emailAddr);
353 XCTAssert([self runTrustEvalForLeaf:leaf policy:policy]);
355 // Look for Key Agreement Decrypt KU
356 CFReleaseNull(policy);
357 policy = SecPolicyCreateSMIME(kSecKeyExchangeDecryptSMIMEUsage, emailAddr);
358 XCTAssert([self runTrustEvalForLeaf:leaf policy:policy]);
360 // Look for Key Agreement Both KU
361 CFReleaseNull(policy);
362 policy = SecPolicyCreateSMIME(kSecKeyExchangeBothSMIMEUsage, emailAddr);
363 XCTAssert([self runTrustEvalForLeaf:leaf policy:policy]);
365 // Look for Digital Signature KU
366 CFReleaseNull(policy);
367 policy = SecPolicyCreateSMIME(kSecSignSMIMEUsage, emailAddr);
368 XCTAssertFalse([self runTrustEvalForLeaf:leaf policy:policy]);
370 CFReleaseNull(policy);
371 CFRelease((SecCertificateRef)leaf);
374 - (void)testKeyAgreementBothKU
376 id leaf = [self SecCertificateCreateFromResource:@"key_agreement_encipher_decipher" subdirectory:testDir];
377 XCTAssertNotNil(leaf);
379 // Look for Key Agreement Encrypt KU
380 SecPolicyRef policy = SecPolicyCreateSMIME(kSecKeyExchangeEncryptSMIMEUsage, emailAddr);
381 XCTAssert([self runTrustEvalForLeaf:leaf policy:policy]);
383 // Look for Key Agreement Decrypt KU
384 CFReleaseNull(policy);
385 policy = SecPolicyCreateSMIME(kSecKeyExchangeDecryptSMIMEUsage, emailAddr);
386 XCTAssert([self runTrustEvalForLeaf:leaf policy:policy]);
388 // Look for Key Agreement Both KU
389 CFReleaseNull(policy);
390 policy = SecPolicyCreateSMIME(kSecKeyExchangeBothSMIMEUsage, emailAddr);
391 XCTAssert([self runTrustEvalForLeaf:leaf policy:policy]);
393 // Look for Digital Signature KU
394 CFReleaseNull(policy);
395 policy = SecPolicyCreateSMIME(kSecSignSMIMEUsage, emailAddr);
396 XCTAssertFalse([self runTrustEvalForLeaf:leaf policy:policy]);
398 CFReleaseNull(policy);
399 CFRelease((SecCertificateRef)leaf);
405 id leaf = [self SecCertificateCreateFromResource:@"digital_signature" subdirectory:testDir];
406 XCTAssertNotNil(leaf);
408 SecPolicyRef policy = SecPolicyCreateSMIME(kSecSignSMIMEUsage, emailAddr);
409 XCTAssert([self runTrustEvalForLeaf:leaf policy:policy]);
411 CFReleaseNull(policy);
412 CFRelease((SecCertificateRef)leaf);
417 id leaf = [self SecCertificateCreateFromResource:@"any_eku" subdirectory:testDir];
418 XCTAssertNotNil(leaf);
420 SecPolicyRef policy = SecPolicyCreateSMIME(kSecSignSMIMEUsage, emailAddr);
421 XCTAssertFalse([self runTrustEvalForLeaf:leaf policy:policy]);
423 CFReleaseNull(policy);
424 CFRelease((SecCertificateRef)leaf);
429 id leaf = [self SecCertificateCreateFromResource:@"email_protection" subdirectory:testDir];
430 XCTAssertNotNil(leaf);
432 SecPolicyRef policy = SecPolicyCreateSMIME(kSecSignSMIMEUsage, emailAddr);
433 XCTAssert([self runTrustEvalForLeaf:leaf policy:policy]);
435 CFReleaseNull(policy);
436 CFRelease((SecCertificateRef)leaf);