Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS 11, 12, and 13 installed certificates not trusted automatically (self signed)

Tags:

ios

On our internal network, we use a self-signed CA certificate. This has worked fine for years, in both Safari and our iOS product, all the way through iOS 10. We simply install the CA certificate on any new device or simulator and everything works, even with ATS. This allows access to all of our internal test servers without having to trust each server individually.

Starting with iOS 11 the installed CA certificate no longer allows Safari or our app to trust the certificate for any of the servers. We receive the following relevant details with CFNETWORK_DIAGNOSTICS enabled for our app:

Error Domain=kCFErrorDomainCFNetwork Code=-1200
_kCFNetworkCFStreamSSLErrorOriginalValue=-9802
_kCFStreamErrorDomainKey=3
_kCFStreamErrorCodeKey=-9802
NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made.
NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?

I spent considerable time trying to resolve this issue, scouring StackOverflow and the rest of the web. Although we use AFNetworking in our app, that seems to be irrelevant, as Safari no longer trusts these servers via the CA. Disabling ATS via NSAllowsArbitraryLoads allows access to the servers, but obviously isn't a solution.

No changes have been made to our -URLSession:didReceiveChallenge:completionHandler code, and we have a proper (worked for years) implementation of challenge response via challenge.protectionSpace.serverTrust.

I have re-evaluated and tested both the CA and server certificates every way I can think of, and they work everywhere except iOS 11. What might have changed in ATS for iOS 11 that could cause this issue?

like image 308
MattP Avatar asked Jul 06 '17 15:07

MattP


People also ask

How do you fix the certificate is not trusted because it is self-signed?

You need to import the root certificate into the trust store for the browser. Once the browser knows you trust this root certificate, all certificates signed by this will show up as trusted.

How do I force my iPhone to trust a certificate?

If you want to turn on SSL/TLS trust for that certificate, go to Settings > General > About > Certificate Trust Settings. Under "Enable full trust for root certificates," turn on trust for the certificate. Apple recommends deploying certificates via Apple Configurator or Mobile Device Management (MDM).


3 Answers

While writing this question, I discovered the answer. Installing a CA from Safari no longer automatically trusts it. I had to manually trust it from the Certificate Trust Settings panel (also mentioned in this question).

enter image description here

I debated canceling the question, but I thought it might be helpful to have some of the relevant code and log details someone might be looking for. Also, I never encountered the issue until iOS 11. I even went back and reconfirmed that it automatically works up through iOS 10.

I've never needed to touch that settings panel before, because any installed certificates were automatically trusted. Maybe it will change by the time iOS 11 ships, but I doubt it. Hopefully this helps save someone the time I wasted.

If anyone knows why this behaves differently for some people on different versions of iOS, I'd love to know in comments.

Update 1: Checking out the first iOS 12 beta, it looks like things remain the same. This question/answer/comments are still relevant on iOS 12.

Update 2: Same solution seems to be needed on iOS 13 beta builds as well.

like image 125
MattP Avatar answered Oct 20 '22 04:10

MattP


I've been struggling with this for 3 days now while attempting to connect to a local API running Laravel valet. I finally figured it out. In my case I had to drag and drop over the LaravelValetCASelfSigned.pem file from ~/.config/valet/CA/LaravelValetCASelfSigned.pem

After verifying the installing within the simulator I had to go to Settings > About > Certificate Trust Settings > and Enable the Laravel Valet VA Self Signed CN

Finally working!!!

like image 8
Juan Rangel Avatar answered Oct 20 '22 05:10

Juan Rangel


Recommended solution is to install and trust a self-signed certificate (root). Assuming you created your own CA and the hierarchy of the certificated is correct you don't need to change the server trust evaluation. This is recommended because it doesn't require any changes in the code.

  1. Generate CA and the certificates (you can use openssl: Generating CA and self-signed certificates.
  2. Install root certificate (*.cer file) on the device - you can open it by Safari and it should redirect you to Settings
  3. When the certificated is installed, go to Certificate Trust Settings (Settings > General > About > Certificate Trust Settings) as in MattP answer.

If it is not possible then you need to change server trust evaluation.

More info in this document: Technical Q&A QA1948 HTTPS and Test Servers

like image 7
Michal Cichon Avatar answered Oct 20 '22 04:10

Michal Cichon