- Optimize a few cpu cycles from _sc_match_atr_hex

- Replace struct sc_atr_table / _sc_match_atr with
  recently introduced _hex variants
- Rewrote _add_atr
- Introduce int type variable to sc_card_t, so that
  every other card driver won't have to glue around
  with this
- Card driver cleanups, optimize the number of
  sc_match_atr called per card driver. Also
  always try direct match with _sc_match_atr
  first, before relying on eg. historical bytes
  information on some card drivers
- Fixed a memory leak from the miocos driver


git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@2145 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
aet 2005-02-06 19:40:40 +00:00
parent c30494a942
commit 69d2e9014d
18 changed files with 208 additions and 285 deletions

View File

@ -119,7 +119,8 @@ static long t1, t2, tot_read = 0, tot_dur = 0, dur;
#define BELPIC_VERSION "1.4" #define BELPIC_VERSION "1.4"
#define BELPIC_EID 1 #define TYPE_BELPIC_EID 1
/* Most of the #defines here are also present in the pkcs15 files, but /* Most of the #defines here are also present in the pkcs15 files, but
* because this driver has no access to them, it's hardcoded here. If * because this driver has no access to them, it's hardcoded here. If
* other Belpic cards with other 'settings' appear, we'll have to move * other Belpic cards with other 'settings' appear, we'll have to move
@ -135,24 +136,23 @@ 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_hex belpic_atrs[] = { static struct sc_atr_table belpic_atrs[] = {
/* Applet V1.1 */ /* Applet V1.1 */
{ "3B:98:13:40:0A:A5:03:01:01:01:AD:13:11", NULL, BELPIC_EID }, { "3B:98:13:40:0A:A5:03:01:01:01:AD:13:11", NULL, TYPE_BELPIC_EID },
/* Applet V1.0 with new EMV-compatible ATR */ /* Applet V1.0 with new EMV-compatible ATR */
{ "3B:98:94:40:0A:A5:03:01:01:01:AD:13:10", NULL, BELPIC_EID }, { "3B:98:94:40:0A:A5:03:01:01:01:AD:13:10", NULL, TYPE_BELPIC_EID },
/* Applet beta 5 + V1.0 */ /* Applet beta 5 + V1.0 */
{ "3B:98:94:40:FF:A5:03:01:01:01:AD:13:10", NULL, BELPIC_EID }, { "3B:98:94:40:FF:A5:03:01:01:01:AD:13:10", NULL, TYPE_BELPIC_EID },
#if 0 #if 0
/* Applet beta 3 + 4 */ /* Applet beta 3 + 4 */
{ "3B:98:11:40:FF:A5:03:01:01:01:AD:13:04", NULL, BELPIC_EID }, { "3B:98:11:40:FF:A5:03:01:01:01:AD:13:04", NULL, TYPE_BELPIC_EID },
/* Applet beta 2 */ /* Applet beta 2 */
{ "3B:68:00:00:29:05:01:02:01:AD:13:03", NULL, BELPIC_EID }, { "3B:68:00:00:29:05:01:02:01:AD:13:03", NULL, TYPE_BELPIC_EID },
#endif #endif
{ NULL } { NULL }
}; };
struct belpic_priv_data { struct belpic_priv_data {
int type;
int lang; int lang;
int options; int options;
#ifdef BELPIC_PIN_PAD #ifdef BELPIC_PIN_PAD
@ -970,7 +970,7 @@ static int belpic_match_card(struct sc_card *card)
{ {
int i; int i;
i = _sc_match_atr_hex(card, belpic_atrs, NULL); i = _sc_match_atr(card, belpic_atrs, &card->type);
if (i < 0) if (i < 0)
return 0; return 0;
return 1; return 1;
@ -978,7 +978,6 @@ static int belpic_match_card(struct sc_card *card)
static int belpic_init(struct sc_card *card) static int belpic_init(struct sc_card *card)
{ {
int i, id;
struct belpic_priv_data *priv = NULL; struct belpic_priv_data *priv = NULL;
scconf_block *conf_block; scconf_block *conf_block;
#ifdef BELPIC_PIN_PAD #ifdef BELPIC_PIN_PAD
@ -994,16 +993,15 @@ static int belpic_init(struct sc_card *card)
#endif #endif
sc_debug(card->ctx, "\n"); sc_debug(card->ctx, "\n");
i = _sc_match_atr_hex(card, belpic_atrs, &id); if (card->type < 0)
if (i < 0) card->type = TYPE_BELPIC_EID; /* Unknown card: 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));
if (priv == NULL) if (priv == NULL)
return SC_ERROR_OUT_OF_MEMORY; return SC_ERROR_OUT_OF_MEMORY;
card->drv_data = priv; card->drv_data = priv;
card->cla = 0x00; card->cla = 0x00;
priv->type = id; if (card->type == TYPE_BELPIC_EID) {
if (id == BELPIC_EID) {
_sc_card_add_rsa_alg(card, 1024, _sc_card_add_rsa_alg(card, 1024,
SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE, 0); SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE, 0);
} }
@ -1034,8 +1032,8 @@ static int belpic_init(struct sc_card *card)
card->max_pin_len = BELPIC_MAX_USER_PIN_LEN; card->max_pin_len = BELPIC_MAX_USER_PIN_LEN;
#ifdef HAVE_GUI #ifdef HAVE_GUI
i = scgui_init(); r = scgui_init();
if (i != 0) if (r != 0)
sc_error(card->ctx, "scgui_init() returned error %d\n", i); sc_error(card->ctx, "scgui_init() returned error %d\n", i);
#endif #endif

View File

@ -31,9 +31,6 @@
* Either coincidence, or a known problem. */ * Either coincidence, or a known problem. */
#define ETOKEN_MAX_PAYLOAD 120 #define ETOKEN_MAX_PAYLOAD 120
/* Different eToken types */
#define CARDOS_TYPE_ANY 1
static const struct sc_card_operations *iso_ops = NULL; static const struct sc_card_operations *iso_ops = NULL;
struct sc_card_operations etoken_ops; struct sc_card_operations etoken_ops;
@ -43,17 +40,17 @@ static struct sc_card_driver etoken_drv = {
&etoken_ops &etoken_ops
}; };
static struct sc_atr_table_hex etoken_atrs[] = { static struct sc_atr_table etoken_atrs[] = {
/* 4.0 */ /* 4.0 */
{ "3b:e2:00:ff:c1:10:31:fe:55:c8:02:9c", NULL, CARDOS_TYPE_ANY }, { "3b:e2:00:ff:c1:10:31:fe:55:c8:02:9c" },
/* 4.01 */ /* 4.01 */
{ "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" },
/* 4.01a */ /* 4.01a */
{ "3b:f2:98:00:ff:c1:10:31:fe:55:c8:04:12", NULL, CARDOS_TYPE_ANY }, { "3b:f2:98:00:ff:c1:10:31:fe:55:c8:04:12" },
/* 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", NULL, CARDOS_TYPE_ANY }, { "3b:e9:00:ff:c1:10:31:fe:55:00:64:05:00:c8:02:31:80:00:47" },
/* 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", NULL, 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 } { NULL }
}; };
@ -66,7 +63,7 @@ static int etoken_match_card(struct sc_card *card)
{ {
int i; int i;
i = _sc_match_atr_hex(card, etoken_atrs, NULL); i = _sc_match_atr(card, etoken_atrs, NULL);
if (i < 0) if (i < 0)
return 0; return 0;
return 1; return 1;

View File

@ -23,18 +23,18 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#define TYPE_UNKNOWN 0x0000
#define TYPE_CRYPTOFLEX 0x0100 #define TYPE_CRYPTOFLEX 0x0100
#define TYPE_MULTIFLEX 0x0200 #define TYPE_MULTIFLEX 0x0200
#define TYPE_CYBERFLEX 0x0300 #define TYPE_CYBERFLEX 0x0300
#define FLAG_KEYGEN 0x0001 #define FLAG_KEYGEN 0x0001
#define FLAG_FULL_DES 0x0002 /* whatever that means */ #define FLAG_FULL_DES 0x0002 /* whatever that means */
#define TYPE_MASK 0xFF00 #define TYPE_MASK 0xFF00
#define IS_CYBERFLEX(card) ((DRV_DATA(card)->card_type & TYPE_MASK) == TYPE_CYBERFLEX) #define IS_CYBERFLEX(card) ((card->type & TYPE_MASK) == TYPE_CYBERFLEX)
static struct sc_atr_table_hex flex_atrs[] = { static struct sc_atr_table flex_atrs[] = {
/* Cryptoflex */ /* Cryptoflex */
/* 8k */ /* 8k */
{ "3B:95:15:40:FF:68:01:02:02:04", "Cryptoflex 8K", TYPE_CRYPTOFLEX }, { "3B:95:15:40:FF:68:01:02:02:04", "Cryptoflex 8K", TYPE_CRYPTOFLEX },
@ -80,11 +80,10 @@ static struct sc_atr_table_hex flex_atrs[] = {
}; };
struct flex_private_data { struct flex_private_data {
int card_type;
int rsa_key_ref; int rsa_key_ref;
/* Support card variations without having to /* Support card variations without having to
* do the if (DRV_DATA(card)->card_type ...) thing * do the if (card->type ...) thing
* all the time */ * all the time */
u8 aak_key_ref; u8 aak_key_ref;
}; };
@ -115,12 +114,13 @@ static int cryptoflex_match_card(struct sc_card *card)
{ {
int idx; int idx;
idx = _sc_match_atr_hex(card, flex_atrs, NULL); idx = _sc_match_atr(card, flex_atrs, NULL);
if (idx < 0) if (idx < 0)
return 0; return 0;
switch (flex_atrs[idx].id & TYPE_MASK) { switch (flex_atrs[idx].id & TYPE_MASK) {
case TYPE_CRYPTOFLEX: case TYPE_CRYPTOFLEX:
case TYPE_MULTIFLEX: case TYPE_MULTIFLEX:
card->type = idx;
return 1; return 1;
} }
return 0; return 0;
@ -130,11 +130,12 @@ static int cyberflex_match_card(struct sc_card *card)
{ {
int idx; int idx;
idx = _sc_match_atr_hex(card, flex_atrs, NULL); idx = _sc_match_atr(card, flex_atrs, NULL);
if (idx < 0) if (idx < 0)
return 0; return 0;
switch (flex_atrs[idx].id & TYPE_MASK) { switch (flex_atrs[idx].id & TYPE_MASK) {
case TYPE_CYBERFLEX: case TYPE_CYBERFLEX:
card->type = idx;
return 1; return 1;
} }
return 0; return 0;
@ -143,23 +144,22 @@ static int cyberflex_match_card(struct sc_card *card)
static int flex_init(struct sc_card *card) static int flex_init(struct sc_card *card)
{ {
struct flex_private_data *data; struct flex_private_data *data;
int idx; int idx = card->type;
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;
card->drv_data = data;
data->card_type = flex_atrs[idx].id; if (idx >= 0) {
card->name = flex_atrs[idx].name;
card->type = flex_atrs[idx].id;
}
card->cla = 0xC0;
data->aak_key_ref = 1; data->aak_key_ref = 1;
card->name = flex_atrs[idx].name;
card->drv_data = data;
card->cla = 0xC0;
/* Override Cryptoflex defaults for specific card types */ /* Override Cryptoflex defaults for specific card types */
switch (data->card_type & TYPE_MASK) { switch (card->type & TYPE_MASK) {
case TYPE_CYBERFLEX: case TYPE_CYBERFLEX:
card->cla = 0x00; card->cla = 0x00;
data->aak_key_ref = 0; data->aak_key_ref = 0;
@ -172,7 +172,7 @@ static int flex_init(struct sc_card *card)
flags = SC_ALGORITHM_RSA_RAW; flags = SC_ALGORITHM_RSA_RAW;
flags |= SC_ALGORITHM_RSA_HASH_NONE; flags |= SC_ALGORITHM_RSA_HASH_NONE;
if (data->card_type & FLAG_KEYGEN) if (card->type & FLAG_KEYGEN)
flags |= SC_ALGORITHM_ONBOARD_KEY_GEN; flags |= SC_ALGORITHM_ONBOARD_KEY_GEN;
_sc_card_add_rsa_alg(card, 512, flags, 0); _sc_card_add_rsa_alg(card, 512, flags, 0);
@ -1109,7 +1109,7 @@ static int flex_get_default_key(struct sc_card *card,
return SC_ERROR_NO_DEFAULT_KEY; return SC_ERROR_NO_DEFAULT_KEY;
/* These seem to be the default AAKs used by Schlumberger */ /* These seem to be the default AAKs used by Schlumberger */
switch (prv->card_type & TYPE_MASK) { switch (card->type & TYPE_MASK) {
case TYPE_CRYPTOFLEX: case TYPE_CRYPTOFLEX:
key = "2c:15:e5:26:e9:3e:8a:19"; key = "2c:15:e5:26:e9:3e:8a:19";
break; break;

View File

@ -72,8 +72,6 @@ enum {
* GPK4000 private data * GPK4000 private data
*/ */
struct gpk_private_data { struct gpk_private_data {
int variant;
/* The GPK usually do file offsets in multiples of /* The GPK usually do file offsets in multiples of
* 4 bytes. This can be customized however. We * 4 bytes. This can be customized however. We
* should really query for this during gpk_init */ * should really query for this during gpk_init */
@ -103,7 +101,7 @@ 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 sc_atr_table_hex gpk_atrs[] = { static struct sc_atr_table gpk_atrs[] = {
{ "3B:27:00:80:65:A2:04:01:01:37", "GPK 4K", GPK4000_s }, { "3B:27:00:80:65:A2:04:01:01:37", "GPK 4K", GPK4000_s },
{ "3B:27:00:80:65:A2:05:01:01:37", "GPK 4K", GPK4000_sp }, { "3B:27:00:80:65:A2:05:01:01:37", "GPK 4K", GPK4000_sp },
{ "3B:27:00:80:65:A2:0C:01:01:37", "GPK 4K", GPK4000_su256 }, { "3B:27:00:80:65:A2:0C:01:01:37", "GPK 4K", GPK4000_su256 },
@ -124,48 +122,41 @@ static struct sc_card_driver gpk_drv = {
&gpk_ops &gpk_ops
}; };
/*
* Identify the card variant based on the ATR
* returns the variant number or 0 on error
*/
static int
gpk_identify(struct sc_card *card)
{
int i, variant;
/* Gemplus GPK docs say we can use just the
* FMN and PRN fields of the historical bytes
* to recognize a GPK card
* See Table 43, pp. 188
* We'll use the first 2 bytes as well
*/
if ( (card->slot->atr_info.hist_bytes_len >= 7)
&& (card->slot->atr_info.hist_bytes[0] == 0x80)
&& (card->slot->atr_info.hist_bytes[1] == 0x65)
&& (card->slot->atr_info.hist_bytes[2] == 0xa2)) { /* FMN */
if (card->slot->atr_info.hist_bytes[3] == 0x08) { /* PRN? */
return GPK8000;
}
if (card->slot->atr_info.hist_bytes[3] == 0x09) { /* PRN? */
return GPK16000;
}
}
/* if the above ATR-analysis fails, check the known ATR list */
i = _sc_match_atr_hex(card, gpk_atrs, &variant);
if (i < 0)
return 0;
return variant;
}
/* /*
* return 1 if this driver can handle the card * return 1 if this driver can handle the card
*/ */
static int static int
gpk_match_card(struct sc_card *card) gpk_match_card(struct sc_card *card)
{ {
return gpk_identify(card) ? 1 : 0; int i;
i = _sc_match_atr(card, gpk_atrs, &card->type);
if (i < 0) {
const u8 *hist_bytes = card->slot->atr_info.hist_bytes;
/* Gemplus GPK docs say we can use just the
* FMN and PRN fields of the historical bytes
* to recognize a GPK card
* See Table 43, pp. 188
* We'll use the first 2 bytes as well
*/
if ((card->slot->atr_info.hist_bytes_len >= 7)
&& (hist_bytes[0] == 0x80)
&& (hist_bytes[1] == 0x65)
&& (hist_bytes[2] == 0xa2)) { /* FMN */
if (hist_bytes[3] == 0x08) { /* PRN? */
card->type = GPK8000;
return 1;
}
if (hist_bytes[3] == 0x09) { /* PRN? */
card->type = GPK16000;
return 1;
}
}
return 0;
}
return 1;
} }
/* /*
@ -177,15 +168,11 @@ gpk_init(struct sc_card *card)
struct gpk_private_data *priv; struct gpk_private_data *priv;
unsigned long exponent, flags, kg; unsigned long exponent, flags, kg;
unsigned char info[13]; unsigned char info[13];
int variant;
if (!(variant = gpk_identify(card)))
return SC_ERROR_INVALID_CARD;
card->drv_data = priv = (struct gpk_private_data *) malloc(sizeof(*priv)); card->drv_data = priv = (struct gpk_private_data *) malloc(sizeof(*priv));
if (card->drv_data == NULL) if (card->drv_data == NULL)
return SC_ERROR_OUT_OF_MEMORY; return SC_ERROR_OUT_OF_MEMORY;
memset(priv, 0, sizeof(*priv)); memset(priv, 0, sizeof(*priv));
priv->variant = variant;
/* read/write/update binary expect offset to be the /* read/write/update binary expect offset to be the
* number of 32 bit words. * number of 32 bit words.
@ -201,8 +188,8 @@ gpk_init(struct sc_card *card)
| SC_ALGORITHM_RSA_HASH_MD5_SHA1; | SC_ALGORITHM_RSA_HASH_MD5_SHA1;
flags |= SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_PAD_ANSI flags |= SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_PAD_ANSI
| SC_ALGORITHM_RSA_PAD_ISO9796; | SC_ALGORITHM_RSA_PAD_ISO9796;
exponent = (variant < 16000)? 0x10001 : 0; exponent = (card->type < 16000)? 0x10001 : 0;
kg = (variant >= 8000)? SC_ALGORITHM_ONBOARD_KEY_GEN : 0; kg = (card->type >= 8000)? SC_ALGORITHM_ONBOARD_KEY_GEN : 0;
_sc_card_add_rsa_alg(card, 512, flags|kg, exponent); _sc_card_add_rsa_alg(card, 512, flags|kg, exponent);
_sc_card_add_rsa_alg(card, 768, flags, exponent); _sc_card_add_rsa_alg(card, 768, flags, exponent);
_sc_card_add_rsa_alg(card, 1024, flags|kg, exponent); _sc_card_add_rsa_alg(card, 1024, flags|kg, exponent);
@ -1397,7 +1384,7 @@ gpk_erase_card(struct sc_card *card)
int r; int r;
SC_FUNC_CALLED(card->ctx, 1); SC_FUNC_CALLED(card->ctx, 1);
switch (priv->variant) { switch (card->type) {
case GPK4000_su256: case GPK4000_su256:
case GPK4000_sdo: case GPK4000_sdo:
offset = 0x6B; /* courtesy gemplus hotline */ offset = 0x6B; /* courtesy gemplus hotline */
@ -1730,9 +1717,8 @@ static int gpk_get_serialnr(sc_card_t *card, sc_serial_number_t *serial)
int r; int r;
u8 rbuf[10]; u8 rbuf[10];
struct sc_apdu apdu; struct sc_apdu apdu;
struct gpk_private_data *priv = DRVDATA(card);
if (priv->variant != GPK16000) if (card->type != GPK16000)
return SC_ERROR_NOT_SUPPORTED; return SC_ERROR_NOT_SUPPORTED;
if (!serial) if (!serial)
@ -1775,7 +1761,7 @@ gpk_card_ctl(struct sc_card *card, unsigned long cmd, void *ptr)
return gpk_get_default_key(card, return gpk_get_default_key(card,
(struct sc_cardctl_default_key *) ptr); (struct sc_cardctl_default_key *) ptr);
case SC_CARDCTL_GPK_VARIANT: case SC_CARDCTL_GPK_VARIANT:
*(int *) ptr = DRVDATA(card)->variant; *(int *) ptr = card->type;
return 0; return 0;
case SC_CARDCTL_GPK_LOCK: case SC_CARDCTL_GPK_LOCK:
return gpk_lock(card, (struct sc_cardctl_gpk_lock *) ptr); return gpk_lock(card, (struct sc_cardctl_gpk_lock *) ptr);

View File

@ -23,7 +23,7 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
static struct sc_atr_table_hex jcop_atrs[] = { static struct sc_atr_table jcop_atrs[] = {
{ "3B:E6:00:FF:81:31:FE:45:4A:43:4F:50:33:31:06" }, { "3B:E6:00:FF:81:31:FE:45:4A:43:4F:50:33:31:06" },
#if 0 #if 0
/* Requires secure messaging */ /* Requires secure messaging */
@ -77,7 +77,7 @@ static int jcop_match_card(struct sc_card *card)
{ {
int i; int i;
i = _sc_match_atr_hex(card, jcop_atrs, NULL); i = _sc_match_atr(card, jcop_atrs, NULL);
if (i < 0) if (i < 0)
return 0; return 0;
return 1; return 1;

View File

@ -30,12 +30,11 @@
#include <ctype.h> #include <ctype.h>
#include "esteid.h" #include "esteid.h"
#define TYPE_UNKNOWN 0 #define TYPE_GENERIC 0
#define TYPE_ANY 1 #define TYPE_ESTEID 1
#define TYPE_ESTEID 2
static struct sc_atr_table_hex mcrd_atrs[] = { static struct sc_atr_table 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", "German BMI", TYPE_ANY }, { "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_GENERIC },
{ "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: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 }, { "3B:6E:00:FF:45:73:74:45:49:44:20:76:65:72:20:31:2E:30", "EstEID (warm)", TYPE_ESTEID },
{ NULL } { NULL }
@ -247,21 +246,11 @@ 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)
{ {
int i; int i;
i = _sc_match_atr_hex(card, mcrd_atrs, NULL); i = _sc_match_atr(card, mcrd_atrs, &card->type);
if (i < 0) if (i < 0)
return 0; return 0;
return 1; return 1;
@ -289,7 +278,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_type(card) != TYPE_ESTEID) if (card->type != TYPE_ESTEID)
load_special_files (card); load_special_files (card);
return 0; return 0;
} }
@ -1084,8 +1073,8 @@ static int mcrd_set_security_env(struct sc_card *card,
assert(card != NULL && env != NULL); assert(card != NULL && env != NULL);
SC_FUNC_CALLED(card->ctx, 2); SC_FUNC_CALLED(card->ctx, 2);
/* special environemnt handling for esteid, stolen from openpgp */ /* special environment handling for esteid, stolen from openpgp */
if (sc_card_type(card) == TYPE_ESTEID) { if (card->type == 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,20 +24,16 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
static struct sc_atr_table_hex miocos_atrs[] = { #define TYPE_PKI 1
static struct sc_atr_table miocos_atrs[] = {
/* Test card with 32 kB memory */ /* Test card with 32 kB memory */
{ "3B:9D:94:40:23:00:68:10:11:4D:69:6F:43:4F:53:00:90:00" }, { "3B:9D:94:40:23:00:68:10:11:4D:69:6F:43:4F:53:00:90:00", NULL, TYPE_PKI },
/* Test card with 64 kB memory */ /* Test card with 64 kB memory */
{ "3B:9D:94:40:23:00:68:20:01:4D:69:6F:43:4F:53:00:90:00" }, { "3B:9D:94:40:23:00:68:20:01:4D:69:6F:43:4F:53:00:90:00", NULL, TYPE_PKI },
{ NULL } { NULL }
}; };
struct miocos_priv_data {
int type;
};
#define DRVDATA(card) ((struct miocos_priv_data *) ((card)->drv_data))
static struct sc_card_operations miocos_ops; static struct sc_card_operations miocos_ops;
static struct sc_card_driver miocos_drv = { static struct sc_card_driver miocos_drv = {
"MioCOS 1.1 cards", "MioCOS 1.1 cards",
@ -54,7 +50,7 @@ static int miocos_match_card(struct sc_card *card)
{ {
int i; int i;
i = _sc_match_atr_hex(card, miocos_atrs, NULL); i = _sc_match_atr(card, miocos_atrs, &card->type);
if (i < 0) if (i < 0)
return 0; return 0;
return 1; return 1;
@ -62,15 +58,9 @@ 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)
{ {
struct miocos_priv_data *priv = NULL;
priv = (struct miocos_priv_data *) malloc(sizeof(struct miocos_priv_data));
if (priv == NULL)
return SC_ERROR_OUT_OF_MEMORY;
card->name = "MioCOS"; card->name = "MioCOS";
card->drv_data = priv;
card->cla = 0x00; card->cla = 0x00;
if (1) { if (card->type == TYPE_PKI) {
unsigned long flags; unsigned long flags;
flags = SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_PAD_PKCS1; flags = SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_PAD_PKCS1;

View File

@ -41,7 +41,7 @@
#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 struct sc_atr_table_hex oberthur_atrs[] = { static struct sc_atr_table oberthur_atrs[] = {
#if 0 #if 0
{ "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 }, { "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 },
{ "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 }, { "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 },
@ -171,7 +171,7 @@ auth_match_card(struct sc_card *card)
{ {
int i; int i;
i = _sc_match_atr_hex(card, oberthur_atrs, NULL); i = _sc_match_atr(card, oberthur_atrs, NULL);
if (i < 0) if (i < 0)
return 0; return 0;
return 1; return 1;

View File

@ -25,7 +25,7 @@
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
static struct sc_atr_table_hex pgp_atrs[] = { static struct sc_atr_table 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 }
}; };
@ -110,7 +110,7 @@ pgp_match_card(sc_card_t *card)
{ {
int i; int i;
i = _sc_match_atr_hex(card, pgp_atrs, NULL); i = _sc_match_atr(card, pgp_atrs, NULL);
if (i < 0) if (i < 0)
return 0; return 0;
return 1; return 1;

View File

@ -22,25 +22,19 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#define SETEC_PKI 1 #define TYPE_GENERIC 0
#define SETEC_OTHER 2 #define TYPE_PKI 1
static struct sc_atr_table_hex setcos_atrs[] = { static struct sc_atr_table setcos_atrs[] = {
/* the current FINEID card has this ATR: */
{ "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 */
{ "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 */
{ "3B:1F:11:00:67:80:42:46:49:53:45:10:52:66:FF:81:90:00", NULL, SETEC_OTHER }, { "3B:1F:11:00:67:80:42:46:49:53:45:10:52:66:FF:81:90:00", NULL, TYPE_GENERIC },
/* RSA SecurID 3100 */
{ "3B:9F:94:40:1E:00:67:16:43:46:49:53:45:10:52:66:FF:81:90:00", NULL, TYPE_PKI },
/* FinEID card */
{ "3B:9F:94:40:1E:00:67:11:43:46:49:53:45:10:52:66:FF:81:90:00", NULL, TYPE_PKI },
{ NULL } { NULL }
}; };
struct setcos_priv_data {
int type;
};
#define DRVDATA(card) ((struct setcos_priv_data *) ((card)->drv_data))
static struct sc_card_operations setcos_ops; static struct sc_card_operations setcos_ops;
static struct sc_card_driver setcos_drv = { static struct sc_card_driver setcos_drv = {
"Setec smartcards", "Setec smartcards",
@ -50,41 +44,35 @@ static struct sc_card_driver setcos_drv = {
static int setcos_finish(struct sc_card *card) static int setcos_finish(struct sc_card *card)
{ {
free(DRVDATA(card));
return 0; return 0;
} }
static int setcos_match_card(struct sc_card *card) static int setcos_match_card(struct sc_card *card)
{ {
int i; int i;
const u8 *hist_bytes = card->slot->atr_info.hist_bytes;
if (card->slot->atr_info.hist_bytes_len < 8) i = _sc_match_atr(card, setcos_atrs, &card->type);
return 0; if (i < 0) {
if (memcmp(hist_bytes + 4, "FISE", 4) != 0) const u8 *hist_bytes = card->slot->atr_info.hist_bytes;
return 0;
i = _sc_match_atr_hex(card, setcos_atrs, NULL); if (card->slot->atr_info.hist_bytes_len < 8)
if (i < 0) return 0;
if (memcmp(hist_bytes + 4, "FISE", 4) == 0)
return 1;
return 0; return 0;
}
return 1; return 1;
} }
static int setcos_init(struct sc_card *card) static int setcos_init(struct sc_card *card)
{ {
int i, id;
struct setcos_priv_data *priv = NULL;
i = _sc_match_atr_hex(card, setcos_atrs, &id);
if (i < 0)
return 0;
priv = (struct setcos_priv_data *) malloc(sizeof(struct setcos_priv_data));
if (priv == NULL)
return SC_ERROR_OUT_OF_MEMORY;
card->name = "SetCOS"; card->name = "SetCOS";
card->drv_data = priv;
card->cla = 0x80; card->cla = 0x80;
priv->type = id;
if (id == SETEC_PKI) { if (card->type < 0)
card->type = TYPE_GENERIC;
if (card->type == TYPE_PKI) {
unsigned long flags; unsigned long flags;
flags = SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_PAD_PKCS1; flags = SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_PAD_PKCS1;
@ -244,8 +232,6 @@ static int setcos_set_security_env(struct sc_card *card,
const struct sc_security_env *env, const struct sc_security_env *env,
int se_num) int se_num)
{ {
struct setcos_priv_data *priv = DRVDATA(card);
if (env->flags & SC_SEC_ENV_ALG_PRESENT) { if (env->flags & SC_SEC_ENV_ALG_PRESENT) {
struct sc_security_env tmp; struct sc_security_env tmp;
@ -256,7 +242,7 @@ static int setcos_set_security_env(struct sc_card *card,
sc_error(card->ctx, "Only RSA algorithm supported.\n"); sc_error(card->ctx, "Only RSA algorithm supported.\n");
return SC_ERROR_NOT_SUPPORTED; return SC_ERROR_NOT_SUPPORTED;
} }
if (priv->type != SETEC_PKI) { if (card->type != TYPE_PKI) {
sc_error(card->ctx, "Card does not support RSA.\n"); sc_error(card->ctx, "Card does not support RSA.\n");
return SC_ERROR_NOT_SUPPORTED; return SC_ERROR_NOT_SUPPORTED;
} }

View File

@ -24,7 +24,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
static struct sc_atr_table_hex starcos_atrs[] = { static struct sc_atr_table 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 }
@ -70,7 +70,7 @@ static int starcos_match_card(struct sc_card *card)
{ {
int i; int i;
i = _sc_match_atr_hex(card, starcos_atrs, NULL); i = _sc_match_atr(card, starcos_atrs, NULL);
if (i < 0) if (i < 0)
return 0; return 0;
return 1; return 1;

View File

@ -27,7 +27,7 @@
#include <time.h> #include <time.h>
#include <stdlib.h> #include <stdlib.h>
static struct sc_atr_table_hex tcos_atrs[] = { static struct sc_atr_table tcos_atrs[] = {
/* SLE44 */ /* SLE44 */
{ "3B:BA:13:00:81:31:86:5D:00:64:05:0A:02:01:31:80:90:00:8B" }, { "3B:BA:13:00:81:31:86:5D:00:64:05:0A:02:01:31:80:90:00:8B" },
/* SLE66S */ /* SLE66S */
@ -60,7 +60,7 @@ static int tcos_match_card(struct sc_card *card)
{ {
int i; int i;
i = _sc_match_atr_hex(card, tcos_atrs, NULL); i = _sc_match_atr(card, tcos_atrs, NULL);
if (i < 0) if (i < 0)
return 0; return 0;
return 1; return 1;

View File

@ -102,7 +102,7 @@ sc_masquerade_apdu(sc_card_t *card, sc_apdu_t *apdu)
sc_context_t *ctx = card->reader->ctx; sc_context_t *ctx = card->reader->ctx;
int masq = card->reader->driver->apdu_masquerade; int masq = card->reader->driver->apdu_masquerade;
int is_t0; int is_t0;
is_t0 = (card->slot->active_protocol == SC_PROTO_T0); is_t0 = (card->slot->active_protocol == SC_PROTO_T0);
if (apdu->cse == SC_APDU_CASE_4_SHORT if (apdu->cse == SC_APDU_CASE_4_SHORT
@ -236,7 +236,7 @@ int sc_transmit_apdu(struct sc_card *card, struct sc_apdu *apdu)
{ {
int r; int r;
size_t orig_resplen; size_t orig_resplen;
assert(card != NULL && apdu != NULL); assert(card != NULL && apdu != NULL);
SC_FUNC_CALLED(card->ctx, 4); SC_FUNC_CALLED(card->ctx, 4);
orig_resplen = apdu->resplen; orig_resplen = apdu->resplen;
@ -315,7 +315,7 @@ void sc_format_apdu(struct sc_card *card, struct sc_apdu *apdu,
static struct sc_card * sc_card_new(void) static struct sc_card * sc_card_new(void)
{ {
struct sc_card *card; struct sc_card *card;
card = (struct sc_card *) calloc(1, sizeof(struct sc_card)); card = (struct sc_card *) calloc(1, sizeof(struct sc_card));
if (card == NULL) if (card == NULL)
return NULL; return NULL;
@ -324,6 +324,7 @@ static struct sc_card * sc_card_new(void)
free(card); free(card);
return NULL; return NULL;
} }
card->type = -1;
card->app_count = -1; card->app_count = -1;
card->magic = SC_CARD_MAGIC; card->magic = SC_CARD_MAGIC;
card->mutex = sc_mutex_new(); card->mutex = sc_mutex_new();
@ -408,7 +409,7 @@ int sc_connect_card(struct sc_reader *reader, int slot_id,
} else for (i = 0; ctx->card_drivers[i] != NULL; i++) { } else for (i = 0; ctx->card_drivers[i] != NULL; i++) {
struct sc_card_driver *drv = ctx->card_drivers[i]; struct sc_card_driver *drv = ctx->card_drivers[i];
const struct sc_card_operations *ops = drv->ops; const struct sc_card_operations *ops = drv->ops;
if (ctx->debug >= 3) if (ctx->debug >= 3)
sc_debug(ctx, "trying driver: %s\n", drv->name); sc_debug(ctx, "trying driver: %s\n", drv->name);
if (ops == NULL || ops->match_card == NULL) if (ops == NULL || ops->match_card == NULL)
@ -458,7 +459,7 @@ int sc_disconnect_card(struct sc_card *card, int action)
int r = card->ops->finish(card); int r = card->ops->finish(card);
if (r) if (r)
sc_error(card->ctx, "card driver finish() failed: %s\n", sc_error(card->ctx, "card driver finish() failed: %s\n",
sc_strerror(r)); sc_strerror(r));
} }
if (card->reader->ops->disconnect) { if (card->reader->ops->disconnect) {
int r = card->reader->ops->disconnect(card->reader, card->slot, action); int r = card->reader->ops->disconnect(card->reader, card->slot, action);
@ -473,7 +474,7 @@ int sc_disconnect_card(struct sc_card *card, int action)
int sc_lock(struct sc_card *card) int sc_lock(struct sc_card *card)
{ {
int r = 0; int r = 0;
assert(card != NULL); assert(card != NULL);
sc_mutex_lock(card->mutex); sc_mutex_lock(card->mutex);
if (card->lock_count == 0) { if (card->lock_count == 0) {
@ -851,7 +852,7 @@ sc_card_ctl(struct sc_card *card, unsigned long cmd, void *args)
int _sc_card_add_algorithm(struct sc_card *card, const struct sc_algorithm_info *info) int _sc_card_add_algorithm(struct sc_card *card, const struct sc_algorithm_info *info)
{ {
struct sc_algorithm_info *p; struct sc_algorithm_info *p;
assert(sc_card_valid(card) && info != NULL); assert(sc_card_valid(card) && info != NULL);
p = (struct sc_algorithm_info *) realloc(card->algorithms, (card->algorithm_count + 1) * sizeof(*info)); p = (struct sc_algorithm_info *) realloc(card->algorithms, (card->algorithm_count + 1) * sizeof(*info));
if (!p) { if (!p) {
@ -878,7 +879,7 @@ int _sc_card_add_rsa_alg(struct sc_card *card, unsigned int key_length,
info.key_length = key_length; info.key_length = key_length;
info.flags = flags; info.flags = flags;
info.u._rsa.exponent = exponent; info.u._rsa.exponent = exponent;
return _sc_card_add_algorithm(card, &info); return _sc_card_add_algorithm(card, &info);
} }
@ -889,7 +890,7 @@ struct sc_algorithm_info * _sc_card_find_rsa_alg(struct sc_card *card,
for (i = 0; i < card->algorithm_count; i++) { for (i = 0; i < card->algorithm_count; i++) {
struct sc_algorithm_info *info = &card->algorithms[i]; struct sc_algorithm_info *info = &card->algorithms[i];
if (info->algorithm != SC_ALGORITHM_RSA) if (info->algorithm != SC_ALGORITHM_RSA)
continue; continue;
if (info->key_length != key_length) if (info->key_length != key_length)
@ -901,43 +902,32 @@ struct sc_algorithm_info * _sc_card_find_rsa_alg(struct sc_card *card,
int _sc_match_atr(struct sc_card *card, struct sc_atr_table *table, int *id_out) int _sc_match_atr(struct sc_card *card, struct sc_atr_table *table, int *id_out)
{ {
const u8 *atr = card->atr; struct sc_context *ctx = card->ctx;
size_t atr_len = card->atr_len; char atr[3 * SC_MAX_ATR_SIZE];
int i = 0; size_t atr_len;
unsigned int i = 0;
if (table == NULL)
if (table == NULL || card == NULL)
return -1; return -1;
for (i = 0; table[i].atr != NULL; i++) { i = sc_bin_to_hex(card->atr, card->atr_len, atr, sizeof(atr), ':');
if (table[i].atr_len != atr_len) if (i != 0)
continue;
if (memcmp(table[i].atr, atr, atr_len) != 0)
continue;
if (id_out != NULL)
*id_out = table[i].id;
return i;
}
return -1;
}
int _sc_match_atr_hex(struct sc_card *card, struct sc_atr_table_hex *table, int *id_out)
{
const u8 *atr = card->atr;
size_t atr_len = card->atr_len;
int i = 0;
if (table == NULL)
return -1; return -1;
atr_len = sizeof(atr);
if (ctx->debug >= 4)
sc_debug(ctx, "current ATR: %s\n", atr);
for (i = 0; table[i].atr != NULL; i++) { for (i = 0; table[i].atr != NULL; i++) {
u8 tatr[SC_MAX_ATR_SIZE]; const char *tatr = table[i].atr;
size_t tlen = sizeof(tatr); size_t tlen = sizeof(tatr);
if (sc_hex_to_bin(table[i].atr, tatr, &tlen)) if (ctx->debug >= 4)
continue; sc_debug(ctx, "trying ATR: %s\n", tatr);
if (tlen != atr_len) if (tlen != atr_len)
continue; continue;
if (memcmp(tatr, atr, tlen) != 0) if (strncasecmp(tatr, atr, tlen) != 0)
continue; continue;
if (id_out != NULL) if (id_out != NULL)
*id_out = table[i].id; *id_out = table[i].id;
@ -946,24 +936,31 @@ int _sc_match_atr_hex(struct sc_card *card, struct sc_atr_table_hex *table, int
return -1; return -1;
} }
int _sc_add_atr(struct sc_card_driver *driver, /* XXX: wtf? I don't see any memory freeing code. -aet */
const u8 *atr, size_t atrlen, int id) int _sc_add_atr(struct sc_context *ctx, struct sc_card_driver *driver, struct sc_atr_table *src)
{ {
struct sc_atr_table *map, *entry; struct sc_atr_table *map, *dst;
u8 *dst_atr;
map = (struct sc_atr_table *) realloc(driver->atr_map, map = (struct sc_atr_table *) realloc(driver->atr_map,
(driver->natrs + 2) * sizeof(struct sc_atr_table)); (driver->natrs + 2) * sizeof(struct sc_atr_table));
if (!map) if (!map)
return SC_ERROR_OUT_OF_MEMORY; return SC_ERROR_OUT_OF_MEMORY;
driver->atr_map = map; driver->atr_map = map;
if (!(dst_atr = (u8 *) malloc(atrlen))) dst = &driver->atr_map[driver->natrs++];
memset(dst, 0, sizeof(*dst));
dst->atr = strdup(src->atr);
if (!dst->atr)
return SC_ERROR_OUT_OF_MEMORY; return SC_ERROR_OUT_OF_MEMORY;
entry = &driver->atr_map[driver->natrs++]; if (src->name) {
memset(entry+1, 0, sizeof(*entry)); dst->name = strdup(src->name);
entry->atr = dst_atr; if (!dst->name)
entry->atr_len = atrlen; return SC_ERROR_OUT_OF_MEMORY;
entry->id = id; } else {
memcpy(dst_atr, atr, atrlen); dst->name = NULL;
}
dst->id = src->id;
dst->flags = src->flags;
if (ctx->debug >= 4)
sc_debug(ctx, "added ATR: %s\n", src->atr);
return 0; return 0;
} }

View File

@ -44,7 +44,7 @@ int _sc_add_reader(struct sc_context *ctx, struct sc_reader *reader)
return SC_ERROR_TOO_MANY_OBJECTS; return SC_ERROR_TOO_MANY_OBJECTS;
ctx->reader[ctx->reader_count] = reader; ctx->reader[ctx->reader_count] = reader;
ctx->reader_count++; ctx->reader_count++;
return 0; return 0;
} }
@ -107,7 +107,7 @@ static void del_drvs(struct _sc_ctx_options *opts, int type)
{ {
struct _sc_driver_entry *lst; struct _sc_driver_entry *lst;
int *cp, i; int *cp, i;
if (type == 0) { if (type == 0) {
lst = opts->rdrv; lst = opts->rdrv;
cp = &opts->rcount; cp = &opts->rcount;
@ -127,7 +127,7 @@ static void add_drv(struct _sc_ctx_options *opts, int type, const char *name)
{ {
struct _sc_driver_entry *lst; struct _sc_driver_entry *lst;
int *cp, i; int *cp, i;
if (type == 0) { if (type == 0) {
lst = opts->rdrv; lst = opts->rdrv;
cp = &opts->rcount; cp = &opts->rcount;
@ -149,7 +149,7 @@ static void add_internal_drvs(struct _sc_ctx_options *opts, int type)
{ {
const struct _sc_driver_entry *lst; const struct _sc_driver_entry *lst;
int i; int i;
if (type == 0) if (type == 0)
lst = internal_reader_drivers; lst = internal_reader_drivers;
else else
@ -183,7 +183,7 @@ static int load_parameters(struct sc_context *ctx, scconf_block *block,
const scconf_list *list; const scconf_list *list;
const char *val; const char *val;
const char *s_internal = "internal"; const char *s_internal = "internal";
ctx->debug = scconf_get_int(block, "debug", ctx->debug); ctx->debug = scconf_get_int(block, "debug", ctx->debug);
val = scconf_get_str(block, "debug_file", NULL); val = scconf_get_str(block, "debug_file", NULL);
if (val) { if (val) {
@ -261,7 +261,7 @@ static void load_reader_driver_options(sc_context_t *ctx,
driver->max_recv_size = SC_APDU_CHOP_SIZE; driver->max_recv_size = SC_APDU_CHOP_SIZE;
if (conf_block != NULL) { if (conf_block != NULL) {
const scconf_list *list; const scconf_list *list;
list = scconf_find_list(conf_block, "apdu_masquerade"); list = scconf_find_list(conf_block, "apdu_masquerade");
if (list) if (list)
driver->apdu_masquerade = 0; driver->apdu_masquerade = 0;
@ -411,20 +411,17 @@ static int load_reader_drivers(struct sc_context *ctx,
ctx->reader_drivers[drv_count] = driver; ctx->reader_drivers[drv_count] = driver;
drv_count++; drv_count++;
} }
return 0; return 0;
} }
static int load_card_driver_options(struct sc_context *ctx, static int load_card_driver_options(struct sc_context *ctx,
struct sc_card_driver *driver) struct sc_card_driver *driver)
{ {
scconf_block **blocks, *blk; scconf_block **blocks, *blk;
const scconf_list *list; const scconf_list *list;
int i, r; int i;
for (i = 0; ctx->conf_blocks[i]; i++) { for (i = 0; ctx->conf_blocks[i]; i++) {
u8 atr_buf[SC_MAX_ATR_SIZE];
size_t atr_len;
blocks = scconf_find_blocks(ctx->conf, blocks = scconf_find_blocks(ctx->conf,
ctx->conf_blocks[i], ctx->conf_blocks[i],
"card_driver", driver->short_name); "card_driver", driver->short_name);
@ -436,16 +433,11 @@ static int load_card_driver_options(struct sc_context *ctx,
list = scconf_find_list(blk, "atr"); list = scconf_find_list(blk, "atr");
while (list != NULL) { while (list != NULL) {
atr_len = sizeof(atr_buf); struct sc_atr_table t;
r = sc_hex_to_bin(list->data,
atr_buf, &atr_len); memset(&t, 0, sizeof(struct sc_atr_table));
if (r < 0) { t.atr = list->data;
sc_error(ctx, _sc_add_atr(ctx, driver, &t);
"Unable to parse ATR '%s'.\n",
list->data);
continue;
}
_sc_add_atr(driver, atr_buf, atr_len, 0);
list = list->next; list = list->next;
} }
} }
@ -488,7 +480,7 @@ static int load_card_drivers(struct sc_context *ctx,
load_card_driver_options(ctx, ctx->card_drivers[drv_count]); load_card_driver_options(ctx, ctx->card_drivers[drv_count]);
drv_count++; drv_count++;
} }
return 0; return 0;
} }
static void process_config_file(struct sc_context *ctx, struct _sc_ctx_options *opts) static void process_config_file(struct sc_context *ctx, struct _sc_ctx_options *opts)
@ -571,7 +563,7 @@ int sc_establish_context(struct sc_context **ctx_out, const char *app_name)
if (opts.forced_card_driver) { if (opts.forced_card_driver) {
sc_set_card_driver(ctx, opts.forced_card_driver); sc_set_card_driver(ctx, opts.forced_card_driver);
free(opts.forced_card_driver); free(opts.forced_card_driver);
} }
del_drvs(&opts, 0); del_drvs(&opts, 0);
del_drvs(&opts, 1); del_drvs(&opts, 1);
if (ctx->reader_count == 0) { if (ctx->reader_count == 0) {
@ -590,7 +582,7 @@ int sc_release_context(struct sc_context *ctx)
SC_FUNC_CALLED(ctx, 1); SC_FUNC_CALLED(ctx, 1);
for (i = 0; i < ctx->reader_count; i++) { for (i = 0; i < ctx->reader_count; i++) {
struct sc_reader *rdr = ctx->reader[i]; struct sc_reader *rdr = ctx->reader[i];
if (rdr->ops->release != NULL) if (rdr->ops->release != NULL)
rdr->ops->release(rdr); rdr->ops->release(rdr);
free(rdr->name); free(rdr->name);
@ -598,7 +590,7 @@ int sc_release_context(struct sc_context *ctx)
} }
for (i = 0; ctx->reader_drivers[i] != NULL; i++) { for (i = 0; ctx->reader_drivers[i] != NULL; i++) {
const struct sc_reader_driver *drv = ctx->reader_drivers[i]; const struct sc_reader_driver *drv = ctx->reader_drivers[i];
if (drv->ops->finish != NULL) if (drv->ops->finish != NULL)
drv->ops->finish(ctx, ctx->reader_drv_data[i]); drv->ops->finish(ctx, ctx->reader_drv_data[i]);
if (drv->dll) if (drv->dll)
@ -627,7 +619,7 @@ int sc_release_context(struct sc_context *ctx)
int sc_set_card_driver(struct sc_context *ctx, const char *short_name) int sc_set_card_driver(struct sc_context *ctx, const char *short_name)
{ {
int i = 0, match = 0; int i = 0, match = 0;
sc_mutex_lock(ctx->mutex); sc_mutex_lock(ctx->mutex);
if (short_name == NULL) { if (short_name == NULL) {
ctx->forced_driver = NULL; ctx->forced_driver = NULL;

View File

@ -39,16 +39,10 @@ extern "C" {
#define SC_CTX_MAGIC 0x0A550335 #define SC_CTX_MAGIC 0x0A550335
struct sc_atr_table { struct sc_atr_table {
const u8 *atr;
size_t atr_len;
int id;
};
struct sc_atr_table_hex {
const char *atr; const char *atr;
const char *name; const char *name;
int id; int id;
unsigned flags; unsigned long flags;
}; };
/* Internal use only */ /* Internal use only */
@ -60,12 +54,11 @@ int _sc_parse_atr(struct sc_context *ctx, struct sc_slot_info *slot);
struct sc_slot_info * _sc_get_slot_info(struct sc_reader *reader, int slot_id); struct sc_slot_info * _sc_get_slot_info(struct sc_reader *reader, int slot_id);
/* Add an ATR to the card driver's struct sc_atr_table */ /* Add an ATR to the card driver's struct sc_atr_table */
int _sc_add_atr(struct sc_card_driver *, const u8 *, size_t, int); int _sc_add_atr(struct sc_context *ctx, struct sc_card_driver *driver, struct sc_atr_table *src);
/* Returns an index number if a match was found, -1 otherwise. table has to /* Returns an index number if a match was found, -1 otherwise. table has to
* be null terminated. */ * be null terminated. */
int _sc_match_atr(struct sc_card *card, struct sc_atr_table *table, int *id_out); int _sc_match_atr(struct sc_card *card, struct sc_atr_table *table, int *id_out);
int _sc_match_atr_hex(struct sc_card *card, struct sc_atr_table_hex *table, int *id_out);
int _sc_card_add_algorithm(struct sc_card *card, const struct sc_algorithm_info *info); int _sc_card_add_algorithm(struct sc_card *card, const struct sc_algorithm_info *info);
int _sc_card_add_rsa_alg(struct sc_card *card, unsigned int key_length, int _sc_card_add_rsa_alg(struct sc_card *card, unsigned int key_length,

View File

@ -444,6 +444,7 @@ struct sc_card {
struct sc_reader *reader; struct sc_reader *reader;
struct sc_slot_info *slot; struct sc_slot_info *slot;
int type; /* Card type, for card driver internal use */
unsigned long caps, flags; unsigned long caps, flags;
unsigned int wait_resend_apdu; /* Delay (msec) before responding to an SW12 = 6CXX */ unsigned int wait_resend_apdu; /* Delay (msec) before responding to an SW12 = 6CXX */
int cla; int cla;

View File

@ -198,22 +198,17 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card)
return 0; return 0;
} }
static struct sc_atr_table_hex esteid_atrs[] = {
{ "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)
{ {
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 */ /* check if we have the correct card OS */
i = _sc_match_atr_hex(card, esteid_atrs, NULL); if (strcmp(card->name, "MICARDO 2.1"))
if (i < 0)
return SC_ERROR_WRONG_CARD; return SC_ERROR_WRONG_CARD;
return SC_SUCCESS; /* Assume type == 1 is just for EstEID cards */
if (card->type == 1)
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,

View File

@ -114,13 +114,13 @@ int sc_detect_card_presence(struct sc_reader *reader, int slot_id)
{ {
int r; int r;
struct sc_slot_info *slot = _sc_get_slot_info(reader, slot_id); struct sc_slot_info *slot = _sc_get_slot_info(reader, slot_id);
if (slot == NULL) if (slot == NULL)
SC_FUNC_RETURN(reader->ctx, 0, SC_ERROR_SLOT_NOT_FOUND); SC_FUNC_RETURN(reader->ctx, 0, SC_ERROR_SLOT_NOT_FOUND);
SC_FUNC_CALLED(reader->ctx, 1); SC_FUNC_CALLED(reader->ctx, 1);
if (reader->ops->detect_card_presence == NULL) if (reader->ops->detect_card_presence == NULL)
SC_FUNC_RETURN(reader->ctx, 0, SC_ERROR_NOT_SUPPORTED); SC_FUNC_RETURN(reader->ctx, 0, SC_ERROR_NOT_SUPPORTED);
r = reader->ops->detect_card_presence(reader, slot); r = reader->ops->detect_card_presence(reader, slot);
SC_FUNC_RETURN(reader->ctx, 1, r); SC_FUNC_RETURN(reader->ctx, 1, r);
} }
@ -250,7 +250,7 @@ int sc_file_add_acl_entry(struct sc_file *file, unsigned int operation,
|| file->acl[operation] == (struct sc_acl_entry *) 3) || file->acl[operation] == (struct sc_acl_entry *) 3)
file->acl[operation] = NULL; file->acl[operation] = NULL;
} }
_new = (struct sc_acl_entry *) malloc(sizeof(struct sc_acl_entry)); _new = (struct sc_acl_entry *) malloc(sizeof(struct sc_acl_entry));
if (_new == NULL) if (_new == NULL)
return SC_ERROR_OUT_OF_MEMORY; return SC_ERROR_OUT_OF_MEMORY;
@ -301,12 +301,12 @@ const struct sc_acl_entry * sc_file_get_acl_entry(const struct sc_file *file,
void sc_file_clear_acl_entries(struct sc_file *file, unsigned int operation) void sc_file_clear_acl_entries(struct sc_file *file, unsigned int operation)
{ {
struct sc_acl_entry *e; struct sc_acl_entry *e;
assert(file != NULL); assert(file != NULL);
assert(operation < SC_MAX_AC_OPS); assert(operation < SC_MAX_AC_OPS);
e = file->acl[operation]; e = file->acl[operation];
if (e == (struct sc_acl_entry *) 1 || if (e == (struct sc_acl_entry *) 1 ||
e == (struct sc_acl_entry *) 2 || e == (struct sc_acl_entry *) 2 ||
e == (struct sc_acl_entry *) 3) { e == (struct sc_acl_entry *) 3) {
file->acl[operation] = NULL; file->acl[operation] = NULL;
@ -324,7 +324,7 @@ void sc_file_clear_acl_entries(struct sc_file *file, unsigned int operation)
struct sc_file * sc_file_new() struct sc_file * sc_file_new()
{ {
struct sc_file *file = (struct sc_file *) malloc(sizeof(struct sc_file)); struct sc_file *file = (struct sc_file *) malloc(sizeof(struct sc_file));
if (file == NULL) if (file == NULL)
return NULL; return NULL;
memset(file, 0, sizeof(struct sc_file)); memset(file, 0, sizeof(struct sc_file));
@ -353,14 +353,14 @@ void sc_file_dup(struct sc_file **dest, const struct sc_file *src)
struct sc_file *newf; struct sc_file *newf;
const struct sc_acl_entry *e; const struct sc_acl_entry *e;
unsigned int op; unsigned int op;
assert(sc_file_valid(src)); assert(sc_file_valid(src));
*dest = NULL; *dest = NULL;
newf = sc_file_new(); newf = sc_file_new();
if (newf == NULL) if (newf == NULL)
return; return;
*dest = newf; *dest = newf;
*newf = *src; *newf = *src;
for (op = 0; op < SC_MAX_AC_OPS; op++) { for (op = 0; op < SC_MAX_AC_OPS; op++) {
newf->acl[op] = NULL; newf->acl[op] = NULL;
@ -396,7 +396,7 @@ int sc_file_set_sec_attr(struct sc_file *file, const u8 *sec_attr,
file->sec_attr_len = sec_attr_len; file->sec_attr_len = sec_attr_len;
return 0; return 0;
} }
int sc_file_set_prop_attr(struct sc_file *file, const u8 *prop_attr, int sc_file_set_prop_attr(struct sc_file *file, const u8 *prop_attr,
size_t prop_attr_len) size_t prop_attr_len)
@ -424,7 +424,7 @@ int sc_file_set_prop_attr(struct sc_file *file, const u8 *prop_attr,
file->prop_attr_len = prop_attr_len; file->prop_attr_len = prop_attr_len;
return 0; return 0;
} }
int sc_file_set_type_attr(struct sc_file *file, const u8 *type_attr, int sc_file_set_type_attr(struct sc_file *file, const u8 *type_attr,
size_t type_attr_len) size_t type_attr_len)
@ -452,7 +452,7 @@ int sc_file_set_type_attr(struct sc_file *file, const u8 *type_attr,
file->type_attr_len = type_attr_len; file->type_attr_len = type_attr_len;
return 0; return 0;
} }
inline int sc_file_valid(const struct sc_file *file) { inline int sc_file_valid(const struct sc_file *file) {
#ifndef NDEBUG #ifndef NDEBUG
@ -534,6 +534,5 @@ int _sc_parse_atr(struct sc_context *ctx, struct sc_slot_info *slot)
n_hist = atr_len; n_hist = atr_len;
slot->atr_info.hist_bytes_len = n_hist; slot->atr_info.hist_bytes_len = n_hist;
slot->atr_info.hist_bytes = p; slot->atr_info.hist_bytes = p;
return 0; return 0;
} }