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
This commit is contained in:
nils 2004-09-17 19:27:49 +00:00
parent 5ebccf1842
commit 60eeadb962
2 changed files with 47 additions and 19 deletions

View File

@ -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;
}

View File

@ -21,6 +21,7 @@
*/
#include "internal.h"
#include "cardctl.h"
#include "pkcs15.h"
#include <stdlib.h>
#include <string.h>
@ -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");