I'm trying to write an application to interact with an API which authenticates requests using a signature from an SSH key. Currently targeting macOS 10.15. Running on iOS eventually might be nice, but that's way, way down my list of priorities right now.
I generated a test key using this command:
ssh-keygen -f ./test_id_ecdsa -t ecdsa -b 521 -m pem
Here is the actual key data (it will never be used for anything but testing key import):
-----BEGIN EC PRIVATE KEY-----
MIHbAgEBBEFaaU0VdcgDi+me65TnhRo9+AodcV5DOfbi8UteeDpojXW5PfkKXNQ+
qJlAyA0nVmkJlrwSOlqSH7XGzHuOTu+nd6AHBgUrgQQAI6GBiQOBhgAEAZMhoDRn
GAeReuc4sKEq3fznP1rPZ4QDdwpNfxQbPLe0rzg4fk+J6BPlyQs74RfHtXxiHOiL
3GZJLzo/pPbi96z7AG1AEABHWCcmi/uclGsjg0wNuKuWHwY8bJGvHZIBtd+px5+L
6L0wg93uMy3o2nMEJd01n18LGvjdl3GUvgq2kXQN
-----END EC PRIVATE KEY-----
The key has no passphrase. OpenSSL is able to work with it. Here is what OpenSSL says about it:
➜ ~ openssl ec -in ./test_id_ecdsa -text
read EC key
Private-Key: (521 bit)
priv:
5a:69:4d:15:75:c8:03:8b:e9:9e:eb:94:e7:85:1a:
3d:f8:0a:1d:71:5e:43:39:f6:e2:f1:4b:5e:78:3a:
68:8d:75:b9:3d:f9:0a:5c:d4:3e:a8:99:40:c8:0d:
27:56:69:09:96:bc:12:3a:5a:92:1f:b5:c6:cc:7b:
8e:4e:ef:a7:77
pub:
04:01:93:21:a0:34:67:18:07:91:7a:e7:38:b0:a1:
2a:dd:fc:e7:3f:5a:cf:67:84:03:77:0a:4d:7f:14:
1b:3c:b7:b4:af:38:38:7e:4f:89:e8:13:e5:c9:0b:
3b:e1:17:c7:b5:7c:62:1c:e8:8b:dc:66:49:2f:3a:
3f:a4:f6:e2:f7:ac:fb:00:6d:40:10:00:47:58:27:
26:8b:fb:9c:94:6b:23:83:4c:0d:b8:ab:96:1f:06:
3c:6c:91:af:1d:92:01:b5:df:a9:c7:9f:8b:e8:bd:
30:83:dd:ee:33:2d:e8:da:73:04:25:dd:35:9f:5f:
0b:1a:f8:dd:97:71:94:be:0a:b6:91:74:0d
ASN1 OID: secp521r1
NIST CURVE: P-521
writing EC key
-----BEGIN EC PRIVATE KEY-----
MIHbAgEBBEFaaU0VdcgDi+me65TnhRo9+AodcV5DOfbi8UteeDpojXW5PfkKXNQ+
qJlAyA0nVmkJlrwSOlqSH7XGzHuOTu+nd6AHBgUrgQQAI6GBiQOBhgAEAZMhoDRn
GAeReuc4sKEq3fznP1rPZ4QDdwpNfxQbPLe0rzg4fk+J6BPlyQs74RfHtXxiHOiL
3GZJLzo/pPbi96z7AG1AEABHWCcmi/uclGsjg0wNuKuWHwY8bJGvHZIBtd+px5+L
6L0wg93uMy3o2nMEJd01n18LGvjdl3GUvgq2kXQN
-----END EC PRIVATE KEY-----
I am trying to import it as a SecKey with the eventual goal of getting it into a CryptoKit P521 key. This is my current Swift code:
let sshPrivateText:String = """
MIHbAgEBBEFaaU0VdcgDi+me65TnhRo9+AodcV5DOfbi8UteeDpojXW5PfkKXNQ+
qJlAyA0nVmkJlrwSOlqSH7XGzHuOTu+nd6AHBgUrgQQAI6GBiQOBhgAEAZMhoDRn
GAeReuc4sKEq3fznP1rPZ4QDdwpNfxQbPLe0rzg4fk+J6BPlyQs74RfHtXxiHOiL
3GZJLzo/pPbi96z7AG1AEABHWCcmi/uclGsjg0wNuKuWHwY8bJGvHZIBtd+px5+L
6L0wg93uMy3o2nMEJd01n18LGvjdl3GUvgq2kXQN
"""
let ecdsaPrivateKeyData:Data = Data(base64Encoded: sshPrivateText, options: .ignoreUnknownCharacters)!
var secKeyCreateWithDataError: Unmanaged<CFError>?
let secKeyAttributes:Dictionary = [kSecAttrKeyType: kSecAttrKeyTypeECDSA,
kSecAttrKeyClass: kSecAttrKeyClassPrivate,
kSecAttrKeySizeInBits: 521] as [CFString : Any]
let ecdsaSecKey = SecKeyCreateWithData(ecdsaPrivateKeyData as CFData, secKeyAttributes as CFDictionary, &secKeyCreateWithDataError)!
The force unwrap at the end is intended, as I want the call to crash while I'm learning. The SecKeyCreateWithData call is failing with the error "EC private key creation from data failed", but no further details. I suspect I'm doing something dumb which will be obvious to somebody more experienced than me.
Can anybody tell me what I'm doing wrong and what I need to research to fix it?