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

Yubikey 5.3+: Add support for PIN policy and touch policy #3071

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

frankmorgner
Copy link
Member

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

@Jakuje
Copy link
Member

Jakuje commented Mar 15, 2024

I have Yubiky 5.4 in the office so I will give it a test run next week.

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.

This wont work as the pin/touch policy is set on the key files and not the pin files. The current code (after going through the issues described inline), I am getting the following response:

P:2605154; T:0x140137054143232 13:55:26.355 [opensc-pkcs11] apdu.c:367:sc_single_transmit: CLA:0, INS:F7, P1:0, P2:80, data(0) (nil)                                                                                                         
P:2605154; T:0x140137054143232 13:55:26.355 [opensc-pkcs11] reader-pcsc.c:324:pcsc_transmit: reader 'Yubico YubiKey OTP+FIDO+CCID 00 00'
P:2605154; T:0x140137054143232 13:55:26.355 [opensc-pkcs11] reader-pcsc.c:325:pcsc_transmit:•
Outgoing APDU (5 bytes):
00 F7 00 80 64 ....d

P:2605154; T:0x140137054143232 13:55:26.355 [opensc-pkcs11] reader-pcsc.c:244:pcsc_internal_transmit: called
P:2605154; T:0x140137054143232 13:55:26.355 [opensc-pkcs11] reader-pcsc.c:334:pcsc_transmit:•
Incoming APDU (12 bytes):                                                                                          
01 01 FF 05 01 01 06 02 03 03 90 00 ............                                                                                                                                                                                             

P:2605154; T:0x140137054143232 13:55:26.355 [opensc-pkcs11] apdu.c:382:sc_single_transmit: returning with: 0 (Success)

The docs say "PIN and Touch policy of the key (keys only)" which means this policy lives only on the key/cert objects and it needs to be touched/pin verified.

The touching requirement on the yubikey worked though so after updating it, I will be able to test it further.

src/libopensc/card-piv.c Outdated Show resolved Hide resolved
src/libopensc/card-piv.c Outdated Show resolved Hide resolved
src/libopensc/card-piv.c Outdated Show resolved Hide resolved
@dengert
Copy link
Member

dengert commented Mar 26, 2024

For whatever it is worth, I wrote this 4 years ago, but no one was interested: https://github.com/dengert/OpenSC/tree/YubiKey5

@frankmorgner
Copy link
Member Author

I fixed the inline comments. Feel free to add more commits on top of this PR (which should work as repo owner).

This wont work as the pin/touch policy is set on the key files and not the pin files

My reading of the documentation is a little different:

  • The policy is tied to the PIN object, that's why it can be read by referencing the slot id, i.e. PIN reference
  • The policy is only evaluated when the key is used. For example, touching the token is only required when some APDU for signing some data has been sent.

Anyway, it should be easy to test.

For whatever it is worth, I wrote this 4 years ago, but no one was interested: https://github.com/dengert/OpenSC/tree/YubiKey5

I don't think that the attestation certificate is the best place to check for the policies. My reading of the documentation is that the initial cert doesn't change when the policies are updated and that users may overwrite the initial cert with custom ones.

@Jakuje
Copy link
Member

Jakuje commented Apr 2, 2024

I fixed the inline comments. Feel free to add more commits on top of this PR (which should work as repo owner).

Thanks. I can try to do that, but first we should agree on the concept of the pin policy, see below. The way how I understand it from reading the manual pages and testing with the yubikey sounds incompatible with what is implemented here.

This wont work as the pin/touch policy is set on the key files and not the pin files

My reading of the documentation is a little different:

* The policy is tied to the PIN object, that's why it can be read by referencing the _slot id_, i.e. PIN reference

I did not find any way to set the pin/touch policy for pins. The only operation that allows setting pin/touch policy is key generation or import as described in the manual page for yubico-piv-tool, which was where I started:

https://developers.yubico.com/yubico-piv-tool/Manuals/yubico-piv-tool.1.html

If you have some reference to the documentation that allows setting policies for PIN objects, I would be happy to test it.

* The policy is only evaluated when the key is used. For example, touching the token is only required when some APDU for signing some data has been sent.

Anyway, it should be easy to test.

Indeed, I tested this and it worked for me, as the operation was not allowed until I touched the token (with the touch policy), but there was no touch policy tag on the pin objects (and I believe it would be on the cert/key object, but I did not test it).

@dengert
Copy link
Member

dengert commented Apr 2, 2024

@Jakuje I agree that the touch policy is set on the key, much like CKA_ALWAYS_AUTHENTICATE method used with the PIV 9C key.

The code from 4 years ago: https://github.com/dengert/OpenSC/tree/YubiKey5 would in effect let user know they may need to touch the token: 06a967b#diff-c951b6f8d354170c2b32ab1f3cc4ae962b09dbef33734ba7fdca5e23c425bf56R1255-R1258

if (has_yubikey_touch_policy) {
			int offset = strlen(label);
			strncpy(label + offset, ",Yubikey has touch policy", SC_PKCS15_MAX_LABEL_SIZE - offset - 1);
		}

This is more of a friendly reminder to look at the token and if blinking, touch it whenever entering a PIN.
Tested using Yubikey 5 NFC version 5.2.6 that Yubico has sent me at that time.

@frankmorgner
Copy link
Member Author

Sorry, I was misled by the documentation available at https://developers.yubico.com/PIV/Introduction/Yubico_extensions.html#_get_metadata. I now found https://docs.yubico.com/yesdk/users-manual/application-piv/slots.html which makes it more clear what they define to be slots. I'll rewrite the code to attach the policies to the keys instead of the PINs.

I find notifications more usable than changing the PIN's label, but your suggestion, Doug, is a good idea if notifications are not available.

src/libopensc/card-piv.c Outdated Show resolved Hide resolved
src/libopensc/card-piv.c Outdated Show resolved Hide resolved
src/libopensc/card-piv.c Outdated Show resolved Hide resolved
@Jakuje
Copy link
Member

Jakuje commented Apr 3, 2024

I will give it a try with a yubikey after the fuzzing issues are resolved.

src/libopensc/card-piv.c Outdated Show resolved Hide resolved
src/libopensc/pkcs15-piv.c Outdated Show resolved Hide resolved
src/libopensc/pkcs15-piv.c Outdated Show resolved Hide resolved
src/libopensc/card-piv.c Outdated Show resolved Hide resolved
src/libopensc/pkcs15-piv.c Outdated Show resolved Hide resolved
@dengert
Copy link
Member

dengert commented Apr 6, 2024

The Yubico metadata has a lot of useful info. If you where to issue the Yubico get metadata command from card-piv.c and cache the data in card-piv.c it could be used to verify that the card has a key and the type and size as well as the public key, even if no certificate is present. And if certificate is present, that the public keys match from metadata and certificate. If the metadata returns that no key is present, then read the certificate code could be skipped.

Could be just before the comment: /* get the cert or the pub key out and into the cache too */
The piv_objects structure could have the key id to use as the "slot" in the metadata and some other flags too.

Standard PIV cards still need to read a certificate to get key type and size.

@frankmorgner
Copy link
Member Author

Reviewing https://docs.yubico.com/yesdk/users-manual/application-piv/attestation.html, it seems that the attestation statement is a good fallback mechanism in order to test for the PIN policy. From the documentation it is unclear whether the attestation statement is always newly created (i.e. a slow signature). Anyway, I'll check if I can copy that to the driver level... (feel free to jump in if you want to push some commit on top of this PR).

src/libopensc/pkcs15-piv.c Outdated Show resolved Hide resolved
@frankmorgner frankmorgner marked this pull request as draft April 18, 2024 09:29
@frankmorgner
Copy link
Member Author

I added debug messages and error codes.

I'd also like to add support for the attestation statements as fall back, because is already implemented. I converted this PR into a draft until I have time to look at it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants