Get list of the all the certificates installed in iOS device

I am trying to use the following code to read the certificates, I tried from the app and the extension, but always getting errSecItemNotFound(-25300), any help would be greatly appreciated.


NSMutableDictionary* query = [[NSMutableDictionaryalloc] initWithObjectsAndKeys:
(_bridgeid)kSecClassCertificate, (_bridgeid)kSecClass,
(_bridgeid)kCFBooleanTrue, (_bridgeid)kSecReturnAttributes,
(_bridgeid)kSecMatchLimitAll, (_bridgeid)kSecMatchLimit,
@"com.apple.managed.vpn.shared", kSecAttrAccessGroup,
nil];

CFTypeRef result = NULL;
OSStatus status = SecItemCopyMatching((__bridgeCFDictionaryRef)query, &result);

if (status == errSecItemNotFound)

{ … }

Updated the above query using kSecClassIdentity. Still no luck.

Replies

In general there’s no way to get a list of certificates (well, what you’re looking for here is actually digital identities) installed on the device. QA1745 Making Certificates and Keys Available To Your App explains why that’s so.

However, if you have Network Extension special entitlements then you can get access to digital identities installed via the same configuration profile that created your Network Extension configuration. Three things:

  • You shouldn’t need to specify

    kSecAttrAccessGroup
    here;
    kSecMatchLimitAll
    will search across all available keychain access groups.
  • The digital identity has to be installed via your configuration profile for it to go into

    com.apple.managed.vpn.shared
    .
  • You should dump the entitlements of your app (

    .app
    ) and your extension (
    .appex
    ) (see Debugging Entitlement Issues) to make sure that the
    keychain-access-groups
    of your those executables lists
    com.apple.managed.vpn.shared
    . Make sure to dump the entitlements of the built executables because that is what the system is paying attention to.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Hi,

I'm try to read certificate from my VPN configuration profile. But only generic password can be read from the keychain group of "com.apple.managed.vpn.shared". My configuration profile is as below, is it right? Thanks!


<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE plist PUBLIC "-/

<plist version="1.0">

<dict>

<key>PayloadContent</key>

<array>

<dict>

<key>IPv4</key>

<dict>

<key>OverridePrimary</key>

<integer>0</integer>

</dict>

<key>PayloadDescription</key>

<string>Per App Configuration</string>

<key>PayloadDisplayName</key>

<string>Per App VPN Configuration</string>

<key>PayloadIdentifier</key>

<string>com.apple.vpn.managed.applayer.2AF4F414-C088-4BFB-BF5E-9C2E89F80FF8</string>

<key>PayloadOrganization</key>

<string>My Inc.</string>

<key>PayloadType</key>

<string>com.apple.vpn.managed.applayer</string>

<key>PayloadUUID</key>

<string>2AF4F414-C088-4BFB-BF5E-9C2E89F80FF8</string>

<key>PayloadVersion</key>

<integer>1</integer>

<key>Proxies</key>

<dict>

<key>HTTPEnable</key>

<integer>0</integer>

<key>HTTPSEnable</key>

<integer>0</integer>

</dict>

<key>UserDefinedName</key>

<string>Per-App SSL VPN</string>

<key>VPN</key>

<dict>

<key>ProviderType</key>

<string>packet-tunnel</string>

<key>RemoteAddress</key>

<string>10.4.130.2</string>

<key>AuthName</key>

<string>z001</string>

<key>AuthPassword</key>

<string>a</string>

<key>AuthenticationMethod</key>

<string>Certificate</string>

<key>OnDemandMatchAppEnabled</key>

<true/>

</dict>

<key>VPNSubType</key>

<string>net.mycopany.iOSVPNTunnel</string>

<key>VPNType</key>

<string>VPN</string>

<key>VPNUUID</key>

<string>C5F8AE81-0664-4269-A10D-5493D067B7E1</string>

<key>VendorConfig</key>

<dict/>

</dict>

<dict>

<key>Password</key>

<string>aaa</string>

<key>PayloadCertificateFileName</key>

<string>z001.p12</string>

<key>PayloadContent</key>

<data>

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

</data>

<key>PayloadDescription</key>

<string>PKCS#12 Cert</string>

<key>PayloadDisplayName</key>

<string>z001.p12</string>

<key>PayloadIdentifier</key>

<string>com.apple.security.pkcs12.2412CDEF-1BE7-4AB8-8D37-D2B6FF2D9C66</string>

<key>PayloadType</key>

<string>com.apple.security.pkcs12</string>

<key>PayloadUUID</key>

<string>2412CDEF-1BE7-4AB8-8D37-D2B6FF2D9C66</string>

<key>PayloadVersion</key>

<integer>1</integer>

</dict>

</array>

<key>PayloadDisplayName</key>

<string>SSL VPN Configuration</string>

<key>PayloadIdentifier</key>

<string>macbookair.local.9B230A95-6ABC-42D4-85F5-45FD9044BFF4</string>

<key>PayloadOrganization</key>

<string>My Inc</string>

<key>PayloadRemovalDisallowed</key>

<false/>

<key>PayloadType</key>

<string>Configuration</string>

<key>PayloadUUID</key>

<string>7F01BC42-7E0D-438B-9DA6-3349B1804104</string>

<key>PayloadVersion</key>

<integer>1</integer>

</dict>

</plist>

Have you confirmed that your

.app
and your
.appex
both have the
com.apple.managed.vpn.shared
keychain access group entitlement?

Also, I tried poking around in the profile you posted but I couldn’t access the PKCS#12 data because the password you listed (

aaa
) isn’t correct. Is that the actual password? Or a dummy you inserted for the benefit of this post? It’d be helpful if you posted the actual password.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

eskimo,


Thanks for your rapid reply!

My issue has been resolved since I added the "PayloadCertificateUUID" key in to my profile under the "VPN" payload.

The password is a dummy because of the certificate is a real certificate of mine.

Thank you very much!

Hi eskimo,


Can you please confirm that the app in fact can access installed identities (along with certificate details) provided it has its keychain-access-group entitlement contains com.apple.managed.vpn.shared.


My issue is that when trying to enumerate the certificates using the code similar cited by the thread-starter, I get the same errSecItemNotFound(-25300). I also see the problem when the VPN configuration is imported by a configuration profile: the passwordReference is assigned properly, but identityReference is nil in the protocol configuration object.


Is there something else I might look for besides the entitlements configuration?


Thanks,

Dmitry

This should work. The gotchas I’m aware of are:

  • You have to make sure that your

    .app
    and your
    .appex
    both have the
    com.apple.managed.vpn.shared
    keychain access group entitlement; you should check the built binaries rather than just your
    .entitlements
    file

    Note You can find instructions for doing that in Technote 2415 Entitlements Troubleshooting.

  • The same profile has to install both the VPN payload (

    com.apple.vpn.managed
    ) and the certificate payload (
    com.apple.security.pkcs12
    )

If that doesn’t fix things, you should open a DTS tech support incident so I can look at your setup in detail.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"