- 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_EID 1
#define TYPE_BELPIC_EID 1
/* 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
* 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 */
static size_t next_idx = -1;
static struct sc_atr_table_hex belpic_atrs[] = {
static struct sc_atr_table belpic_atrs[] = {
/* 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 */
{ "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 */
{ "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
/* 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 */
{ "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
{ NULL }
};
struct belpic_priv_data {
int type;
int lang;
int options;
#ifdef BELPIC_PIN_PAD
@ -970,7 +970,7 @@ static int belpic_match_card(struct sc_card *card)
{
int i;
i = _sc_match_atr_hex(card, belpic_atrs, NULL);
i = _sc_match_atr(card, belpic_atrs, &card->type);
if (i < 0)
return 0;
return 1;
@ -978,7 +978,6 @@ static int belpic_match_card(struct sc_card *card)
static int belpic_init(struct sc_card *card)
{
int i, id;
struct belpic_priv_data *priv = NULL;
scconf_block *conf_block;
#ifdef BELPIC_PIN_PAD
@ -994,16 +993,15 @@ static int belpic_init(struct sc_card *card)
#endif
sc_debug(card->ctx, "\n");
i = _sc_match_atr_hex(card, belpic_atrs, &id);
if (i < 0)
id = BELPIC_EID; /* Unknown ATR: assume it's the Belpic Card */
if (card->type < 0)
card->type = TYPE_BELPIC_EID; /* Unknown card: assume it's the Belpic Card */
priv = (struct belpic_priv_data *) calloc(1, sizeof(struct belpic_priv_data));
if (priv == NULL)
return SC_ERROR_OUT_OF_MEMORY;
card->drv_data = priv;
card->cla = 0x00;
priv->type = id;
if (id == BELPIC_EID) {
if (card->type == TYPE_BELPIC_EID) {
_sc_card_add_rsa_alg(card, 1024,
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;
#ifdef HAVE_GUI
i = scgui_init();
if (i != 0)
r = scgui_init();
if (r != 0)
sc_error(card->ctx, "scgui_init() returned error %d\n", i);
#endif

View File

@ -31,9 +31,6 @@
* Either coincidence, or a known problem. */
#define ETOKEN_MAX_PAYLOAD 120
/* Different eToken types */
#define CARDOS_TYPE_ANY 1
static const struct sc_card_operations *iso_ops = NULL;
struct sc_card_operations etoken_ops;
@ -43,17 +40,17 @@ static struct sc_card_driver etoken_drv = {
&etoken_ops
};
static struct sc_atr_table_hex etoken_atrs[] = {
static struct sc_atr_table etoken_atrs[] = {
/* 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 */
{ "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 */
{ "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 */
{ "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 */
{ "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 }
};
@ -66,7 +63,7 @@ static int etoken_match_card(struct sc_card *card)
{
int i;
i = _sc_match_atr_hex(card, etoken_atrs, NULL);
i = _sc_match_atr(card, etoken_atrs, NULL);
if (i < 0)
return 0;
return 1;

View File

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

View File

@ -72,8 +72,6 @@ enum {
* GPK4000 private data
*/
struct gpk_private_data {
int variant;
/* The GPK usually do file offsets in multiples of
* 4 bytes. This can be customized however. We
* 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
*/
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:05:01:01:37", "GPK 4K", GPK4000_sp },
{ "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
};
/*
* 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
*/
static int
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;
unsigned long exponent, flags, kg;
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));
if (card->drv_data == NULL)
return SC_ERROR_OUT_OF_MEMORY;
memset(priv, 0, sizeof(*priv));
priv->variant = variant;
/* read/write/update binary expect offset to be the
* number of 32 bit words.
@ -201,8 +188,8 @@ gpk_init(struct sc_card *card)
| SC_ALGORITHM_RSA_HASH_MD5_SHA1;
flags |= SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_PAD_ANSI
| SC_ALGORITHM_RSA_PAD_ISO9796;
exponent = (variant < 16000)? 0x10001 : 0;
kg = (variant >= 8000)? SC_ALGORITHM_ONBOARD_KEY_GEN : 0;
exponent = (card->type < 16000)? 0x10001 : 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, 768, flags, exponent);
_sc_card_add_rsa_alg(card, 1024, flags|kg, exponent);
@ -1397,7 +1384,7 @@ gpk_erase_card(struct sc_card *card)
int r;
SC_FUNC_CALLED(card->ctx, 1);
switch (priv->variant) {
switch (card->type) {
case GPK4000_su256:
case GPK4000_sdo:
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;
u8 rbuf[10];
struct sc_apdu apdu;
struct gpk_private_data *priv = DRVDATA(card);
if (priv->variant != GPK16000)
if (card->type != GPK16000)
return SC_ERROR_NOT_SUPPORTED;
if (!serial)
@ -1775,7 +1761,7 @@ gpk_card_ctl(struct sc_card *card, unsigned long cmd, void *ptr)
return gpk_get_default_key(card,
(struct sc_cardctl_default_key *) ptr);
case SC_CARDCTL_GPK_VARIANT:
*(int *) ptr = DRVDATA(card)->variant;
*(int *) ptr = card->type;
return 0;
case SC_CARDCTL_GPK_LOCK:
return gpk_lock(card, (struct sc_cardctl_gpk_lock *) ptr);

View File

@ -23,7 +23,7 @@
#include <string.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" },
#if 0
/* Requires secure messaging */
@ -77,7 +77,7 @@ static int jcop_match_card(struct sc_card *card)
{
int i;
i = _sc_match_atr_hex(card, jcop_atrs, NULL);
i = _sc_match_atr(card, jcop_atrs, NULL);
if (i < 0)
return 0;
return 1;

View File

@ -30,12 +30,11 @@
#include <ctype.h>
#include "esteid.h"
#define TYPE_UNKNOWN 0
#define TYPE_ANY 1
#define TYPE_ESTEID 2
#define TYPE_GENERIC 0
#define TYPE_ESTEID 1
static struct sc_atr_table_hex 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 },
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_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:6E:00:FF:45:73:74:45:49:44:20:76:65:72:20:31:2E:30", "EstEID (warm)", TYPE_ESTEID },
{ 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));
}
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)
{
int i;
i = _sc_match_atr_hex(card, mcrd_atrs, NULL);
i = _sc_match_atr(card, mcrd_atrs, &card->type);
if (i < 0)
return 0;
return 1;
@ -289,7 +278,7 @@ static int mcrd_init(struct sc_card *card)
priv->curpath[0] = MFID;
priv->curpathlen = 1;
if (sc_card_type(card) != TYPE_ESTEID)
if (card->type != TYPE_ESTEID)
load_special_files (card);
return 0;
}
@ -1084,8 +1073,8 @@ static int mcrd_set_security_env(struct sc_card *card,
assert(card != NULL && env != NULL);
SC_FUNC_CALLED(card->ctx, 2);
/* special environemnt handling for esteid, stolen from openpgp */
if (sc_card_type(card) == TYPE_ESTEID) {
/* special environment handling for esteid, stolen from openpgp */
if (card->type == TYPE_ESTEID) {
/* some sanity checks */
if (env->flags & SC_SEC_ENV_ALG_PRESENT) {
if (env->algorithm != SC_ALGORITHM_RSA)

View File

@ -24,20 +24,16 @@
#include <stdlib.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 */
{ "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 */
{ "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 }
};
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_driver miocos_drv = {
"MioCOS 1.1 cards",
@ -54,7 +50,7 @@ static int miocos_match_card(struct sc_card *card)
{
int i;
i = _sc_match_atr_hex(card, miocos_atrs, NULL);
i = _sc_match_atr(card, miocos_atrs, &card->type);
if (i < 0)
return 0;
return 1;
@ -62,15 +58,9 @@ static int miocos_match_card(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->drv_data = priv;
card->cla = 0x00;
if (1) {
if (card->type == TYPE_PKI) {
unsigned long flags;
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)
#endif
static struct sc_atr_table_hex oberthur_atrs[] = {
static struct sc_atr_table oberthur_atrs[] = {
#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: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;
i = _sc_match_atr_hex(card, oberthur_atrs, NULL);
i = _sc_match_atr(card, oberthur_atrs, NULL);
if (i < 0)
return 0;
return 1;

View File

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

View File

@ -22,25 +22,19 @@
#include <stdlib.h>
#include <string.h>
#define SETEC_PKI 1
#define SETEC_OTHER 2
#define TYPE_GENERIC 0
#define TYPE_PKI 1
static struct sc_atr_table_hex 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 },
static struct sc_atr_table setcos_atrs[] = {
/* 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 }
};
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_driver setcos_drv = {
"Setec smartcards",
@ -50,41 +44,35 @@ static struct sc_card_driver setcos_drv = {
static int setcos_finish(struct sc_card *card)
{
free(DRVDATA(card));
return 0;
}
static int setcos_match_card(struct sc_card *card)
{
int i;
const u8 *hist_bytes = card->slot->atr_info.hist_bytes;
if (card->slot->atr_info.hist_bytes_len < 8)
return 0;
if (memcmp(hist_bytes + 4, "FISE", 4) != 0)
return 0;
i = _sc_match_atr_hex(card, setcos_atrs, NULL);
if (i < 0)
i = _sc_match_atr(card, setcos_atrs, &card->type);
if (i < 0) {
const u8 *hist_bytes = card->slot->atr_info.hist_bytes;
if (card->slot->atr_info.hist_bytes_len < 8)
return 0;
if (memcmp(hist_bytes + 4, "FISE", 4) == 0)
return 1;
return 0;
}
return 1;
}
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->drv_data = priv;
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;
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,
int se_num)
{
struct setcos_priv_data *priv = DRVDATA(card);
if (env->flags & SC_SEC_ENV_ALG_PRESENT) {
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");
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");
return SC_ERROR_NOT_SUPPORTED;
}

View File

@ -24,7 +24,7 @@
#include <stdlib.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:81:31:fe:65:53:50:4b:32:33:90:00:d1" },
{ NULL }
@ -70,7 +70,7 @@ static int starcos_match_card(struct sc_card *card)
{
int i;
i = _sc_match_atr_hex(card, starcos_atrs, NULL);
i = _sc_match_atr(card, starcos_atrs, NULL);
if (i < 0)
return 0;
return 1;

View File

@ -27,7 +27,7 @@
#include <time.h>
#include <stdlib.h>
static struct sc_atr_table_hex tcos_atrs[] = {
static struct sc_atr_table tcos_atrs[] = {
/* SLE44 */
{ "3B:BA:13:00:81:31:86:5D:00:64:05:0A:02:01:31:80:90:00:8B" },
/* SLE66S */
@ -60,7 +60,7 @@ static int tcos_match_card(struct sc_card *card)
{
int i;
i = _sc_match_atr_hex(card, tcos_atrs, NULL);
i = _sc_match_atr(card, tcos_atrs, NULL);
if (i < 0)
return 0;
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;
int masq = card->reader->driver->apdu_masquerade;
int is_t0;
is_t0 = (card->slot->active_protocol == SC_PROTO_T0);
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;
size_t orig_resplen;
assert(card != NULL && apdu != NULL);
SC_FUNC_CALLED(card->ctx, 4);
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)
{
struct sc_card *card;
card = (struct sc_card *) calloc(1, sizeof(struct sc_card));
if (card == NULL)
return NULL;
@ -324,6 +324,7 @@ static struct sc_card * sc_card_new(void)
free(card);
return NULL;
}
card->type = -1;
card->app_count = -1;
card->magic = SC_CARD_MAGIC;
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++) {
struct sc_card_driver *drv = ctx->card_drivers[i];
const struct sc_card_operations *ops = drv->ops;
if (ctx->debug >= 3)
sc_debug(ctx, "trying driver: %s\n", drv->name);
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);
if (r)
sc_error(card->ctx, "card driver finish() failed: %s\n",
sc_strerror(r));
sc_strerror(r));
}
if (card->reader->ops->disconnect) {
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 r = 0;
assert(card != NULL);
sc_mutex_lock(card->mutex);
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)
{
struct sc_algorithm_info *p;
assert(sc_card_valid(card) && info != NULL);
p = (struct sc_algorithm_info *) realloc(card->algorithms, (card->algorithm_count + 1) * sizeof(*info));
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.flags = flags;
info.u._rsa.exponent = exponent;
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++) {
struct sc_algorithm_info *info = &card->algorithms[i];
if (info->algorithm != SC_ALGORITHM_RSA)
continue;
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)
{
const u8 *atr = card->atr;
size_t atr_len = card->atr_len;
int i = 0;
if (table == NULL)
struct sc_context *ctx = card->ctx;
char atr[3 * SC_MAX_ATR_SIZE];
size_t atr_len;
unsigned int i = 0;
if (table == NULL || card == NULL)
return -1;
for (i = 0; table[i].atr != NULL; i++) {
if (table[i].atr_len != atr_len)
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)
i = sc_bin_to_hex(card->atr, card->atr_len, atr, sizeof(atr), ':');
if (i != 0)
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++) {
u8 tatr[SC_MAX_ATR_SIZE];
const char *tatr = table[i].atr;
size_t tlen = sizeof(tatr);
if (sc_hex_to_bin(table[i].atr, tatr, &tlen))
continue;
if (ctx->debug >= 4)
sc_debug(ctx, "trying ATR: %s\n", tatr);
if (tlen != atr_len)
continue;
if (memcmp(tatr, atr, tlen) != 0)
if (strncasecmp(tatr, atr, tlen) != 0)
continue;
if (id_out != NULL)
*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;
}
int _sc_add_atr(struct sc_card_driver *driver,
const u8 *atr, size_t atrlen, int id)
/* XXX: wtf? I don't see any memory freeing code. -aet */
int _sc_add_atr(struct sc_context *ctx, struct sc_card_driver *driver, struct sc_atr_table *src)
{
struct sc_atr_table *map, *entry;
u8 *dst_atr;
struct sc_atr_table *map, *dst;
map = (struct sc_atr_table *) realloc(driver->atr_map,
(driver->natrs + 2) * sizeof(struct sc_atr_table));
if (!map)
return SC_ERROR_OUT_OF_MEMORY;
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;
entry = &driver->atr_map[driver->natrs++];
memset(entry+1, 0, sizeof(*entry));
entry->atr = dst_atr;
entry->atr_len = atrlen;
entry->id = id;
memcpy(dst_atr, atr, atrlen);
if (src->name) {
dst->name = strdup(src->name);
if (!dst->name)
return SC_ERROR_OUT_OF_MEMORY;
} else {
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;
}

View File

@ -44,7 +44,7 @@ int _sc_add_reader(struct sc_context *ctx, struct sc_reader *reader)
return SC_ERROR_TOO_MANY_OBJECTS;
ctx->reader[ctx->reader_count] = reader;
ctx->reader_count++;
return 0;
}
@ -107,7 +107,7 @@ static void del_drvs(struct _sc_ctx_options *opts, int type)
{
struct _sc_driver_entry *lst;
int *cp, i;
if (type == 0) {
lst = opts->rdrv;
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;
int *cp, i;
if (type == 0) {
lst = opts->rdrv;
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;
int i;
if (type == 0)
lst = internal_reader_drivers;
else
@ -183,7 +183,7 @@ static int load_parameters(struct sc_context *ctx, scconf_block *block,
const scconf_list *list;
const char *val;
const char *s_internal = "internal";
ctx->debug = scconf_get_int(block, "debug", ctx->debug);
val = scconf_get_str(block, "debug_file", NULL);
if (val) {
@ -261,7 +261,7 @@ static void load_reader_driver_options(sc_context_t *ctx,
driver->max_recv_size = SC_APDU_CHOP_SIZE;
if (conf_block != NULL) {
const scconf_list *list;
list = scconf_find_list(conf_block, "apdu_masquerade");
if (list)
driver->apdu_masquerade = 0;
@ -411,20 +411,17 @@ static int load_reader_drivers(struct sc_context *ctx,
ctx->reader_drivers[drv_count] = driver;
drv_count++;
}
return 0;
}
return 0;
}
static int load_card_driver_options(struct sc_context *ctx,
struct sc_card_driver *driver)
{
scconf_block **blocks, *blk;
const scconf_list *list;
int i, r;
int 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,
ctx->conf_blocks[i],
"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");
while (list != NULL) {
atr_len = sizeof(atr_buf);
r = sc_hex_to_bin(list->data,
atr_buf, &atr_len);
if (r < 0) {
sc_error(ctx,
"Unable to parse ATR '%s'.\n",
list->data);
continue;
}
_sc_add_atr(driver, atr_buf, atr_len, 0);
struct sc_atr_table t;
memset(&t, 0, sizeof(struct sc_atr_table));
t.atr = list->data;
_sc_add_atr(ctx, driver, &t);
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]);
drv_count++;
}
return 0;
return 0;
}
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) {
sc_set_card_driver(ctx, opts.forced_card_driver);
free(opts.forced_card_driver);
}
}
del_drvs(&opts, 0);
del_drvs(&opts, 1);
if (ctx->reader_count == 0) {
@ -590,7 +582,7 @@ int sc_release_context(struct sc_context *ctx)
SC_FUNC_CALLED(ctx, 1);
for (i = 0; i < ctx->reader_count; i++) {
struct sc_reader *rdr = ctx->reader[i];
if (rdr->ops->release != NULL)
rdr->ops->release(rdr);
free(rdr->name);
@ -598,7 +590,7 @@ int sc_release_context(struct sc_context *ctx)
}
for (i = 0; ctx->reader_drivers[i] != NULL; i++) {
const struct sc_reader_driver *drv = ctx->reader_drivers[i];
if (drv->ops->finish != NULL)
drv->ops->finish(ctx, ctx->reader_drv_data[i]);
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 i = 0, match = 0;
sc_mutex_lock(ctx->mutex);
if (short_name == NULL) {
ctx->forced_driver = NULL;

View File

@ -39,16 +39,10 @@ extern "C" {
#define SC_CTX_MAGIC 0x0A550335
struct sc_atr_table {
const u8 *atr;
size_t atr_len;
int id;
};
struct sc_atr_table_hex {
const char *atr;
const char *name;
int id;
unsigned flags;
unsigned long flags;
};
/* 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);
/* 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
* be null terminated. */
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_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_slot_info *slot;
int type; /* Card type, for card driver internal use */
unsigned long caps, flags;
unsigned int wait_resend_apdu; /* Delay (msec) before responding to an SW12 = 6CXX */
int cla;

View File

@ -198,22 +198,17 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card)
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)
{
sc_card_t *card = p15card->card;
int i;
/* XXX: save type of the micardo card in the card structure */
i = _sc_match_atr_hex(card, esteid_atrs, NULL);
if (i < 0)
/* check if we have the correct card OS */
if (strcmp(card->name, "MICARDO 2.1"))
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,

View File

@ -114,13 +114,13 @@ int sc_detect_card_presence(struct sc_reader *reader, int slot_id)
{
int r;
struct sc_slot_info *slot = _sc_get_slot_info(reader, slot_id);
if (slot == NULL)
SC_FUNC_RETURN(reader->ctx, 0, SC_ERROR_SLOT_NOT_FOUND);
SC_FUNC_CALLED(reader->ctx, 1);
if (reader->ops->detect_card_presence == NULL)
SC_FUNC_RETURN(reader->ctx, 0, SC_ERROR_NOT_SUPPORTED);
r = reader->ops->detect_card_presence(reader, slot);
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] = NULL;
}
_new = (struct sc_acl_entry *) malloc(sizeof(struct sc_acl_entry));
if (_new == NULL)
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)
{
struct sc_acl_entry *e;
assert(file != NULL);
assert(operation < SC_MAX_AC_OPS);
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 *) 3) {
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 *file = (struct sc_file *) malloc(sizeof(struct sc_file));
if (file == NULL)
return NULL;
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;
const struct sc_acl_entry *e;
unsigned int op;
assert(sc_file_valid(src));
*dest = NULL;
newf = sc_file_new();
if (newf == NULL)
return;
*dest = newf;
*newf = *src;
for (op = 0; op < SC_MAX_AC_OPS; op++) {
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;
return 0;
}
}
int sc_file_set_prop_attr(struct sc_file *file, const u8 *prop_attr,
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;
return 0;
}
}
int sc_file_set_type_attr(struct sc_file *file, const u8 *type_attr,
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;
return 0;
}
}
inline int sc_file_valid(const struct sc_file *file) {
#ifndef NDEBUG
@ -534,6 +534,5 @@ int _sc_parse_atr(struct sc_context *ctx, struct sc_slot_info *slot)
n_hist = atr_len;
slot->atr_info.hist_bytes_len = n_hist;
slot->atr_info.hist_bytes = p;
return 0;
}