Merge branch 'master' of github.com:szikora/OpenSC

This commit is contained in:
Viktor Tarasov 2013-08-03 17:56:45 +02:00
commit 2c019485e8
3 changed files with 104 additions and 19 deletions

View File

@ -1,6 +1,6 @@
/*
* card-cardos.c: Support for Siemens CardOS based cards and tokens
* (for example Aladdin eToken PRO, Eutron CryptoIdentity IT-SEC)
* card-cardos.c: Support for CardOS (from Siemens or Atos) based cards and
* tokens (for example Aladdin eToken PRO, Eutron CryptoIdentity IT-SEC)
*
* Copyright (c) 2005 Nils Larsch <nils@larsch.net>
* Copyright (C) 2002 Andreas Jellinghaus <aj@dungeon.inka.de>
@ -54,6 +54,8 @@ static struct sc_atr_table cardos_atrs[] = {
{ "3b:f2:18:00:ff:c1:0a:31:fe:55:c8:06:8a", "ff:ff:0f:ff:00:ff:00:ff:ff:00:00:00:00", NULL, SC_CARD_TYPE_CARDOS_M4_2, 0, NULL },
/* CardOS 4.4 */
{ "3b:d2:18:02:c1:0a:31:fe:58:c8:0d:51", NULL, NULL, SC_CARD_TYPE_CARDOS_M4_4, 0, NULL},
/* CardOS v5.0 */
{ "3b:d2:18:00:81:31:fe:58:c9:01:14", NULL, NULL, SC_CARD_TYPE_CARDOS_V5_0, 0, NULL},
{ NULL, NULL, NULL, 0, 0, NULL }
};
@ -76,6 +78,8 @@ static int cardos_match_card(sc_card_t *card)
return 1;
if (card->type == SC_CARD_TYPE_CARDOS_M4_4)
return 1;
if (card->type == SC_CARD_TYPE_CARDOS_V5_0)
return 1;
if (card->type == SC_CARD_TYPE_CARDOS_M4_2) {
int rv;
sc_apdu_t apdu;
@ -110,9 +114,9 @@ static int cardos_match_card(sc_card_t *card)
} else if (atr[11] == 0x09) {
sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "found cardos v4.2b");
card->type = SC_CARD_TYPE_CARDOS_M4_2B;
} else if (atr[11] >= 0x0B) {
sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "found cardos v4.2c or higher");
card->type = SC_CARD_TYPE_CARDOS_M4_2C;
} else if (atr[11] >= 0x0B) {
sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "found cardos v4.2c or higher");
card->type = SC_CARD_TYPE_CARDOS_M4_2C;
} else {
sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "found cardos m4.2");
}
@ -183,7 +187,8 @@ static int cardos_init(sc_card_t *card)
} else if (card->type == SC_CARD_TYPE_CARDOS_M4_3
|| card->type == SC_CARD_TYPE_CARDOS_M4_2B
|| card->type == SC_CARD_TYPE_CARDOS_M4_2C
|| card->type == SC_CARD_TYPE_CARDOS_M4_4) {
|| card->type == SC_CARD_TYPE_CARDOS_M4_4
|| card->type == SC_CARD_TYPE_CARDOS_V5_0) {
rsa_2048 = 1;
card->caps |= SC_CARD_CAP_APDU_EXT;
}

View File

@ -46,6 +46,7 @@ enum {
SC_CARD_TYPE_CARDOS_M4_2C,
SC_CARD_TYPE_CARDOS_CIE_V1, /* Italian CIE (eID) v1 */
SC_CARD_TYPE_CARDOS_M4_4,
SC_CARD_TYPE_CARDOS_V5_0,
/* flex/cyberflex drivers */
SC_CARD_TYPE_FLEX_BASE = 2000,

View File

@ -79,6 +79,7 @@ static int cardos_info(void)
{
sc_apdu_t apdu;
u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
int is_cardos5 = 0;
int r;
if (verbose) {
@ -115,6 +116,24 @@ static int cardos_info(void)
}
printf("Info : %s\n", apdu.resp);
apdu.p2 = 0x82;
apdu.resplen = sizeof(rbuf);
r = sc_transmit_apdu(card, &apdu);
if (r) {
fprintf(stderr, "APDU transmit failed: %s\n",
sc_strerror(r));
return 1;
}
if (apdu.sw1 != 0x90 || apdu.sw2 != 00 || verbose) {
fprintf(stderr, "Received (SW1=0x%02X, SW2=0x%02X)%s\n",
apdu.sw1, apdu.sw2, apdu.resplen ? ":" : "");
if (apdu.resplen)
util_hex_dump_asc(stdout, apdu.resp, apdu.resplen, -1);
return 1;
}
if (apdu.resp[0] == 0xc9)
is_cardos5 = 1;
apdu.p2 = 0x81;
apdu.resplen = sizeof(rbuf);
r = sc_transmit_apdu(card, &apdu);
@ -130,15 +149,20 @@ static int cardos_info(void)
util_hex_dump_asc(stdout, apdu.resp, apdu.resplen, -1);
return 1;
}
printf("Chip type: %d\n", apdu.resp[8]);
printf("Serial number: %02x %02x %02x %02x %02x %02x\n",
apdu.resp[10], apdu.resp[11], apdu.resp[12],
apdu.resp[13], apdu.resp[14], apdu.resp[15]);
printf("Full prom dump:\n");
if (apdu.resplen)
util_hex_dump_asc(stdout, apdu.resp, apdu.resplen, -1);
if (is_cardos5) {
printf("Serial number: %02x %02x %02x %02x %02x %02x %02x %02x\n",
apdu.resp[0], apdu.resp[1], apdu.resp[2], apdu.resp[3],
apdu.resp[4], apdu.resp[5], apdu.resp[6], apdu.resp[7]);
} else {
printf("Chip type: %d\n", apdu.resp[8]);
printf("Serial number: %02x %02x %02x %02x %02x %02x\n",
apdu.resp[10], apdu.resp[11], apdu.resp[12],
apdu.resp[13], apdu.resp[14], apdu.resp[15]);
printf("Full prom dump:\n");
if (apdu.resplen)
util_hex_dump_asc(stdout, apdu.resp, apdu.resplen, -1);
}
apdu.p2 = 0x82;
apdu.resplen = sizeof(rbuf);
r = sc_transmit_apdu(card, &apdu);
@ -173,6 +197,8 @@ static int cardos_info(void)
printf(" (that's CardOS M4.2C)\n");
} else if (apdu.resp[0] == 0xc8 && apdu.resp[1] == 0x0D) {
printf(" (that's CardOS M4.4)\n");
} else if (apdu.resp[0] == 0xc9 && apdu.resp[1] == 0x01) {
printf(" (that's CardOS V5.0)\n");
} else {
printf(" (unknown Version)\n");
}
@ -198,7 +224,12 @@ static int cardos_info(void)
if (rbuf[0] == 0x34) {
printf("%d (manufacturing)\n", rbuf[0]);
} else if (rbuf[0] == 0x26) {
printf("%d (initialization)\n", rbuf[0]);
if (is_cardos5)
printf("%d (physinit)\n", rbuf[0]);
else
printf("%d (initialization)\n", rbuf[0]);
} else if (rbuf[0] == 0x23) {
printf("%d (physpers)\n", rbuf[0]);
} else if (rbuf[0] == 0x24) {
printf("%d (personalization)\n", rbuf[0]);
} else if (rbuf[0] == 0x20) {
@ -207,6 +238,8 @@ static int cardos_info(void)
printf("%d (operational)\n", rbuf[0]);
} else if (rbuf[0] == 0x29) {
printf("%d (erase in progress)\n", rbuf[0]);
} else if (rbuf[0] == 0x3F) {
printf("%d (death)\n", rbuf[0]);
} else {
printf("%d (unknown)\n", rbuf[0]);
}
@ -266,7 +299,7 @@ static int cardos_info(void)
if (rbuf[0] == 0x00) {
printf("ATR Status: 0x%d ROM-ATR\n",rbuf[0]);
} else if (rbuf[0] == 0x90) {
} else if (rbuf[0] == 0x80) {
printf("ATR Status: 0x%d EEPROM-ATR\n",rbuf[0]);
} else {
printf("ATR Status: 0x%d unknown\n",rbuf[0]);
@ -307,7 +340,11 @@ static int cardos_info(void)
return 1;
}
printf("Ram size: %d, Eeprom size: %d, cpu type: %x, chip config: %d\n",
if (is_cardos5)
printf("Ram size: %d, Eeprom size: %d, cpu type: %x, chip config: %d, chip manufacturer: %d\n",
rbuf[0]<<8|rbuf[1], rbuf[2]<<8|rbuf[3], rbuf[4], rbuf[6], rbuf[7]);
else
printf("Ram size: %d, Eeprom size: %d, cpu type: %x, chip config: %d\n",
rbuf[0]<<8|rbuf[1], rbuf[2]<<8|rbuf[3], rbuf[4], rbuf[5]);
apdu.p2 = 0x8a;
@ -326,8 +363,50 @@ static int cardos_info(void)
return 1;
}
printf("Free eeprom memory: %d\n", rbuf[0]<<8|rbuf[1]);
if (is_cardos5)
printf("Free eeprom memory: %d\n", rbuf[0]<<24|rbuf[1]<<16|rbuf[2]<<8|rbuf[3]);
else
printf("Free eeprom memory: %d\n", rbuf[0]<<8|rbuf[1]);
apdu.p2 = 0x8d;
apdu.resplen = sizeof(rbuf);
r = sc_transmit_apdu(card, &apdu);
if (r) {
fprintf(stderr, "APDU transmit failed: %s\n",
sc_strerror(r));
return 1;
}
if (apdu.sw1 != 0x90 || apdu.sw2 != 00 || verbose) {
fprintf(stderr, "Received (SW1=0x%02X, SW2=0x%02X)%s\n",
apdu.sw1, apdu.sw2, apdu.resplen ? ":" : "");
if (apdu.resplen)
util_hex_dump_asc(stdout, apdu.resp, apdu.resplen, -1);
return 1;
}
printf("Current Maximum Data Field Length: %d\n", rbuf[0]<<8|rbuf[1]);
if (is_cardos5) {
apdu.p2 = 0x8B;
apdu.resplen = sizeof(rbuf);
r = sc_transmit_apdu(card, &apdu);
if (r) {
fprintf(stderr, "APDU transmit failed: %s\n",
sc_strerror(r));
return 1;
}
if (apdu.sw1 != 0x90 || apdu.sw2 != 00 || verbose) {
fprintf(stderr, "Received (SW1=0x%02X, SW2=0x%02X)%s\n",
apdu.sw1, apdu.sw2, apdu.resplen ? ":" : "");
if (apdu.resplen)
util_hex_dump_asc(stdout, apdu.resp, apdu.resplen, -1);
return 1;
}
printf("Complete chip production data:\n");
util_hex_dump_asc(stdout, apdu.resp, apdu.resplen, -1);
}
apdu.p2 = 0x96;
apdu.resplen = sizeof(rbuf);
r = sc_transmit_apdu(card, &apdu);