From: Richard Levitte Date: Wed, 2 Jun 2021 04:37:43 +0000 (+0200) Subject: ENCODER: use property definitions instead of getting implementation parameters X-Git-Tag: openssl-3.0.0-beta1~188 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e982e04f5dd12ee2546344b3a26fd0e55f59f5cb;p=thirdparty%2Fopenssl.git ENCODER: use property definitions instead of getting implementation parameters The OSSL_ENCODER library used to ask each encoder implementation for certain data in form of parameters to place them correctly in the encoder chain, if at all. These parameters were duplicates of properties of those same implementations, and therefore unnecessarily redundant. Now that we have functionality to query property definition values, those duplicates are no longer needed, and are therefore not looked at any more. Reviewed-by: Tomas Mraz Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/15570) --- diff --git a/crypto/encode_decode/encoder_lib.c b/crypto/encode_decode/encoder_lib.c index d90ce72528a..cb47e8bc716 100644 --- a/crypto/encode_decode/encoder_lib.c +++ b/crypto/encode_decode/encoder_lib.c @@ -16,6 +16,7 @@ #include #include #include "internal/bio.h" +#include "internal/provider.h" #include "encoder_local.h" struct encoder_process_data_st { @@ -180,46 +181,54 @@ static OSSL_ENCODER_INSTANCE *ossl_encoder_instance_new(OSSL_ENCODER *encoder, void *encoderctx) { OSSL_ENCODER_INSTANCE *encoder_inst = NULL; - OSSL_PARAM params[4]; + const OSSL_PROVIDER *prov; + OSSL_LIB_CTX *libctx; + const OSSL_PROPERTY_LIST *props; + const OSSL_PROPERTY_DEFINITION *prop; if (!ossl_assert(encoder != NULL)) { ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER); return 0; } - if (encoder->get_params == NULL) { - ERR_raise(ERR_LIB_OSSL_ENCODER, - OSSL_ENCODER_R_MISSING_GET_PARAMS); - return 0; - } - if ((encoder_inst = OPENSSL_zalloc(sizeof(*encoder_inst))) == NULL) { ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_MALLOC_FAILURE); return 0; } - /* - * Cache the input and output types for this encoder. The output type - * is mandatory. - */ - params[0] = - OSSL_PARAM_construct_utf8_ptr(OSSL_ENCODER_PARAM_OUTPUT_TYPE, - (char **)&encoder_inst->output_type, 0); - params[1] = - OSSL_PARAM_construct_utf8_ptr(OSSL_ENCODER_PARAM_OUTPUT_STRUCTURE, - (char **)&encoder_inst->output_structure, - 0); - params[2] = OSSL_PARAM_construct_end(); - - if (!encoder->get_params(params) - || !OSSL_PARAM_modified(¶ms[0])) - goto err; - if (!OSSL_ENCODER_up_ref(encoder)) { ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_INTERNAL_ERROR); goto err; } + prov = OSSL_ENCODER_get0_provider(encoder); + libctx = ossl_provider_libctx(prov); + props = ossl_encoder_parsed_properties(encoder); + if (props == NULL) { + ERR_raise_data(ERR_LIB_OSSL_DECODER, ERR_R_INVALID_PROPERTY_DEFINITION, + "there are no property definitions with encoder %s", + OSSL_ENCODER_get0_name(encoder)); + goto err; + } + + /* The "output" property is mandatory */ + prop = ossl_property_find_property(props, libctx, "output"); + encoder_inst->output_type = ossl_property_get_string_value(libctx, prop); + if (encoder_inst->output_type == NULL) { + ERR_raise_data(ERR_LIB_OSSL_DECODER, ERR_R_INVALID_PROPERTY_DEFINITION, + "the mandatory 'output' property is missing " + "for encoder %s (properties: %s)", + OSSL_ENCODER_get0_name(encoder), + OSSL_ENCODER_get0_properties(encoder)); + goto err; + } + + /* The "structure" property is optional */ + prop = ossl_property_find_property(props, libctx, "structure"); + if (prop != NULL) + encoder_inst->output_structure + = ossl_property_get_string_value(libctx, prop); + encoder_inst->encoder = encoder; encoder_inst->encoderctx = encoderctx; return encoder_inst; diff --git a/crypto/encode_decode/encoder_local.h b/crypto/encode_decode/encoder_local.h index 44bd39b7572..a0b10dcd5ea 100644 --- a/crypto/encode_decode/encoder_local.h +++ b/crypto/encode_decode/encoder_local.h @@ -161,3 +161,5 @@ struct ossl_decoder_ctx_st { const OSSL_PROPERTY_LIST * ossl_decoder_parsed_properties(const OSSL_DECODER *decoder); +const OSSL_PROPERTY_LIST * +ossl_encoder_parsed_properties(const OSSL_ENCODER *encoder); diff --git a/crypto/encode_decode/encoder_meth.c b/crypto/encode_decode/encoder_meth.c index 81cebb26597..d50f1dcd0b6 100644 --- a/crypto/encode_decode/encoder_meth.c +++ b/crypto/encode_decode/encoder_meth.c @@ -59,6 +59,7 @@ void OSSL_ENCODER_free(OSSL_ENCODER *encoder) if (ref > 0) return; OPENSSL_free(encoder->base.name); + ossl_property_free(encoder->base.parsed_propdef); ossl_provider_free(encoder->base.prov); CRYPTO_THREAD_lock_free(encoder->base.lock); OPENSSL_free(encoder); @@ -166,6 +167,7 @@ static void *encoder_from_algorithm(int id, const OSSL_ALGORITHM *algodef, { OSSL_ENCODER *encoder = NULL; const OSSL_DISPATCH *fns = algodef->implementation; + OSSL_LIB_CTX *libctx = ossl_provider_libctx(prov); if ((encoder = ossl_encoder_new()) == NULL) return NULL; @@ -176,6 +178,8 @@ static void *encoder_from_algorithm(int id, const OSSL_ALGORITHM *algodef, } encoder->base.propdef = algodef->property_definition; encoder->base.description = algodef->algorithm_description; + encoder->base.parsed_propdef + = ossl_parse_property(libctx, algodef->property_definition); for (; fns->function_id != 0; fns++) { switch (fns->function_id) { @@ -239,9 +243,7 @@ static void *encoder_from_algorithm(int id, const OSSL_ALGORITHM *algodef, || (encoder->newctx != NULL && encoder->freectx != NULL) || (encoder->import_object != NULL && encoder->free_object != NULL) || (encoder->import_object == NULL && encoder->free_object == NULL)) - || encoder->encode == NULL - || encoder->gettable_params == NULL - || encoder->get_params == NULL) { + || encoder->encode == NULL) { OSSL_ENCODER_free(encoder); ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_INVALID_PROVIDER_FUNCTIONS); return NULL; @@ -433,6 +435,17 @@ const char *OSSL_ENCODER_get0_properties(const OSSL_ENCODER *encoder) return encoder->base.propdef; } +const OSSL_PROPERTY_LIST * +ossl_encoder_parsed_properties(const OSSL_ENCODER *encoder) +{ + if (!ossl_assert(encoder != NULL)) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + return encoder->base.parsed_propdef; +} + int ossl_encoder_get_number(const OSSL_ENCODER *encoder) { if (!ossl_assert(encoder != NULL)) { diff --git a/doc/man7/provider-encoder.pod b/doc/man7/provider-encoder.pod index 2f2e8ef6c62..274f1456ec9 100644 --- a/doc/man7/provider-encoder.pod +++ b/doc/man7/provider-encoder.pod @@ -133,8 +133,12 @@ Properties can be used to further specify details about an implementation: =item output -This property is used to specify what type of output implementation -produces. OpenSSL providers recognize the following output types: +This property is used to specify what type of output the implementation +produces. + +This property is I. + +OpenSSL providers recognize the following output types: =over 4 @@ -169,6 +173,8 @@ object. An example could be C, to specify explicitly that an object (presumably an asymmetric key pair, in this case) will be wrapped in a PKCS#8 structure as part of the encoding. +This property is I. + =back The possible values of both these properties is open ended. A provider may @@ -240,38 +246,6 @@ The encoding functions also take an B function pointer along with a pointer to application data I, which should be used when a pass phrase prompt is needed. -=head2 Encoder parameters - -The ENCODER implementation itself has parameters that can be used to -determine how it fits in a chain of encoders: - -=over 4 - -=item "output-type" (B) - -This is used to specify the output type for an ENCODER implementation. - -This parameter is I. - -=for comment If we had functionality to get the value of a specific property -in a set of properties, it would be possible to determine the output type -from the C property. - -=item "output-structure" (B) - -This is used to specify the outermost output structure for an ENCODER -implementation. - -For example, an output of type "DER" for a key pair could be structured -using PKCS#8, or a key type specific structure, such as PKCS#1 for RSA -keys. - -=for comment If we had functionality to get the value of a specific property -in a set of properties, it would be possible to determine the output -structure from the C property. - -=back - =head2 Encoder operation parameters Operation parameters currently recognised by built-in encoders are as