3
votes

I am facing a weird issue. Quite similar to one asked here, but not answered: Read from keychain results in errSecItemNotFound 25300

My code saves a string password in the iOS keychain to be accessed later on. It works just fine most of the times and I am able to fetch the password back after reinstallation or device restart or both.

Problem: Sometimes which is actually rare and hard to reproduce, it does not return the password and instead it returns null and error status:-25300(errSecItemNotFound). Another thing is that this problem got prominent after iOS 9 update. Happening on iOS 9.1 too.

Now, I have been searching the web for a solution. Found the following, which somehow relate to the issue, but do not address to my scenario:

Has anyone got any ideas why this is happening? Many thanks.

Updated

Code for setting:

  NSMutableDictionary *query = [self _queryForService:service account:account];
  [query setObject:password forKey:(__bridge id)kSecValueData]; 
  status = SecItemAdd((__bridge CFDictionaryRef)query, NULL);
}
if (status != errSecSuccess && error != NULL) {
    *error = [NSError errorWithDomain:kAppKeychainErrorDomain code:status userInfo:nil];

}
return (status == noErr);

Final query:

{
acct = user;
class = genp;
svce = "myBundleIdentifier";
"v_Data" = <36314541 38463339 2d363737 462d3445 34372d42 4339452d 31324633 46463937 35374546>;}

Code for fetching:

CFTypeRef result = NULL;    
NSMutableDictionary *query = [self _queryForService:service account:account];
[query setObject:(__bridge id)kCFBooleanTrue forKey:(__bridge id)kSecReturnData];
[query setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit];
status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &result);

if (status != errSecSuccess && error != NULL) {
    *error = [NSError errorWithDomain:kAppKeychainErrorDomain code:status userInfo:nil];
    return nil;
}

return (__bridge_transfer NSData *)result;

Final query:

{
acct = user;
class = genp;
"m_Limit" = "m_LimitOne";
"r_Data" = 1;
svce = "myBundleIdentifier";}
1
Update your question with the code that writes to and reads from the keychain.rmaddy

1 Answers

5
votes

I can see that the question is old, but I have recently almost gone mad trying to solve a similar issue with Keychain, so I will share it in case anyone faces it.

The problem was that the app would randomly crash when writing to the keychain in the background. And the reason is that when the user has a passcode on their phone and selected access level is the safest, iOS will not allow your application to make changes in the keychain while it's protected with a passcode.