ssh-agent: loading a PKCS#11 library without a private key on disk

jweisblat at jweisblat at
Fri Jul 22 10:48:18 AEST 2016

As far as I can tell, the following is a reasonable and useful authentication mechanism but not curently implemented in OpenSSH's agent, but possible with the most recent client version. I'd like to propose an addition to the agent protocol to allow this authentication mechanism.
The authentication mechanism: certificate-based authentication combined with a PIV smartcard for the key. That is, store the private key in PIV hardware, which is currently supported in the agent for use with traditional public-key authentication (publickey is on server, private key is in hardware, accessed through PKCS#11 library) with SSH_AGENTC_ADD_SMARTCARD_KEY and SSH_AGENTC_REMOVE_SMARTCARD_KEY, but provide a certificate from a certificate authority allowing login with a given publickey for a certain amount of time with certain usernames, etc.
This is currently allowed by having a certificate on the filesystem and referencing it with an IdentityFile directive in .ssh/config, but it breaks with agent forwarding. It's impossible with the status quo to add a certificate to the agent without the private key - the protocol doesn't allow it:

 RSA certificates may be added with this request:
 byte SSH2_AGENTC_ADD_IDENTITY or SSH2_AGENTC_ADD_ID_CONSTRAINED string "ssh-rsa-cert-v00 at" string certificate mpint rsa_d mpint rsa_iqmp mpint rsa_p mpint rsa_q string key_comment constraint[] key_constraints
Adding a certificate to the agent requires adding privatekey material as well. I'd be willing to implement a new method for adding a smartcard with associated certificate, or I'd be willing to implement a mechanism for adding RSA certificates without a corresponding privatekey, or am alternate to other proposed solutions, depending on what feedback I get on this.
Jakob WeisblatParanoid LabsYahoo! Inc

I've included a plaintext copy of my previous email, which was garbled by my mailserver upon conversion to plaintext, below.
Several of my coworkers and I, as well as others, have been confused by the behavior of `ssh-add -D`. From the man page:
     -D      Deletes all identities from the agent.
The current behavior of `ssh-add -D` is to send SSH2_AGENTC_REMOVE_ALL_IDENTITIES and SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES to the agent, removing all the keys from the agent, including any keys added via PKCS#11 libraries. However, the PKCS#11 library is still loaded in the agent, and it won't be unloaded (and thus fails to be reloaded, with an unhelpful error) unless SSH_AGENTC_REMOVE_SMARTCARD_KEY is sent, and that takes a parameter of the specific PKCS#11 library involved.
Is this behavior the intended behavior of `ssh-add -D`? If it is, we'd be happy to introduce a patch to improve the error message to suggest trying to remove it first.
If not, I can imagine several solutions, which we'd be happy to implement, depending on which the community thinks is best:
 - change the behavior of the agent to remove the smartcard in addition to the corresponding identity when SSH2_AGENTC_REMOVE_ALL_IDENTITIES is run. This is somewhat inideal in the case of that identity being used with protocol version 1. - add a new agent command SSH_AGENTC_REMOVE_ALL_SMARTCARD_KEYS in addition to SSH_AGENTC_REMOVE_SMARTCARD_KEY that removes all smartcard keys, modify the agent to accept it and modify ssh-add to send it in addition to the other 2 commands on `ssh -D`.
Here is a demonstration of current behavior:
[~]$ ssh-add -l  The agent has no identities.[~]$ ssh-add -s /usr/local/lib/libykcs11.dylib  Enter passphrase for PKCS#11:  Card added: /usr/local/lib/libykcs11.dylib[~]$ ssh-add -l  2048 SHA256:cJUGM7tTnFD9a0BpI936ERA3Ay+/MFu3huzB+APPoZs /usr/local/lib/libykcs11.dylib (RSA)[~]$ ssh-add -D  All identities removed.[~]$ ssh-add -l  The agent has no identities.[~]$ ssh-add -s /usr/local/lib/libykcs11.dylib # Add the card back into the agent, it wasn't unloaded by   Enter passphrase for PKCS#11:  Could not add card "/usr/local/lib/libykcs11.dylib": agent refused operation[~]$ ssh-add -l  The agent has no identities.[~]$ ssh-add -e /usr/local/lib/libykcs11.dylib  Card removed: /usr/local/lib/libykcs11.dylib[~]$ ssh-add -l  The agent has no identities.[~]$ ssh-add -s /usr/local/lib/libykcs11.dylib  Enter passphrase for PKCS#11:  Card added: /usr/local/lib/libykcs11.dylib[~]$ ssh-add -l  2048 SHA256:cJUGM7tTnFD9a0BpI936ERA3Ay+/MFu3huzB+APPoZs /usr/local/lib/libykcs11.dylib (RSA)[~]$

More information about the openssh-unix-dev mailing list