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 - Improved Card Matching for Dual CAC/PIV and PIVKEY cards. #1549
Conversation
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.
Your code doesn't build due to compiler warnings.
The whole PIV situation looks like a big mess. How does it come that we are taking so much care when Apple, for example, is fine with such a simple PIV driver? Are we doing something wrong, are we overly picky regarding features and implementation? |
We are overly picky with:
|
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.
Few comments to the coding style, otherwise it looks good. I will give it a try as soon as possible.
src/libopensc/card-piv.c
Outdated
int r = 0; | ||
u8 * rbuf = NULL; | ||
size_t rbuflen = 0; | ||
/* piv_private_data_t * priv = PIV_DATA(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.
Unused code can be removed.
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.
Fixed
@dengert Thank you for the work through the specification to identify the correct cards. I added few comments to the code that need some more attention but after fixing them, I report success:
Only issue is with the |
I could add the Note that PKCS#11 says So to do this right needs some work in OpenSC internals and pkcs11-tool to address this correctly. |
CI_NO_RANDOM added for Dual PIV/CAC cards. The PIV "9B" admin key was used to get a challenge. Some cards do not have one. |
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 will verify the functionality on Monday or Tuesday, but generally it looks good to me.
if (r < 0) | ||
goto err; | ||
switch (tag) { | ||
case PIV_CCC_TAG_F0: |
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.
nit: Switch and case can have the same indent to avoid too much indentation. I would recommend it in this 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.
If the minor change requests are resolved then this PR looks OK.
src/libopensc/card-piv.c
Outdated
* to test for active AID. | ||
*/ | ||
int i7e = piv_find_discovery(card); | ||
|
||
if (i7e != 0 && i7e != SC_ERROR_FILE_NOT_FOUND) { | ||
sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d i7e:%d CI:%08x r:%d\n", card->type, i7e, priv->card_issues, r); | ||
if (i7e != 0) { |
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.
SC_SUCCESS
instead of 0
?
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.
Fixed use if (i7e < 0) {
as is done in other places when testing return of piv_find_discovery(card)
226dc0b
to
c030412
Compare
Not all PIV applets are the same. Different versions of NIST 800-73 and improperly implemented or not implemented required features of NIST 800-73 cases problems. Have a look at the card_issues listed in card-piv.c. The PIV driver has tried to detect the differences based on clues found in the ATR historical bytes and vendor version numbers for some cards. At the same time it has tried to support the possibility there are multiple applets on a card that the user may want to use at the same time from different applications. This has lead to some detection problems with Dual CAC/PIV cards. The same cards sold by the vendor may have only a PIV applet that may not be the same PIV applet that is on the Dual PIV/CAC cards. http://www.cac.mil/Portals/53/Documents/CAC-utilziation-and-variation-matrix-v2.03-20May2016.doc defines a number of official CAC cards in active service. A table of the ATRs for these is now used to detect these cards. The PIV version of the CCC is also read to see if any CAC PKI objects are defined in the CCC, indicating it is a Dual CAC/PIV, even if the ATR is not listed. A more conservative approach to try and handle multiple applets on a card is used. Based on issues with the implementation of the PIV applet this may not be possible to do. So for many cards no additional detection will be done at the start of every transaction, and the login state can not be detected correctly. ATRs for PIVKEY are also in the match table, as these cards have a log of issues. Other PIV cards in the future or not yet tested may not be covered properly by this patch. Extra debugging was added with "PIV_MATCH" to help with these other cards. With "debug = 7;", `grep PIV_MATCH opensc-debug.log` can be used to see how a card type and card_issues are derived. On branch piv-improved-matching Changes to be committed: modified: card-piv.c modified: cards.h
Random data from PIV card is obtained using GENERAL AUTHENTICATE command for a request of a Challenge from the card. "00 87 00 9B 04 7C 02 81 00" Usually 8 bytes are returned. NIST 800-73-3_PART2, "A.1 Authentication of the PIV Card Application Administrator" "Table 11. Authentication of PIV Card Application Administrator" shows an example of how to do this. Some cards (one I have: 3b:7d:96:00:00:80:31:80:65:b0:83:11:17:d6:83:00:90:00) will not allow 2 of these commands in a row. (Maybe assuming command is only used as in Table 11 and is expecting the second command.) Code was added to card-piv.c so if "6A 80" is returned, try the command one more time. For any other GENERAL AUTHENTICATE failure, SC_ERROR_NOT_SUPPORTED is returned. piv_get_challenge may be called within a loop from sc_get_challenge if more random data is needed thus causing the the 2 commands to sent in a row. On branch piv-improved-matching Changes to be committed: modified: card-piv.c
c030412
to
974ffd8
Compare
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.
Few minor comments, but otherwise I think it is ready for merging.
src/libopensc/card-piv.c
Outdated
end = body + bodylen; | ||
|
||
for(; (body < end); body += len) { | ||
|
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.
nit: trailing whitespace
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.
Fixed
On branch piv-improved-matching Changes to be committed: modified: card-piv.c
On branch piv-improved-matching Changes to be committed: modified: card-piv.c
Changes to be committed: modified: card-piv.c
I believe this PR is ready to commit, and all comments have been addressed. If you want I can rebase into one commit. |
They are against code that was forced merged, and can not be found. The issues were addressed by the merge.
@frankmorgner, I am dismissing your comment: "Your code doesn't build due to compiler warnings." This was caused by Appveyor because I forced merged a new set of commits. "All checks have passed" and "This branch has no conflicts with the base branch" Can we get this merged in soon. @Jakuje has approved it and I would like to get in into master so other can easily try it too. Thanks. |
Not all PIV applets are the same. Different versions of NIST 800-73 and improperly implemented
or not implemented required features of NIST 800-73 cases problems. Have a look at the card_issues
listed in card-piv.c. The PIV driver has tried to detect the differences based on clues found in
the ATR historical bytes and vendor version numbers for some cards.
At the same time it has tried to support the possibility there are multiple applets
on a card that the user may want to use at the same time from different applications.
This has lead to some detection problems with Dual CAC/PIV cards. The same cards
sold by the vendor may have only a PIV applet that may not be the same PIV applet that
is on the Dual PIV/CAC cards.
http://www.cac.mil/Portals/53/Documents/CAC-utilziation-and-variation-matrix-v2.03-20May2016.doc
defines a number of official CAC cards in active service. A table of the ATRs for these is now used
to detect these cards. The PIV version of the CCC is also read to see if any CAC PKI objects
are defined in the CCC, indicating it is a Dual CAC/PIV, even if the ATR is not listed.
A more conservative approach to try and handle multiple applets on a card is used. Based
on issues with the implementation of the PIV applet this may not be possible to do.
So for many cards no additional detection will be done at the start of every transaction,
and the login state can not be detected correctly.
ATRs for PIVKEY are also in the match table, as these cards have a lot of issues.
Other PIV cards in the future or not yet tested may not be covered properly by this patch.
Extra debugging was added with "PIV_MATCH" to help with these other cards.
With "debug = 7;",
grep PIV_MATCH opensc-debug.log
can be used to see how a cardtype and card_issues are derived.
On branch piv-improved-matching
Changes to be committed:
modified: card-piv.c
modified: cards.h
Tested using NIST demo cards, Oberthur cards that have a CCC that lists CAC in CCC F0,
Oberthur PIV card with a CCC copied from a Dual CAC/PIV card, Yubico NEO, Yubkey 4, PIVKEY C980, T600 and T800. These last two are "Feitian eJAVA Tokens" with the Taglio PIVKEY PIV applet.
Checklist