libopensc: fetch card's UID
Fetch card's UID. For file caching, use UID if SN is not available.
This commit is contained in:
parent
cee092a930
commit
60f2d06308
@ -209,6 +209,7 @@ int sc_connect_card(sc_reader_t *reader, sc_card_t **card_out)
|
||||
card->ctx = ctx;
|
||||
|
||||
memcpy(&card->atr, &reader->atr, sizeof(card->atr));
|
||||
memcpy(&card->uid, &reader->uid, sizeof(card->uid));
|
||||
|
||||
_sc_parse_atr(reader);
|
||||
|
||||
|
@ -316,6 +316,7 @@ typedef struct sc_reader {
|
||||
size_t max_recv_size; /* Mac Le supported by the reader layer */
|
||||
|
||||
struct sc_atr atr;
|
||||
struct sc_uid uid;
|
||||
struct _atr_info {
|
||||
u8 *hist_bytes;
|
||||
size_t hist_bytes_len;
|
||||
@ -470,6 +471,7 @@ typedef struct sc_card {
|
||||
struct sc_reader *reader;
|
||||
|
||||
struct sc_atr atr;
|
||||
struct sc_uid uid;
|
||||
|
||||
int type; /* Card type, for card driver internal use */
|
||||
unsigned long caps, flags;
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "internal.h"
|
||||
#include "pkcs15.h"
|
||||
|
||||
#define RANDOM_UID_INDICATOR 0x08
|
||||
static int generate_cache_filename(struct sc_pkcs15_card *p15card,
|
||||
const sc_path_t *path,
|
||||
char *buf, size_t bufsize)
|
||||
@ -45,7 +46,9 @@ static int generate_cache_filename(struct sc_pkcs15_card *p15card,
|
||||
int r;
|
||||
unsigned u;
|
||||
|
||||
if (p15card->tokeninfo->serial_number == NULL)
|
||||
if (p15card->tokeninfo->serial_number == NULL
|
||||
&& (p15card->card->uid.len == 0
|
||||
|| p15card->card->uid.value[0] == RANDOM_UID_INDICATOR))
|
||||
return SC_ERROR_INVALID_ARGUMENTS;
|
||||
|
||||
assert(path->len <= SC_MAX_PATH_SIZE);
|
||||
@ -58,8 +61,16 @@ static int generate_cache_filename(struct sc_pkcs15_card *p15card,
|
||||
if (!last_update)
|
||||
last_update = "NODATE";
|
||||
|
||||
snprintf(dir + strlen(dir), sizeof(dir) - strlen(dir),
|
||||
"%s_%s", p15card->tokeninfo->serial_number, last_update);
|
||||
if (p15card->tokeninfo->serial_number) {
|
||||
snprintf(dir + strlen(dir), sizeof(dir) - strlen(dir),
|
||||
"%s_%s", p15card->tokeninfo->serial_number,
|
||||
last_update);
|
||||
} else {
|
||||
snprintf(dir + strlen(dir), sizeof(dir) - strlen(dir),
|
||||
"uid-%s_%s", sc_dump_hex(
|
||||
p15card->card->uid.value,
|
||||
p15card->card->uid.len), last_update);
|
||||
}
|
||||
|
||||
if (path->aid.len &&
|
||||
(path->type == SC_PATH_TYPE_FILE_ID || path->type == SC_PATH_TYPE_PATH)) {
|
||||
|
@ -470,6 +470,34 @@ static int pcsc_reconnect(sc_reader_t * reader, DWORD action)
|
||||
return pcsc_to_opensc_error(rv);
|
||||
}
|
||||
|
||||
static void initialize_uid(sc_reader_t *reader)
|
||||
{
|
||||
sc_apdu_t apdu;
|
||||
/* though we only expect 10 bytes max, we want to set the Le to 0x00 to not
|
||||
* get 0x6282 as SW in case of a UID variant shorter than 10 bytes */
|
||||
u8 rbuf[256];
|
||||
|
||||
memset(&apdu, 0, sizeof(apdu));
|
||||
apdu.cse = SC_APDU_CASE_2_SHORT;
|
||||
apdu.cla = 0xFF;
|
||||
apdu.ins = 0xCA;
|
||||
apdu.p1 = 0x00;
|
||||
apdu.p2 = 0x00;
|
||||
apdu.le = 0x00;
|
||||
apdu.resp = rbuf;
|
||||
apdu.resplen = sizeof rbuf;
|
||||
|
||||
if (SC_SUCCESS == pcsc_transmit(reader, &apdu)
|
||||
&& apdu.sw1 == 0x90 && apdu.sw2 == 0x00) {
|
||||
reader->uid.len = apdu.resplen;
|
||||
memcpy(reader->uid.value, apdu.resp, reader->uid.len);
|
||||
sc_debug_hex(reader->ctx, SC_LOG_DEBUG_NORMAL, "UID",
|
||||
reader->uid.value, reader->uid.len);
|
||||
} else {
|
||||
sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, "unable to get UID");
|
||||
}
|
||||
}
|
||||
|
||||
static int pcsc_connect(sc_reader_t *reader)
|
||||
{
|
||||
DWORD active_proto, tmp, protocol = SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1;
|
||||
@ -522,6 +550,8 @@ static int pcsc_connect(sc_reader_t *reader)
|
||||
sc_log(reader->ctx, "Final protocol: %s", reader->active_protocol == SC_PROTO_T1 ? "T=1" : "T=0");
|
||||
}
|
||||
|
||||
initialize_uid(reader);
|
||||
|
||||
/* After connect reader is not locked yet */
|
||||
priv->locked = 0;
|
||||
|
||||
@ -2185,6 +2215,8 @@ static int cardmod_connect(sc_reader_t *reader)
|
||||
if (!(reader->flags & SC_READER_CARD_PRESENT))
|
||||
return SC_ERROR_CARD_NOT_PRESENT;
|
||||
|
||||
initialize_uid(reader);
|
||||
|
||||
return SC_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,7 @@ typedef unsigned char u8;
|
||||
#define SC_MAX_EXT_APDU_BUFFER_SIZE 65538
|
||||
#define SC_MAX_PIN_SIZE 256 /* OpenPGP card has 254 max */
|
||||
#define SC_MAX_ATR_SIZE 33
|
||||
#define SC_MAX_UID_SIZE 10
|
||||
#define SC_MAX_AID_SIZE 16
|
||||
#define SC_MAX_AID_STRING_SIZE (SC_MAX_AID_SIZE * 2 + 3)
|
||||
#define SC_MAX_IIN_SIZE 10
|
||||
@ -76,6 +77,11 @@ struct sc_atr {
|
||||
size_t len;
|
||||
};
|
||||
|
||||
struct sc_uid {
|
||||
unsigned char value[SC_MAX_UID_SIZE];
|
||||
size_t len;
|
||||
};
|
||||
|
||||
/* Issuer ID */
|
||||
struct sc_iid {
|
||||
unsigned char value[SC_MAX_IIN_SIZE];
|
||||
|
Loading…
Reference in New Issue
Block a user