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
IASECC: Add support for CPx cards #2217
Conversation
The French CPx Healthcare cards are designed to support the IASECC standard.
Thanks to this commit, we get the full support of: - ./opensc-explore cd 0001 asn1 2F00 - ./pkcs11-tool -O - etc.
There are 2 applications: default one (contact mode) and the contactless mode.
(record notes) Thanks to this patch, we can get its SDO:
or
and its list of applications:
Serial number:
|
Without this fix, we get: ./pkcs11-tool --module ../lib/onepin-opensc-pkcs11.so -M Using slot 0 with a present token (0x0) Supported mechanisms: SHA-1, digest SHA224, digest SHA256, digest SHA384, digest SHA512, digest MD5, digest RIPEMD160, digest GOSTR3411, digest Once we include it, we get: ./pkcs11-tool --module ../lib/onepin-opensc-pkcs11.so -M Using slot 0 with a present token (0x0) Supported mechanisms: SHA-1, digest SHA224, digest SHA256, digest SHA384, digest SHA512, digest MD5, digest RIPEMD160, digest GOSTR3411, digest RSA-9796, keySize={1024,2048}, hw, decrypt, sign, verify RSA-PKCS, keySize={1024,2048}, hw, decrypt, sign, verify SHA1-RSA-PKCS, keySize={1024,2048}, sign, verify SHA256-RSA-PKCS, keySize={1024,2048}, sign, verify RSA-PKCS-KEY-PAIR-GEN, keySize={1024,2048}, generate_key_pair
src/libopensc/card-iasecc.c
Outdated
else if (card->type == SC_CARD_TYPE_IASECC_CPX) | ||
rv = iasecc_init_cpx(card); | ||
else if (card->type == SC_CARD_TYPE_IASECC_CPXCL) | ||
rv = iasecc_init_cpx(card); |
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.
I see this fillows the previous branches, but I would rather see it in one block such as follows so one does not have to investigate what is different in each of the blocks.
else if (card->type == SC_CARD_TYPE_IASECC_CPX) | |
rv = iasecc_init_cpx(card); | |
else if (card->type == SC_CARD_TYPE_IASECC_CPXCL) | |
rv = iasecc_init_cpx(card); | |
else if (card->type == SC_CARD_TYPE_IASECC_CPX || | |
card->type == SC_CARD_TYPE_IASECC_CPXCL) | |
rv = iasecc_init_cpx(card); |
Maybe even better would be the use of switch
/case
.
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.
I agree that a switch
/case
would be a better design, but I do not want to "change" the design logic. It was already a if
/else
chain. Once this pull request will be merged, I can provide an update that replaces this if
/else
chain with a proper switch
/case
.
Thank you for the contribution. I put couple of minor comments inline. Does the |
@Jakuje enclosed some outputs per your request:
regarding the self tests:
which is an expected behavior for the current support. |
The above commands show that you have only data objects on the card so then what is the point registering the RSA mechanisms if it does not have any keys? Or is it WIP to add support for the keys? I am not sure what is the purpose of that card and what do you want to use it for with OpenSC. |
@Jakuje right, it is WIP.
I need OpenSC to support a widely used IASECC card in France by about 1.4M+ users (healthcare users). Till now, it was using a framework that has never been upstreamed. |
I think to make this more valuable, you need to support some private key and PIN operation to make this meaningful for some users. I'm not happy with the changes to ef-atr.c, but let's discuss this in #2220... |
1d702ba
to
2c9aab2
Compare
done b7b5cde#diff-d9ab7bee953b722791ab5aa28ac145b0149fec6cbd3082ce3f5b5c92b44bf953R171 thanks for pointing this issue. |
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.
Looks OK in general, please let me know if you were able to test some private key operation.
I can perform properly a Currently, with OpenSC, it is always:
while any calls to |
card->framework is used by all cards. There is also the pkcs15init director that deals with making changes to a card. There are 3 iasecc files there. You may also need to make changes to pkcs15-iasecc.c if there is still some issue with create_object for your card. |
I need to understand the logics that are under the hood of the pkcs15-iasecc in order to get the proper Oasis C_xyz() callbacks to be set and unset ; for instance C_CreateObject() should be unset. The more I dig, the more I feel it should be part of another pull request once we can close this current pull request. |
PKCS11 is an API. For cards that have a full PKCS15 filesystem, Many OpenSC pkcs15 routines call the card driver to access the card, via the the routines listed in
I don't think you need to worry about trying to create objects for two reasons:
|
b8ae984
to
d66104b
Compare
src/libopensc/card-iasecc.c
Outdated
flags = SC_ALGORITHM_RSA_PAD_PKCS1; | ||
flags |= SC_ALGORITHM_RSA_RAW; | ||
|
||
/* No signature with contactless mode */ |
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.
I think what you do here does not reflect this comment. What you do allows raw RSA and RSA with PKCS1 padding. If you do not want to allow any signatures in contactless mode, you should not set flags at all and not call _sc_card_add_rsa_alg
.
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.
Right, currently, I am focusing on the Contact mode. The contactless mode is supposed to be close to the contactless mode, but with a different AID and no PIN code. For the time being, I'll focus on getting a full support of the contact mode.
So let's focus on this scope:
3867bd3
The previous commit was over simplified. According to the known mechanism, we should have the following scope: ./pkcs11-tool --module ../lib/onepin-opensc-pkcs11.so -M Using slot 0 with a present token (0x0) Supported mechanisms: SHA-1, digest SHA224, digest SHA256, digest SHA384, digest SHA512, digest MD5, digest RIPEMD160, digest GOSTR3411, digest RSA-X-509, keySize={512,2048}, hw, decrypt, sign, verify RSA-PKCS, keySize={512,2048}, hw, decrypt, sign, verify SHA1-RSA-PKCS, keySize={512,2048}, sign, verify SHA256-RSA-PKCS, keySize={512,2048}, sign, verify RSA-PKCS-PSS, keySize={512,2048}, hw, sign, verify SHA1-RSA-PKCS-PSS, keySize={512,2048}, sign, verify SHA256-RSA-PKCS-PSS, keySize={512,2048}, sign, verify do not use the default flags yet: _sc_card_add_rsa_alg(card, 1024, IASECC_CARD_DEFAULT_FLAGS, 0x10001); _sc_card_add_rsa_alg(card, 2048, IASECC_CARD_DEFAULT_FLAGS, 0x10001); _sc_card_add_rsa_alg(card, 512, IASECC_CARD_DEFAULT_FLAGS, 0x10001); Contactless specific behaviour shall be added later on.
Log the send/recv data extracted from the EF.ATR (2F01).
2F01 is: ./opensc-explorer -r 0 OpenSC [3F00]> cat 2F01 00000000: 80 43 01 B8 46 04 04 B0 EC C1 47 03 94 01 80 4F .C..F.....G....O 00000010: 08 80 25 00 00 01 FF 01 00 E0 10 02 02 01 04 02 ..%............. 00000020: 02 01 04 02 02 01 00 02 02 01 00 78 08 06 06 2B ...........x...+ 00000030: 81 22 F8 78 02 82 02 90 00 .".x..... so the ASN1 decoder gets confused because it assumes that two bytes are needed before getting the first tag 43/ISO7816_TAG_II_CARD_SERVICE. In order to avoid such confusion, whenever the content of the EF.ATR/2F01 starts with ISO7816_II_CATEGORY_TLV, we skip the first byte in order to parse the ASN1 payload. Fix: issue OpenSC#2220
I don't like adding more (undocumented) flags globally, because that makes the code even harder to read. In my opinion, having a relaxed parsing as default is just good enough. Actually, instead of introducing new flags, new error codes, we could add a warning to the log that the ASN.1 encoding was incorrect given a strict interpretation of the standard and just continue parsing. Obviously, card manufacturers are making a lot of such errors, so we must cope with this type of problem. Yes, we may trade one error for another, as Doug said, but either way, the user observes an error and will most likely create a log. The latter will then show the exact trace of the error including a possible warning for badly encoded ASN.1... Let's wait for @Jakuje 's comment... |
Right, I forgot to add it. I can add this logic and return SC_ERROR_ASN1_BAD_BITSTRING using a deeper check into this section according to your suggestion:
so, we would get this warning as you suggested:
but it will become quite complex because it requires many changes into the code in order to avoid the "Unknown error"s:
but as commented by @frankmorgner into #2217 (comment) ; let's agree first on the target. Either ways are fine for me, I fully understand @frankmorgner 's comments, but I do not have enough background on OpenSC's community in order to comment which option is best. |
Maintaining software is difficult and implementation has always multiple ways to solve a problem... Thanks for your patience! |
Lets take a step back here. A solution to the opensc-explorer where is is parsing the ASN.1 and would like to skip errors and continue is one thing. But fixing up bad ASN.1 is another, as information may be lost or reported incorrectly. OpenSC needs to work with existing cards with the bad ASN.1 which is loaded via pkcs15.c. There are no hooks, for a card driver or a pkcs15-card.c to ask to "fix" the error while pkcs15 routines loads all the pkcs15 data. We know that the 2 enforcement patches may cause existing cards to stop working if these are included in next release. That said, if we know there is an ASN.1 problem in a specific card in a specific ASN.1 encoding and maybe only in a specify object, we would need a way to let card driver or pkcs15 driver fix the problem. But OpenSC is not setup to allow a card driver to control the reading of PKCS#15 files with bad ASN.1. Decode routines don't ever get passed So in other words, it looks to difficult to do the SC_ERROR_ASN1_BAD_BITSTRING. |
I think it was a bad idea from the beginning to try to enforce the "correct" ASN.1. All it accomplishes is breaking what did or could work. OpenSC is not a Quality Control tool or test suite for manufacturers to debug their implementations. It's a tool for "normal" users to work with their imperfect cards. I say - make parsing "loose" or tolerant by default, maybe add an explicit flag for strict parsing (though who would care to use it, and when - I've no idea). |
The one thing the about enforcing the "correct" ASN.1 has shown that this card has invalid ASN.1 for the commonObjectAttributes Flag bit string. So far @vjardin has shown he can get opensc-explorer to parse the invalid bitstring, but the value of the bits is not what was intended. He still has to show he can get it to work with the incorrect bits, or how to set the bits some other way. @vjardin what does |
Great. And how did it help us? Will we tell the vendor to fix the format? |
I hope so. And we know enough to look at other bit stings on these cards that may also be invalid. |
Yubico listened, and their PIV applet is one of the closest to the standard... Would French government supplier listen? I rather doubt - but let's see. |
see the enclosed logs |
?! What does it mean ? Does Yubico supports the IASECC standard ???
No way, they are not going to change 1.4M of cards which are deployed for many years. They are going to stay as-is for many years. |
It seems that there are only 2 issues, for the 2 flags of these 2 files.
Even if they "listen", it is too late the million of cards are already shipped for many years. I prefer that we live with a proper workaround that fits all the cases. |
No, of course not. It means that Yuhikeys had problems in their PIV implementation, we pointed that out to them, and Yubico improved their implementation greatly.
Completely agree. Not to mention that the probability of "they listen" is very near to zero. |
Please what's next ? How to tackle it ? |
What's next? Not sure. French CPx Healthcare cards are not of much interest outside of France. It looks like a pkcs15 type card, but we have found it does not encode a bit string properly. @Jakuje in #2217 (comment) said it looks like the card has only objects and no keys or certificates. That could be true but it looks like the bit string issue caused pkcs15 routines to not find the keys or certificates. There may be other ANS.1 or invalid PKCS15 structures that will also cause problems. As with other government issues cards, they most likely did not publish the code or documents about the cards. Without these you may have to resort to PC/SC or USB tracing of APDUs. You may want to look at #2244 where I was talking to @the-docta about how to do some traces, and do simple command line issuing of APDUs. There is no general consensus right now on how to handle the ASN1 bit string bug. Either drop the commits the enforce it, or make same major changes in the asn1 parsing code that will effect every card. So if you wish to pursue this, I would suggest for your testing, revert the two commits and see how far you can get. If you can get the card working that is a case to solve the bit string problem. If this card is as simple as I would suspect, with 1 or 2 certificates and private keys on the card and RSA only, it might be possible write a new driver, that emulates PKCS15 and avoids any unnecessary parsing of bas ASN1 data. Personally I fall into the "interested is using their work/government issued card on linux" and "programmers interested in a challenge". But with no one else is interested in CPx Healthcare card, I don't want to spend much time on it. So find some documentation on the card, buy (or find) copy of ISO-7816-4,ISO-7816-8, PKCS15 (or ISO-7816-15) and get some PC/SC traces of a card on windows. |
please leave this PR as is for now. I suggest to remove a0ca9ef from this PR and merge it. Always having a non-strict parsing is in line with what we're currently using with When we're done with this PR, we should discuss elsewhere whether we want to continue adding these type of flags for ASN.1 parsing... |
There are two flavours of CPX cards: - contact mode, - contactless mode
Few years ago, the commit 0362844 did squash the 3F00nnnn path to nnnn. For instance, 3F002F00 becomes 2F00. It is an issue such as: 00000200 [139681798813440] APDU: 00 A4 09 04 02 2F 00 00029790 [139681798813440] SW: 6A 82 Fix: issue OpenSC#2231
done. Thanks for the advices. |
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.
sorry for a delay. Catching up with the emails after last week. I think this PR is fine to merge
thank you. |
The French CPx Healthcare cards are designed to support the IASECC
standard.