I'm trying to get the attributes of a keychain item. This code should look up all the available attributes, then print off their tags and contents.
According to the docs I should be seeing tags like 'cdat', but instead they just look like an index (i.e., the first tag is 0, next is 1). This makes it pretty useless since I can't tell which attribute is the one I'm looking for.
SecItemClass itemClass;
SecKeychainItemCopyAttributesAndData(itemRef, NULL, &itemClass, NULL, NULL, NULL);
SecKeychainRef keychainRef;
SecKeychainItemCopyKeychain(itemRef, &keychainRef);
SecKeychainAttributeInfo *attrInfo;
SecKeychainAttributeInfoForItemID(keychainRef, itemClass, &attrInfo);
SecKeychainAttributeList *attributes;
SecKeychainItemCopyAttributesAndData(itemRef, attrInfo, NULL, &attributes, 0, NULL);
for (int i = 0; i < attributes->count; i ++)
{
SecKeychainAttribute attr = attributes->attr[i];
NSLog(@"%08x %@", attr.tag, [NSData dataWithBytes:attr.data length:attr.length]);
}
SecKeychainFreeAttributeInfo(attrInfo);
SecKeychainItemFreeAttributesAndData(attributes, NULL);
CFRelease(itemRef);
CFRelease(keychainRef);
There are two things you should be doing here. Firstly, you need to handle "generic" itemClasses before the call to SecKeychainAttributeInfoForItemID...
switch (itemClass)
{
case kSecInternetPasswordItemClass:
itemClass = CSSM_DL_DB_RECORD_INTERNET_PASSWORD;
break;
case kSecGenericPasswordItemClass:
itemClass = CSSM_DL_DB_RECORD_GENERIC_PASSWORD;
break;
case kSecAppleSharePasswordItemClass:
itemClass = CSSM_DL_DB_RECORD_APPLESHARE_PASSWORD;
break;
default:
// No action required
}
Second, you need to convert the attr.tag from a FourCharCode to a string, i.e.
NSLog(@"%c%c%c%c %@",
((char *)&attr.tag)[3],
((char *)&attr.tag)[2],
((char *)&attr.tag)[1],
((char *)&attr.tag)[0],
[[[NSString alloc]
initWithData:[NSData dataWithBytes:attr.data length:attr.length]
encoding:NSUTF8StringEncoding]
autorelease]]);
Notice that I've also output the data as a string -- it almost always is UTF8 encoded data.
I think the documentation leads to a bit of confusion.
The numbers I'm seeing appear to be keychain item attribute constants for keys.
However, SecKeychainItemCopyAttributesAndData returns a SecKeychainAttributeList struct, which contains an array of SecKeychainAttributes. From TFD:
tag A 4-byte attribute tag. See “Keychain Item Attribute Constants” for valid attribute types.
The attribute constants (of the non-"for keys" variety) are the 4-char values I expected to see.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With