From 60eeadb96233be6973f651c2393971b0a9a3805e Mon Sep 17 00:00:00 2001 From: nils Date: Fri, 17 Sep 2004 19:27:49 +0000 Subject: [PATCH] add support for sc_card_ctl(*, SC_CARDCTL_GET_SERIALNR, *) for TCOS cards (and use it in the netkey support) git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@1901 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/card-tcos.c | 40 +++++++++++++++++++++++++++++++++++ src/libopensc/pkcs15-netkey.c | 26 ++++++----------------- 2 files changed, 47 insertions(+), 19 deletions(-) diff --git a/src/libopensc/card-tcos.c b/src/libopensc/card-tcos.c index d5007376..0b4f8fca 100644 --- a/src/libopensc/card-tcos.c +++ b/src/libopensc/card-tcos.c @@ -770,11 +770,51 @@ static int tcos_setperm(struct sc_card *card, int enable_nullpin) return sc_check_sw(card, apdu.sw1, apdu.sw2); } +/* read the card serial number from the EF_gdo system file */ +static int tcos_get_serialnr(sc_card_t *card, sc_serial_number_t *serial) +{ + int r; + u8 buf[64]; + size_t len; + sc_path_t tpath; + sc_file_t *tfile = NULL; + + if (!serial) + return SC_ERROR_INVALID_ARGUMENTS; + /* see if we have cached serial number */ + if (card->serialnr.len) { + memcpy(serial, &card->serialnr, sizeof(*serial)); + return SC_SUCCESS; + } + /* read EF_gdo */ + sc_format_path("3F002F02", &tpath); + r = sc_select_file(card, &tpath, &tfile); + if (r < 0) + return r; + len = tfile->size; + sc_file_free(tfile); + if (len > sizeof(buf) || len < 12) + return SC_ERROR_INTERNAL; + r = sc_read_binary(card, 0, buf, len, 0); + if (r < 0) + return r; + if (buf[0] != 0x5a || buf[1] > len - 2) + return SC_ERROR_INTERNAL; + card->serialnr.len = buf[1]; + memcpy(card->serialnr.value, buf+2, buf[1]); + + memcpy(serial, &card->serialnr, sizeof(*serial)); + + return SC_SUCCESS; +} + static int tcos_card_ctl(struct sc_card *card, unsigned long cmd, void *ptr) { switch (cmd) { case SC_CARDCTL_TCOS_SETPERM: return tcos_setperm(card, !!ptr); + case SC_CARDCTL_GET_SERIALNR: + return tcos_get_serialnr(card, (sc_serial_number_t *)ptr); } return SC_ERROR_NOT_SUPPORTED; } diff --git a/src/libopensc/pkcs15-netkey.c b/src/libopensc/pkcs15-netkey.c index 9d4e0716..72e247e7 100644 --- a/src/libopensc/pkcs15-netkey.c +++ b/src/libopensc/pkcs15-netkey.c @@ -21,6 +21,7 @@ */ #include "internal.h" +#include "cardctl.h" #include "pkcs15.h" #include #include @@ -92,29 +93,16 @@ sc_pkcs15emu_netkey_init(sc_pkcs15_card_t *p15card) { unsigned char ef_gdo[20]; unsigned char serial[30]; int i, r; + sc_serial_number_t serialnr; - /* Netkey cards serial file 2F02 has always length 12 - * format is: 5A 0A XX XX XX XX XX XX XX XX XX X0 - * where XXXXXXXXXXXXXXXXXXX is the 19-digit serial number - */ - - sc_format_path("2F02", &path); - card->ctx->suppress_errors++; - r=sc_select_file(card, &path, &file); - card->ctx->suppress_errors--; - if (r<0 || file->size!=12) { - sc_debug(ctx, "Cannot read 2F02 (r=%d)\n", r); + r = sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serialnr); + if (r < 0) { + sc_debug(ctx, "unable to get ICCSN\n"); r = SC_ERROR_WRONG_CARD; goto failed; } - sc_read_binary(card, 0, ef_gdo, 12, 0); - if (ef_gdo[0]!=0x5A || ef_gdo[1]!=10) { - r = SC_ERROR_WRONG_CARD; - sc_debug(ctx, "Invalid 2F02 content %02X %02X ...\n", ef_gdo[0], ef_gdo[1]); - goto failed; - } - sc_bin_to_hex(ef_gdo+2, 10 , serial, sizeof(serial), 0); - serial[19]='\0'; + sc_bin_to_hex(serialnr.value, serialnr.len , serial, sizeof(serial), 0); + serial[19] = '\0'; set_string(&p15card->serial_number, serial); set_string(&p15card->label, "Netkey E4 Card"); set_string(&p15card->manufacturer_id, "TeleSec");