EllipticCurveKeyPair icon indicating copy to clipboard operation
EllipticCurveKeyPair copied to clipboard

"Could not generate keypair." when running on simulator

Open ma-pe opened this issue 6 years ago • 17 comments

Hi! :)

thanks for developing and maintaining this library - this is great!

I just added some code to generate a keypair and sign a digest with it. While this works perfectly on my device (using secure enclave), I have some trouble getting it to run on simulator (using the keychain).

I get this error:

underlying(message: "Could not generate keypair.", error: Error Domain=NSOSStatusErrorDomain Code=-25293 "Could not generate keypair." UserInfo={NSLocalizedRecoverySuggestion=See https://www.osstatus.com/search/results?platform=all&framework=all&search=-25293, NSLocalizedDescription=Could not generate keypair.})

Here is my code:

struct KeyPair {
  static let manager: EllipticCurveKeyPair.Manager = {
    let publicAccessControl = EllipticCurveKeyPair.AccessControl(protection: kSecAttrAccessibleAlwaysThisDeviceOnly, flags: [])
    let privateAccessControl = EllipticCurveKeyPair.AccessControl(protection: kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly, flags: [.userPresence, .privateKeyUsage])
    let config = EllipticCurveKeyPair.Config(
      publicLabel: "n.sign.public",
      privateLabel: "n.sign.private",
      operationPrompt: "N SecureElement",
      publicKeyAccessControl: publicAccessControl,
      privateKeyAccessControl: privateAccessControl,
      publicKeyAccessGroup: nil,
      privateKeyAccessGroup: nil,
      fallbackToKeychainIfSecureEnclaveIsNotAvailable: true
    )
    return EllipticCurveKeyPair.Manager(config: config)
  }()
}

and

do {
      let digest = "some_digest".data(using: .utf8)!
      signature = try KeyPair.manager.sign(digest)
} catch {
...
}

Any ideas what I am doing wrong? Thank you.

ma-pe avatar Feb 19 '18 19:02 ma-pe

Hey. Thanks for the kind words. ❤️

Can you try latest code from master? Seems like you are using release. Which simulator are you using?

hfossli avatar Feb 19 '18 19:02 hfossli

I’m guessing you are using iOS 9 or something? I think your issue has been corrected in master. Sorry about the breaking api changes.

hfossli avatar Feb 19 '18 20:02 hfossli

@hfossli thank you very much for the fast response.

You were right, I was using release. I just updated to master and did the corresponding api-changes.

Testing on device (secure enclave) is still successful. Testing on simulator (keychain) still responds with an error, but now it is another one:

underlying(message: "Could not generate keypair.", error: Error Domain=NSOSStatusErrorDomain Code=-26276 "Could not generate keypair." UserInfo={NSLocalizedRecoverySuggestion=See https://www.osstatus.com/search/results?platform=all&framework=all&search=-26276, NSLocalizedDescription=Could not generate keypair.})

OSStatus.com sais: An internal error occured in the Security framework.

I tried different iPhone simulators featuring iOS 11.2.

ma-pe avatar Feb 19 '18 20:02 ma-pe

Are you on main thread/queue? Try to be on another queue. Can you paste the code?

hfossli avatar Feb 19 '18 21:02 hfossli

Also, make sure you delete and recreate the keys.

hfossli avatar Feb 19 '18 21:02 hfossli

And try with these access flags

let publicAccessControl = EllipticCurveKeyPair.AccessControl(protection: kSecAttrAccessibleAlwaysThisDeviceOnly, flags: [])
            let privateAccessControl = EllipticCurveKeyPair.AccessControl(protection: kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly, flags: {
                return EllipticCurveKeyPair.Device.hasSecureEnclave ? [.userPresence, .privateKeyUsage] : [.userPresence]
            }())

hfossli avatar Feb 19 '18 21:02 hfossli

The code I am using is:

struct KeyPair {
  static let manager: EllipticCurveKeyPair.Manager = {
    let publicAccessControl = EllipticCurveKeyPair.AccessControl(protection: kSecAttrAccessibleAlwaysThisDeviceOnly, flags: [])
    let privateAccessControl = EllipticCurveKeyPair.AccessControl(protection: kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly, flags: {
      return EllipticCurveKeyPair.Device.hasSecureEnclave ? [.userPresence, .privateKeyUsage] : [.userPresence]
    }())
    let config = EllipticCurveKeyPair.Config(
      publicLabel: "n.sign.public",
      privateLabel: "n.sign.private",
      operationPrompt: "n Ident",
      publicKeyAccessControl: publicAccessControl,
      privateKeyAccessControl: privateAccessControl,
      token: .secureEnclave)
    return EllipticCurveKeyPair.Manager(config: config)
  }()
}

No difference for me on different queues :(

How do I remove keys?

ma-pe avatar Feb 20 '18 09:02 ma-pe

do {
      try KeyPair.manager.deleteKeypair()
} catch {
...
}

hfossli avatar Feb 20 '18 09:02 hfossli

Or just delete the app before you install

hfossli avatar Feb 20 '18 09:02 hfossli

Thank you.

I am now deleting the keypair before creating a new one. On device everything works fine, on simulator still the -26276-error.

ma-pe avatar Feb 20 '18 10:02 ma-pe

I will try to recreate the bug on my end. I need xcode version, mac version, simulator version etc.

hfossli avatar Feb 20 '18 15:02 hfossli

That would be great!

macOS High Sierra 10.13.3 XCode Version 9.2 iPhone simulators iOS 11.2 Deployment Target 10.0

do you need anything else?

ma-pe avatar Feb 20 '18 15:02 ma-pe

Xcode build version and swift version would also be useful.

hfossli avatar Feb 20 '18 16:02 hfossli

XCode Version 9.2 (9C40b) Swift 3.2

ma-pe avatar Feb 20 '18 17:02 ma-pe

After studying your README again, I could resolve it: I forgot to replace the token to token: .secureEnclaveIfAvailable.

Thanks for your support!

ma-pe avatar Feb 25 '18 00:02 ma-pe

Ah! That makes sense! Maybe a better error message could be nice in that case. Keeping it open until I fix that. Thanks!

hfossli avatar Feb 25 '18 07:02 hfossli

why can I generate key pair from login screen?

Venkatasatishb avatar Mar 01 '23 08:03 Venkatasatishb