How to verify Let's Encrypt Cert with PersonalVPN

Hi


Goal: to build smoothest VPN user experience (1 tap) 🙂


I am attempting to build a VPN client for iOS using certificate based authentication. Authentication on the sever side is successful. However if i open the console to test device, I see this error.


failed to retrieve remote CA cert data by CN (Let’s Encrypt Authority X3)


Which is odd because we are using Let's Encrypt certs, of which the root (ISRG Root X1) is inhertly trusted by iOS. How can I verify this cert progmatticly so that the user can connect?


I tried:


func installRootCertificate() -> Bool {
        var result: UnsafeMutablePointer<Unmanaged<AnyObject>?>? = nil
        var error = noErr

        let rootCertPath = Bundle.main.path(forResource: "server", ofType: "der")!
        let rootCertData = NSData(contentsOfFile: rootCertPath)!
        let rootCert     = SecCertificateCreateWithData(kCFAllocatorDefault, rootCertData)

        let kSecClassValue            = NSString(format: kSecClass)
        let kSecClassCertificateValue = NSString(format: kSecClassCertificate)
        let kSecValueRefValue         = NSString(format: kSecValueRef)

        let foo = [ kSecClassValue: kSecClassCertificateValue,
                     kSecValueRefValue: rootCert.takeRetainedValue()] as CFDictionary

        error = SecItemAdd(foo, result)

        if(error == noErr)
        {
            print("Installed root certificate successfully");

            return true
        }
        else if(error == errSecDuplicateItem)
        {
            print("Duplicate root certificate entry");
        }
        else
        {
            print("Install root certificate failure")
        }

        return false
    }


Thanks so much!

Replies

Looking at the trusted root certificates on iOS 13 and macOS 10.15, ISRG Root X1 is there so there shouldn't be a need to install a root individually.


What process or app is the message from the console associated with? Are there any other associated messages before or after this message that provide more context?

| failed to retrieve remote CA cert data by CN (Let’s Encrypt Authority X3)



Matt Eaton

DTS Engineering, CoreOS

meaton3 at apple.com

meaton,


Thank you so much for responding! 🙂 I agree the ISRG Root x1 is preloaded, so the issue must be with the verifying that the particular cert we are using is signed by it (or rather by it's intermediate certs)


It is associated with NEIKEv2Provider (Network Extension)


Here is the full console log from app initiating the tunnel:

https://ibb.co/ySFs8Xb

https://ibb.co/PQ2Hv8C

https://ibb.co/Lz4M34r

https://ibb.co/2YCrvXh

I dug into this a bit deeper, and as the log messages indicate, the remote certificate authority reference is not being found when your IKEv2 configuration is loaded (Also, I am assuming this is IKEv2, please let me know if this is IPSec). That is why you are seeing this in the console:


Failed to retrieve remote CA cert data from CN
remoteCertAuthorityArray missing from the config
Certificate authentication data could not be verified.


As a test, try and manually install the missing certificate to see if this resolves the connection issue. If this does, then we will need to take a look at where installed certificates were missed during connection setup.


Matt Eaton

DTS Engineering, CoreOS

meaton3 at apple.com

Thanks for that!


Yes this is IKEv2 though PersonalVPN.


That precisely the issue--I have been unable to install the certificates during the connection setup. Can you help me with this?


When using the Apple VPN widget inside of the settings app--with the exact same configuration--and I can successfully connect. I manually install them and it works like a dream.


I really cannot overstate my appreciation for this help 🙂

No problem, glad to help.


Now that you have confirmed the problem, you can also deliver the desired root certificate via MDM payload if you have MDM setup. The key to take a look at would be com.apple.security.root. Here is the associated documentation.


Matt Eaton

DTS Engineering, CoreOS

meaton3 at apple.com

Is there another way to install the certificates without MDM? I am looking for more of a off the shelf, solution for our customers. MDM seems like I have the ability view and control too much of their device’s system. (If it’s the only way then fine) The issue is I have not found a way to install the certificate from inside the app. Even inside my current swift app setup, the remote dameon successfully authenticates the user and initiates the tunnel. The problem is on the swift side, the certificate is not trusted because it’s not installed.

Is there a way to do this? Can you help me?

For installing root certificates in a enterprise environment, MDM is the off the shelf solution to this. For a consumer environment you can look at using a VPN profile configuration using NETunnelProviderManager, but you will need to apply for the com.apple.managed.vpn.shared entitlement to do so.


If using NETunnelProviderManager is the desired course of action, take a look at number 9 on this forum post about moving forward with applying for this entitlement.


Matt Eaton

DTS Engineering, CoreOS

meaton3 at apple.com