File 8641-crypto-3.0-API-in-pkey.c.patch of Package erlang

From f11a9f2d3a0c0bdd7dbe204d6c4e50499eb63e4a Mon Sep 17 00:00:00 2001
From: Hans Nilsson <hans@erlang.org>
Date: Tue, 1 Mar 2022 13:01:15 +0100
Subject: [PATCH 1/3] crypto: 3.0 API in pkey.c

---
 lib/crypto/c_src/dss.c  |   2 +
 lib/crypto/c_src/ec.c   |   2 +
 lib/crypto/c_src/pkey.c | 610 +++++++++++++++++++++-------------------
 3 files changed, 327 insertions(+), 287 deletions(-)

diff --git a/lib/crypto/c_src/dss.c b/lib/crypto/c_src/dss.c
index 28b11c1a28..b20ed3add1 100644
--- a/lib/crypto/c_src/dss.c
+++ b/lib/crypto/c_src/dss.c
@@ -78,6 +78,7 @@ int get_dss_private_key(ErlNifEnv* env, ERL_NIF_TERM key, EVP_PKEY **pkey)
     dummy_pub_key = NULL;
     priv_key = NULL;
 
+    *pkey = EVP_PKEY_new();
     if (EVP_PKEY_assign_DSA(*pkey, dsa) != 1)
         goto err;
     /* On success, result owns dsa */
@@ -144,6 +145,7 @@ int get_dss_public_key(ErlNifEnv* env, ERL_NIF_TERM key, EVP_PKEY **pkey)
     /* dsa takes ownership on success */
     dsa_y = NULL;
 
+    *pkey = EVP_PKEY_new();
     if (EVP_PKEY_assign_DSA(*pkey, dsa) != 1)
         goto err;
     /* On success, result owns dsa */
diff --git a/lib/crypto/c_src/ec.c b/lib/crypto/c_src/ec.c
index b52aeed6ea..fd66ecfab4 100644
--- a/lib/crypto/c_src/ec.c
+++ b/lib/crypto/c_src/ec.c
@@ -310,6 +310,7 @@ int get_ec_private_key(ErlNifEnv* env, ERL_NIF_TERM key, EVP_PKEY **pkey)
     if (!get_ec_key_sz(env, tpl_terms[0], tpl_terms[1], atom_undefined, &ec, NULL))
         goto err;
 
+    *pkey = EVP_PKEY_new();
     if (EVP_PKEY_assign_EC_KEY(*pkey, ec) != 1)
         goto err;
             /* On success, result owns ec */
@@ -339,6 +340,7 @@ int get_ec_public_key(ErlNifEnv* env, ERL_NIF_TERM key, EVP_PKEY **pkey)
     if (!get_ec_key_sz(env, tpl_terms[0], atom_undefined, tpl_terms[1], &ec, NULL))
         goto err;
 
+    *pkey = EVP_PKEY_new();
     if (EVP_PKEY_assign_EC_KEY(*pkey, ec) != 1)
         goto err;
             /* On success, result owns ec */
diff --git a/lib/crypto/c_src/pkey.c b/lib/crypto/c_src/pkey.c
index 299684d50e..aebe7676ec 100644
--- a/lib/crypto/c_src/pkey.c
+++ b/lib/crypto/c_src/pkey.c
@@ -259,7 +259,6 @@ static int get_pkey_sign_options(ErlNifEnv *env, ERL_NIF_TERM algorithm, ERL_NIF
 
 static int get_pkey_private_key(ErlNifEnv *env, ERL_NIF_TERM algorithm, ERL_NIF_TERM key, EVP_PKEY **pkey)
 {
-    EVP_PKEY *result = NULL;
     char *id = NULL;
     char *password = NULL;
 
@@ -272,23 +271,19 @@ static int get_pkey_private_key(ErlNifEnv *env, ERL_NIF_TERM algorithm, ERL_NIF_
             goto err;
 
         password = get_key_password(env, key);
-        result = ENGINE_load_private_key(e, id, NULL, password);
+        *pkey = ENGINE_load_private_key(e, id, NULL, password);
 
 #else
         return PKEY_BADARG;
 #endif
 
     } else if (algorithm == atom_rsa) {
-        if ((result = EVP_PKEY_new()) == NULL)
-            goto err;
-        if (!get_rsa_private_key(env, key, &result))
+        if (!get_rsa_private_key(env, key, pkey))
             goto err;
 
     } else if (algorithm == atom_ecdsa) {
 #if defined(HAVE_EC)
-        if ((result = EVP_PKEY_new()) == NULL)
-            goto err;
-        if (!get_ec_private_key(env, key, &result))
+        if (!get_ec_private_key(env, key, pkey))
             goto err;
 #else
 	return PKEY_NOTSUP;
@@ -298,7 +293,7 @@ static int get_pkey_private_key(ErlNifEnv *env, ERL_NIF_TERM algorithm, ERL_NIF_
 #ifdef HAVE_EDDSA
         if (FIPS_MODE())
             return PKEY_NOTSUP;
-        if (!get_eddsa_key(env, 0, key, &result))
+        if (!get_eddsa_key(env, 0, key, pkey))
             goto err;
 #else
             return PKEY_NOTSUP;
@@ -306,9 +301,7 @@ static int get_pkey_private_key(ErlNifEnv *env, ERL_NIF_TERM algorithm, ERL_NIF_
 
     } else if (algorithm == atom_dss) {
 #ifdef HAVE_DSA
-        if ((result = EVP_PKEY_new()) == NULL)
-            goto err;
-        if (!get_dss_private_key(env, key, &result))
+        if (!get_dss_private_key(env, key, pkey))
             goto err;
 #else
         return PKEY_NOTSUP;
@@ -324,17 +317,17 @@ static int get_pkey_private_key(ErlNifEnv *env, ERL_NIF_TERM algorithm, ERL_NIF_
     if (id)
         enif_free(id);
 
-    if (result == NULL) {
+    if (*pkey == NULL) {
         return PKEY_BADARG;
     } else {
-        *pkey = result;
+        *pkey = *pkey;
         return PKEY_OK;
     }
 
  err:
-    if (result)
-        EVP_PKEY_free(result);
-    result = NULL;
+    if (*pkey)
+        EVP_PKEY_free(*pkey);
+    *pkey = NULL;
     goto free_and_return;
 }
 
@@ -342,7 +335,6 @@ static int get_pkey_private_key(ErlNifEnv *env, ERL_NIF_TERM algorithm, ERL_NIF_
 static int get_pkey_public_key(ErlNifEnv *env, ERL_NIF_TERM algorithm, ERL_NIF_TERM key,
 			       EVP_PKEY **pkey)
 {
-    EVP_PKEY *result = NULL;
     char *id = NULL;
     char *password = NULL;
 
@@ -355,22 +347,17 @@ static int get_pkey_public_key(ErlNifEnv *env, ERL_NIF_TERM algorithm, ERL_NIF_T
             goto err;
 
         password = get_key_password(env, key);
-        result = ENGINE_load_public_key(e, id, NULL, password);
-
+        *pkey = ENGINE_load_public_key(e, id, NULL, password);
 #else
         return PKEY_BADARG;
 #endif
     } else  if (algorithm == atom_rsa) {
-        if ((result = EVP_PKEY_new()) == NULL)
-            goto err;
-        if (!get_rsa_public_key(env, key, &result))
+        if (!get_rsa_public_key(env, key, pkey))
             goto err;
 
     } else if (algorithm == atom_ecdsa) {
 #if defined(HAVE_EC)
-        if ((result = EVP_PKEY_new()) == NULL)
-            goto err;
-        if (!get_ec_public_key(env, key, &result))
+        if (!get_ec_public_key(env, key, pkey))
             goto err;
 #else
 	return PKEY_NOTSUP;
@@ -378,7 +365,7 @@ static int get_pkey_public_key(ErlNifEnv *env, ERL_NIF_TERM algorithm, ERL_NIF_T
     } else if (algorithm == atom_eddsa) {
 #ifdef HAVE_EDDSA
         if (!FIPS_MODE()) {
-            if (!get_eddsa_key(env, 1, key, &result))
+            if (!get_eddsa_key(env, 1, key, pkey))
                 goto err;
         }
 #else
@@ -386,9 +373,7 @@ static int get_pkey_public_key(ErlNifEnv *env, ERL_NIF_TERM algorithm, ERL_NIF_T
 #endif
     } else if (algorithm == atom_dss) {
 #ifdef HAVE_DSA
-        if ((result = EVP_PKEY_new()) == NULL)
-            goto err;
-        if (!get_dss_public_key(env, key, &result))
+        if (!get_dss_public_key(env, key, pkey))
             goto err;
 #else
         return PKEY_NOTSUP;
@@ -400,9 +385,9 @@ static int get_pkey_public_key(ErlNifEnv *env, ERL_NIF_TERM algorithm, ERL_NIF_T
     goto done;
 
  err:
-    if (result)
-        EVP_PKEY_free(result);
-    result = NULL;
+    if (*pkey)
+        EVP_PKEY_free(*pkey);
+    *pkey = NULL;
 
  done:
     if (password)
@@ -410,12 +395,11 @@ static int get_pkey_public_key(ErlNifEnv *env, ERL_NIF_TERM algorithm, ERL_NIF_T
     if (id)
         enif_free(id);
 
-    if (result == NULL) {
+    if (*pkey == NULL)
         return PKEY_BADARG;
-    } else {
-        *pkey = result;
+    else
         return PKEY_OK;
-    }
+
 }
 
 ERL_NIF_TERM pkey_sign_nif(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
@@ -426,37 +410,29 @@ ERL_NIF_TERM pkey_sign_nif(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
     const EVP_MD *md = NULL;
     unsigned char md_value[EVP_MAX_MD_SIZE];
     EVP_PKEY *pkey = NULL;
-#ifdef HAVE_EDDSA
-    EVP_MD_CTX *mdctx = NULL;
-#endif
 #ifdef HAS_EVP_PKEY_CTX
     EVP_PKEY_CTX *ctx = NULL;
     size_t siglen;
 #else
     int len;
     unsigned int siglen;
+    RSA *rsa = NULL;
+# ifdef HAVE_DSA
+    DSA *dsa = NULL;
+# endif
+# if defined(HAVE_EC)
+    EC_KEY *ec = NULL;
+# endif
 #endif
     PKeySignOptions sig_opt;
     ErlNifBinary sig_bin; /* signature */
     unsigned char *tbs = NULL; /* data to be signed */
     size_t tbslen = 0;
-    RSA *rsa = NULL;
-#ifdef HAVE_DSA
-    DSA *dsa = NULL;
-#endif
-#if defined(HAVE_EC)
-    EC_KEY *ec = NULL;
-#endif
-/*char buf[1024];
-enif_get_atom(env,argv[0],buf,1024,ERL_NIF_LATIN1); printf("algo=%s ",buf);
-enif_get_atom(env,argv[1],buf,1024,ERL_NIF_LATIN1); printf("hash=%s ",buf);
-*/
 
 #ifndef HAS_ENGINE_SUPPORT
     if (enif_is_map(env, argv[3]))
         return atom_notsup;
 #endif
-
     i = get_pkey_sign_digest(env, argv[0], argv[1], argv[2], md_value, &md, &tbs, &tbslen);
     switch (i) {
     case PKEY_OK:
@@ -477,131 +453,83 @@ enif_get_atom(env,argv[1],buf,1024,ERL_NIF_LATIN1); printf("hash=%s ",buf);
         goto bad_arg;
     }
 
-    if (get_pkey_private_key(env, argv[0], argv[3], &pkey) != PKEY_OK)
-        goto bad_arg;
-
 #ifdef HAS_EVP_PKEY_CTX
-    if ((ctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL)
-        goto err;
+    { /* EVP_MD_CTX */
+        if (get_pkey_private_key(env, argv[0], argv[3], &pkey) != PKEY_OK)
+            goto bad_arg;
 
-    if (argv[0] != atom_eddsa) {
-        if (EVP_PKEY_sign_init(ctx) != 1)
+        if ((ctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL)
             goto err;
-        if (md != NULL) {
-            if (EVP_PKEY_CTX_set_signature_md(ctx, md) != 1)
+
+        if (argv[0] != atom_eddsa) {
+            if (EVP_PKEY_sign_init(ctx) != 1)
                 goto err;
+            if (md != NULL) {
+                if (EVP_PKEY_CTX_set_signature_md(ctx, md) != 1)
+                    goto err;
+            }
         }
-    }
 
-    if (argv[0] == atom_rsa) {
-        if (EVP_PKEY_CTX_set_rsa_padding(ctx, sig_opt.rsa_padding) != 1)
-            goto err;
+        if (argv[0] == atom_rsa) {
+            if (EVP_PKEY_CTX_set_rsa_padding(ctx, sig_opt.rsa_padding) != 1)
+                goto err;
 # ifdef HAVE_RSA_PKCS1_PSS_PADDING
-	if (sig_opt.rsa_padding == RSA_PKCS1_PSS_PADDING) {
-            if (sig_opt.rsa_mgf1_md != NULL) {
+            if (sig_opt.rsa_padding == RSA_PKCS1_PSS_PADDING) {
+                if (sig_opt.rsa_mgf1_md != NULL) {
 #  ifdef HAVE_RSA_MGF1_MD
-                if (EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, sig_opt.rsa_mgf1_md) != 1)
-                    goto err;
+                    if (EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, sig_opt.rsa_mgf1_md) != 1)
+                        goto err;
 #  else
-                goto notsup;
+                    goto notsup;
 #  endif
+                }
+                if (sig_opt.rsa_pss_saltlen > -2) {
+                    if (EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, sig_opt.rsa_pss_saltlen) != 1)
+                        goto err;
+                }
             }
-            if (sig_opt.rsa_pss_saltlen > -2) {
-                if (EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, sig_opt.rsa_pss_saltlen) != 1)
-                    goto err;
-            }
-        }
 # endif
-    }
+        }
 
-    if (argv[0] == atom_eddsa) {
+        if (argv[0] == atom_eddsa) {
 # ifdef HAVE_EDDSA
-        if (!FIPS_MODE()) {
-            if ((mdctx = EVP_MD_CTX_new()) == NULL)
-                goto err;
+            if (!FIPS_MODE()) {
+                EVP_MD_CTX *mdctx = NULL;
+                if ((mdctx = EVP_MD_CTX_new()) == NULL)
+                    goto err;
 
-            if (EVP_DigestSignInit(mdctx, NULL, NULL, NULL, pkey) != 1)
-                goto err;
-            if (EVP_DigestSign(mdctx, NULL, &siglen, tbs, tbslen) != 1)
+                if (EVP_DigestSignInit(mdctx, NULL, NULL, NULL, pkey) != 1)
+                    goto err;
+                if (EVP_DigestSign(mdctx, NULL, &siglen, tbs, tbslen) != 1)
+                    goto err;
+                if (!enif_alloc_binary(siglen, &sig_bin))
+                    goto err;
+                sig_bin_alloc = 1;
+
+                if (EVP_DigestSign(mdctx, sig_bin.data, &siglen, tbs, tbslen) != 1) {
+                    if (mdctx)
+                        EVP_MD_CTX_free(mdctx);
+                    goto bad_key;
+                }
+                if (mdctx)
+                    EVP_MD_CTX_free(mdctx);
+            }
+            else
+# endif
+                goto notsup;
+        } else {
+            if (EVP_PKEY_sign(ctx, NULL, &siglen, tbs, tbslen) != 1)
                 goto err;
             if (!enif_alloc_binary(siglen, &sig_bin))
                 goto err;
             sig_bin_alloc = 1;
 
-            if (EVP_DigestSign(mdctx, sig_bin.data, &siglen, tbs, tbslen) != 1)
+            if (md != NULL) {
+                ERL_VALGRIND_ASSERT_MEM_DEFINED(tbs, EVP_MD_size(md));
+            }
+            if (EVP_PKEY_sign(ctx, sig_bin.data, &siglen, tbs, tbslen) != 1)
                 goto bad_key;
         }
-        else
-# endif
-            goto notsup;
-    } else {
-        if (EVP_PKEY_sign(ctx, NULL, &siglen, tbs, tbslen) != 1)
-            goto err;
-        if (!enif_alloc_binary(siglen, &sig_bin))
-            goto err;
-        sig_bin_alloc = 1;
-
-        if (md != NULL) {
-            ERL_VALGRIND_ASSERT_MEM_DEFINED(tbs, EVP_MD_size(md));
-        }
-        if (EVP_PKEY_sign(ctx, sig_bin.data, &siglen, tbs, tbslen) != 1)
-            goto bad_key;
-    }
-#else
-/*printf("Old interface\r\n");
- */
-    if (argv[0] == atom_rsa) {
-        if ((rsa = EVP_PKEY_get1_RSA(pkey)) == NULL)
-            goto err;
-        if ((len = RSA_size(rsa)) < 0)
-            goto err;
-        if (!enif_alloc_binary((size_t)len, &sig_bin))
-            goto err;
-        sig_bin_alloc = 1;
-
-        if ((len = EVP_MD_size(md)) < 0)
-            goto err;
-        ERL_VALGRIND_ASSERT_MEM_DEFINED(tbs, len);
-
-        if (RSA_sign(md->type, tbs, (unsigned int)len, sig_bin.data, &siglen, rsa) != 1)
-            goto bad_key;
-    } else if (argv[0] == atom_dss) {
-        if ((dsa = EVP_PKEY_get1_DSA(pkey)) == NULL)
-            goto err;
-        if ((len = DSA_size(dsa)) < 0)
-            goto err;
-        if (!enif_alloc_binary((size_t)len, &sig_bin))
-            goto err;
-        sig_bin_alloc = 1;
-
-        if ((len = EVP_MD_size(md)) < 0)
-            goto err;
-        ERL_VALGRIND_ASSERT_MEM_DEFINED(tbs, len);
-
-        if (DSA_sign(md->type, tbs, len, sig_bin.data, &siglen, dsa) != 1)
-            goto bad_key;
-    } else if (argv[0] == atom_ecdsa) {
-#if defined(HAVE_EC)
-        if ((ec = EVP_PKEY_get1_EC_KEY(pkey)) == NULL)
-            goto err;
-        if ((len = ECDSA_size(ec)) < 0)
-            goto err;
-        if (!enif_alloc_binary((size_t)len, &sig_bin))
-            goto err;
-        sig_bin_alloc = 1;
-
-        len = EVP_MD_size(md);
-        ERL_VALGRIND_ASSERT_MEM_DEFINED(tbs, len);
-
-        if (ECDSA_sign(md->type, tbs, len, sig_bin.data, &siglen, ec) != 1)
-            goto bad_key;
-#else
-        goto notsup;
-#endif
-    } else {
-        goto bad_arg;
-    }
-#endif
 
     ERL_VALGRIND_MAKE_MEM_DEFINED(sig_bin.data, siglen);
     if (siglen != sig_bin.size) {
@@ -613,47 +541,138 @@ enif_get_atom(env,argv[1],buf,1024,ERL_NIF_LATIN1); printf("hash=%s ",buf);
     sig_bin_alloc = 0;
     goto done;
 
- bad_key:
+    bad_key:
     ret = atom_error;
     goto done;
 
- notsup:
+    notsup:
     ret = atom_notsup;
     goto done;
 
- bad_arg:
- err:
+    bad_arg:
+    err:
     ret = enif_make_badarg(env);
     goto done;
 
- done:
+    done:
     if (sig_bin_alloc)
         enif_release_binary(&sig_bin);
-    if (rsa)
-        RSA_free(rsa);
-#ifdef HAVE_DSA
-    if (dsa)
-        DSA_free(dsa);
-#endif
-#ifdef HAVE_EC
-    if (ec)
-        EC_KEY_free(ec);
-#endif
-#ifdef HAS_EVP_PKEY_CTX
     if (ctx)
         EVP_PKEY_CTX_free(ctx);
-#endif
     if (pkey)
         EVP_PKEY_free(pkey);
+    return ret;
+    }
+    /* End of HAS_EVP_PKEY_CTX */
+#else
+    /* Old interface - before EVP_PKEY_CTX */
+    {
+        if (get_pkey_private_key(env, argv[0], argv[3], &pkey) != PKEY_OK)
+            goto bad_arg;
 
-#ifdef HAVE_EDDSA
-    if (mdctx)
-        EVP_MD_CTX_free(mdctx);
+        if (argv[0] == atom_rsa) {
+            if ((rsa = EVP_PKEY_get1_RSA(pkey)) == NULL)
+                goto err;
+            if ((len = RSA_size(rsa)) < 0)
+                goto err;
+            if (!enif_alloc_binary((size_t)len, &sig_bin))
+                goto err;
+            sig_bin_alloc = 1;
+
+            if ((len = EVP_MD_size(md)) < 0)
+                goto err;
+            ERL_VALGRIND_ASSERT_MEM_DEFINED(tbs, len);
+
+            if (RSA_sign(md->type, tbs, (unsigned int)len, sig_bin.data, &siglen, rsa) != 1)
+                goto bad_key;
+        } else if (argv[0] == atom_dss) {
+            if ((dsa = EVP_PKEY_get1_DSA(pkey)) == NULL)
+                goto err;
+            if ((len = DSA_size(dsa)) < 0)
+                goto err;
+            if (!enif_alloc_binary((size_t)len, &sig_bin))
+                goto err;
+            sig_bin_alloc = 1;
+
+            if ((len = EVP_MD_size(md)) < 0)
+                goto err;
+            ERL_VALGRIND_ASSERT_MEM_DEFINED(tbs, len);
+
+            if (DSA_sign(md->type, tbs, len, sig_bin.data, &siglen, dsa) != 1)
+                goto bad_key;
+        } else if (argv[0] == atom_ecdsa) {
+# if defined(HAVE_EC)
+            if ((ec = EVP_PKEY_get1_EC_KEY(pkey)) == NULL)
+                goto err;
+            if ((len = ECDSA_size(ec)) < 0)
+                goto err;
+            if (!enif_alloc_binary((size_t)len, &sig_bin))
+                goto err;
+            sig_bin_alloc = 1;
+
+            len = EVP_MD_size(md);
+            ERL_VALGRIND_ASSERT_MEM_DEFINED(tbs, len);
+
+            if (ECDSA_sign(md->type, tbs, len, sig_bin.data, &siglen, ec) != 1)
+                goto bad_key;
+# else
+            goto notsup;
+# endif /* HAVE_EC */
+        } else {
+            goto bad_arg;
+        }
+
+        ERL_VALGRIND_MAKE_MEM_DEFINED(sig_bin.data, siglen);
+        if (siglen != sig_bin.size) {
+            if (!enif_realloc_binary(&sig_bin, siglen))
+                goto err;
+            ERL_VALGRIND_ASSERT_MEM_DEFINED(sig_bin.data, siglen);
+        }
+        ret = enif_make_binary(env, &sig_bin);
+        sig_bin_alloc = 0;
+        goto done;
+
+    bad_key:
+        ret = atom_error;
+        goto done;
+
+    notsup:
+        ret = atom_notsup;
+        goto done;
+
+    bad_arg:
+    err:
+        ret = enif_make_badarg(env);
+        goto done;
+
+    done:
+        if (sig_bin_alloc)
+            enif_release_binary(&sig_bin);
+        if (rsa)
+            RSA_free(rsa);
+# ifdef HAVE_DSA
+        if (dsa)
+            DSA_free(dsa);
+# endif
+# ifdef HAVE_EC
+        if (ec)
+            EC_KEY_free(ec);
+# endif
+# ifdef HAS_EVP_PKEY_CTX
+        if (ctx)
+            EVP_PKEY_CTX_free(ctx);
+# endif
+        if (pkey)
+            EVP_PKEY_free(pkey);
+
+        return ret;
+    }
 #endif
 
-    return ret;
 }
 
+
+
 ERL_NIF_TERM pkey_verify_nif(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
 {/* (Algorithm, Type, Data|{digest,Digest}, Signature, Key, Options) */
     int i;
@@ -661,25 +680,24 @@ ERL_NIF_TERM pkey_verify_nif(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]
     const EVP_MD *md = NULL;
     unsigned char md_value[EVP_MAX_MD_SIZE];
     EVP_PKEY *pkey = NULL;
-#ifdef HAS_EVP_PKEY_CTX
-    EVP_PKEY_CTX *ctx = NULL;
-#else
-#endif
     PKeySignOptions sig_opt;
     ErlNifBinary sig_bin; /* signature */
     unsigned char *tbs = NULL; /* data to be signed */
     size_t tbslen = 0;
     ERL_NIF_TERM ret;
+
+#ifdef HAS_EVP_PKEY_CTX
+    EVP_PKEY_CTX *ctx = NULL;
+#else
     RSA *rsa = NULL;
-#ifdef HAVE_DSA
-    DSA *dsa = NULL;
-#endif
-#ifdef HAVE_EC
-    EC_KEY *ec = NULL;
-#endif
-#ifdef HAVE_EDDSA
-    EVP_MD_CTX *mdctx = NULL;
-#endif
+# ifdef HAVE_DSA
+        DSA *dsa = NULL;
+# endif
+# ifdef HAVE_EC
+        EC_KEY *ec = NULL;
+# endif
+#endif  // HAS_EVP_PKEY_CTX
+
 
 #ifndef HAS_ENGINE_SUPPORT
     if (enif_is_map(env, argv[4]))
@@ -709,128 +727,146 @@ ERL_NIF_TERM pkey_verify_nif(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]
         goto bad_arg;
     }
 
-    if (get_pkey_public_key(env, argv[0], argv[4], &pkey) != PKEY_OK) {
-        goto bad_arg;
-    }
-
 #ifdef HAS_EVP_PKEY_CTX
-/* printf("EVP interface\r\n");
- */
-    if ((ctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL)
-        goto err;
+    /* EVP_PKEY_CTX */
+    {
+        if (get_pkey_public_key(env, argv[0], argv[4], &pkey) != PKEY_OK)
+            goto bad_arg;
 
-    if (argv[0] != atom_eddsa) {
-        if (EVP_PKEY_verify_init(ctx) != 1)
+        if ((ctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL)
             goto err;
-        if (md != NULL) {
-            if (EVP_PKEY_CTX_set_signature_md(ctx, md) != 1)
+
+        if (argv[0] != atom_eddsa) {
+            if (EVP_PKEY_verify_init(ctx) != 1)
                 goto err;
+            if (md != NULL) {
+                if (EVP_PKEY_CTX_set_signature_md(ctx, md) != 1)
+                    goto err;
+            }
         }
-    }
 
-    if (argv[0] == atom_rsa) {
-        if (EVP_PKEY_CTX_set_rsa_padding(ctx, sig_opt.rsa_padding) != 1)
-            goto err;
-        if (sig_opt.rsa_padding == RSA_PKCS1_PSS_PADDING) {
-            if (sig_opt.rsa_mgf1_md != NULL) {
+        if (argv[0] == atom_rsa) {
+            if (EVP_PKEY_CTX_set_rsa_padding(ctx, sig_opt.rsa_padding) != 1)
+                goto err;
+            if (sig_opt.rsa_padding == RSA_PKCS1_PSS_PADDING) {
+                if (sig_opt.rsa_mgf1_md != NULL) {
 # ifdef HAVE_RSA_MGF1_MD
-                if (EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, sig_opt.rsa_mgf1_md) != 1)
-                    goto err;
+                    if (EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, sig_opt.rsa_mgf1_md) != 1)
+                        goto err;
 # else
-                goto notsup;
+                    goto notsup;
 # endif
+                }
+                if (sig_opt.rsa_pss_saltlen > -2) {
+                    if (EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, sig_opt.rsa_pss_saltlen) != 1)
+                        goto err;
+                }
             }
-            if (sig_opt.rsa_pss_saltlen > -2) {
-                if (EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, sig_opt.rsa_pss_saltlen) != 1)
+        }
+
+        if (argv[0] == atom_eddsa) {
+# ifdef HAVE_EDDSA
+            EVP_MD_CTX *mdctx = NULL;
+            if (!FIPS_MODE()) {
+                if ((mdctx = EVP_MD_CTX_new()) == NULL)
                     goto err;
+
+                if (EVP_DigestVerifyInit(mdctx, NULL, NULL, NULL, pkey) != 1)
+                    goto err;
+
+                result = EVP_DigestVerify(mdctx, sig_bin.data, sig_bin.size, tbs, tbslen);
+                if (mdctx)
+                    EVP_MD_CTX_free(mdctx);
+            }
+            else
+# endif /* HAVE_EDDSA */
+                goto notsup;
+        } else {
+            /* RSA or DSS */
+            if (md != NULL) {
+                ERL_VALGRIND_ASSERT_MEM_DEFINED(tbs, EVP_MD_size(md));
             }
+            result = EVP_PKEY_verify(ctx, sig_bin.data, sig_bin.size, tbs, tbslen);
         }
-    }
+        ret = (result == 1 ? atom_true : atom_false);
+        goto done;
 
-    if (argv[0] == atom_eddsa) {
-#ifdef HAVE_EDDSA
-        if (!FIPS_MODE()) {
-            if ((mdctx = EVP_MD_CTX_new()) == NULL)
-                goto err;
+    bad_arg:
+    err:
+        ret = enif_make_badarg(env);
+        goto done;
 
-            if (EVP_DigestVerifyInit(mdctx, NULL, NULL, NULL, pkey) != 1)
-                goto err;
+    notsup:
+        ret = atom_notsup;
 
-            result = EVP_DigestVerify(mdctx, sig_bin.data, sig_bin.size, tbs, tbslen);
-        }
-        else
-#endif
-        goto notsup;
-    } else {
-        if (md != NULL) {
-            ERL_VALGRIND_ASSERT_MEM_DEFINED(tbs, EVP_MD_size(md));
-        }
-        result = EVP_PKEY_verify(ctx, sig_bin.data, sig_bin.size, tbs, tbslen);
+    done:
+        if (ctx)
+            EVP_PKEY_CTX_free(ctx);
+        if (pkey)
+            EVP_PKEY_free(pkey);
+
+        return ret;
     }
+    /* End of HAS_EVP_PKEY_CTX */
 #else
-/*printf("Old interface\r\n");
-*/
-    if (tbslen > INT_MAX)
-        goto bad_arg;
-    if (sig_bin.size > INT_MAX)
-        goto bad_arg;
-    if (argv[0] == atom_rsa) {
-        if ((rsa = EVP_PKEY_get1_RSA(pkey)) == NULL)
-            goto err;
-        result = RSA_verify(md->type, tbs, (unsigned int)tbslen, sig_bin.data, (unsigned int)sig_bin.size, rsa);
-    } else if (argv[0] == atom_dss) {
-        if ((dsa = EVP_PKEY_get1_DSA(pkey)) == NULL)
-            goto err;
-        result = DSA_verify(0, tbs, (int)tbslen, sig_bin.data, (int)sig_bin.size, dsa);
-    } else if (argv[0] == atom_ecdsa) {
-#if defined(HAVE_EC)
-        if ((ec = EVP_PKEY_get1_EC_KEY(pkey)) == NULL)
-            goto err;
-        result = ECDSA_verify(EVP_MD_type(md), tbs, (int)tbslen, sig_bin.data, (int)sig_bin.size, ec);
-#else
-        goto notsup;
-#endif
-    } else {
-        goto bad_arg;
-    }
-#endif
-
-    ret = (result == 1 ? atom_true : atom_false);
-    goto done;
+    /* Old interface - before EVP_PKEY_CTX */
+    {
+        if (get_pkey_public_key(env, argv[0], argv[4], &pkey) != PKEY_OK)
+            goto bad_arg;
 
- bad_arg:
- err:
-    ret = enif_make_badarg(env);
-    goto done;
+        if (tbslen > INT_MAX)
+            goto bad_arg;
+        if (sig_bin.size > INT_MAX)
+            goto bad_arg;
+        if (argv[0] == atom_rsa) {
+            if ((rsa = EVP_PKEY_get1_RSA(pkey)) == NULL)
+                goto err;
+            result = RSA_verify(md->type, tbs, (unsigned int)tbslen, sig_bin.data, (unsigned int)sig_bin.size, rsa);
+        } else if (argv[0] == atom_dss) {
+            if ((dsa = EVP_PKEY_get1_DSA(pkey)) == NULL)
+                goto err;
+            result = DSA_verify(0, tbs, (int)tbslen, sig_bin.data, (int)sig_bin.size, dsa);
+        } else if (argv[0] == atom_ecdsa) {
+# if defined(HAVE_EC)
+            if ((ec = EVP_PKEY_get1_EC_KEY(pkey)) == NULL)
+                goto err;
+            result = ECDSA_verify(EVP_MD_type(md), tbs, (int)tbslen, sig_bin.data, (int)sig_bin.size, ec);
+# else
+            goto notsup;
+# endif /* HAVE_EC */
+        } else {
+            goto bad_arg;
+        }
+        ret = (result == 1 ? atom_true : atom_false);
+        goto done;
 
- notsup:
-    ret = atom_notsup;
+    bad_arg:
+    err:
+        ret = enif_make_badarg(env);
+        goto done;
+    notsup:
+        ret = atom_notsup;
+    done:
+        if (rsa)
+            RSA_free(rsa);
+# ifdef HAVE_DSA
+        if (dsa)
+            DSA_free(dsa);
+# endif
+# ifdef HAVE_EC
+        if (ec)
+            EC_KEY_free(ec);
+# endif
+        if (pkey)
+            EVP_PKEY_free(pkey);
 
- done:
-#ifdef HAS_EVP_PKEY_CTX
-    if (ctx)
-        EVP_PKEY_CTX_free(ctx);
-#endif
-#ifdef HAVE_EDDSA
-    if (mdctx)
-        EVP_MD_CTX_free(mdctx);
-#endif
-    if (pkey)
-        EVP_PKEY_free(pkey);
-    if (rsa)
-        RSA_free(rsa);
-#ifdef HAVE_DSA
-    if (dsa)
-        DSA_free(dsa);
-#endif
-#ifdef HAVE_EC
-    if (ec)
-        EC_KEY_free(ec);
-#endif
+        return ret;
+    }
+#endif /* Pre  EVP_PKEY_CTX */
 
-    return ret;
 }
 
+
 static int get_pkey_crypt_options(ErlNifEnv *env, ERL_NIF_TERM algorithm, ERL_NIF_TERM options,
 				  PKeyCryptOptions *opt)
 {
-- 
2.34.1

openSUSE Build Service is sponsored by