iOS8 + Apple's KeychainItemWrapper results in a crash
Asked Answered
C

3

8

I've been digging around Apple forums and SO for this issue to no avail. Using Apple's KeychainItemWrapper (ARCified), trying to set the kSecAttrAccessible attribute to anything except the default (kSecAttrAccessibleWhenUnlocked) results in an assertion failure from SecItemUpdate returning an error.

KeychainItemWrapper *wrapper = [[KeyChainItemWrapper alloc] initWithIdentifier:kMyIdentifier accessGroup:nil];
[wrapper setObject:kMyServiceName forKey:(__bridge NSString*)kSecAttrService];
[wrapper setObject:kMyAccountToken forKey:(__bridge NSString*)kSecAttrAccount];
[wrapper setObject:(__bridge NSString*)kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly forKey:(__bridge NSString*)kSecAttrAccessible];

The rest of our keychain updates seem to be going through fine, but the last line results in:

*** Assertion failure in -[KeychainItemWrapper writeToKeychain], /Users/john.hammerlund/.../KeychainItemWrapper.m:299

The assertion failure is due to SecItemUpdate() returning a status of -50, which appears to be a generic "invalid parameters" error.

Immediately setting the kSecAttrAccessible key has no impact, but setting it to the default kSecAttrAccessibleWhenUnlocked mitigates the issue (but eliminates the point). This other question is the only additional info I've found relating to iOS 8 causing the KeychainItemWrapper to crash. Building to a device with iOS 7 or a simulator on iOS 7/8 eliminates the issue; it's only flaring up on a real device using iOS 8.

Update

Here's a broad overview of the query dictionary:

{ accc = "<SecAccessControlRef: 0x1687cc70>"; acct = ...; agrp = ...; cdat = "2014-10-13 22:22:47 +0000"; desc = ""; gena = ...; labl = ""; mdat = "2014-10-13 22:34:16 +0000"; pdmn = cku; <-- kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly svce = ...; sync = 0; tomb = 0; "v_Data" = <>; }

and the attributesToUpdate parameter:

{ accc = "<SecAccessControlRef: 0x1687cc70>"; acct = ...; agrp = ...; cdat = "2014-10-13 22:22:47 +0000"; desc = ""; gena = ...; labl = ""; mdat = "2014-10-13 22:34:16 +0000"; pdmn = ak; <-- kSecAttrAccessibleWhenUnlocked svce = ...; sync = 0; tomb = 0; "v_Data" = <>; }

I've confirmed that changing other fields (i.e. kSecAttrService, kSecAttrAccount) have the same effect on the corresponding fields in the dictionaries, but with an expected status of 0.

Calvinism answered 24/9, 2014 at 23:43 Comment(4)
you are going to have to dump the 2 dictionaries passed to SecItemUpdate in writeToKeychain so you can see the problemDividers
@Calvinism any update on this ?Butyl
It's been a while, but thank you @singhSan for bringing me back to this. I've assumed this is an Apple bug, as described below.Calvinism
@Calvinism thanks. Hopes they will resolve this soon, because from last few months issue exists in keychain. Seen questions in Apple forum too for this.Butyl
H
2

I also had the exact problem. Gave me:

OSStatus error -50 - conflicting kSecAccess and kSecAccessControl attributes

Crashed to all my users in the app store just after they updated.

Did the same as Peter. Grabed the data, deleted the item and inserted it as new item instead of trying to update the existing one.

I guess this is an Apple bug.

I opened a TSI but they didn't contact me yet.

From what i understand, It happens to users updated from iOS7 to iOS 8, where their first app was compiled with XCode for iOS7 (Before iOS 8 was out), and then on iOS8 updated to the new app which was compiled with XCode to iOS8.

Honey answered 3/12, 2014 at 9:57 Comment(0)
H
4

I had the same problem. I ended up testing kSecAttrAccessibile and if it wasn't what I wanted I recorded the value and attributes in the keychain in local variables, reset the keychain, set kSecAttrAccessible as desired and then set the value and attributes in the keychain to their original settings.

Hewett answered 27/11, 2014 at 4:48 Comment(2)
Thanks Peter It took lot of pain to figure out reason for crash.Looks like crash is from apples end.Hope they will fix it soon.I did same as you suggested and it worked for me.+upvoted.Ferdy
@peter I'm running into the same issues, tried to reset keychain but still getting the error. Can you please post a snippet of how you were able to get this working?Micropaleontology
E
2

A shot in the dark here:

Maybe the iOS device has iCloud synching enabled and adding an item that is not device specific and then making it ThisDeviceOnly results in the error. iOS8 may also have changed the behavior.

Can you try changing the order of attributes that are set to keychain

KeychainItemWrapper *wrapper = [[KeyChainItemWrapper alloc] initWithIdentifier:kMyIdentifier accessGroup:nil];
[wrapper setObject:(__bridge NSString*)kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly forKey:(__bridge NSString*)kSecAttrAccessible];
[wrapper setObject:kMyServiceName forKey:(__bridge NSString*)kSecAttrService];
[wrapper setObject:kMyAccountToken forKey:(__bridge NSString*)kSecAttrAccount];

If this doesn't help, you should change KeychainItemWrapper to look like this

- (void)resetKeychainItem
{
    if (!keychainItemData)
    {
        keychainItemData = [[NSMutableDictionary alloc] init];
        [keychainItemData setObject:(__bridge id)kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly forKey:(__bridge id)kSecAttrAccessible];
    }
Epineurium answered 17/10, 2014 at 10:8 Comment(3)
Yes, all values except the pdmn values and the accc references are the same.Calvinism
I updated the answer. Did you try out what is mentioned here ?Epineurium
I did...no dice. I've been digging through that wrapper for hours and still can't figure this out.Calvinism
H
2

I also had the exact problem. Gave me:

OSStatus error -50 - conflicting kSecAccess and kSecAccessControl attributes

Crashed to all my users in the app store just after they updated.

Did the same as Peter. Grabed the data, deleted the item and inserted it as new item instead of trying to update the existing one.

I guess this is an Apple bug.

I opened a TSI but they didn't contact me yet.

From what i understand, It happens to users updated from iOS7 to iOS 8, where their first app was compiled with XCode for iOS7 (Before iOS 8 was out), and then on iOS8 updated to the new app which was compiled with XCode to iOS8.

Honey answered 3/12, 2014 at 9:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.