]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Fix EVP_PKEY_CTX_dup() so that it copies the keymanager.
authorslontis <shane.lontis@oracle.com>
Wed, 9 Apr 2025 00:05:09 +0000 (10:05 +1000)
committerMatt Caswell <matt@openssl.org>
Tue, 15 Apr 2025 14:50:31 +0000 (15:50 +0100)
A call to EVP_PKEY_CTX_new() creates a keymgmt pointer internally,
but EVP_PKEY_CTX_dup() does not copy this field.

Calling EVP_PKEY_derive_set_peer_ex() after EVP_PKEY_CTX_dup() resulted
in a segfault because it tried to access this pointer.

EVP_PKEY_CTX_dup() has been updated to copy the keymanager (and upref it).

Reported by Eamon ODea (Oracle).

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <ppzgs1@gmail.com>
(Merged from https://github.com/openssl/openssl/pull/27304)

(cherry picked from commit 3c22da73465f5dd211299e64f0de8786dcaf86c3)

crypto/evp/pmeth_lib.c
test/ectest.c

index 245ca2d41d72c78746c164172abc481e5039da15..b7253f115053787b866a18d3cbdd6dcf173be1cc 100644 (file)
@@ -501,6 +501,12 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx)
     }
     rctx->legacy_keytype = pctx->legacy_keytype;
 
+    if (pctx->keymgmt != NULL) {
+        if (!EVP_KEYMGMT_up_ref(pctx->keymgmt))
+            goto err;
+        rctx->keymgmt = pctx->keymgmt;
+    }
+
     if (EVP_PKEY_CTX_IS_DERIVE_OP(pctx)) {
         if (pctx->op.kex.exchange != NULL) {
             rctx->op.kex.exchange = pctx->op.kex.exchange;
index 946973c2f4d9fdb6d6429e262800d06feed4c72d..0318bc9eae79fa9f713d27b10cfcb654d287986a 100644 (file)
@@ -2707,7 +2707,7 @@ static int custom_params_test(int id)
     int is_prime = 0;
     EC_KEY *eckey1 = NULL, *eckey2 = NULL;
     EVP_PKEY *pkey1 = NULL, *pkey2 = NULL;
-    EVP_PKEY_CTX *pctx1 = NULL, *pctx2 = NULL;
+    EVP_PKEY_CTX *pctx1 = NULL, *pctx2 = NULL, *dctx = NULL;
     size_t sslen, t;
     unsigned char *pub1 = NULL , *pub2 = NULL;
     OSSL_PARAM_BLD *param_bld = NULL;
@@ -2930,11 +2930,12 @@ static int custom_params_test(int id)
     EVP_PKEY_CTX_free(pctx1);
     if (!TEST_ptr(pctx1 = EVP_PKEY_CTX_new(pkey1, NULL))
             || !TEST_int_eq(EVP_PKEY_derive_init(pctx1), 1)
-            || !TEST_int_eq(EVP_PKEY_derive_set_peer(pctx1, pkey2), 1)
-            || !TEST_int_eq(EVP_PKEY_derive(pctx1, NULL, &t), 1)
+            || !TEST_ptr(dctx = EVP_PKEY_CTX_dup(pctx1))
+            || !TEST_int_eq(EVP_PKEY_derive_set_peer_ex(dctx, pkey2, 1), 1)
+            || !TEST_int_eq(EVP_PKEY_derive(dctx, NULL, &t), 1)
             || !TEST_int_gt(bsize, t)
             || !TEST_int_le(sslen, t)
-            || !TEST_int_eq(EVP_PKEY_derive(pctx1, buf1, &t), 1)
+            || !TEST_int_eq(EVP_PKEY_derive(dctx, buf1, &t), 1)
             /* compare with previous result */
             || !TEST_mem_eq(buf1, t, buf2, sslen))
         goto err;
@@ -2962,6 +2963,7 @@ static int custom_params_test(int id)
     EVP_PKEY_free(pkey2);
     EVP_PKEY_CTX_free(pctx1);
     EVP_PKEY_CTX_free(pctx2);
+    EVP_PKEY_CTX_free(dctx);
 
     return ret;
 }