diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index ac4d1e9a..eee3cd49 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -60,7 +60,7 @@ struct sc_aid sc_hsm_aid = { { 0xE8,0x2B,0x06,0x01,0x04,0x01,0x81,0xC3,0x1F,0x02 /* Known ATRs for SmartCard-HSMs */ -static const struct sc_atr_table sc_hsm_atrs[] = { +const 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}, diff --git a/src/libopensc/card-sc-hsm.h b/src/libopensc/card-sc-hsm.h index c9b32815..da57c1c0 100644 --- a/src/libopensc/card-sc-hsm.h +++ b/src/libopensc/card-sc-hsm.h @@ -21,6 +21,9 @@ #ifndef SC_HSM_H_ #define SC_HSM_H_ +#include "pkcs15.h" +#include "internal.h" + #define MAX_EXT_APDU_LENGTH 1014 #define PRKD_PREFIX 0xC4 /* Hi byte in file identifier for PKCS#15 PRKD objects */ @@ -125,4 +128,6 @@ void sc_pkcs15emu_sc_hsm_free_cvc(sc_cvc_t *cvc); int sc_pkcs15emu_sc_hsm_get_curve(struct ec_curve **curve, u8 *oid, size_t oidlen); int sc_pkcs15emu_sc_hsm_get_public_key(struct sc_context *ctx, sc_cvc_t *cvc, struct sc_pkcs15_pubkey *pubkey); +/* Known ATRs for SmartCard-HSMs */ +extern const struct sc_atr_table sc_hsm_atrs[]; #endif /* SC_HSM_H_ */ diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index c362bc5b..c905c3f3 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -39,6 +39,7 @@ #include "common/libscdl.h" #include "internal.h" #include "internal-winscard.h" +#include "card-sc-hsm.h" #include "pace.h" @@ -430,7 +431,7 @@ static int pcsc_detect_card_presence(sc_reader_t *reader) static int check_forced_protocol(sc_reader_t *reader, DWORD *protocol) { scconf_block *atrblock = NULL; - int ok = 0; + int forced = 0; atrblock = _sc_match_atr_block(reader->ctx, NULL, &reader->atr); if (atrblock != NULL) { @@ -439,26 +440,37 @@ static int check_forced_protocol(sc_reader_t *reader, DWORD *protocol) forcestr = scconf_get_str(atrblock, "force_protocol", "unknown"); if (!strcmp(forcestr, "t0")) { *protocol = SCARD_PROTOCOL_T0; - ok = 1; + forced = 1; } else if (!strcmp(forcestr, "t1")) { *protocol = SCARD_PROTOCOL_T1; - ok = 1; + forced = 1; } else if (!strcmp(forcestr, "raw")) { *protocol = SCARD_PROTOCOL_RAW; - ok = 1; + forced = 1; } - if (ok) + if (forced) sc_log(reader->ctx, "force_protocol: %s", forcestr); } - if (!ok && reader->uid.len) { + if (!forced && reader->uid.len) { /* We identify contactless cards by their UID. Communication * defined by ISO/IEC 14443 is identical to T=1. */ *protocol = SCARD_PROTOCOL_T1; - ok = 1; + forced = 1; } - return ok; + if (!forced) { + sc_card_t card; + memset(&card, 0, sizeof card); + card.ctx = reader->ctx; + card.atr = reader->atr; + if (0 <= _sc_match_atr(&card, sc_hsm_atrs, NULL)) { + *protocol = SCARD_PROTOCOL_T1; + forced = 1; + } + } + + return forced; }