iOS 10 crypto not working on simulator

This particular piece of code (minus the setup code) generate a 2048 key pair


sanityCheck = SecKeyGeneratePair((__bridge CFDictionaryRef)keyPairAttr, &publicKeyRef, &privateKeyRef);


It works wonderfully on iOS 9 simulator, iOS 9 device, iOS 10 device, but not iOS 10 simulator.


Was there any change in the iOS 10 simulator prevent it from working?


The error while calling this function on iOS 10 simulator is -34018


thanks

jerry

Replies

-34018 is

errSecMissingEntitlement
, indicating an entitlements problem. However, the simulator doesn’t support entitlements, so this is clearly a bug and I’ve filed it as such (r. 28297379).

ps Here’s the code I was testing with.

func SecKeyGeneratePair(_ parameters: [String:AnyObject]) throws -> (publicKey: SecKey, privateKey: SecKey) {
    var publicKey: SecKey? = nil
    var privateKey: SecKey? = nil
    let err = Security.SecKeyGeneratePair(parameters as CFDictionary, &publicKey, &privateKey)
    guard err == errSecSuccess else {
        print(err)
        throw NSError(domain: NSOSStatusErrorDomain, code: Int(err), userInfo: nil)
    }
    return (publicKey!, privateKey!)
}

let keyID = UUID().uuidString
let keyPair = try? SecKeyGeneratePair([
    kSecAttrKeyType as String:      kSecAttrKeyTypeRSA,
    kSecAttrKeySizeInBits as String: 2048 as NSNumber,
    kSecAttrIsPermanent as String:  true as NSNumber,
    kSecAttrLabel as String:        keyID as NSString
])
print(keyPair)

Built with Xcode 8, it works on the iOS 9 simulator but fails on the iOS 10 simulator.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

-34018 is errSecMissingEntitlement, indicating an entitlements problem. However, the simulator doesn’t support entitlements, so this is clearly a bug and I’ve filed it as such (r. 28297379).

OK, that was interesting. My bug has come back to me as Behaves Correctly. It seems that the iOS 10 and related simulators do support entitlements. As such, you should fix this problem by code signing your app for the simulator, just like you do for the device. I tried this out myself and it works a treat.

I’ve filed a new bug against Xcode to get the project templates updated to reflect this reality (r. 28338972).

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
As such, you should fix this problem by code signing your app for the simulator, just like you do for the device.  I tried this out myself and it works a treat.


Do you mind elaborating what you mean by code signing for the simulator? Is this invoked via the console codesign tool?

Just go into your Project Build Settings and switch Code Signing Identity -> Debug -> Any iOS SDK to "Don't Code Sign".

A newly created Xcode project for iOS has the Code Signing (`CODESIGNIDENTITY) build setting set like this:

//:configuration = Debug
CODE_SIGN_IDENTITY[sdk=iphoneos*] = iPhone Developer

//:configuration = Release
CODE_SIGN_IDENTITY[sdk=iphoneos*] = iPhone Developer

//:completeSettings = some
CODE_SIGN_IDENTITY

This only signs the app if you’re building for the device. I set it to this:

//:configuration = Debug
CODE_SIGN_IDENTITY = iPhone Developer

//:configuration = Release
CODE_SIGN_IDENTITY = iPhone Developer

//:completeSettings = some
CODE_SIGN_IDENTITY

This signs the app for both device and simulator builds.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

This wasn't enough for me. I also had to enable the "Keychain Sharing" capability as suggested here:

https://forums.developer.apple.com/thread/60617

Thanks, I did get it to work. I had to delete and reinstall the app (to trigger the keychain item being stored in our app's scenario) though because I'm assuming the Keychain items stored before code signing will not be visible.

Same here. It does not work without enabling Keychain Sharing.

That doesn't solve the problem at all when you are using the keychain with Unit Testing inside a Framework which is NOT included inside an app.

There is no workaround this so far ....


And over it, I get an error message that logic test can't run on the device and I should use the simulator instead. Neato.


OSStatus: The operation couldn’t be completed. (OSStatus error -34018.)

Right. That’s a separate problem, caused by the fact that unit test are actually run by an executable embedded within Xcode (

xctest
) and that that process does not have entitlements. Previously this only inconvenienced folks using interesting entitlements, but now it applies to the keychain as well.

There’s a bug on file about this (r. 14493584) but feel free to file your own bug describing your own specific requirements.

I believe you can work around this by creating a dummy app target that has the appropriate entitlements and then hosting your tests within that (via the Host Application popup in the General tab of the unit test’s target editor). I haven’t tried to do this myself yet; I ran out of time and just decided to run my unit tests in the iOS 9 simulator for the moment )-:

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

For those still struggling with this, particularly those who have required adding keychain sharing to workaround, here is what has been working for me.


The issue seems to be that there must be at least one entitlement in order for Xcode to properly add the "application-identifier" enttilement to the built application. This is why keychain sharing seems to be a solution but it is only indirectly so: any other entitlement seems to work fine.


Take a vanilla application and do a build. During the "Process Product Packaging" build step it will not show any entitlements. Any attempt to use the keychain in the simulator with that application will fail with the -34018 error.


You could add keychain sharing to work around this, as this adds an entitlement, and the final application will contain the keychain-access-group and the application-identifier entitelments. If you do not want to enable keychain sharing you can simply add another entitlement.


For example, I created an entitlements.plist and configured by project to use it for CODE_SIGN_ENTITLEMENTS for a simulator build. This enttilements plist simply adds the get-task-allow (allow a debugger to be attached)


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-/
<plist version="1.0">
    <dict>
        <key>get-task-allow</key>
        <true/>
    </dict>
</plist>


By adding this entitlement, which is a bit unnecessary for a simulator build, the keychain access will work correctly. During the "Process Product Packaging" step you will see output that contains the get-task-allow and application-identifier entitlements now. Abbreviated output from this step show below..


...

Entitlements:
{
    "application-identifier" = "AAABBBCCDDD.com.company.MyBundleID";
    "get-task-allow" = 1;
}

...


You can now successfully run your application in the simualtor and you did not have to configure any unwanted entitlements such as keychain sharing.


This strikes me as a bug in Xcode 8 whereby it should always be adding the application-identifier entitlement for simulator builds.

The issue seems to be that there must be at least one entitlement in order for Xcode to properly add the "application-identifier" enttilement to the built application.

Right.

This strikes me as a bug in Xcode 8 whereby it should always be adding the application-identifier entitlement for simulator builds.

Right. Since I last posted on this thread I’ve been back and forth with both Security and Xcode engineering about this issue, and I eventually uncovered a bug report (r. 26953315) that’s exactly this.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Hi Eskimo

We have an sdk which uses this feature(keychain). Our product (which is out there) is breaking on ios10 simulators. Can we know what are the timelines when we can expect this to get fixed?


Thanks

Rahul

Can we know what are the timelines when we can expect this to get fixed?

I can’t speculate about the future.

Presumably your SDK has instructions that tell your clients how to integrate the SDK into their product; if I were in your shoes I’d update those instructions to account for this issue.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

I can’t speculate about the future.

I just noticed that the release notes for the Xcode 8.1 GM seed now touches on this issue:

Keychain APIs may fail to work in the Simulator if your entitlements file doesn’t contain a value for the application-identifier entitlement. (28338972)

Workaround: Add a user-defined build setting to your target named

ENTITLEMENTS_REQUIRED
and set the value to
YES
. This will cause Xcode to automatically insert an application-identifier entitlement when building.

I haven’t tried this myself yet.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"