SecItemUpdate fails with errSecDuplicateItem

My code works 70% of the time, but sometimes it throws an error errSecDuplicateItem

in SecItemUpdate

, and I just don't understand why.

In the code below, two class objects are available self.storedActiveDirectoryKeychainItem

, which is an immutable dictionary that represents the keychain item and self.activeDirectoryKeychainItem

which contains the modified values.

I am making changes to the username and / or password field and sometimes it works as expected and other times it SecItemUpdate

returns the result code -25299, which is errSecDuplicateItem

. Insertion ( SecItemAdd

) throws no errors.

- (void)persistStandardADKeychainItem {
    NSMutableDictionary *keychainItemContents = [self.activeDirectoryKeychainItem mutableCopy];

    // encode password
    NSData *encodedPassword = [self.password dataUsingEncoding:NSUTF8StringEncoding];
    keychainItemContents[(__bridge id)kSecValueData] = encodedPassword;

    // encode the meta data
    NSData *encodedData = [NSKeyedArchiver archivedDataWithRootObject:keychainItemContents[(__bridge id)kSecAttrGeneric]];
    keychainItemContents[(__bridge id)kSecAttrGeneric] = encodedData;

    OSStatus resultCode;
    if (self.storedActiveDirectoryKeychainItem[(__bridge id)kSecAttrCreationDate]) {
        // Update Existing Item
        NSMutableDictionary *query = [self.storedActiveDirectoryKeychainItem mutableCopy];
        // add in keychain item type to search query
        query[(__bridge id)kSecClass] = (__bridge id)kSecClassGenericPassword;
        // remove the Generic Data (meta data), we don't want to search on it.
        [query removeObjectForKey:(__bridge id)kSecAttrGeneric];

        resultCode = SecItemUpdate((__bridge CFDictionaryRef)query, (__bridge CFDictionaryRef)keychainItemContents);
        if (resultCode != 0)
            NSLog(@"Updated standard keychain credentials result code: %d", (int)resultCode);
    } else {
        // Insert New Item
        keychainItemContents[(__bridge id)kSecClass] = (__bridge id)kSecClassGenericPassword;
        keychainItemContents[(__bridge id)kSecAttrAccessible] = (__bridge id)kSecAttrAccessibleWhenUnlockedThisDeviceOnly;
        keychainItemContents[(__bridge id)kSecAttrCreator] = self.configurationManager.keychainItemCreatorName;
        keychainItemContents[(__bridge id)kSecAttrService] = self.configurationManager.keychainItemServiceName;

        resultCode = SecItemAdd((__bridge CFDictionaryRef)keychainItemContents, NULL);
        if (resultCode != 0)
            NSLog(@"Insert standard keychain credentials result code: %d", (int)resultCode);
    }
}

      

Below is a debug error message where I dumped both dictionaries query

and keychainItemContents

.

2014-12-03 11:46:55.776 TestKeychainServices[314:34883] query
{
    accc = "<SecAccessControlRef: 0x165d01f0>";
    acct = fubar;
    agrp = "C35BXHSRSA.com.bobco.Security";
    cdat = "2014-12-02 17:05:44 +0000";
    class = genp;
    crtr = MyCompany;
    icmt = "12/3/14, 11:46 AM";
    mdat = "2014-12-03 16:46:52 +0000";
    pdmn = aku;
    svce = "Active Directory";
    sync = 0;
    tomb = 0;
    "v_Data" = <54155341 34452965 6374>;
}
2014-12-03 11:46:55.778 TestKeychainServices[314:34883] new contents
{
    accc = "<SecAccessControlRef: 0x165d01f0>";
    acct = user123;
    agrp = "C35BXHSRSA.com.bobco.Security";
    cdat = "2014-12-02 17:05:44 +0000";
    crtr = MyCompany;
    gena = <62706c69 73743030 d4010203 04050827 28542474 6f705824 6f626a65 63747358 24766572 0a012001 25000000 00000002 01000000 00000000 29000000 00000000 00000000 00000001 37>;
    icmt = "12/3/14, 11:46 AM";
    mdat = "2014-12-03 16:46:52 +0000";
    pdmn = aku;
    svce = "Active Directory";
    sync = 0;
    tomb = 0;
    "v_Data" = <54155341 34452965 6374>;
}
2014-12-03 11:46:55.801 TestKeychainServices[314:34883] Updated standard keychain credentials result code: -25299

      

+3


source to share





All Articles