/*
 * Copyright 2019-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 "e_os.h"                /* strcasecmp on Windows */
#include <openssl/core_names.h>
#include <openssl/bio.h>
#include <openssl/encoder.h>
#include <openssl/buffer.h>
#include <openssl/params.h>
#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 {
    OSSL_ENCODER_CTX *ctx;

    /* Current BIO */
    BIO *bio;

    /* Index of the current encoder instance to be processed */
    int current_encoder_inst_index;

    /* Processing data passed down through recursion */
    int level;                   /* Recursion level */
    OSSL_ENCODER_INSTANCE *next_encoder_inst;
    int count_output_structure;

    /* Processing data passed up through recursion */
    OSSL_ENCODER_INSTANCE *prev_encoder_inst;
    unsigned char *running_output;
    size_t running_output_length;
    /* Data type = the name of the first succeeding encoder implementation */
    const char *data_type;
};

static int encoder_process(struct encoder_process_data_st *data);

int OSSL_ENCODER_to_bio(OSSL_ENCODER_CTX *ctx, BIO *out)
{
    struct encoder_process_data_st data;

    memset(&data, 0, sizeof(data));
    data.ctx = ctx;
    data.bio = out;
    data.current_encoder_inst_index = OSSL_ENCODER_CTX_get_num_encoders(ctx);

    if (data.current_encoder_inst_index == 0) {
        ERR_raise_data(ERR_LIB_OSSL_ENCODER, OSSL_ENCODER_R_ENCODER_NOT_FOUND,
                       "No encoders were found. For standard encoders you need "
                       "at least one of the default or base providers "
                       "available. Did you forget to load them?");
        return 0;
    }

    return encoder_process(&data) > 0;
}

#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_ENCODER, ERR_R_BUF_LIB);
        return NULL;
    }
    BIO_set_fp(b, fp, BIO_NOCLOSE);
    return b;
}

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

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

    BIO_free(b);
    return ret;
}
#endif

int OSSL_ENCODER_to_data(OSSL_ENCODER_CTX *ctx, unsigned char **pdata,
                         size_t *pdata_len)
{
    BIO *out = BIO_new(BIO_s_mem());
    BUF_MEM *buf = NULL;
    int ret = 0;

    if (pdata_len == NULL) {
        ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }

    if (OSSL_ENCODER_to_bio(ctx, out)
        && BIO_get_mem_ptr(out, &buf) > 0) {
        ret = 1; /* Hope for the best. A too small buffer will clear this */

        if (pdata != NULL && *pdata != NULL) {
            if (*pdata_len < buf->length)
                /*
                 * It's tempting to do |*pdata_len = (size_t)buf->length|
                 * However, it's believed to be confusing more than helpful,
                 * so we don't.
                 */
                ret = 0;
            else
                *pdata_len -= buf->length;
        } else {
            /* The buffer with the right size is already allocated for us */
            *pdata_len = (size_t)buf->length;
        }

        if (ret) {
            if (pdata != NULL) {
                if (*pdata != NULL) {
                    memcpy(*pdata, buf->data, buf->length);
                    *pdata += buf->length;
                } else {
                    /* In this case, we steal the data from BIO_s_mem() */
                    *pdata = (unsigned char *)buf->data;
                    buf->data = NULL;
                }
            }
        }
    }
    BIO_free(out);
    return ret;
}

int OSSL_ENCODER_CTX_set_selection(OSSL_ENCODER_CTX *ctx, int selection)
{
    if (!ossl_assert(ctx != NULL)) {
        ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }

    if (!ossl_assert(selection != 0)) {
        ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_INVALID_ARGUMENT);
        return 0;
    }

    ctx->selection = selection;
    return 1;
}

int OSSL_ENCODER_CTX_set_output_type(OSSL_ENCODER_CTX *ctx,
                                     const char *output_type)
{
    if (!ossl_assert(ctx != NULL) || !ossl_assert(output_type != NULL)) {
        ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }

    ctx->output_type = output_type;
    return 1;
}

int OSSL_ENCODER_CTX_set_output_structure(OSSL_ENCODER_CTX *ctx,
                                          const char *output_structure)
{
    if (!ossl_assert(ctx != NULL) || !ossl_assert(output_structure != NULL)) {
        ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }

    ctx->output_structure = output_structure;
    return 1;
}

static OSSL_ENCODER_INSTANCE *ossl_encoder_instance_new(OSSL_ENCODER *encoder,
                                                        void *encoderctx)
{
    OSSL_ENCODER_INSTANCE *encoder_inst = NULL;
    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_inst = OPENSSL_zalloc(sizeof(*encoder_inst))) == NULL) {
        ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_MALLOC_FAILURE);
        return 0;
    }

    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;
 err:
    ossl_encoder_instance_free(encoder_inst);
    return NULL;
}

void ossl_encoder_instance_free(OSSL_ENCODER_INSTANCE *encoder_inst)
{
    if (encoder_inst != NULL) {
        if (encoder_inst->encoder != NULL)
            encoder_inst->encoder->freectx(encoder_inst->encoderctx);
        encoder_inst->encoderctx = NULL;
        OSSL_ENCODER_free(encoder_inst->encoder);
        encoder_inst->encoder = NULL;
        OPENSSL_free(encoder_inst);
    }
}

static int ossl_encoder_ctx_add_encoder_inst(OSSL_ENCODER_CTX *ctx,
                                             OSSL_ENCODER_INSTANCE *ei)
{
    int ok;

    if (ctx->encoder_insts == NULL
        && (ctx->encoder_insts =
            sk_OSSL_ENCODER_INSTANCE_new_null()) == NULL) {
        ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_MALLOC_FAILURE);
        return 0;
    }

    ok = (sk_OSSL_ENCODER_INSTANCE_push(ctx->encoder_insts, ei) > 0);
    if (ok) {
        OSSL_TRACE_BEGIN(ENCODER) {
            BIO_printf(trc_out,
                       "(ctx %p) Added encoder instance %p (encoder %p):\n"
                       "    %s with %s\n",
                       (void *)ctx, (void *)ei, (void *)ei->encoder,
                       OSSL_ENCODER_get0_name(ei->encoder),
                       OSSL_ENCODER_get0_properties(ei->encoder));
        } OSSL_TRACE_END(ENCODER);
    }
    return ok;
}

int OSSL_ENCODER_CTX_add_encoder(OSSL_ENCODER_CTX *ctx, OSSL_ENCODER *encoder)
{
    OSSL_ENCODER_INSTANCE *encoder_inst = NULL;
    const OSSL_PROVIDER *prov = NULL;
    void *encoderctx = NULL;
    void *provctx = NULL;

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

    prov = OSSL_ENCODER_get0_provider(encoder);
    provctx = OSSL_PROVIDER_get0_provider_ctx(prov);

    if ((encoderctx = encoder->newctx(provctx)) == NULL
        || (encoder_inst =
            ossl_encoder_instance_new(encoder, encoderctx)) == NULL)
        goto err;
    /* Avoid double free of encoderctx on further errors */
    encoderctx = NULL;

    if (!ossl_encoder_ctx_add_encoder_inst(ctx, encoder_inst))
        goto err;

    return 1;
 err:
    ossl_encoder_instance_free(encoder_inst);
    if (encoderctx != NULL)
        encoder->freectx(encoderctx);
    return 0;
}

int OSSL_ENCODER_CTX_add_extra(OSSL_ENCODER_CTX *ctx,
                               OSSL_LIB_CTX *libctx, const char *propq)
{
    return 1;
}

int OSSL_ENCODER_CTX_get_num_encoders(OSSL_ENCODER_CTX *ctx)
{
    if (ctx == NULL || ctx->encoder_insts == NULL)
        return 0;
    return sk_OSSL_ENCODER_INSTANCE_num(ctx->encoder_insts);
}

int OSSL_ENCODER_CTX_set_construct(OSSL_ENCODER_CTX *ctx,
                                   OSSL_ENCODER_CONSTRUCT *construct)
{
    if (!ossl_assert(ctx != NULL)) {
        ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }
    ctx->construct = construct;
    return 1;
}

int OSSL_ENCODER_CTX_set_construct_data(OSSL_ENCODER_CTX *ctx,
                                        void *construct_data)
{
    if (!ossl_assert(ctx != NULL)) {
        ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }
    ctx->construct_data = construct_data;
    return 1;
}

int OSSL_ENCODER_CTX_set_cleanup(OSSL_ENCODER_CTX *ctx,
                                 OSSL_ENCODER_CLEANUP *cleanup)
{
    if (!ossl_assert(ctx != NULL)) {
        ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }
    ctx->cleanup = cleanup;
    return 1;
}

OSSL_ENCODER *
OSSL_ENCODER_INSTANCE_get_encoder(OSSL_ENCODER_INSTANCE *encoder_inst)
{
    if (encoder_inst == NULL)
        return NULL;
    return encoder_inst->encoder;
}

void *
OSSL_ENCODER_INSTANCE_get_encoder_ctx(OSSL_ENCODER_INSTANCE *encoder_inst)
{
    if (encoder_inst == NULL)
        return NULL;
    return encoder_inst->encoderctx;
}

const char *
OSSL_ENCODER_INSTANCE_get_output_type(OSSL_ENCODER_INSTANCE *encoder_inst)
{
    if (encoder_inst == NULL)
        return NULL;
    return encoder_inst->output_type;
}

const char *
OSSL_ENCODER_INSTANCE_get_output_structure(OSSL_ENCODER_INSTANCE *encoder_inst)
{
    if (encoder_inst == NULL)
        return NULL;
    return encoder_inst->output_structure;
}

static int encoder_process(struct encoder_process_data_st *data)
{
    OSSL_ENCODER_INSTANCE *current_encoder_inst = NULL;
    OSSL_ENCODER *current_encoder = NULL;
    OSSL_ENCODER_CTX *current_encoder_ctx = NULL;
    BIO *allocated_out = NULL;
    const void *original_data = NULL;
    OSSL_PARAM abstract[10];
    const OSSL_PARAM *current_abstract = NULL;
    int i;
    int ok = -1;  /* -1 signifies that the lookup loop gave nothing */
    int top = 0;

    if (data->next_encoder_inst == NULL) {
        /* First iteration, where we prepare for what is to come */

        data->count_output_structure =
            data->ctx->output_structure == NULL ? -1 : 0;
        top = 1;
    }

    for (i = data->current_encoder_inst_index; i-- > 0;) {
        OSSL_ENCODER *next_encoder = NULL;
        const char *current_output_type;
        const char *current_output_structure;
        struct encoder_process_data_st new_data;

        if (!top)
            next_encoder =
                OSSL_ENCODER_INSTANCE_get_encoder(data->next_encoder_inst);

        current_encoder_inst =
            sk_OSSL_ENCODER_INSTANCE_value(data->ctx->encoder_insts, i);
        current_encoder =
            OSSL_ENCODER_INSTANCE_get_encoder(current_encoder_inst);
        current_encoder_ctx =
            OSSL_ENCODER_INSTANCE_get_encoder_ctx(current_encoder_inst);
        current_output_type =
            OSSL_ENCODER_INSTANCE_get_output_type(current_encoder_inst);
        current_output_structure =
            OSSL_ENCODER_INSTANCE_get_output_structure(current_encoder_inst);
        memset(&new_data, 0, sizeof(new_data));
        new_data.ctx = data->ctx;
        new_data.current_encoder_inst_index = i;
        new_data.next_encoder_inst = current_encoder_inst;
        new_data.count_output_structure = data->count_output_structure;
        new_data.level = data->level + 1;

        OSSL_TRACE_BEGIN(ENCODER) {
            BIO_printf(trc_out,
                       "[%d] (ctx %p) Considering encoder instance %p (encoder %p)\n",
                       data->level, (void *)data->ctx,
                       (void *)current_encoder_inst, (void *)current_encoder);
        } OSSL_TRACE_END(ENCODER);

        /*
         * If this is the top call, we check if the output type of the current
         * encoder matches the desired output type.
         * If this isn't the top call, i.e. this is deeper in the recursion,
         * we instead check if the output type of the current encoder matches
         * the name of the next encoder (the one found by the parent call).
         */
        if (top) {
            if (data->ctx->output_type != NULL
                && strcasecmp(current_output_type,
                              data->ctx->output_type) != 0) {
                OSSL_TRACE_BEGIN(ENCODER) {
                    BIO_printf(trc_out,
                               "[%d]    Skipping because current encoder output type (%s) != desired output type (%s)\n",
                               data->level,
                               current_output_type, data->ctx->output_type);
                } OSSL_TRACE_END(ENCODER);
                continue;
            }
        } else {
            if (!OSSL_ENCODER_is_a(next_encoder, current_output_type)) {
                OSSL_TRACE_BEGIN(ENCODER) {
                    BIO_printf(trc_out,
                               "[%d]    Skipping because current encoder output type (%s) != name of encoder %p\n",
                               data->level,
                               current_output_type, (void *)next_encoder);
                } OSSL_TRACE_END(ENCODER);
                continue;
            }
        }

        /*
         * If the caller and the current encoder specify an output structure,
         * Check if they match.  If they do, count the match, otherwise skip
         * the current encoder.
         */
        if (data->ctx->output_structure != NULL
            && current_output_structure != NULL) {
            if (strcasecmp(data->ctx->output_structure,
                           current_output_structure) != 0) {
                OSSL_TRACE_BEGIN(ENCODER) {
                    BIO_printf(trc_out,
                               "[%d]    Skipping because current encoder output structure (%s) != ctx output structure (%s)\n",
                               data->level,
                               current_output_structure,
                               data->ctx->output_structure);
                } OSSL_TRACE_END(ENCODER);
                continue;
            }

            data->count_output_structure++;
        }

        /*
         * Recurse to process the encoder implementations before the current
         * one.
         */
        ok = encoder_process(&new_data);

        data->prev_encoder_inst = new_data.prev_encoder_inst;
        data->running_output = new_data.running_output;
        data->running_output_length = new_data.running_output_length;

        /*
         * ok == -1     means that the recursion call above gave no further
         *              encoders, and that the one we're currently at should
         *              be tried.
         * ok == 0      means that something failed in the recursion call
         *              above, making the result unsuitable for a chain.
         *              In this case, we simply continue to try finding a
         *              suitable encoder at this recursion level.
         * ok == 1      means that the recursion call was successful, and we
         *              try to use the result at this recursion level.
         */
        if (ok != 0)
            break;

        OSSL_TRACE_BEGIN(ENCODER) {
            BIO_printf(trc_out,
                       "[%d]    Skipping because recusion level %d failed\n",
                       data->level, new_data.level);
        } OSSL_TRACE_END(ENCODER);
    }

    /*
     * If |i < 0|, we didn't find any useful encoder in this recursion, so
     * we do the rest of the process only if |i >= 0|.
     */
    if (i < 0) {
        ok = -1;

        OSSL_TRACE_BEGIN(ENCODER) {
            BIO_printf(trc_out,
                       "[%d] (ctx %p) No suitable encoder found\n",
                       data->level, (void *)data->ctx);
        } OSSL_TRACE_END(ENCODER);
    } else {
        /* Preparations */

        switch (ok) {
        case 0:
            break;
        case -1:
            /*
             * We have reached the beginning of the encoder instance sequence,
             * so we prepare the object to be encoded.
             */

            /*
             * |data->count_output_structure| is one of these values:
             *
             * -1       There is no desired output structure
             *  0       There is a desired output structure, and it wasn't
             *          matched by any of the encoder instances that were
             *          considered
             * >0       There is a desired output structure, and at least one
             *          of the encoder instances matched it
             */
            if (data->count_output_structure == 0)
                return 0;

            original_data =
                data->ctx->construct(current_encoder_inst,
                                     data->ctx->construct_data);

            /* Also set the data type, using the encoder implementation name */
            data->data_type = OSSL_ENCODER_get0_name(current_encoder);

            /* Assume that the constructor recorded an error */
            if (original_data != NULL)
                ok = 1;
            else
                ok = 0;
            break;
        case 1:
            if (!ossl_assert(data->running_output != NULL)) {
                ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_INTERNAL_ERROR);
                ok = 0;
                break;
            }

            {
                /*
                 * Create an object abstraction from the latest output, which
                 * was stolen from the previous round.
                 */

                OSSL_PARAM *abstract_p = abstract;
                const char *prev_output_structure =
                    OSSL_ENCODER_INSTANCE_get_output_structure(data->prev_encoder_inst);

                *abstract_p++ =
                    OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_TYPE,
                                                     (char *)data->data_type, 0);
                if (prev_output_structure != NULL)
                    *abstract_p++ =
                        OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_STRUCTURE,
                                                         (char *)prev_output_structure,
                                                         0);
                *abstract_p++ =
                    OSSL_PARAM_construct_octet_string(OSSL_OBJECT_PARAM_DATA,
                                                      data->running_output,
                                                      data->running_output_length);
                *abstract_p = OSSL_PARAM_construct_end();
                current_abstract = abstract;
            }
            break;
        }

        /* Calling the encoder implementation */

        if (ok) {
            OSSL_CORE_BIO *cbio = NULL;
            BIO *current_out = NULL;

            /*
             * If we're at the last encoder instance to use, we're setting up
             * final output.  Otherwise, set up an intermediary memory output.
             */
            if (top)
                current_out = data->bio;
            else if ((current_out = allocated_out = BIO_new(BIO_s_mem()))
                     == NULL)
                ok = 0;     /* Assume BIO_new() recorded an error */

            if (ok)
                ok = (cbio = ossl_core_bio_new_from_bio(current_out)) != NULL;
            if (ok) {
                ok = current_encoder->encode(current_encoder_ctx, cbio,
                                             original_data, current_abstract,
                                             data->ctx->selection,
                                             ossl_pw_passphrase_callback_enc,
                                             &data->ctx->pwdata);
                OSSL_TRACE_BEGIN(ENCODER) {
                    BIO_printf(trc_out,
                               "[%d] (ctx %p) Running encoder instance %p => %d\n",
                               data->level, (void *)data->ctx,
                               (void *)current_encoder_inst, ok);
                } OSSL_TRACE_END(ENCODER);
            }

            ossl_core_bio_free(cbio);
            data->prev_encoder_inst = current_encoder_inst;
        }
    }

    /* Cleanup and collecting the result */

    OPENSSL_free(data->running_output);
    data->running_output = NULL;

    /*
     * Steal the output from the BIO_s_mem, if we did allocate one.
     * That'll be the data for an object abstraction in the next round.
     */
    if (allocated_out != NULL) {
        BUF_MEM *buf;

        BIO_get_mem_ptr(allocated_out, &buf);
        data->running_output = (unsigned char *)buf->data;
        data->running_output_length = buf->length;
        memset(buf, 0, sizeof(*buf));
    }

    BIO_free(allocated_out);
    if (original_data != NULL)
        data->ctx->cleanup(data->ctx->construct_data);
    return ok;
}
