Search code examples
iosobjective-cnevpnmanager

Using NEVPNManager how do I set SharedSecretReference


So I am trying to use NEVPNManager to set up my VPN programtically. I'm stuck on the config and really confused as to what goes where.

The sharedSecretReference really trips me up. I've seen things elsewhere that said I need to be using the keychain, but how and why. I can connect to this VPN with about 6 options using it manually, so why do I need so much on here.

If you see anything else that I may be doing wrong please let me know. This is the exact code i'm using currently

    NEVPNProtocolIPSec *p = [[NEVPNProtocolIPSec alloc] init];
    p.username = [config objectForKey: @"username"];
    p.passwordReference = [config objectForKey: @"password"];
    p.serverAddress = [config objectForKey: @"ip"];
    p.localIdentifier = [config objectForKey: @"vpn"];
    p.remoteIdentifier = [config objectForKey: @"vpn"];
    p.useExtendedAuthentication = NO;
    p.authenticationMethod = NEVPNIKEAuthenticationMethodSharedSecret;   
    p.disconnectOnSleep = NO;

    p.sharedSecretReference = [config objectForKey: @"psk"];

Solution

  • What's import to understand is that you are giving NEVPNManager a configuration that it can use to start a VPN connection, even if your app in inactive (via the Settings app). The VPN manager needs to be able to fetch the secure data (shared secret or password) from the keychain without going through your app. To do that it uses a persistent reference to the secret in the keychain, not the secret itself. If you use a library like KeychainAccess it's easy to get this reference and set it:

    let keychain = Keychain()
    let persistentRefSharedSecret = keychain[attributes: "my_shared_secret"].persistentRef
    let persistentRefPassword = keychain[attributes: "my_password"].persistentRef
    
    ...
    
    p.sharedSecretReference = persistentRefSharedSecret
    p.passwordReference = persistentRefPassword