From 20b1d829b9ebe0fa28357843ac407026c4b39747 Mon Sep 17 00:00:00 2001 From: rmartinc Date: Fri, 13 Apr 2018 15:04:41 +0200 Subject: [PATCH] Always allocate resp buffer in DNIe. --- src/libopensc/card-dnie.c | 20 ++++++++++++++------ src/libopensc/cwa14890.c | 8 +++----- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/libopensc/card-dnie.c b/src/libopensc/card-dnie.c index cefe0788..542e4610 100644 --- a/src/libopensc/card-dnie.c +++ b/src/libopensc/card-dnie.c @@ -760,15 +760,23 @@ static int dnie_sm_free_wrapped_apdu(struct sc_card *card, if ((*sm_apdu) != plain) { rv = cwa_decode_response(card, provider, *sm_apdu); - if (plain) { - plain->resplen = (*sm_apdu)->resplen; + if (plain && rv == SC_SUCCESS) { + if (plain->resp) { + /* copy the response into the original resp buffer */ + if ((*sm_apdu)->resplen <= plain->resplen) { + memcpy(plain->resp, (*sm_apdu)->resp, (*sm_apdu)->resplen); + plain->resplen = (*sm_apdu)->resplen; + } else { + sc_log(card->ctx, "Invalid initial length, needed %lu bytes but has %lu", + (*sm_apdu)->resplen, plain->resplen); + rv = SC_ERROR_BUFFER_TOO_SMALL; + } + } 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((unsigned char *) (*sm_apdu)->data); + free((*sm_apdu)->resp); free(*sm_apdu); } *sm_apdu = NULL; diff --git a/src/libopensc/cwa14890.c b/src/libopensc/cwa14890.c index 873af564..a8b0664d 100644 --- a/src/libopensc/cwa14890.c +++ b/src/libopensc/cwa14890.c @@ -1431,11 +1431,9 @@ int cwa_encode_apdu(sc_card_t * card, sizeof(u8)); ccbuf = calloc(MAX(SC_MAX_APDU_BUFFER_SIZE, 20 + from->datalen), sizeof(u8)); - 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; - } + /* always create a new 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;