iOS Keychain writing value results in error code -34018 - ios

I have an iOS application that stores some sensitive information in the keychain.
While writing values into the keychain, I am getting error code -34018.
I am currently using Apple's iOS KeyChainItemWrapper class.
Both of the following lines of code receive the same error code.
OSStatus res1 = SecItemCopyMatching((__bridge CFDictionaryRef)genericPasswordQuery, (CFTypeRef *)&attributes);
OSStatus res = SecItemUpdate((__bridge CFDictionaryRef)updateItem, (__bridge CFDictionaryRef)tempCheck);
This issue does not occur every time, but intermittently. Once I get this error, I am no longer able to write any values to the keychain.
I have printed the error description like so:
NSError *error = [NSError errorWithDomain:NSOSStatusErrorDomain code:res userInfo:nil];
and this is what the error prints out:
Error: Error Domain=NSOSStatusErrorDomain Code=-34018 "The operation couldn’t be completed. (OSStatus error -34018.)"

Seems like this is a bug in Keychain, which only appears when you launch your app from xcode. See here: https://github.com/soffes/sskeychain/issues/52
We debugged it a lot and it seems an issue accessing the keychain when
the app is launched from the background. This is only happening with
the debugger (i.e. when launched from Xcode). We think the issue
might be related in our case to the debugger keeping alive the app
even if it should be killed by the OS. We tried in fact to run the
app and then put it in background and launch many other app to occupy
RAM. With the debugger the bug came up when resuming the app from the
background, while without the debugger it didn't (we did run at least
10 tests each).

If someone will come here back with this error and XCode8 with iOS10, probably you have to enable KeyChain Share in the tab Capabilities:

As others have mentioned, this is a Keychain bug, one that Apple is aware of and has been aware of since at least mid-2015.
As of March 22, 2016, however, Apple has said:
We believe these problems were resolved in iOS 9.3.
iOS 9.3 was released on March 21, 2016.
See the thread: https://forums.developer.apple.com/thread/4743
To quote the response by an Apple employee:
Mar 22, 2016 3:28 AM
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

This held me up for 2 hours before I found a quick "fix" - reboot the iOS device
A quote from the discussion at http://forums.developer.apple.com/thread/4743,
From user littledetails
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.
When I rebooted my device the error went away, allowing me to continue testing. Not sure what else to do. In my situation, moving to NSUserDefaults or some other storage solution was not a possibility.

One way to get around this issue with the keychain is to use dispatch_async to allow the app to launch. This works when the app is opened from the background. Also make sure you have the kSecAttrAccessibleAfterFirstUnlock accessibility setting on the keychain.
dispatch_async(dispatch_get_main_queue(), ^{
// save/write to keychain
})

I am using GenericKeychain classes from apple:
https://developer.apple.com/library/content/samplecode/GenericKeychain/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007797-Intro-DontLinkElementID_2
struct KeychainConfiguration {
static let serviceName = "MyAppService"
/*
Specifying an access group to use with `KeychainPasswordItem` instances will create items shared accross both apps.
For information on App ID prefixes, see:
https://developer.apple.com/library/ios/documentation/General/Conceptual/DevPedia-CocoaCore/AppID.html
and:
https://developer.apple.com/library/ios/technotes/tn2311/_index.html
*/
// static let accessGroup = "[YOUR APP ID PREFIX].com.example.apple-samplecode.GenericKeychainShared"
/*
Not specifying an access group to use with `KeychainPasswordItem` instances
will create items specific to each app.
*/
static let accessGroup: String? = nil
}
In this file I was specifying my custom accessGroup in this line static let accessGroup = "[YOUR APP ID PREFIX].com.example.apple-samplecode.GenericKeychainShared"
After returning to static let accessGroup: String? = nil the problem was gone. :)

Make sure keychain sharing must on under Capabilities in project Target.
In my case the App_Name.entitlements file has different bundle id than of my project bundle id. So, I change bundle id in the App_Name.entitlements file as of my project bundle id.
e.g., Suppose your project bundle id is com.Apple.testApp then got to
App_Name.entitlements file open key Keychain Access Groups key which is of Array type.
Under item0 set value of your project bundle id as eg:- $(AppIdentifierPrefix)com.Apple.testAp.

According to #iCaramba's answer. I've found a workaround:
Stop the task to kill the app (if you are already running the app)
Launch the app on your device manually. DO NOT use Xcode
Use Xcode to re-launch the app

Related

Keychain returned the following status: -34018 [duplicate]

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.
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
Basically you have to codesign your .xcttest 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.
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.
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.
Try disabling all breakpoints when launching the app from Xcode.
You can enable them afterwards.
(None of the above workarounds worked for me)
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.
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
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.
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)
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
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."
Just got bitten by this bug on Xcode 8 Beta 3. Turning on Keychain Sharing seems to be the only solution.
I had the same issue. Fixed it by setting up Keychain Sharing.
(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.
In iOS 9 I turned off Address Sanitizer and it started working on the device.
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.
I met this -34018 issue today when running SecItemDelete API.
What I did to fix this is:
1. Following #k1th solution https://stackoverflow.com/a/33085955/889892
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 :(
Turn on Keychain sharing in your project's capabilities, it should solve the problem.
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.
For me it was an app signing issue. I simply switched to the correct signing team in Xcode and the error no longer occurred

Keychain error -34018, unable to delete current dictionary

I have an app that is written in Swift 2.3. The app uses the KeychainItemWrapper that makes accessing the Keychain simpler.
When I run the app in the iOS 9.3 simulator with Xcode, the app runs as expected and there are no issues reading/writing to the keychain.
The same exact app, without any changes in my code, crashes with the call to:
- (void)resetKeychainItem
With the line:
SecItemDelete((__bridge CFDictionaryRef)tempDictionary);
Thus making this NSAssert give me my error:
NSAssert( junk == noErr || junk == errSecItemNotFound, #"Problem deleting current dictionary." );
Researching this error by the code 34018 pointed me to other posts with users experiencing a bug with the keychain that was actually brought to the attention of the devs at Apple. It was made a high priority bug, and one post suggested iOS 9.3 had a fix for this (my app works on iOS 9.3!).
However, it is my understanding that Xcode 8 handles such things as code signing differently than previous versions. So I wonder if with iOS 10 if this is a possible new bug.
If anyone has any ideas or experience with this error on iOS 10/Xcode 8... please share your suggestions.

iOS 10 with XCode 8 GM caused NSUserDefaults to intermittently not work

NOTE: I have seen many other posts on Stack Overflow about NSUserDefaults being renamed to UserDefaults in Swift or not working on simulator until a restart. This is not a duplicate by anyway. Many of the questions SO is tagging against is from 4 years ago. My question is specific to iOS 10 from this year as this has always worked in older versions. I have mentioned in my question already that my question is not a duplicate of those questions as those were simulator bugs in swift and my issue is on device objective C bug. Please read the questions before marking as duplicate
My issue is different as I am able to reproduce this on objective C and on physical device itself.
I created a brand new project from scratch for this test. I placed this code in the viewDidLoad of a view controller:
if (![[NSUserDefaults standardUserDefaults] valueForKey:#"checkIfInitialized"]){
NSLog(#"setting checkIfInitialized as not exist");
[[NSUserDefaults standardUserDefaults] setValue:#"test" forKey:#"checkIfInitialized"];
[[NSUserDefaults standardUserDefaults] synchronize];
self.view.backgroundColor=[UIColor redColor];
self.mylabel.text=#"NSUserDefaults was NOT there, try running again";
} else {
NSLog(#"checkIfInitialized exists already");
self.view.backgroundColor=[UIColor blueColor];
self.mylabel.text=#"NSUserDefaults was already there this time, try running again";
}
Now if I run the app about 10 times, few times it finds the checkIfInitialized and sometimes it doesn't. No exact number on how many times it fails as it might work 3 times then fail next 2 times then work 4 times and fail once and so on.
Now something I have noticed (not 100% sure though) that the issue only seems to happen when I am testing connected via Xcode. If I run by launching the app by clicking the app icon on device without Xcode, then it seems to work fine but I can't be 100% sure.
I noticed this error occur sometimes:
[User Defaults] Failed to write value for key checkIfInitialized in CFPrefsPlistSource<0x1700f7200> (Domain: com.xxxx.appname, User: kCFPreferencesCurrentUser, ByHost: No, Container: (null)): Path not accessible, switching to read-only
I have this very simple project on my dropbox if you want to test it out.
I would suggest testing about 10-15 times to reproduce this issue.
https://www.dropbox.com/s/j7vbgl6e15s57ix/nsuserdefaultbug.zip?dl=0
This works completely fine on iOS 9 so definitely something to do with iOS 10.
EDIT
Bug logged: 28287988
Response from apple DTS team:
First off, you should first determine whether standardUserDefaults or
valueForKey is failing. My guess is that “standardUserDefaults” is
returning NULL and, if that’s the case, then that’s something you
should be guarding against generally. Notably, standardUserDefaults
will return NULL if the preference file is encrypted in the
environment the app is currently running in (for example, preferences
is set to “NSFileProtectionComplete” and the app is running in the
background). That shouldn’t be an issue for standard foreground-only
apps, but it’s something to be aware of anyway.
It’s very likely that Xcode is actually inducing the problem here.
Xcode vastly complicates the app launching environment in a way that’s
VERY different than a standard app launch. My guess is that this is
basically being triggered by Xcode’s timing inducing an an expected
situation during the app launch, but if you want a more formal test of
that try setting a single breakpoint in applicationDidFinishLaunching
and continuing in the debugger as soon as you hit it. My guess is
just adding that disrupts the timing enough to stop the problem from
happening. Sort of. It’s iOS 10 only in the sense that iOS 9 will
never print that log message, but that’s because the log message was
added in iOS 10. The code itself is similar enough to iOS 9.3 that I
suspect exactly the same behavior is (at least in theory) possible in
iOS 9.
Yes, this is definitely a reproducible bug.
It happens with the GM release of Xcode 8 and iOS 10.
It is not the linked question referring to Swift.
It is not the linked question referring to beta versions of the Simulator.
The bug happens on devices and on the Simulator. It is intermittent: saving will work six times and then fail. Unlike you, I did not get the "failed to write key" message.
The bug also occurs when operating directly on the device without Xcode. This is in fact how I discovered it.
You should report a bug to Apple, especially since you have a short program that will reproduce it. I will do the same.
One key difference: In my case the failure is in writing the default. The previously written value remains in NSUserDefaults. Sometimes one key is successfully written while another is unchanged.
A similarly very intelligent DTS response from my own support request. Basically, killing using Xcode is more murderous than anything that would naturally happen on the device (even the double-Home-click-and-upswipe method) and since everything is abruptly crashed when Xcode halts it, the lazy writing of NSUserDefaults can fail, or be only half completed.
And indeed, pure on-device testing of the app, without Xcode involved, shows that everything does get correctly written to NSUserDefaults when the app is terminated.
I have closed my own bug report.

SecItemAdd and SecItemCopyMatching returns error code -34018 (errSecMissingEntitlement)

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.
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
Basically you have to codesign your .xcttest 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.
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.
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.
Try disabling all breakpoints when launching the app from Xcode.
You can enable them afterwards.
(None of the above workarounds worked for me)
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.
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
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.
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)
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
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."
Just got bitten by this bug on Xcode 8 Beta 3. Turning on Keychain Sharing seems to be the only solution.
I had the same issue. Fixed it by setting up Keychain Sharing.
(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.
In iOS 9 I turned off Address Sanitizer and it started working on the device.
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.
I met this -34018 issue today when running SecItemDelete API.
What I did to fix this is:
1. Following #k1th solution https://stackoverflow.com/a/33085955/889892
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 :(
Turn on Keychain sharing in your project's capabilities, it should solve the problem.
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.
For me it was an app signing issue. I simply switched to the correct signing team in Xcode and the error no longer occurred

iOS Keychain SecItemAdd returns -25243

I'm working on updating an iPhone application with a minor change in its default configuration. It's been awhile since I've built it last, though, and so I've upgraded Xcode to 4.2 and included iOS 5 support in the latest builds.
When I go to test on the device, I get the following assertion error:
2011-11-02 20:57:18.869 RoseBandwidth[903:707] Tried to add item, got result: -25243
2011-11-02 20:57:18.870 RoseBandwidth[903:707] *** Assertion failure in -[KeychainItemWrapper writeToKeychain], /Users/tim/code/RoseBandwidth/Classes/KeychainItemWrapper.m:312
2011-11-02 20:57:18.872 RoseBandwidth[903:707] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Couldn't add the Keychain Item.'
I'm using the implementation of the KeychainItemWrapper class from Apple's GenericKeychain project. It's worth noting that this error only shows up on the device, not in the Simulator (and I'm aware of the access group restriction differences between platforms, but usually I thought that caused problems on the Simulator, not actual hardware).
Why would I be getting this error back? I've touched nothing relevant to the keychain-related parts of the app; it stores and retrieves data exactly like it used to.
Okay, I couldn't quite get your project to build, but from How to share keychain data between iOS applications I think you might want to check your entitlements file. At least in the github project you didn't have anything specified in the Keychain Access Groups.
For future searchers who happen to end up here, another possible cause of the -25243 error (which means No access control, BTW) is running on the simulator.
My best theory is the app's provisioning profile (or the signature thereof) is how the app knows what its bundle seed is. And the bundle seed needs to be part of the your keychain's access group name. But apps run on the simulator don't get signed, and so have a missing (or different?) bundle seed than you specified keychain-access-group.
Or something. It's all so poorly documented, it's hard to tell what's what. Just try running it on a device and see if that helps.
For those of you getting this error and trying to achieve "Shared Key Chain Access" between two apps:
You need to create an App Id for your app with same Team Id you selected when you first activated "Shared Keychain Access" in 'Capabilities'. Create your App Id in here:
Apple Member Center
After that you need to create provisioning profile from that App Id and download it to your computer.(Double click it to install to x-code)
I assume you already know you need "App ID Prefix" to access key chain, but for those who don't know:
"App ID Prefix" is unique text identifier associated with your Apple developer account:
To access "SharedKeychain" you need to implement it like this before you try to write or read from keychain
keychainAccessGroupName = "AB123CDE45.myKeyChainGroup":
You can check out this tutorial for further info:Share Keychain between iOS apps.
Hope that helps.
I get the same error from time to time in the simulator even if I did not touch the code. A reset of the simulator solves the problem for me.
See this question/answer how to reset the simulator: https://stackoverflow.com/a/3442326
As others have pointed out, in device builds error -25243 is often caused by trying to access a keychain access group that you don't have permissions for. (It's missing from your Entitlements.plist file or your provisioning profile.)
But in the simulator there can be another cause. The simulator doesn't support keychain access groups at all, so if you set the kSecAttrAccessGroup property on a keychain item and try to write it you'll get this -25243 error code.
FYI, Apple's GenericKeychain sample code has this comment:
// Ignore the access group if running on the iPhone simulator.
//
// Apps that are built for the simulator aren't signed, so there's no keychain access group
// for the simulator to check. This means that all apps can see all keychain items when run
// on the simulator.
//
// If a SecItem contains an access group attribute, SecItemAdd and SecItemUpdate on the
// simulator will return -25243 (errSecNoAccessForItem).
This worked for me when I used a production certificate and provisioning profile. Using debug did not work.
In my experience, I get that return value -25243 when I realized that I was trying to pass kSecMatchLimit with kSecMatchLimitOne and kSecReturnData with kCFBooleanTrue values to the SecItemAdd() function. I removed those and double checked the app ids and provisioning profiles and everything is good.
I am not sure if this is helpful or not, but in my experience if you will use SecItemAdd() function for shared keychain access, those two parameters must not be there.

Resources