Removing all memory leaks in DNIe but one. Refactoring pending.

This commit is contained in:
German Blanco 2015-11-27 11:32:33 +01:00
parent a454dd7fc9
commit d1a1830115
4 changed files with 150 additions and 147 deletions

View File

@ -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

View File

@ -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 - */

View File

@ -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

View File

@ -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 =