Sunday, September 10, 2017

Keychain references in Swift used in NEVPNManager

Leave a Comment

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?

1 Answers

Answers 1

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

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment