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;
|
card->ctx = ctx;
|
||||||
|
|
||||||
memcpy(&card->atr, &reader->atr, sizeof(card->atr));
|
memcpy(&card->atr, &reader->atr, sizeof(card->atr));
|
||||||
|
memcpy(&card->uid, &reader->uid, sizeof(card->uid));
|
||||||
|
|
||||||
_sc_parse_atr(reader);
|
_sc_parse_atr(reader);
|
||||||
|
|
||||||
|
|
|
@ -316,6 +316,7 @@ typedef struct sc_reader {
|
||||||
size_t max_recv_size; /* Mac Le supported by the reader layer */
|
size_t max_recv_size; /* Mac Le supported by the reader layer */
|
||||||
|
|
||||||
struct sc_atr atr;
|
struct sc_atr atr;
|
||||||
|
struct sc_uid uid;
|
||||||
struct _atr_info {
|
struct _atr_info {
|
||||||
u8 *hist_bytes;
|
u8 *hist_bytes;
|
||||||
size_t hist_bytes_len;
|
size_t hist_bytes_len;
|
||||||
|
@ -470,6 +471,7 @@ typedef struct sc_card {
|
||||||
struct sc_reader *reader;
|
struct sc_reader *reader;
|
||||||
|
|
||||||
struct sc_atr atr;
|
struct sc_atr atr;
|
||||||
|
struct sc_uid uid;
|
||||||
|
|
||||||
int type; /* Card type, for card driver internal use */
|
int type; /* Card type, for card driver internal use */
|
||||||
unsigned long caps, flags;
|
unsigned long caps, flags;
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include "pkcs15.h"
|
#include "pkcs15.h"
|
||||||
|
|
||||||
|
#define RANDOM_UID_INDICATOR 0x08
|
||||||
static int generate_cache_filename(struct sc_pkcs15_card *p15card,
|
static int generate_cache_filename(struct sc_pkcs15_card *p15card,
|
||||||
const sc_path_t *path,
|
const sc_path_t *path,
|
||||||
char *buf, size_t bufsize)
|
char *buf, size_t bufsize)
|
||||||
|
@ -45,7 +46,9 @@ static int generate_cache_filename(struct sc_pkcs15_card *p15card,
|
||||||
int r;
|
int r;
|
||||||
unsigned u;
|
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;
|
return SC_ERROR_INVALID_ARGUMENTS;
|
||||||
|
|
||||||
assert(path->len <= SC_MAX_PATH_SIZE);
|
assert(path->len <= SC_MAX_PATH_SIZE);
|
||||||
|
@ -58,8 +61,16 @@ static int generate_cache_filename(struct sc_pkcs15_card *p15card,
|
||||||
if (!last_update)
|
if (!last_update)
|
||||||
last_update = "NODATE";
|
last_update = "NODATE";
|
||||||
|
|
||||||
|
if (p15card->tokeninfo->serial_number) {
|
||||||
snprintf(dir + strlen(dir), sizeof(dir) - strlen(dir),
|
snprintf(dir + strlen(dir), sizeof(dir) - strlen(dir),
|
||||||
"%s_%s", p15card->tokeninfo->serial_number, last_update);
|
"%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 &&
|
if (path->aid.len &&
|
||||||
(path->type == SC_PATH_TYPE_FILE_ID || path->type == SC_PATH_TYPE_PATH)) {
|
(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);
|
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)
|
static int pcsc_connect(sc_reader_t *reader)
|
||||||
{
|
{
|
||||||
DWORD active_proto, tmp, protocol = SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1;
|
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");
|
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 */
|
/* After connect reader is not locked yet */
|
||||||
priv->locked = 0;
|
priv->locked = 0;
|
||||||
|
|
||||||
|
@ -2185,6 +2215,8 @@ static int cardmod_connect(sc_reader_t *reader)
|
||||||
if (!(reader->flags & SC_READER_CARD_PRESENT))
|
if (!(reader->flags & SC_READER_CARD_PRESENT))
|
||||||
return SC_ERROR_CARD_NOT_PRESENT;
|
return SC_ERROR_CARD_NOT_PRESENT;
|
||||||
|
|
||||||
|
initialize_uid(reader);
|
||||||
|
|
||||||
return SC_SUCCESS;
|
return SC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@ typedef unsigned char u8;
|
||||||
#define SC_MAX_EXT_APDU_BUFFER_SIZE 65538
|
#define SC_MAX_EXT_APDU_BUFFER_SIZE 65538
|
||||||
#define SC_MAX_PIN_SIZE 256 /* OpenPGP card has 254 max */
|
#define SC_MAX_PIN_SIZE 256 /* OpenPGP card has 254 max */
|
||||||
#define SC_MAX_ATR_SIZE 33
|
#define SC_MAX_ATR_SIZE 33
|
||||||
|
#define SC_MAX_UID_SIZE 10
|
||||||
#define SC_MAX_AID_SIZE 16
|
#define SC_MAX_AID_SIZE 16
|
||||||
#define SC_MAX_AID_STRING_SIZE (SC_MAX_AID_SIZE * 2 + 3)
|
#define SC_MAX_AID_STRING_SIZE (SC_MAX_AID_SIZE * 2 + 3)
|
||||||
#define SC_MAX_IIN_SIZE 10
|
#define SC_MAX_IIN_SIZE 10
|
||||||
|
@ -76,6 +77,11 @@ struct sc_atr {
|
||||||
size_t len;
|
size_t len;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct sc_uid {
|
||||||
|
unsigned char value[SC_MAX_UID_SIZE];
|
||||||
|
size_t len;
|
||||||
|
};
|
||||||
|
|
||||||
/* Issuer ID */
|
/* Issuer ID */
|
||||||
struct sc_iid {
|
struct sc_iid {
|
||||||
unsigned char value[SC_MAX_IIN_SIZE];
|
unsigned char value[SC_MAX_IIN_SIZE];
|
||||||
|
|
Loading…
Reference in New Issue