I'm attempting to use NSURLDownload to download files from a web server with a self-signed certificate. This normally results in:
NSURLConnection/CFURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9812)
or similar.
According to the NSURLDownloadDelegate Protocol Reference, the following methods are supposed to be called during authentication:
- (BOOL)download:(NSURLDownload *)download canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
- (void)download:(NSURLDownload *)download didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
As mentioned in other SO answers, those methods can be used to allow the use of self-signed certificates. Unfortunately, they are not being called.
All other delegate methods work as expected.
Simplified code (not much to see here):
- (int)retrieve:(NSString *)urlString
{
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *theRequest = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
downloadComplete = false;
downloadSucceeded = true;
NSURLDownload *download = [[NSURLDownload alloc] initWithRequest:theRequest delegate:self];
if (!download) {
fprintf(stderr, "Download failed\n");
}
while ((downloadComplete == false) && [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]);
return (downloadSucceeded == true);
}
- (BOOL)download:(NSURLDownload *)download canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
NSLog(@"download:canAuthenticateAgainstProtectionSpace");
return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}
- (void)download:(NSURLDownload *)download didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
NSLog(@"download:didReceiveAuthenticationChallenge");
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
if([challenge.protectionSpace.host isEqualToString:@"myhost.mydomain.com"])
[challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
[challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}
I have worked around the issue by scrapping NSURLDownload
in favor of NSURLConnection
, but I'd still like to know what's going on. (The equivalent NSURLConnectionDelegate
methods are called as expected.)
Has anyone successfully used NSURLDownload
with self-signed certificates?