| Summary: | ssh-keygen when creating sk fido keys does not create sufficient data for attestation verification. | ||
|---|---|---|---|
| Product: | Portable OpenSSH | Reporter: | William Brown <william.brown> |
| Component: | ssh-keygen | Assignee: | Assigned to nobody <unassigned-bugs> |
| Status: | NEW --- | ||
| Severity: | normal | CC: | djm, pedro |
| Priority: | P5 | ||
| Version: | 9.1p1 | ||
| Hardware: | All | ||
| OS: | All | ||
|
Description
William Brown
2023-01-03 18:29:54 AEDT
I don't think that's correct - these are not webauthn, but FIDO2 credentials (which is built on top of FIDO2 but adds additional encapsulation). I'm pretty sure that it's possible to verify ssh-keygen's attestation. Adding Pedro as he knows way more about this than me. The webauthn attestation sections are reflections of their underlying standards in most cases. However, for FIDO2 the attestation format is defined in the Webauthn standard. For FIDO2, and more specifically CTAP2, this is discussed here: https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-errata-20220621.html#op-makecred-step-rk """ Step 19: Generate an attestation statement for the newly-created credential using clientDataHash, taking into account the value of the enterpriseAttestation parameter, if present, as described above in Step 9. ... attStmt (0x03) ... The attestation statement, as specified in [WebAuthn]. """ Thus the document and structure I linked is the correct one. With this in mind, the lack of a clientDataHash in the attest output created by ssh-keygen means verification of an attestation is not possible as the FIDO2 device itself will be signing the concatenation of authenticatorData and clientDataHash. Since this will likely constitute a change to the attest blob format that ssh-keygen produces, this is also why I made the other suggestions to altering the format as currently the format as it stands is not able to create or validate ECDAA attestation either. The client data part of the attestation payload can be specified out-of-band through ssh-keygen -O challenge=, https://man.openbsd.org/ssh-keygen#challenge. Regarding different attestation statement formats, intermediate or root certificates, and other data required to attest a credential: in most cases involving USB or NFC security keys, the format will be "packed" or "fido-u2f", and the root CA published by the vendor of the security key (e.g. https://developers.yubico.com/U2F/yubico-u2f-ca-certs.txt). What is current in place should be enough to satisfy that scenario. Going forward, we might want to embed the attestation format and the entire attestation statement (fido_cred_fmt() and fido_cred_attstmt_ptr() respectively) in the attestation blob. > The client data part of the attestation payload can be specified out-of-band through ssh-keygen -O challenge=, https://man.openbsd.org/ssh-keygen#challenge. This doesn't help when the challenge *isn't* specified though, meaning that if attestation is requested, challenge either has to be a mandatory argument and ssh-keygen should error or that the challenge needs to be added to the attestation format so that the attestation can be validated. > in most cases involving USB or NFC security keys, the format will be "packed" or "fido-u2f", and the root CA published by the vendor of the security key (e.g. https://developers.yubico.com/U2F/yubico-u2f-ca-certs.txt). What is current in place should be enough to satisfy that scenario. In packed https://w3c.github.io/webauthn/#sctn-packed-attestation the specification states: """ x5c The elements of this array contain attestnCert and its certificate chain (if any), each encoded in X.509 format. The attestation certificate attestnCert MUST be the first element in the array. """ However the current attest format that is created by ssh-keygen does not contain the full x5c chain, it only contains the attestation (leaf) certificate meaning that it is not always true that the vendors CA certificate is sufficient to validate the attestation since the chain may be missing. > Going forward, we might want to embed the attestation format and the entire attestation statement (fido_cred_fmt() and fido_cred_attstmt_ptr() respectively) in the attestation blob. Yes this would resolve the issues I have raised with regard to x5c chains as well as the current inability to validate ecdaa attestations (which do not use x5c). > This doesn't help when the challenge *isn't* specified though,
> meaning that if attestation is requested
Attestation without a verifier-specified challenge is pretty worthless, as otherwise there is no guarantee of freshness, or conversely, it would allow replay of prior attestations.
(In reply to Damien Miller from comment #5) > > This doesn't help when the challenge *isn't* specified though, > > meaning that if attestation is requested > > Attestation without a verifier-specified challenge is pretty > worthless, as otherwise there is no guarantee of freshness, or > conversely, it would allow replay of prior attestations. Then when attestation is requested, it should be an error to also not provide a challenge parameter. |