Yubico / yubico-piv-tool

Command line tool for the YubiKey PIV application
https://developers.yubico.com/yubico-piv-tool
BSD 2-Clause "Simplified" License
289 stars 97 forks source link

SSH with libykcs11.so does not work with 4096 bit RSA keys #502

Closed peto59 closed 3 weeks ago

peto59 commented 1 month ago

Hello.

I generate RSA key pair and import them with this snippet of commands: openssl genrsa -out private_key.pem 4096 openssl rsa -in private_key.pem -outform PEM -pubout -out public_key.pem yubico-piv-tool -s 9a -a import-key -i private_key.pem yubico-piv-tool -a verify-pin -a selfsign-certificate -s 9a -S "/CN=SSH key/" -i public_key.pem -o cert.pem ssh-keygen -i -m pkcs8 -f public_key.pem > ssh.pem.pub ssh-copy-id -f -i ssh.pem.pub <user>@<ip>

Afterwards I import the certificate into yubikey with yubico authenticator (tried with yubikey manager and got same result). Then I try to connect with ssh -I /usr/lib/libykcs11.so <user>@<ip> of which output is: Enter PIN for 'YubiKey PIV #<redacted>': cannot find private key pkcs11_get_key failed sign_and_send_pubkey: signing failed for RSA "/CN=SSH key": error in libcrypto

This only happens with 4096 bit keys. 2048 and 3072 bit keys work fine. Is the problem on my side or is this expected behaviour?

yubikey: YubiKey 5 NFC yubico-piv-tool: 2.5.2 ssh: OpenSSH_9.8p1, OpenSSL 3.3.1 4 Jun 2024 openssl: OpenSSL 3.3.1 4 Jun 2024 (Library: OpenSSL 3.3.1 4 Jun 2024) OS: ArchLinux Kernel: 6.9.7-arch1-1

peto59 commented 1 month ago

Interesting... If the key is generated on yubikey it works even with 4096 bits. I generated it with yubico authenticator, exported certificate, extracted public key with openssl x509 -pubkey -in cert.crt -noout > public_key.pem and converted it to ssh format.

This doesn't work for me as I want to have the same private key on 2 yubikeys in case of losing or breaking one, but posting just in case it can give you some clues.

joanandk commented 4 weeks ago

Hi, I am using Yubikey 5c NFC. Imported RSA 4096 and ED25519 keys do not work (RSA 3072 works). My usecase is also to have a spare indentical Yubikey in case of if one breaks. Would be nice if the issue gets fixed as soon as possible.

BR

aveenismail commented 4 weeks ago

Does the certificate import return any error? If you run yubico-piv-tool -a status after certificate import, does it list the content of slot 9a?

Out of curiosity, is there a reason for importing the certificate with Yubico Authenticator or YubiKey Manager rather than yubico-piv-tool? Not that it should make a difference

peto59 commented 4 weeks ago

the output of yubico-piv-tool -a status is: Version: 5.7.1 Serial Number: <redacted> CHUID: <redacted> CCC: No data available Slot 9a: Algorithm: RSA4096 Subject DN: CN=SSH key Issuer DN: CN=SSH key Fingerprint: 02f2e11c78a53d53bfa24a9f7df68df4988c984d330bbca2456da16d2ba61784 Not Before: Aug 14 12:43:22 2024 GMT Not After: Aug 14 12:43:22 2025 GMT PIN tries left: 3

Output is identical when using yubico-piv-tool -a import-certificate -s 9a -i cert.pem to import certificate and not GUI. I haven't noticed any errors when importing either private key or certificate.

As for the reason to use GUI, there's none, just a bit of misunderstanding. I've been trying to do this for a few days before I created an issue. For the first time, I did this purely with CLI and got the same error so I assumed that the act of importing certificate has overwritten private key and I needed to use PKCS12 to import them at the same time. so I switched to importing through GUI (especially authenticator because it shows whether private key is present) and just made a habit of it. Kind of stupid assumption but it was the first time I ever held any Yubikey.

aveenismail commented 4 weeks ago

It was not a stupid assumption, we can try to make the documentation clearer :)

Can you set the environment variable YKCS11_DBG to any value higher than 1 then run the ssh -I /usr/lib/libykcs11.so command? Please post the output here (removing any sensitive data if there are any).

peto59 commented 4 weeks ago

It was not a stupid assumption, we can try to make the documentation clearer :)

Thank you :). The documentation is fine, it was mostly the error that it cannot find private key that led me to my assumption. But what I'd appreciate is some way to check if private key is present like Yubico Autheticator is capable of doing, but that's topic for another time.

And now for the debug log. I've set YKCS11_DBG to 2 and tried to connect Currently only slot 9a contains any private key or certificate The log is huge so I used pastebin, if you prefer something else just let me know. https://pastebin.com/HA90cJpm

aveenismail commented 3 weeks ago

As far as I can tell from the debug output and some tests, it seems to be looking for a certificate but it can't find it for some reason. Just to eliminate some scenarios, the imported certificate is an X509 certificate, correct?

aveenismail commented 3 weeks ago

Never mind. I remembered that it's the selfsigned cert produced by the YubiKey so it's definitely an X509.

Running some more tests

aveenismail commented 3 weeks ago

Instead of converting the public key produced by OpenSSL, can you download it from the YubiKey instead and use that with ssh just in case it's a format issue? Use the following command to download the public keys from the YubiKey

ssh-keygen -D /usr/lib/libykcs11.so

peto59 commented 3 weeks ago

running ssh-keygen -D /usr/lib/libykcs11.so gave me 2 ssh keys. First one is Public key for PIV Attestation and second one is identical to the one obtained by ssh-keygen -i -m pkcs8 -f public_key.pem > ssh.pem.pub except it has /CN=SSH key at the end.

I tried copying only the one with /CN=SSH key at the end which gave exactly same output as before.

Then I tried copying both of them and connecting which produced the output of

Enter PIN for 'YubiKey PIV #<redacted>': 
C_Sign failed: 7
sign_and_send_pubkey: signing failed for RSA "Public key for PIV Attestation": error in libcrypto
cannot find private key
pkcs11_get_key failed
sign_and_send_pubkey: signing failed for RSA "/CN=SSH key": error in libcrypto

I deleted ~/.ssh/authorized_keys each time to start with clean slate.

joanandk commented 3 weeks ago

I am too getting successful login with RSA 2048 and RSA 3072, but RSA 4096 stops with the message "error in libcrypto". I have tried with openSC and RSA 4096 doesn't work there either. The RSA 4096 key on the disk successfully connects to the remote server. So I would say PKCS11 seems to be the culprit here.

phonexicum commented 3 weeks ago

I also having trouble using yubikey 5.7.1 with libykcs11.so pkcs11 library to work with RSA 4096. I have:

  1. generated self-signed RSA4096 with openssl and imported key and certificate into yubikey's 9a slot
  2. cloned yubico-piv-tool repository and build it with -DYKCS11_DBG=9
  3. run p11tool --provider /usr/local/lib/libykcs11.so --list-privkeys --login --set-pin 123456
    • here is the debug output: https://pastebin.com/raw/6qw2rT2Y
    • this is the output of the p11tool without debug output (it doesn't list the rsa 4096 at 9a slot, but lists the rsa 2048 attest key)
      Object 0:
          URL: pkcs11:model=YubiKey%20YK5;manufacturer=Yubico%20%28www.yubico.com%29;serial=29507445;token=YubiKey%20PIV%20%2329507445;id=%19;object=Private%20key%20for%20PIV%20Attestation;type=private
          Type: Private key (RSA-2048)
          Label: Private key for PIV Attestation
          Flags: CKA_PRIVATE; CKA_NEVER_EXTRACTABLE; CKA_SENSITIVE; 
          ID: 19
aveenismail commented 3 weeks ago

It looks like this was a bug that got pass our tests. The next release scheduled for tomorrow should contain a fix. Please let us know if the problem still persist.