/*
 * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

#include <openssl/core_names.h>
#include <openssl/bio.h>
#include <openssl/params.h>
#include <openssl/provider.h>
#include <openssl/evperr.h>
#include <openssl/ecerr.h>
#include <openssl/pkcs12err.h>
#include <openssl/x509err.h>
#include <openssl/trace.h>
#include "internal/passphrase.h"
#include "internal/bio.h"
#include "crypto/decoder.h"
#include "encoder_local.h"
#include "e_os.h"

struct decoder_process_data_st {
    OSSL_DECODER_CTX *ctx;

    /* Current BIO */
    BIO *bio;

    /* Index of the current decoder instance to be processed */
    size_t current_decoder_inst_index;
    /* For tracing, count recursion level */
    size_t recursion;

    /*-
     * Flags
     */
    unsigned int flag_next_level_called : 1;
    unsigned int flag_construct_called : 1;
};

static int decoder_process(const OSSL_PARAM params[], void *arg);

int OSSL_DECODER_from_bio(OSSL_DECODER_CTX *ctx, BIO *in)
{
    struct decoder_process_data_st data;
    int ok = 0;
    BIO *new_bio = NULL;

    if (BIO_tell(in) < 0) {
        new_bio = BIO_new(BIO_f_readbuffer());
        if (new_bio == NULL)
            return 0;
        in = BIO_push(new_bio, in);
    }
    memset(&data, 0, sizeof(data));
    data.ctx = ctx;
    data.bio = in;

    /* Enable passphrase caching */
    (void)ossl_pw_enable_passphrase_caching(&ctx->pwdata);

    ok = decoder_process(NULL, &data);

    if (!data.flag_construct_called) {
        const char *spaces
            = ctx->start_input_type != NULL && ctx->input_structure != NULL
            ? " " : "";
        const char *input_type_label
            = ctx->start_input_type != NULL ? "Input type: " : "";
        const char *input_structure_label
            = ctx->input_structure != NULL ? "Input structure: " : "";
        const char *comma
            = ctx->start_input_type != NULL && ctx->input_structure != NULL
            ? ", " : "";
        const char *input_type
            = ctx->start_input_type != NULL ? ctx->start_input_type : "";
        const char *input_structure
            = ctx->input_structure != NULL ? ctx->input_structure : "";

        ERR_raise_data(ERR_LIB_OSSL_DECODER, ERR_R_UNSUPPORTED,
                       "No supported for the data to decode.%s%s%s%s%s%s",
                       spaces, input_type_label, input_type, comma,
                       input_structure_label, input_structure);
        ok = 0;
    }

    /* Clear any internally cached passphrase */
    (void)ossl_pw_clear_passphrase_cache(&ctx->pwdata);

    if (new_bio != NULL) {
        BIO_pop(new_bio);
        BIO_free(new_bio);
    }
    return ok;
}

#ifndef OPENSSL_NO_STDIO
static BIO *bio_from_file(FILE *fp)
{
    BIO *b;

    if ((b = BIO_new(BIO_s_file())) == NULL) {
        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_BIO_LIB);
        return NULL;
    }
    BIO_set_fp(b, fp, BIO_NOCLOSE);
    return b;
}

int OSSL_DECODER_from_fp(OSSL_DECODER_CTX *ctx, FILE *fp)
{
    BIO *b = bio_from_file(fp);
    int ret = 0;

    if (b != NULL)
        ret = OSSL_DECODER_from_bio(ctx, b);

    BIO_free(b);
    return ret;
}
#endif

int OSSL_DECODER_from_data(OSSL_DECODER_CTX *ctx, const unsigned char **pdata,
                           size_t *pdata_len)
{
    BIO *membio;
    int ret = 0;

    if (pdata == NULL || *pdata == NULL || pdata_len == NULL) {
        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }

    membio = BIO_new_mem_buf(*pdata, (int)*pdata_len);
    if (OSSL_DECODER_from_bio(ctx, membio)) {
        *pdata_len = (size_t)BIO_get_mem_data(membio, pdata);
        ret = 1;
    }
    BIO_free(membio);

    return ret;
}

int OSSL_DECODER_CTX_set_selection(OSSL_DECODER_CTX *ctx, int selection)
{
    if (!ossl_assert(ctx != NULL)) {
        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }

    /*
     * 0 is a valid selection, and means that the caller leaves
     * it to code to discover what the selection is.
     */
    ctx->selection = selection;
    return 1;
}

int OSSL_DECODER_CTX_set_input_type(OSSL_DECODER_CTX *ctx,
                                    const char *input_type)
{
    if (!ossl_assert(ctx != NULL)) {
        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }

    /*
     * NULL is a valid starting input type, and means that the caller leaves
     * it to code to discover what the starting input type is.
     */
    ctx->start_input_type = input_type;
    return 1;
}

int OSSL_DECODER_CTX_set_input_structure(OSSL_DECODER_CTX *ctx,
                                         const char *input_structure)
{
    if (!ossl_assert(ctx != NULL)) {
        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }

    /*
     * NULL is a valid starting input type, and means that the caller leaves
     * it to code to discover what the starting input type is.
     */
    ctx->input_structure = input_structure;
    return 1;
}

OSSL_DECODER_INSTANCE *ossl_decoder_instance_new(OSSL_DECODER *decoder,
                                                 void *decoderctx)
{
    OSSL_DECODER_INSTANCE *decoder_inst = NULL;
    OSSL_PARAM params[3];

    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;
    }
    if (!OSSL_DECODER_up_ref(decoder)) {
        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_INTERNAL_ERROR);
        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(&params[0]))
        goto err;

    decoder_inst->flag_input_structure_was_set =
        OSSL_PARAM_modified(&params[1]);
    decoder_inst->decoder = decoder;
    decoder_inst->decoderctx = decoderctx;
    return decoder_inst;
 err:
    ossl_decoder_instance_free(decoder_inst);
    return NULL;
}

void ossl_decoder_instance_free(OSSL_DECODER_INSTANCE *decoder_inst)
{
    if (decoder_inst != NULL) {
        if (decoder_inst->decoder != NULL)
            decoder_inst->decoder->freectx(decoder_inst->decoderctx);
        decoder_inst->decoderctx = NULL;
        OSSL_DECODER_free(decoder_inst->decoder);
        decoder_inst->decoder = NULL;
        OPENSSL_free(decoder_inst);
    }
}

int ossl_decoder_ctx_add_decoder_inst(OSSL_DECODER_CTX *ctx,
                                      OSSL_DECODER_INSTANCE *di)
{
    int ok;

    if (ctx->decoder_insts == NULL
        && (ctx->decoder_insts =
            sk_OSSL_DECODER_INSTANCE_new_null()) == NULL) {
        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE);
        return 0;
    }

    ok = (sk_OSSL_DECODER_INSTANCE_push(ctx->decoder_insts, di) > 0);
    if (ok) {
        OSSL_TRACE_BEGIN(DECODER) {
            BIO_printf(trc_out,
                       "(ctx %p) Added decoder instance %p (decoder %p) with:\n",
                       (void *)ctx, (void *)di, (void *)di->decoder);
            BIO_printf(trc_out,
                       "    input type: %s, input structure: %s\n",
                       di->input_type, di->input_structure);
        } OSSL_TRACE_END(DECODER);
    }
    return ok;
}

int OSSL_DECODER_CTX_add_decoder(OSSL_DECODER_CTX *ctx, OSSL_DECODER *decoder)
{
    OSSL_DECODER_INSTANCE *decoder_inst = NULL;
    const OSSL_PROVIDER *prov = NULL;
    void *decoderctx = NULL;
    void *provctx = NULL;

    if (!ossl_assert(ctx != NULL) || !ossl_assert(decoder != NULL)) {
        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }

    prov = OSSL_DECODER_provider(decoder);
    provctx = OSSL_PROVIDER_get0_provider_ctx(prov);

    if ((decoderctx = decoder->newctx(provctx)) == NULL
        || (decoder_inst =
            ossl_decoder_instance_new(decoder, decoderctx)) == NULL)
        goto err;
    /* Avoid double free of decoderctx on further errors */
    decoderctx = NULL;

    if (!ossl_decoder_ctx_add_decoder_inst(ctx, decoder_inst))
        goto err;

    return 1;
 err:
    ossl_decoder_instance_free(decoder_inst);
    if (decoderctx != NULL)
        decoder->freectx(decoderctx);
    return 0;
}

int OSSL_DECODER_CTX_add_extra(OSSL_DECODER_CTX *ctx,
                               OSSL_LIB_CTX *libctx, const char *propq)
{
    /*
     * This function goes through existing decoder methods in
     * |ctx->decoder_insts|, and tries to fetch new decoders that produce
     * what the existing ones want as input, and push those newly fetched
     * decoders on top of the same stack.
     * Then it does the same again, but looping over the newly fetched
     * decoders, until there are no more decoders to be fetched, or
     * when we have done this 10 times.
     *
     * we do this with sliding windows on the stack by keeping track of indexes
     * and of the end.
     *
     * +----------------+
     * |   DER to RSA   | <--- w_prev_start
     * +----------------+
     * |   DER to DSA   |
     * +----------------+
     * |   DER to DH    |
     * +----------------+
     * |   PEM to DER   | <--- w_prev_end, w_new_start
     * +----------------+
     *                    <--- w_new_end
     */
    size_t w_prev_start, w_prev_end; /* "previous" decoders */
    size_t w_new_start, w_new_end;   /* "new" decoders */
    size_t count = 0; /* Calculates how many were added in each iteration */
    size_t depth = 0; /* Counts the number of iterations */

    if (!ossl_assert(ctx != NULL)) {
        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }

    /*
     * If there is no stack of OSSL_DECODER_INSTANCE, we have nothing
     * more to add.  That's fine.
     */
    if (ctx->decoder_insts == NULL)
        return 1;

    w_prev_start = 0;
    w_prev_end = sk_OSSL_DECODER_INSTANCE_num(ctx->decoder_insts);
    do {
        size_t i;

        w_new_start = w_new_end = w_prev_end;

        for (i = w_prev_start; i < w_prev_end; i++) {
            OSSL_DECODER_INSTANCE *decoder_inst =
                sk_OSSL_DECODER_INSTANCE_value(ctx->decoder_insts, i);
            const char *input_type =
                OSSL_DECODER_INSTANCE_get_input_type(decoder_inst);
            OSSL_DECODER *decoder = NULL;

            /*
             * If the caller has specified what the initial input should be,
             * and the decoder implementation we're looking at has that
             * input type, there's no point adding on more implementations
             * on top of this one, so we don't.
             */
            if (ctx->start_input_type != NULL
                && strcasecmp(ctx->start_input_type, input_type) == 0)
                continue;

            ERR_set_mark();
            decoder = OSSL_DECODER_fetch(libctx, input_type, propq);
            ERR_pop_to_mark();

            if (decoder != NULL) {
                size_t j;

                /*
                 * Check that we don't already have this decoder in our
                 * stack We only need to check among the newly added ones.
                 */
                for (j = w_new_start; j < w_new_end; j++) {
                    OSSL_DECODER_INSTANCE *check_inst =
                        sk_OSSL_DECODER_INSTANCE_value(ctx->decoder_insts, j);

                    if (decoder == check_inst->decoder) {
                        /* We found it, so drop the new fetch */
                        OSSL_DECODER_free(decoder);
                        decoder = NULL;
                        break;
                    }
                }
            }

            if (decoder == NULL)
                continue;

            /*
             * Apart from keeping w_new_end up to date, We don't care about
             * errors here.  If it doesn't collect, then it doesn't...
             */
            if (OSSL_DECODER_CTX_add_decoder(ctx, decoder)) /* ref++ */
                w_new_end++;
            OSSL_DECODER_free(decoder); /* ref-- */
        }
        /* How many were added in this iteration */
        count = w_new_end - w_new_start;

        /* Slide the "previous decoder" windows */
        w_prev_start = w_new_start;
        w_prev_end = w_new_end;

        depth++;
    } while (count != 0 && depth <= 10);

    return 1;
}

int OSSL_DECODER_CTX_get_num_decoders(OSSL_DECODER_CTX *ctx)
{
    if (ctx == NULL || ctx->decoder_insts == NULL)
        return 0;
    return sk_OSSL_DECODER_INSTANCE_num(ctx->decoder_insts);
}

int OSSL_DECODER_CTX_set_construct(OSSL_DECODER_CTX *ctx,
                                   OSSL_DECODER_CONSTRUCT *construct)
{
    if (!ossl_assert(ctx != NULL)) {
        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }
    ctx->construct = construct;
    return 1;
}

int OSSL_DECODER_CTX_set_construct_data(OSSL_DECODER_CTX *ctx,
                                        void *construct_data)
{
    if (!ossl_assert(ctx != NULL)) {
        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }
    ctx->construct_data = construct_data;
    return 1;
}

int OSSL_DECODER_CTX_set_cleanup(OSSL_DECODER_CTX *ctx,
                                 OSSL_DECODER_CLEANUP *cleanup)
{
    if (!ossl_assert(ctx != NULL)) {
        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }
    ctx->cleanup = cleanup;
    return 1;
}

OSSL_DECODER_CONSTRUCT *
OSSL_DECODER_CTX_get_construct(OSSL_DECODER_CTX *ctx)
{
    if (ctx == NULL)
        return NULL;
    return ctx->construct;
}

void *OSSL_DECODER_CTX_get_construct_data(OSSL_DECODER_CTX *ctx)
{
    if (ctx == NULL)
        return NULL;
    return ctx->construct_data;
}

OSSL_DECODER_CLEANUP *
OSSL_DECODER_CTX_get_cleanup(OSSL_DECODER_CTX *ctx)
{
    if (ctx == NULL)
        return NULL;
    return ctx->cleanup;
}

int OSSL_DECODER_export(OSSL_DECODER_INSTANCE *decoder_inst,
                        void *reference, size_t reference_sz,
                        OSSL_CALLBACK *export_cb, void *export_cbarg)
{
    OSSL_DECODER *decoder = NULL;
    void *decoderctx = NULL;

    if (!(ossl_assert(decoder_inst != NULL)
          && ossl_assert(reference != NULL)
          && ossl_assert(export_cb != NULL)
          && ossl_assert(export_cbarg != NULL))) {
        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }

    decoder = OSSL_DECODER_INSTANCE_get_decoder(decoder_inst);
    decoderctx = OSSL_DECODER_INSTANCE_get_decoder_ctx(decoder_inst);
    return decoder->export_object(decoderctx, reference, reference_sz,
                                  export_cb, export_cbarg);
}

OSSL_DECODER *
OSSL_DECODER_INSTANCE_get_decoder(OSSL_DECODER_INSTANCE *decoder_inst)
{
    if (decoder_inst == NULL)
        return NULL;
    return decoder_inst->decoder;
}

void *
OSSL_DECODER_INSTANCE_get_decoder_ctx(OSSL_DECODER_INSTANCE *decoder_inst)
{
    if (decoder_inst == NULL)
        return NULL;
    return decoder_inst->decoderctx;
}

const char *
OSSL_DECODER_INSTANCE_get_input_type(OSSL_DECODER_INSTANCE *decoder_inst)
{
    if (decoder_inst == NULL)
        return NULL;
    return decoder_inst->input_type;
}

const char *
OSSL_DECODER_INSTANCE_get_input_structure(OSSL_DECODER_INSTANCE *decoder_inst,
                                          int *was_set)
{
    if (decoder_inst == NULL)
        return NULL;
    *was_set = decoder_inst->flag_input_structure_was_set;
    return decoder_inst->input_structure;
}

static int decoder_process(const OSSL_PARAM params[], void *arg)
{
    struct decoder_process_data_st *data = arg;
    OSSL_DECODER_CTX *ctx = data->ctx;
    OSSL_DECODER_INSTANCE *decoder_inst = NULL;
    OSSL_DECODER *decoder = NULL;
    OSSL_CORE_BIO *cbio = NULL;
    BIO *bio = data->bio;
    long loc;
    size_t i;
    int ok = 0;
    /* For recursions */
    struct decoder_process_data_st new_data;
    const char *data_type = NULL;
    const char *data_structure = NULL;

    /*
     * This is an indicator up the call stack that something was indeed
     * decoded, leading to a recursive call of this function.
     */
    data->flag_next_level_called = 1;

    memset(&new_data, 0, sizeof(new_data));
    new_data.ctx = data->ctx;
    new_data.recursion = data->recursion + 1;

#define LEVEL_STR ">>>>>>>>>>>>>>>>"
#define LEVEL (new_data.recursion < sizeof(LEVEL_STR)                   \
               ? &LEVEL_STR[sizeof(LEVEL_STR) - new_data.recursion - 1] \
               : LEVEL_STR "...")

    if (params == NULL) {
        /* First iteration, where we prepare for what is to come */

        OSSL_TRACE_BEGIN(DECODER) {
            BIO_printf(trc_out,
                       "(ctx %p) starting to walk the decoder chain\n",
                       (void *)new_data.ctx);
        } OSSL_TRACE_END(DECODER);

        data->current_decoder_inst_index =
            OSSL_DECODER_CTX_get_num_decoders(ctx);

        bio = data->bio;
    } else {
        const OSSL_PARAM *p;
        const char *trace_data_structure;

        decoder_inst =
            sk_OSSL_DECODER_INSTANCE_value(ctx->decoder_insts,
                                           data->current_decoder_inst_index);
        decoder = OSSL_DECODER_INSTANCE_get_decoder(decoder_inst);

        data->flag_construct_called = 0;
        if (ctx->construct != NULL) {
            int rv = ctx->construct(decoder_inst, params, ctx->construct_data);

            data->flag_construct_called = 1;
            ok = (rv > 0);
            if (ok)
                goto end;
        }

        /* The constructor didn't return success */

        /*
         * so we try to use the object we got and feed it to any next
         * decoder that will take it.  Object references are not
         * allowed for this.
         * If this data isn't present, decoding has failed.
         */

        p = OSSL_PARAM_locate_const(params, OSSL_OBJECT_PARAM_DATA);
        if (p == NULL || p->data_type != OSSL_PARAM_OCTET_STRING)
            goto end;
        new_data.bio = BIO_new_mem_buf(p->data, (int)p->data_size);
        if (new_data.bio == NULL)
            goto end;
        bio = new_data.bio;

        /* Get the data type if there is one */
        p = OSSL_PARAM_locate_const(params, OSSL_OBJECT_PARAM_DATA_TYPE);
        if (p != NULL && !OSSL_PARAM_get_utf8_string_ptr(p, &data_type))
            goto end;

        /* Get the data structure if there is one */
        p = OSSL_PARAM_locate_const(params, OSSL_OBJECT_PARAM_DATA_STRUCTURE);
        if (p != NULL && !OSSL_PARAM_get_utf8_string_ptr(p, &data_structure))
            goto end;

        /*
         * If the data structure is "type-specific" and the data type is
         * given, we drop the data structure.  The reasoning is that the
         * data type is already enough to find the applicable next decoder,
         * so an additional "type-specific" data structure is extraneous.
         *
         * Furthermore, if the OSSL_DECODER caller asked for a type specific
         * structure under another name, such as "DH", we get a mismatch
         * if the data structure we just received is "type-specific".
         * There's only so much you can do without infusing this code with
         * too special knowledge.
         */
        trace_data_structure = data_structure;
        if (data_type != NULL && data_structure != NULL
            && strcasecmp(data_structure, "type-specific") == 0)
            data_structure = NULL;

        OSSL_TRACE_BEGIN(DECODER) {
            BIO_printf(trc_out,
                       "(ctx %p) %s incoming from previous decoder (%p):\n"
                       "    data type: %s, data structure: %s%s\n",
                       (void *)new_data.ctx, LEVEL, (void *)decoder,
                       data_type, trace_data_structure,
                       (trace_data_structure == data_structure
                        ? "" : " (dropped)"));
        } OSSL_TRACE_END(DECODER);
    }

    /*
     * If we have no more decoders to look through at this point,
     * we failed
     */
    if (data->current_decoder_inst_index == 0)
        goto end;

    if ((loc = BIO_tell(bio)) < 0) {
        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_BIO_LIB);
        goto end;
    }

    if ((cbio = ossl_core_bio_new_from_bio(bio)) == NULL) {
        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE);
        goto end;
    }

    for (i = data->current_decoder_inst_index; i-- > 0;) {
        OSSL_DECODER_INSTANCE *new_decoder_inst =
            sk_OSSL_DECODER_INSTANCE_value(ctx->decoder_insts, i);
        OSSL_DECODER *new_decoder =
            OSSL_DECODER_INSTANCE_get_decoder(new_decoder_inst);
        void *new_decoderctx =
            OSSL_DECODER_INSTANCE_get_decoder_ctx(new_decoder_inst);
        const char *new_input_type =
            OSSL_DECODER_INSTANCE_get_input_type(new_decoder_inst);
        int n_i_s_was_set = 0;   /* We don't care here */
        const char *new_input_structure =
            OSSL_DECODER_INSTANCE_get_input_structure(new_decoder_inst,
                                                      &n_i_s_was_set);

        OSSL_TRACE_BEGIN(DECODER) {
            BIO_printf(trc_out,
                       "(ctx %p) %s [%u] Considering decoder instance %p, which has:\n"
                       "    input type: %s, input structure: %s, decoder: %p\n",
                       (void *)new_data.ctx, LEVEL, (unsigned int)i,
                       (void *)new_decoder_inst, new_input_type,
                       new_input_structure, (void *)new_decoder);
        } OSSL_TRACE_END(DECODER);

        /*
         * If |decoder| is NULL, it means we've just started, and the caller
         * may have specified what it expects the initial input to be.  If
         * that's the case, we do this extra check.
         */
        if (decoder == NULL && ctx->start_input_type != NULL
            && strcasecmp(ctx->start_input_type, new_input_type) != 0) {
            OSSL_TRACE_BEGIN(DECODER) {
                BIO_printf(trc_out,
                           "(ctx %p) %s [%u] the start input type '%s' doesn't match the input type of the considered decoder, skipping...\n",
                           (void *)new_data.ctx, LEVEL, (unsigned int)i,
                           ctx->start_input_type);
            } OSSL_TRACE_END(DECODER);
            continue;
        }

        /*
         * If we have a previous decoder, we check that the input type
         * of the next to be used matches the type of this previous one.
         * |new_input_type| holds the value of the "input-type" parameter
         * for the decoder we're currently considering.
         */
        if (decoder != NULL && !OSSL_DECODER_is_a(decoder, new_input_type)) {
            OSSL_TRACE_BEGIN(DECODER) {
                BIO_printf(trc_out,
                           "(ctx %p) %s [%u] the input type doesn't match the name of the previous decoder (%p), skipping...\n",
                           (void *)new_data.ctx, LEVEL, (unsigned int)i,
                           (void *)decoder);
            } OSSL_TRACE_END(DECODER);
            continue;
        }

        /*
         * If the previous decoder gave us a data type, we check to see
         * if that matches the decoder we're currently considering.
         */
        if (data_type != NULL && !OSSL_DECODER_is_a(new_decoder, data_type)) {
            OSSL_TRACE_BEGIN(DECODER) {
                BIO_printf(trc_out,
                           "(ctx %p) %s [%u] the previous decoder's data type doesn't match the name of the considered decoder, skipping...\n",
                           (void *)new_data.ctx, LEVEL, (unsigned int)i);
            } OSSL_TRACE_END(DECODER);
            continue;
        }

        /*
         * If the previous decoder gave us a data structure name, we check
         * to see that it matches the input data structure of the decoder
         * we're currently considering.
         */
        if (data_structure != NULL
            && (new_input_structure == NULL
                || strcasecmp(data_structure, new_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 of the considered decoder, 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
         * to be a BIO_s_mem(), because the earlier BIO_tell() gives us zero
         * no matter where we are in the underlying buffer we're reading from.
         *
         * So, we simply do a BIO_seek(), and use BIO_tell() that we're back
         * at the same position.  This is a best effort attempt, but BIO_seek()
         * and BIO_tell() should come as a pair...
         */
        (void)BIO_seek(bio, loc);
        if (BIO_tell(bio) != loc)
            goto end;

        /* Recurse */
        OSSL_TRACE_BEGIN(DECODER) {
            BIO_printf(trc_out,
                       "(ctx %p) %s [%u] Running decoder instance %p\n",
                       (void *)new_data.ctx, LEVEL, (unsigned int)i,
                       (void *)new_decoder_inst);
        } OSSL_TRACE_END(DECODER);

        /*
         * We only care about errors reported from decoder implementations
         * if it returns false (i.e. there was a fatal error).
         */
        ERR_set_mark();

        new_data.current_decoder_inst_index = i;
        ok = new_decoder->decode(new_decoderctx, cbio,
                                 new_data.ctx->selection,
                                 decoder_process, &new_data,
                                 ossl_pw_passphrase_callback_dec,
                                 &new_data.ctx->pwdata);

        OSSL_TRACE_BEGIN(DECODER) {
            BIO_printf(trc_out,
                       "(ctx %p) %s [%u] Running decoder instance %p => %d"
                       " (recursed further: %s, construct called: %s)\n",
                       (void *)new_data.ctx, LEVEL, (unsigned int)i,
                       (void *)new_decoder_inst, ok,
                       new_data.flag_next_level_called ? "yes" : "no",
                       new_data.flag_construct_called ? "yes" : "no");
        } OSSL_TRACE_END(DECODER);

        data->flag_construct_called = new_data.flag_construct_called;

        /* Break on error or if we tried to construct an object already */
        if (!ok || data->flag_construct_called) {
            ERR_clear_last_mark();
            break;
        }
        ERR_pop_to_mark();

        /*
         * Break if the decoder implementation that we called recursed, since
         * that indicates that it successfully decoded something.
         */
        if (new_data.flag_next_level_called)
            break;
    }

 end:
    ossl_core_bio_free(cbio);
    BIO_free(new_data.bio);
    return ok;
}
