From 64d3d81036c027a0a52e15e2b36e125b6216a181 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 4 Sep 2019 17:00:50 +0200 Subject: [PATCH] fixed invalid free --- src/libopensc/pkcs15-pubkey.c | 90 ++++++++++++++++++----------------- 1 file changed, 47 insertions(+), 43 deletions(-) diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index 9cb7710e..2149d3ab 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -213,11 +213,10 @@ int sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card *p15card, const u8 ** buf, size_t *buflen) { struct sc_context *ctx = p15card->card->ctx; - struct sc_pkcs15_pubkey_info info; + struct sc_pkcs15_pubkey_info *info; int r, gostr3410_params[3]; struct sc_pkcs15_keyinfo_gostparams *keyinfo_gostparams; - size_t usage_len = sizeof(info.usage); - size_t af_len = sizeof(info.access_flags); + size_t usage_len, af_len; struct sc_pkcs15_der *der = &obj->content; struct sc_asn1_entry asn1_com_key_attr[C_ASN1_COM_KEY_ATTR_SIZE]; struct sc_asn1_entry asn1_com_pubkey_attr[C_ASN1_COM_PUBKEY_ATTR_SIZE]; @@ -242,6 +241,14 @@ int sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card *p15card, struct sc_asn1_pkcs15_object gostr3410key_obj = { obj, asn1_com_key_attr, asn1_com_pubkey_attr, asn1_gostr3410_type_attr }; + info = calloc(1, sizeof *info); + if (info == NULL) { + r = SC_ERROR_OUT_OF_MEMORY; + goto err; + } + usage_len = sizeof(info->usage); + af_len = sizeof(info->access_flags); + sc_copy_asn1_entry(c_asn1_pubkey, asn1_pubkey); sc_copy_asn1_entry(c_asn1_pubkey_choice, asn1_pubkey_choice); sc_copy_asn1_entry(c_asn1_rsa_type_attr, asn1_rsa_type_attr); @@ -257,7 +264,7 @@ int sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card *p15card, sc_copy_asn1_entry(c_asn1_com_pubkey_attr, asn1_com_pubkey_attr); sc_copy_asn1_entry(c_asn1_com_key_attr, asn1_com_key_attr); - sc_format_asn1_entry(asn1_com_pubkey_attr + 0, &info.subject.value, &info.subject.len, 0); + sc_format_asn1_entry(asn1_com_pubkey_attr + 0, &info->subject.value, &info->subject.len, 0); sc_format_asn1_entry(asn1_pubkey_choice + 0, &rsakey_obj, NULL, 0); sc_format_asn1_entry(asn1_pubkey_choice + 1, &dsakey_obj, NULL, 0); @@ -266,42 +273,41 @@ int sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card *p15card, sc_format_asn1_entry(asn1_rsa_type_attr + 0, asn1_rsakey_attr, NULL, 0); - sc_format_asn1_entry(asn1_rsakey_value_choice + 0, &info.path, NULL, 0); + sc_format_asn1_entry(asn1_rsakey_value_choice + 0, &info->path, NULL, 0); sc_format_asn1_entry(asn1_rsakey_value_choice + 1, &der->value, &der->len, 0); sc_format_asn1_entry(asn1_rsakey_attr + 0, asn1_rsakey_value_choice, NULL, 0); - sc_format_asn1_entry(asn1_rsakey_attr + 1, &info.modulus_length, NULL, 0); + sc_format_asn1_entry(asn1_rsakey_attr + 1, &info->modulus_length, NULL, 0); sc_format_asn1_entry(asn1_ec_type_attr + 0, asn1_eckey_attr, NULL, 0); - sc_format_asn1_entry(asn1_eckey_value_choice + 0, &info.path, NULL, 0); + sc_format_asn1_entry(asn1_eckey_value_choice + 0, &info->path, NULL, 0); sc_format_asn1_entry(asn1_eckey_value_choice + 1, &der->value, &der->len, 0); sc_format_asn1_entry(asn1_eckey_attr + 0, asn1_eckey_value_choice, NULL, 0); sc_format_asn1_entry(asn1_dsa_type_attr + 0, asn1_dsakey_attr, NULL, 0); - sc_format_asn1_entry(asn1_dsakey_attr + 0, &info.path, NULL, 0); + sc_format_asn1_entry(asn1_dsakey_attr + 0, &info->path, NULL, 0); sc_format_asn1_entry(asn1_gostr3410_type_attr + 0, asn1_gostr3410key_attr, NULL, 0); - sc_format_asn1_entry(asn1_gostr3410key_attr + 0, &info.path, NULL, 0); + sc_format_asn1_entry(asn1_gostr3410key_attr + 0, &info->path, NULL, 0); sc_format_asn1_entry(asn1_gostr3410key_attr + 1, &gostr3410_params[0], NULL, 0); sc_format_asn1_entry(asn1_gostr3410key_attr + 2, &gostr3410_params[1], NULL, 0); sc_format_asn1_entry(asn1_gostr3410key_attr + 3, &gostr3410_params[2], NULL, 0); - sc_format_asn1_entry(asn1_com_key_attr + 0, &info.id, NULL, 0); - sc_format_asn1_entry(asn1_com_key_attr + 1, &info.usage, &usage_len, 0); - sc_format_asn1_entry(asn1_com_key_attr + 2, &info.native, NULL, 0); - sc_format_asn1_entry(asn1_com_key_attr + 3, &info.access_flags, &af_len, 0); - sc_format_asn1_entry(asn1_com_key_attr + 4, &info.key_reference, NULL, 0); + sc_format_asn1_entry(asn1_com_key_attr + 0, &info->id, NULL, 0); + sc_format_asn1_entry(asn1_com_key_attr + 1, &info->usage, &usage_len, 0); + sc_format_asn1_entry(asn1_com_key_attr + 2, &info->native, NULL, 0); + sc_format_asn1_entry(asn1_com_key_attr + 3, &info->access_flags, &af_len, 0); + sc_format_asn1_entry(asn1_com_key_attr + 4, &info->key_reference, NULL, 0); sc_format_asn1_entry(asn1_pubkey + 0, asn1_pubkey_choice, NULL, 0); /* Fill in defaults */ - memset(&info, 0, sizeof(info)); - info.key_reference = -1; - info.native = 1; + info->key_reference = -1; + info->native = 1; memset(gostr3410_params, 0, sizeof(gostr3410_params)); r = sc_asn1_decode(ctx, asn1_pubkey, *buf, *buflen, buf, buflen); @@ -312,17 +318,17 @@ int sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card *p15card, obj->type = SC_PKCS15_TYPE_PUBKEY_RSA; } else if (asn1_pubkey_choice[2].flags & SC_ASN1_PRESENT) { obj->type = SC_PKCS15_TYPE_PUBKEY_GOSTR3410; - assert(info.modulus_length == 0); - info.modulus_length = SC_PKCS15_GOSTR3410_KEYSIZE; - assert(info.params.len == 0); - info.params.len = sizeof(struct sc_pkcs15_keyinfo_gostparams); - info.params.data = malloc(info.params.len); - if (info.params.data == NULL) { + assert(info->modulus_length == 0); + info->modulus_length = SC_PKCS15_GOSTR3410_KEYSIZE; + assert(info->params.len == 0); + info->params.len = sizeof(struct sc_pkcs15_keyinfo_gostparams); + info->params.data = malloc(info->params.len); + if (info->params.data == NULL) { r = SC_ERROR_OUT_OF_MEMORY; goto err; } - assert(sizeof(*keyinfo_gostparams) == info.params.len); - keyinfo_gostparams = info.params.data; + assert(sizeof(*keyinfo_gostparams) == info->params.len); + keyinfo_gostparams = info->params.data; keyinfo_gostparams->gostr3410 = (unsigned int)gostr3410_params[0]; keyinfo_gostparams->gostr3411 = (unsigned int)gostr3410_params[1]; keyinfo_gostparams->gost28147 = (unsigned int)gostr3410_params[2]; @@ -335,39 +341,35 @@ int sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card *p15card, } if (!p15card->app || !p15card->app->ddo.aid.len) { - r = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &info.path); + r = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &info->path); if (r < 0) { goto err; } } else { - info.path.aid = p15card->app->ddo.aid; + info->path.aid = p15card->app->ddo.aid; } - sc_log(ctx, "PubKey path '%s'", sc_print_path(&info.path)); + sc_log(ctx, "PubKey path '%s'", sc_print_path(&info->path)); /* OpenSC 0.11.4 and older encoded "keyReference" as a negative value. Fixed in 0.11.5 we need to add a hack, so old cards continue to work. */ - if (info.key_reference < -1) - info.key_reference += 256; + if (info->key_reference < -1) + info->key_reference += 256; - obj->data = malloc(sizeof(info)); - if (obj->data == NULL) { - r = SC_ERROR_OUT_OF_MEMORY; - goto err; - } - memcpy(obj->data, &info, sizeof(info)); + obj->data = info; + info = NULL; r = sc_pkcs15_decode_pubkey_direct_value(p15card, obj); if (r < 0) { - free(obj->data); + info = obj->data; obj->data = NULL; } LOG_TEST_GOTO_ERR(ctx, r, "Decode public key direct value failed"); err: if (r < 0) { - sc_pkcs15_free_pubkey_info(&info); + sc_pkcs15_free_pubkey_info(info); } LOG_FUNC_RETURN(ctx, r); @@ -1227,11 +1229,13 @@ sc_pkcs15_free_pubkey(struct sc_pkcs15_pubkey *key) void sc_pkcs15_free_pubkey_info(sc_pkcs15_pubkey_info_t *info) { - free(info->subject.value); - free(info->direct.spki.value); - free(info->direct.raw.value); - sc_pkcs15_free_key_params(&info->params); - free(info); + if (info) { + free(info->subject.value); + free(info->direct.spki.value); + free(info->direct.raw.value); + sc_pkcs15_free_key_params(&info->params); + free(info); + } }