fixed various memory leaks and potential segfaults
git-svn-id: https://vsmartcard.svn.sourceforge.net/svnroot/vsmartcard@70 96b47cad-a561-4643-ad3b-153ac7d7599c
This commit is contained in:
@@ -29,7 +29,6 @@
|
|||||||
#include "ccid.h"
|
#include "ccid.h"
|
||||||
#include "pace.h"
|
#include "pace.h"
|
||||||
|
|
||||||
//static const char *app_name = "ccid";
|
|
||||||
static sc_context_t *ctx = NULL;
|
static sc_context_t *ctx = NULL;
|
||||||
static sc_card_t *card_in_slot[SC_MAX_SLOTS];
|
static sc_card_t *card_in_slot[SC_MAX_SLOTS];
|
||||||
static sc_reader_t *reader;
|
static sc_reader_t *reader;
|
||||||
@@ -118,7 +117,11 @@ int ccid_initialize(int reader_id, int verbose)
|
|||||||
{
|
{
|
||||||
unsigned int i, reader_count;
|
unsigned int i, reader_count;
|
||||||
|
|
||||||
SC_TEST_RET(ctx, sc_context_create(&ctx, NULL), "Failed to create initial context.");
|
int r = sc_context_create(&ctx, NULL);
|
||||||
|
if (r < 0) {
|
||||||
|
printf("Failed to create initial context: %s", sc_strerror(r));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
ctx->debug = verbose;
|
ctx->debug = verbose;
|
||||||
|
|
||||||
|
|||||||
66
ccid/pace.c
66
ccid/pace.c
@@ -201,24 +201,34 @@ static int get_ef_card_access(sc_card_t *card,
|
|||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
sc_path_t path;
|
sc_path_t path;
|
||||||
sc_file_t *file;
|
sc_file_t *file = NULL;
|
||||||
__u8 *p;
|
__u8 *p;
|
||||||
|
|
||||||
memset(&path, 0, sizeof path);
|
memset(&path, 0, sizeof path);
|
||||||
SC_TEST_RET(card->ctx, sc_append_file_id(&path, FID_EF_CARDACCESS),
|
r = sc_append_file_id(&path, FID_EF_CARDACCESS);
|
||||||
"Could not create path object.");
|
if (r < 0) {
|
||||||
SC_TEST_RET(card->ctx, sc_concatenate_path(&path, sc_get_mf_path(), &path),
|
sc_error(card->ctx, "Could not create path object.");
|
||||||
"Could not create path object.");
|
goto err;
|
||||||
|
}
|
||||||
|
r = sc_concatenate_path(&path, sc_get_mf_path(), &path);
|
||||||
|
if (r < 0) {
|
||||||
|
sc_error(card->ctx, "Could not create path object.");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = sc_select_file(card, &path, &file);
|
||||||
|
if (r < 0) {
|
||||||
|
sc_error(card->ctx, "Could not select EF.CardAccess.");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
memset(&file, 0, sizeof file);
|
|
||||||
SC_TEST_RET(card->ctx, sc_select_file(card, &path, &file),
|
|
||||||
"Could not select EF.CardAccess.");
|
|
||||||
*length_ef_cardaccess = 0;
|
*length_ef_cardaccess = 0;
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
p = realloc(*ef_cardaccess, *length_ef_cardaccess + maxresp);
|
p = realloc(*ef_cardaccess, *length_ef_cardaccess + maxresp);
|
||||||
if (!p)
|
if (!p) {
|
||||||
SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, SC_ERROR_OUT_OF_MEMORY);
|
r = SC_ERROR_OUT_OF_MEMORY;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
*ef_cardaccess = p;
|
*ef_cardaccess = p;
|
||||||
|
|
||||||
r = sc_read_binary(card, *length_ef_cardaccess,
|
r = sc_read_binary(card, *length_ef_cardaccess,
|
||||||
@@ -229,17 +239,29 @@ static int get_ef_card_access(sc_card_t *card,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
SC_TEST_RET(card->ctx, r, "Could not read EF.CardAccess.");
|
if (r < 0) {
|
||||||
|
sc_error(card->ctx, "Could not read EF.CardAccess.");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
*length_ef_cardaccess += r;
|
*length_ef_cardaccess += r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* test cards only return an empty FCI template,
|
/* test cards only return an empty FCI template,
|
||||||
* so we can't determine any file proberties */
|
* so we can't determine any file proberties */
|
||||||
if (*length_ef_cardaccess < file->size)
|
if (*length_ef_cardaccess < file->size) {
|
||||||
SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, SC_ERROR_FILE_TOO_SMALL);
|
r = SC_ERROR_FILE_TOO_SMALL;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, SC_SUCCESS);
|
r = SC_SUCCESS;
|
||||||
|
|
||||||
|
err:
|
||||||
|
if (file) {
|
||||||
|
free(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pace_mse_set_at(sc_card_t *card,
|
static int pace_mse_set_at(sc_card_t *card,
|
||||||
@@ -324,6 +346,8 @@ static int pace_mse_set_at(sc_card_t *card,
|
|||||||
}
|
}
|
||||||
|
|
||||||
err:
|
err:
|
||||||
|
if (apdu.resp)
|
||||||
|
free(apdu.resp);
|
||||||
if (data) {
|
if (data) {
|
||||||
// XXX
|
// XXX
|
||||||
//if (data->cryptographic_mechanism_reference)
|
//if (data->cryptographic_mechanism_reference)
|
||||||
@@ -336,8 +360,6 @@ err:
|
|||||||
}
|
}
|
||||||
if (d)
|
if (d)
|
||||||
free(d);
|
free(d);
|
||||||
if (apdu.resplen)
|
|
||||||
free(apdu.resp);
|
|
||||||
|
|
||||||
SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, r);
|
SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, r);
|
||||||
}
|
}
|
||||||
@@ -523,9 +545,9 @@ err:
|
|||||||
ASN1_OCTET_STRING_free(r_data->auth_token);*/
|
ASN1_OCTET_STRING_free(r_data->auth_token);*/
|
||||||
PACE_GEN_AUTH_R_free(r_data);
|
PACE_GEN_AUTH_R_free(r_data);
|
||||||
}
|
}
|
||||||
// XXX
|
/* XXX */
|
||||||
//if (apdu.resplen)
|
/*if (apdu.resp)*/
|
||||||
//free(apdu.resp);
|
/*free(apdu.resp);*/
|
||||||
|
|
||||||
SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, r);
|
SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, r);
|
||||||
}
|
}
|
||||||
@@ -753,6 +775,8 @@ int EstablishPACEChannel(sc_card_t *card, const __u8 *in,
|
|||||||
r = reset_ssc(sctx);
|
r = reset_ssc(sctx);
|
||||||
|
|
||||||
err:
|
err:
|
||||||
|
if (ef_cardaccess)
|
||||||
|
free(ef_cardaccess);
|
||||||
if (info)
|
if (info)
|
||||||
PACEInfo_free(info);
|
PACEInfo_free(info);
|
||||||
if (static_dp)
|
if (static_dp)
|
||||||
@@ -965,6 +989,8 @@ update_iv(struct sm_ctx *ctx)
|
|||||||
r = SC_SUCCESS;
|
r = SC_SUCCESS;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
|
if (ssc)
|
||||||
|
free(ssc);
|
||||||
if (sscbuf)
|
if (sscbuf)
|
||||||
BUF_MEM_free(sscbuf);
|
BUF_MEM_free(sscbuf);
|
||||||
if (ivbuf)
|
if (ivbuf)
|
||||||
|
|||||||
37
ccid/sm.c
37
ccid/sm.c
@@ -177,7 +177,7 @@ static int prefix_buf(u8 prefix, u8 *buf, size_t buflen, u8 **cat)
|
|||||||
return SC_ERROR_OUT_OF_MEMORY;
|
return SC_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
if (*cat == buf) {
|
if (*cat == buf) {
|
||||||
memmove(p + 1, buf, buflen);
|
memmove(p + 1, p, buflen);
|
||||||
} else {
|
} else {
|
||||||
memcpy(p + 1, buf, buflen);
|
memcpy(p + 1, buf, buflen);
|
||||||
}
|
}
|
||||||
@@ -420,7 +420,12 @@ static int sm_encrypt(const struct sm_ctx *ctx, sc_card_t *card,
|
|||||||
r = sc_asn1_encode(card->ctx, sm_capdu, (u8 **) &sm_data, &sm_data_len);
|
r = sc_asn1_encode(card->ctx, sm_capdu, (u8 **) &sm_data, &sm_data_len);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto err;
|
goto err;
|
||||||
sm_apdu->data = sm_data;
|
if (sm_apdu->datalen < sm_data_len) {
|
||||||
|
sc_error(card->ctx, "Data for SM APDU too long");
|
||||||
|
r = SC_ERROR_OUT_OF_MEMORY;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
memcpy((u8 *) sm_apdu->data, sm_data, sm_data_len);
|
||||||
sm_apdu->datalen = sm_data_len;
|
sm_apdu->datalen = sm_data_len;
|
||||||
sm_apdu->lc = sm_apdu->datalen;
|
sm_apdu->lc = sm_apdu->datalen;
|
||||||
sm_apdu->le = 0;
|
sm_apdu->le = 0;
|
||||||
@@ -428,21 +433,18 @@ static int sm_encrypt(const struct sm_ctx *ctx, sc_card_t *card,
|
|||||||
bin_log(card->ctx, "ASN.1 encoded APDU data", sm_apdu->data, sm_apdu->datalen);
|
bin_log(card->ctx, "ASN.1 encoded APDU data", sm_apdu->data, sm_apdu->datalen);
|
||||||
|
|
||||||
err:
|
err:
|
||||||
if (fdata) {
|
if (fdata)
|
||||||
free(fdata);
|
free(fdata);
|
||||||
}
|
if (asn1)
|
||||||
if (asn1) {
|
|
||||||
free(asn1);
|
free(asn1);
|
||||||
}
|
if (mac_data)
|
||||||
if (mac_data) {
|
|
||||||
free(mac_data);
|
free(mac_data);
|
||||||
}
|
if (mac)
|
||||||
if (mac) {
|
|
||||||
free(mac);
|
free(mac);
|
||||||
}
|
if (le)
|
||||||
if (le) {
|
|
||||||
free(le);
|
free(le);
|
||||||
}
|
if (sm_data)
|
||||||
|
free(sm_data);
|
||||||
|
|
||||||
SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_ERROR, r);
|
SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_ERROR, r);
|
||||||
}
|
}
|
||||||
@@ -538,16 +540,17 @@ int sm_transmit_apdu(const struct sm_ctx *sctx, sc_card_t *card,
|
|||||||
sc_apdu_t *apdu)
|
sc_apdu_t *apdu)
|
||||||
{
|
{
|
||||||
sc_apdu_t sm_apdu;
|
sc_apdu_t sm_apdu;
|
||||||
u8 buf[SC_MAX_APDU_BUFFER_SIZE - 2];
|
u8 rbuf[SC_MAX_APDU_BUFFER_SIZE - 2], sbuf[SC_MAX_APDU_BUFFER_SIZE - 4];
|
||||||
|
|
||||||
|
sm_apdu.data = sbuf;
|
||||||
|
sm_apdu.datalen = sizeof sbuf;
|
||||||
|
sm_apdu.resp = rbuf;
|
||||||
|
sm_apdu.resplen = sizeof rbuf;
|
||||||
|
|
||||||
SC_TEST_RET(card->ctx, sm_encrypt(sctx, card, apdu, &sm_apdu),
|
SC_TEST_RET(card->ctx, sm_encrypt(sctx, card, apdu, &sm_apdu),
|
||||||
"Could not encrypt APDU.");
|
"Could not encrypt APDU.");
|
||||||
|
|
||||||
sm_apdu.resplen = sizeof *buf;
|
|
||||||
sm_apdu.resp = buf;
|
|
||||||
SC_TEST_RET(card->ctx, my_transmit_apdu(card, &sm_apdu),
|
SC_TEST_RET(card->ctx, my_transmit_apdu(card, &sm_apdu),
|
||||||
"Could not send SM APDU.");
|
"Could not send SM APDU.");
|
||||||
|
|
||||||
SC_TEST_RET(card->ctx, sc_check_sw(card, sm_apdu.sw1, sm_apdu.sw2),
|
SC_TEST_RET(card->ctx, sc_check_sw(card, sm_apdu.sw1, sm_apdu.sw2),
|
||||||
"Card returned error.");
|
"Card returned error.");
|
||||||
SC_TEST_RET(card->ctx, sm_decrypt(sctx, card, &sm_apdu, apdu),
|
SC_TEST_RET(card->ctx, sm_decrypt(sctx, card, &sm_apdu, apdu),
|
||||||
|
|||||||
@@ -1798,7 +1798,9 @@ main (int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (dotest) {
|
if (dotest) {
|
||||||
return ccid_testpace();
|
i = ccid_testpace();
|
||||||
|
ccid_shutdown();
|
||||||
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
fd = init_device ();
|
fd = init_device ();
|
||||||
|
|||||||
Reference in New Issue
Block a user