GenericKeychain sample code does not create unique keychain items

Originator:kristopherdjohnson
Number:rdar://13472204 Date Originated:21-Mar-2013 09:52 AM
Status:Open Resolved:
Product:iPhone SDK Product Version:6
Classification:Serious Bug Reproducible:Always
 
Summary: The KeychainItemWrapper class in the GenericKeychain sample does not create items that are considered unique by Keychain Services. So if a developer attempts to use that sample code to create multiple items with different identifiers, the SecItemAdd() call fails with an OSStatus of -25299 ("The item already exists.")

The Keychain Services documentation is not clear about how it determines the identity of an item, so a developer using the sample code will have difficulty determining why the SecItemAdd() call is failing.

The problem is that Keychain Services uses the kSecAttrAccount and/or kSecAttrService attributes to determine uniqueness. The sample code does not set those attributes on its items, so they are not unique. The sample code does set the kSecAttrGeneric attribute, but that attribute does not determine uniqueness.

The sample code should be fixed, and the Keychain Services documentation should be updated to make it clear which attributes determine uniqueness.


Steps to Reproduce:

In the GenericKeychain sample, add the following lines to the bottom of the AppDelegate's applicationDidFinishLaunching: method:


    KeychainItemWrapper *otherItem = [[KeychainItemWrapper alloc] initWithIdentifier:@"Other" accessGroup:nil];
    [self.passwordItem setObject:@"foo" forKey:kSecValueData];
    [otherItem setObject:@"bar" forKey:kSecValueData];


This code attempts to create a second keychain item, named "Other", and then tries to set values for the previously created passwordItem and this new otherItem. When it does this, the assertion at the bottom of -[KeychainItemWrapper writeToKeychain] will fail with the message "Couldn't add the Keychain Item" because SecItemAdd() returns -25299 instead of noErr.


Expected Results:

Developer should be able to create and use multiple KeychainItemWrapper instances with different identifiers.


Actual Results:

SecItemAdd() call fails with an OSStatus of -25299 ("The item already exists.") for any KeychainItemWrapper instance other than the first one.


Regression: N/A


Notes:

More details/discussion of this problem are here:

- http://useyourloaf.com/blog/2010/04/28/keychain-duplicate-item-when-adding-password.html
- http://stackoverflow.com/questions/4891562/ios-keychain-services-only-specific-values-allowed-for-ksecattrgeneric-key

Comments


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!