The support for PKCS#11 in ssh-agent is limited to the smart cards that are not removed from the computer. Once removed and reinserted one needs to do the same also with the agent: ssh-add -e /usr/lib64/opensc-pkcs11.so ssh-add -s /usr/lib64/opensc-pkcs11.so The ssh-agent interface is limited so there is no way to request the re-authentication from user, but it would be nice if this would happen automatically, if the agent fails to provide ssh-signature from the card. I might have some better look into this issue later.
We are making extensive use of PKCS#11 support in OpenSSH to meet governmental multi-factor authentication requirements. Issues like this one make it much more cumbersome than necessary to use smart cards and would be great to see fixed. Thanks.
Created attachment 3196 [details] proposed patch There was some progress that we are able to get the relogin in case of the smart card was removed between before the invocation of the C_Sign(). The attached patch implements the check in the ssh-pkcs11-helper, which allows to ask for the pin using SSH_ASKPASS (because of missing API that could be used to query the pkcs11 status from either ssh-agent or ssh). I would be glad for any comments, reviews or testing whether this would work for you or there will be need some new API in the ssh-agent.
I'm a bit confused. First off, what version of openssh is this patch for? I had to tweak it a bit to apply to openssh-7.4p1-16.el7 and similar for openssh-7.9p1. Also, with openssh-7.4p1-16.el7 it doesn't appear to do anything for my use case, I still get: debug1: Next authentication method: publickey debug1: Offering RSA public key: /usr/lib64/opensc-pkcs11.so debug3: send_pubkey_test debug3: send packet: type 50 debug2: we sent a publickey packet, wait for reply debug3: receive packet: type 60 debug1: Server accepts key: pkalg rsa-sha2-512 blen 279 debug2: input_userauth_pk_ok: fp SHA256:jBuSAbMlPTbA80YeT6JgUPJcm/c7LIDKV3Sn02UEbrg debug3: sign_and_send_pubkey: RSA SHA256:jBuSAbMlPTbA80YeT6JgUPJcm/c7LIDKV3Sn02UEbrg sign_and_send_pubkey: signing failed: agent refused operation debug1: Offering RSA public key: /usr/lib64/opensc-pkcs11.so debug3: send_pubkey_test debug3: send packet: type 50 debug2: we sent a publickey packet, wait for reply debug3: receive packet: type 51 Tracing through ssh-pkcs11-helper it seems that pkcs11_key_is_present() returns 0, so it does not refresh the key. But RSA_private_encrypt() fails. I'm guessing that I've already invoked C_Sign.
Created attachment 3197 [details] clean patch on current master Sorry, the patch was on top of some other pkcs11 work, that is not yet upstream (sigh ...). I attached a clean one. Unfortunately, the ssh-pkcs11-helper does not provide any sensible way of logging. What smart card are you using and which key? Isn't it the Signature key of the PIV card? The refresh should be invoked only if the smart card was removed since the last login.
Created attachment 3369 [details] updated patch, March 2020 I've applied the patch locally and brought it up to date so it builds with the latest master. I'm interested in fixing the workflow for a token + builtin reader (e.g. a Yubikey in PIV mode), as discussed at https://lists.mindrot.org/pipermail/openssh-unix-dev/2020-February/038317.html. I can confirm that this patch doesn't solve my use case. When I remove and then reinsert my Yubikey, and run `ssh example.com`, I get: ssh-agent: fd 4 setting O_NONBLOCK ssh-agent: process_message: socket 1 (fd=4) type 11 ssh-agent: process_message: socket 1 (fd=4) type 13 ssh-pkcs11-helper: process_sign ssh-pkcs11-helper: check 0x559707702c70 /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so PIV AUTH pubkey ssh-pkcs11-helper: RSA_get_app_data failed for rsa 0x559707776630 ssh-pkcs11-helper: pkcs11_check_obj_bool_attrib: provider 0x55970771b5f0 slot 0 object 94107153503168: attrib 514 = 0 ssh-pkcs11-helper: C_Sign failed: 5 ssh-pkcs11-helper: pkcs11_k11_free: parent 0x5597077700c0 ptr (nil) idx 1 ssh-agent: process_sign_request2: sshkey_sign: error in libcrypto sign_and_send_pubkey: signing failed: agent refused operation I would be curious to hear if the updated patch works for the separate token + reader use case.
What version of OpenSC are you using? This worked fine for removing smart card from reader when I wrote this two years ago. The yubikey is different as it removes also the reader. I was fixing an issue with this in OpenSC some months back: https://github.com/OpenSC/OpenSC/issues/1822 Can you try with recent OpenSC 0.20.0 or master?
I tried with OpenSC 0.20 plus the attached patch, and can confirm it works great. Tested with both an RSA key and a P-256 key.
I wonder if it wouldn't be better to cache the PIN in struct pkcs11_slotinfo and automatically retry it instead of going back to the user via ssh-askpass, which is problematic in the case of ssh-agent.
(In reply to Damien Miller from comment #8) > I wonder if it wouldn't be better to cache the PIN in struct > pkcs11_slotinfo and automatically retry it instead of going back to > the user via ssh-askpass, which is problematic in the case of > ssh-agent. Well ... that would be the other, less secure option. And personally, I am not sure if I would be comfortable using that when I would have known that the pin is sitting somewhere in the memory unencrypted. Especially when we already encrypt private keys, the PIN would be very vulnerable. The other problem might be with some regulations. I probably don't care enough as I have just bunch of testing cards and personal yubikey, but in production when the smart card backed keys are used for accessing production servers, I would be something I would like to avoid.
Created attachment 3415 [details] patch including pin caching (2020) Damien, I rebased the patch on current master and reworked it to cache the pin. Tested locally that it works fine with my yubikey, not asking for pin anymore, but keeping the pin cached in the pkcs11-helper process. It has few additions from previous version, including handling of ECDSA keys correctly and more cleanly failing if the refresh does not work (the card was removed and not yet reinserted).
Hello! I have come across this bug multiple times for multiple different fixes for multiple implementors of a PKCS11Provider. It appears as if Jakub has provided code that does the work here already, but this bug has been sitting around for 4 years. As hardware tokens become more and more relevant in the world of technology, it seems like this would be a solid (and easy since a lot of the work appears to be done) win. It appears there hasn't even been any interaction from the maintainers here at all. What can be done in order to move this forward? Is there a problem with the implementation? Is there a reason you don't want to implement this?