Skip to content

Commit cfb371a

Browse files
committed
card-piv.c - PIV card type matching
Nitroket PIV is based on 800-74-4 but is not compliant at this time So the card type will remain SC_CARD_TYPE_PIV_II_NITROKEY and not changed to SC_CARD_TYPE_PIV_II_800_73_4. Nitrokey is identified much like Yubikeys, from the ATR and uses the same Yubico version number APDU. SC_CARD_TYPE_PIV_II_800_73_4 is left for cards that appear to be compliant, but are not identified in any specific way. On branch Nitrokey-PIV Changes to be committed: modified: card-piv.c
1 parent 705e97c commit cfb371a

File tree

1 file changed

+28
-25
lines changed

1 file changed

+28
-25
lines changed

src/libopensc/card-piv.c

+28-25
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* card-default.c: Support for cards with no driver
44
*
55
* Copyright (C) 2001, 2002 Juha Yrjölä <juha.yrjola@iki.fi>
6-
* Copyright (C) 2005-2024 Douglas E. Engert <deengert@gmail.com>
6+
* Copyright (C) 2005-2025 Douglas E. Engert <deengert@gmail.com>
77
* Copyright (C) 2006, Identity Alliance, Thomas Harning <thomas.harning@identityalliance.com>
88
* Copyright (C) 2007, EMC, Russell Larner <rlarner@rsa.com>
99
*
@@ -2902,8 +2902,10 @@ static int piv_find_aid(sc_card_t * card)
29022902
if (tag != NULL) {
29032903
priv->init_flags |= PIV_INIT_AID_PARSED;
29042904
/* look for 800-73-4 0xAC for Cipher Suite Algorithm Identifier Table 14 */
2905-
/* There may be more than one 0xAC tag, loop to find all */
2906-
/* TODO do we need to look for "Nitrokey PIVP" in tag 0x50 length 12 */
2905+
/* 800-73-4 only expects 1 0xAC tag len 6 with a 80 01 xx 06 01 00
2906+
* where xx is the SM csID either 27 or 2E.
2907+
* Some vendors may include entries for supported Algorithms even when
2908+
* not required */
29072909
nextac = tag;
29082910
while((actag = sc_asn1_find_tag(card->ctx, nextac, taglen - (nextac - tag),
29092911
0xAC, &actaglen)) != NULL) {
@@ -2912,7 +2914,7 @@ static int piv_find_aid(sc_card_t * card)
29122914
csai = sc_asn1_find_tag(card->ctx, actag, actaglen, 0x80, &csailen);
29132915
if (csai != NULL) {
29142916
if (csailen == 1) {
2915-
sc_log(card->ctx,"found csID=0x%2.2x",*csai);
2917+
sc_log(card->ctx,"found 0xAC 0x80 entry:0x%2.2x",*csai);
29162918
#ifdef ENABLE_PIV_SM
29172919
for (i = 0; i < PIV_CSS_SIZE; i++) {
29182920
if (*csai != css[i].id)
@@ -5345,6 +5347,7 @@ static int piv_match_card(sc_card_t *card)
53455347
case SC_CARD_TYPE_PIV_II_PIVKEY:
53465348
case SC_CARD_TYPE_PIV_II_SWISSBIT:
53475349
case SC_CARD_TYPE_PIV_II_800_73_4:
5350+
case SC_CARD_TYPE_PIV_II_NITROKEY:
53485351
break;
53495352
default:
53505353
return 0; /* can not handle the card */
@@ -5547,10 +5550,11 @@ static int piv_match_card_continued(sc_card_t *card)
55475550
goto err;
55485551
}
55495552

5550-
/* Assumes all Yubikey cards are identified via ATR Historic bytes */
5553+
/* Assumes all Yubikey/Nitrokey cards are identified via ATR Historic bytes */
55515554
switch (card->type) {
55525555
case SC_CARD_TYPE_PIV_II_NEO:
55535556
case SC_CARD_TYPE_PIV_II_YUBIKEY4:
5557+
case SC_CARD_TYPE_PIV_II_NITROKEY: /* Nitrokey PIV iuses same APDU as Yubikey */
55545558
sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xFD, 0x00, 0x00);
55555559
apdu.lc = 0;
55565560
apdu.data = NULL;
@@ -5561,12 +5565,9 @@ static int piv_match_card_continued(sc_card_t *card)
55615565
r2 = sc_transmit_apdu(card, &apdu); /* on error yubico_version == 0 */
55625566
if (apdu.resplen == 3) {
55635567
priv->yubico_version = (yubico_version_buf[0]<<16) | (yubico_version_buf[1] <<8) | yubico_version_buf[2];
5564-
sc_log(card->ctx, "Yubico card->type=%d, r=0x%08x version=0x%08x", card->type, r, priv->yubico_version);
5568+
sc_log(card->ctx, "Yubico/Nitrokey card->type=%d, r=0x%08x version=0x%08x", card->type, r, priv->yubico_version);
55655569
}
55665570
break;
5567-
case SC_CARD_TYPE_PIV_II_NITROKEY:
5568-
/* TODO get Nitrokey version number */
5569-
break;
55705571
}
55715572
sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d\n", card->type, r2, priv->card_issues, r);
55725573

@@ -5619,7 +5620,6 @@ static int piv_match_card_continued(sc_card_t *card)
56195620
priv->card_issues |= CI_DISCOVERY_USELESS;
56205621
priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT;
56215622
break;
5622-
/* TODO SC_CARD_TYPE_PIV_II_NITROKEY: nothing to do for now */
56235623
}
56245624
sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d\n", card->type, r2, priv->card_issues, r);
56255625

@@ -5633,19 +5633,23 @@ static int piv_match_card_continued(sc_card_t *card)
56335633
}
56345634
}
56355635

5636-
/* If SM is supported, set SC_CARD_TYPE_PIV_II_800_73_4 */
5637-
if (priv->init_flags & PIV_INIT_AID_AC) {
5638-
card->type = SC_CARD_TYPE_PIV_II_800_73_4;
5639-
}
5640-
5641-
sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d\n", card->type, r2, priv->card_issues, r);
5636+
/* If unknown card has 800-73-4 features, it must be based on 800-73-4 or above */
5637+
/* SC_CARD_TYPE_PIV_II_NITROKEY is already known to be based on 800-73-4 */
5638+
switch(card->type) {
5639+
case SC_CARD_TYPE_PIV_II_BASE:
5640+
if (priv->init_flags & PIV_INIT_AID_AC) {
5641+
card->type = SC_CARD_TYPE_PIV_II_800_73_4;
5642+
}
56425643

56435644
#ifdef ENABLE_PIV_SM
5644-
/* Discovery object has pin policy. 800-74-4 bits, its at least SC_CARD_TYPE_PIV_II_800_73_4 */
5645-
if ((priv->pin_policy & (PIV_PP_OCC | PIV_PP_VCI_IMPL | PIV_PP_VCI_WITHOUT_PC)) != 0) {
5646-
card->type = SC_CARD_TYPE_PIV_II_800_73_4;
5647-
}
5645+
/* Discovery object has pin policy. 800-74-4 bits, its at least SC_CARD_TYPE_PIV_II_800_73_4 */
5646+
if ((priv->pin_policy & (PIV_PP_OCC | PIV_PP_VCI_IMPL | PIV_PP_VCI_WITHOUT_PC)) != 0) {
5647+
card->type = SC_CARD_TYPE_PIV_II_800_73_4;
5648+
}
56485649
#endif
5650+
break;
5651+
}
5652+
56495653
sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d\n", card->type, r2, priv->card_issues, r);
56505654

56515655
/*
@@ -5685,6 +5689,10 @@ static int piv_match_card_continued(sc_card_t *card)
56855689
priv->card_issues |= CI_RSA_4096 | CI_25519;
56865690
break;
56875691

5692+
case SC_CARD_TYPE_PIV_II_NITROKEY:
5693+
priv->card_issues |= CI_OTHER_AID_LOSE_STATE;
5694+
break;
5695+
56885696
case SC_CARD_TYPE_PIV_II_GI_DE:
56895697
case SC_CARD_TYPE_PIV_II_OBERTHUR:
56905698
case SC_CARD_TYPE_PIV_II_GEMALTO:
@@ -5722,11 +5730,6 @@ static int piv_match_card_continued(sc_card_t *card)
57225730
/* TODO may need more research */
57235731
break;
57245732

5725-
case SC_CARD_TYPE_PIV_II_NITROKEY:
5726-
priv->card_issues |= CI_PIV_AID_LOSE_STATE;
5727-
/* TODO may need to add others */
5728-
break;
5729-
57305733
default:
57315734
priv->card_issues |= CI_VERIFY_LC0_FAIL
57325735
| CI_OTHER_AID_LOSE_STATE;

0 commit comments

Comments
 (0)