myeid: fixed a bug in setting card->name

Fixed a bug in setting card->name in myeid_init and myeid_get_info:
The buffer containing the card name fell out of scope.
This commit is contained in:
Hannu Honkanen 2016-03-30 10:53:14 +03:00 committed by Viktor Tarasov
parent bd84e18f45
commit fe2312dd19
1 changed files with 98 additions and 93 deletions

View File

@ -47,6 +47,10 @@
#define MYEID_STATE_ACTIVATED 0x07 #define MYEID_STATE_ACTIVATED 0x07
#define MYEID_INFINEON_CHIP_ATR 0x04 #define MYEID_INFINEON_CHIP_ATR 0x04
#define MYEID_CARD_NAME_MAX_LEN 100
static const char *myeid_card_name = "MyEID";
static char card_name_buf[MYEID_CARD_NAME_MAX_LEN];
static struct sc_card_operations myeid_ops; static struct sc_card_operations myeid_ops;
static struct sc_card_driver myeid_drv = { static struct sc_card_driver myeid_drv = {
@ -80,15 +84,15 @@ typedef struct myeid_private_data {
} myeid_private_data_t; } myeid_private_data_t;
static struct myeid_supported_ec_curves { static struct myeid_supported_ec_curves {
char *curve_name; char *curve_name;
struct sc_object_id curve_oid; struct sc_object_id curve_oid;
size_t size; size_t size;
} ec_curves[] = { } ec_curves[] = {
{"secp192r1", {{1, 2, 840, 10045, 3, 1, 1, -1}},192}, {"secp192r1", {{1, 2, 840, 10045, 3, 1, 1, -1}},192},
/* {"secp224r1", {{1, 3, 132, 0, 33, -1}}, 224}, */ /* {"secp224r1", {{1, 3, 132, 0, 33, -1}}, 224}, */
{"secp256r1", {{1, 2, 840, 10045, 3, 1, 7, -1}},256}, {"secp256r1", {{1, 2, 840, 10045, 3, 1, 7, -1}},256},
{"secp384r1", {{1, 3, 132, 0, 34, -1}}, 384}, {"secp384r1", {{1, 3, 132, 0, 34, -1}}, 384},
{"secp521r1", {{1, 3, 132, 0, 35, -1}}, 521}, {"secp521r1", {{1, 3, 132, 0, 35, -1}}, 521},
{NULL, {{-1}}, 0}, {NULL, {{-1}}, 0},
}; };
@ -121,8 +125,7 @@ static int myeid_match_card(struct sc_card *card)
static int myeid_init(struct sc_card *card) static int myeid_init(struct sc_card *card)
{ {
unsigned long flags = 0, unsigned long flags = 0, ext_flags = 0;
ext_flags = 0;
myeid_private_data_t *priv; myeid_private_data_t *priv;
u8 appletInfo[20]; u8 appletInfo[20];
size_t appletInfoLen; size_t appletInfoLen;
@ -133,7 +136,11 @@ static int myeid_init(struct sc_card *card)
const char *atrp = myeid_atrs[MYEID_INFINEON_CHIP_ATR]; const char *atrp = myeid_atrs[MYEID_INFINEON_CHIP_ATR];
LOG_FUNC_CALLED(card->ctx); LOG_FUNC_CALLED(card->ctx);
card->name = myeid_card_name;
priv = calloc(1, sizeof(myeid_private_data_t)); priv = calloc(1, sizeof(myeid_private_data_t));
if (!priv) if (!priv)
LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
@ -160,11 +167,11 @@ static int myeid_init(struct sc_card *card)
_sc_card_add_rsa_alg(card, 2048, flags, 0); _sc_card_add_rsa_alg(card, 2048, flags, 0);
if (sc_hex_to_bin(atrp, defatr, &len) == 0 if (sc_hex_to_bin(atrp, defatr, &len) == 0
&& (len == card->atr.len) && && (len == card->atr.len) &&
memcmp(card->atr.value, defatr, len) == 0) { memcmp(card->atr.value, defatr, len) == 0) {
largeEccKeys = 1; largeEccKeys = 1;
} }
/* show ECC algorithms if the applet version of the inserted card supports them */ /* show ECC algorithms if the applet version of the inserted card supports them */
if ((card->version.fw_major == 3 && card->version.fw_minor > 5) || if ((card->version.fw_major == 3 && card->version.fw_minor > 5) ||
card->version.fw_major >= 4) { card->version.fw_major >= 4) {
@ -309,7 +316,7 @@ static int myeid_list_files(struct sc_card *card, u8 *buf, size_t buflen)
} }
static int myeid_process_fci(struct sc_card *card, struct sc_file *file, static int myeid_process_fci(struct sc_card *card, struct sc_file *file,
const u8 *buf, size_t buflen) const u8 *buf, size_t buflen)
{ {
myeid_private_data_t *priv = (myeid_private_data_t *) card->drv_data; myeid_private_data_t *priv = (myeid_private_data_t *) card->drv_data;
size_t taglen = 0; size_t taglen = 0;
@ -331,8 +338,8 @@ static int myeid_process_fci(struct sc_card *card, struct sc_file *file,
} }
if(file->sec_attr_len >= 3) if(file->sec_attr_len >= 3)
{ {
sc_log(card->ctx, "id (%X) sec_attr (%X %X %X)", file->id, sc_log(card->ctx, "id (%X) sec_attr (%X %X %X)", file->id,
file->sec_attr[0],file->sec_attr[1],file->sec_attr[2]); file->sec_attr[0],file->sec_attr[1],file->sec_attr[2]);
} }
tag = sc_asn1_find_tag(NULL, buf, buflen, 0x8A, &taglen); tag = sc_asn1_find_tag(NULL, buf, buflen, 0x8A, &taglen);
if (tag != NULL && taglen > 0) if (tag != NULL && taglen > 0)
@ -401,7 +408,7 @@ static int encode_file_structure(sc_card_t *card, const sc_file_t *file,
buf[17] = file->sec_attr[2]; buf[17] = file->sec_attr[2];
sc_log(card->ctx, "id (%X), sec_attr %X %X %X", file->id, sc_log(card->ctx, "id (%X), sec_attr %X %X %X", file->id,
file->sec_attr[0],file->sec_attr[1],file->sec_attr[2]); file->sec_attr[0],file->sec_attr[1],file->sec_attr[2]);
} }
else { else {
delete = sc_file_get_acl_entry(file, SC_AC_OP_DELETE); delete = sc_file_get_acl_entry(file, SC_AC_OP_DELETE);
@ -539,7 +546,7 @@ static int myeid_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data,
LOG_FUNC_CALLED(card->ctx); LOG_FUNC_CALLED(card->ctx);
sc_log(card->ctx, "ref (%d), pin1 len(%d), pin2 len (%d)\n", sc_log(card->ctx, "ref (%d), pin1 len(%d), pin2 len (%d)\n",
data->pin_reference, data->pin1.len, data->pin2.len); data->pin_reference, data->pin1.len, data->pin2.len);
if(data->pin1.len > 8 || data->pin2.len > 8) if(data->pin1.len > 8 || data->pin2.len > 8)
LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_PIN_LENGTH); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_PIN_LENGTH);
@ -651,12 +658,12 @@ static int myeid_set_security_env_ec(sc_card_t *card, const sc_security_env_t *e
if (env->flags & SC_SEC_ENV_KEY_REF_ASYMMETRIC) if (env->flags & SC_SEC_ENV_KEY_REF_ASYMMETRIC)
{ {
sc_log(card->ctx, "asymmetric keyref not supported.\n"); sc_log(card->ctx, "asymmetric keyref not supported.");
return SC_ERROR_NOT_SUPPORTED; return SC_ERROR_NOT_SUPPORTED;
} }
if (se_num > 0) if (se_num > 0)
{ {
sc_log(card->ctx, "restore security environment not supported.\n"); sc_log(card->ctx, "restore security environment not supported.");
return SC_ERROR_NOT_SUPPORTED; return SC_ERROR_NOT_SUPPORTED;
} }
@ -664,7 +671,7 @@ static int myeid_set_security_env_ec(sc_card_t *card, const sc_security_env_t *e
switch (env->operation) switch (env->operation)
{ {
case SC_SEC_OPERATION_DECIPHER: case SC_SEC_OPERATION_DECIPHER:
sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Decipher operation is not supported with EC keys.\n"); sc_log(card->ctx, "Decipher operation is not supported with EC keys.");
return SC_ERROR_NOT_SUPPORTED; return SC_ERROR_NOT_SUPPORTED;
break; break;
case SC_SEC_OPERATION_SIGN: case SC_SEC_OPERATION_SIGN:
@ -780,34 +787,34 @@ myeid_convert_ec_signature(struct sc_context *ctx, size_t s_len, unsigned char *
size_t sig_len = 0; size_t sig_len = 0;
assert(data && datalen && datalen > 3); assert(data && datalen && datalen > 3);
/* /*
* When validating the signature data, we have to consider that length of the signature * When validating the signature data, we have to consider that length of the signature
* can be encoded in either one or two bytes depending on key size. With 521 bit keys * can be encoded in either one or two bytes depending on key size. With 521 bit keys
* length of the structure takes two bytes. * length of the structure takes two bytes.
*/ */
if (*data != 0x30) if (*data != 0x30)
return SC_ERROR_INVALID_DATA; return SC_ERROR_INVALID_DATA;
if ((*(data + 1) & 0x80) == 0x80) if ((*(data + 1) & 0x80) == 0x80)
len_size += *(data + 1) & 0x7F; len_size += *(data + 1) & 0x7F;
if (len_size == 1) if (len_size == 1)
sig_len = *(data + 1); sig_len = *(data + 1);
else if (len_size == 2) else if (len_size == 2)
sig_len = *(data + 2); sig_len = *(data + 2);
else if (len_size == 3) else if (len_size == 3)
{ {
sig_len = *(data + 2) | (*data + 3) << 8; sig_len = *(data + 2) | (*data + 3) << 8;
} }
else else
return SC_ERROR_INVALID_DATA; return SC_ERROR_INVALID_DATA;
if (*(data + 1 + len_size) != 0x02) /* Verify that it is an INTEGER */ if (*(data + 1 + len_size) != 0x02) /* Verify that it is an INTEGER */
if (sig_len != (datalen - len_size - 1)) /* validate size of the DER structure */ if (sig_len != (datalen - len_size - 1)) /* validate size of the DER structure */
return SC_ERROR_INVALID_DATA; return SC_ERROR_INVALID_DATA;
buf = calloc(1, (s_len + 7)/8*2); buf = calloc(1, (s_len + 7)/8*2);
if (!buf) if (!buf)
@ -817,7 +824,7 @@ myeid_convert_ec_signature(struct sc_context *ctx, size_t s_len, unsigned char *
r = sc_asn1_sig_value_sequence_to_rs(ctx, data, datalen, buf, buflen); r = sc_asn1_sig_value_sequence_to_rs(ctx, data, datalen, buf, buflen);
if (r < 0) if (r < 0)
free(buf); free(buf);
LOG_TEST_RET(ctx, r, "Failed to cenvert Sig-Value to the raw RS format"); LOG_TEST_RET(ctx, r, "Failed to cenvert Sig-Value to the raw RS format");
if (buflen > datalen) if (buflen > datalen)
LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA); LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA);
@ -837,9 +844,9 @@ myeid_compute_signature(struct sc_card *card, const u8 * data, size_t datalen,
u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; u8 sbuf[SC_MAX_APDU_BUFFER_SIZE];
struct myeid_private_data* priv; struct myeid_private_data* priv;
int r; int r;
size_t field_length = 0; size_t field_length = 0;
size_t pad_chars = 0; size_t pad_chars = 0;
assert(card != NULL && data != NULL && out != NULL); assert(card != NULL && data != NULL && out != NULL);
ctx = card->ctx; ctx = card->ctx;
@ -849,19 +856,19 @@ myeid_compute_signature(struct sc_card *card, const u8 * data, size_t datalen,
sc_log(ctx, "key type %i, key length %i", priv->sec_env->algorithm, priv->sec_env->algorithm_ref); sc_log(ctx, "key type %i, key length %i", priv->sec_env->algorithm, priv->sec_env->algorithm_ref);
if (priv->sec_env->algorithm == SC_ALGORITHM_EC ) { if (priv->sec_env->algorithm == SC_ALGORITHM_EC ) {
field_length = priv->sec_env->algorithm_ref; field_length = priv->sec_env->algorithm_ref;
/* pad with zeros if needed */ /* pad with zeros if needed */
if (datalen < (field_length + 7) / 8 ) { if (datalen < (field_length + 7) / 8 ) {
pad_chars = ((field_length + 7) / 8) - datalen; pad_chars = ((field_length + 7) / 8) - datalen;
memset(sbuf, 0, pad_chars); memset(sbuf, 0, pad_chars);
} }
} }
if ((datalen + pad_chars) > 256) if ((datalen + pad_chars) > 256)
LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
/* INS: 0x2A PERFORM SECURITY OPERATION /* INS: 0x2A PERFORM SECURITY OPERATION
* P1: 0x9E Resp: Digital Signature * P1: 0x9E Resp: Digital Signature
@ -886,7 +893,7 @@ myeid_compute_signature(struct sc_card *card, const u8 * data, size_t datalen,
r = sc_transmit_apdu(card, &apdu); r = sc_transmit_apdu(card, &apdu);
LOG_TEST_RET(ctx, r, "APDU transmit failed"); LOG_TEST_RET(ctx, r, "APDU transmit failed");
r = sc_check_sw(card, apdu.sw1, apdu.sw2); r = sc_check_sw(card, apdu.sw1, apdu.sw2);
LOG_TEST_RET(ctx, r, "compute_signature failed"); LOG_TEST_RET(ctx, r, "compute_signature failed");
if (priv->sec_env->algorithm == SC_ALGORITHM_EC) { if (priv->sec_env->algorithm == SC_ALGORITHM_EC) {
r = myeid_convert_ec_signature(ctx, priv->sec_env->algorithm_ref, apdu.resp, apdu.resplen); r = myeid_convert_ec_signature(ctx, priv->sec_env->algorithm_ref, apdu.resp, apdu.resplen);
@ -914,9 +921,7 @@ int myeid_ecdh_derive(struct sc_card *card, const u8* pubkey, size_t pubkey_len,
int r; int r;
sc_format_apdu(card, &apdu, sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x86, 0x00, 0x00);
SC_APDU_CASE_4_SHORT,
0x86, 0x00, 0x00);
apdu.resp = rbuf; apdu.resp = rbuf;
apdu.resplen = sizeof(rbuf); apdu.resplen = sizeof(rbuf);
@ -941,8 +946,8 @@ int myeid_ecdh_derive(struct sc_card *card, const u8* pubkey, size_t pubkey_len,
if (outlen < apdu.resplen) if (outlen < apdu.resplen)
{ {
r = SC_ERROR_BUFFER_TOO_SMALL; r = SC_ERROR_BUFFER_TOO_SMALL;
LOG_TEST_RET(card->ctx, r, "Buffer too small to hold shared secret."); LOG_TEST_RET(card->ctx, r, "Buffer too small to hold shared secret.");
} }
memcpy(out, rbuf, apdu.resplen); memcpy(out, rbuf, apdu.resplen);
@ -968,23 +973,23 @@ static int myeid_decipher(struct sc_card *card, const u8 * crgram,
priv = (myeid_private_data_t*) card->drv_data; priv = (myeid_private_data_t*) card->drv_data;
if (priv->sec_env && priv->sec_env->algorithm == SC_ALGORITHM_EC if (priv->sec_env && priv->sec_env->algorithm == SC_ALGORITHM_EC
&& priv->sec_env->operation == SC_SEC_OPERATION_DERIVE && priv->sec_env->operation == SC_SEC_OPERATION_DERIVE
&& priv->sec_env->algorithm_flags & SC_ALGORITHM_ECDSA_RAW) && priv->sec_env->algorithm_flags & SC_ALGORITHM_ECDSA_RAW)
{ {
r = myeid_ecdh_derive(card, crgram, crgram_len, out, outlen); r = myeid_ecdh_derive(card, crgram, crgram_len, out, outlen);
priv->sec_env = NULL; /* clear after operation */ priv->sec_env = NULL; /* clear after operation */
LOG_FUNC_RETURN(card->ctx, r); LOG_FUNC_RETURN(card->ctx, r);
} }
if (crgram_len > 256) if (crgram_len > 256)
LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
/* INS: 0x2A PERFORM SECURITY OPERATION /* INS: 0x2A PERFORM SECURITY OPERATION
* P1: 0x80 Resp: Plain value * P1: 0x80 Resp: Plain value
* P2: 0x86 Cmd: Padding indicator byte followed by cryptogram */ * P2: 0x86 Cmd: Padding indicator byte followed by cryptogram */
sc_format_apdu(card, &apdu, sc_format_apdu(card, &apdu,
(crgram_len < 256) ? SC_APDU_CASE_4_SHORT : SC_APDU_CASE_3_SHORT, (crgram_len < 256) ? SC_APDU_CASE_4_SHORT : SC_APDU_CASE_3_SHORT,
0x2A, 0x80, 0x86); 0x2A, 0x80, 0x86);
apdu.resp = rbuf; apdu.resp = rbuf;
apdu.resplen = sizeof(rbuf); apdu.resplen = sizeof(rbuf);
@ -992,17 +997,17 @@ static int myeid_decipher(struct sc_card *card, const u8 * crgram,
if (crgram_len == 256) if (crgram_len == 256)
{ {
apdu.le = 0; apdu.le = 0;
/* padding indicator byte, 0x81 = first half of 2048 bit cryptogram */ /* padding indicator byte, 0x81 = first half of 2048 bit cryptogram */
sbuf[0] = 0x81; sbuf[0] = 0x81;
memcpy(sbuf + 1, crgram, crgram_len / 2); memcpy(sbuf + 1, crgram, crgram_len / 2);
apdu.lc = crgram_len / 2 + 1; apdu.lc = crgram_len / 2 + 1;
} }
else else
{ {
sbuf[0] = 0; /* padding indicator byte, 0x00 = No further indication */ sbuf[0] = 0; /* padding indicator byte, 0x00 = No further indication */
memcpy(sbuf + 1, crgram, crgram_len); memcpy(sbuf + 1, crgram, crgram_len);
apdu.lc = crgram_len + 1; apdu.lc = crgram_len + 1;
} }
apdu.datalen = apdu.lc; apdu.datalen = apdu.lc;
@ -1012,39 +1017,39 @@ static int myeid_decipher(struct sc_card *card, const u8 * crgram,
LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00)
{ {
if (crgram_len == 256) if (crgram_len == 256)
{ {
sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT,
0x2A, 0x80, 0x86); 0x2A, 0x80, 0x86);
apdu.resp = rbuf; apdu.resp = rbuf;
apdu.resplen = sizeof(rbuf); apdu.resplen = sizeof(rbuf);
apdu.le = crgram_len; apdu.le = crgram_len;
/* padding indicator byte, /* padding indicator byte,
* 0x82 = Second half of 2048 bit cryptogram */ * 0x82 = Second half of 2048 bit cryptogram */
sbuf[0] = 0x82; sbuf[0] = 0x82;
memcpy(sbuf + 1, crgram + crgram_len / 2, crgram_len / 2); memcpy(sbuf + 1, crgram + crgram_len / 2, crgram_len / 2);
apdu.lc = crgram_len / 2 + 1; apdu.lc = crgram_len / 2 + 1;
apdu.datalen = apdu.lc; apdu.datalen = apdu.lc;
apdu.data = sbuf; apdu.data = sbuf;
r = sc_transmit_apdu(card, &apdu); r = sc_transmit_apdu(card, &apdu);
LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00)
{ {
int len = apdu.resplen > outlen ? outlen : apdu.resplen; int len = apdu.resplen > outlen ? outlen : apdu.resplen;
memcpy(out, apdu.resp, len); memcpy(out, apdu.resp, len);
LOG_FUNC_RETURN(card->ctx, len); LOG_FUNC_RETURN(card->ctx, len);
} }
} }
else else
{ {
int len = apdu.resplen > outlen ? outlen : apdu.resplen; int len = apdu.resplen > outlen ? outlen : apdu.resplen;
memcpy(out, apdu.resp, len); memcpy(out, apdu.resp, len);
LOG_FUNC_RETURN(card->ctx, len); LOG_FUNC_RETURN(card->ctx, len);
} }
} }
LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2)); LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2));
} }
@ -1297,7 +1302,6 @@ static int myeid_get_info(struct sc_card *card, u8 *rbuf, size_t buflen)
{ {
sc_apdu_t apdu; sc_apdu_t apdu;
int r; int r;
char nameBuf[100];
LOG_FUNC_CALLED(card->ctx); LOG_FUNC_CALLED(card->ctx);
@ -1314,7 +1318,7 @@ static int myeid_get_info(struct sc_card *card, u8 *rbuf, size_t buflen)
if (apdu.resplen != 20) if (apdu.resplen != 20)
{ {
sc_log(card->ctx, "Unexpected response to GET DATA (applet info)\n"); sc_log(card->ctx, "Unexpected response to GET DATA (applet info)");
return SC_ERROR_INTERNAL; return SC_ERROR_INTERNAL;
} }
@ -1322,9 +1326,10 @@ static int myeid_get_info(struct sc_card *card, u8 *rbuf, size_t buflen)
card->version.fw_major = rbuf[5] * 10 + rbuf[6]; card->version.fw_major = rbuf[5] * 10 + rbuf[6];
card->version.fw_minor = rbuf[7]; card->version.fw_minor = rbuf[7];
/* add version to name */ /* add version to name */
sprintf((char *) nameBuf, "%s %d.%d.%d", card->name, rbuf[5], rbuf[6], rbuf[7]); snprintf(card_name_buf, sizeof(card_name_buf),
card->name = nameBuf; "%s %d.%d.%d", card->name, rbuf[5], rbuf[6], rbuf[7]);
//card->driver->name card->name = card_name_buf;
LOG_FUNC_RETURN(card->ctx, r); LOG_FUNC_RETURN(card->ctx, r);
} }