File 0333-crypto-Fix-leaks-in-otp_test_engine.patch of Package erlang

From 81a213be710a88a6ba183948023f258aedcb97b3 Mon Sep 17 00:00:00 2001
From: Sverker Eriksson <sverker@erlang.org>
Date: Mon, 18 Dec 2023 17:07:16 +0100
Subject: [PATCH 1/2] crypto: Fix leaks in otp_test_engine

One EVP_MD_meth_new() leak for each hash() call.

One RSA_meth_new() leak for each engine unload.
---
 lib/crypto/c_src/otp_test_engine.c | 117 +++++++++++++++++------------
 1 file changed, 67 insertions(+), 50 deletions(-)

diff --git a/lib/crypto/c_src/otp_test_engine.c b/lib/crypto/c_src/otp_test_engine.c
index ffa1bfebf2..e77124c3a8 100644
--- a/lib/crypto/c_src/otp_test_engine.c
+++ b/lib/crypto/c_src/otp_test_engine.c
@@ -87,20 +87,35 @@ EVP_PKEY* test_pubkey_load(ENGINE *eng, const char *id, UI_METHOD *ui_method, vo
 
 EVP_PKEY* test_key_load(ENGINE *er, const char *id, UI_METHOD *ui_method, void *callback_data, int priv);
 
+static int init_test_md5(void);
+static void finish_test_md5(void);
+
 /*----------------------------------------------------------------*/
 
 static int test_init(ENGINE *e) {
     printf("OTP Test Engine Initializatzion!\r\n");
 
 #if defined(FAKE_RSA_IMPL)
+    if ((test_rsa_method = RSA_meth_new("OTP test RSA method", 0)) == NULL) {
+        fprintf(stderr, "RSA_meth_new failed\r\n");
+        goto err;
+    }
+
     if (!RSA_meth_set_finish(test_rsa_method, test_rsa_free))
         goto err;
     if (!RSA_meth_set_sign(test_rsa_method, test_rsa_sign))
         goto err;
     if (!RSA_meth_set_verify(test_rsa_method, test_rsa_verify))
         goto err;
+
+    if (!ENGINE_set_RSA(e, test_rsa_method))
+        goto err;
+
 #endif /* if defined(FAKE_RSA_IMPL) */
 
+    if (!init_test_md5())
+        goto err;
+
 #if OPENSSL_VERSION_NUMBER < PACKED_OPENSSL_VERSION_PLAIN(1,1,0)
     /* Load all digest and cipher algorithms. Needed for password protected private keys */
     OpenSSL_add_all_ciphers();
@@ -109,16 +124,27 @@ static int test_init(ENGINE *e) {
 
     return 111;
 
-#if defined(FAKE_RSA_IMPL)
 err:
-    fprintf(stderr, "Setup RSA_METHOD failed\r\n");
-    return 0;
+#if defined(FAKE_RSA_IMPL)
+    if (test_rsa_method)
+        RSA_meth_free(test_rsa_method);
+    test_rsa_method = NULL;
 #endif
+    return 0;
 }
 
 static int test_finish(ENGINE *e) {
     printf("OTP Test Engine Finish!\r\n");
 
+#if defined(FAKE_RSA_IMPL)
+    if (test_rsa_method) {
+        RSA_meth_free(test_rsa_method);
+        test_rsa_method = NULL;
+    }
+#endif
+
+    finish_test_md5();
+
     //    EVP_cleanup();
 
     return 111;
@@ -190,6 +216,8 @@ static int test_engine_md5_final(EVP_MD_CTX *ctx,unsigned char *md) {
 #endif
 }
 
+static EVP_MD *test_engine_md5_ptr = NULL;
+
 #ifdef OLD
 static EVP_MD test_engine_md5_method=  {
         NID_md5,                      /* The name ID for MD5 */
@@ -210,6 +238,41 @@ static EVP_MD test_engine_md5_method=  {
 };
 #endif
 
+static int init_test_md5(void)
+{
+#ifdef OLD
+    test_engine_md5_ptr = &test_engine_md5_method;
+#else
+    EVP_MD *md;
+
+    if ((md = EVP_MD_meth_new(NID_md5, NID_undef)) == NULL)
+        return 0;
+    EVP_MD_meth_set_result_size(md, MD5_DIGEST_LENGTH);
+    EVP_MD_meth_set_flags(md, 0);
+    EVP_MD_meth_set_init(md, test_engine_md5_init);
+    EVP_MD_meth_set_update(md, test_engine_md5_update);
+    EVP_MD_meth_set_final(md, test_engine_md5_final);
+    EVP_MD_meth_set_copy(md, NULL);
+    EVP_MD_meth_set_cleanup(md, NULL);
+    EVP_MD_meth_set_input_blocksize(md, MD5_CBLOCK);
+    EVP_MD_meth_set_app_datasize(md, sizeof(EVP_MD *) + sizeof(MD5_CTX));
+    EVP_MD_meth_set_ctrl(md, NULL);
+
+    test_engine_md5_ptr = md;
+#endif
+    return 1;
+}
+
+static void finish_test_md5(void)
+{
+#ifndef OLD
+    if (test_engine_md5_ptr) {
+        EVP_MD_meth_free(test_engine_md5_ptr);
+        test_engine_md5_ptr = NULL;
+    }
+#endif
+}
+
 static int test_digest_ids[] = {NID_md5};
 
 static int test_engine_digest_selector(ENGINE *e, const EVP_MD **digest,
@@ -221,36 +284,7 @@ static int test_engine_digest_selector(ENGINE *e, const EVP_MD **digest,
     }
     fprintf(stderr, "Digest no %d requested\r\n",nid);
     if (nid == NID_md5) {
-#ifdef OLD
-        *digest = &test_engine_md5_method;
-#else
-        EVP_MD *md;
-
-        if ((md = EVP_MD_meth_new(NID_md5, NID_undef)) == NULL)
-            goto err;
-        if (EVP_MD_meth_set_result_size(md, MD5_DIGEST_LENGTH) != 1)
-            goto err;
-        if (EVP_MD_meth_set_flags(md, 0) != 1)
-            goto err;
-        if (EVP_MD_meth_set_init(md, test_engine_md5_init) != 1)
-            goto err;
-        if (EVP_MD_meth_set_update(md, test_engine_md5_update) != 1)
-            goto err;
-        if (EVP_MD_meth_set_final(md, test_engine_md5_final) != 1)
-            goto err;
-        if (EVP_MD_meth_set_copy(md, NULL) != 1)
-            goto err;
-        if (EVP_MD_meth_set_cleanup(md, NULL) != 1)
-            goto err;
-        if (EVP_MD_meth_set_input_blocksize(md, MD5_CBLOCK) != 1)
-            goto err;
-        if (EVP_MD_meth_set_app_datasize(md, sizeof(EVP_MD *) + sizeof(MD5_CTX)) != 1)
-            goto err;
-        if (EVP_MD_meth_set_ctrl(md, NULL) != 1)
-            goto err;
-
-        *digest = md;
-#endif
+        *digest = test_engine_md5_ptr;
     }
     else {
         goto err;
@@ -265,13 +299,6 @@ static int test_engine_digest_selector(ENGINE *e, const EVP_MD **digest,
 
 static int bind_helper(ENGINE * e, const char *id)
 {
-#if defined(FAKE_RSA_IMPL)
-    if ((test_rsa_method = RSA_meth_new("OTP test RSA method", 0)) == NULL) {
-        fprintf(stderr, "RSA_meth_new failed\r\n");
-        goto err;
-    }
-#endif /* if defined(FAKE_RSA_IMPL) */
-
     if (!ENGINE_set_id(e, test_engine_id))
         goto err;
     if (!ENGINE_set_name(e, test_engine_name))
@@ -288,19 +315,9 @@ static int bind_helper(ENGINE * e, const char *id)
     if (!ENGINE_set_load_pubkey_function(e, &test_pubkey_load))
         goto err;
 
-#if defined(FAKE_RSA_IMPL)
-    if (!ENGINE_set_RSA(e, test_rsa_method))
-        goto err;
-#endif /* if defined(FAKE_RSA_IMPL) */
-
     return 1;
 
  err:
-#if defined(FAKE_RSA_IMPL)
-    if (test_rsa_method)
-        RSA_meth_free(test_rsa_method);
-    test_rsa_method = NULL;
-#endif
     return 0;
 }
 
-- 
2.35.3

openSUSE Build Service is sponsored by