iOS15, TLS trust failed for self-signed certificate

After starting using Xcode 13 beta(1 and 2) and iOS15 simulators we realized that we can't connect to our internal servers using https connection with self-signed certificate. We are receiving

NSUnderlyingError=0x600003f91e30 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, kCFStreamPropertySSLPeerTrust=<SecTrustRef: 0x6000000f4e60>, _kCFNetworkCFStreamSSLErrorOriginalValue=-9802, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802

At the moment we don't have any devices with iOS15 beta installed on them and couldn't confirm if issue reproduced there as well but using simulator or real devices with prior versions of iOS works without any issues and we are not sure if it's a bug in iOS15 beta builds or some new security restrictions for SSL/TLS connections or trusted connections. We are using certificate pinning(and including and using root certificate) and couldn't see any issues while validating SecTrust object after receiving challenge inside URLSessionDelegate

let host = challenge.protectionSpace.host

      guard challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust,
         let trust = challenge.protectionSpace.serverTrust
      else {
        completionHandler(.performDefaultHandling, nil)
        return
      }
       
      let policy = SecPolicyCreateSSL(true, host as CFString)
      let status = SecTrustSetPolicies(trust, policy)
      let pinCertificate = SecTrustSetAnchorCertificates(trust, certificates as CFArray)
      let onlyStatus = SecTrustSetAnchorCertificatesOnly(trust, true)
       
      var error: CFError?
      let isValidationSuccessful = SecTrustEvaluateWithError(trust, &error)
      if isValidationSuccessful {
        completionHandler(.useCredential, URLCredential(trust: trust))
      } else {
        completionHandler(.cancelAuthenticationChallenge, nil)
      }

Could someone clarify next questions:

  • What does 9802 error code actually mean? i found that it some kind of generic fatal error but it isn't useful information
  • Are there any new restrictions for self signed certificates or ssl/tls connections that will be introduced in iOS15?

What does 9802 error code actually mean? i found that it some kind of generic fatal error but it isn't useful information

A -9802 is a fatal SSL error, or errSSLFatalAlert. This means that there was a TLS problem when your client and server were setting up an encrypted connection.

Are there any new restrictions for self signed certificates or ssl/tls connections that will be introduced in iOS15?

I am not aware of any as I have tested with self signed certificates myself on iOS 15, but let's start with the basics; can you verify that you have the root certificate installed on the iOS 15 device and it is trusted on the device?

Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com

After a couple weeks of investigation we find out that it's something with PFS check, but at the same time all tests using ATS Diagnostics are passing without issues.

To be able to connect to our internal servers I've used next rules, where ****** is masked version of our internal domain

ATS Dictionary:
{
    NSExceptionDomains =     {
        "******" =         {
            NSExceptionRequiresForwardSecrecy = false;
        };
    };
}

So it seems for us that it is a bug

I have the same issue with iOS 15. Is there any solution how it can be fixed? For iOS 13 and 14 all works fine.

@Anastasiia_Zh

I have the same issue with iOS 15. Is there any solution how it can be fixed?

What specifically are you seeing?

Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com

Hi, i have the same issue with iOS 15.1 with a Iphone SE (1. G.). There is no button to confirm the certificate, only "Display" or "Cancel". It works with the Ipad (6. G. / iOS 15.1). Is there a fix or minimum a workaround to accept self signed certificates? Import and mark as general accepted in the settings doesn't work.

Thanks.

@corniki

Is there a fix or minimum a workaround to accept self signed certificates? Import and mark as general accepted in the settings doesn't work.

This is tricky because using self-signed certificates usually assumes that the user also has the complete chain of trust (root and any intermediates) installed on the device and trusted as well. So, these will need to be installed first, as explained here, and then if the connection is using a hostname, that is contained in the DNS name field of the self-signed leaf certificate, then trust is eligible for proceeding as usual. Otherwise, you will need to override trust evaluation and decide on whether you want to proceed on your own, and that can get ugly.

Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com

@p33yay

the “trust” button is missing on the pop up dialog box on my iPad ios15.1 and when I click the upper right area of the dialog box (where the ‘trust” button was on my iPhone (where no button is visible on ipad)) crashes ipad to home screen; any resolution yet?

You are mentioning that the trust dialog is gone on an iPad only when an untrusted certificate is encountered? Is it the first time the device has encountered this certificate? Are you performing any custom evaluation on this certificate, or the chain, that would result in a crash taking place?

Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com
iOS15, TLS trust failed for self-signed certificate
 
 
Q