From 76d1ffb6f12ccce33ea2c3a1753591a1c69f53b4 Mon Sep 17 00:00:00 2001 From: slontis Date: Tue, 25 Feb 2025 17:03:38 +1100 Subject: [PATCH] Encoder : Fix floating pointer when OSSL_ENCODER_to_data() is called twice. Fixes #26862 This only happens when using the FIPS provider, since it needs to export the key. Reviewed-by: Tim Hudson Reviewed-by: Paul Dale Reviewed-by: Tomas Mraz Reviewed-by: Viktor Dukhovni (Merged from https://github.com/openssl/openssl/pull/26891) (cherry picked from commit c2f4d7aae1c7c726eb1f8226d3d454dfd9754758) --- crypto/encode_decode/encoder_pkey.c | 3 +++ test/endecode_test.c | 23 +++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/crypto/encode_decode/encoder_pkey.c b/crypto/encode_decode/encoder_pkey.c index af18bcd3852..30eaa0b496c 100644 --- a/crypto/encode_decode/encoder_pkey.c +++ b/crypto/encode_decode/encoder_pkey.c @@ -210,6 +210,7 @@ encoder_construct_pkey(OSSL_ENCODER_INSTANCE *encoder_inst, void *arg) static void encoder_destruct_pkey(void *arg) { struct construct_data_st *data = arg; + int match = (data->obj == data->constructed_obj); if (data->encoder_inst != NULL) { OSSL_ENCODER *encoder = @@ -218,6 +219,8 @@ static void encoder_destruct_pkey(void *arg) encoder->free_object(data->constructed_obj); } data->constructed_obj = NULL; + if (match) + data->obj = NULL; } /* diff --git a/test/endecode_test.c b/test/endecode_test.c index 1bf99556f94..08a57c3da54 100644 --- a/test/endecode_test.c +++ b/test/endecode_test.c @@ -1245,6 +1245,28 @@ static int create_ec_explicit_trinomial_params(OSSL_PARAM_BLD *bld) return do_create_ec_explicit_trinomial_params(bld, gen2, sizeof(gen2)); } # endif /* OPENSSL_NO_EC2M */ + +/* + * Test that multiple calls to OSSL_ENCODER_to_data() do not cause side effects + */ +static int ec_encode_to_data_multi(void) +{ + int ret; + OSSL_ENCODER_CTX *ectx = NULL; + EVP_PKEY *key = NULL; + uint8_t *enc = NULL; + size_t enc_len = 0; + + ret = TEST_ptr(key = EVP_PKEY_Q_keygen(testctx, "", "EC", "P-256")) + && TEST_ptr(ectx = OSSL_ENCODER_CTX_new_for_pkey(key, EVP_PKEY_KEYPAIR, + "DER", NULL, NULL)) + && TEST_int_eq(OSSL_ENCODER_to_data(ectx, NULL, &enc_len), 1) + && TEST_int_eq(OSSL_ENCODER_to_data(ectx, &enc, &enc_len), 1); + OPENSSL_free(enc); + EVP_PKEY_free(key); + OSSL_ENCODER_CTX_free(ectx); + return ret; +} #endif /* OPENSSL_NO_EC */ typedef enum OPTION_choice { @@ -1435,6 +1457,7 @@ int setup_tests(void) # endif #endif #ifndef OPENSSL_NO_EC + ADD_TEST(ec_encode_to_data_multi); ADD_TEST_SUITE(EC); ADD_TEST_SUITE_PARAMS(EC); ADD_TEST_SUITE_LEGACY(EC); -- 2.47.2