iOS 13 - SecTrustEvaluate fails with kSecTrustResultRecoverableTrustFailure

Hi,


On iOS 13 when we evaluate the trust for self signed certificates it throws kSecTrustResultRecoverableTrustFailure however same url loads fine on Safari. And It seems to be happening only with third party apps, I've tested with my app and also using Chrome browser It throws "Connection is not private" error in both the apps but Safari loads the url properly.


Is this a Bug on iOS 13?


Note: Public certificates works fine. I do not observe the same error on iOS 12.


Regards,

Meera Mohideen

Replies

Are you checking with SecTrustEvaluate or SecTrustEvaluateAsync? Because they have been marked as deprecated. We are running into the same problem and are trying to use SecTrustEvaluateWithError instead.

Thanks Patrics for the reply.


Yes, we are using SecTrustEvaluate. I've tried with SecTrustEvaluateWithError as you suggested but it still fails with error "certificates do not meet pinning requirements", "SSL hostname does not match name(s) in certificate, Signature hash algorithm is not permitted for this use" I do not find any problem with host name as same certificate work fine on iOS 12

I am running into the same problem now 😟

Currently digging into it.


Update: Comparing common name of the index-0 certificate to the trusted domain entered into the SSL trust policy manually shows that they are equal.


Update 2: Further digging (including subjectAltName, CRL checks, etc.) did not bring up any success, so I am now manually comparing hostnames.

SecCertificateRef serverCert = SecTrustGetCertificateAtIndex(serverTrust, 0);
CFStringRef commonName;
SecCertificateCopyCommonName(serverCert, &commonName);
BOOL hostnameDoesMatch = [trustedHostname isEqualToString:(__bridge_transfer id)commonName];

To save everybody else from trying: Beta 2 shows the same behaviour.

Thank you for letting us know. I also facing this issue.

Further insight:

Regarding the domain verification: Apple seems to be following a security advice here (sorry, can't find the link at the moment) to ignore the CN field in the subject (which does not have any strictly defined semantics and may be used otherwise) and instead verify the domain against the "dNSName" entries in the "subjectAltName" extension.


So, if you are indeed verifying DNS names, your best bet would be to get the server to support this extension, because other clients are probably going to follow this advice, soon.


If you are verifying a specific, non-DNS string in the common name, use the snippet from my answer above 🙂

Although your certificate has "Common Name", it probably has no "Subject Alternative Name" extension. It turns out that using "Common Name" as host name was deprecated a long time ago.


> If a subjectAltName extension of type dNSName is present, that MUST

> be used as the identity. Otherwise, the (most specific) Common Name

> field in the Subject field of the certificate MUST be used. Although

> the use of the Common Name is existing practice, it is deprecated and

> Certification Authorities are encouraged to use the dNSName instead.

> -- https://tools.ietf.org/html/rfc6125


Google already added SAN requirement in Chrome browser in 2017. Looks like iOS 13 now requires "Subject Alternative Name" in order for the certificate to be valid. iOS 12 still uses "Common Name" in case of "Subject Alternative Name" being absent.

Apple has now published guidelines on these changes: https://support.apple.com/en-us/HT210176