From: Richard Levitte Date: Fri, 27 Nov 2020 06:59:02 +0000 (+0100) Subject: ENCODER: Don't pass libctx to OSSL_ENCODER_CTX_new_by_EVP_PKEY() X-Git-Tag: openssl-3.0.0-alpha10~206 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=cbcbac644c4679e535948e49983d335ae46c578e;p=thirdparty%2Fopenssl.git ENCODER: Don't pass libctx to OSSL_ENCODER_CTX_new_by_EVP_PKEY() The passed 'pkey' already contains a library context, and the encoder implementations should be found within the same context, so passing an explicit library context seems unnecessary, and potentially dangerous. It should be noted that it's possible to pass an EVP_PKEY with a legacy internal key. The condition there is that it doesn't have a library context assigned to it, so the NULL library context is used automatically, thus requiring that appropriate encoders are available through that context. Fixes #13544 Reviewed-by: Tim Hudson (Merged from https://github.com/openssl/openssl/pull/13545) --- diff --git a/crypto/encode_decode/encoder_pkey.c b/crypto/encode_decode/encoder_pkey.c index 594543b19ee..e8e1c77b5f1 100644 --- a/crypto/encode_decode/encoder_pkey.c +++ b/crypto/encode_decode/encoder_pkey.c @@ -210,10 +210,10 @@ static void encoder_destruct_EVP_PKEY(void *arg) static int ossl_encoder_ctx_setup_for_EVP_PKEY(OSSL_ENCODER_CTX *ctx, const EVP_PKEY *pkey, int selection, - OSSL_LIB_CTX *libctx, const char *propquery) { struct construct_data_st *data = NULL; + OSSL_LIB_CTX *libctx = NULL; int ok = 0; if (!ossl_assert(ctx != NULL) || !ossl_assert(pkey != NULL)) { @@ -221,6 +221,12 @@ static int ossl_encoder_ctx_setup_for_EVP_PKEY(OSSL_ENCODER_CTX *ctx, return 0; } + if (evp_pkey_is_provided(pkey)) { + const OSSL_PROVIDER *prov = EVP_KEYMGMT_provider(pkey->keymgmt); + + libctx = ossl_provider_libctx(prov); + } + if (pkey->keymgmt != NULL) { struct collected_encoder_st encoder_data; struct collected_names_st keymgmt_data; @@ -280,16 +286,33 @@ OSSL_ENCODER_CTX *OSSL_ENCODER_CTX_new_by_EVP_PKEY(const EVP_PKEY *pkey, int selection, const char *output_type, const char *output_struct, - OSSL_LIB_CTX *libctx, const char *propquery) { OSSL_ENCODER_CTX *ctx = NULL; + OSSL_LIB_CTX *libctx = NULL; + + if (pkey == NULL) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + + if (!evp_pkey_is_assigned(pkey)) { + ERR_raise_data(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_INVALID_ARGUMENT, + "The passed EVP_PKEY must be assigned a key"); + return NULL; + } if ((ctx = OSSL_ENCODER_CTX_new()) == NULL) { ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_MALLOC_FAILURE); return NULL; } + if (evp_pkey_is_provided(pkey)) { + const OSSL_PROVIDER *prov = EVP_KEYMGMT_provider(pkey->keymgmt); + + libctx = ossl_provider_libctx(prov); + } + OSSL_TRACE_BEGIN(ENCODER) { BIO_printf(trc_out, "(ctx %p) Looking for %s encoders with selection %d\n", @@ -302,8 +325,7 @@ OSSL_ENCODER_CTX *OSSL_ENCODER_CTX_new_by_EVP_PKEY(const EVP_PKEY *pkey, && (output_struct == NULL || OSSL_ENCODER_CTX_set_output_structure(ctx, output_struct)) && OSSL_ENCODER_CTX_set_selection(ctx, selection) - && ossl_encoder_ctx_setup_for_EVP_PKEY(ctx, pkey, selection, - libctx, propquery) + && ossl_encoder_ctx_setup_for_EVP_PKEY(ctx, pkey, selection, propquery) && OSSL_ENCODER_CTX_add_extra(ctx, libctx, propquery)) { OSSL_TRACE_BEGIN(ENCODER) { BIO_printf(trc_out, "(ctx %p) Got %d encoders\n", diff --git a/doc/man3/OSSL_ENCODER_CTX_new_by_EVP_PKEY.pod b/doc/man3/OSSL_ENCODER_CTX_new_by_EVP_PKEY.pod index 97ffaa56cdc..403d7a00bef 100644 --- a/doc/man3/OSSL_ENCODER_CTX_new_by_EVP_PKEY.pod +++ b/doc/man3/OSSL_ENCODER_CTX_new_by_EVP_PKEY.pod @@ -18,7 +18,7 @@ OSSL_ENCODER_CTX_set_passphrase_ui OSSL_ENCODER_CTX_new_by_EVP_PKEY(const EVP_PKEY *pkey, int selection, const char *output_type, const char *output_structure, - OSSL_LIB_CTX *libctx, const char *propquery); + const char *propquery); int OSSL_ENCODER_CTX_set_cipher(OSSL_ENCODER_CTX *ctx, const char *cipher_name, @@ -51,7 +51,7 @@ L implementation associated with I to build a list of applicable encoder implementations that are used to process the I into the encoding named by I, with the outermost structure named by I if that's relevant. All these implementations are -implicitly fetched using I and I. +implicitly fetched, with I for finer selection. If no suitable encoder implementation is found, OSSL_ENCODER_CTX_new_by_EVP_PKEY() still creates a B, but diff --git a/include/openssl/encoder.h b/include/openssl/encoder.h index f50d16517ed..122a46bac95 100644 --- a/include/openssl/encoder.h +++ b/include/openssl/encoder.h @@ -117,7 +117,6 @@ OSSL_ENCODER_CTX *OSSL_ENCODER_CTX_new_by_EVP_PKEY(const EVP_PKEY *pkey, int selection, const char *output_type, const char *output_struct, - OSSL_LIB_CTX *libctx, const char *propquery); # ifdef __cplusplus