Re-adding PKCS#11 key in ssh-agent produces "agent refused operation" error.

Jacob Hoffman-Andrews jsha at letsencrypt.org
Sat Feb 22 14:53:18 AEDT 2020


Hi all,

Thanks for all your hard work! I was particularly excited to see
FIDO/U2F support in the latest release.

I'd like to make the following bug report in ssh-agent's PKCS#11 support:

Steps to reproduce:

1. Configure a smart card (e.g. Yubikey in PIV mode) as an SSH key.
2. Add that key to ssh-agent.
3. Remove that key from ssh-agent.
4. Add that key to ssh-agent.

Expected results:

Key is successfully added to ssh-agent.

Actual results:

ssh-add fails with "agent refused operation".

I've looked at the code, and it appears that register_pkcs11_provider
(https://github.com/openssh/openssh-portable/blob/master/ssh-pkcs11.c#L1470)
fails if a PKCS#11 provider already exists. However, PKCS#11 providers
are never unloaded. There is a pkcs11_del_provider but it is never called.

That means that after deleting a key, there is no way to re-add it. Also, since
removing a USB smartcard reader results in ssh-agent losing its session, the
user must call ssh-add again after reinserting the USB card reader, and that
second ssh-add will fail in the same way.

I think the best fix here is to treat "provider already exists" as a non-error.
There is no need to unload providers when they become unused because they
don't use very much memory, and because it is uncommon to have more than one
provider on any given system. Also, a user is likely to reuse a provider they
have previously used.

If a maintainer can confirm that this is an acceptable fix, I may be able to
write a patch.

Environments reproduced on: Ubuntu 19.10, Fedora
Version of OpenSSH: git commit b2491c28, latest at time of writing.

Example output demonstrating the problem (with a Yubikey in PIV mode inserted):

 $ SSH_AUTH_SOCK=/tmp/ssh-dhfNCpXwSk8B/agent.21022; export SSH_AUTH_SOCK;
 $ ssh-add -s /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so
Enter passphrase for PKCS#11:
Could not add card "/usr/lib/x86_64-linux-gnu/opensc-pkcs11.so": agent
refused operation
 $ SSH_AUTH_SOCK=/tmp/ssh-RORElJeiiHBc/agent.21116; export SSH_AUTH_SOCK;
 $ ssh-add -s /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so
Enter passphrase for PKCS#11:
Card added: /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so
 $ ssh-add -D
All identities removed.
 $ ssh-add -s /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so
Enter passphrase for PKCS#11:
Could not add card "/usr/lib/x86_64-linux-gnu/opensc-pkcs11.so": agent
refused operation

In a separate terminal:

 $ ./ssh-agent -d
SSH_AUTH_SOCK=/tmp/ssh-RORElJeiiHBc/agent.21116; export SSH_AUTH_SOCK;
echo Agent pid 21116;
debug2: fd 3 setting O_NONBLOCK
debug2: fd 4 setting O_NONBLOCK
debug1: process_message: socket 1 (fd=4) type 20
debug1: process_add_smartcard_key: add
/usr/lib/x86_64-linux-gnu/opensc-pkcs11.so
debug1: pkcs11_start_helper: starting /usr/local/libexec/ssh-pkcs11-helper -vvv
debug1: process_add
debug1: provider /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so:
manufacturerID <OpenSC Project> cryptokiVersion 2.20
libraryDescription <OpenSC smartcard framework> libraryVersion 0.19
debug1: provider /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so slot 0:
label <SSH key> manufacturerID <piv_II> model <PKCS#15 emulate> serial
<00000000> flags 0x40d
debug1: have 1 keys
debug1: pkcs11_k11_free: parent 0x5598092d2f30 ptr 0x5598092d2b10 idx 1
debug1: pkcs11_provider_unref: 0x559809258df0 refcount 2
debug2: fd 4 setting O_NONBLOCK
debug1: process_message: socket 1 (fd=4) type 19
debug1: process_message: socket 1 (fd=4) type 9
debug2: fd 4 setting O_NONBLOCK
debug1: process_message: socket 1 (fd=4) type 20
debug1: process_add_smartcard_key: add
/usr/lib/x86_64-linux-gnu/opensc-pkcs11.so
debug1: process_add
debug1: check 0x559809258df0 /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so
debug1: pkcs11_register_provider: provider already registered:
/usr/lib/x86_64-linux-gnu/opensc-pkcs11.so


More information about the openssh-unix-dev mailing list