Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enumerate all Keychain items in my iOS application

What's the easiest way to programmatically (from within my app) get all items stored in the keychain?

It probably has something to do with SecItemCopyMatching(), but the documentation for that function is not very clear (and I failed to find a decent sample on the web).

like image 610
noamtm Avatar asked Jun 10 '12 07:06

noamtm


People also ask

What are keychain items?

Embed confidential information in items that you store in a keychain.

What is a keychain in IOS?

With iCloud Keychain, you can keep your passwords and other secure information updated across your devices. iCloud Keychain remembers things, so that you don't have to. It auto-fills your information—like your Safari usernames and passwords, credit cards, and Wi-Fi passwords on any device that you approve.

What is keychain on app?

android.security.KeyChain. The KeyChain class provides access to private keys and their corresponding certificate chains in credential storage. Applications accessing the KeyChain normally go through these steps: Receive a callback from an X509KeyManager that a private key is requested.

How do I access keychain on my iPhone?

To enable Keychain on your iPhone or iPad, go to Settings. Tap your name at the top of the screen and then select iCloud. At the iCloud screen, tap the setting for Keychain and then turn on its switch (Figure A). Next, navigate back to the main Settings screen and then tap the option for Passwords & Accounts.


1 Answers

SecItemCopyMatching is the right call for that. First we build our query dictionary so that the items' attributes are returned in dictionaries, and that all items are returned:

NSMutableDictionary *query = [NSMutableDictionary dictionaryWithObjectsAndKeys:     (__bridge id)kCFBooleanTrue, (__bridge id)kSecReturnAttributes,     (__bridge id)kSecMatchLimitAll, (__bridge id)kSecMatchLimit,     nil]; 

As SecItemCopyMatching requires at least the class of the returned SecItems, we create an array with all the classes…

NSArray *secItemClasses = [NSArray arrayWithObjects:                            (__bridge id)kSecClassGenericPassword,                            (__bridge id)kSecClassInternetPassword,                            (__bridge id)kSecClassCertificate,                            (__bridge id)kSecClassKey,                            (__bridge id)kSecClassIdentity,                            nil]; 

...and for each class, set the class in our query, call SecItemCopyMatching, and log the result.

for (id secItemClass in secItemClasses) {     [query setObject:secItemClass forKey:(__bridge id)kSecClass];      CFTypeRef result = NULL;     SecItemCopyMatching((__bridge CFDictionaryRef)query, &result);     NSLog(@"%@", (__bridge id)result);     if (result != NULL) CFRelease(result); } 

In production code, you should check that the OSStatus returned by SecItemCopyMatching is either errSecItemNotFound (no items found) or errSecSuccess (at least one item was found).

like image 169
Tammo Freese Avatar answered Nov 03 '22 08:11

Tammo Freese