PKCS#11 libraries and the SSH Agent

Jakob Weisblat jakobw at
Tue Aug 2 08:16:30 AEST 2016


I have 2 questions/suggestions regarding the behavior of ssh-agent
with PKCS#11 libraries. The first concerns authenticating with a
certificate and a smartcard key.

As far as I can tell, the following is a reasonable and useful
authentication mechanism but not currently 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

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 (public key is on server,
private key is in hardware, accessed through PKCS#11 library) with
provide a certificate from a certificate authority allowing login with
a given public key 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
        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 private key 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
private key, or am amenable to implementing other proposed solutions,
depending on what feedback I get on this.


My second concern regards the behavior of `ssh-add -D`. 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
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`.
 - somehow get the list of loaded PKCS#11 libraries and send
SSH_AGENT_REMOVE_SMARTCARD_KEY for each one in addition to current
behavior on `ssh-add -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)


Jakob Weisblat
Paranoid Labs
Yahoo! Inc

More information about the openssh-unix-dev mailing list