Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Keychain references in Swift used in NEVPNManager

I'm trying to connect to a VPN using Swift in Xcode. I'm using KeychainSwift to keep keychain references. My code looks like this:

    private func connectVPN(completion: @escaping () -> Void) { 
        let keychain = KeychainSwift()
        keychain.set("<mypassword>", forKey: "passref")
        keychain.set("<sharedsecretpassword>", forKey: "secretref")

        NEVPNManager.shared().loadFromPreferences { error in
            let vpnhost = "<11.11.11.11>"
            let username = "<myusername>"

            let p = NEVPNProtocolIPSec()
            p.username = username
            p.localIdentifier = username
            p.serverAddress = vpnhost
            p.remoteIdentifier = vpnhost
            p.authenticationMethod = .sharedSecret
            p.disconnectOnSleep = false

            p.sharedSecretReference = keychain.getData("secretref")
            p.passwordReference = keychain.getData("passref")

            var rules = [NEOnDemandRule]()
            let rule = NEOnDemandRuleConnect()
            rule.interfaceTypeMatch = .any
            rules.append(rule)

            NEVPNManager.shared().localizedDescription = "My VPN"
            NEVPNManager.shared().protocolConfiguration = p
            NEVPNManager.shared().onDemandRules = rules
            NEVPNManager.shared().isOnDemandEnabled = true
            NEVPNManager.shared().isEnabled = true
            NEVPNManager.shared().saveToPreferences { error in
                if (error != nil) {
                    print(error!)
                } else {
                    do {
                        try NEVPNManager.shared().connection.startVPNTunnel()
                        completion()
                    } catch {
                        print("can't connect VPN'")
                    }
                }
            }
        }
    }

I'm using keychain.getData("secretref"), because this field needs

A persistent keychain reference to a keychain item containing the IKE shared secret.

What's more,

The persistent keychain reference must refer to a keychain item of class kSecClassGenericPassword.

I'm not really sure, if I'm doing it right. I didn't subclass kSecClassGenericPassword or use it in any way.

When I'm using this function in code, a window shows with information, that there is no shared secret for this VPN. I think it means that this keychain doesn't work as it's supposed to.

In iPhone settings, it tries to connect, moves switch towards green and instantly the switch goes back to "off" state. When I put the same data as in code manually, the connection works.

What am I doing wrong? What should I correct?

like image 251
Bartosz Woźniak Avatar asked Aug 11 '17 15:08

Bartosz Woźniak


1 Answers

Okay, I have the answer. In the query for the SecItemCopyMatching, I had to choose kSecReturnPersistentRef with kCFBooleanTrue - not kSecReturnData.

like image 106
Bartosz Woźniak Avatar answered Oct 22 '22 08:10

Bartosz Woźniak