-
Notifications
You must be signed in to change notification settings - Fork 803
added Swissbit iShield FIDO2 Authenticator #2671
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
Conversation
7398160 to
b80009c
Compare
|
It looks like the only use of this is to generate an RSA key and retrieve the public key. Does not look like you are using piv-tool. piv-tool will only generate key for 9A, 9C, 9D and 9E. Why did you have to change the size of the exponent? piv-tool and piv cards assume the card uses a default exponent as defined by the card and return it and gets passed as a long in the keydata. Your changed still left "if (tag != NULL && taglen <= 4) {" which limits the size returned to 4 bytes. Can you get a debug log and show the APDU sent and its response? You define both SC_CARD_TYPE_PIV_II_SWISSBIT and SC_CARD_TYPE_PIV_II_SWISSBIT_DUAL_CAC but treat them the same in all cases. The "_DUAL_CAC" was meant to be used for cards that have both a PIV and CAC applet on the card and the PIV part is non standard. Can this card also have a CAC applet on the card? Please change PIV_OBJ_PRIV something like PIV_OBJ_PRIV_SWISSBIT_5015 for readability. In: If you are only changing the driver and piv-tool to generate this one key and don't expect the driver, pkcs15, pkcs11 the other option to use the piv-tool to authenticate to the card, then use the -s option to send the generate key APDU and retrieve the response. |
|
Are you using https://fidoalliance.org/specs/fido-uaf-v1.2-ps-20201020/fido-uaf-apdu-v1.2-ps-20201020.html When you create the key on the card, do you need to authenticate to the card using the PIV 9B key or some other way for example user pin? I am trying to understand why changes are needed in the PIV code. PIV applet is selected using SELECT command: FIDO spec above use 4.2.3 APDU Command "SELECT" command: In other words how do you use the key you are creating on the PIV card, without using PIV commands? |
|
Do you work for Swissbit? How does Swissbit code create the FODO RSA key you are trying to create? Yubico provides tokens with FIDO and PIV, and they don't need any changes in PIV code to use FIDO . Do you really need to changes OpenSC ? |
|
The more I have read today about FIDO, the less I like this modification to OpenSC. PIV and FIDO are separate applets. PIV can do authentication, sign and encryption using 3 keys with certificates. So the same key and certificate are used for all sites. FIDO has a different key and public key for each site stored on the token, so the user can not be tracked across sites. Windows has built-in FIDO routines that do not depend on PIV. Ubuntu has the fido-tools package that appears to do what you want. Redhat has many docs on using FIDO. Token vendors such as Yubikey and NitroKey have similar tools. There are multiple site showing how to use FIDO with or without tokens. https://github.com/topics/fido2 shows there are 198 repositories dealing with FIDO, including: Google, Nitrokey, Solkeys and |
If I understand correctly, then the token in question works similar to the Yubikey. The changes suggested here are related to the PIV applet only, and don't have anything to do with the FIDO authentcation. |
|
Yes, @frankmorgner is right. Like the Yubikey, the Swissbit iShield FIDO2 Authenticator comes also with the PIV applet installed. Yubico provides their own minidriver, the Swissbit token, however, can be managed via the native Windows user interface using the OpenSC minidriver and a custom PIV module that is integrated via the OpenSC configuration. For certificate enrollment via the minidriver, we also want to enable key generation using PKCS#11 for our token. The suggested changes are required to install the OpenSC minidriver for the iShield FIDO2 Authenticator and to enable key generation using an external module instead of the built-in PIV module and PKCS#11. |
dengert
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please drop the use of SC_CARD_TYPE_PIV_II_DUAL_CAC as this deals with official PIV and CAC cards.
I'm a bit puzzled... where do you draw the line between a Yubikey and the swissbit token? Is it that you don't want to add proprietary functionality to the PIV driver (i.e. something not specified by NIST)? |
Sorry, SC_CARD_TYPE_PIV_II_DUAL_CAC should be SC_CARD_TYPE_PIV_II_SWISSBIT_DUAL_CAC. But changes like When a key is generated is the only time the public key is returned. The code to generate the key is in card-piv.c and called from piv-tool which saves it off card, so it can be included in a CSR. Yubikey tool actually creates a dummy certificate and writes it to the card right away. piv-tool or card-piv.c could be modified to save the public key in a dummy certificate too. To write objects, or generate key requires some type of authentication, normally not done by PIN and not known by user. It is not clear what the SwissBit code is doing for authentication to write objects. See https://github.com/OpenSC/OpenSC/blob/master/src/libopensc/card-piv.c#L692 I did ask for a debug log showing failure when |
|
Sorry, this is a log with I am not using the piv-tool for key generation but the OpenSC minidriver with a custom PIV module instead of the built-in one. The code for authentication and key generation of card-piv.c is called from this module. |
|
It looks like from the log, you have your own: C:\Program Files\OpenSC Project\OpenSC\profiles\PIV-II.profile Do you plans on submitting these to OpenSC? The card-piv.c provides its own What your code appears to do is circumvent piv_find_obj_by_containerid by adding an entry for one file. What I would like to propose, is the piv_select_file, piv_read_binary and piv_write_binary be modified so if the path is not for a PIV object, i.e. not found by Thus you could read or write any iso7816 files if present on the card. Other cards that have additional files could also take advantage of this too. See https://github.com/dengert/OpenSC/tree/non-piv-files and aaad966 I don't have any PIV cards with non piv files so needs testing. |
|
How does you custom PIV module for card administration, would it make sense to integrate this into OpenSC, i.e. pkcs15-init? Where are your tools published? |
|
pkcs15init/pkcs15-piv.c is part of our PIV module and we also do have a card profile PIV-II.profile. Our PIV module is still in development and currently shipped with sample tokens to customers. The PIV applet does not support object selection by path (instruction code 0xA4 is not supported), so calling iso7816 select_file fails. Also, as PIV cards are non-PKCS#15 cards, there is no actual private key file with known path that could be selected. So I tried to extend the selectable PIV objects as it is done for the non standard public key objects used by the piv-tool. However, when using a private key, enabling file selection by path is not required for empty private key paths. In order not to set the path of a new private key based on the card profile with |
|
Have you looked at https://github.com/dengert/OpenSC/tree/non-piv-files and aaad966 yet? If I understand your overall problem with PIV generation of private keys, is that the public key is returned as part of the GENERATE ASYMMETRIC KEY PAIR command done in Another possibility is to have I believe Yubikey does something like this. I am willing to write this for card-piv.c and simplify piv-tool. |
|
I'll tap out for now. Please let me know when you have finalized |
|
I am already calling Key reference selection during key generation does not work as expected: It is iterated through key references, and for each key reference, it is checked if a private key object of that key reference and path coinciding with the path selected for the private key to be generated already exists. If the path of the private key is selected by Choosing an empty path for newly generated private keys also solves my problem when using this key e.g. for signing. With an empty key path the usage of a new key proceeds as for a key that was already present at card binding. If the key path is not empty, the private key file needs to be selectable by @frankmorgner Our PIV module is and will stay continuously tailored to our products. So at least for the moment we need to keep our module separate and proprietary in order to remain flexible and fully traceable with our deliveries. Currently, it is not planned to submit |
This comment was marked as outdated.
This comment was marked as outdated.
NIST 800-78-4 does not define a "private key object". The OpenSC piv driver emulates one for each asymmetric key by reading the associated certificate object (Part 1 Table 7. PIV Data Containers), extracting the SPKI from the certificate to get the key type and size. See Part 1 C.1 PIV Algorithm Identifier Discovery for Asymmetric Cryptographic Authentication) So it might be possible to have multiple keys with the same reference on the card, (For example Key reference 9A RSA 2048 and 9A ECC p-256), the discovery process uses a single certificate (Part 1 Table 7. "X.509 Certificate for PIV Authentication (Key Reference '9A')" which can only define one key type and size.
PIV does not have any concept of: "an empty path for new private keys for PIV cards." PIV does define "ContainerID" for some backwards compatibility but only for data objects, not private keys. The OpenSC piv driver uses these for known objects to emulate pkcs15 paths between pkcs15-piv.c and card-piv.c as paths. It goes further and for certificates uses the certificate's ContainerID + CECE so pkcs15 can read either the full object or just the certificate contained on the object. (certificates may be zipped, so card-piv.c also unzips the certificate) And to emulate pkcs15 private keys, OpenSC piv driver https://github.com/OpenSC/OpenSC/blob/master/src/libopensc/card-piv.c#L439-L497 fills these in from the SPKI in a certificate (or from ENV set by piv-tool), and does not try and read from the card.
The commit was designed to let you try select, read binary and write binary any path other then the ones defined as "ContainerID". Do you have any debug log showing how it failed? |
|
After per some offline clearification, I realized that even a driver for pkcs15init can be loaded using a shared library. This should be fine according to the LGPL licensing, I think. However, please have the technical restrictions in mind:
|
|
The PKCS#15 layer uses The same problem arises when accessing the objects from pkcs15init. In particular, I think the original approach of adding a dummy object(s) to card-piv.c with the path of the PRKDF does the least harm. Now, with the additional callback in sc_pkcs15init_operations we see modifications in all other drivers without any real benefit. However, I don't have a complete picture which other paths/objects need to be selectable and which other problems may still be present. @swissbit-okaufmann , could you point to the exact pieces of code that are returning an error if neither PIV_OBJ_PRIV nor the callbacks would be present? Maybe @dengert can then suggest some alternative solution. |
|
The main problem I have with OpenSC/src/libopensc/card-piv.c Line 500 in b80009c
The default would then be something like: I still don't see how you use PIV_OBJ_PRIV other then to trick I would also like to see a debug log showing why the https://github.com/dengert/OpenSC/tree/non-piv-files did not work for you. |
|
@dengert Please find the debug log using https://github.com/dengert/OpenSC/tree/non-piv-files. As you can see, the card does not support selection of files by their path. Also it is not the case that I have non PIV objects on my card but with the current implementation of OpenSC, when signing with a newly generated private key (with nonempty path), private key selection is required. This is the case as for a new private key a path based on the card's profile is selected by In the log without my modifications, i.e. without extension of the In order to avoid affecting the other card drivers, I would go back to the approach using |
|
(See last lines that may be the best solution.) Thanks for the dump. The "non-piv-files" appears in line 1244 to have sent: Another approach... If the 0x50 tag value was something like: "Swissbit iShield FIDO2" or at least start with "Swissbit" I would prefer the above, but It is also possible to use the ATR. Do you have plans for any other cards that need @frankmorgner may still have license issues. Is all your the code changes in the PR? The PR hit a lot of OpenSC files. If I recall, only In regard to:
The OpenSC PIV code was written to NIST specs that left up to the vendors how to provision a card. NIST did include some capability to generate a key on card and write some objects, and these are done via the piv-tool for testing. I think what you are seeing is NIST only allows one key per reference. With admin privileges a generate key command will over write any existing key. It is up to the provisioning software to make sure a certificate is written. NIST does not support writing a private key to the card. The way to do this with
The key to above - when There are hints in |
With respect to the license, a loadable and proprietary pkcs15init module should be fine in my opinion. Only the technical limitations as stated above should be kept in mind. |
|
The Swissbit iShield FIDO2 key is a non-PKCS15 PIV card but needs emulation as started in From my point of view, the object path selection for private keys is a general problem that does not only affect the Swissbit PIV card, so we decided to handle it in our external PKCS15init module and not to go back to the previous approach of extending the piv objects array in card-piv.c. Does any other card vendor use OpenSC for card provisioning? Maybe no one encountered the inconsistency as other tools were used for administration. |
frankmorgner
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great to hear that you found a working solution!
We are aware that multiple parts were written with a specific file structure in mind. For now, we need to rely on workarounds like file emulation to solve this.
If you have ideas and time for solving this in a generic way, I'd be more than happy to share thoughts and give feedback on refactoring the code.
|
Thanks, @frankmorgner! If we reconsider our solution and file handling, I'll come back to your offer and would be happy to discuss ideas with you. |
|
@dengert Is there anything missing that needs to be addressed before this PR can get merged? |
dengert
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only comment is with minidriver. If this card responds to PIV AID, Microsoft may use internal Microsoft PIV driver and never get to the OpenSC minidriver. i.e. if user inserts card before the OpenSC minidriver is installed.
https://learn.microsoft.com/en-us/windows-hardware/drivers/smartcard/discovery-process
One way around this it to remove PIV ATR from registry:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Calais\PIV Device ATR Cache
Thanks for the info, I think this can be tracked in a seperate issue/pr, which allows @swissbit-okaufmann to reproduce/test this. I think the solution could be straight forward by removing the iShield Authenticator's ATR from |
3edf7c9 to
4c95817
Compare
Thanks for your review. As @frankmorgner suggested, I can try to reproduce this behaviour in a separate issue. I just rebased to the current state of the master and updated the product name in two places. |
|
Can this be merged? |
|
Perfect, thanks a lot 🥳 |
Hi,
the Swissbit iShield FIDO2 Authenticator with PIV applet uses the OpenSC minidriver with a custom PIV module for card administration