From f2945905fbae7728869bffb9e034604cafcffb49 Mon Sep 17 00:00:00 2001
From: Ryan Kelley <ryan.parker.kelley@gmail.com>
Date: Thu, 18 Jan 2024 14:37:52 -0500
Subject: [PATCH] openssl: fix cppcheck found NULL dereferences (#1304)

* Fix NULL dereference in gen_publickey_from_rsa_evp and
  gen_publickey_from_dsa_evp.
* Add checks for en_publickey_from_ec_evp and en_publickey_from_ed_evp

Reference:https://github.com/libssh2/libssh2/commit/f2945905fbae7728869bffb9e034604cafcffb49
Conflict:b0ab005fe792(openssl: use non-deprecated APIs with OpenSSL3.x)
         ed439a29bb04(Support for sk-ecdsa-sha2-nistp256 and sk-ssh-ed25519 keys)

---
 src/openssl.c | 83 ++++++++++++++++++++++++++++++++-------------------
 1 file changed, 53 insertions(+), 30 deletions(-)

diff --git a/src/openssl.c b/src/openssl.c
index 919a8d9..905af3e 100644
--- a/src/openssl.c
+++ b/src/openssl.c
@@ -820,10 +820,14 @@ gen_publickey_from_rsa_evp(LIBSSH2_SESSION *session,
     RSA_free(rsa);
 
     memcpy(method_buf, "ssh-rsa", 7);
-    *method         = method_buf;
-    *method_len     = 7;
-    *pubkeydata     = key;
-    *pubkeydata_len = key_len;
+    *method = method_buf;
+    if(method_len) {
+        *method_len = 7;
+    }
+    *pubkeydata = key;
+    if(pubkeydata_len) {
+        *pubkeydata_len = key_len;
+    }
     return 0;
 
 __alloc_error:
@@ -1219,10 +1223,14 @@ gen_publickey_from_dsa_evp(LIBSSH2_SESSION *session,
     DSA_free(dsa);
 
     memcpy(method_buf, "ssh-dss", 7);
-    *method         = method_buf;
-    *method_len     = 7;
-    *pubkeydata     = key;
-    *pubkeydata_len = key_len;
+    *method = method_buf;
+    if(method_len) {
+        *method_len = 7;
+    }
+    *pubkeydata = key;
+    if(pubkeydata_len) {
+        *pubkeydata_len = key_len;
+    }
     return 0;
 
 __alloc_error:
@@ -1589,10 +1597,14 @@ gen_publickey_from_ed_evp(LIBSSH2_SESSION *session,
         goto fail;
     }
 
-    *method         = methodBuf;
-    *method_len     = sizeof(methodName) - 1;
-    *pubkeydata     = keyBuf;
-    *pubkeydata_len = bufLen;
+    *method = methodBuf;
+    if(method_len) {
+        *method_len = sizeof(methodName) - 1;
+    }
+    *pubkeydata = keyBuf;
+    if(pubkeydata_len) {
+        *pubkeydata_len = bufLen;
+    }
     return 0;
 
 fail:
@@ -2561,6 +2573,7 @@ gen_publickey_from_ec_evp(LIBSSH2_SESSION *session,
     unsigned char *p;
     unsigned char *method_buf = NULL;
     unsigned char *key;
+    size_t  method_buf_len = 0;
     size_t  key_len = 0;
     unsigned char *octal_value = NULL;
     size_t octal_len;
@@ -2588,24 +2601,29 @@ gen_publickey_from_ec_evp(LIBSSH2_SESSION *session,
     type = _libssh2_ecdsa_get_curve_type(ec);
 
     if(is_sk)
-        *method_len = 34;
+        method_buf_len = 34;
     else
-        *method_len = 19;
+        method_buf_len = 19;
 
-    method_buf = LIBSSH2_ALLOC(session, *method_len);
+    method_buf = LIBSSH2_ALLOC(session, method_buf_len);
     if(!method_buf) {
         return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
                               "out of memory");
     }
 
-    if(is_sk)
-        memcpy(method_buf, "sk-ecdsa-sha2-nistp256@openssh.com", *method_len);
-    else if(type == LIBSSH2_EC_CURVE_NISTP256)
-        memcpy(method_buf, "ecdsa-sha2-nistp256", *method_len);
-    else if(type == LIBSSH2_EC_CURVE_NISTP384)
-        memcpy(method_buf, "ecdsa-sha2-nistp384", *method_len);
-    else if(type == LIBSSH2_EC_CURVE_NISTP521)
-        memcpy(method_buf, "ecdsa-sha2-nistp521", *method_len);
+    if(is_sk) {
+        memcpy(method_buf, "sk-ecdsa-sha2-nistp256@openssh.com",
+               method_buf_len);
+    }
+    else if(type == LIBSSH2_EC_CURVE_NISTP256) {
+        memcpy(method_buf, "ecdsa-sha2-nistp256", method_buf_len);
+    }
+    else if(type == LIBSSH2_EC_CURVE_NISTP384) {
+        memcpy(method_buf, "ecdsa-sha2-nistp384", method_buf_len);
+    }
+    else if(type == LIBSSH2_EC_CURVE_NISTP521) {
+        memcpy(method_buf, "ecdsa-sha2-nistp521", method_buf_len);
+    }
     else {
         _libssh2_debug((session,
                        LIBSSH2_TRACE_ERROR,
@@ -2636,9 +2654,9 @@ gen_publickey_from_ec_evp(LIBSSH2_SESSION *session,
         goto clean_exit;
     }
 
-    /* Key form is: type_len(4) + type(method_len) + domain_len(4) + domain(8)
-       + pub_key_len(4) + pub_key(~65). */
-    key_len = 4 + *method_len + 4 + 8 + 4 + octal_len;
+    /* Key form is: type_len(4) + type(method_buf_len) + domain_len(4)
+       + domain(8) + pub_key_len(4) + pub_key(~65). */
+    key_len = 4 + method_buf_len + 4 + 8 + 4 + octal_len;
     key = LIBSSH2_ALLOC(session, key_len);
     if(!key) {
         rc = -1;
@@ -2649,7 +2667,7 @@ gen_publickey_from_ec_evp(LIBSSH2_SESSION *session,
     p = key;
 
     /* Key type */
-    _libssh2_store_str(&p, (const char *)method_buf, *method_len);
+    _libssh2_store_str(&p, (const char *)method_buf, method_buf_len);
 
     /* Name domain */
     if(is_sk) {
@@ -2662,9 +2680,14 @@ gen_publickey_from_ec_evp(LIBSSH2_SESSION *session,
     /* Public key */
     _libssh2_store_str(&p, (const char *)octal_value, octal_len);
 
-    *method         = method_buf;
-    *pubkeydata     = key;
-    *pubkeydata_len = key_len;
+    *method = method_buf;
+    if(method_len) {
+        *method_len = method_buf_len;
+    }
+    *pubkeydata = key;
+    if(pubkeydata_len) {
+        *pubkeydata_len = key_len;
+    }
 
 clean_exit:
 
-- 
2.33.0

