I deployed a custom VPN configuration on the device alongwith a MDM certificate. The field "Identifier" of the VPN configuration has the value same as that of my app's bundle identifier so that my app uses that VPN profile for network extension. While establishing a vpn connection, I want to verify the MDM certificate that is deployed along with my vpn configuration. But, SecItemCopyMatching returns all the certificates present on the device and not just the one associated with my vpn configuration. Is there a way to filter the certificates based on the vpn profile that contains them?
Accepted Reply
Yes I do get the
but it is in theidentityReference
format.NSData
That’s expected. The data is a persistent reference to an item in the keychain, and you can find the underlying item with code like this:
let persistentRef: Data = …
var copyResult: CFTypeRef? = nil
let err = SecItemCopyMatching([
kSecValuePersistentRef: persistentRef,
kSecReturnRef: true
] as NSDictionary, ©Result)
guard err == errSecSuccess else {
… handle the error …
}
let identity = copyResult! as! SecIdentity
print(identity)
Share and Enjoy
—
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"
Replies
There’s four steps to make this work:
Your app must have access to the
keychain access group, as described in FAQ#9 in the Network Extension Framework Entitlements.com.apple.managed.vpn.shared
Your certificate payload (
) must be in the same configuration profile as the VPN payload (com.apple.security.pkcs12
orcom.apple.vpn.managed
).com.apple.vpn.managed.applayer
Your VPN payload must have
set toAuthenticationMethod
.Certificate
Your VPN payload must explicitly reference the certificate payload via the
property.PayloadCertificateUUID
With regards the last two points, the best way to make sure your VPN payload is set up correctly is to use Apple Configurator to create the profile, setting the VPN type to Custom SSL.
Share and Enjoy
—
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"
Thanks for the answer Eskimo. I can confirm that I have all of these setup correctly. Still, when I call SecItemCopyMatching, it returns all the certificates in the keychain. Is there any specific filter that I should add to the dictionary that I am passing in SecItemCopyMatching? Or is there a different method to fetch just the certificate associated with vpn profile?
Still, when I call SecItemCopyMatching, it returns all the certificates in the keychain.
Indeed. Sorry, I misread your original email.
Do you not get a reference to the right digital identity via the
identityReference
property of the
NETunnelProviderProtocol
object?
Share and Enjoy
—
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"
> Do you not get a reference to the right digital identity via the
identityReference
property of the NETunnelProviderProtocol
object?Yes I do get the identityReference but it is in the NSData format. What I need is a SecIdentityRef so that I can use all the apple-provided functions like SecIdentityCopyPrivateKey, SecIdentityCopyCertificate, SecKeyCreateSignature etc. Is there a way to get is in the SecIdentityRef format or convert what I get in NSData format into SecIdentityRef?
Yes I do get the
but it is in theidentityReference
format.NSData
That’s expected. The data is a persistent reference to an item in the keychain, and you can find the underlying item with code like this:
let persistentRef: Data = …
var copyResult: CFTypeRef? = nil
let err = SecItemCopyMatching([
kSecValuePersistentRef: persistentRef,
kSecReturnRef: true
] as NSDictionary, ©Result)
guard err == errSecSuccess else {
… handle the error …
}
let identity = copyResult! as! SecIdentity
print(identity)
Share and Enjoy
—
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"
Thanks Eskimo! This solved my issue.