2 * Copyright (c) 2018 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
24 #include <AssertMacros.h>
25 #import <Foundation/Foundation.h>
28 #import <archive_entry.h>
30 #include <Security/SecCertificate.h>
31 #include <Security/SecCertificatePriv.h>
32 #include <Security/SecPolicyPriv.h>
33 #include <Security/SecTrustPriv.h>
34 #include <Security/SecItem.h>
35 #include <utilities/SecCFWrappers.h>
37 #import "TrustEvaluationTestCase.h"
38 #include "NameConstraintsTests_data.h"
39 #include "../TestMacroConversions.h"
41 @interface NameConstraintsTests : TrustEvaluationTestCase
44 @implementation NameConstraintsTests
46 - (void)testIntersectingConstraintsInSubCA {
47 SecCertificateRef root = NULL, subca = NULL, leaf1 = NULL;
48 NSArray *certs1 = nil, *test_anchors = nil;
49 SecPolicyRef policy = SecPolicyCreateBasicX509();
50 SecTrustRef trust = NULL;
51 NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:517282600.0]; // 23 May 2017
53 require_action(root = SecCertificateCreateWithBytes(NULL, _test_root, sizeof(_test_root)), errOut,
54 fail("Failed to create root cert"));
55 require_action(subca = SecCertificateCreateWithBytes(NULL, _test_intermediate, sizeof(_test_intermediate)), errOut,
56 fail("Failed to create subca cert"));
57 require_action(leaf1 = SecCertificateCreateWithBytes(NULL, _test_leaf1, sizeof(_test_leaf1)), errOut,
58 fail("Failed to create leaf cert 1"));
60 certs1 = @[(__bridge id)leaf1, (__bridge id)subca];
61 test_anchors = @[(__bridge id)root];
63 /* Test multiple pre-pended labels and intersecting name constraints in the subCA */
64 require_noerr_action(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs1,
65 policy, &trust), errOut,
66 fail("Failed to create trust for leaf 1"));
67 require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut,
68 fail("Failed to set verify date"));
69 require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)test_anchors), errOut,
70 fail("Failed to set anchors"));
71 XCTAssert(SecTrustEvaluateWithError(trust, NULL), "evaluate trust");
77 CFReleaseNull(policy);
81 - (void) testNoPrePendedLabels {
82 SecCertificateRef root = NULL, subca = NULL, leaf2 = NULL;
83 NSArray *certs2 = nil, *test_anchors = nil;
84 SecPolicyRef policy = SecPolicyCreateBasicX509();
85 SecTrustRef trust = NULL;
86 NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:517282600.0]; // 23 May 2017
88 require_action(root = SecCertificateCreateWithBytes(NULL, _test_root, sizeof(_test_root)), errOut,
89 fail("Failed to create root cert"));
90 require_action(subca = SecCertificateCreateWithBytes(NULL, _test_intermediate, sizeof(_test_intermediate)), errOut,
91 fail("Failed to create subca cert"));
92 require_action(leaf2 = SecCertificateCreateWithBytes(NULL, _test_leaf2, sizeof(_test_leaf2)), errOut,
93 fail("Failed to create leaf cert 2"));
95 certs2 = @[(__bridge id)leaf2, (__bridge id)subca];
96 test_anchors = @[(__bridge id)root];
98 /* Test no pre-pended labels */
99 require_noerr_action(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs2,
100 policy, &trust), errOut,
101 fail("Failed to create trust for leaf 2"));
102 require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut,
103 fail("Failed to set verify date"));
104 require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)test_anchors), errOut,
105 fail("Failed to set anchors"));
106 XCTAssert(SecTrustEvaluateWithError(trust, NULL), "evaluate trust");
110 CFReleaseNull(subca);
111 CFReleaseNull(leaf2);
112 CFReleaseNull(policy);
113 CFReleaseNull(trust);
116 - (void) testDNSLookingCommonName {
117 SecCertificateRef root = NULL, subca = NULL, leaf3 = NULL;
118 NSArray *certs3 = nil, *test_anchors = nil;
119 SecPolicyRef policy = SecPolicyCreateBasicX509();
120 SecTrustRef trust = NULL;
121 NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:548800000.0]; // 23 May 2018
123 require_action(root = SecCertificateCreateWithBytes(NULL, _test_root, sizeof(_test_root)), errOut,
124 fail("Failed to create root cert"));
125 require_action(subca = SecCertificateCreateWithBytes(NULL, _test_intermediate, sizeof(_test_intermediate)), errOut,
126 fail("Failed to create subca cert"));
127 require_action(leaf3 = SecCertificateCreateWithBytes(NULL, _test_leaf3, sizeof(_test_leaf3)), errOut,
128 fail("Failed to create leaf cert 3"));;
130 certs3 = @[(__bridge id)leaf3, (__bridge id)subca];
131 test_anchors = @[(__bridge id)root];
133 /* Test DNS-looking Common Name */
134 require_noerr_action(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs3,
135 policy, &trust), errOut,
136 fail("Failed to create trust for leaf 3"));
137 require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut,
138 fail("Failed to set verify date"));
139 require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)test_anchors), errOut,
140 fail("Failed to set anchors"));
141 XCTAssert(SecTrustEvaluateWithError(trust, NULL), "evaluate trust");
145 CFReleaseNull(subca);
146 CFReleaseNull(leaf3);
147 CFReleaseNull(policy);
148 CFReleaseNull(trust);
151 #if !TARGET_OS_BRIDGE
152 - (void)testUserAnchorWithNameConstraintsPass {
153 SecCertificateRef subca = NULL, leaf1 = NULL;
154 NSArray *certs1 = nil;
155 SecPolicyRef policy = SecPolicyCreateBasicX509();
156 SecTrustRef trust = NULL;
157 NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:517282600.0]; // 23 May 2017
158 id persistentRef = nil;
160 require_action(subca = SecCertificateCreateWithBytes(NULL, _test_intermediate, sizeof(_test_intermediate)), errOut,
161 fail("Failed to create subca cert"));
162 require_action(leaf1 = SecCertificateCreateWithBytes(NULL, _test_leaf1, sizeof(_test_leaf1)), errOut,
163 fail("Failed to create leaf cert 1"));
165 certs1 = @[(__bridge id)leaf1, (__bridge id)subca];
166 persistentRef = [self addTrustSettingsForCert:subca]; // subCA has name constraints
167 require_noerr_action(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs1,
168 policy, &trust), errOut,
169 fail("Failed to create trust for leaf 1"));
170 require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut,
171 fail("Failed to set verify date"));
172 XCTAssert(SecTrustEvaluateWithError(trust, NULL), "evaluate trust");
173 [self removeTrustSettingsForCert:subca persistentRef:persistentRef];
175 CFReleaseNull(subca);
176 CFReleaseNull(leaf1);
177 CFReleaseNull(policy);
178 CFReleaseNull(trust);
182 - (void)testAppAnchorWithNameConstraintsPass {
183 SecCertificateRef subca = NULL, leaf1 = NULL;
184 NSArray *certs1 = nil, *test_anchors = nil;
185 SecPolicyRef policy = SecPolicyCreateBasicX509();
186 SecTrustRef trust = NULL;
187 NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:517282600.0]; // 23 May 2017
189 require_action(subca = SecCertificateCreateWithBytes(NULL, _test_intermediate, sizeof(_test_intermediate)), errOut,
190 fail("Failed to create subca cert"));
191 require_action(leaf1 = SecCertificateCreateWithBytes(NULL, _test_leaf1, sizeof(_test_leaf1)), errOut,
192 fail("Failed to create leaf cert 1"));
194 certs1 = @[(__bridge id)leaf1, (__bridge id)subca];
195 test_anchors = @[(__bridge id)subca]; // subCA has name constraints
197 require_noerr_action(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs1,
198 policy, &trust), errOut,
199 fail("Failed to create trust for leaf 1"));
200 require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut,
201 fail("Failed to set verify date"));
202 require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)test_anchors), errOut,
203 fail("Failed to set anchors"));
204 XCTAssert(SecTrustEvaluateWithError(trust, NULL), "evaluate trust");
206 CFReleaseNull(subca);
207 CFReleaseNull(leaf1);
208 CFReleaseNull(policy);
209 CFReleaseNull(trust);
212 #if !TARGET_OS_BRIDGE
213 - (void)testUserAnchorWithNameConstraintsFail {
214 SecCertificateRef subca = NULL, leaf4 = NULL;
215 NSArray *certs1 = nil;
216 SecPolicyRef policy = SecPolicyCreateBasicX509();
217 SecTrustRef trust = NULL;
218 NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:578000000.0]; // 23 May 2017
219 id persistentRef = nil;
221 require_action(subca = SecCertificateCreateWithBytes(NULL, _test_intermediate, sizeof(_test_intermediate)), errOut,
222 fail("Failed to create subca cert"));
223 require_action(leaf4 = SecCertificateCreateWithBytes(NULL, _test_leaf4, sizeof(_test_leaf4)), errOut,
224 fail("Failed to create leaf cert 4"));
226 certs1 = @[(__bridge id)leaf4, (__bridge id)subca];
227 persistentRef = [self addTrustSettingsForCert:subca]; // subCA has name constraints
228 require_noerr_action(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs1,
229 policy, &trust), errOut,
230 fail("Failed to create trust for leaf 4"));
231 require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut,
232 fail("Failed to set verify date"));
233 XCTAssertFalse(SecTrustEvaluateWithError(trust, NULL), "evaluate trust");
234 [self removeTrustSettingsForCert:subca persistentRef:persistentRef];
236 CFReleaseNull(subca);
237 CFReleaseNull(leaf4);
238 CFReleaseNull(policy);
239 CFReleaseNull(trust);
243 - (void)testAppAnchorwithNameContraintsFail {
244 SecCertificateRef subca = NULL, leaf4 = NULL;
245 NSArray *certs1 = nil, *test_anchors = nil;
246 SecPolicyRef policy = SecPolicyCreateBasicX509();
247 SecTrustRef trust = NULL;
248 NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:578000000.0]; // 23 May 2017
250 require_action(subca = SecCertificateCreateWithBytes(NULL, _test_intermediate, sizeof(_test_intermediate)), errOut,
251 fail("Failed to create subca cert"));
252 require_action(leaf4 = SecCertificateCreateWithBytes(NULL, _test_leaf4, sizeof(_test_leaf4)), errOut,
253 fail("Failed to create leaf cert 4"));
255 certs1 = @[(__bridge id)leaf4, (__bridge id)subca];
256 test_anchors = @[(__bridge id)subca]; // subCA has name constraints
258 require_noerr_action(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs1,
259 policy, &trust), errOut,
260 fail("Failed to create trust for leaf 4"));
261 require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut,
262 fail("Failed to set verify date"));
263 require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)test_anchors), errOut,
264 fail("Failed to set anchors"));
265 XCTAssertFalse(SecTrustEvaluateWithError(trust, NULL), "evaluate trust");
267 CFReleaseNull(subca);
268 CFReleaseNull(leaf4);
269 CFReleaseNull(policy);
270 CFReleaseNull(trust);
273 /* MARK: BetterTLS tests */
274 NSString *kSecTrustTestNameConstraintsResources = @"si-87-sectrust-name-constraints";
275 NSString *kSecTrustTestCertificates = @"TestCertificates";
276 NSString *kSecTrustTestIPAddress = @"52.20.118.238";
277 NSString *kSecTrustTestDNSAddress = @"test.nameconstraints.bettertls.com";
278 NSString *kSecTrustTestID = @"id";
279 NSString *kSecTrustTestDNSResult = @"dns";
280 NSString *kSecTrustTestIPResult = @"ip";
281 NSString *kSecTrustTestExpect = @"expect";
282 NSString *kSecTrustTestExpectFailure = @"ERROR";
283 NSString *kSecTrustTestExpectSuccess = @"OK";
284 NSString *kSecTrustTestExpectMaybeSuccess = @"WEAK-OK";
286 static NSArray *anchors = nil;
287 static NSURL *tmpCertsDir = nil;
289 - (NSArray*)getTestsArray {
290 NSURL *testPlist = nil;
291 NSDictionary *testsDict = nil;
292 NSArray *testsArray = nil;
294 testPlist = [[NSBundle bundleForClass:[self class]] URLForResource:@"debugging" withExtension:@"plist"
295 subdirectory:kSecTrustTestNameConstraintsResources];
297 testPlist = [[NSBundle bundleForClass:[self class]] URLForResource:@"expects" withExtension:@"plist"
298 subdirectory:kSecTrustTestNameConstraintsResources];
300 require_action_quiet(testPlist, exit,
301 fail("Failed to get tests plist from %@", kSecTrustTestNameConstraintsResources));
302 testsDict = [NSDictionary dictionaryWithContentsOfURL:testPlist];
303 require_action_quiet(testsDict, exit, fail("Failed to decode tests plist into dictionary"));
305 testsArray = testsDict[@"expects"];
306 require_action_quiet(testsArray, exit, fail("Failed to get expects array from test dictionary"));
307 require_action_quiet([testsArray isKindOfClass:[NSArray class]], exit, fail("expected array of tests"));
313 - (NSFileHandle *)openFileForWriting:(const char *)filename {
314 NSFileHandle *fileHandle = NULL;
315 NSURL *file = [NSURL URLWithString:[NSString stringWithCString:filename encoding:NSUTF8StringEncoding] relativeToURL:tmpCertsDir];
318 fd = open([file fileSystemRepresentation], O_RDWR | O_CREAT | O_TRUNC, 0644);
319 if (fd < 0 || (off = lseek(fd, 0, SEEK_SET)) < 0) {
320 fail("unable to open file for archive");
327 fileHandle = [NSFileHandle fileHandleForWritingToURL:file error:&error];
329 fail("unable to get file handle for %@\n\terror:%@", file, error);
335 - (BOOL)extract:(NSURL *)archive {
338 struct archive_entry *entry;
340 struct archive *a = archive_read_new();
341 archive_read_support_filter_all(a);
342 archive_read_support_format_tar(a);
343 r = archive_read_open_filename(a, [archive fileSystemRepresentation], 16384);
344 if (r != ARCHIVE_OK) {
345 fail("unable to open archive");
349 while((r = archive_read_next_header(a, &entry)) == ARCHIVE_OK) {
351 const char *filename = archive_entry_pathname(entry);
352 NSFileHandle *fh = [self openFileForWriting:filename];
354 size_t bufsize = 4192;
355 uint8_t *buf = calloc(bufsize, 1);
357 size = archive_read_data(a, buf, bufsize);
359 fail("failed to read %s from archive", filename);
366 [fh writeData:[NSData dataWithBytes:buf length:size]];
372 if (r != ARCHIVE_EOF) {
373 fail("unable to read archive header");
379 archive_read_free(a);
383 - (BOOL)untar_test_certs {
384 NSError *error = nil;
385 NSString* pid = [NSString stringWithFormat: @"tst-%d", [[NSProcessInfo processInfo] processIdentifier]];
386 NSURL* tmpPidDirURL = [[NSURL fileURLWithPath:NSTemporaryDirectory() isDirectory:YES] URLByAppendingPathComponent:pid isDirectory:YES];
387 tmpCertsDir = [tmpPidDirURL URLByAppendingPathComponent:kSecTrustTestNameConstraintsResources isDirectory:YES];
389 if (![[NSFileManager defaultManager] createDirectoryAtURL:tmpCertsDir
390 withIntermediateDirectories:NO
393 fail("unable to create temporary cert directory: %@", error);
397 NSURL *certs_tar = [[NSBundle bundleForClass:[self class]] URLForResource:kSecTrustTestCertificates withExtension:nil
398 subdirectory:kSecTrustTestNameConstraintsResources];
399 if(![self extract:certs_tar]) {
406 - (BOOL)extractLeaf:(NSString *)filename andAppendTo:(NSMutableArray *)certs {
407 NSString *fullFilename = [NSString stringWithFormat:@"%@.cer", filename];
408 NSURL *leafURL = [tmpCertsDir URLByAppendingPathComponent:fullFilename];
410 fail("Failed to get leaf certificate for test id %@", filename);
413 NSData *leafData = [NSData dataWithContentsOfURL:leafURL];
415 fail("Failed to get leaf certificate data for URL %@", leafURL);
418 SecCertificateRef cert = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)leafData);
420 fail("Failed to create leaf cert for %@", leafURL);
423 [certs addObject:(__bridge id)cert];
428 - (BOOL)extractChain:(NSString *)filename andAppendTo:(NSMutableArray *)certs {
429 NSString *fullFilename = [NSString stringWithFormat:@"%@.chain", filename];
430 NSURL *chainURL = [tmpCertsDir URLByAppendingPathComponent:fullFilename];
432 fail("Failed to get chain URL for %@", filename);
435 NSString *chain = [NSString stringWithContentsOfURL:chainURL encoding:NSUTF8StringEncoding error:nil];
437 fail("Failed to get chain for %@", chainURL);
441 NSString *pattern = @"-----BEGIN CERTIFICATE-----.+?-----END CERTIFICATE-----\n";
442 NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern
443 options:NSRegularExpressionDotMatchesLineSeparators|NSRegularExpressionUseUnixLineSeparators
445 [regex enumerateMatchesInString:chain options:0 range:NSMakeRange(0, [chain length])
446 usingBlock:^(NSTextCheckingResult * _Nullable result, NSMatchingFlags flags, BOOL * _Nonnull stop) {
447 NSString *certPEMString = [chain substringWithRange:[result range]];
448 NSData *certPEMData = [certPEMString dataUsingEncoding:NSUTF8StringEncoding];
449 SecCertificateRef cert = SecCertificateCreateWithPEM(NULL, (__bridge CFDataRef)certPEMData);
450 [certs addObject:(__bridge id)cert];
457 NSURL *rootURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"root" withExtension:@"cer"
458 subdirectory:kSecTrustTestNameConstraintsResources];
460 fail("Failed to get root cert");
463 NSData *rootData = [NSData dataWithContentsOfURL:rootURL];
464 SecCertificateRef root = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)rootData);
466 fail("failed to create root cert");
469 anchors = [NSArray arrayWithObject:(__bridge id)root];
474 - (BOOL) runTrustForCerts:(NSArray *)certs hostname:(NSString *)hostname {
475 if (!anchors && ![self getAnchor]) {
479 SecPolicyRef policy = SecPolicyCreateSSL(true, (__bridge CFStringRef)hostname);
480 SecTrustRef trust = NULL;
481 NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:531900000.0]; /* November 8, 2017 at 10:00:00 PM PST */
482 require_noerr_action(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trust), exit,
483 fail("Failed to create trust ref"));
484 require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)anchors), exit,
485 fail("Failed to add anchor"));
486 require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), exit,
487 fail("Failed to set verify date"));
488 result = SecTrustEvaluateWithError(trust, nil);
491 CFReleaseNull(policy);
492 CFReleaseNull(trust);
497 // Skip test on watchOS due to size constraints (rdar://66792084)
498 - (void) testBetterTLS {
499 NSArray<NSDictionary *> *testsArray = [self getTestsArray];
500 if([self untar_test_certs]) {
501 [testsArray enumerateObjectsUsingBlock:^(NSDictionary * _Nonnull testDict, NSUInteger idx, BOOL * _Nonnull stop) {
503 /* Get the certificates */
504 NSNumber *testNum = testDict[kSecTrustTestID];
505 NSString *fileName = [NSString stringWithFormat:@"%@",testNum];
506 NSMutableArray *certificates = [NSMutableArray array];
507 if (![self extractLeaf:fileName andAppendTo:certificates] || ![self extractChain:fileName andAppendTo:certificates]) {
511 /* Test DNS address */
512 NSDictionary *dnsDict = testDict[kSecTrustTestDNSResult];
513 BOOL result = [self runTrustForCerts:certificates hostname:kSecTrustTestDNSAddress];
514 NSString *dnsExpectedResult = dnsDict[kSecTrustTestExpect];
515 if ([dnsExpectedResult isEqualToString:kSecTrustTestExpectFailure]) {
517 "Test DNS id: %@. Expected %@. Got %d", testNum, dnsExpectedResult, result);
518 } else if ([dnsExpectedResult isEqualToString:kSecTrustTestExpectSuccess]) {
520 "Test DNS id: %@. Expected %@. Got %d", testNum, dnsExpectedResult, result);
521 } else if ([dnsExpectedResult isEqualToString:kSecTrustTestExpectMaybeSuccess]) {
522 /* These are "OK" but it's acceptable to reject them */
525 /* Test IP address */
526 NSDictionary *ipDict = testDict[kSecTrustTestIPResult];
527 result = [self runTrustForCerts:certificates hostname:kSecTrustTestIPAddress];
528 NSString *ipExpectedResult = ipDict[kSecTrustTestExpect];
529 if ([ipExpectedResult isEqualToString:kSecTrustTestExpectFailure]) {
531 "Test IP id: %@. Expected %@. Got %d", testNum, ipExpectedResult, result);
532 } else if ([ipExpectedResult isEqualToString:kSecTrustTestExpectSuccess]) {
534 "Test IP id: %@. Expected %@. Got %d", testNum, ipExpectedResult, result);
535 } else if ([ipExpectedResult isEqualToString:kSecTrustTestExpectMaybeSuccess]) {
536 /* These are "OK" but it's acceptable to reject them */
542 [[NSFileManager defaultManager] removeItemAtURL:tmpCertsDir error:nil];
544 #endif //!TARGET_OS_WATCH