- 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_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
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue