Removing all memory leaks in DNIe but one. Refactoring pending.
This commit is contained in:
parent
a454dd7fc9
commit
d1a1830115
|
@ -634,17 +634,16 @@ static int dnie_get_serialnr(sc_card_t * card, sc_serial_number_t * serial)
|
|||
LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
|
||||
}
|
||||
/* not cached, retrieve it by mean of an APDU */
|
||||
sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xb8, 0x00, 0x00);
|
||||
/* official driver read 0x11 bytes, but only uses 7. Manual says just 7 (for le) */
|
||||
dnie_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xb8, 0x00, 0x00, 0x07, 0,
|
||||
rbuf, sizeof(rbuf), NULL, 0);
|
||||
apdu.cla = 0x90; /* propietary cmd */
|
||||
apdu.resp = rbuf;
|
||||
apdu.resplen = sizeof(rbuf);
|
||||
/* official driver read 0x11 bytes, but only uses 7. Manual says just 7 */
|
||||
apdu.le = 0x07;
|
||||
apdu.lc = 0;
|
||||
apdu.datalen = 0;
|
||||
/* send apdu */
|
||||
result = dnie_transmit_apdu(card, &apdu);
|
||||
LOG_TEST_RET(card->ctx, result, "APDU transmit failed");
|
||||
if (result != SC_SUCCESS) {
|
||||
dnie_free_apdu_buffers(&apdu, rbuf, sizeof(rbuf));
|
||||
LOG_TEST_RET(card->ctx, result, "APDU transmit failed");
|
||||
}
|
||||
if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00)
|
||||
return SC_ERROR_INTERNAL;
|
||||
/* cache serial number */
|
||||
|
@ -660,6 +659,7 @@ static int dnie_get_serialnr(sc_card_t * card, sc_serial_number_t * serial)
|
|||
memcpy(serial, &card->serialnr, sizeof(*serial));
|
||||
sc_log(card->ctx, "Serial Number (apdu): '%s'",
|
||||
sc_dump_hex(serial->value, serial->len));
|
||||
dnie_free_apdu_buffers(&apdu, rbuf, sizeof(rbuf));
|
||||
LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
|
||||
}
|
||||
|
||||
|
@ -807,8 +807,8 @@ static int dnie_finish(struct sc_card *card)
|
|||
/* disable sm channel if established */
|
||||
result = cwa_create_secure_channel(card, GET_DNIE_PRIV_DATA(card)->cwa_provider, CWA_SM_OFF);
|
||||
#endif
|
||||
if (card->drv_data != NULL)
|
||||
free(card->drv_data);
|
||||
free(GET_DNIE_PRIV_DATA(card)->cwa_provider);
|
||||
free(card->drv_data);
|
||||
LOG_FUNC_RETURN(card->ctx, result);
|
||||
}
|
||||
|
||||
|
@ -949,8 +949,9 @@ static int dnie_fill_cache(sc_card_t * card)
|
|||
/* transmit apdu */
|
||||
r = dnie_transmit_apdu(card, &apdu);
|
||||
if (r != SC_SUCCESS) {
|
||||
if (buffer)
|
||||
free(buffer);
|
||||
free(buffer);
|
||||
if (apdu.resp != tmp)
|
||||
free(apdu.resp);
|
||||
sc_log(ctx, "read_binary() APDU transmit failed");
|
||||
LOG_FUNC_RETURN(ctx, r);
|
||||
}
|
||||
|
@ -960,20 +961,33 @@ static int dnie_fill_cache(sc_card_t * card)
|
|||
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
if (r == SC_ERROR_WRONG_LENGTH) {
|
||||
count = 0xff & apdu.sw2;
|
||||
if (count != 0)
|
||||
if (count != 0) {
|
||||
if (apdu.resp != tmp)
|
||||
free(apdu.resp);
|
||||
continue; /* read again with correct size */
|
||||
}
|
||||
goto read_done; /* no more data to read */
|
||||
}
|
||||
if (r == SC_ERROR_INCORRECT_PARAMETERS)
|
||||
goto read_done;
|
||||
if (apdu.resp != tmp)
|
||||
free(apdu.resp);
|
||||
LOG_FUNC_RETURN(ctx, r); /* arriving here means response error */
|
||||
}
|
||||
/* copy received data into buffer. realloc() if not enought space */
|
||||
count = apdu.resplen;
|
||||
buffer = realloc(buffer, len + count);
|
||||
if (!buffer)
|
||||
if (!buffer) {
|
||||
free((void *)apdu.data);
|
||||
if (apdu.resp != tmp)
|
||||
free(apdu.resp);
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
memcpy(buffer + len, apdu.resp, count);
|
||||
if (apdu.resp != tmp) {
|
||||
free(apdu.resp);
|
||||
apdu.resp = tmp;
|
||||
}
|
||||
len += count;
|
||||
if (count != card->max_recv_size)
|
||||
goto read_done;
|
||||
|
@ -982,15 +996,16 @@ static int dnie_fill_cache(sc_card_t * card)
|
|||
read_done:
|
||||
/* no more data to read: check if data is compressed */
|
||||
pt = dnie_uncompress(card, buffer, &len);
|
||||
free((void *)apdu.data);
|
||||
if (apdu.resp != tmp)
|
||||
free(apdu.resp);
|
||||
if (pt == NULL) {
|
||||
sc_log(ctx, "Uncompress proccess failed");
|
||||
if (buffer)
|
||||
free(buffer);
|
||||
free(buffer);
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL);
|
||||
}
|
||||
if (pt != buffer)
|
||||
if (buffer)
|
||||
free(buffer);
|
||||
free(buffer);
|
||||
|
||||
/* ok: as final step, set correct cache data into dnie_priv structures */
|
||||
GET_DNIE_PRIV_DATA(card)->cache = pt;
|
||||
|
@ -1066,16 +1081,10 @@ static int dnie_compose_and_send_apdu(sc_card_t *card, const u8 *path, size_t pa
|
|||
|
||||
LOG_FUNC_CALLED(ctx);
|
||||
|
||||
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "called, p1=%u, path=%s\n", p1, sc_dump_hex(path, pathlen));
|
||||
|
||||
/* Arriving here means need to compose and send apdu */
|
||||
sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xA4, p1, 0);
|
||||
apdu.resp = rbuf;
|
||||
apdu.resplen = sizeof(rbuf);
|
||||
apdu.lc = pathlen;
|
||||
apdu.data = path;
|
||||
apdu.datalen = pathlen;
|
||||
apdu.le = sc_get_max_recv_size(card);
|
||||
dnie_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xA4, p1, 0,
|
||||
sc_get_max_recv_size(card), pathlen,
|
||||
rbuf, sizeof(rbuf), path, pathlen);
|
||||
if (p1 == 3)
|
||||
apdu.cse= SC_APDU_CASE_1;
|
||||
|
||||
|
@ -1084,6 +1093,8 @@ static int dnie_compose_and_send_apdu(sc_card_t *card, const u8 *path, size_t pa
|
|||
apdu.le = 0;
|
||||
}
|
||||
res = dnie_transmit_apdu(card, &apdu);
|
||||
if ((res != SC_SUCCESS) || (file_out == NULL))
|
||||
dnie_free_apdu_buffers(&apdu, rbuf, sizeof(rbuf));
|
||||
LOG_TEST_RET(ctx, res, "SelectFile() APDU transmit failed");
|
||||
if (file_out == NULL) {
|
||||
if (apdu.sw1 == 0x61)
|
||||
|
@ -1094,20 +1105,26 @@ static int dnie_compose_and_send_apdu(sc_card_t *card, const u8 *path, size_t pa
|
|||
|
||||
/* analyze response. if FCI, try to parse */
|
||||
res = sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
LOG_TEST_RET(ctx, res, "SelectFile() check_sw failed");
|
||||
if (apdu.resplen < 2)
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
|
||||
if (apdu.resp[0] == 0x00) /* proprietary coding */
|
||||
if (res != SC_SUCCESS) {
|
||||
dnie_free_apdu_buffers(&apdu, rbuf, sizeof(rbuf));
|
||||
LOG_TEST_RET(ctx, res, "SelectFile() check_sw failed");
|
||||
}
|
||||
if ((apdu.resplen < 2) || (apdu.resp[0] == 0x00)) {
|
||||
dnie_free_apdu_buffers(&apdu, rbuf, sizeof(rbuf));
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
|
||||
}
|
||||
|
||||
/* finally process FCI response */
|
||||
file = sc_file_new();
|
||||
if (file == NULL)
|
||||
if (file == NULL) {
|
||||
dnie_free_apdu_buffers(&apdu, rbuf, sizeof(rbuf));
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
res = card->ops->process_fci(card, file, apdu.resp + 2, apdu.resp[1]);
|
||||
if (*file_out != NULL)
|
||||
sc_file_free(*file_out);
|
||||
*file_out = file;
|
||||
dnie_free_apdu_buffers(&apdu, rbuf, sizeof(rbuf));
|
||||
LOG_FUNC_RETURN(ctx, res);
|
||||
}
|
||||
|
||||
|
@ -1267,10 +1284,8 @@ static int dnie_get_challenge(struct sc_card *card, u8 * rnd, size_t len)
|
|||
result = SC_ERROR_INVALID_ARGUMENTS;
|
||||
goto dnie_get_challenge_error;
|
||||
}
|
||||
sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0x84, 0x00, 0x00);
|
||||
apdu.le = 8;
|
||||
apdu.resp = buf;
|
||||
apdu.resplen = 8; /* include SW's */
|
||||
dnie_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0x84, 0x00, 0x00, 8, 0,
|
||||
buf, 8, NULL, 0);
|
||||
|
||||
/*
|
||||
* As DNIe cannot handle other data length than 0x08 and 0x14,
|
||||
|
@ -1279,12 +1294,17 @@ static int dnie_get_challenge(struct sc_card *card, u8 * rnd, size_t len)
|
|||
while (len > 0) {
|
||||
size_t n = len > 8 ? 8 : len;
|
||||
result = dnie_transmit_apdu(card, &apdu);
|
||||
LOG_TEST_RET(card->ctx, result, "APDU transmit failed");
|
||||
if (result != SC_SUCCESS) {
|
||||
dnie_free_apdu_buffers(&apdu, buf, 8);
|
||||
LOG_TEST_RET(card->ctx, result, "APDU transmit failed");
|
||||
}
|
||||
if (apdu.resplen != 8) {
|
||||
result = sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
dnie_free_apdu_buffers(&apdu, buf, 8);
|
||||
goto dnie_get_challenge_error;
|
||||
}
|
||||
memcpy(rnd, apdu.resp, n);
|
||||
dnie_free_apdu_buffers(&apdu, buf, 8);
|
||||
len -= n;
|
||||
rnd += n;
|
||||
}
|
||||
|
@ -1414,7 +1434,8 @@ static int dnie_set_security_env(struct sc_card *card,
|
|||
}
|
||||
|
||||
/* create and format apdu */
|
||||
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x00, 0x00);
|
||||
dnie_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x00, 0x00, 0, p - sbuf,
|
||||
NULL, 0, sbuf, p - sbuf);
|
||||
|
||||
/* check and perform operation */
|
||||
switch (env->operation) {
|
||||
|
@ -1436,18 +1457,13 @@ static int dnie_set_security_env(struct sc_card *card,
|
|||
LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
|
||||
}
|
||||
|
||||
/* complete apdu contents with buffer data */
|
||||
apdu.data = sbuf;
|
||||
apdu.datalen = p - sbuf;
|
||||
apdu.lc = p - sbuf;
|
||||
apdu.resplen = 0;
|
||||
|
||||
/* Notice that Manual states that DNIE only allows handle of
|
||||
* current security environment, so se_num is ignored, and
|
||||
* store sec env apdu (00 22 F2 se_num) command will not be issued */
|
||||
|
||||
/* send composed apdu and parse result */
|
||||
result = dnie_transmit_apdu(card, &apdu);
|
||||
dnie_free_apdu_buffers(&apdu, NULL, 0);
|
||||
LOG_TEST_RET(card->ctx, result, "Set Security Environment failed");
|
||||
result = sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
|
||||
|
@ -1501,19 +1517,15 @@ static int dnie_decipher(struct sc_card *card,
|
|||
* (90 74 40 keyID). This code uses standard 00 2A 80 8x one)
|
||||
* as shown in card-atrust-acos.c and card-jcop.c
|
||||
*/
|
||||
sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, /* INS: 0x2A perform security operation */
|
||||
0x80, /* P1: Response is plain value */
|
||||
0x86 /* P2: 8x: Padding indicator byte followed by cryptogram */
|
||||
dnie_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT,
|
||||
0x2A, /* INS: 0x2A perform security operation */
|
||||
0x80, /* P1: Response is plain value */
|
||||
0x86, /* P2: 8x: Padding indicator byte followed by cryptogram */
|
||||
256, crgram_len + 1, rbuf, sizeof(rbuf), sbuf, crgram_len + 1
|
||||
);
|
||||
apdu.resp = rbuf;
|
||||
apdu.resplen = sizeof(rbuf);
|
||||
|
||||
sbuf[0] = 0; /* padding indicator byte, 0x00 = No further indication */
|
||||
memcpy(sbuf + 1, crgram, crgram_len);
|
||||
apdu.data = sbuf;
|
||||
apdu.lc = crgram_len + 1;
|
||||
apdu.datalen = crgram_len + 1;
|
||||
apdu.le = 256;
|
||||
/* send apdu */
|
||||
result = dnie_transmit_apdu(card, &apdu);
|
||||
LOG_TEST_RET(card->ctx, result, "APDU transmit failed");
|
||||
|
@ -1557,6 +1569,7 @@ static int dnie_compute_signature(struct sc_card *card,
|
|||
u8 * out, size_t outlen)
|
||||
{
|
||||
int result = SC_SUCCESS;
|
||||
int result_resplen = 0;
|
||||
struct sc_apdu apdu;
|
||||
u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; /* to receive sign response */
|
||||
|
||||
|
@ -1595,24 +1608,27 @@ static int dnie_compute_signature(struct sc_card *card,
|
|||
/*INS: 0x2A PERFORM SECURITY OPERATION
|
||||
* P1: 0x9E Resp: Digital Signature
|
||||
* P2: 0x9A Cmd: Input for Digital Signature */
|
||||
sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x9E, 0x9A);
|
||||
apdu.resp = rbuf;
|
||||
apdu.resplen = sizeof(rbuf);
|
||||
apdu.le = 256; /* signature response size */
|
||||
apdu.data = data;
|
||||
apdu.lc = datalen; /* Caller determines the type of hash and its size */
|
||||
apdu.datalen = datalen;
|
||||
dnie_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x9E, 0x9A, 256, datalen,
|
||||
rbuf, sizeof(rbuf), data, datalen);
|
||||
/* tell card to compute signature */
|
||||
result = dnie_transmit_apdu(card, &apdu);
|
||||
LOG_TEST_RET(card->ctx, result, "compute_signature() failed");
|
||||
if (result != SC_SUCCESS) {
|
||||
dnie_free_apdu_buffers(&apdu, rbuf, sizeof(rbuf));
|
||||
LOG_TEST_RET(card->ctx, result, "compute_signature() failed");
|
||||
}
|
||||
/* check response */
|
||||
result = sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
LOG_TEST_RET(card->ctx, result, "compute_signature() response error");
|
||||
if (result != SC_SUCCESS) {
|
||||
dnie_free_apdu_buffers(&apdu, rbuf, sizeof(rbuf));
|
||||
LOG_TEST_RET(card->ctx, result, "compute_signature() response error");
|
||||
}
|
||||
|
||||
/* ok: copy result from buffer */
|
||||
memcpy(out, apdu.resp, apdu.resplen);
|
||||
result_resplen = apdu.resplen;
|
||||
memcpy(out, apdu.resp, result_resplen);
|
||||
/* and return response length */
|
||||
LOG_FUNC_RETURN(card->ctx, apdu.resplen);
|
||||
dnie_free_apdu_buffers(&apdu, rbuf, sizeof(rbuf));
|
||||
LOG_FUNC_RETURN(card->ctx, result_resplen);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1642,7 +1658,6 @@ static int dnie_list_files(sc_card_t * card, u8 * buf, size_t buflen)
|
|||
size_t count = 0;
|
||||
u8 data[2];
|
||||
sc_apdu_t apdu;
|
||||
sc_apdu_t back;
|
||||
if (!card || !card->ctx)
|
||||
return SC_ERROR_INVALID_ARGUMENTS;
|
||||
|
||||
|
@ -1651,21 +1666,8 @@ static int dnie_list_files(sc_card_t * card, u8 * buf, size_t buflen)
|
|||
LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
|
||||
|
||||
/* compose select_file(ID) command */
|
||||
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xA4, 0x00, 0x00);
|
||||
apdu.le = 0;
|
||||
apdu.lc = 2;
|
||||
apdu.data = data;
|
||||
apdu.resp = NULL;
|
||||
apdu.datalen = 2;
|
||||
apdu.resplen = 0;
|
||||
/* compose select_file(PARENT) command */
|
||||
sc_format_apdu(card, &back, SC_APDU_CASE_1, 0xA4, 0x03, 0x00);
|
||||
back.le = 0;
|
||||
back.lc = 0;
|
||||
back.data = NULL;
|
||||
back.resp = NULL;
|
||||
back.datalen = 0;
|
||||
back.resplen = 0;
|
||||
dnie_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xA4, 0x00, 0x00, 0, 2,
|
||||
NULL, 0, data, 2);
|
||||
/* iterate on every possible ids */
|
||||
for (id1 = 0; id1 < 256; id1++) {
|
||||
for (id2 = 0; id2 < 256; id2++) {
|
||||
|
@ -1685,6 +1687,7 @@ static int dnie_list_files(sc_card_t * card, u8 * buf, size_t buflen)
|
|||
data[0] = (u8) (0xff & id1);
|
||||
data[1] = (u8) (0xff & id2);
|
||||
res = dnie_transmit_apdu(card, &apdu);
|
||||
dnie_free_apdu_buffers(&apdu, NULL, 0);
|
||||
if (res != SC_SUCCESS) {
|
||||
sc_log(card->ctx, "List file '%02X%02X' failed",
|
||||
id1, id2);
|
||||
|
@ -1832,15 +1835,12 @@ static int dnie_read_header(struct sc_card *card)
|
|||
LOG_FUNC_CALLED(ctx);
|
||||
|
||||
/* initialize apdu */
|
||||
sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xB0, 0x00, 0x00);
|
||||
apdu.p1 = 0x00;
|
||||
apdu.p2 = 0x00;
|
||||
apdu.le = 8; /* read 8 bytes at begining of file */
|
||||
apdu.resplen = SC_MAX_APDU_BUFFER_SIZE;
|
||||
apdu.resp = buf;
|
||||
dnie_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xB0, 0x00, 0x00, 8, 0,
|
||||
buf, SC_MAX_APDU_BUFFER_SIZE, NULL, 0);
|
||||
/* transmit apdu */
|
||||
r = dnie_transmit_apdu(card, &apdu);
|
||||
if (r != SC_SUCCESS) {
|
||||
dnie_free_apdu_buffers(&apdu, buf, SC_MAX_APDU_BUFFER_SIZE);
|
||||
sc_log(ctx, "read_header() APDU transmit failed");
|
||||
LOG_FUNC_RETURN(ctx, r);
|
||||
}
|
||||
|
@ -1855,10 +1855,12 @@ static int dnie_read_header(struct sc_card *card)
|
|||
goto header_notcompressed;
|
||||
/* ok: assume data is correct */
|
||||
sc_log(ctx, "read_header: uncompressed file size is %lu", uncompressed);
|
||||
dnie_free_apdu_buffers(&apdu, buf, SC_MAX_APDU_BUFFER_SIZE);
|
||||
return (int)(0x7FFF & uncompressed);
|
||||
|
||||
header_notcompressed:
|
||||
sc_log(ctx, "response doesn't match compressed file header");
|
||||
dnie_free_apdu_buffers(&apdu, buf, SC_MAX_APDU_BUFFER_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2107,33 +2109,28 @@ static int dnie_pin_verify(struct sc_card *card,
|
|||
pinlen = res;
|
||||
|
||||
/* compose apdu */
|
||||
memset(&apdu, 0, sizeof(apdu)); /* clear buffer */
|
||||
apdu.cla = 0x00;
|
||||
apdu.cse = SC_APDU_CASE_3_SHORT;
|
||||
apdu.ins = (u8) 0x20; /* Verify cmd */
|
||||
apdu.p1 = (u8) 0x00;
|
||||
apdu.p2 = (u8) 0x00;
|
||||
apdu.lc = pinlen;
|
||||
apdu.datalen = pinlen;
|
||||
apdu.data = pinbuffer;
|
||||
apdu.resplen = 0;
|
||||
apdu.le = 0;
|
||||
dnie_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x20, 0x00, 0x00, 0x00, pinlen,
|
||||
NULL, 0, pinbuffer, pinlen);
|
||||
|
||||
/* and send to card throught virtual channel */
|
||||
res = dnie_transmit_apdu(card, &apdu);
|
||||
LOG_TEST_RET(card->ctx, res, "VERIFY APDU Transmit fail");
|
||||
if (res != SC_SUCCESS) {
|
||||
dnie_free_apdu_buffers(&apdu, NULL, 0);
|
||||
LOG_TEST_RET(card->ctx, res, "VERIFY APDU Transmit fail");
|
||||
}
|
||||
|
||||
/* check response and if requested setup tries_left */
|
||||
if (tries_left != NULL) { /* returning tries_left count is requested */
|
||||
if ((apdu.sw1 == 0x63) && ((apdu.sw2 & 0xF0) == 0xC0)) {
|
||||
*tries_left = apdu.sw2 & 0x0F;
|
||||
dnie_free_apdu_buffers(&apdu, NULL, 0);
|
||||
LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT);
|
||||
}
|
||||
}
|
||||
res = dnie_check_sw(card, apdu.sw1, apdu.sw2); /* not a pinerr: parse result */
|
||||
|
||||
/* the end: a bit of Mister Proper and return */
|
||||
memset(&apdu, 0, sizeof(apdu)); /* clear buffer */
|
||||
dnie_free_apdu_buffers(&apdu, NULL, 0);
|
||||
data->apdu = NULL;
|
||||
LOG_FUNC_RETURN(card->ctx, res);
|
||||
#else
|
||||
|
|
|
@ -757,14 +757,9 @@ static int dnie_transmit_apdu_internal(sc_card_t * card, sc_apdu_t * apdu)
|
|||
index, len);
|
||||
|
||||
/* compose envelope apdu command */
|
||||
sc_format_apdu(card, &e_apdu, apdu->cse, 0xC2, 0x00, 0x00);
|
||||
dnie_format_apdu(card, &e_apdu, apdu->cse, 0xC2, 0x00, 0x00, apdu->le, len,
|
||||
apdu->resp, apdu->resplen, e_tx + index, len);
|
||||
e_apdu.cla = 0x90; /* propietary CLA */
|
||||
e_apdu.data = e_tx + index;
|
||||
e_apdu.lc = len;
|
||||
e_apdu.datalen = len;
|
||||
e_apdu.le = apdu->le;
|
||||
e_apdu.resp = apdu->resp;
|
||||
e_apdu.resplen = apdu->resplen;
|
||||
/* if SM is ON, ensure resp exists, and force getResponse() */
|
||||
if (provider->status.session.state == CWA_SM_ACTIVE) {
|
||||
/* set up proper apdu type */
|
||||
|
@ -915,5 +910,33 @@ int dnie_transmit_apdu(sc_card_t * card, sc_apdu_t * apdu)
|
|||
return sc_transmit_apdu(card, apdu);
|
||||
}
|
||||
|
||||
void dnie_format_apdu(sc_card_t *card, sc_apdu_t *apdu,
|
||||
int cse, int ins, int p1, int p2, int le, int lc,
|
||||
unsigned char * resp, size_t resplen,
|
||||
const unsigned char * data, size_t datalen)
|
||||
{
|
||||
sc_format_apdu(card, apdu, cse, ins, p1, p2);
|
||||
apdu->le = le;
|
||||
apdu->lc = lc;
|
||||
if (resp != NULL) {
|
||||
apdu->resp = resp;
|
||||
apdu->resplen = resplen;
|
||||
}
|
||||
if (data != NULL) {
|
||||
apdu->data = data;
|
||||
apdu->datalen = datalen;
|
||||
}
|
||||
}
|
||||
|
||||
void dnie_free_apdu_buffers(sc_apdu_t *apdu,
|
||||
unsigned char * resp, size_t resplen)
|
||||
{
|
||||
if (apdu->resp != resp) {
|
||||
free(apdu->resp);
|
||||
apdu->resp = resp;
|
||||
apdu->resplen = resplen;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* HAVE_OPENSSL */
|
||||
/* _ end of cwa-dnie.c - */
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
#ifdef ENABLE_OPENSSL
|
||||
|
||||
#include "libopensc/opensc.h"
|
||||
#include "cwa14890.h"
|
||||
|
||||
#ifdef ENABLE_DNIE_UI
|
||||
/**
|
||||
|
@ -38,6 +37,8 @@ typedef struct ui_context {
|
|||
} ui_context_t;
|
||||
#endif
|
||||
|
||||
struct cwa_provider_st;
|
||||
|
||||
/**
|
||||
* OpenDNIe private data declaration
|
||||
*
|
||||
|
@ -48,7 +49,7 @@ typedef struct ui_context {
|
|||
int rsa_key_ref; /**< Key id reference being used in sec operation */
|
||||
u8 *cache; /**< Cache buffer for read_binary() operation */
|
||||
size_t cachelen; /**< length of cache buffer */
|
||||
cwa_provider_t *cwa_provider;
|
||||
struct cwa_provider_st *cwa_provider;
|
||||
#ifdef ENABLE_DNIE_UI
|
||||
struct ui_context ui_ctx;
|
||||
#endif
|
||||
|
@ -62,6 +63,14 @@ typedef struct ui_context {
|
|||
|
||||
int dnie_transmit_apdu(sc_card_t * card, sc_apdu_t * apdu);
|
||||
|
||||
void dnie_format_apdu(sc_card_t *card, sc_apdu_t *apdu,
|
||||
int cse, int ins, int p1, int p2, int le, int lc,
|
||||
unsigned char * resp, size_t resplen,
|
||||
const unsigned char * data, size_t datalen);
|
||||
|
||||
void dnie_free_apdu_buffers(sc_apdu_t *apdu,
|
||||
unsigned char * resp, size_t resplen);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -443,13 +443,8 @@ static int cwa_verify_cvc_certificate(sc_card_t * card,
|
|||
LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
|
||||
|
||||
/* compose apdu for Perform Security Operation (Verify cert) cmd */
|
||||
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x2A, 0x00, 0xAE);
|
||||
apdu.data = cert;
|
||||
apdu.datalen = len;
|
||||
apdu.lc = len;
|
||||
apdu.le = 0;
|
||||
apdu.resplen = 0;
|
||||
apdu.resp = NULL;
|
||||
dnie_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x2A, 0x00, 0xAE, 0, len,
|
||||
NULL, 0, cert, len);
|
||||
|
||||
/* send composed apdu and parse result */
|
||||
result = dnie_transmit_apdu(card, &apdu);
|
||||
|
@ -488,13 +483,8 @@ static int cwa_set_security_env(sc_card_t * card,
|
|||
LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
|
||||
|
||||
/* compose apdu for Manage Security Environment cmd */
|
||||
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, p1, p2);
|
||||
apdu.data = buffer;
|
||||
apdu.datalen = length;
|
||||
apdu.lc = length;
|
||||
apdu.resp = NULL;
|
||||
apdu.resplen = 0;
|
||||
apdu.le = 0;
|
||||
dnie_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, p1, p2, 0, length,
|
||||
NULL, 0, buffer, length);
|
||||
|
||||
/* send composed apdu and parse result */
|
||||
result = dnie_transmit_apdu(card, &apdu);
|
||||
|
@ -531,13 +521,8 @@ static int cwa_internal_auth(sc_card_t * card,
|
|||
LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
|
||||
|
||||
/* compose apdu for Internal Authenticate cmd */
|
||||
sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x88, 0x00, 0x00);
|
||||
apdu.data = data;
|
||||
apdu.datalen = datalen;
|
||||
apdu.lc = datalen;
|
||||
apdu.le = 0x80; /* expected 1024 bits response */
|
||||
apdu.resp = rbuf;
|
||||
apdu.resplen = sizeof(rbuf);
|
||||
dnie_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x88, 0x00, 0x00, 0x80, datalen,
|
||||
rbuf, sizeof(rbuf), data, datalen);
|
||||
|
||||
/* send composed apdu and parse result */
|
||||
result = dnie_transmit_apdu(card, &apdu);
|
||||
|
@ -740,13 +725,8 @@ static int cwa_external_auth(sc_card_t * card, cwa_sm_status_t * sm)
|
|||
LOG_FUNC_CALLED(ctx);
|
||||
|
||||
/* compose apdu for External Authenticate cmd */
|
||||
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x82, 0x00, 0x00);
|
||||
apdu.data = sm->sig;
|
||||
apdu.datalen = sizeof(sm->sig);
|
||||
apdu.lc = sizeof(sm->sig);
|
||||
apdu.le = 0;
|
||||
apdu.resp = NULL;
|
||||
apdu.resplen = 0;
|
||||
dnie_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x82, 0x00, 0x00, 0, sizeof(sm->sig),
|
||||
NULL, 0, sm->sig, sizeof(sm->sig));
|
||||
|
||||
/* send composed apdu and parse result */
|
||||
result = dnie_transmit_apdu(card, &apdu);
|
||||
|
@ -1048,13 +1028,13 @@ static int cwa_verify_internal_auth(sc_card_t * card,
|
|||
int cwa_create_secure_channel(sc_card_t * card,
|
||||
cwa_provider_t * provider, int flag)
|
||||
{
|
||||
u8 *cert;
|
||||
u8 *cert = NULL;
|
||||
size_t certlen;
|
||||
|
||||
int res = SC_SUCCESS;
|
||||
char *msg = "Success";
|
||||
|
||||
u8 *sn_icc;
|
||||
u8 *sn_icc = NULL;
|
||||
|
||||
/* data to get and parse certificates */
|
||||
X509 *icc_cert = NULL;
|
||||
|
@ -1065,11 +1045,11 @@ int cwa_create_secure_channel(sc_card_t * card,
|
|||
cwa_sm_status_t *sm = NULL;
|
||||
|
||||
/* several buffer and buffer pointers */
|
||||
u8 *buffer;
|
||||
u8 *buffer = NULL;
|
||||
size_t bufferlen;
|
||||
u8 *tlv = NULL; /* buffer to compose TLV messages */
|
||||
size_t tlvlen = 0;
|
||||
u8 *rndbuf=NULL;
|
||||
u8 rndbuf[16]; /* 8 RND.IFD + 8 SN.IFD */
|
||||
|
||||
/* preliminary checks */
|
||||
if (!card || !card->ctx )
|
||||
|
@ -1320,12 +1300,6 @@ int cwa_create_secure_channel(sc_card_t * card,
|
|||
msg = "Cannot get ifd serial number from provider";
|
||||
goto csc_end;
|
||||
}
|
||||
rndbuf = calloc(8 /*RND.IFD */ + 8 /*SN.IFD */ , sizeof(u8));
|
||||
if (!rndbuf) {
|
||||
msg = "Cannot calloc for RND.IFD+SN.IFD";
|
||||
res = SC_ERROR_OUT_OF_MEMORY;
|
||||
goto csc_end;
|
||||
}
|
||||
RAND_bytes(sm->rndifd, 8); /* generate 8 random bytes */
|
||||
memcpy(rndbuf, sm->rndifd, 8); /* insert RND.IFD into rndbuf */
|
||||
memcpy(rndbuf + 8, buffer, 8); /* insert SN.IFD into rndbuf */
|
||||
|
@ -1501,7 +1475,7 @@ int cwa_encode_apdu(sc_card_t * card,
|
|||
/* trace APDU before encoding process */
|
||||
cwa_trace_apdu(card, from, 0);
|
||||
|
||||
/* reserve enougth space for apdulen+tlv bytes
|
||||
/* reserve enough space for apdulen+tlv bytes
|
||||
* to-be-crypted buffer and result apdu buffer */
|
||||
/* TODO DEE add 4 more bytes for testing.... */
|
||||
apdubuf =
|
||||
|
|
Loading…
Reference in New Issue