Add dnie_free_apdu_buffers into dnie_sm_free_wrapped_apdu.

This commit is contained in:
rickyepoderi 2017-04-15 17:09:55 +02:00 committed by Frank Morgner
parent 74f11a32a5
commit ac091b7466
4 changed files with 27 additions and 65 deletions

View File

@ -658,7 +658,6 @@ static int dnie_get_serialnr(sc_card_t * card, sc_serial_number_t * serial)
/* send apdu */
result = sc_transmit_apdu(card, &apdu);
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)
@ -676,7 +675,6 @@ 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);
}
@ -761,17 +759,17 @@ static int dnie_sm_free_wrapped_apdu(struct sc_card *card,
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
if ((*sm_apdu) != plain) {
rv = cwa_decode_response(card, provider, *sm_apdu);
if (plain) {
plain->resp = (*sm_apdu)->resp;
plain->resplen = (*sm_apdu)->resplen;
plain->sw1 = (*sm_apdu)->sw1;
plain->sw2 = (*sm_apdu)->sw2;
if (((*sm_apdu)->data) != plain->data)
free((unsigned char *) (*sm_apdu)->data);
if ((*sm_apdu)->resp != plain->resp)
free((*sm_apdu)->resp);
}
free(*sm_apdu);
rv = cwa_decode_response(card, provider, plain);
}
*sm_apdu = NULL;
@ -1179,8 +1177,7 @@ static int dnie_compose_and_send_apdu(sc_card_t *card, const u8 *path, size_t pa
res = sc_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");
LOG_TEST_RET(ctx, res, "SelectFile() APDU transmit failed");
if (file_out == NULL) {
if (apdu.sw1 == 0x61)
SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, 0);
@ -1191,24 +1188,20 @@ 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);
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) {
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]);
sc_file_free(*file_out);
*file_out = file;
dnie_free_apdu_buffers(&apdu, rbuf, sizeof(rbuf));
LOG_FUNC_RETURN(ctx, res);
}
@ -1384,16 +1377,13 @@ static int dnie_get_challenge(struct sc_card *card, u8 * rnd, size_t len)
apdu.resplen = MAX_RESP_BUFFER_SIZE; /* include SW's */
result = sc_transmit_apdu(card, &apdu);
if (result != SC_SUCCESS) {
dnie_free_apdu_buffers(&apdu, buf, MAX_RESP_BUFFER_SIZE);
LOG_TEST_RET(card->ctx, result, "APDU transmit failed");
}
if (apdu.resplen != BUFFER_SIZE) {
result = sc_check_sw(card, apdu.sw1, apdu.sw2);
dnie_free_apdu_buffers(&apdu, buf, MAX_RESP_BUFFER_SIZE);
goto dnie_get_challenge_error;
}
memcpy(rnd, apdu.resp, n);
dnie_free_apdu_buffers(&apdu, buf, MAX_RESP_BUFFER_SIZE);
len -= n;
rnd += n;
}
@ -1551,7 +1541,6 @@ static int dnie_set_security_env(struct sc_card *card,
/* send composed apdu and parse result */
result = sc_transmit_apdu(card, &apdu);
dnie_free_apdu_buffers(&apdu, rbuf, MAX_RESP_BUFFER_SIZE);
LOG_TEST_RET(card->ctx, result, "Set Security Environment failed");
result = sc_check_sw(card, apdu.sw1, apdu.sw2);
@ -1701,13 +1690,11 @@ static int dnie_compute_signature(struct sc_card *card,
/* tell card to compute signature */
result = sc_transmit_apdu(card, &apdu);
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);
if (result != SC_SUCCESS) {
dnie_free_apdu_buffers(&apdu, rbuf, sizeof(rbuf));
LOG_TEST_RET(card->ctx, result, "compute_signature() response error");
}
@ -1715,7 +1702,6 @@ static int dnie_compute_signature(struct sc_card *card,
result_resplen = apdu.resplen;
memcpy(out, apdu.resp, result_resplen);
/* and return response length */
dnie_free_apdu_buffers(&apdu, rbuf, sizeof(rbuf));
LOG_FUNC_RETURN(card->ctx, result_resplen);
}
@ -1775,7 +1761,6 @@ 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 = sc_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);
@ -1928,7 +1913,6 @@ static int dnie_read_header(struct sc_card *card)
/* transmit apdu */
r = sc_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);
}
@ -1943,12 +1927,10 @@ 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;
}
@ -2175,7 +2157,6 @@ static int dnie_pin_verify(struct sc_card *card,
sc_apdu_t apdu;
u8 pinbuffer[SC_MAX_APDU_BUFFER_SIZE];
u8 resp[MAX_RESP_BUFFER_SIZE];
int pinlen = 0;
int padding = 0;
@ -2200,13 +2181,12 @@ static int dnie_pin_verify(struct sc_card *card,
pinlen = res;
/* compose apdu */
dnie_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x20, 0x00, 0x00, 255, pinlen,
resp, MAX_RESP_BUFFER_SIZE, pinbuffer, pinlen);
dnie_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x20, 0x00, 0x00, 0, pinlen,
NULL, 0, pinbuffer, pinlen);
/* and send to card throught virtual channel */
res = sc_transmit_apdu(card, &apdu);
if (res != SC_SUCCESS) {
dnie_free_apdu_buffers(&apdu, resp, MAX_RESP_BUFFER_SIZE);
LOG_TEST_RET(card->ctx, res, "VERIFY APDU Transmit fail");
}
@ -2214,16 +2194,11 @@ static int dnie_pin_verify(struct sc_card *card,
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, resp, MAX_RESP_BUFFER_SIZE);
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 */
dnie_free_apdu_buffers(&apdu, resp, MAX_RESP_BUFFER_SIZE);
data->apdu = NULL;
/* ensure that secure channel is established after a PIN channel in 3.0 */
if (card->atr.value[15] >= DNIE_30_VERSION) {
sc_log(card->ctx, "DNIe 3.0 detected => re-establish secure channel");

View File

@ -913,15 +913,5 @@ void dnie_format_apdu(sc_card_t *card, sc_apdu_t *apdu,
}
}
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

@ -75,9 +75,6 @@ void dnie_format_apdu(sc_card_t *card, sc_apdu_t *apdu,
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

@ -435,7 +435,6 @@ static int cwa_verify_cvc_certificate(sc_card_t * card,
sc_apdu_t apdu;
int result = SC_SUCCESS;
sc_context_t *ctx = NULL;
u8 resp[MAX_RESP_BUFFER_SIZE];
/* safety check */
if (!card || !card->ctx)
@ -446,8 +445,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 */
dnie_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x00, 0xAE, 255, len,
resp, MAX_RESP_BUFFER_SIZE, cert, len);
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 = sc_transmit_apdu(card, &apdu);
@ -476,7 +475,6 @@ static int cwa_set_security_env(sc_card_t * card,
sc_apdu_t apdu;
int result = SC_SUCCESS;
sc_context_t *ctx = NULL;
u8 resp[MAX_RESP_BUFFER_SIZE];
/* safety check */
if (!card || !card->ctx)
@ -487,8 +485,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 */
dnie_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x22, p1, p2, 255, length,
resp, MAX_RESP_BUFFER_SIZE, buffer, length);
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 = sc_transmit_apdu(card, &apdu);
@ -726,7 +724,6 @@ static int cwa_external_auth(sc_card_t * card, u8 * sig, size_t sig_len)
sc_apdu_t apdu;
int result = SC_SUCCESS;
sc_context_t *ctx = NULL;
u8 resp[MAX_RESP_BUFFER_SIZE];
/* safety check */
if (!card || !card->ctx)
@ -735,8 +732,8 @@ static int cwa_external_auth(sc_card_t * card, u8 * sig, size_t sig_len)
LOG_FUNC_CALLED(ctx);
/* compose apdu for External Authenticate cmd */
dnie_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x82, 0x00, 0x00, 255, sig_len,
resp, MAX_RESP_BUFFER_SIZE, sig, sig_len);
dnie_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x82, 0x00, 0x00, 0, sig_len,
NULL, 0, sig, sig_len);
/* send composed apdu and parse result */
result = sc_transmit_apdu(card, &apdu);
@ -1467,13 +1464,16 @@ int cwa_encode_apdu(sc_card_t * card,
/* reserve enough space for apdulen+tlv bytes
* to-be-crypted buffer and result apdu buffer */
/* TODO DEE add 4 more bytes for testing.... */
apdubuf =
calloc(MAX(SC_MAX_APDU_BUFFER_SIZE, 20 + from->datalen),
apdubuf = calloc(MAX(SC_MAX_APDU_BUFFER_SIZE, 20 + from->datalen),
sizeof(u8));
ccbuf =
calloc(MAX(SC_MAX_APDU_BUFFER_SIZE, 20 + from->datalen),
ccbuf = calloc(MAX(SC_MAX_APDU_BUFFER_SIZE, 20 + from->datalen),
sizeof(u8));
if (!apdubuf || !ccbuf) {
if (!to->resp) {
/* if no response create a buffer for the encoded response */
to->resp = calloc(MAX_RESP_BUFFER_SIZE, sizeof(u8));
to->resplen = MAX_RESP_BUFFER_SIZE;
}
if (!apdubuf || !ccbuf || (!from->resp && !to->resp)) {
res = SC_ERROR_OUT_OF_MEMORY;
goto err;
}
@ -1485,6 +1485,8 @@ int cwa_encode_apdu(sc_card_t * card,
to->p1 = from->p1;
to->p2 = from->p2;
to->le = from->le;
if (!to->le)
to->le = 255;
to->lc = 0; /* to be evaluated */
/* fill buffer with header info */
*(ccbuf + cclen++) = to->cla;
@ -1591,6 +1593,8 @@ err:
encode_end:
if (apdubuf)
free(apdubuf);
if (from->resp != to->resp)
free(to->resp);
encode_end_apdu_valid:
if (msg)
sc_log(ctx, "%s", msg);
@ -1784,13 +1788,9 @@ int cwa_decode_response(sc_card_t * card,
/* allocate response buffer */
resplen = 10 + MAX(p_tlv->len, e_tlv->len); /* estimate response buflen */
if (apdu->resplen < resplen) {
free(apdu->resp);
apdu->resp = calloc(resplen, sizeof(u8));
if (!apdu->resp) {
msg = "Cannot allocate buffer to store response";
res = SC_ERROR_OUT_OF_MEMORY;
goto response_decode_end;
}
msg = "Cannot allocate buffer to store response";
res = SC_ERROR_BUFFER_TOO_SMALL;
goto response_decode_end;
}
apdu->resplen = resplen;