[pkg-opensc-commit] [opensc] 46/295: libopensc: fetch card's UID

Eric Dorland eric at moszumanska.debian.org
Sat Jun 24 21:11:14 UTC 2017


This is an automated email from the git hooks/post-receive script.

eric pushed a commit to branch master
in repository opensc.

commit 60f2d063085ffec2751bca9936842d558b3d0230
Author: Frank Morgner <frankmorgner at gmail.com>
Date:   Mon Jun 20 11:43:27 2016 +0200

    libopensc: fetch card's UID
    
    Fetch card's UID.
    For file caching, use UID if SN is not available.
---
 src/libopensc/card.c         |  1 +
 src/libopensc/opensc.h       |  2 ++
 src/libopensc/pkcs15-cache.c | 17 ++++++++++++++---
 src/libopensc/reader-pcsc.c  | 32 ++++++++++++++++++++++++++++++++
 src/libopensc/types.h        |  6 ++++++
 5 files changed, 55 insertions(+), 3 deletions(-)

diff --git a/src/libopensc/card.c b/src/libopensc/card.c
index 8c04207..910cffb 100644
--- a/src/libopensc/card.c
+++ b/src/libopensc/card.c
@@ -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);
 
diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h
index 65d626e..8913cc7 100644
--- a/src/libopensc/opensc.h
+++ b/src/libopensc/opensc.h
@@ -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;
diff --git a/src/libopensc/pkcs15-cache.c b/src/libopensc/pkcs15-cache.c
index 865db03..5cdd0cd 100644
--- a/src/libopensc/pkcs15-cache.c
+++ b/src/libopensc/pkcs15-cache.c
@@ -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))   {
diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c
index 304a14e..93bfbbe 100644
--- a/src/libopensc/reader-pcsc.c
+++ b/src/libopensc/reader-pcsc.c
@@ -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;
 }
 
diff --git a/src/libopensc/types.h b/src/libopensc/types.h
index 38f4c4b..a5f9250 100644
--- a/src/libopensc/types.h
+++ b/src/libopensc/types.h
@@ -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];

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-opensc/opensc.git



More information about the pkg-opensc-commit mailing list