NEAppProxyProvider VPN and self signed certificates

HI,


We have NEAppProxyProvider VPN client deployed and the VPN server is using the self signed certificate. We install this server self signed certificate on devices using MDM. In this case TLS handshake still fails saying "Invalid Certificate Chain" so we have couple of questions here:

1. Should self signed certs not work with TLS handshake if installed by MDM?

2. If this fails for self signed certificates would the same use case still fail with enterprise CA (issuing the VPN server cert) deployed by MDM?


Is it recommended to override the TLS chain validation here and set the "SecTrustSetAnchorCertificates" in the both cases but how can we read those custom CAs from keychain in that case? Any suggestions?

Accepted Reply

Honestly, I don’t have an answer for you here. This is one of the reasons why I recommend against using self-signed certificates: The semantics of trust evaluation start getting very squidgy. For example, at one point in the past the scenario you’ve described would only pass trust evaluation if the self-signed certificate had a Basic Constraints extension that indicated that it was a CA. It seems that things have changed since then but *shrug*

If you’re dealing with self-signed certificates, there seems little point in involving the entire trust evaluation machinery. You can just check the leaf certificate to see if it’s the certificate you expect.

However, my general advice is to not do this, but instead avoid self-signed stuff completely.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Replies

I’m not going to answer your specific questions, but instead focus on best practices. Apple generally recommends that you configure your VPN server to use a CA-issued certificate that’s trusted by default. This avoids the need for any extra customisation, and enables additional security checks, most notably certificate transparency.

If you’re deploying to an enterprise environment, it’s reasonable to set up an enterprise CA, have it issue a certificate for your server, and then install the enterprise CA’s root certificate on your device via MDM.

We specifically recommend against:

  • Self-signed certificates (except insofar as your enterprise CA’s root certificate is self-signed)

  • Customising TLS server trust evaluation

If push comes to shove it’s possible to use these techniques, but it’s generally best to stick to the best practices discussed above.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks Quinn as always.


So one more question about the usage and observation of "SecTrustSetAnchorCertificates()" API, one thing which we observed is that if we add the lead certificate of the server certification keychain to the "SecTrustSetAnchorCertificates()" and then run "SecTrustEvaluate()" it always "passes" irrespective of the cert being not self-signed with resultType set to "kSecTrustResultUnspecified".


Is this expected behavior? Or "kSecTrustResultUnspecified " indicates some mistrust in this case? As we would expect it to fail as there is no true Anchor certificate added to the list and also there is no CA installed on the device in this case being third party CA.



In the Console logs for "trustd" at one point I see :


completed:  i: >, <cert(0x10100f000) s:="" <issuer=""> i: > > details: (
        {
    },
        {
        AnchorTrusted = 0;
    }
) result: 5

which makes sense but suddenly the result is overriden and set to :


completed:  i: > > details: (
        {
    }
) result: 4


Thanks.

Honestly, I don’t have an answer for you here. This is one of the reasons why I recommend against using self-signed certificates: The semantics of trust evaluation start getting very squidgy. For example, at one point in the past the scenario you’ve described would only pass trust evaluation if the self-signed certificate had a Basic Constraints extension that indicated that it was a CA. It seems that things have changed since then but *shrug*

If you’re dealing with self-signed certificates, there seems little point in involving the entire trust evaluation machinery. You can just check the leaf certificate to see if it’s the certificate you expect.

However, my general advice is to not do this, but instead avoid self-signed stuff completely.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"