From: Richard Levitte Date: Tue, 1 Jun 2021 18:04:59 +0000 (+0200) Subject: DECODER: use property definitions instead of getting implementation parameters X-Git-Tag: openssl-3.0.0-beta1~191 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9379bf943a12090de6280e88fb0d246e73658116;p=thirdparty%2Fopenssl.git DECODER: use property definitions instead of getting implementation parameters The OSSL_DECODER library used to ask each decoder implementation for certain data in form of parameters to place them correctly in the decoder 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. This adds the "global" error reason ERR_R_INVALID_PROPERTY_DEFINITION, which can be re-used elsewhere. Reviewed-by: Tomas Mraz Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/15570) --- diff --git a/crypto/encode_decode/decoder_lib.c b/crypto/encode_decode/decoder_lib.c index ddfd90aae55..bf9b17f754a 100644 --- a/crypto/encode_decode/decoder_lib.c +++ b/crypto/encode_decode/decoder_lib.c @@ -16,8 +16,8 @@ #include #include #include -#include "internal/passphrase.h" #include "internal/bio.h" +#include "internal/provider.h" #include "crypto/decoder.h" #include "encoder_local.h" #include "e_os.h" @@ -204,19 +204,16 @@ OSSL_DECODER_INSTANCE *ossl_decoder_instance_new(OSSL_DECODER *decoder, void *decoderctx) { OSSL_DECODER_INSTANCE *decoder_inst = NULL; - OSSL_PARAM params[3]; + const OSSL_PROVIDER *prov; + OSSL_LIB_CTX *libctx; + const OSSL_PROPERTY_LIST *props; + const OSSL_PROPERTY_DEFINITION *prop; if (!ossl_assert(decoder != NULL)) { ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER); return 0; } - if (decoder->get_params == NULL) { - ERR_raise(ERR_LIB_OSSL_DECODER, - OSSL_DECODER_R_MISSING_GET_PARAMS); - return 0; - } - if ((decoder_inst = OPENSSL_zalloc(sizeof(*decoder_inst))) == NULL) { ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE); return 0; @@ -226,22 +223,35 @@ OSSL_DECODER_INSTANCE *ossl_decoder_instance_new(OSSL_DECODER *decoder, goto err; } - /* Cache the input type for this decoder */ - params[0] = - OSSL_PARAM_construct_utf8_ptr(OSSL_DECODER_PARAM_INPUT_TYPE, - (char **)&decoder_inst->input_type, 0); - params[1] = - OSSL_PARAM_construct_utf8_ptr(OSSL_DECODER_PARAM_INPUT_STRUCTURE, - (char **)&decoder_inst->input_structure, - 0); - params[2] = OSSL_PARAM_construct_end(); - - if (!decoder->get_params(params) - || !OSSL_PARAM_modified(¶ms[0])) + prov = OSSL_DECODER_get0_provider(decoder); + libctx = ossl_provider_libctx(prov); + props = ossl_decoder_parsed_properties(decoder); + if (props == NULL) { + ERR_raise_data(ERR_LIB_OSSL_DECODER, ERR_R_INVALID_PROPERTY_DEFINITION, + "there are no property definitions with decoder %s", + OSSL_DECODER_get0_name(decoder)); + goto err; + } + + /* The "input" property is mandatory */ + prop = ossl_property_find_property(props, libctx, "input"); + decoder_inst->input_type = ossl_property_get_string_value(libctx, prop); + if (decoder_inst->input_type == NULL) { + ERR_raise_data(ERR_LIB_OSSL_DECODER, ERR_R_INVALID_PROPERTY_DEFINITION, + "the mandatory 'input' property is missing " + "for decoder %s (properties: %s)", + OSSL_DECODER_get0_name(decoder), + OSSL_DECODER_get0_properties(decoder)); goto err; + } + + /* The "structure" property is optional */ + prop = ossl_property_find_property(props, libctx, "structure"); + if (prop != NULL) { + decoder_inst->input_structure + = ossl_property_get_string_value(libctx, prop); + } - decoder_inst->flag_input_structure_was_set = - OSSL_PARAM_modified(¶ms[1]); decoder_inst->decoder = decoder; decoder_inst->decoderctx = decoderctx; return decoder_inst; diff --git a/crypto/encode_decode/decoder_meth.c b/crypto/encode_decode/decoder_meth.c index 7197b9090db..e203c5fe660 100644 --- a/crypto/encode_decode/decoder_meth.c +++ b/crypto/encode_decode/decoder_meth.c @@ -59,6 +59,7 @@ void OSSL_DECODER_free(OSSL_DECODER *decoder) if (ref > 0) return; OPENSSL_free(decoder->base.name); + ossl_property_free(decoder->base.parsed_propdef); ossl_provider_free(decoder->base.prov); CRYPTO_THREAD_lock_free(decoder->base.lock); OPENSSL_free(decoder); @@ -166,6 +167,7 @@ void *ossl_decoder_from_algorithm(int id, const OSSL_ALGORITHM *algodef, { OSSL_DECODER *decoder = NULL; const OSSL_DISPATCH *fns = algodef->implementation; + OSSL_LIB_CTX *libctx = ossl_provider_libctx(prov); if ((decoder = ossl_decoder_new()) == NULL) return NULL; @@ -176,6 +178,8 @@ void *ossl_decoder_from_algorithm(int id, const OSSL_ALGORITHM *algodef, } decoder->base.propdef = algodef->property_definition; decoder->base.description = algodef->algorithm_description; + decoder->base.parsed_propdef + = ossl_parse_property(libctx, algodef->property_definition); for (; fns->function_id != 0; fns++) { switch (fns->function_id) { @@ -421,6 +425,17 @@ const char *OSSL_DECODER_get0_properties(const OSSL_DECODER *decoder) return decoder->base.propdef; } +const OSSL_PROPERTY_LIST * +ossl_decoder_parsed_properties(const OSSL_DECODER *decoder) +{ + if (!ossl_assert(decoder != NULL)) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + return decoder->base.parsed_propdef; +} + int ossl_decoder_get_number(const OSSL_DECODER *decoder) { if (!ossl_assert(decoder != NULL)) { diff --git a/crypto/encode_decode/encoder_local.h b/crypto/encode_decode/encoder_local.h index d53f7603794..0678fc20141 100644 --- a/crypto/encode_decode/encoder_local.h +++ b/crypto/encode_decode/encoder_local.h @@ -14,6 +14,7 @@ #include #include "internal/cryptlib.h" #include "internal/passphrase.h" +#include "internal/property.h" #include "internal/refcount.h" struct ossl_endecode_base_st { @@ -22,6 +23,7 @@ struct ossl_endecode_base_st { char *name; const char *propdef; const char *description; + OSSL_PROPERTY_LIST *parsed_propdef; CRYPTO_REF_COUNT refcnt; CRYPTO_RWLOCK *lock; @@ -157,3 +159,6 @@ struct ossl_decoder_ctx_st { /* For any function that needs a passphrase reader */ struct ossl_passphrase_data_st pwdata; }; + +const OSSL_PROPERTY_LIST * +ossl_decoder_parsed_properties(const OSSL_DECODER *decoder); diff --git a/crypto/err/err.c b/crypto/err/err.c index 84bb429c640..9b1a15d5bdf 100644 --- a/crypto/err/err.c +++ b/crypto/err/err.c @@ -125,6 +125,8 @@ static ERR_STRING_DATA ERR_str_reasons[] = { * unsupported. */ {ERR_R_FETCH_FAILED, "fetch failed"}, + + {ERR_R_INVALID_PROPERTY_DEFINITION, "invalid property definition"}, {0, NULL}, }; #endif diff --git a/doc/man7/provider-decoder.pod b/doc/man7/provider-decoder.pod index 23b4fbc9df7..2ac56cf1d12 100644 --- a/doc/man7/provider-decoder.pod +++ b/doc/man7/provider-decoder.pod @@ -117,7 +117,11 @@ Properties can be used to further specify details about an implementation: =item input This property is used to specify what format of input the implementation -can decode. OpenSSL providers recognize the following input types: +can decode. + +This property is I. + +OpenSSL providers recognize the following input types: =over 4 @@ -142,9 +146,27 @@ An implementation with that input type decodes PVK formatted data. =item structure This property is used to specify the structure that the decoded data is -expected to have. An example could be C, to specify explicitly that -the object to be decoded (presumably an asymmetric key pair, in this case) -is wrapped in a PKCS#8 structure. +expected to have. + +This property is I. + +Structures currently recognised by built-in decoders: + +=over 4 + +=item "type-specific" + +Type specific structure. + +=item "pkcs8" + +Structure according to the PKCS#8 specification. + +=item "SubjectPublicKeyInfo" + +Encoding of public keys according to the Subject Public Key Info of RFC 5280. + +=back =back @@ -236,80 +258,6 @@ possible for some other decoder implementation to get a different result. The conditions to stop the decoding process are at the discretion of the implementation. -=head2 Decoder parameters - -The decoder implementation itself has parameters that can be used to -determine how it fits in a chain of decoders: - -=over 4 - -=item "input-type" (B) - -This is used to specify the input type for a decoder implementation. - -This parameter is I. - -Input types currently recognized by built-in decoders: - -=over 4 - -=item "DER" - -ASN.1 DER encoded binary data - -=item "PEM" - -Base64 encoded data with PEM headers - -=item "MSBLOB" - -Private or public key encoding according to Microsoft specification - -=item "PVK" - -Encrypted private key encoding according to Microsoft specification - -=back - -=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 input type -from the C property. - -=item "input-structure" (B) - -This is used to specify the outermost input structure for a decoder -implementation. - -For example, an input 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. - -This parameter is I. - -Input structures currently recognized by built-in decoders: - -=over 4 - -=item "type-specific" - -Type specific structure. - -=item "PKCS8" - -Structure according to the PKCS#8 specification. - -=item "SubjectPublicKeyInfo" - -Encoding of public keys according to the Subject Public Key Info of RFC 5280. - -=back - -=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 input -structure from the C property. - -=back - =head2 Decoder operation parameters There are currently no operation parameters currently recognised by the diff --git a/include/openssl/err.h.in b/include/openssl/err.h.in index f7d5c174a17..4bc5d1eea56 100644 --- a/include/openssl/err.h.in +++ b/include/openssl/err.h.in @@ -357,6 +357,7 @@ static ossl_unused ossl_inline int ERR_COMMON_ERROR(unsigned long errcode) # define ERR_R_MISSING_ASN1_EOS (267|ERR_RFLAG_COMMON) # define ERR_R_UNSUPPORTED (268|ERR_RFLAG_COMMON) # define ERR_R_FETCH_FAILED (269|ERR_RFLAG_COMMON) +# define ERR_R_INVALID_PROPERTY_DEFINITION (270|ERR_RFLAG_COMMON) typedef struct ERR_string_data_st { unsigned long error;