SecItemAdd and SecItemCopyMatching returns error code -34018 (errSecMissingEntitlement)
Asked Answered
M

20

120

Sometimes when I run an application on device from Xcode I would try to access the keychain but fail due to error -34018. This doesn't match any of the documented keychain error codes and can't be consistently reproduced. (happens maybe 30% of the time, and it's not clear to me why it happens). What makes debugging this problem very difficult is the total lack of documentation. Any idea what causes this and how to fix it? I'm using Xcode 5 and running iOS 7.0.4 on device.

There is an open issue about this here: https://github.com/soffes/sskeychain/issues/52

EDIT: Adding keychain access code per request

I'm using the SSKeychain library for interfacing with keychain. Here's the snippet.

#define SERVICE @"default"

@implementation SSKeychain (EXT)

+ (void)setValue:(NSString *)value forKey:(NSString *)key {
    NSError *error = nil;
    BOOL success = NO;
    if (value) {
        success = [self setPassword:value forService:SERVICE account:key error:&error];
    } else {
        success = [self deletePasswordForService:SERVICE account:key error:&error];
    }
    NSAssert(success, @"Unable to set keychain value %@ for key %@ error %@", value, key, error);
    if (!success) {
        LogError(@"Unable to set value to keychain %@", error);
    }
    LogTrace(@"Will set keychain account %@. is to nil? %d", key, value == nil);
    if (value == nil)
        LogWarn(@"Setting keychain %@ to nil!!!", key);
}

+ (NSString *)valueForKey:(NSString *)key {
    NSError *error = nil;
    NSString *value = [self passwordForService:SERVICE account:key error:&error];
    if (error && error.code != errSecItemNotFound) {
        NSAssert(!error, @"Unable to retrieve keychain value for key %@ error %@", key, error);
        LogError(@"Unable to retrieve keychain value for key %@ error %@", key, error);
    }
    return value;
}

+ (BOOL)removeAllValues {
    LogInfo(@"Completely Reseting Keychain");
    return [[self accountsForService:SERVICE] all:^BOOL(NSDictionary *accountInfo) {
        return [self deletePasswordForService:SERVICE account:accountInfo[@"acct"]];
    }];
}

@end

Vast majority of the time it's just fine. Sometimes I'll hit the assertion failures where I'm unable to either write to or read from keychain, causing critical assertion failure.

Mart answered 3/12, 2013 at 6:22 Comment(15)
i have same problem and can't reproduce it...I'm using KeychainItemWrapper class from Apple. Sometimes it crashes from Google Analytics with the same error message. I am in use of Google Analytics v3.02.Greek
Also, it seems to be OK in the app from AppStore. it happens only in development version app.Greek
I have crashlytics for app store version and unfortunately it seems to happen in app store also, albeit less frequent than on dev :/Mart
I'm thinking of switching away from keychain because the fact that data stored in keychain can randomly be lost like this is pretty much a fatal error for the application.Mart
thank you for sharing your idea. i'm going to access to keychain only once when launching the app at first, and store it into the memory.Greek
Does that actually help though? Is the problem avoided that way?Mart
i don't think it's solved completely. but the fact is that it doesn't happen all the time. that's why i try to access to keychain as less as possible.Greek
I wonder if this is a problem with the iOS7 SDK. I'm still using the iOS6 SDK and haven't had this happen to me yet.Fascista
We are also seeing this intermittent issue. We raise an exception when we get an unexpected rc from secItemCopyMatching including the -34018 case. We tried (reluctantly) adding a mechanism where, once we get the value we need from the keychain, we cache it in app memory and then serve it from there without keychain access. But now we are seeing rare occasions where that one keychain access to get it in the first place fails with a -34018. Has anyone tried retrying the operation after a -34018?Vaas
I've had success deleting the entire keychain in the event of the error happening consistently. Returning it to a clean initial state is a costly maneuver, but it at least gives you the keychain to use again.Wittol
I have te same problem. It looks like it is only happing in my XCTest-target.Tho
I'm experiencing this as well when trying to get previously stored items. They weird thing is that it seems to be happening semi-randomly. In our case it seems related to trying to access the keychain in code inside a dispatch_once(&token, block) block.Cherida
I'm also getting this error. No where near 30% of the time-- less frequent for me. I'm not sure yet if it's occurring in production. It does not seem to be specifically occurring when I run the app from Xcode.Huntley
Just wanted to add a little more info about the conditions under which this is (still) occurring in my app. It appears to happen after I remove the app without having first removed the keychain items. And then reinstall the app and try to add the item into the key chain. There is at least one more factor involved, but haven't nailed that down. When it does happen, it does seem to be in this circumstance. So far I only know of this happening when running under Xcode. This doesn't appear to be related in my case to when the app returns from the background, or upon launch.Huntley
I have this issue running Xcode 9.3 and Xcode 9.4 beta, with iOS 11.4 simulator (Swift 4.1). I cannot use the "keychain sharing" workaround since I am developing a Cocoa Touch Dynamic Framework and wants to test me framework code. Have anyone fixed it on Xcode 9.3 or 9.4 beta?Kurrajong
G
47

iOS 10 / XCode 8 Fix:

Add KeyChain Entitlement, Go to project settings->Capabilities->Keychain Sharing->Add Keychain Groups+Turn On

An answer here, from Apple:

UPDATE: We have finally been able to reproduce the -34018 error on iOS 8.3. This is the first step in identifying the root cause and then coming up with a fix.

As usual, we can't commit to a release timeframe, but this has affected many developers and we really want to get this resolved.

Earlier I suggested adding a small delay in application:didFinishLaunchingWithOptions and applicationDidBecomeActive: before accessing the keychain as a workaround. However, that doesn't actually appear to help. That means that there's no known workaround at this time other than relaunching the app.

The issue appears to be related to memory pressure, so perhaps being more aggressive in handling memory warnings may alleviate the problem

https://forums.developer.apple.com/thread/4743#14441

UPDATE

OK, here’s the latest.
This is a complex problem with multiple possible causes:

  • Some instances of the problem are caused by incorrect app signing. You can easily distinguish this case because the problem is 100% reproducible.
  • Some instances of the problem are caused by a bug in how iOS supports app development (r. 23,991,853). Debugging this was complicated by the fact that another bug in the OS (r. 23,770,418) masked its effect, meaning the problem only cropped up when the device was under memory pressure. We believe these problems were resolved in iOS 9.3.
  • We suspect that there may be yet more causes of this problem.

So, if you see this problem on a user device (one that hasn’t been talked to by Xcode) that’s running iOS 9.3 or later, please do file a bug report about it. Try to include the device system log in your bug report (I realise that can be tricky when dealing with customer devices; one option is to ask the customer to install Apple Configurator, which lets them view the system log). And if you do file a bug, please post your bug number, just for the record.

On behalf of Apple I’d like to thank everyone for their efforts in helping to track down this rather horrid issue. Share and Enjoy

https://forums.developer.apple.com/thread/4743#126088

Grizzly answered 15/7, 2015 at 4:50 Comment(9)
The issue still reproduces on iOS 9.2, iPhone 5S.Dobson
Looks like iOS 9.3 should resolve this issue according to the latest response from Apple in the thread you linked. @daidai, could you please update your answer with this new information?Mafia
Hmm, I get iOS 10.0 simulator getting -34018 using AWS API's keychain. Once I get stuck, even with reboot simulator won't help.Demurrer
@YoonLee am also seeing this with iOS10 - also using AWS's 2.4.8 SDK. Error triggered in AWSClientContext.m line 54. Any luck solving this?Monies
@YoonLee btw, just solved this using one of the answers below: 'KeyChain Sharing turned on for target capabilities'Monies
@Monies Yes, I did solved on that day. You are right. Seems to be 'KeyChain Entitlement turn on' fixes the problem. Surprisingly, this error doesn't trigger always. Anyways, now on I am turning this on.Demurrer
Moreover, To add KeyChain Entitlement, Go to project settings->Capabilities->Keychain Sharing->Add Keychain Groups+Turn OnDemurrer
@YoonLee yep can confirm this fixed it for me tooGrizzly
This is the correct answer for iOS 10! Way to go for updating your answer.Rountree
T
27

Basically you have to codesign your .xctest folder by adding the following as a run script in your test target.

codesign --verify --force --sign "$CODE_SIGN_IDENTITY" "$CODESIGNING_FOLDER_PATH"

I got a lot of -34018 errors when testing my keychain on the device and this managed to fix it.

If the problem does not exist in your test target this is probably not the solution.

Tho answered 10/3, 2014 at 16:2 Comment(7)
Confirmed this fixed it in the test environment. I had to add the run script onto the actual test target (e.g. the ones w/ all the unit tests, not the build target that runs on the device). Also confirmed this was only an issue on the device, not on the simulator.Romanticist
I get ": no identity found Command /bin/sh failed with exit code 1" when I do this? Guessing I don't have a $CODE_SIGN_IDENTITY. Any idea how I fix this?Balikpapan
@DanielCoffman, you must go to your target settings and in Code Signing Identity select "iOS Developer" (or any other valid identity). This fixes the build error, however at least for me it doesn't fix the Keychain problem. I still get -34018 error code.Oratorical
Thanks Marcin. I started getting this error when I switched to xcode 6 beta. No suggestion in this thread resolved. Reverted to xcode 5 and -34018 no longer occurs.Balikpapan
I experience also this error for the first time since I use XCode 6.3.Corbeil
This answer saves my life.Hydrolyse
the link is deadWaistband
B
13

After inspecting the source code. I have noticed that the keychain features are accessed through a security daemon that runs in its own process (separated from the app process).

Your app and the securityd process 'talk' together through a technology called XPC.

If necessary, the securityd is launched via the well-known launchd command by XPC. You can probably check that the daemon is running in the Activity Monitor App (if running in Simulator of course) and that its parent process is launchd.

My guess here is that it is possible that for any unknown reason the security daemon fails to start or do it too slowly and is not ready when you try to use it.

Maybe you could think on how to pre-launch the daemon.

I apologize for not being more precise. I hope it could help you to go a bite further in your investigations.

Berkshire answered 24/1, 2014 at 21:38 Comment(2)
I get this problem only when my app is re-opened via a Deep link with the following app delegate method: - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url. If I just start the app, keychain writing works, and if I minimize and maximize the app, it still works. It's only when I re-open with the deep link that this problem occurs. I do have MyApp.entitlements configured in my project ( Keychain Sharing in the Capabilities tab) Xcode 7 beta 4.Blindheim
My case is similar to Alex's, which only happens when the app is deep-linked. Otherwise it runs fine. Maybe some context is not right when the app is opened from another app.Sim
O
13

I’m observing similar behavior after building and running my code in Xcode 6 beta with iOS 8 SDK (it’s working correctly with Xcode 5 / iOS 7). In Xcode 6, in iOS Simulator SecItemCopyMatching always returns -34018. It started working after turning on the “Keychain Sharing” in Capabilities tab.

However I have another issue. I’m developing static library, that is used by (among others) Demo application. The above solution works for Demo application project, but when I try to unit test my static library project, I have exactly the same error. And the problem is that my static library project doesn’t have the Capabilities tab (as it’s not the standalone application).

I’ve tried the solution posted here by JorgeDeCorte, with codesigning in the test target, but it doesn’t work for me.

Oratorical answered 9/6, 2014 at 12:38 Comment(10)
This seems to be a known issue of iOS 8, that is listed here developer.apple.com/library/prerelease/ios/releasenotes/General/… According to that: "Keychain Access developer APIs may not work in Simulator"Oratorical
Fixed in iOS 8 beta 2.Oratorical
And back in iOS 8 beta 3 :)Ayrshire
And now back in iOS 9.2 :-(Upsurge
Same result on iOS 9.2 to me.Semivitreous
The issue is back in iOS 9.3 beta/ Xcode 7. happens on and off, randomlyAbbey
Back in iOS 10 beta 2Exciting
also in ios10 beta 4Darden
And back in iOS 10 beta 5Ema
Experiencing it on Xcode 8.0 with the 9.3 and 10.0 simulatorsPolad
H
6

Try disabling all breakpoints when launching the app from Xcode. You can enable them afterwards.

(None of the above workarounds worked for me)

Helle answered 24/3, 2016 at 11:56 Comment(1)
Strange. Seems to fix this issue for me too! Every time i started debugging on simulator i could experience the -34018 OSStatus.Encouragement
R
4

I just had the same issue on the simulator running 7.1 & 8.0. While doing some digging, I noticed that the Apple sample app had KeyChain Sharing turned on for its target capabilities. I turned it on for my app which resulted in creating an entitlement file that I left with the default values and now I am not getting anymore -34018 errors. This is not ideal but I will live the KeyChain sharing option for now.

Rathenau answered 8/6, 2014 at 7:16 Comment(0)
P
4

Codesigning a .xctest bundle isn't as easy as it sounds in some cases. Principally JorgeDeCorte is right with his answer that the given short line as a Run Script is enough for most of the devs.

codesign --verify --force --sign "$CODE_SIGN_IDENTITY" "$CODESIGNING_FOLDER_PATH"

But when you have multiple certificates in your keychain this will fail with the following line

iPhone Developer: ambiguous (matches "iPhone Developer: Your Name (ABC123DEF45)" and "iPhone Developer: Your Name (123ABC456DE)"

A solution to get the right certificate even with multiple ones is this short script. For sure this is not ideal, but as of my knowledge you have no chance to get the certificate that Xcode found and uses for signing your .app.

echo "codesign --verify --force --sign \"$CODE_SIGN_IDENTITY\" \"$CODESIGNING_FOLDER_PATH\""
IDENTITIES=`security find-identity -v -s "Code Signing" | grep "iPhone Developer" | awk '{ print $2 }'`

for SHA in $IDENTITIES; do
    codesign --verify --force --sign $SHA "$CODESIGNING_FOLDER_PATH"
    if [ $? -eq 0 ]; then
        echo "Matching identity found: $SHA"
        exit 0
    fi
done;

exit 1
Petry answered 24/7, 2014 at 9:19 Comment(0)
N
4

I got bitten by this, too and had no success with any of the other workarounds. I then cleaned up my provisioning profiles on the devices itself by deleting all of them related to my app as well as all the wildcard profiles (this seems to be the point). To do this, go to the "Devices" Window in Xcode and right-click your (connected) phone:

Click on "Show provisioning profiles" and delete the related ones, and especially the team profiles:

including the ones with the asterisk. After reinstallation the app, everything went back to normal.

Nikos answered 12/10, 2015 at 16:30 Comment(3)
This helped me to run app from Xcode and continue development process.Airy
When building an AdHoc release you can check which PPs are used. if you see any XC: profiles, delete those, and refresh your PP!Olga
I can see how this might be a factor. What a mess in there!! Doing some fall clean-upTransducer
D
3

I have fixed this problem (I think). I had a wildcard provisioning profile on my device that showed it did not have a valid signing identity. I also had a provisioning profile for my app that was valid. When I deleted the wildcard profile, I stopped getting the -34018 errors.

I also made sure that the code signing identity and provisioning profile listed in the Code Signing section of the Build Settings of the target were identical to the one for the app (not the generic "iPhone Developer" one)

Disintegrate answered 6/8, 2014 at 0:30 Comment(1)
Similar to this fixed it for me. Set project-level code signing to "iPhone Developer" for Debug and "iPhone Distribution" for Release. I then removed the overrides on the main target so they show the same. Before, saving in the keychain was failing 100% of the time. Afterwards, saving in the keychain appears to be stable.Ulcerous
M
2

I was getting -34018 error in my app (iOS 8.4) very rarely. After some investigation I've found that this issue occurs when the app requests data from keychain too often.
For example, in my situation it was two read requests for one specific key at the same time from different application modules.
To fix that I've just added caching this value in memory

Mccay answered 16/9, 2015 at 6:29 Comment(0)
D
1

I was having the same problem, out of the blue, running on a test device with Xcode 6.2, iPhone 6, iOS 8.3. To be clear, this was not experienced while running Xcode tests, but rather while running the actual app on my device. In the simulator it was fine, and running on the app itself it had been perfectly fine until recently.

I tried all of the suggestions I could find here, such as removing the provisioning profiles on my device (I removed ALL of them), temporarily enabling the Keychain Sharing capability in my project (even though we don't really need that), making sure my development account in Xcode was totally refreshed with all of the certificates and provisioning profiles, etc. Nothing helped.

Then I temporarily changed the accessibility level from kSecAttrAccessibleAfterFirstUnlock to kSecAttrAccessibleAlwaysThisDeviceOnly, ran the app, and it worked fine and was able to write to the Keychain. Then I changed it back to kSecAttrAccessibleAfterFirstUnlock, and the problem seems to have gone away "permanently."

Defenestration answered 22/6, 2015 at 18:37 Comment(0)
U
1

Just got bitten by this bug on Xcode 8 Beta 3. Turning on Keychain Sharing seems to be the only solution.

Unplug answered 1/8, 2016 at 6:53 Comment(0)
F
1

I had the same issue. Fixed it by setting up Keychain Sharing.

Fanatic answered 4/8, 2016 at 19:44 Comment(0)
P
1

(this is not a direct answer to the OP's question, but might help others)

Started getting the keychain error -34018 consistently in simulator after updating Xcode from version 7.3.1 to 8.0.

Following this tip from daidai's answer,

Some instances of the problem are caused by incorrect app signing. You can easily distinguish this case because the problem is 100% reproducible.

it was discovered that Provisioning Profile had somehow been set to None in the Signing sections of the target.

However, setting the Provisioning Profile fields to valid values was not sufficient to resolve the issue in this case.

Further investigation showed that the Push Notifications entitlement also displayed an error. It said the "Add the Push Notifications feature to your App ID." step was completed, but step "Add the Push Notifications entitlement to your entitlements file" was not.

After pressing "Fix Issue" to fix the Push Notification issue, the keychain error was resolved.

For this particular target, the "Keychain Sharing" entitlement had already been turned on at some previous time. Turning it off has not caused the keychain error to reappear so far, so its not clear whether it is necessary in this case.

Promethean answered 14/9, 2016 at 22:6 Comment(0)
E
0

In iOS 9 I turned off Address Sanitizer and it started working on the device.

Examination answered 14/10, 2015 at 19:37 Comment(0)
B
0

The only solution that worked for me was first storing nil for the specified key, and then storing my new value with a separate operation. It would fail due to error -34018 if I attempted to overwrite the existing value. But as long as I stored nil first, then the updated value would be stored successfully immediately afterwards.

Blindheim answered 24/10, 2015 at 1:53 Comment(0)
B
0

I met this -34018 issue today when running SecItemDelete API. What I did to fix this is: 1. Following @k1th solution https://mcmap.net/q/181730/-secitemadd-and-secitemcopymatching-returns-error-code-34018-errsecmissingentitlement 2. Run the SecItemDelete in main thread(Previously it's read from main thread, so just align this with deleting).

Sorry it comes back again :(

Bipropellant answered 7/3, 2016 at 13:10 Comment(0)
L
0

Turn on Keychain sharing in your project's capabilities, it should solve the problem. enter image description here

Laclair answered 8/12, 2016 at 13:8 Comment(0)
R
0

What worked for me

  • Turn on Keychain Sharing.
  • Use the keychain as less as possible and cache the data in memory, UserPreferences, disk, etc.
  • Retry many times the keychain CRUD operations if these failed.
  • Use DispatchQueue.sync for storing/deleting/updating the data.
Ruwenzori answered 19/9, 2018 at 11:0 Comment(0)
F
0

For me it was an app signing issue. I simply switched to the correct signing team in Xcode and the error no longer occurred

Flashback answered 24/7, 2019 at 15:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.