I am using NSURLSession in NSURLProtocol to capture some traffic and pass it through a proxy for UIWebView. When on an HTTPS browser website that has an invalid certificate, UIWebView fails with:
Domain Error = NSURLErrorDomain Code = -1202 "The certificate for this server is not valid. You may be connecting to a server that is pretending to be" revoked.grc.com ", which could compromise your sensitive information." UserInfo = {NSURLErrorFailingURLPeerTrustErrorKey =, NSLocalizedRecoverySuggestion = Would you like to connect to the server in any case ?, NSErrorFailingURLKey =, NSErrorFailingURLStringKey =, NSErrorPeerCertificateChainKateClientNice = Native () to a server that pretends to be “revoked.grc.com”, which could put your sensitive information at risk., _kCFStreamErrorDomainKey = 3,NSUnderlyingError = 0x170255420 {Error Domain = kCFErrorDomainCFNetwork Code = -1202 "(null)" UserInfo = {_ kCFStreamPropertySSLClientCertificateState = 0, kCFStreamPropertySSLPeerTrust =, _kCFNetworkCFStreamSSLErrorOriginalValue = -9807, _kCFStreamErrorDomainKey = 3, _kCFStreamErrorCodeKey = -9807, kCFStreamPropertySSLPeerCertificates = ( "," ") }}, _kCFStreamErrorCodeKey = -9807}
on iOS 9 and below, but on iOS 10 it gives the following error:
Domain Error = kCFErrorDomainCFNetwork Code = 310 "Failed to contact secure web proxy server (HTTPS)." UserInfo = {NSErrorFailingURLStringKey =, NSErrorFailingURLKey =, _kCFStreamErrorCodeKey = -2096, _kCFStreamErrorDomainKey = 4, NSLocalizedRecoverySuggestion = Check the proxy settings. For help with this issue, contact your system administrator. NSLocalizedDescription = Failed to contact Secure Web Proxy (HTTPS).}
So, in iOS 10, I cannot find a way for untrusted sites that go through proxies. If I browse a site with an invalid certificate without a proxy server in NSURLProtocol (i.e. NSURLSession), it also works fine in iOS 10.
Implementation of the didReceiveChallenge delegation method.
AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
if([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]){
SecTrustRef trust = [[challenge protectionSpace] serverTrust];
SecCertificateRef cert = SecTrustGetCertificateAtIndex(trust, 0);
if ([[appDelegate certStore] containsCertificate:cert]) {
completionHandler(NSURLSessionAuthChallengeUseCredential,[NSURLCredential credentialForTrust:trust]);
return;
}
}
completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);