Merge pull request #452 from frankmorgner/memory-leaks

Fix some memory leaks
This commit is contained in:
Frank Morgner 2015-10-02 15:13:34 +02:00
commit 4f4643ee3e
7 changed files with 96 additions and 60 deletions

View File

@ -402,6 +402,7 @@ static int tcos_select_file(sc_card_t *card,
file = sc_file_new();
if (file == NULL) SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY);
*file_out = file;
file->path = *in_path;
for(i=2; i+1<apdu.resplen && i+1+apdu.resp[i+1]<apdu.resplen; i+=2+apdu.resp[i+1]){
@ -440,7 +441,6 @@ static int tcos_select_file(sc_card_t *card,
}
}
file->magic = SC_FILE_MAGIC;
*file_out = file;
parse_sec_attr(card, file, file->sec_attr, file->sec_attr_len);

View File

@ -1466,17 +1466,21 @@ int cwa_encode_apdu(sc_card_t * card,
/* reserve extra bytes for padding and tlv header */
msgbuf = calloc(12 + from->lc, sizeof(u8)); /* to encrypt apdu data */
cryptbuf = calloc(12 + from->lc, sizeof(u8));
if (!msgbuf || !cryptbuf)
LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
if (!msgbuf || !cryptbuf) {
res = SC_ERROR_OUT_OF_MEMORY;
goto err;
}
/* check if APDU is already encoded */
if ((from->cla & 0x0C) != 0) {
memcpy(to, from, sizeof(sc_apdu_t));
return SC_SUCCESS; /* already encoded */
res = SC_SUCCESS; /* already encoded */
goto encode_end;
}
if (from->ins == 0xC0) {
memcpy(to, from, sizeof(sc_apdu_t));
return SC_SUCCESS; /* dont encode GET Response cmd */
res = SC_SUCCESS; /* dont encode GET Response cmd */
goto encode_end;
}
/* call provider pre-operation method */
@ -1500,8 +1504,10 @@ int cwa_encode_apdu(sc_card_t * card,
ccbuf =
calloc(MAX(SC_MAX_APDU_BUFFER_SIZE, 20 + from->datalen),
sizeof(u8));
if (!apdubuf || !ccbuf)
LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
if (!apdubuf || !ccbuf) {
res = SC_ERROR_OUT_OF_MEMORY;
goto err;
}
/* set up data on destination apdu */
to->cse = SC_APDU_CASE_3_SHORT;
@ -1615,6 +1621,7 @@ int cwa_encode_apdu(sc_card_t * card,
res = SC_SUCCESS;
goto encode_end_apdu_valid;
err:
encode_end:
if (apdubuf)
free(apdubuf);

View File

@ -764,15 +764,14 @@ iasecc_sdo_allocate_and_parse(struct sc_card *card, unsigned char *data, size_t
sdo = calloc(1, sizeof(struct iasecc_sdo));
if (!sdo)
return SC_ERROR_OUT_OF_MEMORY;
*out = sdo;
sdo->sdo_class = *(data + 1) & 0x7F;
sdo->sdo_ref = *(data + 2) & 0x3F;
sc_log(ctx, "sdo_class 0x%X, sdo_ref 0x%X", sdo->sdo_class, sdo->sdo_ref);
if (data_len == 3) {
*out = sdo;
if (data_len == 3)
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
}
size_size = iasecc_parse_size(data + 3, &size);
LOG_TEST_RET(ctx, size_size, "parse error: invalid size data");
@ -795,8 +794,6 @@ iasecc_sdo_allocate_and_parse(struct sc_card *card, unsigned char *data, size_t
sc_log(ctx, "docp.acls_contact.size %i; docp.size.size %i", sdo->docp.acls_contact.size, sdo->docp.size.size);
*out = sdo;
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
}

View File

@ -499,7 +499,7 @@ static int epass2003_pkcs15_generate_key(struct sc_profile *profile,
/* allocate key object */
r = cosm_new_file(profile, card, SC_PKCS15_TYPE_PRKEY_RSA, idx, &file);
SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r,
SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_NORMAL, r,
"create key: failed to allocate new key object");
file->size = keybits;
sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "private key path: %s",
@ -509,13 +509,13 @@ static int epass2003_pkcs15_generate_key(struct sc_profile *profile,
r = sc_pkcs15init_authenticate(profile, p15card, file,
SC_AC_OP_DELETE);
SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r,
SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_NORMAL, r,
"generate key: pkcs15init_authenticate(SC_AC_OP_DELETE) failed");
r = sc_delete_file(p15card->card, &file->path);
/* create */
r = sc_pkcs15init_create_file(profile, p15card, file);
SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r,
SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_NORMAL, r,
"create key: failed to create key file");
sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "index %i; keybits %i\n", idx,
@ -523,33 +523,32 @@ static int epass2003_pkcs15_generate_key(struct sc_profile *profile,
if (keybits < 1024 || keybits > 2048 || (keybits % 0x20)) {
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE_TOOL,
"Unsupported key size %u\n", keybits);
return SC_ERROR_INVALID_ARGUMENTS;
r = SC_ERROR_INVALID_ARGUMENTS;
goto err;
}
path = key_info->path;
path.len -= 2;
r = sc_select_file(card, &path, &tfile);
SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r,
SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_NORMAL, r,
"generate key: no private object DF");
r = sc_pkcs15init_authenticate(profile, p15card, tfile,
SC_AC_OP_CRYPTO);
SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r,
SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_NORMAL, r,
"generate key: pkcs15init_authenticate(SC_AC_OP_CRYPTO) failed");
r = sc_pkcs15init_authenticate(profile, p15card, tfile,
SC_AC_OP_CREATE);
SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r,
SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_NORMAL, r,
"generate key: pkcs15init_authenticate(SC_AC_OP_CREATE) failed");
sc_file_free(tfile);
if ((r = cosm_new_file(profile, card, SC_PKCS15_TYPE_PUBKEY_RSA, idx,
&pukf)) < 0) {
sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,
"generate key: create temporary pukf failed\n");
goto failed;
goto err;
}
pukf->size = keybits;
pukf->id = pukf->path.value[pukf->path.len - 2] * 0x100
@ -565,14 +564,14 @@ static int epass2003_pkcs15_generate_key(struct sc_profile *profile,
if (r == SC_SUCCESS) {
r = sc_pkcs15init_authenticate(profile, p15card, pukf,
SC_AC_OP_DELETE);
SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r,
SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_NORMAL, r,
"generate key - pubkey: pkcs15init_authenticate(SC_AC_OP_DELETE) failed");
r = sc_pkcs15init_delete_by_path(profile, p15card, &pukf->path);
if (r != SC_SUCCESS) {
sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,
"generate key: failed to delete existing key file\n");
goto failed;
goto err;
}
}
/* create */
@ -580,12 +579,12 @@ static int epass2003_pkcs15_generate_key(struct sc_profile *profile,
if (r != SC_SUCCESS) {
sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,
"generate key: pukf create file failed\n");
goto failed;
goto err;
}
r = sc_pkcs15init_authenticate(profile, p15card, pukf,
SC_AC_OP_UPDATE);
SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r,
SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_NORMAL, r,
"generate key - pubkey: pkcs15init_authenticate(SC_AC_OP_UPDATE) failed");
/* generate key pair */
@ -597,7 +596,7 @@ static int epass2003_pkcs15_generate_key(struct sc_profile *profile,
gendat.key_length = keybits;
gendat.modulus = NULL;
r = sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_GENERATE_KEY, &gendat);
SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r,
SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_NORMAL, r,
"generate RSA key pair failed");
/* get the modulus */
@ -611,7 +610,7 @@ static int epass2003_pkcs15_generate_key(struct sc_profile *profile,
buf = (u8 *) malloc(3);
if (!buf) {
r = SC_ERROR_OUT_OF_MEMORY;
goto failed;
goto err;
}
buf[0] = 0x01;
buf[1] = 0x00;
@ -624,9 +623,13 @@ static int epass2003_pkcs15_generate_key(struct sc_profile *profile,
/* free public key */
free(gendat.modulus);
failed:
err:
if (pukf)
sc_file_free(pukf);
if (file)
sc_file_free(file);
if (tfile)
sc_file_free(tfile);
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r);
}

View File

@ -2329,6 +2329,8 @@ sc_pkcs15init_select_intrinsic_id(struct sc_pkcs15_card *p15card, struct sc_prof
break;
default:
sc_log(ctx, "Unsupported ID style: %i", id_style);
if (allocated)
sc_pkcs15_free_pubkey(pubkey);
LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Non supported ID style");
}
@ -3407,6 +3409,7 @@ sc_pkcs15init_authenticate(struct sc_profile *profile, struct sc_pkcs15_card *p1
int r = 0;
LOG_FUNC_CALLED(ctx);
assert(file != NULL);
sc_log(ctx, "path '%s', op=%u", sc_print_path(&file->path), op);
if (p15card->card->caps & SC_CARD_CAP_USE_FCI_AC) {

View File

@ -76,15 +76,21 @@ cosm_write_tokeninfo (struct sc_pkcs15_card *p15card, struct sc_profile *profile
SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "cosm_write_tokeninfo() label '%s'; flags 0x%X", label, flags);
if (sc_profile_get_file(profile, COSM_TITLE"-token-info", &file))
SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INCONSISTENT_PROFILE, "Cannot find "COSM_TITLE"-token-info");
if (sc_profile_get_file(profile, COSM_TITLE"-token-info", &file)) {
rv = SC_ERROR_INCONSISTENT_PROFILE;
SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "Cannot find "COSM_TITLE"-token-info");
}
if (file->size < 16)
SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INCONSISTENT_PROFILE, "Unsufficient size of the "COSM_TITLE"-token-info file");
if (file->size < 16) {
rv = SC_ERROR_INCONSISTENT_PROFILE;
SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "Unsufficient size of the "COSM_TITLE"-token-info file");
}
buffer = calloc(1, file->size);
if (!buffer)
SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY, "Allocation error in cosm_write_tokeninfo()");
if (!buffer) {
rv = SC_ERROR_OUT_OF_MEMORY;
SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "Allocation error in cosm_write_tokeninfo()");
}
if (label)
strncpy(buffer, label, file->size - 4);
@ -109,6 +115,9 @@ cosm_write_tokeninfo (struct sc_pkcs15_card *p15card, struct sc_profile *profile
if (rv > 0)
rv = 0;
err:
if (file)
sc_file_free(file);
free(buffer);
SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, rv);
}
@ -574,6 +583,8 @@ cosm_get_temporary_public_key_file(struct sc_card *card,
rv = sc_file_add_acl_entry(file, SC_AC_OP_PSO_VERIFY_SIGNATURE, SC_AC_NONE, 0);
if (!rv)
rv = sc_file_add_acl_entry(file, SC_AC_OP_EXTERNAL_AUTHENTICATE, SC_AC_NONE, 0);
if (rv < 0)
sc_file_free(file);
SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Failed to add ACL entry to the temporary public key file");
*pubkey_file = file;
@ -696,18 +707,20 @@ cosm_create_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
rv = sc_select_file(p15card->card, &file->path, NULL);
if (rv == 0) {
rv = cosm_delete_file(p15card, profile, file);
SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Failed to delete private key file");
SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "Failed to delete private key file");
}
else if (rv != SC_ERROR_FILE_NOT_FOUND) {
SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Select private key file error");
SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "Select private key file error");
}
rv = sc_pkcs15init_create_file(profile, p15card, file);
SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Failed to create private key file");
SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "Failed to create private key file");
key_info->key_reference = file->path.value[file->path.len - 1];
sc_file_free(file);
err:
if (file)
sc_file_free(file);
SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, rv);
}
@ -808,8 +821,10 @@ cosm_emu_update_tokeninfo(struct sc_profile *profile, struct sc_pkcs15_card *p15
SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INCONSISTENT_PROFILE, "cannot find "COSM_TITLE"-token-info");
buf = calloc(1, file->size);
if (!buf)
if (!buf) {
sc_file_free(file);
SC_FUNC_RETURN(ctx, 1, SC_ERROR_OUT_OF_MEMORY);
}
label_len = strlen(tinfo->label) > (file->size - 4) ? (file->size - 4) : strlen(tinfo->label);
memcpy(buf, tinfo->label, label_len);
@ -830,6 +845,7 @@ cosm_emu_update_tokeninfo(struct sc_profile *profile, struct sc_pkcs15_card *p15
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Update token info (label:'%s',flags:%X,p15card->flags:%X)", buf, flags, p15card->flags);
rv = sc_pkcs15init_update_file(profile, p15card, file, buf, file->size);
free(buf);
sc_file_free(file);
if (rv > 0)
rv = 0;

View File

@ -104,41 +104,41 @@ static EVP_PKEY * evpkey = NULL;
static int load_object(const char * object_id, const char * object_file)
{
FILE *fp;
FILE *fp = NULL;
sc_path_t path;
size_t derlen;
u8 *der = NULL;
u8 *body;
size_t bodylen;
int r;
int r = -1;
struct stat stat_buf;
if(!object_file || (fp=fopen(object_file, "r")) == NULL){
printf("Cannot open object file, %s %s\n",
(object_file)?object_file:"", strerror(errno));
return -1;
goto err;
}
if (0 != stat(object_file, &stat_buf)) {
printf("unable to read file %s\n",object_file);
return -1;
goto err;
}
derlen = stat_buf.st_size;
der = malloc(derlen);
if (der == NULL) {
printf("file %s is too big, %lu\n",
object_file, (unsigned long)derlen);
return-1 ;
goto err;
}
if (1 != fread(der, derlen, 1, fp)) {
printf("unable to read file %s\n",object_file);
return -1;
goto err;
}
/* check if tag and length are valid */
body = (u8 *)sc_asn1_find_tag(card->ctx, der, derlen, 0x53, &bodylen);
if (body == NULL || derlen != body - der + bodylen) {
fprintf(stderr, "object tag or length not valid\n");
return -1;
goto err;
}
sc_format_path(object_id, &path);
@ -146,11 +146,17 @@ static int load_object(const char * object_id, const char * object_file)
r = sc_select_file(card, &path, NULL);
if (r < 0) {
fprintf(stderr, "select file failed\n");
return -1;
r = -1;
goto err;
}
/* leave 8 bits for flags, and pass in total length */
r = sc_write_binary(card, 0, der, derlen, derlen<<8);
err:
free(der);
if (fp)
fclose(fp);
return r;
}
@ -159,49 +165,49 @@ static int load_cert(const char * cert_id, const char * cert_file,
int compress)
{
X509 * cert = NULL;
FILE *fp;
FILE *fp = NULL;
u8 buf[1];
size_t buflen = 1;
sc_path_t path;
u8 *der = NULL;
u8 *p;
size_t derlen;
int r;
int r = -1;
if (!cert_file) {
printf("Missing cert file\n");
return -1;
goto err;
}
if((fp=fopen(cert_file, "r"))==NULL){
printf("Cannot open cert file, %s %s\n",
cert_file, strerror(errno));
return -1;
goto err;
}
if (compress) { /* file is gziped already */
struct stat stat_buf;
if (0 != stat(cert_file, &stat_buf)) {
printf("unable to read file %s\n",cert_file);
return -1;
goto err;
}
derlen = stat_buf.st_size;
der = malloc(derlen);
if (der == NULL) {
printf("file %s is too big, %lu\n",
cert_file, (unsigned long)derlen);
return -1 ;
goto err;
}
if (1 != fread(der, derlen, 1, fp)) {
printf("unable to read file %s\n",cert_file);
return -1;
goto err;
}
} else {
cert = PEM_read_X509(fp, &cert, NULL, NULL);
if(cert == NULL){
printf("file %s does not conatin PEM-encoded certificate\n",
cert_file);
return -1 ;
goto err;
}
derlen = i2d_X509(cert, NULL);
@ -209,7 +215,6 @@ static int load_cert(const char * cert_id, const char * cert_file,
p = der;
i2d_X509(cert, &p);
}
fclose(fp);
sc_hex_to_bin(cert_id, buf,&buflen);
switch (buf[0]) {
@ -219,20 +224,25 @@ static int load_cert(const char * cert_id, const char * cert_file,
case 0x9e: sc_format_path("0500",&path); break;
default:
fprintf(stderr,"cert must be 9A, 9C, 9D or 9E\n");
return 2;
r = 2;
goto err;
}
r = sc_select_file(card, &path, NULL);
if (r < 0) {
fprintf(stderr, "select file failed\n");
return -1;
goto err;
}
/* we pass length and 8 bits of flag to card-piv.c write_binary */
/* pass in its a cert and if needs compress */
r = sc_write_binary(card, 0, der, derlen, (derlen<<8) | (compress<<4) | 1);
return r;
err:
free(der);
if (fp)
fclose(fp);
return r;
}
static int admin_mode(const char* admin_info)
{