]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
DECODER: check the first decoded structure name against user given structure
authorRichard Levitte <levitte@openssl.org>
Mon, 30 Aug 2021 11:16:42 +0000 (13:16 +0200)
committerRichard Levitte <levitte@openssl.org>
Sun, 5 Sep 2021 19:34:50 +0000 (21:34 +0200)
In a chain of decoders, the first that specifies an input structure
gets it compared with the structure specified by the user, if there is
one.  If they aren't the same, that decoder is skipped.

Because the first structure can appear anywhere along a chain of
decoders, not just the decoders associated with the resulting OpenSSL
type, the code that checked the structure name when building up the
chain of decoders is removed.

Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/16466)

crypto/encode_decode/decoder_lib.c
crypto/encode_decode/decoder_pkey.c

index 938f97c2820551963655492c0a51512ac37cc9de..10a38b6f82a7ee7f982cf3e61767e03ec75940cc 100644 (file)
@@ -38,6 +38,7 @@ struct decoder_process_data_st {
      */
     unsigned int flag_next_level_called : 1;
     unsigned int flag_construct_called : 1;
+    unsigned int flag_input_structure_checked : 1;
 };
 
 static int decoder_process(const OSSL_PARAM params[], void *arg);
@@ -904,6 +905,26 @@ static int decoder_process(const OSSL_PARAM params[], void *arg)
             continue;
         }
 
+        /*
+         * If the decoder we're currently considering specifies a structure,
+         * and this check hasn't already been done earlier in this chain of
+         * decoder_process() calls, check that it matches the user provided
+         * input structure, if one is given.
+         */
+        if (!data->flag_input_structure_checked
+            && ctx->input_structure != NULL
+            && new_input_structure != NULL) {
+            data->flag_input_structure_checked = 1;
+            if (strcasecmp(new_input_structure, ctx->input_structure) != 0) {
+                OSSL_TRACE_BEGIN(DECODER) {
+                    BIO_printf(trc_out,
+                               "(ctx %p) %s [%u] the previous decoder's data structure doesn't match the input structure given by the user, skipping...\n",
+                               (void *)new_data.ctx, LEVEL, (unsigned int)i);
+                } OSSL_TRACE_END(DECODER);
+                continue;
+            }
+        }
+
         /*
          * Checking the return value of BIO_reset() or BIO_seek() is unsafe.
          * Furthermore, BIO_reset() is unsafe to use if the source BIO happens
@@ -933,6 +954,8 @@ static int decoder_process(const OSSL_PARAM params[], void *arg)
         ERR_set_mark();
 
         new_data.current_decoder_inst_index = i;
+        new_data.flag_input_structure_checked
+            = data->flag_input_structure_checked;
         ok = new_decoder->decode(new_decoderctx, cbio,
                                  new_data.ctx->selection,
                                  decoder_process, &new_data,
index edbea4face46a13426fe7a655d6e5cd5284411c4..475117a463af09f622d2dd06b4fd8e8f0b6539a1 100644 (file)
@@ -215,32 +215,6 @@ static void collect_keymgmt(EVP_KEYMGMT *keymgmt, void *arg)
     }
 }
 
-/*
- * The input structure check is only done on the initial decoder
- * implementations.
- */
-static int decoder_check_input_structure(OSSL_DECODER_CTX *ctx,
-                                         OSSL_DECODER_INSTANCE *di)
-{
-    int di_is_was_set = 0;
-    const char *di_is =
-        OSSL_DECODER_INSTANCE_get_input_structure(di, &di_is_was_set);
-
-    /*
-     * If caller didn't give an input structure name, the decoder is accepted
-     * unconditionally with regards to the input structure.
-     */
-    if (ctx->input_structure == NULL)
-        return 1;
-    /*
-     * If the caller did give an input structure name, the decoder must have
-     * a matching input structure to be accepted.
-     */
-    if (di_is != NULL && strcasecmp(ctx->input_structure, di_is) == 0)
-        return 1;
-    return 0;
-}
-
 struct collect_decoder_data_st {
     STACK_OF(OPENSSL_CSTRING) *names;
     OSSL_DECODER_CTX *ctx;
@@ -310,15 +284,6 @@ static void collect_decoder(OSSL_DECODER *decoder, void *arg)
                            OSSL_DECODER_get0_properties(decoder));
             } OSSL_TRACE_END(DECODER);
 
-            if (!decoder_check_input_structure(data->ctx, di)) {
-                OSSL_TRACE_BEGIN(DECODER) {
-                    BIO_printf(trc_out,
-                               "    REJECTED: not the desired input structure\n");
-                } OSSL_TRACE_END(DECODER);
-                ossl_decoder_instance_free(di);
-                /* Not a fatal error. Just return */
-                return;
-            }
             if (!ossl_decoder_ctx_add_decoder_inst(data->ctx, di)) {
                 ossl_decoder_instance_free(di);
                 data->error_occurred = 1;