/*
 * 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.h>
#include <openssl/core_dispatch.h>
#include <openssl/decoder.h>
#include <openssl/ui.h>
#include "internal/core.h"
#include "internal/namemap.h"
#include "internal/property.h"
#include "internal/provider.h"
#include "crypto/decoder.h"
#include "encoder_local.h"

/*
 * Decoder can have multiple names, separated with colons in a name string
 */
#define NAME_SEPARATOR ':'

/* Simple method structure constructor and destructor */
static OSSL_DECODER *ossl_decoder_new(void)
{
    OSSL_DECODER *decoder = NULL;

    if ((decoder = OPENSSL_zalloc(sizeof(*decoder))) == NULL
        || (decoder->base.lock = CRYPTO_THREAD_lock_new()) == NULL) {
        OSSL_DECODER_free(decoder);
        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE);
        return NULL;
    }

    decoder->base.refcnt = 1;

    return decoder;
}

int OSSL_DECODER_up_ref(OSSL_DECODER *decoder)
{
    int ref = 0;

    CRYPTO_UP_REF(&decoder->base.refcnt, &ref, decoder->base.lock);
    return 1;
}

void OSSL_DECODER_free(OSSL_DECODER *decoder)
{
    int ref = 0;

    if (decoder == NULL)
        return;

    CRYPTO_DOWN_REF(&decoder->base.refcnt, &ref, decoder->base.lock);
    if (ref > 0)
        return;
    OPENSSL_free(decoder->base.name);
    ossl_property_free(decoder->base.parsed_propdef);
    ossl_provider_free(decoder->base.prov);
    CRYPTO_THREAD_lock_free(decoder->base.lock);
    OPENSSL_free(decoder);
}

/* Permanent decoder method store, constructor and destructor */
static void decoder_store_free(void *vstore)
{
    ossl_method_store_free(vstore);
}

static void *decoder_store_new(OSSL_LIB_CTX *ctx)
{
    return ossl_method_store_new(ctx);
}


static const OSSL_LIB_CTX_METHOD decoder_store_method = {
    /* We want decoder_store to be cleaned up before the provider store */
    OSSL_LIB_CTX_METHOD_PRIORITY_2,
    decoder_store_new,
    decoder_store_free,
};

/* Data to be passed through ossl_method_construct() */
struct decoder_data_st {
    OSSL_LIB_CTX *libctx;
    int id;                      /* For get_decoder_from_store() */
    const char *names;           /* For get_decoder_from_store() */
    const char *propquery;       /* For get_decoder_from_store() */

    OSSL_METHOD_STORE *tmp_store; /* For get_tmp_decoder_store() */

    unsigned int flag_construct_error_occurred : 1;
};

/*
 * Generic routines to fetch / create DECODER methods with
 * ossl_method_construct()
 */

/* Temporary decoder method store, constructor and destructor */
static void *get_tmp_decoder_store(void *data)
{
    struct decoder_data_st *methdata = data;

    if (methdata->tmp_store == NULL)
        methdata->tmp_store = ossl_method_store_new(methdata->libctx);
    return methdata->tmp_store;
}

static void dealloc_tmp_decoder_store(void *store)
{
    if (store != NULL)
        ossl_method_store_free(store);
}

/* Get the permanent decoder store */
static OSSL_METHOD_STORE *get_decoder_store(OSSL_LIB_CTX *libctx)
{
    return ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_DECODER_STORE_INDEX,
                                 &decoder_store_method);
}

/* Get decoder methods from a store, or put one in */
static void *get_decoder_from_store(void *store, const OSSL_PROVIDER **prov,
                                    void *data)
{
    struct decoder_data_st *methdata = data;
    void *method = NULL;
    int id;

    /*
     * get_decoder_from_store() is only called to try and get the method
     * that OSSL_DECODER_fetch() is asking for, and the name or name id are
     * passed via methdata.
     */
    if ((id = methdata->id) == 0 && methdata->names != NULL) {
        OSSL_NAMEMAP *namemap = ossl_namemap_stored(methdata->libctx);
        const char *names = methdata->names;
        const char *q = strchr(names, NAME_SEPARATOR);
        size_t l = (q == NULL ? strlen(names) : (size_t)(q - names));

        if (namemap == 0)
            return NULL;
        id = ossl_namemap_name2num_n(namemap, names, l);
    }

    if (id == 0)
        return NULL;

    if (store == NULL
        && (store = get_decoder_store(methdata->libctx)) == NULL)
        return NULL;

    if (!ossl_method_store_fetch(store, id, methdata->propquery, prov, &method))
        return NULL;
    return method;
}

static int put_decoder_in_store(void *store, void *method,
                                const OSSL_PROVIDER *prov,
                                const char *names, const char *propdef,
                                void *data)
{
    struct decoder_data_st *methdata = data;
    OSSL_NAMEMAP *namemap;
    int id;
    size_t l = 0;

    /*
     * put_decoder_in_store() is only called with an OSSL_DECODER method that
     * was successfully created by construct_decoder() below, which means that
     * all the names should already be stored in the namemap with the same
     * numeric identity, so just use the first to get that identity.
     */
    if (names != NULL) {
        const char *q = strchr(names, NAME_SEPARATOR);

        l = (q == NULL ? strlen(names) : (size_t)(q - names));
    }

    if ((namemap = ossl_namemap_stored(methdata->libctx)) == NULL
        || (id = ossl_namemap_name2num_n(namemap, names, l)) == 0)
        return 0;

    if (store == NULL && (store = get_decoder_store(methdata->libctx)) == NULL)
        return 0;

    return ossl_method_store_add(store, prov, id, propdef, method,
                                 (int (*)(void *))OSSL_DECODER_up_ref,
                                 (void (*)(void *))OSSL_DECODER_free);
}

/* Create and populate a decoder method */
void *ossl_decoder_from_algorithm(int id, const OSSL_ALGORITHM *algodef,
                                  OSSL_PROVIDER *prov)
{
    OSSL_DECODER *decoder = NULL;
    const OSSL_DISPATCH *fns = algodef->implementation;
    OSSL_LIB_CTX *libctx = ossl_provider_libctx(prov);

    if ((decoder = ossl_decoder_new()) == NULL)
        return NULL;
    decoder->base.id = id;
    if ((decoder->base.name = ossl_algorithm_get1_first_name(algodef)) == NULL) {
        OSSL_DECODER_free(decoder);
        return NULL;
    }
    decoder->base.algodef = algodef;
    decoder->base.parsed_propdef
        = ossl_parse_property(libctx, algodef->property_definition);

    for (; fns->function_id != 0; fns++) {
        switch (fns->function_id) {
        case OSSL_FUNC_DECODER_NEWCTX:
            if (decoder->newctx == NULL)
                decoder->newctx = OSSL_FUNC_decoder_newctx(fns);
            break;
        case OSSL_FUNC_DECODER_FREECTX:
            if (decoder->freectx == NULL)
                decoder->freectx = OSSL_FUNC_decoder_freectx(fns);
            break;
        case OSSL_FUNC_DECODER_GET_PARAMS:
            if (decoder->get_params == NULL)
                decoder->get_params =
                    OSSL_FUNC_decoder_get_params(fns);
            break;
        case OSSL_FUNC_DECODER_GETTABLE_PARAMS:
            if (decoder->gettable_params == NULL)
                decoder->gettable_params =
                    OSSL_FUNC_decoder_gettable_params(fns);
            break;
        case OSSL_FUNC_DECODER_SET_CTX_PARAMS:
            if (decoder->set_ctx_params == NULL)
                decoder->set_ctx_params =
                    OSSL_FUNC_decoder_set_ctx_params(fns);
            break;
        case OSSL_FUNC_DECODER_SETTABLE_CTX_PARAMS:
            if (decoder->settable_ctx_params == NULL)
                decoder->settable_ctx_params =
                    OSSL_FUNC_decoder_settable_ctx_params(fns);
            break;
        case OSSL_FUNC_DECODER_DOES_SELECTION:
            if (decoder->does_selection == NULL)
                decoder->does_selection =
                    OSSL_FUNC_decoder_does_selection(fns);
            break;
        case OSSL_FUNC_DECODER_DECODE:
            if (decoder->decode == NULL)
                decoder->decode = OSSL_FUNC_decoder_decode(fns);
            break;
        case OSSL_FUNC_DECODER_EXPORT_OBJECT:
            if (decoder->export_object == NULL)
                decoder->export_object = OSSL_FUNC_decoder_export_object(fns);
            break;
        }
    }
    /*
     * Try to check that the method is sensible.
     * If you have a constructor, you must have a destructor and vice versa.
     * You must have at least one of the encoding driver functions.
     */
    if (!((decoder->newctx == NULL && decoder->freectx == NULL)
          || (decoder->newctx != NULL && decoder->freectx != NULL))
        || decoder->decode == NULL) {
        OSSL_DECODER_free(decoder);
        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_INVALID_PROVIDER_FUNCTIONS);
        return NULL;
    }

    if (prov != NULL && !ossl_provider_up_ref(prov)) {
        OSSL_DECODER_free(decoder);
        return NULL;
    }

    decoder->base.prov = prov;
    return decoder;
}


/*
 * The core fetching functionality passes the names of the implementation.
 * This function is responsible to getting an identity number for them,
 * then call ossl_decoder_from_algorithm() with that identity number.
 */
static void *construct_decoder(const OSSL_ALGORITHM *algodef,
                               OSSL_PROVIDER *prov, void *data)
{
    /*
     * This function is only called if get_decoder_from_store() returned
     * NULL, so it's safe to say that of all the spots to create a new
     * namemap entry, this is it.  Should the name already exist there, we
     * know that ossl_namemap_add() will return its corresponding number.
     */
    struct decoder_data_st *methdata = data;
    OSSL_LIB_CTX *libctx = ossl_provider_libctx(prov);
    OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
    const char *names = algodef->algorithm_names;
    int id = ossl_namemap_add_names(namemap, 0, names, NAME_SEPARATOR);
    void *method = NULL;

    if (id != 0)
        method = ossl_decoder_from_algorithm(id, algodef, prov);

    /*
     * Flag to indicate that there was actual construction errors.  This
     * helps inner_evp_generic_fetch() determine what error it should
     * record on inaccessible algorithms.
     */
    if (method == NULL)
        methdata->flag_construct_error_occurred = 1;

    return method;
}

/* Intermediary function to avoid ugly casts, used below */
static void destruct_decoder(void *method, void *data)
{
    OSSL_DECODER_free(method);
}

static int up_ref_decoder(void *method)
{
    return OSSL_DECODER_up_ref(method);
}

static void free_decoder(void *method)
{
    OSSL_DECODER_free(method);
}

/* Fetching support.  Can fetch by numeric identity or by name */
static OSSL_DECODER *
inner_ossl_decoder_fetch(struct decoder_data_st *methdata, int id,
                         const char *name, const char *properties)
{
    OSSL_METHOD_STORE *store = get_decoder_store(methdata->libctx);
    OSSL_NAMEMAP *namemap = ossl_namemap_stored(methdata->libctx);
    const char *const propq = properties != NULL ? properties : "";
    void *method = NULL;
    int unsupported = 0;

    if (store == NULL || namemap == NULL) {
        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_INVALID_ARGUMENT);
        return NULL;
    }

    /*
     * If we have been passed both an id and a name, we have an
     * internal programming error.
     */
    if (!ossl_assert(id == 0 || name == NULL)) {
        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_INTERNAL_ERROR);
        return NULL;
    }

    if (id == 0 && name != NULL)
        id = ossl_namemap_name2num(namemap, name);

    /*
     * If we haven't found the name yet, chances are that the algorithm to
     * be fetched is unsupported.
     */
    if (id == 0)
        unsupported = 1;

    if (id == 0
        || !ossl_method_store_cache_get(store, NULL, id, propq, &method)) {
        OSSL_METHOD_CONSTRUCT_METHOD mcm = {
            get_tmp_decoder_store,
            get_decoder_from_store,
            put_decoder_in_store,
            construct_decoder,
            destruct_decoder
        };
        OSSL_PROVIDER *prov = NULL;

        methdata->id = id;
        methdata->names = name;
        methdata->propquery = propq;
        methdata->flag_construct_error_occurred = 0;
        if ((method = ossl_method_construct(methdata->libctx, OSSL_OP_DECODER,
                                            &prov, 0 /* !force_cache */,
                                            &mcm, methdata)) != NULL) {
            /*
             * If construction did create a method for us, we know that
             * there is a correct name_id and meth_id, since those have
             * already been calculated in get_decoder_from_store() and
             * put_decoder_in_store() above.
             */
            if (id == 0 && name != NULL)
                id = ossl_namemap_name2num(namemap, name);
            if (id != 0)
                ossl_method_store_cache_set(store, prov, id, propq, method,
                                            up_ref_decoder, free_decoder);
        }

        /*
         * If we never were in the constructor, the algorithm to be fetched
         * is unsupported.
         */
        unsupported = !methdata->flag_construct_error_occurred;
    }

    if ((id != 0 || name != NULL) && method == NULL) {
        int code = unsupported ? ERR_R_UNSUPPORTED : ERR_R_FETCH_FAILED;

        if (name == NULL)
            name = ossl_namemap_num2name(namemap, id, 0);
        ERR_raise_data(ERR_LIB_OSSL_DECODER, code,
                       "%s, Name (%s : %d), Properties (%s)",
                       ossl_lib_ctx_get_descriptor(methdata->libctx),
                       name = NULL ? "<null>" : name, id,
                       properties == NULL ? "<null>" : properties);
    }

    return method;
}

OSSL_DECODER *OSSL_DECODER_fetch(OSSL_LIB_CTX *libctx, const char *name,
                                 const char *properties)
{
    struct decoder_data_st methdata;
    void *method;

    methdata.libctx = libctx;
    methdata.tmp_store = NULL;
    method = inner_ossl_decoder_fetch(&methdata, 0, name, properties);
    dealloc_tmp_decoder_store(methdata.tmp_store);
    return method;
}

OSSL_DECODER *ossl_decoder_fetch_by_number(OSSL_LIB_CTX *libctx, int id,
                                           const char *properties)
{
    struct decoder_data_st methdata;
    void *method;

    methdata.libctx = libctx;
    methdata.tmp_store = NULL;
    method = inner_ossl_decoder_fetch(&methdata, id, NULL, properties);
    dealloc_tmp_decoder_store(methdata.tmp_store);
    return method;
}

/*
 * Library of basic method functions
 */

const OSSL_PROVIDER *OSSL_DECODER_get0_provider(const OSSL_DECODER *decoder)
{
    if (!ossl_assert(decoder != NULL)) {
        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }

    return decoder->base.prov;
}

const char *OSSL_DECODER_get0_properties(const OSSL_DECODER *decoder)
{
    if (!ossl_assert(decoder != NULL)) {
        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }

    return decoder->base.algodef->property_definition;
}

const OSSL_PROPERTY_LIST *
ossl_decoder_parsed_properties(const OSSL_DECODER *decoder)
{
    if (!ossl_assert(decoder != NULL)) {
        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }

    return decoder->base.parsed_propdef;
}

int ossl_decoder_get_number(const OSSL_DECODER *decoder)
{
    if (!ossl_assert(decoder != NULL)) {
        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }

    return decoder->base.id;
}

const char *OSSL_DECODER_get0_name(const OSSL_DECODER *decoder)
{
    return decoder->base.name;
}

const char *OSSL_DECODER_get0_description(const OSSL_DECODER *decoder)
{
    return decoder->base.algodef->algorithm_description;
}

int OSSL_DECODER_is_a(const OSSL_DECODER *decoder, const char *name)
{
    if (decoder->base.prov != NULL) {
        OSSL_LIB_CTX *libctx = ossl_provider_libctx(decoder->base.prov);
        OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);

        return ossl_namemap_name2num(namemap, name) == decoder->base.id;
    }
    return 0;
}

struct do_one_data_st {
    void (*user_fn)(OSSL_DECODER *decoder, void *arg);
    void *user_arg;
};

static void do_one(ossl_unused int id, void *method, void *arg)
{
    struct do_one_data_st *data = arg;

    data->user_fn(method, data->user_arg);
}

void OSSL_DECODER_do_all_provided(OSSL_LIB_CTX *libctx,
                                  void (*user_fn)(OSSL_DECODER *decoder,
                                                  void *arg),
                                  void *user_arg)
{
    struct decoder_data_st methdata;
    struct do_one_data_st data;

    methdata.libctx = libctx;
    methdata.tmp_store = NULL;
    (void)inner_ossl_decoder_fetch(&methdata, 0, NULL, NULL /* properties */);

    data.user_fn = user_fn;
    data.user_arg = user_arg;
    if (methdata.tmp_store != NULL)
        ossl_method_store_do_all(methdata.tmp_store, &do_one, &data);
    ossl_method_store_do_all(get_decoder_store(libctx), &do_one, &data);
    dealloc_tmp_decoder_store(methdata.tmp_store);
}

int OSSL_DECODER_names_do_all(const OSSL_DECODER *decoder,
                              void (*fn)(const char *name, void *data),
                              void *data)
{
    if (decoder == NULL)
        return 0;

    if (decoder->base.prov != NULL) {
        OSSL_LIB_CTX *libctx = ossl_provider_libctx(decoder->base.prov);
        OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);

        return ossl_namemap_doall_names(namemap, decoder->base.id, fn, data);
    }

    return 1;
}

const OSSL_PARAM *
OSSL_DECODER_gettable_params(OSSL_DECODER *decoder)
{
    if (decoder != NULL && decoder->gettable_params != NULL) {
        void *provctx = ossl_provider_ctx(OSSL_DECODER_get0_provider(decoder));

        return decoder->gettable_params(provctx);
    }
    return NULL;
}

int OSSL_DECODER_get_params(OSSL_DECODER *decoder, OSSL_PARAM params[])
{
    if (decoder != NULL && decoder->get_params != NULL)
        return decoder->get_params(params);
    return 0;
}

const OSSL_PARAM *
OSSL_DECODER_settable_ctx_params(OSSL_DECODER *decoder)
{
    if (decoder != NULL && decoder->settable_ctx_params != NULL) {
        void *provctx = ossl_provider_ctx(OSSL_DECODER_get0_provider(decoder));

        return decoder->settable_ctx_params(provctx);
    }
    return NULL;
}

/*
 * Decoder context support
 */

/*
 * |encoder| value NULL is valid, and signifies that there is no decoder.
 * This is useful to provide fallback mechanisms.
 *  Functions that want to verify if there is a decoder can do so with
 * OSSL_DECODER_CTX_get_decoder()
 */
OSSL_DECODER_CTX *OSSL_DECODER_CTX_new(void)
{
    OSSL_DECODER_CTX *ctx;

    if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL)
        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE);

    return ctx;
}

int OSSL_DECODER_CTX_set_params(OSSL_DECODER_CTX *ctx,
                                const OSSL_PARAM params[])
{
    int ok = 1;
    size_t i;
    size_t l;

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

    if (ctx->decoder_insts == NULL)
        return 1;

    l = OSSL_DECODER_CTX_get_num_decoders(ctx);
    for (i = 0; i < l; i++) {
        OSSL_DECODER_INSTANCE *decoder_inst =
            sk_OSSL_DECODER_INSTANCE_value(ctx->decoder_insts, i);
        OSSL_DECODER *decoder =
            OSSL_DECODER_INSTANCE_get_decoder(decoder_inst);
        OSSL_DECODER *decoderctx =
            OSSL_DECODER_INSTANCE_get_decoder_ctx(decoder_inst);

        if (decoderctx == NULL || decoder->set_ctx_params == NULL)
            continue;
        if (!decoder->set_ctx_params(decoderctx, params))
            ok = 0;
    }
    return ok;
}

void OSSL_DECODER_CTX_free(OSSL_DECODER_CTX *ctx)
{
    if (ctx != NULL) {
        if (ctx->cleanup != NULL)
            ctx->cleanup(ctx->construct_data);
        sk_OSSL_DECODER_INSTANCE_pop_free(ctx->decoder_insts,
                                          ossl_decoder_instance_free);
        ossl_pw_clear_passphrase_data(&ctx->pwdata);
        OPENSSL_free(ctx);
    }
}
