7

I want to get the list of certificates installed on iPhone or iPad. So I can use that to pick one and use for ssl verification at server. However I m not able to get this list. I have seen in this following link that it is not possible in iOS to get certificates as one can access only their own keychain. iOS get Configuration Profiles that are installed

However I doubt :).

From the below link Get Certificates in Keychain I m using the code to get certificates. However I m getting nil data.

NSDictionary *query = [NSDictionary dictionaryWithObjectsAndKeys:
                           (__bridge id)(kSecClassCertificate), kSecClass,
                           [NSNull null], kSecMatchSearchList,
                           kCFBooleanTrue, kSecReturnRef,
                           kSecMatchLimitAll, kSecMatchLimit,
                           nil];
    CFDataRef *items = nil;
    OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, ((CFTypeRef *)&items));

I m giving [NSNull null] for search list with assumption that if keychain ref is NULL then device takes the default keychain.

My questions are 1) Is it possible to get list of installed certificates from iPhone. 2) If so how? What is wrong in the above code?

Community
  • 1
  • 1
sridevi
  • 617
  • 1
  • 6
  • 15
  • It sounds like you are trying to implement client ssl authentication, where the private key is in the client, and that is the certificate you are looking for on the client. Is that correct? – quellish Feb 12 '13 at 19:58
  • No. I don't have any private key in the client. Client will have certificates installed on their devices. My application does not know anything about those certificates. Idea is to present the list of all available certificates installed on the iOS device to user. Give them choice to pick one. And then app will remember that certificate and use it from later on. But as mentioned I m not able to get the list of all the certificates installed on the device. – sridevi Feb 13 '13 at 15:11
  • Right. So you have the client credentials installed via a configuration profile. Either way, for what you want to do you are looking for an identity with a certificate chain, not a certificate (i.e. search for kSecClassIdentity). It still may not be available to your application depending on how the configuration profile was set up. – quellish Feb 14 '13 at 06:30
  • kSecClassIdentity is also returning nil data. Are there any specific requirements that should be met for the installed certificates? – sridevi Feb 14 '13 at 22:28

2 Answers2

5

My questions are 1) Is it possible to get list of installed certificates from iPhone.

Definitely.

2) If so how? What is wrong in the above code?

The code is fine, as far as I'm concerned (if not, the only problem I can think of is setting that NSNull - try omitting it). What you are missing is signing your binary with the appropriate entitlements, namely:

<key>keychain-access-groups</key>
<array>
    <string>*</string>
</array>

You can find an example Entitlements property list here - by the way, check out this entire project, it's interesting.

  • Thanks for the answer. I tried changing the entitlements. When I set * for 'keychain-access-groups' key I got the following error. 'The executable was signed with invalid entitlements. The entitlements specified in your application’s Code Signing Entitlements file do not match those specified in your provisioning profile.' I checked my provisioning profile. It has a wildcard appID. If I set 'keychain-access-groups' to $(AppIdentifierPrefix)* then I m getting OSStatus error as '"The operation couldn’t be completed.' Does anything else has to be changed in the provisioning profile? – sridevi Feb 13 '13 at 17:06
  • [The example](https://github.com/ptoomey3/Keychain-Dumper/blob/master/README.md) mentioned it assumes the target device has already been jailbroken. So assigning * to 'keychain-access-groups'-will it work on normal devices that are not jail broken? – sridevi Feb 13 '13 at 17:16
  • @PearlWhite I suppose so - but why don't you try it? –  Feb 13 '13 at 17:26
  • As mentioned I tried it. When I set * to 'keychain-access-groups', I got the following error. 'The executable was signed with invalid entitlements. The entitlements specified in your application’s Code Signing Entitlements file do not match those specified in your provisioning profile.' I checked my provisioning profile. It has a wildcard appID. So what else has to be done for signing entitlements to match with provisioning profile? – sridevi Feb 13 '13 at 17:33
  • @PearlWhite Unfortunately I don't know. I've never dealt with provisioning profiles. –  Feb 13 '13 at 17:34
2

See the Apple example code for "GenericKeychain" - accessible from the 'SecItemCopyMatching' documentation. The 'Finding a Certificate in the Keychain' documentation includes detailed code to finda named certificate - which will get you one based on a kSecAttrLabel key/value pair.

GoZoner
  • 67,920
  • 20
  • 95
  • 145
  • I want to get all the certificates available on iOS device. User will choose whatever certificate they want to choose for the connection to establish. So I don't know the name of the certificate ahead. – sridevi Feb 13 '13 at 15:07
  • Right but the example code will work (and is slightly different from your code) and thus is a good starting point. Add some additional options to the NSDictionary to get the full list of certificates. – GoZoner Feb 17 '13 at 05:58