iOS KeychainItemWrapper not updating
Asked Answered
B

2

11

I just found an interesting problem with my app. In the app I am saving the user's user name and password to the keychain.

keychainWrapper = [[KeychainItemWrapper alloc] initWithIdentifier:@"MyLoginPassword" accessGroup:nil];

[keychainWrapper setObject:usernameField.text forKey:(id)kSecAttrAccount];
[keychainWrapper setObject:passwordField.text forKey:(id)kSecValueData];

When this code is run in Debug it seems to work just fine. It updates each time and I can later retrieve the items from the keychain. When it is run in Distribution however the keychain never gets updated. I have verified that yes these lines of code are hit in both builds. I am using Xcode 4.2 with the iOS5 SDK and running the app on an iPad 2 with iOS5 installed.

Belie answered 8/11, 2011 at 17:6 Comment(0)
I
17

I also had this problem, and it took me forever to figure out

There is a version of "KeychainWrapper" floating around that has it's SecItemUpdate within an NSAssert (among other things).

Whoever did this is a moron!, when building for release/distribution every NSAssert is nullified, meaning that code doesn't even get run.

For example:

NSAssert(SecItemUpdate((CFDictionaryRef)updateItem, (CFDictionaryRef)tempCheck), @"Couldn't update the Keychain Item." );

Needs to become

OSStatus status = SecItemUpdate((CFDictionaryRef)updateItem, (CFDictionaryRef)tempCheck);
NSAssert(status == noErr, @"Couldn't update the Keychain Item." );

Notice how the actual SecItemUpdate is moved outside the NSAssert, and instead the result is checked

Important note: Attempting to update a value for kSecValueData, without also specifying a value for kSecAttrAccount, will cause the assertion to fail as well. So, if your intent is to store a single string of sensitive data (such as a list of credit card numbers), be sure to store some "account name" text in the kSecAttrAccount attribute, like so:

static NSString* kCardListXML = @"cardListXML";
static NSString* cardListAccountName = @"cardListAccount";

-(void)setCardListXML:(NSString*)xml {
  KeychainItemWrapper* wrapper =
    [[KeychainItemWrapper alloc] initWithIdentifier:kCardListXML accessGroup:nil];
  [wrapper setObject:cardListAccountName forKey:(id)CFBridgingRelease(kSecAttrAccount)];
  [wrapper setObject:xml forKey:(id)CFBridgingRelease(kSecValueData)];
}    

-(NSString*)getCardListXML {
  KeychainItemWrapper* wrapper =
    [[KeychainItemWrapper alloc] initWithIdentifier:kCardListXML accessGroup:nil];
  [wrapper setObject:cardListAccountName forKey:(id)CFBridgingRelease(kSecAttrAccount)];
  return [wrapper objectForKey:CFBridgingRelease(kSecValueData)];
}
Interment answered 23/11, 2011 at 9:19 Comment(2)
I had figured it out and this was essentially the problem. Thanks.Belie
That seem to be fixed in v1.2 of the KeychainWrapper, available from the Xcode Sample CodeUndies
T
16

When you include

keychainWrapper = [[KeychainItemWrapper alloc] initWithIdentifier:@"MyLoginPassword" accessGroup:nil];

[keychainWrapper setObject:usernameField.text forKey:(id)kSecAttrAccount];
[keychainWrapper setObject:passwordField.text forKey:(id)kSecValueData];

you also had to include

[keychainWrapper setObject:@"Myappstring" forKey: (id)kSecAttrService];

Or I get a "SIGABRT" error. (Myappstring) is a string defining your application.

Maybe I'm missing something, this should be done at least once.

Thallus answered 7/12, 2011 at 8:53 Comment(3)
KeychainItemWrapper was mostly working for me, worked on many email addresses (stored as username in kSecAttrAccount), but one email in particular did not work. I then added the above line for kSecAttrService and all is now perfect! -Thank you @AndresVoronezh
I struggled with it for quite a while. Glad it helpedThallus
This fix worked for me. It's tricky to figure out what is going on from the error messages, because if you have ever previously set these values correctly, you will not see an error. Only when you change the initWithIdentifier: value AND fail to set kSecAttrService do you then start to get errors.Retreat

© 2022 - 2024 — McMap. All rights reserved.