]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Fix mem leak in ECDSA_sign().
authorslontis <shane.lontis@oracle.com>
Tue, 21 Mar 2023 06:06:06 +0000 (16:06 +1000)
committerTodd Short <todd.short@me.com>
Fri, 31 Mar 2023 18:57:47 +0000 (14:57 -0400)
Similiar to the issue found in PR #20553 for DSA_sign().
ECDSA_sign() leaked memory if the signature was NULL
when i2d_ECDSA_SIG was called.

Note that this does not affect the higher level EVP
functions as they correctly handle NULL.

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Todd Short <todd.short@me.com>
(Merged from https://github.com/openssl/openssl/pull/20554)

crypto/ec/ecdsa_ossl.c
crypto/sm2/sm2_sign.c
test/ecdsatest.c

index 6ab7be0fe5c7d5067a6bbcab9a13b3c0207e51e8..0d0506937ab37dc907f68b2e20ba0db7da6011e4 100644 (file)
@@ -82,7 +82,7 @@ int ossl_ecdsa_sign(int type, const unsigned char *dgst, int dlen,
         *siglen = 0;
         return 0;
     }
-    *siglen = i2d_ECDSA_SIG(s, &sig);
+    *siglen = i2d_ECDSA_SIG(s, sig != NULL ? &sig : NULL);
     ECDSA_SIG_free(s);
     return 1;
 }
@@ -106,7 +106,7 @@ int ossl_ecdsa_deterministic_sign(const unsigned char *dgst, int dlen,
     if (s == NULL)
         goto end;
 
-    *siglen = i2d_ECDSA_SIG(s, &sig);
+    *siglen = i2d_ECDSA_SIG(s, sig != NULL ? &sig : NULL);
     ECDSA_SIG_free(s);
     ret = 1;
 end:
index 7113f4740b898a8923cf4cb1712bbe8675181c21..67c61b1dcdc8ebb67857f1e15659a013537df490 100644 (file)
@@ -461,7 +461,7 @@ int ossl_sm2_internal_sign(const unsigned char *dgst, int dgstlen,
         goto done;
     }
 
-    sigleni = i2d_ECDSA_SIG(s, &sig);
+    sigleni = i2d_ECDSA_SIG(s, sig != NULL ? &sig : NULL);
     if (sigleni < 0) {
        ERR_raise(ERR_LIB_SM2, ERR_R_INTERNAL_ERROR);
        goto done;
index 0baeb8923046793766f5ee6ddd15b6ceef968e92..0954239684dae36e5077c1a7ebebfd90786c89ac 100644 (file)
@@ -346,6 +346,22 @@ static int test_builtin_as_sm2(int n)
     return test_builtin(n, EVP_PKEY_SM2);
 }
 # endif
+
+static int test_ecdsa_sig_NULL(void)
+{
+    int ret;
+    unsigned int siglen;
+    unsigned char dgst[128] = { 0 };
+    EC_KEY *eckey = NULL;
+
+    ret = TEST_ptr(eckey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1))
+          && TEST_int_eq(EC_KEY_generate_key(eckey), 1)
+          && TEST_int_eq(ECDSA_sign(0, dgst, sizeof(dgst), NULL, &siglen, eckey), 1)
+          && TEST_int_gt(siglen, 0);
+    EC_KEY_free(eckey);
+    return ret;
+}
+
 #endif /* OPENSSL_NO_EC */
 
 int setup_tests(void)
@@ -365,6 +381,7 @@ int setup_tests(void)
         return 0;
     }
     ADD_ALL_TESTS(test_builtin_as_ec, crv_len);
+    ADD_TEST(test_ecdsa_sig_NULL);
 # ifndef OPENSSL_NO_SM2
     ADD_ALL_TESTS(test_builtin_as_sm2, crv_len);
 # endif