File 8655-crypto-Internal-pkey.c.-Include-extra-arg-and-argv-a.patch of Package erlang

From d36e1fed14f9bdc6d7d7ba6bd12e50c2a1312df8 Mon Sep 17 00:00:00 2001
From: Hans Nilsson <hans@erlang.org>
Date: Fri, 11 Mar 2022 14:18:12 +0100
Subject: [PATCH 5/8] crypto: Internal pkey.c.  Include extra arg and
 argv/arg-nums

for propagating error message upwards and
to be able to point at erroneous argument.
---
 lib/crypto/c_src/pkey.c | 102 +++++++++++++++++++++++-----------------
 1 file changed, 60 insertions(+), 42 deletions(-)

diff --git a/lib/crypto/c_src/pkey.c b/lib/crypto/c_src/pkey.c
index d395806b7e..0423fbd470 100644
--- a/lib/crypto/c_src/pkey.c
+++ b/lib/crypto/c_src/pkey.c
@@ -47,24 +47,34 @@ typedef struct PKeySignOptions {
 
 
 static int get_pkey_digest_type(ErlNifEnv *env, ERL_NIF_TERM algorithm, ERL_NIF_TERM type,
-				const EVP_MD **md);
-static int get_pkey_sign_digest(ErlNifEnv *env, ERL_NIF_TERM algorithm,
-				ERL_NIF_TERM type, ERL_NIF_TERM data,
+				const EVP_MD **md,
+                                ERL_NIF_TERM *err_return);
+static int get_pkey_sign_digest(ErlNifEnv *env,
+                                const ERL_NIF_TERM argv[],
+                                int algorithm_arg_num, int type_arg_num, int data_arg_num,
 				unsigned char *md_value, const EVP_MD **mdp,
-				unsigned char **tbsp, size_t *tbslenp);
-static int get_pkey_sign_options(ErlNifEnv *env, ERL_NIF_TERM algorithm, ERL_NIF_TERM options,
-                                 const EVP_MD *md, PKeySignOptions *opt);
+				unsigned char **tbsp, size_t *tbslenp,
+                                ERL_NIF_TERM *err_return);
+static int get_pkey_sign_options(ErlNifEnv *env,
+                                 const ERL_NIF_TERM argv[],
+                                 int algorithm_arg_num, int options_arg_num,
+                                 const EVP_MD *md, PKeySignOptions *opt,
+                                 ERL_NIF_TERM *err_return);
 static int get_pkey_private_key(ErlNifEnv *env, ERL_NIF_TERM algorithm, ERL_NIF_TERM key, EVP_PKEY **pkey);
 static int get_pkey_public_key(ErlNifEnv *env, ERL_NIF_TERM algorithm, ERL_NIF_TERM key,
 			       EVP_PKEY **pkey);
-static int get_pkey_crypt_options(ErlNifEnv *env, ERL_NIF_TERM algorithm, ERL_NIF_TERM options,
-				  PKeyCryptOptions *opt);
+static int get_pkey_crypt_options(ErlNifEnv *env,
+                                  const ERL_NIF_TERM argv[],
+                                  int algorithm_arg_num, int options_arg_num,
+				  PKeyCryptOptions *opt,
+                                  ERL_NIF_TERM *err_return);
 #ifdef HAVE_RSA_SSLV23_PADDING
 static size_t size_of_RSA(EVP_PKEY *pkey);
 #endif
 
 static int get_pkey_digest_type(ErlNifEnv *env, ERL_NIF_TERM algorithm, ERL_NIF_TERM type,
-				const EVP_MD **md)
+				const EVP_MD **md,
+                                ERL_NIF_TERM *err_return)
 {
     struct digest_type_t *digp = NULL;
     *md = NULL;
@@ -89,10 +99,12 @@ static int get_pkey_digest_type(ErlNifEnv *env, ERL_NIF_TERM algorithm, ERL_NIF_
     return PKEY_OK;
 }
 
-static int get_pkey_sign_digest(ErlNifEnv *env, ERL_NIF_TERM algorithm,
-				ERL_NIF_TERM type, ERL_NIF_TERM data,
+static int get_pkey_sign_digest(ErlNifEnv *env,
+                                const ERL_NIF_TERM argv[],
+                                int algorithm_arg_num, int type_arg_num, int data_arg_num,
 				unsigned char *md_value, const EVP_MD **mdp,
-				unsigned char **tbsp, size_t *tbslenp)
+				unsigned char **tbsp, size_t *tbslenp,
+                                ERL_NIF_TERM *err_return)
 {
     int i, ret;
     const ERL_NIF_TERM *tpl_terms;
@@ -108,10 +120,10 @@ static int get_pkey_sign_digest(ErlNifEnv *env, ERL_NIF_TERM algorithm,
     tbs = *tbsp;
     tbslen = *tbslenp;
 
-    if ((i = get_pkey_digest_type(env, algorithm, type, &md)) != PKEY_OK)
+    if ((i = get_pkey_digest_type(env, argv[algorithm_arg_num], argv[type_arg_num], &md, err_return)) != PKEY_OK)
         return i;
 
-    if (enif_get_tuple(env, data, &tpl_arity, &tpl_terms)) {
+    if (enif_get_tuple(env, argv[data_arg_num], &tpl_arity, &tpl_terms)) {
         if (tpl_arity != 2)
             goto bad_arg;
         if (tpl_terms[0] != atom_digest)
@@ -129,14 +141,14 @@ static int get_pkey_sign_digest(ErlNifEnv *env, ERL_NIF_TERM algorithm,
 	tbs = tbs_bin.data;
 	tbslen = tbs_bin.size;
     } else if (md == NULL) {
-        if (!enif_inspect_iolist_as_binary(env, data, &tbs_bin))
+        if (!enif_inspect_iolist_as_binary(env, argv[data_arg_num], &tbs_bin))
             goto bad_arg;
 
         /* md == NULL, that is no hashing because DigestType argument was atom_none */
 	tbs = tbs_bin.data;
 	tbslen = tbs_bin.size;
     } else {
-        if (!enif_inspect_iolist_as_binary(env, data, &tbs_bin))
+        if (!enif_inspect_iolist_as_binary(env, argv[data_arg_num], &tbs_bin))
             goto bad_arg;
 
         /* We have the cleartext in tbs_bin and the hash algo info in md */
@@ -173,19 +185,22 @@ static int get_pkey_sign_digest(ErlNifEnv *env, ERL_NIF_TERM algorithm,
     return ret;
 }
 
-static int get_pkey_sign_options(ErlNifEnv *env, ERL_NIF_TERM algorithm, ERL_NIF_TERM options,
-                                 const EVP_MD *md, PKeySignOptions *opt)
+static int get_pkey_sign_options(ErlNifEnv *env,
+                                 const ERL_NIF_TERM argv[],
+                                 int algorithm_arg_num, int options_arg_num,
+                                 const EVP_MD *md, PKeySignOptions *opt,
+                                 ERL_NIF_TERM *err_return)
 {
     ERL_NIF_TERM head, tail;
     const ERL_NIF_TERM *tpl_terms;
     int tpl_arity;
     const EVP_MD *opt_md;
 
-    if (!enif_is_list(env, options))
+    if (!enif_is_list(env, argv[options_arg_num]))
         goto bad_arg;
 
     /* defaults */
-    if (algorithm == atom_rsa) {
+    if (argv[algorithm_arg_num] == atom_rsa) {
 	opt->rsa_mgf1_md = NULL;
 	opt->rsa_padding = RSA_PKCS1_PADDING;
 	opt->rsa_pss_saltlen = -2;
@@ -195,13 +210,13 @@ static int get_pkey_sign_options(ErlNifEnv *env, ERL_NIF_TERM algorithm, ERL_NIF
 	opt->rsa_pss_saltlen = 0;
     }
 
-    if (enif_is_empty_list(env, options))
+    if (enif_is_empty_list(env, argv[options_arg_num]))
 	return PKEY_OK;
 
-    if (algorithm != atom_rsa)
+    if (argv[algorithm_arg_num] != atom_rsa)
         goto bad_arg;
 
-    tail = options;
+    tail = argv[options_arg_num];
     while (enif_get_list_cell(env, tail, &head, &tail)) {
         if (!enif_get_tuple(env, head, &tpl_arity, &tpl_terms))
             goto bad_arg;
@@ -211,7 +226,7 @@ static int get_pkey_sign_options(ErlNifEnv *env, ERL_NIF_TERM algorithm, ERL_NIF
         if (tpl_terms[0] == atom_rsa_mgf1_md && enif_is_atom(env, tpl_terms[1])) {
             int result;
 
-            result = get_pkey_digest_type(env, algorithm, tpl_terms[1], &opt_md);
+            result = get_pkey_digest_type(env, argv[algorithm_arg_num], tpl_terms[1], &opt_md, err_return);
             if (result != PKEY_OK)
                 return result;
 
@@ -406,7 +421,7 @@ ERL_NIF_TERM pkey_sign_nif(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
 {/* (Algorithm, Type, Data|{digest,Digest}, Key|#{}, Options) */
     int i;
     int sig_bin_alloc = 0;
-    ERL_NIF_TERM ret;
+    ERL_NIF_TERM ret = atom_undefined;
     const EVP_MD *md = NULL;
     unsigned char md_value[EVP_MAX_MD_SIZE];
     EVP_PKEY *pkey = NULL;
@@ -433,7 +448,7 @@ ERL_NIF_TERM pkey_sign_nif(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
     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);
+    i = get_pkey_sign_digest(env, argv, 0, 1, 2, md_value, &md, &tbs, &tbslen, &ret);
     switch (i) {
     case PKEY_OK:
         break;
@@ -443,7 +458,7 @@ ERL_NIF_TERM pkey_sign_nif(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
         goto bad_arg;
     }
 
-    i = get_pkey_sign_options(env, argv[0], argv[4], md, &sig_opt);
+    i = get_pkey_sign_options(env, argv, 0, 4, md, &sig_opt, &ret);
     switch (i) {
     case PKEY_OK:
         break;
@@ -684,7 +699,7 @@ ERL_NIF_TERM pkey_verify_nif(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]
     ErlNifBinary sig_bin; /* signature */
     unsigned char *tbs = NULL; /* data to be signed */
     size_t tbslen = 0;
-    ERL_NIF_TERM ret;
+    ERL_NIF_TERM ret = atom_undefined;
 
 #ifdef HAS_EVP_PKEY_CTX
     EVP_PKEY_CTX *ctx = NULL;
@@ -707,7 +722,7 @@ ERL_NIF_TERM pkey_verify_nif(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]
     if (!enif_inspect_binary(env, argv[3], &sig_bin))
 	return enif_make_badarg(env);
 
-    i = get_pkey_sign_digest(env, argv[0], argv[1], argv[2], md_value, &md, &tbs, &tbslen);
+    i = get_pkey_sign_digest(env, argv, 0, 1, 2, md_value, &md, &tbs, &tbslen, &ret);
     switch (i) {
     case PKEY_OK:
         break;
@@ -717,7 +732,7 @@ ERL_NIF_TERM pkey_verify_nif(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]
         goto bad_arg;
     }
 
-    i = get_pkey_sign_options(env, argv[0], argv[5], md, &sig_opt);
+    i = get_pkey_sign_options(env, argv, 0, 5, md, &sig_opt, &ret);
     switch (i) {
     case PKEY_OK:
         break;
@@ -867,19 +882,22 @@ ERL_NIF_TERM pkey_verify_nif(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]
 }
 
 
-static int get_pkey_crypt_options(ErlNifEnv *env, ERL_NIF_TERM algorithm, ERL_NIF_TERM options,
-				  PKeyCryptOptions *opt)
+static int get_pkey_crypt_options(ErlNifEnv *env,
+                                  const ERL_NIF_TERM argv[],
+                                  int algorithm_arg_num, int options_arg_num,
+				  PKeyCryptOptions *opt,
+                                  ERL_NIF_TERM *err_return)
 {
     ERL_NIF_TERM head, tail;
     const ERL_NIF_TERM *tpl_terms;
     int tpl_arity;
     const EVP_MD *opt_md;
 
-    if (!enif_is_list(env, options))
+    if (!enif_is_list(env, argv[options_arg_num]))
         goto bad_arg;
 
     /* defaults */
-    if (algorithm == atom_rsa) {
+    if (argv[algorithm_arg_num] == atom_rsa) {
         opt->rsa_mgf1_md = NULL;
         opt->rsa_oaep_label.data = NULL;
         opt->rsa_oaep_label.size = 0;
@@ -895,13 +913,13 @@ static int get_pkey_crypt_options(ErlNifEnv *env, ERL_NIF_TERM algorithm, ERL_NI
         opt->signature_md = NULL;
     }
 
-    if (enif_is_empty_list(env, options))
+    if (enif_is_empty_list(env, argv[options_arg_num]))
         return PKEY_OK;
 
-    if (algorithm != atom_rsa)
+    if (argv[algorithm_arg_num] != atom_rsa)
         goto bad_arg;
 
-    tail = options;
+    tail = argv[options_arg_num];
     while (enif_get_list_cell(env, tail, &head, &tail)) {
         if (!enif_get_tuple(env, head, &tpl_arity, &tpl_terms))
             goto bad_arg;
@@ -936,7 +954,7 @@ static int get_pkey_crypt_options(ErlNifEnv *env, ERL_NIF_TERM algorithm, ERL_NI
 
         } else if (tpl_terms[0] == atom_signature_md && enif_is_atom(env, tpl_terms[1])) {
             int i;
-            i = get_pkey_digest_type(env, algorithm, tpl_terms[1], &opt_md);
+            i = get_pkey_digest_type(env, argv[algorithm_arg_num], tpl_terms[1], &opt_md, err_return);
             if (i != PKEY_OK) {
                 return i;
             }
@@ -948,7 +966,7 @@ static int get_pkey_crypt_options(ErlNifEnv *env, ERL_NIF_TERM algorithm, ERL_NI
             if (tpl_terms[1] != atom_sha)
                 return PKEY_NOTSUP;
 #endif
-            i = get_pkey_digest_type(env, algorithm, tpl_terms[1], &opt_md);
+            i = get_pkey_digest_type(env, argv[algorithm_arg_num], tpl_terms[1], &opt_md, err_return);
             if (i != PKEY_OK) {
                 return i;
             }
@@ -968,7 +986,7 @@ static int get_pkey_crypt_options(ErlNifEnv *env, ERL_NIF_TERM algorithm, ERL_NI
             if (tpl_terms[1] != atom_sha)
                 return PKEY_NOTSUP;
 #endif
-            i = get_pkey_digest_type(env, algorithm, tpl_terms[1], &opt_md);
+            i = get_pkey_digest_type(env, argv[algorithm_arg_num], tpl_terms[1], &opt_md, err_return);
             if (i != PKEY_OK) {
                 return i;
             }
@@ -1004,7 +1022,7 @@ static size_t size_of_RSA(EVP_PKEY *pkey) {
 
 ERL_NIF_TERM pkey_crypt_nif(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
 {/* (Algorithm, Data, PublKey=[E,N]|[E,N,D]|[E,N,D,P1,P2,E1,E2,C], Options, IsPrivate, IsEncrypt) */
-    ERL_NIF_TERM ret;
+    ERL_NIF_TERM ret = atom_undefined;
     int i;
     int result = 0;
     int tmp_bin_alloc = 0;
@@ -1041,7 +1059,7 @@ ERL_NIF_TERM pkey_crypt_nif(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
     if (!enif_inspect_binary(env, argv[1], &in_bin))
         goto bad_arg;
 
-    i = get_pkey_crypt_options(env, argv[0], argv[3], &crypt_opt);
+    i = get_pkey_crypt_options(env, argv, 0, 3, &crypt_opt, &ret);
     switch (i) {
     case PKEY_OK:
         break;
-- 
2.34.1

openSUSE Build Service is sponsored by