diff --git a/src/libopensc/card-dnie.c b/src/libopensc/card-dnie.c index f6eaf190..e442cb48 100644 --- a/src/libopensc/card-dnie.c +++ b/src/libopensc/card-dnie.c @@ -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 diff --git a/src/libopensc/cwa-dnie.c b/src/libopensc/cwa-dnie.c index 2ade71f3..6cabcd3f 100644 --- a/src/libopensc/cwa-dnie.c +++ b/src/libopensc/cwa-dnie.c @@ -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 - */ diff --git a/src/libopensc/cwa-dnie.h b/src/libopensc/cwa-dnie.h index 8c0f2081..ffd16d74 100644 --- a/src/libopensc/cwa-dnie.h +++ b/src/libopensc/cwa-dnie.h @@ -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 diff --git a/src/libopensc/cwa14890.c b/src/libopensc/cwa14890.c index c4d3f78a..9d3e1a86 100644 --- a/src/libopensc/cwa14890.c +++ b/src/libopensc/cwa14890.c @@ -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 =