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:
parent
5ebccf1842
commit
60eeadb962
|
@ -770,11 +770,51 @@ static int tcos_setperm(struct sc_card *card, int enable_nullpin)
|
||||||
return sc_check_sw(card, apdu.sw1, apdu.sw2);
|
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)
|
static int tcos_card_ctl(struct sc_card *card, unsigned long cmd, void *ptr)
|
||||||
{
|
{
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case SC_CARDCTL_TCOS_SETPERM:
|
case SC_CARDCTL_TCOS_SETPERM:
|
||||||
return tcos_setperm(card, !!ptr);
|
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;
|
return SC_ERROR_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
#include "cardctl.h"
|
||||||
#include "pkcs15.h"
|
#include "pkcs15.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -92,29 +93,16 @@ sc_pkcs15emu_netkey_init(sc_pkcs15_card_t *p15card) {
|
||||||
unsigned char ef_gdo[20];
|
unsigned char ef_gdo[20];
|
||||||
unsigned char serial[30];
|
unsigned char serial[30];
|
||||||
int i, r;
|
int i, r;
|
||||||
|
sc_serial_number_t serialnr;
|
||||||
|
|
||||||
/* Netkey cards serial file 2F02 has always length 12
|
r = sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serialnr);
|
||||||
* format is: 5A 0A XX XX XX XX XX XX XX XX XX X0
|
if (r < 0) {
|
||||||
* where XXXXXXXXXXXXXXXXXXX is the 19-digit serial number
|
sc_debug(ctx, "unable to get ICCSN\n");
|
||||||
*/
|
|
||||||
|
|
||||||
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_ERROR_WRONG_CARD;
|
r = SC_ERROR_WRONG_CARD;
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
sc_read_binary(card, 0, ef_gdo, 12, 0);
|
sc_bin_to_hex(serialnr.value, serialnr.len , serial, sizeof(serial), 0);
|
||||||
if (ef_gdo[0]!=0x5A || ef_gdo[1]!=10) {
|
serial[19] = '\0';
|
||||||
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';
|
|
||||||
set_string(&p15card->serial_number, serial);
|
set_string(&p15card->serial_number, serial);
|
||||||
set_string(&p15card->label, "Netkey E4 Card");
|
set_string(&p15card->label, "Netkey E4 Card");
|
||||||
set_string(&p15card->manufacturer_id, "TeleSec");
|
set_string(&p15card->manufacturer_id, "TeleSec");
|
||||||
|
|
Loading…
Reference in New Issue