Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

piv-tool: Fix RSA key generation #3158

Merged
merged 1 commit into from
Jun 13, 2024
Merged

Conversation

invis-z
Copy link
Contributor

@invis-z invis-z commented May 25, 2024

params = OSSL_PARAM_BLD_to_param(bld) was called twice, once inside if condition and once after the if. Removed the second one to resolve issue generating RSA keys with OpenSSL 3.0.

Someone else please verify this is the correct fix, I am far from understanding all the code and only did some preliminary tests to check if it is working after the fix.

Also, maybe consider adding a test for piv-tool inside the piv test routine (with PivApplet)?

Fixes #3156

Checklist
  • Documentation is added or updated
  • New files have a LGPL 2.1 license statement
  • PKCS#11 module is tested
  • Windows minidriver is tested
  • macOS tokend is tested

@dengert
Copy link
Member

dengert commented May 25, 2024

Tested using Yubikey 4 with PIV applet with OpenSC master and OpenSSL 3.2.1 on Ubuntu 22.04.

Copy link
Member

@Jakuje Jakuje left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch! Thanks!

You mentioned you tested this with Yubikey, does the piv-took key generation work also with the applet in CI, so we could use the piv-tool for enrollment instead of (or in addition to) the yubico-piv-tool?

@dengert
Copy link
Member

dengert commented May 27, 2024

I did use my enrolment scripts which call piv-tool to test this patch.

The OpenSC piv-tool could be used, but many of the operations such as deleting a cert or setting a pin are done using -s "apdu" option. Creating some objects such as a CHUID are done via a separate program which has not been generally published.

(There used to be a WIKI pages with all of this, but I can't find it. Any way to find deleted WIKI pages?)

The piv-tool when generating a key saves the public key to a file and scripts must be used to create a certificate either self signed or via a certificate request signed using libp11. if pkcs15-piv.c does not find a certificate on the card it will look for an environment variable pointing at the saved public key. https://github.com/OpenSC/OpenSC/blob/master/src/libopensc/pkcs15-piv.c#L1023-L1072

Yubikey piv tool when generating a key writes a dummy certificate to the card as part of the key gen process, which simplifies the process.

One main difference between Yubikey piv tool and piv-tool is piv-tool expects objects to be written (other then a certificate) to be contained in the 7E or 5C tag and length. Yubikey piv tool wraps the input in 7E or 5C.

piv-tool can take a certificate and optionally gzip it and place in a certificate object and write the certificate object to the card.

The piv-tool was written in 2004 to do the minimal needed to write to test cards, not to be a general support tool, as PIV cards at that time were only issued by government agencies and card vendors provided the card management systems.

I have no real interest it trying to make any substantial changes to piv-tool.

I did provide my enrolment scripts to my employer at the time to be used to generate temporary PIV cards, for new hires while waiting for a gov issued card, or a card that broke, was lost, or was left at home. The PIV cards tmp or gov issued were used to authenticate to Active Directory, so these people could still get some work done.

@invis-z
Copy link
Contributor Author

invis-z commented May 27, 2024

good catch! Thanks!

You mentioned you tested this with Yubikey, does the piv-took key generation work also with the applet in CI, so we could use the piv-tool for enrollment instead of (or in addition to) the yubico-piv-tool?

Yes, that is actually how I did my preliminary test. I modified .github/test-piv.sh to use github actions to test key generation (with PivApplet). I am not familiar with the CI tools used here so I just read the log to find if there is a key.

However, the problem here is to generate the certificate, as I don't see how to use piv-tool to sign the self-signed cert with only the key slot number. I am not very familiar with all the tools so there is a high chance that I missed something.

I tried to get around this by generating a temporary CA and sign a dummy cert with the correct pubkey, load the certificate to the correct slot, use openssl with pkcs11-module to generate another self-signed certificate (now the slot can be accessed because it has a corresponding certfiicate), and load that cert to the slot again. I was able make it work without ever needing yubico-piv-tool.

@dengert
Copy link
Member

dengert commented May 27, 2024

One way to generate a certificate or certificate request is by using PKCS11. The CKA_ID of the certificate, public key and private key are the same. In my test scripts I used the openssl , CA.pl and openssl.conf with a pkcs11 engine or provider.
Since the PIV card did not have a certificate, the public key was passed by the env variable as outlined in: https://github.com/OpenSC/OpenSC/blob/master/src/libopensc/pkcs15-piv.c#L1023-L1072

The test scripts would make a copy of openssl.conf and using sed make changes based on the username, email, which CKA_ID and other extensions to sign a CSR which was then sent to an AD CA or my test CA which used CA.pl to call openssl to sign the CSR and create a certificate using a test CA certificate. The certificate was then loaded onto the card using piv-tool.
All of this was run on Linux.

@invis-z
Copy link
Contributor Author

invis-z commented May 28, 2024

So, if I am understanding correctly, since there is no deletion needed in test-piv.sh, the following code provides the same functionality in the test (if openssl is already configured to use pkcs11 provider):

PIN="123456"
yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P "$PIN" -s 9e -a generate -A RSA2048 | tee 9e.pub
yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P "$PIN" -s 9e -S'/CN=barCard/OU=test/O=example.com/' -averify -aselfsign < 9e.pub | tee 9e.cert
yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P "$PIN" -s 9e -aimport-certificate < 9e.cert
yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P "$PIN" -s 9a -a generate -A RSA2048 | tee 9a.pub
yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P "$PIN" -s 9a -S'/CN=bar/OU=test/O=example.com/' -averify -aselfsign < 9a.pub | tee 9a.cert
yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P "$PIN" -s 9a -aimport-certificate < 9a.cert
yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P "$PIN" -s 9c -a generate -A ECCP256 | tee 9c.pub
yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P "$PIN" -s 9c -S'/CN=bar/OU=test/O=example.com/' -averify -aselfsign < 9c.pub | tee 9c.cert
yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P "$PIN" -s 9c -aimport-certificate < 9c.cert
yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P "$PIN" -s 9d -a generate -A ECCP256 | tee 9d.pub
yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P "$PIN" -s 9d -S'/CN=bar/OU=test/O=example.com/' -averify -aselfsign < 9d.pub | tee 9d.cert
yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P "$PIN" -s 9d -aimport-certificate < 9d.cert

PIN="123456"
echo '01:02:03:04:05:06:07:08:01:02:03:04:05:06:07:08:01:02:03:04:05:06:07:08' > key
export PIV_EXT_AUTH_KEY="$(pwd)/key"

piv-tool -v -A A:9B:03 -G 9E:07 -o 9e.pub
export PIV_9E_KEY="$(pwd)/9e.pub"
openssl req -key "pkcs11:id=%04;type=private;pin-value=$PIN" -subj "/CN=barCard/OU=test/O=example.com/" -new -x509 -out 9e.cert
piv-tool -v -A A:9B:03 -C 9E -i 9e.cert

piv-tool -v -A A:9B:03 -G 9A:07 -o 9a.pub
export PIV_9A_KEY="$(pwd)/9a.pub"
openssl req -key "pkcs11:id=%01;type=private;pin-value=$PIN" -subj "/CN=bar/OU=test/O=example.com/" -new -x509 -out 9a.cert
piv-tool -v -A A:9B:03 -C 9A -i 9a.cert

piv-tool -v -A A:9B:03 -G 9C:11 -o 9c.pub
export PIV_9C_KEY="$(pwd)/9c.pub"
openssl req -key "pkcs11:id=%02;type=private;pin-value=$PIN" -subj "/CN=bar/OU=test/O=example.com/" -new -x509 -out 9c.cert
piv-tool -v -A A:9B:03 -C 9C -i 9c.cert

piv-tool -v -A A:9B:03 -G 9D:11 -o 9d.pub
export PIV_9D_KEY="$(pwd)/9d.pub"
openssl req -key "pkcs11:id=%03;type=private;pin-value=$PIN" -subj "/CN=bar/OU=test/O=example.com/" -new -x509 -out 9d.cert
piv-tool -v -A A:9B:03 -C 9D -i 9d.cert

@Jakuje
Copy link
Member

Jakuje commented May 28, 2024

(There used to be a WIKI pages with all of this, but I can't find it. Any way to find deleted WIKI pages?)

The whole wiki pages history should be here: https://github.com/OpenSC/Wiki. Searching through git I managed to find
PivTool.textile which was destroyed with OpenSC/Wiki@58193e3

I vaguely remember we discussed that this was more confusing users than helping as it could not do all the operations the Yubico piv tool could do, but the commit message is not very descriptive.

So, if I am understanding correctly, since there is no deletion needed in test-piv.sh, the following code provides the same functionality in the test (if openssl is already configured to use pkcs11 provider):

Thanks! This looks reasonable. But if I am right, the pkcs11-provider is not yet in standard ubuntu repositories (especially not in the old images in GH actions) so we would need to build it as part of the CI (instead of the yubico-piv-tool).

The only thing I found is ppc64el version in universe: https://packages.ubuntu.com/noble/ppc64el/libs/pkcs11-provider

I think this does not have to happen now in this PR, but at very least, we should create an issue with the notes from here as they are certainly helpful for writing the test.

Copy link
Contributor

@xhanulik xhanulik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please fix the spelling errors.

@invis-z
Copy link
Contributor Author

invis-z commented May 29, 2024

Please fix the spelling errors.

All the spelling error is not related to this PR, I only deleted one line of code.

`params = OSSL_PARAM_BLD_to_param(bld)` was called twice, once inside `if` condition and once after the `if`. 
Removed the second one to resolve issue generating RSA keys with OpenSSL 3.0.
@invis-z
Copy link
Contributor Author

invis-z commented Jun 5, 2024

Rebased so that there shouldn't be typo anymore.

@Jakuje
Copy link
Member

Jakuje commented Jun 13, 2024

Created separate issue for the tests #3181 and merging this not to delay the fix even mode.

Thank you for your contribution!

@Jakuje Jakuje merged commit 1685f37 into OpenSC:master Jun 13, 2024
45 checks passed
OpenSC 0.26.0 automation moved this from In progress to Done Jun 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Development

Successfully merging this pull request may close these issues.

Unable to generate RSA key using piv-tool
5 participants