2

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?

Kevin Richardson
  • 3,592
  • 22
  • 14
  • Have you tried NSURLDownload since you added the NSURLConnection delegate methods? – dgatwood May 03 '16 at 07:27
  • I never did get self-signed + NSURLDownload working. The appropriate delegates simply didn't get called. I abandoned the NSURLDownload approach in favor of the more modern NSURLSession. – Kevin Richardson May 03 '16 at 15:38

0 Answers0