From 5d75090d9fe23c6ef27560de47fc141fc769c6cd Mon Sep 17 00:00:00 2001 From: Jon Simons Date: Sun, 5 Oct 2014 05:59:54 -0700 Subject: [PATCH] pki_crypto.c: plug ecdsa_sig->[r,s] bignum leaks Per ecdsa(3ssl), ECDSA_SIG_new does allocate its 'r' and 's' bignum fields. Fix a bug where the initial 'r' and 's' bignums were being overwritten with newly-allocated bignums, resulting in a memory leak. BUG: https://red.libssh.org/issues/175 Signed-off-by: Jon Simons Reviewed-by: Andreas Schneider (cherry picked from commit 4745d652b5e71c27fd891edfe690162c0b8d3005) --- include/libssh/dh.h | 2 +- src/dh.c | 9 +++++++++ src/pki_crypto.c | 4 ++-- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/include/libssh/dh.h b/include/libssh/dh.h index e1039e24..f28b9169 100644 --- a/include/libssh/dh.h +++ b/include/libssh/dh.h @@ -49,7 +49,7 @@ int hashbufin_add_cookie(ssh_session session, unsigned char *cookie); int hashbufout_add_cookie(ssh_session session); int generate_session_keys(ssh_session session); bignum make_string_bn(ssh_string string); +void make_string_bn_inplace(ssh_string string, bignum bnout); ssh_string make_bignum_string(bignum num); - #endif /* DH_H_ */ diff --git a/src/dh.c b/src/dh.c index 3c2e5adb..84355d48 100644 --- a/src/dh.c +++ b/src/dh.c @@ -407,6 +407,15 @@ bignum make_string_bn(ssh_string string){ return bn; } +void make_string_bn_inplace(ssh_string string, bignum bnout) { + unsigned int len = ssh_string_len(string); +#ifdef HAVE_LIBGCRYPT + #error "unsupported" +#elif defined HAVE_LIBCRYPTO + bignum_bin2bn(string->data, len, bnout); +#endif +} + ssh_string dh_get_e(ssh_session session) { return make_bignum_string(session->next_crypto->e); } diff --git a/src/pki_crypto.c b/src/pki_crypto.c index 5e2585da..39742817 100644 --- a/src/pki_crypto.c +++ b/src/pki_crypto.c @@ -1397,7 +1397,7 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey, ssh_print_hexa("r", ssh_string_data(r), ssh_string_len(r)); #endif - sig->ecdsa_sig->r = make_string_bn(r); + make_string_bn_inplace(r, sig->ecdsa_sig->r); ssh_string_burn(r); ssh_string_free(r); if (sig->ecdsa_sig->r == NULL) { @@ -1418,7 +1418,7 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey, ssh_print_hexa("s", ssh_string_data(s), ssh_string_len(s)); #endif - sig->ecdsa_sig->s = make_string_bn(s); + make_string_bn_inplace(s, sig->ecdsa_sig->s); ssh_string_burn(s); ssh_string_free(s); if (sig->ecdsa_sig->s == NULL) {