Testing the Keychain - OSStatus error -34018
Asked Answered
A

5

44

I'm trying to test code that reads and alters the keychain using the basic SenTest framework on Xcode. The code works fine on device, but when I start the test I get these errors every time I want to touch the keychain with SecItemDelete/SecItemAdd/etc.

The operation couldn’t be completed. (OSStatus error -34018 - client has neither application-identifier nor keychain-access-groups entitlements)

I have matching wildcard provisioning profiles (iOS Team Provisioning Profile: *) for both the build target and the test target.

These (unconfirmed) stack overflow answers:

Read from keychain results in errSecItemNotFound 25300

say that I need a provisioning profile matching my app identifier every time I use the keychain, but that can't be right, or I'd get the same errors outside of the test target.

Digging deeper, the (unconfirmed) answers here:

SecItemAdd and SecItemCopyMatching returns error code -34018 (errSecMissingEntitlement)

imply that there might be a bug within keychain and more generally Security.framework, which is frankly terrifying.

My question is; has anyone hit OSStatus error -34018 only when they were on a test-target? That appears to be the behavior I am seeing.

EDIT: Adding this answer that JorgeDeCorte used in his answer below.

This thread seems to contain the solution if the problem exits in your unit-test target.

https://devforums.apple.com/message/917498#917498

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.

So I guess the solution is: force sign your test target.

Achromatize answered 27/2, 2014 at 23:32 Comment(0)
T
10

To answer your question: Yes, I experience the same problem. It seems to work fine when running my app. But when I run my XCTests on my device it seems that the keychain returns error -34018. The strange thing is that it doesn't happen when I run the tests on the simulator.

EDIT: I found a solution which I have explained in this answer

Tragedian answered 10/3, 2014 at 14:25 Comment(1)
Could you describe the solution you've linked to, just in case the link ever goes down? Or so we don't have to click through to find it....Jerrybuilt
P
4

I got this error when attempting to run keychain operations via Grand Central Dispatch. Find a way to instantiate your keychain (or keychain wrapper) on the main thread.

//results in code -34018
   static dispatch_once_t token;
    dispatch_once(&token, ^{
        keychain = [[KeychainWrapper alloc] init];

    });

//works fine
keychain = [[KeychainWrapper alloc] init];
Palazzo answered 5/6, 2015 at 14:37 Comment(1)
I've experienced this error when running on the main thread too.Sambo
S
3

I was also unable to run tests that involved the Keychain.

What worked for me was adding a "Host Application" for the tests. You can find this by going to your project targets, tapping "MyTestTarget", click the "General" tab and select a "Host Application" with a drop-down.

I was testing a CocoaTouch Framework so there was no host application for it. I had to create one (ex. "MyFrameworkTestApp") just for the tests.

If that didn't help, you can also try to go to the "Capabilities" tab for the "MyFrameworkTestApp" target and try enabling the "Keychain Sharing" capability.

Spicate answered 28/2, 2019 at 16:3 Comment(1)
Thanks! That helped a lot! I also had to do a slight workaround as my project is structured in subprojects that get built as frameworks and are then imported into the app project. I wanted to test my "Data" subproject which doesn't have a host application. So I added the test class in the main app project tests where the host application was already set. That did the trick.Buckish
P
1

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
Patrolman answered 24/7, 2014 at 9:21 Comment(0)
H
1

I also got the "OSStatus error -34018". I solved it by recreating my provisioning profile.

Hideous answered 14/7, 2015 at 22:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.