I am working on an Networkextension using NEPacketTunnelProvider. I am using a configuration profile with com.apple.vpn.managed payload. Furthermore, I use ClientCertificate authentication with an com.apple.security.pkcs12 payload. According to NETunnelProviderManager documentation https://developer.apple.com/documentation/networkextension/netunnelprovidermanager#1661706 it should be possible for my extension to retrieve this identity using the com.apple.managed.vpn.shared keychain access group.
If I query the Keychain for the identity, I always get error code `-25300`. According to https://www.osstatus.com/search/results?platform=all&framework=all&search=-25300 this means: "The item cannot be found."
Code 1:
I try to use the persistent reference provided by the protocolConfiguration to retrieve the identity.
class PacketTunnelProvider: NEPacketTunnelProvider {
override func startTunnel(options: [String : NSObject]?, completionHandler: @escaping (Error?) -> Void) {
NSLog("vpn-service startTunnel")
let pc = self.protocolConfiguration
NSLog("vpn-service protocolConfiguration " + pc.debugDescription)
if let identity = pc.identityReference {
let persistentRef = identity as NSData
NSLog("vpn-service persistentRef " + persistentRef.description)
var copyResult: AnyObject?
let copyErr = SecItemCopyMatching([
kSecValuePersistentRef as String: persistentRef,
kSecReturnData as String: true
] as CFDictionary, ©Result)
NSLog("vpn-service getCert copyErr " + copyErr.description)
}
}
}
Output is:
Jul 27 10:07:53 Tims-iPhone vpn(libswiftFoundation.dylib)[4994] : vpn-service startTunnel
Jul 27 10:07:53 Tims-iPhone vpn(libswiftFoundation.dylib)[4994] : vpn-service protocolConfiguration
type = plugin
identifier = 3B39941E-AF39-45CE-B869-68AF392FBCA0
serverAddress = DEFAULT
password = {
domain = user
accessGroup = com.apple.managed.vpn.shared
}
identity = {
identifier =
persistentReference = <69646e74 00000000 00000011>
domain = user
}
identityDataImported = NO
identityReference = <69646e74 00000000 00000011>
proxySettings = {
autoProxyDiscovery = NO
autoProxyConfigurationEnabled = NO
HTTPEnabled = NO
HTTPSEnabled = NO
FTPEnabled = NO
SOCKSEnabled = NO
RTSPEnabled = NO
gopherEnabled = NO
excludeSimpleHostnames = NO
usePassiveFTP = YES
}
disconnectOnSleep = NO
disconnectOnIdle = NO
disconnectOnIdleTimeout = 0
disconnectOnWake = NO
disconnectOnWakeTimeout = 0
pluginType =
authenticationMethod = 1
Jul 27 10:07:53 Tims-iPhone vpn(libswiftFoundation.dylib)[4994] : vpn-service persistentRef <69646e74 00000000 00000011>
Jul 27 10:07:53 Tims-iPhone vpn(libswiftFoundation.dylib)[4994] : vpn-service getCert copyErr -25300
Code 2:
If I try to retrieve all identitys without the reference, I get `-25300` too.
let getQuery: [String: Any] = [
kSecClass as String: kSecClassIdentity,
kSecMatchLimit as String: kSecMatchLimitAll,
kSecReturnAttributes as String: true,
]
var item: CFTypeRef?
let status = SecItemCopyMatching(getQuery as CFDictionary, &item)
NSLog("vpn-service status: " + status.description)
I rechecked that the build result got the keychain access group:
codesign -d --ent :- build/Debug-iphoneos/agent.app/PlugIns/vpn.appex/
Result:
Executable=/Users/timb/projects/xcode/ios-client/build/Debug-iphoneos/agent.app/PlugIns/vpn.appex/vpn
application-identifier
com.apple.developer.networking.networkextension
com.apple.developer.team-identifier
get-task-allow
keychain-access-groups
.com.apple.managed.vpn.shared
How to get an identity for NEPacketTunnelProvider Networkextension from com.apple.managed.vpn.shared keychain access group?
Edit: According to https://forums.developer.apple.com/thread/67613 #9 I need a special entitlement to get com.apple.managed.vpn.shared keychain access group. I created a TSI to get this entitlement.