Using SecItemUpdate in Keychain Services

I have the following code to create a keychain element in a keychain:

NSMutableDictionary* dict = [NSMutableDictionary dictionary]; [dict setObject: (__bridge id) kSecClassGenericPassword forKey: (__bridge id) kSecClass]; [dict setObject: MYKEY forKey: (__bridge id) kSecAttrService]; [dict setObject: @"0" forKey: (__bridge id) kSecValueData]; SecItemAdd ((__bridge CFDictionaryRef) dict, NULL); 

Which works great. Can someone give a syntax of what exactly to put for SecItemUpdate if I want to change this element?

UPDATE: with the following:

 NSMutableDictionary *query = [NSMutableDictionary dictionary]; NSMutableDictionary *attributesToUpdate = [NSMutableDictionary dictionary]; [query setObject: (__bridge id) kSecClassGenericPassword forKey: (__bridge id) kSecClass]; [query setObject: MYKEY forKey: (__bridge id) kSecAttrService]; [query setObject: (id) kCFBooleanTrue forKey: (__bridge id) kSecReturnData]; NSString *numberOfBalloonsString = [NSString stringWithFormat:@"%d", numberOfBalloonsUsed]; NSData *numberOfBalloonsData = [numberOfBalloonsString dataUsingEncoding:NSUTF8StringEncoding]; [attributesToUpdate setObject: numberOfBalloonsData forKey:(__bridge id)kSecValueData]; OSStatus error = SecItemUpdate ((__bridge CFDictionaryRef) query, (__bridge CFDictionaryRef) attributesToUpdate); NSLog(@"Error #: %ld", error); 

I get error code -50 =

One or more parameters passed to the function are invalid.

+6
source share
2 answers

SecItemUpdate horribly documented.

The query SecItemUpdate documented as a query (as used in other functions), as well as an undefined expression: "Specify the elements whose values ​​you want to change." This means that you must include the existing attribute value in this dictionary that you want to change, but I don’t think you are doing this. I found that you can use the same query that you use to get the attributes for the element you want to update.

The attributes parameter should be the result of SecItemCopyMatching with the kSecValueData key and the value added, and any attributes changed.

+6
source

Late answer but answer nonetheless:

I struggled with updating the items in the keychain, my context was a little different though.


What happened:

I could successfully add a keychain element (using SecItemAdd ), but the SecItemUpdate call on the same element failed with the notorious errSecParam -50 .
Worse yet; if the keychain element already exists (so I immediately called SecItemUpdate ), the update passed without any problems.
I have no idea why this happened ...

How I fixed it:

Pretty simple actually, I just deleted the "params" until I was satisfied with a big bad -50 . This happened when I removed kSecClass from a dictionary retrieved from kSecItemCopyMatching .
Here is my code:

  // If the item already exists, we update it instead if (SecItemCopyMatching((__bridge CFDictionaryRef)self.searchQueryDict, (CFTypeRef *)&foundItem) == errSecSuccess) { NSMutableDictionary *updateDict = (__bridge NSMutableDictionary *)foundItem; [updateDict addEntriesFromDictionary:dictToSave]; [updateDict removeObjectForKey:(__bridge id)kSecClass]; OSStatus updateSuccess = SecItemUpdate((__bridge CFDictionaryRef)self.updateQueryDict, (__bridge CFDictionaryRef)updateDict); NSAssert(updateSuccess == errSecSuccess, @"Couldn't save the dirty info to the keychain, might want to log the updateSuccess (%d)", updateSuccess); } 

As a reference, I used the following dictionaries

self.searchQueryDict contains:

 (__bridge id)kSecClass : (__bridge id)kSecClassGenericPassword (__bridge id)kSecAttrService : service (__bridge id)kSecAttrGeneric : [identifier dataUsingEncoding:NSUTF8StringEncoding] (__bridge id)kSecMatchLimit : (__bridge id)kSecMatchLimitOne (__bridge id)kSecReturnAttributes : (__bridge id)kCFBooleanTrue (__bridge id)kSecReturnData : (__bridge id)kCFBooleanTrue 

self.updateQueryDict contains:

 (__bridge id)kSecClass : (__bridge id)kSecClassGenericPassword, (__bridge id)kSecAttrService : service, (__bridge id)kSecAttrGeneric : [identifier dataUsingEncoding:NSUTF8StringEncoding] 

dictToSave must contain the values ​​(in the correct format) that need to be changed

Removing kSecClass fixed the problem for me.

+3
source

Source: https://habr.com/ru/post/958587/


All Articles