5

I use a NSURLSession in a NSURLProtocol for catching some traffic and channeling it through a proxy for UIWebView. When i browser HTTPS site which is having invalid certificate then UIWebView fails with:

Error Domain=NSURLErrorDomain Code=-1202 "The certificate for this server is invalid. You might be connecting to a server that is pretending to be “revoked.grc.com” which could put your confidential information at risk." UserInfo={NSURLErrorFailingURLPeerTrustErrorKey=, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, NSErrorFailingURLKey=, NSErrorFailingURLStringKey=, NSErrorPeerCertificateChainKey=( "", "" ), NSErrorClientCertificateStateKey=0, NSLocalizedDescription=The certificate for this server is invalid. You might be connecting to a server that is pretending to be “revoked.grc.com” which could put your confidential 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}

in iOS 9 and below but in iOS 10 it gives the following error:

Error Domain=kCFErrorDomainCFNetwork Code=310 "There was a problem communicating with the secure web proxy server (HTTPS)." UserInfo={NSErrorFailingURLStringKey=, NSErrorFailingURLKey=, _kCFStreamErrorCodeKey=-2096, _kCFStreamErrorDomainKey=4, NSLocalizedRecoverySuggestion=Please check your proxy settings. For help with this problem, contact your system administrator., NSLocalizedDescription=There was a problem communicating with the secure web proxy server (HTTPS).}

So in iOS 10 i am not able to figure-out the way for untrusted sites which are passing through proxy. If i browser a site with invalid certificate without proxy in NSURLProtocol(i.e. NSURLSession) then it also working fine in iOS 10.

Implementation of didReceiveChallenge delegate 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);

user1878752
  • 51
  • 1
  • 5

2 Answers2

2

You will get error code 310 if the underlying request accesses a certificate via proxy on iOS 10. Which means It's not secured to issue an HTTP request to get certificates via proxy. This happens when iOS needs to get or update an intermediate certificate, a standalone process securityd issues the request.

You should make the cert request go without proxy by:

  • Temporally turn off the proxy
  • Or mark any request ends with .crt not using proxy

Then you should get the right certificate and code will continue to run.

janlay
  • 441
  • 4
  • 12
0

If I connect to that host using openssl s_client, copy the certificate to a file, and run openssl x509 -in cert.crt -text -noout on that, I see this:

Signature Algorithm: sha1WithRSAEncryption

Support for SHA-1 certificates is deprecated in iOS 10, and requires an App Transport Security exception.

This means two things:

  • You should temporarily add an ATS exception to get your app running again.
  • You must replace that cert with one that does not use a SHA-1 signature ASAP.

That second step is very important. As I understand things, after 2016, you will not be allowed to submit new versions of your app that contain an ATS exception for SHA-1.

dgatwood
  • 10,129
  • 1
  • 28
  • 49
  • I have set ATS to true in my plist. NSAppTransportSecurity NSAllowsArbitraryLoads – user1878752 Sep 20 '16 at 13:21
  • I'm out of ideas unless your proxy is rejecting the cert based on it having been revoked.... I would file a bug with Apple and see if they can make sense of it. – dgatwood Sep 21 '16 at 18:39
  • Thanks for reply, When you file a bug please post the link in comment. – user1878752 Sep 22 '16 at 06:10
  • didReceiveChallenge delegate method is being called properly in NSURLProtocol implementation. – user1878752 Sep 22 '16 at 06:17
  • I meant that *you* should file a bug. I don't have your code, so I can't file the bug. Hmm. Your didReceiveChallenge *is* getting called? Maybe there's a bug in your implementation of that method. Could you post a snippet? – dgatwood Sep 22 '16 at 06:20
  • @Wood, I posted code snippet, it is working fine without proxy in iOS 10. – user1878752 Sep 23 '16 at 06:10
  • Implementation looks okay to me. And you say it is getting called even with the proxy, but you're still getting this error? The error, BTW, is `_kCFStreamErrorHTTPSProxyFailure`, which indicates that the proxy did not return a 200 status code. See https://github.com/jmgao/CFNetwork/blob/master/HTTP/CFHTTPFilter.c for details. I would check the proxy's logs to see if it gives any additional info. My guess is that it is sending some header that tells the proxy to do additional verification, but also make sure other sites work through the proxy (i.e. that the proxy is trusted). – dgatwood Sep 23 '16 at 07:47
  • @wood, Other site(i.e. trusted) working fine with proxy. – user1878752 Sep 27 '16 at 05:39