2

Please, help me resolve problem with enumerating keychain items in OS X. I read topic about enumerating all keychain items in my iOS application, but a want understand, how write the same code, which written in the topic with Core Foundation functions??? I tried to do that:

CFDictionaryRef query = CFDictionaryCreate ( kCFAllocatorDefault, NULL, NULL, 0, NULL, NULL);
CFTypeRef *result = NULL;

status = SecItemCopyMatching(query, result );
if (status != errSecSuccess)
{
    GetLastError(status);
}

But this code didn't work! Could you help me understand, where I was wrong. Function "SecItemCopyMatching" returned error: One or more parameters passed to the function were not valid. Error code: -50.

neo
  • 197
  • 2
  • 14

2 Answers2

5

You're providing an empty dictionary and not a valid query.

If you take the code from the answer you were looking at and drop it into your project:

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

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

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);
}

You'll have a happier result.

EDITED to add the CoreFoundation equivalent

There's no reason why you can't include the Cocoa framework in your MacOS command line tool (which is what I'm assuming you are writing). What a command line tool can't easily include is the AppKit UI framework.

Anyways, here is the CoreFoundation equivalent:

CFMutableDictionaryRef query = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
                                   &kCFTypeDictionaryKeyCallBacks,
                                   &kCFTypeDictionaryValueCallBacks);


CFDictionarySetValue(query, kSecReturnAttributes, kCFBooleanTrue);
CFDictionarySetValue(query, kSecMatchLimit, kSecMatchLimitAll);

CFTypeRef types[5];

types[0] = kSecClassGenericPassword;
types[1] = kSecClassInternetPassword;
types[2] = kSecClassCertificate;
types[3] = kSecClassKey;
types[4] = kSecClassIdentity;

CFArrayRef secItemClasses = CFArrayCreate(NULL, (void *)types, 5, &kCFTypeArrayCallBacks);
CFIndex i, c = CFArrayGetCount(secItemClasses);

for(i = 0; i<c; i++)
{
    CFTypeRef secItemClass = CFArrayGetValueAtIndex(secItemClasses,i);
    CFDictionarySetValue(query, kSecClass, secItemClass);

    CFTypeRef result = NULL;
    SecItemCopyMatching(query, &result);
    NSLog(@"%@", (__bridge id)result);
    if (result != NULL) CFRelease(result);
}

CFRelease(secItemClasses);
CFRelease(query);

When I put this into my own test app, I'm seeing quite a large dump of various keychain items and certificates.

Community
  • 1
  • 1
Michael Dautermann
  • 88,797
  • 17
  • 166
  • 215
  • thank you for your answer. But if I want to write application without Cocoa.framework, I should adaptive this code with CoreFoundation.framework. According with it, I answer, how can I modify that code? And then, how I can find my password and login from site? – neo Jan 28 '15 at 10:55
1

The OP did not ask about another keychain, but hopefully this will help future readers.

Michael's code is a simple way to show 'some' of the items stored in the keychain. I discovered through much trial and error that his code will not return the iCloud keychain. To see the iCloud keychain, add the key/value pair:

NSMutableDictionary *query = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                              (__bridge id)kCFBooleanTrue, (__bridge id)kSecReturnAttributes,
                              (__bridge id)kSecMatchLimitAll, (__bridge id)kSecMatchLimit,
                              //  added to find keychain items saved in iCloud
                              (__bridge id)kCFBooleanTrue, (__bridge id)kSecAttrSynchronizable,
                              nil];

The query dictionary for SecItemCopyMatching() is important and little understood!

** Caveat: This was tested on iPhone device, not on Mac.

David
  • 3,285
  • 1
  • 37
  • 54