mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-02-11 10:40:27 +09:00
pki_crypto: Fix ecdsa memory leak
Fixed a memory leak in pki_privkey_build_ecdsa. The BIGNUM bexp was getting allocated, but not free'd. It gets stored by reference in param_bld. Signed-off-by: roytak <xjanot04@fit.vutbr.cz> Reviewed-by: Norbert Pocs <npocs@redhat.com>
This commit is contained in:
108
src/pki_crypto.c
108
src/pki_crypto.c
@@ -204,111 +204,125 @@ int pki_key_ecdsa_nid_from_name(const char *name)
|
|||||||
|
|
||||||
int pki_privkey_build_ecdsa(ssh_key key, int nid, ssh_string e, ssh_string exp)
|
int pki_privkey_build_ecdsa(ssh_key key, int nid, ssh_string e, ssh_string exp)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc = 0;
|
||||||
|
BIGNUM *bexp = NULL;
|
||||||
|
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||||
EC_POINT *p = NULL;
|
EC_POINT *p = NULL;
|
||||||
const EC_GROUP *g = NULL;
|
const EC_GROUP *g = NULL;
|
||||||
int ok;
|
|
||||||
BIGNUM *bexp = NULL;
|
|
||||||
EC_KEY *ecdsa = NULL;
|
EC_KEY *ecdsa = NULL;
|
||||||
#else
|
#else
|
||||||
const BIGNUM *expb;
|
|
||||||
const char *group_name = OSSL_EC_curve_nid2name(nid);
|
const char *group_name = OSSL_EC_curve_nid2name(nid);
|
||||||
OSSL_PARAM_BLD *param_bld = NULL;
|
OSSL_PARAM_BLD *param_bld = NULL;
|
||||||
|
|
||||||
if (group_name == NULL) {
|
if (group_name == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
expb = ssh_make_string_bn(exp);
|
|
||||||
#endif /* OPENSSL_VERSION_NUMBER */
|
#endif /* OPENSSL_VERSION_NUMBER */
|
||||||
|
|
||||||
|
bexp = ssh_make_string_bn(exp);
|
||||||
|
if (bexp == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
key->ecdsa_nid = nid;
|
key->ecdsa_nid = nid;
|
||||||
key->type_c = pki_key_ecdsa_nid_to_name(nid);
|
key->type_c = pki_key_ecdsa_nid_to_name(nid);
|
||||||
|
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||||
ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid);
|
ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid);
|
||||||
if (ecdsa == NULL) {
|
if (ecdsa == NULL) {
|
||||||
return -1;
|
rc = -1;
|
||||||
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
g = EC_KEY_get0_group(ecdsa);
|
g = EC_KEY_get0_group(ecdsa);
|
||||||
|
|
||||||
p = EC_POINT_new(g);
|
p = EC_POINT_new(g);
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
EC_KEY_free(ecdsa);
|
rc = -1;
|
||||||
return -1;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
ok = EC_POINT_oct2point(g,
|
rc = EC_POINT_oct2point(g,
|
||||||
p,
|
p,
|
||||||
ssh_string_data(e),
|
ssh_string_data(e),
|
||||||
ssh_string_len(e),
|
ssh_string_len(e),
|
||||||
NULL);
|
NULL);
|
||||||
if (!ok) {
|
if (rc != 1) {
|
||||||
EC_KEY_free(ecdsa);
|
rc = -1;
|
||||||
EC_POINT_free(p);
|
goto cleanup;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EC_KEY_set_public_key duplicates p */
|
/* EC_KEY_set_public_key duplicates p */
|
||||||
ok = EC_KEY_set_public_key(ecdsa, p);
|
rc = EC_KEY_set_public_key(ecdsa, p);
|
||||||
EC_POINT_free(p);
|
if (rc != 1) {
|
||||||
if (!ok) {
|
rc = -1;
|
||||||
EC_KEY_free(ecdsa);
|
goto cleanup;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bexp = ssh_make_string_bn(exp);
|
|
||||||
if (bexp == NULL) {
|
|
||||||
EC_KEY_free(ecdsa);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
/* EC_KEY_set_private_key duplicates exp */
|
/* EC_KEY_set_private_key duplicates exp */
|
||||||
ok = EC_KEY_set_private_key(ecdsa, bexp);
|
rc = EC_KEY_set_private_key(ecdsa, bexp);
|
||||||
BN_free(bexp);
|
if (rc != 1) {
|
||||||
if (!ok) {
|
rc = -1;
|
||||||
EC_KEY_free(ecdsa);
|
goto cleanup;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
key->key = EVP_PKEY_new();
|
key->key = EVP_PKEY_new();
|
||||||
if (key->key == NULL) {
|
if (key->key == NULL) {
|
||||||
EC_KEY_free(ecdsa);
|
rc = -1;
|
||||||
return -1;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ecdsa will be freed when the EVP_PKEY key->key is freed */
|
||||||
rc = EVP_PKEY_assign_EC_KEY(key->key, ecdsa);
|
rc = EVP_PKEY_assign_EC_KEY(key->key, ecdsa);
|
||||||
if (rc != 1) {
|
if (rc != 1) {
|
||||||
EVP_PKEY_free(key->key);
|
rc = -1;
|
||||||
EC_KEY_free(ecdsa);
|
goto cleanup;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
/* ssh_key is now the owner of this memory */
|
||||||
|
ecdsa = NULL;
|
||||||
|
|
||||||
return 0;
|
/* set rc to 0 if everything went well */
|
||||||
|
rc = 0;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
EC_KEY_free(ecdsa);
|
||||||
|
EC_POINT_free(p);
|
||||||
|
BN_free(bexp);
|
||||||
|
return rc;
|
||||||
#else
|
#else
|
||||||
param_bld = OSSL_PARAM_BLD_new();
|
param_bld = OSSL_PARAM_BLD_new();
|
||||||
if (param_bld == NULL)
|
if (param_bld == NULL){
|
||||||
goto err;
|
rc = -1;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
rc = OSSL_PARAM_BLD_push_utf8_string(param_bld, OSSL_PKEY_PARAM_GROUP_NAME,
|
rc = OSSL_PARAM_BLD_push_utf8_string(param_bld, OSSL_PKEY_PARAM_GROUP_NAME,
|
||||||
group_name, strlen(group_name));
|
group_name, strlen(group_name));
|
||||||
if (rc != 1)
|
if (rc != 1) {
|
||||||
goto err;
|
rc = -1;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
rc = OSSL_PARAM_BLD_push_octet_string(param_bld, OSSL_PKEY_PARAM_PUB_KEY,
|
rc = OSSL_PARAM_BLD_push_octet_string(param_bld, OSSL_PKEY_PARAM_PUB_KEY,
|
||||||
ssh_string_data(e), ssh_string_len(e));
|
ssh_string_data(e), ssh_string_len(e));
|
||||||
if (rc != 1)
|
if (rc != 1) {
|
||||||
goto err;
|
rc = -1;
|
||||||
rc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_PRIV_KEY, expb);
|
goto cleanup;
|
||||||
if (rc != 1)
|
}
|
||||||
goto err;
|
|
||||||
|
rc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_PRIV_KEY, bexp);
|
||||||
|
if (rc != 1) {
|
||||||
|
rc = -1;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
rc = evp_build_pkey("EC", param_bld, &(key->key), EVP_PKEY_KEYPAIR);
|
rc = evp_build_pkey("EC", param_bld, &(key->key), EVP_PKEY_KEYPAIR);
|
||||||
OSSL_PARAM_BLD_free(param_bld);
|
|
||||||
|
|
||||||
return rc;
|
cleanup:
|
||||||
err:
|
|
||||||
OSSL_PARAM_BLD_free(param_bld);
|
OSSL_PARAM_BLD_free(param_bld);
|
||||||
return -1;
|
BN_free(bexp);
|
||||||
|
return rc;
|
||||||
#endif /* OPENSSL_VERSION_NUMBER */
|
#endif /* OPENSSL_VERSION_NUMBER */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user