Keychain error -34018 (errSecMissingEntitlement)

This thread has been locked by a moderator.

This is a continuation of from the old forums: https://devforums.apple.com/thread/246122


Calling SecItemCopyMatching will sometimes return an OSStatus of -34018 (errSecMissingEntitlement). This seems to happen when the system is running low on memory. This has not been fixed in iOS9. I've of course filed radars about this and I would encourage others to do the same while iOS 9 is under development.

Up vote post of briandw
99k views

Replies

So the two things that fixed it for me were to 1, turn on the Keychain Sharing entitlement (why, I don't understand since I'm not sharing the Keychain with any other apps) to fix my issue at App launch, and 2, doing a dispatch_async(dispatch_get_main_queue()) from my UIApplicationWillEnterForegroundNotification handler for dealing with bringing the App forward.


Now everything appears to be happy.


Andrew

Hello,


I am also struggling with a occasional -38014 error code when accessing keychain data with the following code.


I can reproduce the issue almost every time the app runs, the keychain data is read corrctly, then all of a sudden, it throws the error.


I tried to add keychain sharing to the configuration and this did not work. This is primarially an issue when we are running in debug mode(with the device connected to the debugger) in developing new features for our app.

Any help in mitigating the issue would be appreciated.



NSMutableDictionary *queryDictionary = [[NSMutableDictionary alloc] init];
    [queryDictionary setObject:[key dataUsingEncoding:NSUTF8StringEncoding] forKey:(__bridge id)kSecAttrGeneric];
    [queryDictionary setObject:(__bridge id) kCFBooleanTrue forKey:(__bridge id)kSecReturnAttributes];
    [queryDictionary setObject:(__bridge id) kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit];
    [queryDictionary setObject:(__bridge id) kCFBooleanTrue forKey:(__bridge id)kSecReturnData];
    [queryDictionary setObject:(__bridge id) kSecClassGenericPassword forKey:(__bridge id)kSecClass];

    NSDictionary *returnedDictionary = NULL;/
    CFDictionaryRef cfquery = (__bridge_retained CFDictionaryRef)queryDictionary;
     CFDictionaryRef cfresult = NULL;
     OSStatus keychainError = SecItemCopyMatching(cfquery, (CFTypeRef *)&cfresult);
     CFRelease(cfquery);
    if (keychainError == errSecSuccess)
    {
        returnedDictionary = (__bridge_transfer NSDictionary *)cfresult;
        NSData *rawData = [returnedDictionary objectForKey:(__bridge id)kSecValueData];
        NSString* value = [[NSString alloc] initWithBytes:[rawData bytes] length:[rawData length] encoding:NSUTF8StringEncoding];
        AMZLogDebug(@"Get Value for KeyChain key:[%@],%@", key,value);
    
        return value;
    }
    else
    {
        AMZLogDebug(@"Get Value for KeyChain key:[%@],%@", key,@"nil");
        return nil;
    }

I ran into this problem running Xcode 7 beta 5, and iOS 9.0 Beta 6 running in Debug mode started from Xcode. I am requiring User Presence for accessing an important value in my keychain, and if I start the app with passcode set, everything works fine. This error pops up when putting the app in the background, removing the passcode, and bringing the app back to foreground. When trying to access this value, I start receiving -34018 rather than the proper Keychain error values I am looking for. However, if I start this app with no passcode being set at app launch, then all error codes are given appropriately, and I have no issues.


This does not happen with iOS 8.X running the same code.


Is this being caused because it is a Beta build? or will this possibly happen with App Store builds for iOS 9 as well?

Quinn, I have a detail that I don't see elsewhere in this thread.


When starting or resuming my app normally, I never have any problems accessing the keychain immediately when UIApplicationDidBecomeActiveNotification gets fired. However, I'm in the process of adding support for iOS 9 Universal Links, and ONLY when resuming the app as a result of tapping a web link I get the -34018 keychain error 100% of the time. In that case, and only in that case, when the UIApplicationDidBecomeActiveNotification notification gets fired, attempts to access the keychain fail. This may mean that I cannot ship with the Universal Links feature until it is fixed.


Keychain Access Fails Consistently When Resuming App From a Universal Link

rdar://22583555


I also tried removing all apps from the multitasking view until it was just my app and Dropbox.app (where I keep a file for testing Universal Links), trying to rule out memory pressure, and I still got the keychain error.

Thanks so much for your patience and help on this matter.

Here are some more potentially helpful details I've discovered:


1. This issue only happens when the debugger is attached. Run the app from the device alone without Xcode, and it all works as expected. Should have tried this sooner. :/


2. Everything works as expected on my iPad mini 1. Problem exists only on my iPhone 6 Plus. Strange.


3. The problem happens also when tapping a spotlight result that opens my app.

Just to add some more color:


I'm storing oauth2 creds in the keychain. From a fresh start, the following work:

* Accessing an existing credential

* Deleting a credential and storing a new one.


Where I run into problems is in resuming app after being previously logged in, stepping out to settings, and returning. One feature of the internal build is that the identifier for the service to be used is stored in NSUserDefaults, so the user can go to iOS Settings and toggle their service endpoint. When the app resumes after this happends, I check to see if the service changed, and if it did, I force a logout and ask the user to sign in again.


It is at this point I run into problems. After having previously been able to read/write the keychain, I get a -34018 for every keychain access. While the deletes happen almost immediately after the app resumes, the adds typically happen quite a while afterwards, since the user has to enter a name and password.


I'm using accessibility specifier kSecAttrAccessibleAfterFirstUnlock. I have app groups enabled, and an entitlements file in place. Codesign output is as expected.


This is happening on iOS9b5 / 13A4325c on an iPhone6+. It does not happen on my iPhone5 running iOS 8.4./12H143.

I would like to confirm that for me as well:


1. the issue only happens with debugger attached on iPhone (for me it's iPhone 5S)

2. Everything works on iPad mini with or without debugger

@gc That's great news.


As others have reported, this mysterious keychain error is most easily observable when launching via Xcode with the debugger attached. Once the error starts occurring, the keychain doesn't seem to right itself regardless of memory pressure until one reboots the device.


I just wanted to add that I've received reports from end users that indicate to me that this error can also occur in a production App Store environment, not just when connected to the debugger. For example, I get sparse reports of things like a player's coin balance no longer updating in one of my games (their coin balance in this case is stored in a keychain item to make it harder to tamper with - as opposed to using NSUserDefaults). I've carefully checked my code and the only way I can figure that players aren't being credited coins sometimes is that the keychain becomes inaccessible and is returning this error. I've observed the same behavior when attached to the debugger when this error occurs. The incidence of this error in production seems to be <1%, but it's obviously a serious problem for affected users.


Until this is fixed it looks like I'll have to migrate my code away from using the keychain for storing small bits of critical information. 😟 End users who have this problem have little recourse except to reboot their device, which seems to fix the problem. Any update for us?

In the middle time at Apple resolves this bug, what is your recomendation for save critical data?


What is your recomendation developers? In my case, i am affected by this issue only when debug on iOS 9 device and receive system memory warnings .

I can test many other options, wrappers, codes and more for save data and after read without problems, but finally I verify that this is the same issue with SecItemCopyMatching.

So, what other options can use to save critical data or save in other way?

When is possible to fix this issue Apple?

This is nuts. I'm really coming to the conclusion that we can simply ignore OSStatuses (a little bit exagerating, but at least I meant that really for -34018). All goes fine, pretty much like a Success. False positive. Very disturbing.

No, we actually can not ignore it because we can not save anything in keychain. It breaks our app behaviour. Apple should find a way to fix this bug

Hey guys,


any updates on this?


We were told in July you were working on this but several months have passed and this is still a major issue.


What is going on? What can we expect going forward?


We really need some official response on this.


Thank you.

We are desparate for this fix too.

I've been having same problems on iOS 8 and iOS 9, with iPhone 5, 5s, 6, 6+, 6s+. I don't think this problem is related to a combination of OS and device, beecause after reading this thread, there a lots of combinations that just don't work.

I wanted to publish my app, but it won't pass review because it uses Keychain not only for registration, but also many times in app.

I decided to put an alert when user starts the app. It would check whether I can retrieve values from Keychain, if not, I'll tell them to kill the app and start over, hopefully, with Keychain working. This will get me a lot one star ratings ...


Certainly, not a good for Apple as well. Their keychain doesn't store sensitive data correctly!!!

Xcode, Mac OSX, and iOS update today. Seems to be fixed for me.... for now at least.


Edit: Nope. Still Broken. Is this happening in the wild or just debug mode? I only know debug mode but I'm also see bug reports that don't make any sense unless this is also happening in the wild.