sc-hsm: fixed forcing a card driver via opensc.conf

- don't use private data on card matching
- instead, return 1 for every known ATR and only select the applet if the ATR is unknown.
- card initialization always selects the applet.

Advantage: decouples memeory management in matching from initializing the card.
Disadvantage: Applet is selected twice in case of an unknown ATR (once for matching and a second time for initializing the card).

Fixes https://github.com/OpenSC/OpenSC/issues/1042
This commit is contained in:
Frank Morgner 2017-05-04 13:53:50 +02:00
parent a0e868974d
commit b7de5888a0
1 changed files with 19 additions and 44 deletions

View File

@ -72,7 +72,8 @@ static struct sc_atr_table sc_hsm_jc_atrs[] = {
/* standard version */
{"3b:f8:13:00:00:81:31:fe:45:4a:43:4f:50:76:32:34:31:b7", NULL, NULL, SC_CARD_TYPE_SC_HSM, 0, NULL}, // JCOP 2.4.1 Default ATR contact based
{"3b:88:80:01:4a:43:4f:50:76:32:34:31:5e", NULL, NULL, SC_CARD_TYPE_SC_HSM, 0, NULL}, // JCOP 2.4.1 Default ATR contactless
{"3B:80:80:01:01", NULL, NULL, SC_CARD_TYPE_SC_HSM_SOC, 0, NULL}, // SoC Sample Card
/* SoC Sample Card */
{"3B:80:80:01:01", NULL, NULL, SC_CARD_TYPE_SC_HSM_SOC, 0, NULL},
{NULL, NULL, NULL, 0, 0, NULL}
};
@ -120,15 +121,17 @@ static int sc_hsm_select_file_ex(sc_card_t *card,
&& in_path->len == 0
&& in_path->aid.len == sc_hsm_aid.len
&& !memcmp(in_path->aid.value, sc_hsm_aid.value, sc_hsm_aid.len))) {
if ((priv->dffcp == NULL) || forceselect) {
if (!priv || (priv->dffcp == NULL) || forceselect) {
rv = (*iso_ops->select_file)(card, in_path, file_out);
LOG_TEST_RET(card->ctx, rv, "Could not select SmartCard-HSM application");
if (priv->dffcp != NULL) {
sc_file_free(priv->dffcp);
if (priv) {
if (priv->dffcp != NULL) {
sc_file_free(priv->dffcp);
}
// Cache the FCP returned when selecting the applet
sc_file_dup(&priv->dffcp, *file_out);
}
// Cache the FCP returned when selecting the applet
sc_file_dup(&priv->dffcp, *file_out);
} else {
sc_file_dup(file_out, priv->dffcp);
rv = SC_SUCCESS;
@ -173,7 +176,6 @@ static int sc_hsm_select_file(sc_card_t *card,
static int sc_hsm_match_card(struct sc_card *card)
{
sc_hsm_private_data_t *priv;
sc_path_t path;
int i, r;
@ -182,47 +184,13 @@ static int sc_hsm_match_card(struct sc_card *card)
return 1;
i = _sc_match_atr(card, sc_hsm_jc_atrs, &card->type);
if (i < 0)
return 0;
priv = calloc(1, sizeof(sc_hsm_private_data_t));
if (!priv)
LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
card->drv_data = priv;
if (i >= 0)
return 1;
sc_path_set(&path, SC_PATH_TYPE_DF_NAME, sc_hsm_aid.value, sc_hsm_aid.len, 0, 0);
r = (*iso_ops->select_file)(card, &path, &priv->dffcp);
r = sc_hsm_select_file(card, &path, NULL);
LOG_TEST_RET(card->ctx, r, "Could not select SmartCard-HSM application");
if (priv->dffcp) {
if (priv->dffcp->prop_attr && priv->dffcp->prop_attr_len >= 5) {
static char card_name[SC_MAX_APDU_BUFFER_SIZE];
u8 type = priv->dffcp->prop_attr[2];
u8 major = priv->dffcp->prop_attr[3];
u8 minor = priv->dffcp->prop_attr[4];
char p00[] = "SmartCard-HSM Applet for JCOP";
char p01[] = "SmartCard-HSM Demo Applet for JCOP";
char *p = "SmartCard-HSM";
switch (type) {
case 0x00:
p = p00;
break;
case 0x01:
p = p01;
break;
default:
break;
}
snprintf(card_name, sizeof card_name, "%s version %u.%u", p, major, minor);
card->name = card_name;
if (priv->dffcp->prop_attr[1] & 0x04) {
card->caps |= SC_CARD_CAP_SESSION_PIN;
}
}
}
// Select Applet to be sure
return 1;
}
@ -1480,6 +1448,13 @@ static int sc_hsm_init(struct sc_card *card)
LOG_FUNC_CALLED(card->ctx);
if (!priv) {
priv = calloc(1, sizeof(sc_hsm_private_data_t));
if (!priv)
LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
card->drv_data = priv;
}
flags = SC_ALGORITHM_RSA_RAW|SC_ALGORITHM_ONBOARD_KEY_GEN;
_sc_card_add_rsa_alg(card, 1024, flags, 0);