On an old MacBook Pro 2019, I've been trying out Secretive (secretive.dev) to let me use the Touch ID (aka SecureEnclave) as a hardware SSH key, like how I would use Yubikey on other computers.
One of the things I would like to do is to create a certificate authority for key signing, to avoid having to manually add new keys to each host I have to SSH into. The certificate authority needs to tell that the hardware key is indeed generated by some qualified hardware, so the private key cannot be easily exfiltrated. Also, I should not be able to cheat by generating a key pair on a computer, making a copy somewhere, then load the private key onto the hardware token and pretend it was generated there.
Normally, using U2F with SSH gives me the option to generate a key attestation that can then be verified by the CA before signing the public key certificate. Essentially, I tell ssh-keygen to write the attestation to another file as the new key is generated, and the attestation will have to be parsed using a custom script in order to check against the vendor certificates published by FIDO2 Alliance.
There are several ways to generate key from the Secure Enclave:
- Secretive uses CryptoKit SecureEnclave.P256.Signing.PrivateKey to create an ecdsa key in SecureEnclaveStore.swift. This API does not currently generate key attestation.
- SecKeyCreateRandomKey also does not generate key attestation. It appears to be a keychain wrapper around CryptoKit, and it does not necessarily generated the key on Secure Enclave either; it has to be specified in the parameters as
[ kSecAttrTokenID: kSecAttrTokenIDSecureEnclave ]according to Protecting keys with the Secure Enclave. This function also does not generate key attestation. - There is a DeviceCheck.DCAppAttestService with two functions: generateKey and attestKey. The intended purpose is to establish the app's integrity. After generating a key, attestKey will send it to an Apple server over the network and then return an attestation object with the public key. After we validate the attestation object ourselves, the public key can presumably be used by Secretive to perform SSH agent operations.
Note that the Secretive 3.0.4 release notes mentions "GitHub attestation" but that is entirely different. It just says the binary built by GitHub actions will now have provenance.
Even though DeviceCheck.DCAppAttestService seems like a likely candidate to generate attested keys, the fact it requires a validation roundtrip to Apple's server can be problematic. It likely only works for apps uploaded to the App Store (which Secretive is not), and people will not be able to compile their own binaries and expect it to work. I'm also not sure how people may feel that Apple can now keep a record of all their SSH keys.
Probably, it's easier to just buy another Yubikey.
No comments:
Post a Comment