Agent protocol changes related to U2F/FIDO2 keys
Damien Miller
djm at mindrot.org
Wed Dec 11 10:36:15 AEDT 2019
On Fri, 6 Dec 2019, Ron Frederick wrote:
> I spent some time today implementing support for loading U2F keys into
> the SSH agent from my AsyncSSH library. I got it working, but along
> the way I ran into a few issues I wanted to report:
>
> First, it looks like the value of SSH_AGENT_CONSTRAIN_EXTENSION has
> changed from the value 3 defined at
> https://tools.ietf.org/html/draft-miller-ssh-agent-02 to the value 255
> now, and somewhere along the way the constraint
> SSH_AGENT_CONSTRAIN_MAXSIGN was defined to use the value 3.
Yes, I had already updated the I-D back in July to fix this collision:
https://tools.ietf.org/html/draft-miller-ssh-agent-03
> Second, https://raw.githubusercontent.com/openssh/openssh-portable/master/PROTOCOL.u2f documents the new extension for loading SK keys as:
>
> byte SSH_AGENT_CONSTRAIN_EXTENSION
> string sk at openssh.com
> string middleware path
> However, the current OpenSSH agent code actually expects to receive:
> byte SSH_AGENT_CONSTRAIN_EXTENSION
> string sk-provider at openssh.com
> string middleware path
oops, I'll fix.
> Also, this documentation doesn’t define the format of the key data
> sent to the agent for SK keys with certificates. Similar to plain
> ECDSA keys with certificates, the key data sent for ECDSA SK keys
> omits the curve_id and Q value of the ECDSA key that would normally be
> written out when serializing a local private key. So, the data sent to
> the agent for an ECDSA SK key with certificate looks like:
>
> string "sk-ecdsa-sha2-nistp256-cert-v01 at openssh.com"
> string nonce
> string curve name
> ec_point Q
> string application
> uint64 serial
> uint32 type
> string key id
> string valid principals
> uint64 valid after
> uint64 valid before
> string critical options
> string extensions
> string reserved
> string signature key
> string signature
> string application
> uint8 flags
> string key_handle
> string reserved
I don't think that's quite right as it has the pubkey/cert expanded rather
than encoded in a string - for all certificates, including sk-* the wire
format for private keys should be:
string key type
string public key (including certificate data)
... private key fields
E.g.
string "sk-ecdsa-sha2-nistp256-cert-v01 at openssh.com"
string pubkey
string application
uint8 flags
string key_handle
string reserved
You're correct that this is not documented in PROTOCOL.u2f. I'll update
that now.
> If the instant was to avoid duplicating what was already in the
> certificate, though, I’m not sure why “application” is sent twice. It
> seems like that should have been left out along with the curve_id and
> Q value, appending only the flags, key_handle, and reserved values
> from the private key at the end.
Yeah, application is accidentally repeated. I don't think that I'll touch
it for now, unless there is some other change that requires changing the
serialisation format.
> I also noticed that
https://raw.githubusercontent.com/openssh/openssh-portable/master/PROTOCOL.u2f
> incorrectly documents the flags value as being a uint32 in the Ed25519
> SK private key encoding:
yes, that's a mistake too. I'll fix that now.
Thanks for the detailed feedback!
-d
More information about the openssh-unix-dev
mailing list