Hello, I forgot to mention one other issue in my previous e-mail about the ssh-agent documentation for U2F keys. Right now, https://raw.githubusercontent.com/openssh/openssh-portable/master/PROTOCOL.u2f <https://raw.githubusercontent.com/openssh/openssh-portable/master/PROTOCOL.u2f> has the following text:> ssh-agent requires a protocol extension to support U2F keys. At > present the closest analogue to Security Keys in ssh-agent are PKCS#11 > tokens, insofar as they require a middleware library to communicate with > the device that holds the keys. Unfortunately, the protocol message used > to add PKCS#11 keys to ssh-agent does not include any way to send the > key handle to the agent as U2F keys require.However, the extension described there has nothing to do with sending the key handle. In fact, all of the necessary fields (public key, application, flags, and key_handle) are all already encoded in the private key blob (and appended to the certificate blob when certificates are being imported). The extension only communicates the path to the middleware library to use, not the additional key information such as the key handle. If you had ssh-agent pick up the location of the middleware library when the ssh-agent was started (from the environment and/or a command-line option), you wouldn?t actually need clients talking to the agent to use ADD_ID_CONSTRAINED when sending requests. Alternately, if you want clients to be able to set this library on a per-request basis, you could support the proposed constraint for this purpose but fall back to the provider set when ssh-agent started up and/or to the ?internal? provider that OpenSSH has built-in, avoiding the need for either the agent client or the agent itself to have to specify anything to get SK keys to work in the common case. An unmodified client sending a normal ADD_IDENTITY request would work just fine in this case, as long as it sent the new SK format private key blob. As an aside, I also noticed that sending the new constraint when importing non-SK keys seems to cause the add operation to fail. That?s easy enough to prevent in the client code, but the code would be simpler if it was always safe to add the extension (when a middleware path was available) regardless of the type of key being added. -- Ron Frederick ronf at timeheart.net
On Sat, 7 Dec 2019, Ron Frederick wrote:> Hello, > > I forgot to mention one other issue in my previous e-mail > about the ssh-agent documentation for U2F keys. Right now, > https://raw.githubusercontent.com/openssh/openssh-portable/master/PROTOCOL.u2f > has the following text: > > > ssh-agent requires a protocol extension to support U2F keys. At > > present the closest analogue to Security Keys in ssh-agent are PKCS#11 > > tokens, insofar as they require a middleware library to communicate with > > the device that holds the keys. Unfortunately, the protocol message used > > to add PKCS#11 keys to ssh-agent does not include any way to send the > > key handle to the agent as U2F keys require. > > However, the extension described there has nothing to do with sending > the key handle. In fact, all of the necessary fields (public key, > application, flags, and key_handle) are all already encoded in > the private key blob (and appended to the certificate blob when > certificates are being imported). The extension only communicates > the path to the middleware library to use, not the additional key > information such as the key handle.That text explains why it was not possible to use the PKCS#11 token- related messages that already exist in the ssh-agent protocol.> If you had ssh-agent pick up the location of the middleware library > when the ssh-agent was started (from the environment and/or a > command-line option), you wouldn?t actually need clients talking > to the agent to use ADD_ID_CONSTRAINED when sending requests.It was a goal to support multiple providers concurrently, e.g. a user who has some keys on a USB security key and others on a BLE one.> Alternately, if you want clients to be able to set this library on a > per-request basis, you could support the proposed constraint for this > purpose but fall back to the provider set when ssh-agent started up > and/or to the ?internal? provider that OpenSSH has built-in, avoiding > the need for either the agent client or the agent itself to have > to specify anything to get SK keys to work in the common case. An > unmodified client sending a normal ADD_IDENTITY request would work > just fine in this case, as long as it sent the new SK format private > key blob.I don't think providing that sort of backwards compatibility buys anything because both the agent and the client need to support the security key formats anyway.> As an aside, I also noticed that sending the new constraint when > importing non-SK keys seems to cause the add operation to fail. That?s > easy enough to prevent in the client code, but the code would be > simpler if it was always safe to add the extension (when a middleware > path was available) regardless of the type of key being added.IMO it doesn't generally make sense for the agent to be liberal in what it accepts :) -d
On Dec 10, 2019, at 2:34 PM, Damien Miller <djm at mindrot.org> wrote:> On Sat, 7 Dec 2019, Ron Frederick wrote: >> I forgot to mention one other issue in my previous e-mail >> about the ssh-agent documentation for U2F keys. Right now, >> https://raw.githubusercontent.com/openssh/openssh-portable/master/PROTOCOL.u2f >> has the following text: >> >>> ssh-agent requires a protocol extension to support U2F keys. At >>> present the closest analogue to Security Keys in ssh-agent are PKCS#11 >>> tokens, insofar as they require a middleware library to communicate with >>> the device that holds the keys. Unfortunately, the protocol message used >>> to add PKCS#11 keys to ssh-agent does not include any way to send the >>> key handle to the agent as U2F keys require. >> >> However, the extension described there has nothing to do with sending >> the key handle. In fact, all of the necessary fields (public key, >> application, flags, and key_handle) are all already encoded in >> the private key blob (and appended to the certificate blob when >> certificates are being imported). The extension only communicates >> the path to the middleware library to use, not the additional key >> information such as the key handle. > > That text explains why it was not possible to use the PKCS#11 token- > related messages that already exist in the ssh-agent protocol.Ah, I think I see what you meant now. The PKCS#11 message SSH_AGENTC_ADD_SMARTCARD_KEY can?t be used as it isn?t called on a per-key basis. It was intended to be called once and have the smart card automatically add all the keys inside it, providing the necessary public key data back to the agent, and that?s not possible with U2F/FIDO2 keys.>> If you had ssh-agent pick up the location of the middleware library >> when the ssh-agent was started (from the environment and/or a >> command-line option), you wouldn?t actually need clients talking >> to the agent to use ADD_ID_CONSTRAINED when sending requests. > > It was a goal to support multiple providers concurrently, e.g. a > user who has some keys on a USB security key and others on a BLE one.Understood - thanks.>> Alternately, if you want clients to be able to set this library on a >> per-request basis, you could support the proposed constraint for this >> purpose but fall back to the provider set when ssh-agent started up >> and/or to the ?internal? provider that OpenSSH has built-in, avoiding >> the need for either the agent client or the agent itself to have >> to specify anything to get SK keys to work in the common case. An >> unmodified client sending a normal ADD_IDENTITY request would work >> just fine in this case, as long as it sent the new SK format private >> key blob. > > I don't think providing that sort of backwards compatibility buys > anything because both the agent and the client need to support the > security key formats anyway.It wasn?t so much about backward compatibility as it was about simplifying the implementation. Existing agent client implementations could be practically unchanged as long as they had an abstraction to ask keys for the SSH-encoded private data or the private data to append to the end of a cert (which AsyncSSH did). However, if your goal is to allow a single agent to be able to simultaneously access keys via different middleware libraries, I agree that you need something like what you currently have. -- Ron Frederick ronf at timeheart.net