- Unify all card drivers ATR matching code to use _sc_match_atr_hex,

untested as of yet.


git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@2134 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
aet 2005-02-04 20:29:35 +00:00
parent 0b43659efa
commit bd0f86f69c
14 changed files with 214 additions and 396 deletions

View File

@ -135,20 +135,20 @@ static long t1, t2, tot_read = 0, tot_dur = 0, dur;
/* Used for a trick in select file and read binary */ /* Used for a trick in select file and read binary */
static size_t next_idx = -1; static size_t next_idx = -1;
static struct sc_atr_table belpic_atrs[] = { static struct sc_atr_table_hex belpic_atrs[] = {
/* Applet V1.1 */ /* Applet V1.1 */
{(const u8 *) "\x3B\x98\x13\x40\x0A\xA5\x03\x01\x01\x01\xAD\x13\x11", 13, BELPIC_EID}, { "3B:98:13:40:0A:A5:03:01:01:01:AD:13:11", NULL, BELPIC_EID },
/* Applet V 1.0 with new EMV-compatible ATR */ /* Applet V1.0 with new EMV-compatible ATR */
{(const u8 *) "\x3B\x98\x94\x40\x0A\xA5\x03\x01\x01\x01\xAD\x13\x10", 13, BELPIC_EID}, { "3B:98:94:40:0A:A5:03:01:01:01:AD:13:10", NULL, BELPIC_EID },
/* Applet beta 5 + V 1.0 */ /* Applet beta 5 + V1.0 */
{(const u8 *) "\x3B\x98\x94\x40\xFF\xA5\x03\x01\x01\x01\xAD\x13\x10", 13, BELPIC_EID}, { "3B:98:94:40:FF:A5:03:01:01:01:AD:13:10", NULL, BELPIC_EID },
#if 0 #if 0
/* Applet beta 3 + 4 */ /* Applet beta 3 + 4 */
{(const u8 *) "\x3B\x98\x11\x40\xFF\xA5\x03\x01\x01\x01\xAD\x13\x04", 13, BELPIC_EID}, { "3B:98:11:40:FF:A5:03:01:01:01:AD:13:04", NULL, BELPIC_EID },
/* Applet beta 2 */ /* Applet beta 2 */
{(const u8 *) "\x3B\x68\x00\x00\x29\x05\x01\x02\x01\xAD\x13\x03", 12, BELPIC_EID}, { "3B:68:00:00:29:05:01:02:01:AD:13:03", NULL, BELPIC_EID },
#endif #endif
{NULL} { NULL }
}; };
struct belpic_priv_data { struct belpic_priv_data {
@ -970,7 +970,7 @@ static int belpic_match_card(struct sc_card *card)
{ {
int i; int i;
i = _sc_match_atr(card, belpic_atrs, NULL); i = _sc_match_atr_hex(card, belpic_atrs, NULL);
if (i < 0) if (i < 0)
return 0; return 0;
return 1; return 1;
@ -994,7 +994,7 @@ static int belpic_init(struct sc_card *card)
#endif #endif
sc_debug(card->ctx, "\n"); sc_debug(card->ctx, "\n");
i = _sc_match_atr(card, belpic_atrs, &id); i = _sc_match_atr_hex(card, belpic_atrs, &id);
if (i < 0) if (i < 0)
id = BELPIC_EID; /* Unknown ATR: assume it's the Belpic Card */ id = BELPIC_EID; /* Unknown ATR: assume it's the Belpic Card */
priv = (struct belpic_priv_data *) calloc(1, sizeof(struct belpic_priv_data)); priv = (struct belpic_priv_data *) calloc(1, sizeof(struct belpic_priv_data));

View File

@ -43,19 +43,18 @@ static struct sc_card_driver etoken_drv = {
&etoken_ops &etoken_ops
}; };
static const struct { static struct sc_atr_table_hex etoken_atrs[] = {
const char * atr; /* 4.0 */
int type; { "3b:e2:00:ff:c1:10:31:fe:55:c8:02:9c", NULL, CARDOS_TYPE_ANY },
} etoken_atrs[] = { /* 4.01 */
{ "3b:e2:00:ff:c1:10:31:fe:55:c8:02:9c", CARDOS_TYPE_ANY }, /* 4.0 */ { "3b:f2:98:00:ff:c1:10:31:fe:55:c8:03:15", NULL, CARDOS_TYPE_ANY },
{ "3b:f2:98:00:ff:c1:10:31:fe:55:c8:03:15", CARDOS_TYPE_ANY }, /* 4.01 */ /* 4.01a */
{ "3b:f2:98:00:ff:c1:10:31:fe:55:c8:04:12", CARDOS_TYPE_ANY }, /* 4.01a */ { "3b:f2:98:00:ff:c1:10:31:fe:55:c8:04:12", NULL, CARDOS_TYPE_ANY },
/* Italian eID card: */ /* Italian eID card */
{ "3b:e9:00:ff:c1:10:31:fe:55:00:64:05:00:c8:02:31:80:00:47", CARDOS_TYPE_ANY }, { "3b:e9:00:ff:c1:10:31:fe:55:00:64:05:00:c8:02:31:80:00:47", NULL, CARDOS_TYPE_ANY },
/* Italian eID card from Infocamere */ /* Italian eID card from Infocamere */
{ "3b:fb:98:00:ff:c1:10:31:fe:55:00:64:05:20:47:03:31:80:00:90:00:f3", CARDOS_TYPE_ANY }, { "3b:fb:98:00:ff:c1:10:31:fe:55:00:64:05:20:47:03:31:80:00:90:00:f3", NULL, CARDOS_TYPE_ANY },
{ NULL }
{ NULL }
}; };
static int etoken_finish(struct sc_card *card) static int etoken_finish(struct sc_card *card)
@ -63,28 +62,14 @@ static int etoken_finish(struct sc_card *card)
return 0; return 0;
} }
static int etoken_identify_card(struct sc_card *card) static int etoken_match_card(struct sc_card *card)
{ {
int i; int i;
for (i = 0; etoken_atrs[i].atr; i++) { i = _sc_match_atr_hex(card, etoken_atrs, NULL);
u8 defatr[SC_MAX_ATR_SIZE]; if (i < 0)
size_t len = sizeof(defatr); return 0;
return 1;
if (sc_hex_to_bin(etoken_atrs[i].atr, defatr, &len))
continue;
if (len != card->atr_len)
continue;
if (!memcmp(card->atr, defatr, len))
return etoken_atrs[i].type;
}
return 0;
}
static int etoken_match_card(struct sc_card *card)
{
return etoken_identify_card(card) != 0;
} }
static int etoken_init(struct sc_card *card) static int etoken_init(struct sc_card *card)

View File

@ -34,74 +34,49 @@
#define IS_CYBERFLEX(card) ((DRV_DATA(card)->card_type & TYPE_MASK) == TYPE_CYBERFLEX) #define IS_CYBERFLEX(card) ((DRV_DATA(card)->card_type & TYPE_MASK) == TYPE_CYBERFLEX)
/* We may want to change sc_atr_table to hold the string representation static struct sc_atr_table_hex flex_atrs[] = {
* of the ATR instead */ /* Cryptoflex */
static struct { /* 8k */
const char * atr; { "3B:95:15:40:FF:68:01:02:02:04", "Cryptoflex 8K", TYPE_CRYPTOFLEX },
int type; /* 8k */
const char * name; { "3B:85:40:20:68:01:01:05:01", "Cryptoflex 8K", TYPE_CRYPTOFLEX },
} flex_atrs[] = { /* 16k */
/* Cryptoflex */ { "3B:95:94:40:FF:63:01:01:02:01", "Cryptoflex 16K", TYPE_CRYPTOFLEX|FLAG_KEYGEN },
{ "3B:95:15:40:FF:68:01:02:02:04", /* 8k */ /* 32K v4 */
TYPE_CRYPTOFLEX, { "3B:95:18:40:FF:64:02:01:01:02", "Cryptoflex 32K v4", TYPE_CRYPTOFLEX|FLAG_KEYGEN },
"Cryptoflex 8K" }, /* 32K e-gate */
{ "3B:85:40:20:68:01:01:05:01", /* 8k */ { "3B:95:18:40:FF:62:01:02:01:04", "Cryptoflex 32K e-gate", TYPE_CRYPTOFLEX|FLAG_KEYGEN },
TYPE_CRYPTOFLEX, /* 32K e-gate v4 */
"Cryptoflex 8K" }, { "3B:95:18:40:FF:62:04:01:01:05", "Cryptoflex 32K e-gate v4", TYPE_CRYPTOFLEX|FLAG_KEYGEN },
{ "3B:95:94:40:FF:63:01:01:02:01", /* 16k */
TYPE_CRYPTOFLEX|FLAG_KEYGEN,
"Cryptoflex 16K" },
{ "3B:95:18:40:FF:64:02:01:01:02", /* 32K v4 */
TYPE_CRYPTOFLEX|FLAG_KEYGEN,
"Cryptoflex 32K v4" },
{ "3B:95:18:40:FF:62:01:02:01:04", /* 32K e-gate */
TYPE_CRYPTOFLEX|FLAG_KEYGEN,
"Cryptoflex 32K e-gate" },
{ "3B:95:18:40:FF:62:04:01:01:05", /* 32K e-gate v4 */
TYPE_CRYPTOFLEX|FLAG_KEYGEN,
"Cryptoflex 32K e-gate v4" },
{ "3B:E2:00:00:40:20:49:06",
TYPE_CRYPTOFLEX,
"Cryptoflex" },
{ "3B:E2:00:00:40:20:49:05", /* + full DES option */
TYPE_CRYPTOFLEX|FLAG_FULL_DES,
"Cryptoflex" },
{ "3B:E2:00:00:40:20:49:07", /* + Key Generation */
TYPE_CRYPTOFLEX|FLAG_KEYGEN,
"Cryptoflex" },
{ "3B:85:40:20:68:01:01:03:05", /* + Key Generation */
TYPE_CRYPTOFLEX|FLAG_KEYGEN,
"Cryptoflex" },
/* Multiflex */ { "3B:E2:00:00:40:20:49:06", "Cryptoflex", TYPE_CRYPTOFLEX },
{ "3B:02:14:50", /* 3K */ /* + full DES option */
TYPE_MULTIFLEX, { "3B:E2:00:00:40:20:49:05", "Cryptoflex", TYPE_CRYPTOFLEX|FLAG_FULL_DES },
"Multiflex 3K" }, /* + Key Generation */
{ "3B:19:14:55:90:01:02:01:00:05:04:B0", /* 4K */ { "3B:E2:00:00:40:20:49:07", "Cryptoflex", TYPE_CRYPTOFLEX|FLAG_KEYGEN },
TYPE_MULTIFLEX, /* + Key Generation */
"Multiflex 4K" }, { "3B:85:40:20:68:01:01:03:05", "Cryptoflex", TYPE_CRYPTOFLEX|FLAG_KEYGEN },
{ "3B:32:15:00:06:80", /* 8K */
TYPE_MULTIFLEX,
"Multiflex 8K" },
{ "3B:32:15:00:06:95", /* 8K + full DES option */
TYPE_MULTIFLEX,
"Multiflex 8K" },
{ "3B:19:14:59:01:01:0F:01:00:05:08:B0", /* 8K */
TYPE_MULTIFLEX,
"Multiflex 8K" },
{ "3B:19:14:55:90:01:01:01:00:05:08:B0", /* 8K */
TYPE_MULTIFLEX,
"Multiflex 8K" },
/* Cyberflex Access */ /* Multiflex */
{ "3B:16:94:81:10:06:01:81:3F", /* Crypto */ /* 3K */
TYPE_CYBERFLEX, { "3B:02:14:50", "Multiflex 3K", TYPE_MULTIFLEX },
"Cyberflex Access" }, /* 4K */
{ "3B:16:94:81:10:06:01:81:2F", /* Aug. Crypto */ { "3B:19:14:55:90:01:02:01:00:05:04:B0", "Multiflex 4K", TYPE_MULTIFLEX },
TYPE_CYBERFLEX, /* 8K */
"Cyberflex Access" }, { "3B:32:15:00:06:80", "Multiflex 8K", TYPE_MULTIFLEX },
/* 8K + full DES option */
{ "3B:32:15:00:06:95", "Multiflex 8K", TYPE_MULTIFLEX },
/* 8K */
{ "3B:19:14:59:01:01:0F:01:00:05:08:B0", "Multiflex 8K", TYPE_MULTIFLEX },
/* 8K */
{ "3B:19:14:55:90:01:01:01:00:05:08:B0", "Multiflex 8K", TYPE_MULTIFLEX },
{ NULL, TYPE_UNKNOWN } /* Cyberflex Access */
/* Crypto */
{ "3B:16:94:81:10:06:01:81:3F", "Cyberflex Access", TYPE_CYBERFLEX },
/* Aug. Crypto */
{ "3B:16:94:81:10:06:01:81:2F", "Cyberflex Access", TYPE_CYBERFLEX },
{ NULL }
}; };
struct flex_private_data { struct flex_private_data {
@ -136,33 +111,14 @@ static int flex_finish(struct sc_card *card)
return 0; return 0;
} }
static int flex_identify_card(struct sc_card *card)
{
int i;
for (i = 0; flex_atrs[i].atr != NULL; i++) {
u8 defatr[SC_MAX_ATR_SIZE];
size_t len = sizeof(defatr);
const char *atrp = flex_atrs[i].atr;
if (sc_hex_to_bin(atrp, defatr, &len))
continue;
if (len != card->atr_len)
continue;
if (memcmp(card->atr, defatr, len) == 0)
break;
}
return i;
}
static int cryptoflex_match_card(struct sc_card *card) static int cryptoflex_match_card(struct sc_card *card)
{ {
int idx; int idx;
idx = flex_identify_card(card); idx = _sc_match_atr_hex(card, flex_atrs, NULL);
if (idx < 0)
switch (flex_atrs[idx].type & TYPE_MASK) { return 0;
switch (flex_atrs[idx].id & TYPE_MASK) {
case TYPE_CRYPTOFLEX: case TYPE_CRYPTOFLEX:
case TYPE_MULTIFLEX: case TYPE_MULTIFLEX:
return 1; return 1;
@ -174,9 +130,10 @@ static int cyberflex_match_card(struct sc_card *card)
{ {
int idx; int idx;
idx = flex_identify_card(card); idx = _sc_match_atr_hex(card, flex_atrs, NULL);
if (idx < 0)
switch (flex_atrs[idx].type & TYPE_MASK) { return 0;
switch (flex_atrs[idx].id & TYPE_MASK) {
case TYPE_CYBERFLEX: case TYPE_CYBERFLEX:
return 1; return 1;
} }
@ -188,11 +145,13 @@ static int flex_init(struct sc_card *card)
struct flex_private_data *data; struct flex_private_data *data;
int idx; int idx;
idx = _sc_match_atr_hex(card, flex_atrs, NULL);
if (idx < 0)
return 0;
if (!(data = (struct flex_private_data *) malloc(sizeof(*data)))) if (!(data = (struct flex_private_data *) malloc(sizeof(*data))))
return SC_ERROR_OUT_OF_MEMORY; return SC_ERROR_OUT_OF_MEMORY;
idx = flex_identify_card(card); data->card_type = flex_atrs[idx].id;
data->card_type = flex_atrs[idx].type;
data->aak_key_ref = 1; data->aak_key_ref = 1;
card->name = flex_atrs[idx].name; card->name = flex_atrs[idx].name;

View File

@ -103,21 +103,15 @@ static int gpk_get_info(struct sc_card *, u8, u8, u8 *, size_t);
/* /*
* ATRs of GPK4000 cards courtesy of libscez * ATRs of GPK4000 cards courtesy of libscez
*/ */
static struct atrinfo { static struct sc_atr_table_hex gpk_atrs[] = {
unsigned char atr[SC_MAX_ATR_SIZE]; { "3B:27:00:80:65:A2:04:01:01:37", "GPK 4K", GPK4000_s },
unsigned int atr_len; { "3B:27:00:80:65:A2:05:01:01:37", "GPK 4K", GPK4000_sp },
int variant; { "3B:27:00:80:65:A2:0C:01:01:37", "GPK 4K", GPK4000_su256 },
const char * name; { "3B:A7:00:40:14:80:65:A2:14:01:01:37", "GPK 4K", GPK4000_sdo },
} atrlist[] = { { "3B:A7:00:40:18:80:65:A2:08:01:01:52", "GPK 8K", GPK8000_8K },
{ "\x3B\x27\x00\x80\x65\xA2\x04\x01\x01\x37", 10, GPK4000_s, "GPK 4K" }, { "3B:A7:00:40:18:80:65:A2:09:01:01:52", "GPK 8K", GPK8000_16K },
{ "\x3B\x27\x00\x80\x65\xA2\x05\x01\x01\x37", 10, GPK4000_sp, "GPK 4K" }, { "3B:A7:00:40:18:80:65:A2:09:01:02:52", "GPK 16K", GPK16000 },
{ "\x3B\x27\x00\x80\x65\xA2\x0C\x01\x01\x37", 10, GPK4000_su256, "GPK 4K" }, { NULL }
{ "\x3B\xA7\x00\x40\x14\x80\x65\xA2\x14\x01\x01\x37", 12, GPK4000_sdo, "GPK 4K" },
{ "\x3B\xA7\x00\x40\x18\x80\x65\xA2\x08\x01\x01\x52", 12, GPK8000_8K, "GPK 8K" },
{ "\x3B\xA7\x00\x40\x18\x80\x65\xA2\x09\x01\x01\x52", 12, GPK8000_16K, "GPK 8K" },
{ "\x3B\xA7\x00\x40\x18\x80\x65\xA2\x09\x01\x02\x52", 12, GPK16000, "GPK 16K" },
{ "", 0, -1 }
}; };
/* /*
@ -138,7 +132,7 @@ static struct sc_card_driver gpk_drv = {
static int static int
gpk_identify(struct sc_card *card) gpk_identify(struct sc_card *card)
{ {
struct atrinfo *ai; int i, variant;
/* Gemplus GPK docs say we can use just the /* Gemplus GPK docs say we can use just the
* FMN and PRN fields of the historical bytes * FMN and PRN fields of the historical bytes
@ -149,32 +143,29 @@ gpk_identify(struct sc_card *card)
if ( (card->slot->atr_info.hist_bytes_len >= 7) if ( (card->slot->atr_info.hist_bytes_len >= 7)
&& (card->slot->atr_info.hist_bytes[0] == 0x80) && (card->slot->atr_info.hist_bytes[0] == 0x80)
&& (card->slot->atr_info.hist_bytes[1] == 0x65) && (card->slot->atr_info.hist_bytes[1] == 0x65)
&& (card->slot->atr_info.hist_bytes[2] == 0xa2)) /* FMN */ && (card->slot->atr_info.hist_bytes[2] == 0xa2)) { /* FMN */
{ if (card->slot->atr_info.hist_bytes[3] == 0x08) { /* PRN? */
if (card->slot->atr_info.hist_bytes[3] == 0x08){ /* PRN? */
return GPK8000; return GPK8000;
} }
if (card->slot->atr_info.hist_bytes[3] == 0x09){ /* PRN? */ if (card->slot->atr_info.hist_bytes[3] == 0x09) { /* PRN? */
return GPK16000; return GPK16000;
} }
} }
/* if the above ATR-analysis fails, check the known ATR list */ /* if the above ATR-analysis fails, check the known ATR list */
for (ai = atrlist; ai->atr_len; ai++) { i = _sc_match_atr_hex(card, gpk_atrs, &variant);
if (card->atr_len >= ai->atr_len if (i < 0)
&& !memcmp(card->atr, ai->atr, ai->atr_len)) return 0;
return ai->variant; return variant;
}
return 0;
} }
/* /*
* return 1 iff this driver can handle the card * return 1 if this driver can handle the card
*/ */
static int static int
gpk_match(struct sc_card *card) gpk_match_card(struct sc_card *card)
{ {
return gpk_identify(card)? 1 : 0; return gpk_identify(card) ? 1 : 0;
} }
/* /*
@ -1906,7 +1897,7 @@ sc_get_driver()
iso_ops = iso_drv->ops; iso_ops = iso_drv->ops;
gpk_ops = *iso_ops; gpk_ops = *iso_ops;
gpk_ops.match_card = gpk_match; gpk_ops.match_card = gpk_match_card;
gpk_ops.init = gpk_init; gpk_ops.init = gpk_init;
gpk_ops.finish = gpk_finish; gpk_ops.finish = gpk_finish;
gpk_ops.select_file = gpk_select_file; gpk_ops.select_file = gpk_select_file;

View File

@ -23,12 +23,22 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
static struct sc_atr_table_hex jcop_atrs[] = {
{ "3B:E6:00:FF:81:31:FE:45:4A:43:4F:50:33:31:06" },
#if 0
/* Requires secure messaging */
{ "3B:E6:00:FF:81:31:FE:45:4A:43:4F:50:32:31:06" },
#endif
{ NULL }
};
static struct sc_card_operations jcop_ops; static struct sc_card_operations jcop_ops;
static struct sc_card_driver jcop_drv = { static struct sc_card_driver jcop_drv = {
"JCOP cards with BlueZ PKCS#15 applet", "JCOP cards with BlueZ PKCS#15 applet",
"jcop", "jcop",
&jcop_ops &jcop_ops
}; };
#define SELECT_MF 0 #define SELECT_MF 0
#define SELECT_EFDIR 1 #define SELECT_EFDIR 1
#define SELECT_APPDF 2 #define SELECT_APPDF 2
@ -62,35 +72,15 @@ static int jcop_finish(struct sc_card *card)
return 0; return 0;
} }
static const char *jcop_atrs[] = {
"3B:E6:00:FF:81:31:FE:45:4A:43:4F:50:33:31:06",
/* Requires secure messaging */
/*"3B:E6:00:FF:81:31:FE:45:4A:43:4F:50:32:31:06",*/
NULL
};
static int jcop_match_card(struct sc_card *card) static int jcop_match_card(struct sc_card *card)
{ {
int i, match = -1; int i;
for (i = 0; jcop_atrs[i] != NULL; i++) { i = _sc_match_atr_hex(card, jcop_atrs, NULL);
u8 defatr[SC_MAX_ATR_SIZE]; if (i < 0)
size_t len = sizeof(defatr); return 0;
const char *atrp = jcop_atrs[i]; return 1;
if (sc_hex_to_bin(atrp, defatr, &len))
continue;
if (len != card->atr_len)
continue;
if (memcmp(card->atr, defatr, len) != 0)
continue;
match = i;
break;
}
if (match == -1)
return 0;
return 1;
} }
static unsigned char ef_dir_contents[128] = { static unsigned char ef_dir_contents[128] = {

View File

@ -28,28 +28,17 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include "esteid.h" #include "esteid.h"
#define TYPE_UNKNOWN 0 #define TYPE_UNKNOWN 0
#define TYPE_ANY 1 #define TYPE_ANY 1
#define TYPE_ESTEID 2 #define TYPE_ESTEID 2
static struct sc_atr_table_hex mcrd_atrs[] = {
/* this structure should be somewhere else. Copied from other card source. { "3B:FF:94:00:FF:80:B1:FE:45:1F:03:00:68:D2:76:00:00:28:FF:05:1E:31:80:00:90:00:23", "German BMI", TYPE_ANY },
* I need to make sure a 'variant' of a card to make decisions. { "3B:FE:94:00:FF:80:B1:FA:45:1F:03:45:73:74:45:49:44:20:76:65:72:20:31:2E:30:43", "EstEID (cold)", TYPE_ESTEID },
*/ { "3B:6E:00:FF:45:73:74:45:49:44:20:76:65:72:20:31:2E:30", "EstEID (warm)", TYPE_ESTEID },
struct sc_card_atrs { { NULL }
const char *atr;
const int type;
const char *name;
};
static struct sc_card_atrs mcrd_atrs[] = {
{"3B:FF:94:00:FF:80:B1:FE:45:1F:03:00:68:D2:76:00:00:28:FF:05:1E:31:80:00:90:00:23", TYPE_ANY, "German BMI"},
{"3B:FE:94:00:FF:80:B1:FA:45:1F:03:45:73:74:45:49:44:20:76:65:72:20:31:2E:30:43", TYPE_ESTEID, "EstEID (cold)"},
{"3B:6E:00:FF:45:73:74:45:49:44:20:76:65:72:20:31:2E:30", TYPE_ESTEID, "EstEID (warm)"},
{NULL, TYPE_UNKNOWN, NULL}
}; };
static struct sc_card_operations mcrd_ops; static struct sc_card_operations mcrd_ops;
@ -160,26 +149,6 @@ static void clear_special_files (struct df_info_s *dfi)
} }
} }
/* this function should be somewhere else in opensc code, too */
static int
sc_card_identify (struct sc_card *card, struct sc_card_atrs *atr_list)
{
int i;
for (i = 0; atr_list[i].atr != NULL; i++)
{
u8 defatr[SC_MAX_ATR_SIZE];
size_t len = sizeof (defatr);
const char *atrp = atr_list[i].atr;
if (sc_hex_to_bin (atrp, defatr, &len))
continue;
if (len != card->atr_len)
continue;
if (memcmp (card->atr, defatr, len) == 0)
return atr_list[i].type;
}
return 0;
}
/* Some functionality straight from the EstEID manual. /* Some functionality straight from the EstEID manual.
* Official notice: Refer to the Micardo 2.1 Public manual. * Official notice: Refer to the Micardo 2.1 Public manual.
* Sad side: not available without a NDA. * Sad side: not available without a NDA.
@ -278,9 +247,24 @@ mcrd_set_decipher_key_ref (struct sc_card *card, int key_reference)
SC_FUNC_RETURN (card->ctx, 2, sc_check_sw (card, apdu.sw1, apdu.sw2)); SC_FUNC_RETURN (card->ctx, 2, sc_check_sw (card, apdu.sw1, apdu.sw2));
} }
static int sc_card_type(struct sc_card *card)
{
int i, type;
i = _sc_match_atr_hex(card, mcrd_atrs, &type);
if (i < 0)
return 0;
return type;
}
static int mcrd_match_card(struct sc_card *card) static int mcrd_match_card(struct sc_card *card)
{ {
return sc_card_identify(card, mcrd_atrs) != 0; int i;
i = _sc_match_atr_hex(card, mcrd_atrs, NULL);
if (i < 0)
return 0;
return 1;
} }
static int mcrd_init(struct sc_card *card) static int mcrd_init(struct sc_card *card)
@ -305,7 +289,7 @@ static int mcrd_init(struct sc_card *card)
priv->curpath[0] = MFID; priv->curpath[0] = MFID;
priv->curpathlen = 1; priv->curpathlen = 1;
if (sc_card_identify(card, mcrd_atrs) != TYPE_ESTEID) if (sc_card_type(card) != TYPE_ESTEID)
load_special_files (card); load_special_files (card);
return 0; return 0;
} }
@ -1101,7 +1085,7 @@ static int mcrd_set_security_env(struct sc_card *card,
SC_FUNC_CALLED(card->ctx, 2); SC_FUNC_CALLED(card->ctx, 2);
/* special environemnt handling for esteid, stolen from openpgp */ /* special environemnt handling for esteid, stolen from openpgp */
if (sc_card_identify(card, mcrd_atrs) == TYPE_ESTEID) { if (sc_card_type(card) == TYPE_ESTEID) {
/* some sanity checks */ /* some sanity checks */
if (env->flags & SC_SEC_ENV_ALG_PRESENT) { if (env->flags & SC_SEC_ENV_ALG_PRESENT) {
if (env->algorithm != SC_ALGORITHM_RSA) if (env->algorithm != SC_ALGORITHM_RSA)

View File

@ -24,11 +24,11 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
static struct sc_atr_table miocos_atrs[] = { static struct sc_atr_table_hex miocos_atrs[] = {
/* Test card with 32 kB memory */ /* Test card with 32 kB memory */
{ (const u8 *) "\x3B\x9D\x94\x40\x23\x00\x68\x10\x11\x4D\x69\x6F\x43\x4F\x53\x00\x90\x00", 18 }, { "3B:9D:94:40:23:00:68:10:11:4D:69:6F:43:4F:53:00:90:00" },
/* Test card with 64 kB memory */ /* Test card with 64 kB memory */
{ (const u8 *) "\x3B\x9D\x94\x40\x23\x00\x68\x20\x01\x4D\x69\x6F\x43\x4F\x53\x00\x90\x00", 18 }, { "3B:9D:94:40:23:00:68:20:01:4D:69:6F:43:4F:53:00:90:00" },
{ NULL } { NULL }
}; };
@ -54,7 +54,7 @@ static int miocos_match_card(struct sc_card *card)
{ {
int i; int i;
i = _sc_match_atr(card, miocos_atrs, NULL); i = _sc_match_atr_hex(card, miocos_atrs, NULL);
if (i < 0) if (i < 0)
return 0; return 0;
return 1; return 1;
@ -62,12 +62,8 @@ static int miocos_match_card(struct sc_card *card)
static int miocos_init(struct sc_card *card) static int miocos_init(struct sc_card *card)
{ {
int i, id;
struct miocos_priv_data *priv = NULL; struct miocos_priv_data *priv = NULL;
i = _sc_match_atr(card, miocos_atrs, &id);
if (i < 0)
return 0;
priv = (struct miocos_priv_data *) malloc(sizeof(struct miocos_priv_data)); priv = (struct miocos_priv_data *) malloc(sizeof(struct miocos_priv_data));
if (priv == NULL) if (priv == NULL)
return SC_ERROR_OUT_OF_MEMORY; return SC_ERROR_OUT_OF_MEMORY;

View File

@ -26,17 +26,11 @@
#include "cardctl.h" #include "cardctl.h"
#include "pkcs15.h" #include "pkcs15.h"
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include <openssl/des.h> #include <openssl/des.h>
#include <openssl/opensslv.h> #include <openssl/opensslv.h>
#include "log.h"
#include "pkcs15.h"
#include "card-oberthur.h" #include "card-oberthur.h"
/* keep OpenSSL 0.9.6 users happy ;-) */ /* keep OpenSSL 0.9.6 users happy ;-) */
@ -47,42 +41,30 @@
#define DES_ecb_encrypt(a,b,c,d) des_ecb_encrypt(a,b,*c,d) #define DES_ecb_encrypt(a,b,c,d) des_ecb_encrypt(a,b,*c,d)
#endif #endif
static NTLV_t oberthur_atrs[] = { static struct sc_atr_table_hex oberthur_atrs[] = {
#if 0 #if 0
{ "Oberthur 32k", ATR_OBERTHUR_32K, 20, { "3B:7F:18:00:00:00:31:C0:73:9E:01:0B:64:52:D9:04:00:82:90:00", "Oberthur 32k", ATR_OBERTHUR_32K },
(unsigned char *) "\x3B\x7F\x18\x00\x00\x00\x31\xC0\x73\x9E\x01\x0B\x64\x52\xD9\x04\x00\x82\x90\x00" { "3B:7F:18:00:00:00:31:C0:73:9E:01:0B:64:52:D9:05:00:82:90:00", "Oberthur 32k BIO", ATR_OBERTHUR_32K_BIO },
},
{ "Oberthur 32k BIO", ATR_OBERTHUR_32K_BIO, 20,
(unsigned char *) "\x3B\x7F\x18\x00\x00\x00\x31\xC0\x73\x9E\x01\x0B\x64\x52\xD9\x05\x00\x82\x90\x00"
},
#endif #endif
{ "Oberthur 64k v4/2.1.1", ATR_OBERTHUR_64K, 18, { "3B:7D:18:00:00:00:31:80:71:8E:64:77:E3:01:00:82:90:00", "Oberthur 64k v4/2.1.1", ATR_OBERTHUR_64K },
"\x3B\x7D\x18\x00\x00\x00\x31\x80\x71\x8E\x64\x77\xE3\x01\x00\x82\x90\x00" { "3B:7D:18:00:00:00:31:80:71:8E:64:77:E3:02:00:82:90:00", "Oberthur 64k v4/2.1.1", ATR_OBERTHUR_64K },
}, { "3B:7D:11:00:00:00:31:80:71:8E:64:77:E3:01:00:82:90:00", "Oberthur 64k v5", ATR_OBERTHUR_64K },
{ "Oberthur 64k v4/2.1.1", ATR_OBERTHUR_64K, 18, { "3B:7D:11:00:00:00:31:80:71:8E:64:77:E3:02:00:82:90:00", "Oberthur 64k v5/2.2.0", ATR_OBERTHUR_64K },
"\x3B\x7D\x18\x00\x00\x00\x31\x80\x71\x8E\x64\x77\xE3\x02\x00\x82\x90\x00" { NULL }
},
{ "Oberthur 64k v5", ATR_OBERTHUR_64K, 18,
"\x3B\x7D\x11\x00\x00\x00\x31\x80\x71\x8E\x64\x77\xE3\x01\x00\x82\x90\x00"
},
{ "Oberthur 64k v5/2.2.0", ATR_OBERTHUR_64K, 18,
"\x3B\x7D\x11\x00\x00\x00\x31\x80\x71\x8E\x64\x77\xE3\x02\x00\x82\x90\x00"
},
{ NULL, 0, 0, NULL }
}; };
static NTLV_t oberthur_aids[] = { static NTLV_t oberthur_aids[] = {
#if 0 #if 0
{ "AuthentIC v2", AID_OBERTHUR_V2, 14, { "AuthentIC v2", AID_OBERTHUR_V2, 14,
(unsigned char *) "\xA0\x00\x00\x00\x77\x58\x35\x30\x39\x23\x56\x32\x2E\x30" (const unsigned char *) "\xA0\x00\x00\x00\x77\x58\x35\x30\x39\x23\x56\x32\x2E\x30"
}, },
{ "AuthentIC v4", AID_OBERTHUR_V4, 16, { "AuthentIC v4", AID_OBERTHUR_V4, 16,
(unsigned char *) "\xA0\x00\x00\x00\x77\x01\x03\x03\x00\x20\x03\xF1\x00\x00\x00\x02" (const unsigned char *) "\xA0\x00\x00\x00\x77\x01\x03\x03\x00\x20\x03\xF1\x00\x00\x00\x02"
}, },
#endif #endif
{ "AuthentIC v5", AID_OBERTHUR_V5, 16, { "AuthentIC v5", AID_OBERTHUR_V5, 16,
"\xA0\x00\x00\x00\x77\x01\x03\x03\x00\x00\x00\xF1\x00\x00\x00\x02" (const unsigned char *) "\xA0\x00\x00\x00\x77\x01\x03\x03\x00\x00\x00\xF1\x00\x00\x00\x02"
}, },
{ NULL, 0, 0, NULL } { NULL, 0, 0, NULL }
}; };
@ -184,23 +166,17 @@ auth_select_aid(struct sc_card *card)
return oberthur_aids[ii].value == NULL ? -1 : 0; return oberthur_aids[ii].value == NULL ? -1 : 0;
} }
static int static int
auth_match_card(struct sc_card *card) auth_match_card(struct sc_card *card)
{ {
int ii; int i;
for (ii = 0; oberthur_atrs[ii].value != NULL; ii++) {
if (oberthur_atrs[ii].len != card->atr_len)
continue;
else if (!memcmp(card->atr, oberthur_atrs[ii].value, oberthur_atrs[ii].len))
return 1;
}
return 0; i = _sc_match_atr_hex(card, oberthur_atrs, NULL);
if (i < 0)
return 0;
return 1;
} }
static int static int
auth_init(struct sc_card *card) auth_init(struct sc_card *card)
{ {

View File

@ -3,25 +3,23 @@
#include <opensc/opensc.h> #include <opensc/opensc.h>
#define AID_OBERTHUR_V2 0x201 #define AID_OBERTHUR_V2 0x201
#define AID_OBERTHUR_V4 0x401 #define AID_OBERTHUR_V4 0x401
#define AID_OBERTHUR_V5 0x501 #define AID_OBERTHUR_V5 0x501
#define ATR_OBERTHUR 0x0100 #define ATR_OBERTHUR 0x0100
#define ATR_OBERTHUR_32K 0x0110 #define ATR_OBERTHUR_32K 0x0110
#define ATR_OBERTHUR_32K_BIO 0x0112 #define ATR_OBERTHUR_32K_BIO 0x0112
#define ATR_OBERTHUR_64K 0x0120 #define ATR_OBERTHUR_64K 0x0120
#define FLAG_KEYGEN 0x0001 #define AUTH_PIN 1
#define AUTH_PUK 2
#define AUTH_PIN 1 #define PUBKEY_512_ASN1_SIZE 0x4A
#define AUTH_PUK 2 #define PUBKEY_1024_ASN1_SIZE 0x8C
#define PUBKEY_2048_ASN1_SIZE 0x10E
#define PUBKEY_512_ASN1_SIZE 0x4A #define SC_OBERTHUR_MAX_ATTR_SIZE 8
#define PUBKEY_1024_ASN1_SIZE 0x8C
#define PUBKEY_2048_ASN1_SIZE 0x10E
#define SC_OBERTHUR_MAX_ATTR_SIZE 8
struct NTLV { struct NTLV {
const char *name; const char *name;
@ -31,19 +29,6 @@ struct NTLV {
}; };
typedef struct NTLV NTLV_t; typedef struct NTLV NTLV_t;
struct oberthur_atr {
const char *atr;
const char *name;
unsigned int type;
};
struct oberthur_aid {
const char *aid;
const char *name;
unsigned int type;
};
typedef struct oberthur_aid oberthur_aid_t;
struct auth_application_id { struct auth_application_id {
unsigned int tag; unsigned int tag;
u8 value[SC_MAX_AID_SIZE]; u8 value[SC_MAX_AID_SIZE];
@ -58,7 +43,6 @@ struct auth_senv {
}; };
typedef struct auth_senv auth_senv_t; typedef struct auth_senv auth_senv_t;
struct auth_private_data { struct auth_private_data {
struct sc_pin_cmd_pin pin_info; struct sc_pin_cmd_pin pin_info;
long int sn; long int sn;

View File

@ -1,5 +1,5 @@
/* /*
* card-pgp.c: Support for OpenPGP card * card-openpgp.c: Support for OpenPGP card
* *
* Copyright (C) 2003 Olaf Kirch <okir@suse.de> * Copyright (C) 2003 Olaf Kirch <okir@suse.de>
* *
@ -25,9 +25,9 @@
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
static const char *pgp_atrs[] = { static struct sc_atr_table_hex pgp_atrs[] = {
"3b:fa:13:00:ff:81:31:80:45:00:31:c1:73:c0:01:00:00:90:00:b1", { "3b:fa:13:00:ff:81:31:80:45:00:31:c1:73:c0:01:00:00:90:00:b1" },
NULL { NULL }
}; };
static struct sc_card_operations *iso_ops; static struct sc_card_operations *iso_ops;
@ -108,25 +108,11 @@ struct pgp_priv_data {
static int static int
pgp_match_card(sc_card_t *card) pgp_match_card(sc_card_t *card)
{ {
int i, match = -1; int i;
for (i = 0; pgp_atrs[i] != NULL; i++) { i = _sc_match_atr_hex(card, pgp_atrs, NULL);
u8 defatr[SC_MAX_ATR_SIZE]; if (i < 0)
size_t len = sizeof(defatr);
const char *atrp = pgp_atrs[i];
if (sc_hex_to_bin(atrp, defatr, &len))
continue;
if (len != card->atr_len)
continue;
if (memcmp(card->atr, defatr, len) != 0)
continue;
match = i;
break;
}
if (match == -1)
return 0; return 0;
return 1; return 1;
} }

View File

@ -25,13 +25,13 @@
#define SETEC_PKI 1 #define SETEC_PKI 1
#define SETEC_OTHER 2 #define SETEC_OTHER 2
static struct sc_atr_table setcos_atrs[] = { static struct sc_atr_table_hex setcos_atrs[] = {
/* the current FINEID card has this ATR: */ /* the current FINEID card has this ATR: */
{ (const u8 *) "\x3B\x9F\x94\x40\x1E\x00\x67\x11\x43\x46\x49\x53\x45\x10\x52\x66\xFF\x81\x90\x00", 20, SETEC_PKI }, { "3B:9F:94:40:1E:00:67:11:43:46:49:53:45:10:52:66:FF:81:90:00", NULL, SETEC_PKI },
/* RSA SecurID 3100 */ /* RSA SecurID 3100 */
{ (const u8 *) "\x3B\x9F\x94\x40\x1E\x00\x67\x16\x43\x46\x49\x53\x45\x10\x52\x66\xFF\x81\x90\x00", 20, SETEC_PKI }, { "3B:9F:94:40:1E:00:67:16:43:46:49:53:45:10:52:66:FF:81:90:00", NULL, SETEC_PKI },
/* this is from a Nokia branded SC */ /* this is from a Nokia branded SC */
{ (const u8 *) "\x3B\x1F\x11\x00\x67\x80\x42\x46\x49\x53\x45\x10\x52\x66\xFF\x81\x90\x00", 18, SETEC_OTHER }, { "3B:1F:11:00:67:80:42:46:49:53:45:10:52:66:FF:81:90:00", NULL, SETEC_OTHER },
{ NULL } { NULL }
}; };
@ -63,8 +63,7 @@ static int setcos_match_card(struct sc_card *card)
return 0; return 0;
if (memcmp(hist_bytes + 4, "FISE", 4) != 0) if (memcmp(hist_bytes + 4, "FISE", 4) != 0)
return 0; return 0;
i = _sc_match_atr_hex(card, setcos_atrs, NULL);
i = _sc_match_atr(card, setcos_atrs, NULL);
if (i < 0) if (i < 0)
return 0; return 0;
return 1; return 1;
@ -75,7 +74,7 @@ static int setcos_init(struct sc_card *card)
int i, id; int i, id;
struct setcos_priv_data *priv = NULL; struct setcos_priv_data *priv = NULL;
i = _sc_match_atr(card, setcos_atrs, &id); i = _sc_match_atr_hex(card, setcos_atrs, &id);
if (i < 0) if (i < 0)
return 0; return 0;
priv = (struct setcos_priv_data *) malloc(sizeof(struct setcos_priv_data)); priv = (struct setcos_priv_data *) malloc(sizeof(struct setcos_priv_data));

View File

@ -27,10 +27,10 @@
/* TODO: - secure messaging /* TODO: - secure messaging
*/ */
static const char *starcos_atrs[] = { static struct sc_atr_table_hex starcos_atrs[] = {
"3B:B7:94:00:c0:24:31:fe:65:53:50:4b:32:33:90:00:b4", { "3B:B7:94:00:c0:24:31:fe:65:53:50:4b:32:33:90:00:b4" },
"3B:B7:94:00:81:31:fe:65:53:50:4b:32:33:90:00:d1", { "3B:B7:94:00:81:31:fe:65:53:50:4b:32:33:90:00:d1" },
NULL { NULL }
}; };
static struct sc_card_operations starcos_ops; static struct sc_card_operations starcos_ops;
@ -43,7 +43,6 @@ static struct sc_card_driver starcos_drv = {
NULL, 0 NULL, 0
}; };
static const struct sc_card_error starcos_errors[] = static const struct sc_card_error starcos_errors[] =
{ {
{ 0x6600, SC_ERROR_INCORRECT_PARAMETERS, "Error setting the security env"}, { 0x6600, SC_ERROR_INCORRECT_PARAMETERS, "Error setting the security env"},
@ -72,27 +71,12 @@ typedef struct starcos_ex_data_st {
/* the starcos part */ /* the starcos part */
static int starcos_match_card(struct sc_card *card) static int starcos_match_card(struct sc_card *card)
{ {
int i, match = -1; int i;
for (i = 0; starcos_atrs[i] != NULL; i++) i = _sc_match_atr_hex(card, starcos_atrs, NULL);
{ if (i < 0)
u8 defatr[SC_MAX_ATR_SIZE];
size_t len = sizeof(defatr);
const char *atrp = starcos_atrs[i];
if (sc_hex_to_bin(atrp, defatr, &len))
continue;
if (len != card->atr_len)
continue;
if (memcmp(card->atr, defatr, len) != 0)
continue;
match = i + 1;
break;
}
if (match == -1)
return 0; return 0;
return i + 1; /* XXX */
return i;
} }
static int starcos_init(struct sc_card *card) static int starcos_init(struct sc_card *card)

View File

@ -27,11 +27,14 @@
#include <time.h> #include <time.h>
#include <stdlib.h> #include <stdlib.h>
static const char *tcos_atrs[] = { static struct sc_atr_table_hex tcos_atrs[] = {
"3B:BA:13:00:81:31:86:5D:00:64:05:0A:02:01:31:80:90:00:8B", /* SLE44 */ /* SLE44 */
"3B:BA:14:00:81:31:86:5D:00:64:05:14:02:02:31:80:90:00:91", /* SLE66S */ { "3B:BA:13:00:81:31:86:5D:00:64:05:0A:02:01:31:80:90:00:8B" },
"3B:BA:96:00:81:31:86:5D:00:64:05:60:02:03:31:80:90:00:66", /* SLE66P */ /* SLE66S */
NULL { "3B:BA:14:00:81:31:86:5D:00:64:05:14:02:02:31:80:90:00:91" },
/* SLE66P */
{ "3B:BA:96:00:81:31:86:5D:00:64:05:60:02:03:31:80:90:00:66" },
{ NULL }
}; };
static struct sc_card_operations tcos_ops; static struct sc_card_operations tcos_ops;
@ -55,25 +58,11 @@ static int tcos_finish(struct sc_card *card)
static int tcos_match_card(struct sc_card *card) static int tcos_match_card(struct sc_card *card)
{ {
int i, match = -1; int i;
for (i = 0; tcos_atrs[i] != NULL; i++) { i = _sc_match_atr_hex(card, tcos_atrs, NULL);
u8 defatr[SC_MAX_ATR_SIZE]; if (i < 0)
size_t len = sizeof(defatr);
const char *atrp = tcos_atrs[i];
if (sc_hex_to_bin(atrp, defatr, &len))
continue;
if (len != card->atr_len)
continue;
if (memcmp(card->atr, defatr, len) != 0)
continue;
match = i;
break;
}
if (match == -1)
return 0; return 0;
return 1; return 1;
} }

View File

@ -198,27 +198,22 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card)
return 0; return 0;
} }
static const char *atr1 = "3B:FE:94:00:FF:80:B1:FA:45:1F:03:45:73:74:45:49:44:20:76:65:72:20:31:2E:30:43"; static struct sc_atr_table_hex esteid_atrs[] = {
static const char *atr2 = "3B:6E:00:FF:45:73:74:45:49:44:20:76:65:72:20:31:2E:30"; { "3B:FE:94:00:FF:80:B1:FA:45:1F:03:45:73:74:45:49:44:20:76:65:72:20:31:2E:30:43" },
{ "3B:6E:00:FF:45:73:74:45:49:44:20:76:65:72:20:31:2E:30" },
{ NULL }
};
static int esteid_detect_card(sc_pkcs15_card_t *p15card) static int esteid_detect_card(sc_pkcs15_card_t *p15card)
{ {
u8 buf[SC_MAX_ATR_SIZE];
size_t len = sizeof(buf);
sc_card_t *card = p15card->card; sc_card_t *card = p15card->card;
int i;
/* XXX: save type of the micardo card in the card structure */ /* XXX: save type of the micardo card in the card structure */
if (sc_hex_to_bin(atr1, buf, &len)) i = _sc_match_atr_hex(card, esteid_atrs, NULL);
return SC_ERROR_INTERNAL; if (i < 0)
if (len == card->atr_len && !memcmp(card->atr, buf, len)) return SC_ERROR_WRONG_CARD;
return SC_SUCCESS; return SC_SUCCESS;
len = sizeof(buf);
if (sc_hex_to_bin(atr2, buf, &len))
return SC_ERROR_INTERNAL;
if (len == card->atr_len && !memcmp(card->atr, buf, len))
return SC_SUCCESS;
return SC_ERROR_WRONG_CARD;
} }
int sc_pkcs15emu_esteid_init_ex(sc_pkcs15_card_t *p15card, int sc_pkcs15emu_esteid_init_ex(sc_pkcs15_card_t *p15card,