/*
 * 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 "internal/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;
    BUF_MEM *buf = NULL;
    int ret = 0;

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

    out = BIO_new(BIO_s_mem());

    if (out != NULL
        && 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 recursion 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;
}
