pem: avoid segfault if PKEY is NULL in PEM_write_bio_PrivateKey
authorMilan Broz <gmazyland@gmail.com>
Sat, 29 Oct 2022 09:48:51 +0000 (11:48 +0200)
committerTomas Mraz <tomas@openssl.org>
Thu, 10 Nov 2022 17:10:48 +0000 (18:10 +0100)
Make the code more robust and correctly handle EVP_PKEY set to NULL
instead of dereferencing null pointer.

Signed-off-by: Milan Broz <gmazyland@gmail.com>
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/19536)

crypto/pem/pem_pkey.c
test/evp_pkey_provided_test.c

index 53367c03dbbe043d213f2fdf1aeafc220cf7c926..8ffeed9d788d9455423abad536f3e805ae92c580 100644 (file)
@@ -311,7 +311,7 @@ PEM_write_cb_ex_fnsig(PrivateKey, EVP_PKEY, BIO, write_bio)
     IMPLEMENT_PEM_provided_write_body_main(pkey, bio);
 
  legacy:
-    if (x->ameth == NULL || x->ameth->priv_encode != NULL)
+    if (x != NULL && (x->ameth == NULL || x->ameth->priv_encode != NULL))
         return PEM_write_bio_PKCS8PrivateKey(out, x, enc,
                                              (const char *)kstr, klen, cb, u);
     return PEM_write_bio_PrivateKey_traditional(out, x, enc, kstr, klen, cb, u);
@@ -336,6 +336,9 @@ int PEM_write_bio_PrivateKey_traditional(BIO *bp, const EVP_PKEY *x,
     EVP_PKEY *copy = NULL;
     int ret;
 
+    if (x == NULL)
+        return 0;
+
     if (evp_pkey_is_assigned(x)
         && evp_pkey_is_provided(x)
         && evp_pkey_copy_downgraded(&copy, x))
index 1269fbf24f4a4885453196da011ac74e11d84666..3237884d7c9381e92d54a61bf7810bcaafb68d8c 100644 (file)
@@ -188,7 +188,12 @@ static int test_print_key_using_pem(const char *alg, const EVP_PKEY *pk)
         /* Unencrypted private key in PEM form */
         || !TEST_true(PEM_write_bio_PrivateKey(membio, pk,
                                                NULL, NULL, 0, NULL, NULL))
-        || !TEST_true(compare_with_file(alg, PRIV_PEM, membio)))
+        || !TEST_true(compare_with_file(alg, PRIV_PEM, membio))
+        /* NULL key */
+        || !TEST_false(PEM_write_bio_PrivateKey(membio, NULL,
+                                               NULL, NULL, 0, NULL, NULL))
+        || !TEST_false(PEM_write_bio_PrivateKey_traditional(membio, NULL,
+                                               NULL, NULL, 0, NULL, NULL)))
         goto err;
 
     ret = 1;