- 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:
parent
c30494a942
commit
69d2e9014d
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue