This is working for me. Pasted in below is some code that I used to verify it. You should be able to paste the code into a new command line tool project and call it from
main
.
Note If you put the code in an app, you’ll need to also disable ATS.
Note that
anarchistturtle.com
is my personal web server that just happens to be on my home network, and thus I can access it via its local name,
fluffy.local
. You’ll need to change the names to match your own setup.
IMPORTANT
anarchistturtle.com
has a TLS certificate issued by my own personal CA and thus, to run my test as is, you’d have to install that CA’s certificate.
My best guess as to what’s going on here is that your server has other trust issues, above and beyond that name. The Investigating Hard-To-Debug Trust Evaluation Failures section of TN2232 has other hints as to how to debug this.
Share and Enjoy
—
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"
@import Foundation;
@interface Main : NSObject <NSURLSessionDelegate>
@property (nonatomic, strong, readwrite) NSURLSession * session;
@end
@implementation Main
- (void)test {
NSURL * url;
NSURLRequest * request;
NSURLSessionConfiguration * config;
config = [NSURLSessionConfiguration defaultSessionConfiguration];
self.session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:nil];
url = [NSURL URLWithString:@"https://fluffy.local"];
request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60.0];
[[self.session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
#pragma unused(data)
#pragma unused(response)
if (error != nil) {
NSLog(@"transport error %@ / %d", error.domain, (int) error.code);
} else {
NSLog(@"success");
}
exit(0);
}] resume];
dispatch_main();
}
static BOOL evaluateTrust(SecTrustRef trust) {
OSStatus err;
SecTrustResultType result;
err = SecTrustEvaluate(trust, &result);
return (err == errSecSuccess) && ( (result == kSecTrustResultProceed) || (result == kSecTrustResultUnspecified) );
}
- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler {
#pragma unused(session)
NSLog(@"challenge %@", challenge.protectionSpace.authenticationMethod);
if ([challenge.protectionSpace.authenticationMethod isEqual:NSURLAuthenticationMethodServerTrust]) {
BOOL allow;
SecTrustRef trust;
trust = challenge.protectionSpace.serverTrust;
allow = evaluateTrust(trust);
if ( ! allow ) {
OSStatus err;
SecPolicyRef policy;
policy = SecPolicyCreateSSL(true, CFSTR("anarchistturtle.com"));
err = SecTrustSetPolicies(trust, policy);
if (err == errSecSuccess) {
allow = evaluateTrust(trust);
}
CFRelease(policy);
}
if (allow) {
completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:trust]);
} else {
completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);
}
} else {
completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);
}
}
@end