SecItemUpdate使用errSecDuplicateItem间歇性地失败

时间:2014-12-03 16:11:29

标签: ios objective-c keychain

我的代码在70%的时间都有效,但有时会在errSecDuplicateItem上引发SecItemUpdate错误,我只是不明白为什么。

下面的代码访问两个类对象self.storedActiveDirectoryKeychainItem,它是表示钥匙串项的未更改字典,self.activeDirectoryKeychainItem包含修改后的值。

我正在修改用户名和/或密码字段,有时它会按预期工作,有时SecItemUpdate会返回-25299的结果代码errSecDuplicateItem。插入(SecItemAdd)不会出错。

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

下面是我执行了querykeychainItemContents词典转储的失败的调试输出。

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

0 个答案:

没有答案
相关问题