Skip to content

Commit

Permalink
myeid: fix EC key upload, and avoid data copying
Browse files Browse the repository at this point in the history
Fixes regression from commit 3688dfe which did not consider that
the zero prefixing tests were too generic and matched EC keys too.

This simplifies the code even further and avoids data copying
when possible. Proper test is now included to do data value prefixing
only for the RSA keys it is needed.

Closes #1701.
  • Loading branch information
fabled authored and frankmorgner committed Jun 17, 2019
1 parent 8c12835 commit 19711d0
Showing 1 changed file with 18 additions and 24 deletions.
42 changes: 18 additions & 24 deletions src/libopensc/card-myeid.c
Original file line number Diff line number Diff line change
Expand Up @@ -1460,36 +1460,27 @@ static int myeid_loadkey(sc_card_t *card, unsigned mode, u8* value, int value_le
myeid_private_data_t *priv = (myeid_private_data_t *) card->drv_data;
sc_apdu_t apdu;
u8 sbuf[MYEID_MAX_EXT_APDU_BUFFER_SIZE];
int r, len;
int r;

LOG_FUNC_CALLED(card->ctx);
len = 0;
if (value_len == 0 || value == NULL)
return 0;

if (value[0] != 0x0 &&
mode != LOAD_KEY_PUBLIC_EXPONENT &&
mode != LOAD_KEY_SYMMETRIC)
sbuf[len++] = 0x0;

if (mode == LOAD_KEY_MODULUS && value_len == 256 && !priv->cap_chaining)
{
if ((value_len % 2) > 0 && value[0] == 0x00)
{
value_len--;
memmove(value, value + 1, value_len);
value++;
}
mode = 0x88;
len = 128;
memcpy(sbuf,value, 128);

mode = 0x88;
memset(&apdu, 0, sizeof(apdu));
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xDA, 0x01, mode);

apdu.cla = 0x00;
apdu.data = sbuf;
apdu.datalen = len;
apdu.lc = len;
apdu.data = value;
apdu.datalen = 128;
apdu.lc = 128;

r = sc_transmit_apdu(card, &apdu);
LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
Expand All @@ -1498,23 +1489,26 @@ static int myeid_loadkey(sc_card_t *card, unsigned mode, u8* value, int value_le
LOG_TEST_RET(card->ctx, r, "LOAD KEY returned error");

mode = 0x89;
len = value_len - 128;
memset(&sbuf, 0, SC_MAX_APDU_BUFFER_SIZE);
memcpy(sbuf,value + 128, value_len - 128);
value += 128;
value_len -= 128;
}
else
else if ((mode & 0xff00) == 0 && mode != LOAD_KEY_PUBLIC_EXPONENT &&
value[0] != 0x00)
{
memcpy(sbuf + len, value, value_len);
len += value_len;
/* RSA components needing leading zero byte */
sbuf[0] = 0x0;
memcpy(&sbuf[1], value, value_len);
value = sbuf;
value_len ++;
}

memset(&apdu, 0, sizeof(apdu));
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xDA, 0x01, mode & 0xFF);
apdu.flags = SC_APDU_FLAGS_CHAINING;
apdu.cla = 0x00;
apdu.data = sbuf;
apdu.datalen = len;
apdu.lc = len;
apdu.data = value;
apdu.datalen = value_len;
apdu.lc = value_len;

r = sc_transmit_apdu(card, &apdu);
LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
Expand Down

0 comments on commit 19711d0

Please sign in to comment.