Various PIV changes
Some ActivIdentity CAC/PIV cards lose the login state when selecting the PIV AID SC_CARD_TYPE_PIV_II_CAC and CI_PIV_AID_LOSE_STATE were added so piv_card_reader_lock_obtained will try and do a SELECT PIV AID. card->type is reset to its original value if piv_match_card_continued fails to match a card as PIV. pkcs15-piv.c now uses sc_card_ctl which checks card->ops->card_ctl for NULL. closes https://github.com/OpenSC/OpenSC/pull/1307 fixes https://github.com/OpenSC/OpenSC/issues/1297
This commit is contained in:
parent
a5839bb83c
commit
0911982bef
|
@ -214,6 +214,7 @@ static struct piv_aid piv_aids[] = {
|
||||||
#define CI_CANT_USE_GETDATA_FOR_STATE 0x00000008U /* No object to test verification inplace of VERIFY Lc=0 */
|
#define CI_CANT_USE_GETDATA_FOR_STATE 0x00000008U /* No object to test verification inplace of VERIFY Lc=0 */
|
||||||
#define CI_LEAKS_FILE_NOT_FOUND 0x00000010U /* GET DATA of empty object returns 6A 82 even if PIN not verified */
|
#define CI_LEAKS_FILE_NOT_FOUND 0x00000010U /* GET DATA of empty object returns 6A 82 even if PIN not verified */
|
||||||
#define CI_DISCOVERY_USELESS 0x00000020U /* Discovery can not be used to query active AID */
|
#define CI_DISCOVERY_USELESS 0x00000020U /* Discovery can not be used to query active AID */
|
||||||
|
#define CI_PIV_AID_LOSE_STATE 0x00000040U /* PIV AID can lose the login state run with out it*/
|
||||||
|
|
||||||
#define CI_OTHER_AID_LOSE_STATE 0x00000100U /* Other drivers match routines may reset our security state and lose AID!!! */
|
#define CI_OTHER_AID_LOSE_STATE 0x00000100U /* Other drivers match routines may reset our security state and lose AID!!! */
|
||||||
#define CI_NFC_EXPOSE_TOO_MUCH 0x00000200U /* PIN, crypto and objects exposed over NFS in violation of 800-73-3 */
|
#define CI_NFC_EXPOSE_TOO_MUCH 0x00000200U /* PIN, crypto and objects exposed over NFS in violation of 800-73-3 */
|
||||||
|
@ -2965,8 +2966,6 @@ static int piv_match_card(sc_card_t *card)
|
||||||
{
|
{
|
||||||
int r = 0;
|
int r = 0;
|
||||||
|
|
||||||
SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
|
|
||||||
|
|
||||||
/* piv_match_card may be called with card->type, set by opensc.conf */
|
/* piv_match_card may be called with card->type, set by opensc.conf */
|
||||||
/* user provide card type must be one we know */
|
/* user provide card type must be one we know */
|
||||||
switch (card->type) {
|
switch (card->type) {
|
||||||
|
@ -2975,6 +2974,7 @@ static int piv_match_card(sc_card_t *card)
|
||||||
case SC_CARD_TYPE_PIV_II_HIST:
|
case SC_CARD_TYPE_PIV_II_HIST:
|
||||||
case SC_CARD_TYPE_PIV_II_NEO:
|
case SC_CARD_TYPE_PIV_II_NEO:
|
||||||
case SC_CARD_TYPE_PIV_II_YUBIKEY4:
|
case SC_CARD_TYPE_PIV_II_YUBIKEY4:
|
||||||
|
case SC_CARD_TYPE_PIV_II_GI_DE:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return 0; /* can not handle the card */
|
return 0; /* can not handle the card */
|
||||||
|
@ -3005,8 +3005,7 @@ static int piv_match_card_continued(sc_card_t *card)
|
||||||
sc_file_t aidfile;
|
sc_file_t aidfile;
|
||||||
int type = -1;
|
int type = -1;
|
||||||
piv_private_data_t *priv = NULL;
|
piv_private_data_t *priv = NULL;
|
||||||
|
int saved_type = card->type;
|
||||||
SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
|
|
||||||
|
|
||||||
/* Since we send an APDU, the card's logout function may be called...
|
/* Since we send an APDU, the card's logout function may be called...
|
||||||
* however it may be in dirty memory */
|
* however it may be in dirty memory */
|
||||||
|
@ -3020,6 +3019,7 @@ static int piv_match_card_continued(sc_card_t *card)
|
||||||
case SC_CARD_TYPE_PIV_II_HIST:
|
case SC_CARD_TYPE_PIV_II_HIST:
|
||||||
case SC_CARD_TYPE_PIV_II_NEO:
|
case SC_CARD_TYPE_PIV_II_NEO:
|
||||||
case SC_CARD_TYPE_PIV_II_YUBIKEY4:
|
case SC_CARD_TYPE_PIV_II_YUBIKEY4:
|
||||||
|
case SC_CARD_TYPE_PIV_II_GI_DE:
|
||||||
type = card->type;
|
type = card->type;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -3043,6 +3043,18 @@ static int piv_match_card_continued(sc_card_t *card)
|
||||||
!(memcmp(card->reader->atr_info.hist_bytes, "Yubikey", 7))) {
|
!(memcmp(card->reader->atr_info.hist_bytes, "Yubikey", 7))) {
|
||||||
type = SC_CARD_TYPE_PIV_II_NEO;
|
type = SC_CARD_TYPE_PIV_II_NEO;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* https://csrc.nist.gov/csrc/media/projects/cryptographic-module-validation-program/documents/security-policies/140sp1239.pdf
|
||||||
|
* lists 2 ATRS with historical bytes:
|
||||||
|
* 73 66 74 65 2D 63 64 30 38 30
|
||||||
|
* 73 66 74 65 20 63 64 31 34 34
|
||||||
|
* will check for 73 66 74 65
|
||||||
|
*/
|
||||||
|
else if (card->reader->atr_info.hist_bytes_len >= 4 &&
|
||||||
|
!(memcmp(card->reader->atr_info.hist_bytes, "sfte", 4))) {
|
||||||
|
type = SC_CARD_TYPE_PIV_II_GI_DE;
|
||||||
|
}
|
||||||
|
|
||||||
else if (card->reader->atr_info.hist_bytes[0] == 0x80u) { /* compact TLV */
|
else if (card->reader->atr_info.hist_bytes[0] == 0x80u) { /* compact TLV */
|
||||||
p = card->reader->atr_info.hist_bytes;
|
p = card->reader->atr_info.hist_bytes;
|
||||||
pe = p + card->reader->atr_info.hist_bytes_len;
|
pe = p + card->reader->atr_info.hist_bytes_len;
|
||||||
|
@ -3129,6 +3141,7 @@ static int piv_match_card_continued(sc_card_t *card)
|
||||||
/* don't match. Does not have a PIV applet. */
|
/* don't match. Does not have a PIV applet. */
|
||||||
sc_unlock(card);
|
sc_unlock(card);
|
||||||
piv_finish(card);
|
piv_finish(card);
|
||||||
|
card->type = saved_type;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3228,6 +3241,13 @@ static int piv_init(sc_card_t *card)
|
||||||
priv->card_issues |= 0;
|
priv->card_issues |= 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SC_CARD_TYPE_PIV_II_GI_DE:
|
||||||
|
priv->card_issues |= CI_VERIFY_LC0_FAIL
|
||||||
|
| CI_PIV_AID_LOSE_STATE
|
||||||
|
| CI_OTHER_AID_LOSE_STATE;;
|
||||||
|
/* TODO may need more research */
|
||||||
|
break;
|
||||||
|
|
||||||
case SC_CARD_TYPE_PIV_II_GENERIC:
|
case SC_CARD_TYPE_PIV_II_GENERIC:
|
||||||
priv->card_issues |= CI_VERIFY_LC0_FAIL
|
priv->card_issues |= CI_VERIFY_LC0_FAIL
|
||||||
| CI_OTHER_AID_LOSE_STATE;
|
| CI_OTHER_AID_LOSE_STATE;
|
||||||
|
@ -3564,6 +3584,13 @@ static int piv_card_reader_lock_obtained(sc_card_t *card, int was_reset)
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* can we detect and then select the PIV AID without losinig the login state? */
|
||||||
|
if ((priv->card_issues & CI_DISCOVERY_USELESS)
|
||||||
|
&& (priv->card_issues & CI_PIV_AID_LOSE_STATE)) {
|
||||||
|
r = 0; /* do nothing, hope card was not interferred with */
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
/* make sure our application is active */
|
/* make sure our application is active */
|
||||||
|
|
||||||
/* first see if AID is active AID by reading discovery object '7E' */
|
/* first see if AID is active AID by reading discovery object '7E' */
|
||||||
|
@ -3576,8 +3603,13 @@ static int piv_card_reader_lock_obtained(sc_card_t *card, int was_reset)
|
||||||
r = piv_find_discovery(card);
|
r = piv_find_discovery(card);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r < 0)
|
if (r < 0) {
|
||||||
|
if (!(priv->card_issues & CI_PIV_AID_LOSE_STATE)) {
|
||||||
r = piv_select_aid(card, piv_aids[0].value, piv_aids[0].len_short, temp, &templen);
|
r = piv_select_aid(card, piv_aids[0].value, piv_aids[0].len_short, temp, &templen);
|
||||||
|
} else {
|
||||||
|
r = 0; /* cant do anything with this card, hope there was no interference */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (r < 0) /* bad error return will show up in sc_lock as error*/
|
if (r < 0) /* bad error return will show up in sc_lock as error*/
|
||||||
goto err;
|
goto err;
|
||||||
|
|
|
@ -138,6 +138,7 @@ enum {
|
||||||
SC_CARD_TYPE_PIV_II_HIST,
|
SC_CARD_TYPE_PIV_II_HIST,
|
||||||
SC_CARD_TYPE_PIV_II_NEO,
|
SC_CARD_TYPE_PIV_II_NEO,
|
||||||
SC_CARD_TYPE_PIV_II_YUBIKEY4,
|
SC_CARD_TYPE_PIV_II_YUBIKEY4,
|
||||||
|
SC_CARD_TYPE_PIV_II_GI_DE,
|
||||||
|
|
||||||
/* MuscleApplet */
|
/* MuscleApplet */
|
||||||
SC_CARD_TYPE_MUSCLE_BASE = 15000,
|
SC_CARD_TYPE_MUSCLE_BASE = 15000,
|
||||||
|
|
|
@ -658,7 +658,7 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card)
|
||||||
sc_format_path(objects[i].path, &obj_info.path);
|
sc_format_path(objects[i].path, &obj_info.path);
|
||||||
|
|
||||||
/* See if the object can not be present on the card */
|
/* See if the object can not be present on the card */
|
||||||
r = (card->ops->card_ctl)(card, SC_CARDCTL_PIV_OBJECT_PRESENT, &obj_info.path);
|
r = sc_card_ctl(card, SC_CARDCTL_PIV_OBJECT_PRESENT, &obj_info.path);
|
||||||
if (r == 1)
|
if (r == 1)
|
||||||
continue; /* Not on card, do not define the object */
|
continue; /* Not on card, do not define the object */
|
||||||
|
|
||||||
|
@ -734,7 +734,7 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card)
|
||||||
cert_obj.flags = certs[i].obj_flags;
|
cert_obj.flags = certs[i].obj_flags;
|
||||||
|
|
||||||
/* See if the cert might be present or not. */
|
/* See if the cert might be present or not. */
|
||||||
r = (card->ops->card_ctl)(card, SC_CARDCTL_PIV_OBJECT_PRESENT, &cert_info.path);
|
r = sc_card_ctl(card, SC_CARDCTL_PIV_OBJECT_PRESENT, &cert_info.path);
|
||||||
if (r == 1) {
|
if (r == 1) {
|
||||||
sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Cert can not be present,i=%d", i);
|
sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Cert can not be present,i=%d", i);
|
||||||
continue;
|
continue;
|
||||||
|
@ -948,7 +948,7 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card)
|
||||||
|
|
||||||
label = pins[i].label;
|
label = pins[i].label;
|
||||||
if (i == 0 &&
|
if (i == 0 &&
|
||||||
(card->ops->card_ctl)(card, SC_CARDCTL_PIV_PIN_PREFERENCE,
|
sc_card_ctl(card, SC_CARDCTL_PIV_PIN_PREFERENCE,
|
||||||
&pin_ref) == 0 &&
|
&pin_ref) == 0 &&
|
||||||
pin_ref == 0x00) { /* must be 80 for PIV pin, or 00 for Global PIN */
|
pin_ref == 0x00) { /* must be 80 for PIV pin, or 00 for Global PIN */
|
||||||
pin_info.attrs.pin.reference = pin_ref;
|
pin_info.attrs.pin.reference = pin_ref;
|
||||||
|
|
Loading…
Reference in New Issue