]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
ENCODER: use property definitions instead of getting implementation parameters
authorRichard Levitte <levitte@openssl.org>
Wed, 2 Jun 2021 04:37:43 +0000 (06:37 +0200)
committerPauli <pauli@openssl.org>
Sat, 5 Jun 2021 10:30:47 +0000 (20:30 +1000)
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 <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15570)

crypto/encode_decode/encoder_lib.c
crypto/encode_decode/encoder_local.h
crypto/encode_decode/encoder_meth.c
doc/man7/provider-encoder.pod

index d90ce72528a02836eacbbbb3f7c8826e2bbec428..cb47e8bc7168d9702ca94abc76aeda9db8f1b636 100644 (file)
@@ -16,6 +16,7 @@
 #include <openssl/provider.h>
 #include <openssl/trace.h>
 #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(&params[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;
index 44bd39b7572020d3c61659afc26ae0f06369f447..a0b10dcd5eafe1ac88594d8cb9e9cf4a4dbde841 100644 (file)
@@ -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);
index 81cebb265970ec9779e6d8f242450b3156253a16..d50f1dcd0b661d4fd30b938deba3c3c45cc4443e 100644 (file)
@@ -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)) {
index 2f2e8ef6c6293d21d262d5301d97899eef492d39..274f1456ec9e2846a18ece4d5180f77dbc357f7e 100644 (file)
@@ -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<mandatory>.
+
+OpenSSL providers recognize the following output types:
 
 =over 4
 
@@ -169,6 +173,8 @@ object.  An example could be C<pkcs8>, 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<optional>.
+
 =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<OSSL_PASSPHRASE_CALLBACK> function
 pointer along with a pointer to application data I<cbarg>, 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<OSSL_ENCODER_PARAM_OUTPUT_TYPE>) <UTF8 string>
-
-This is used to specify the output type for an ENCODER implementation.
-
-This parameter is I<mandatory>.
-
-=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<output> property.
-
-=item "output-structure" (B<OSSL_ENCODER_PARAM_OUTPUT_STRUCTURE>) <UTF8 string>
-
-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<structure> property.
-
-=back
-
 =head2 Encoder operation parameters
 
 Operation parameters currently recognised by built-in encoders are as