我的代码在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);
}
}
下面是我执行了query
和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