diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index cd1988cf..cfa084a0 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -64,6 +64,7 @@ static struct sc_atr_table sc_hsm_atrs[] = { /* standard version */ {"3B:FE:18:00:00:81:31:FE:45:80:31:81:54:48:53:4D:31:73:80:21:40:81:07:FA", NULL, NULL, SC_CARD_TYPE_SC_HSM, 0, NULL}, {"3B:8E:80:01:80:31:81:54:48:53:4D:31:73:80:21:40:81:07:18", NULL, NULL, SC_CARD_TYPE_SC_HSM, 0, NULL}, + {"3B:80:80:01:01", NULL, NULL, SC_CARD_TYPE_SC_HSM_SOC, 0, NULL}, // SoC Sample Card { "3B:84:80:01:47:6f:49:44:00", "FF:FF:FF:FF:FF:FF:FF:FF:00", @@ -237,7 +238,8 @@ static int sc_hsm_match_card(struct sc_card *card) r = sc_hsm_select_file(card, &path, NULL); LOG_TEST_RET(card->ctx, r, "Could not select SmartCard-HSM application"); - // Select Applet to be sure + card->type = SC_CARD_TYPE_SC_HSM; + return 1; } @@ -484,13 +486,11 @@ static int sc_hsm_perform_chip_authentication(sc_card_t *card) goto err; } - if (card->type == SC_CARD_TYPE_SC_HSM_SOC) { - /* SoC cards are known to be implemented on newer JCOPs */ - protocol = NID_id_CA_ECDH_AES_CBC_CMAC_128; - } else { - /* Older cards may not support AES accelerator */ - protocol = NID_id_CA_ECDH_3DES_CBC_CBC; - } + /* XXX on older JCOPs only NID_id_CA_ECDH_3DES_CBC_CBC may be + * supported. The card does not export its capabilities. We hardcode + * NID_id_CA_ECDH_AES_CBC_CMAC_128 here, because we don't have the older + * cards in production. */ + protocol = NID_id_CA_ECDH_AES_CBC_CMAC_128; /* initialize CA domain parameter with the document's public key */ if (!EAC_CTX_init_ca(ctx, protocol, 8)) { @@ -559,8 +559,9 @@ static int sc_hsm_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, } /* For contactless cards always establish a secure channel before PIN - * verification */ - if (card->type == SC_CARD_TYPE_SC_HSM_SOC + * verification. Also, Session PIN generation requires SM. */ + if ((card->type == SC_CARD_TYPE_SC_HSM_SOC || card->reader->uid.len + || cmd == SC_PIN_CMD_GET_SESSION_PIN) && (data->cmd != SC_PIN_CMD_GET_INFO) && card->sm_ctx.sm_mode != SM_MODE_TRANSMIT) { LOG_TEST_RET(card->ctx,