/*
 * 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/crypto.h>
#include "crypto/store.h"
#include "internal/core.h"
#include "internal/namemap.h"
#include "internal/property.h"
#include "internal/provider.h"
#include "store_local.h"

int OSSL_STORE_LOADER_up_ref(OSSL_STORE_LOADER *loader)
{
    int ref = 0;

    if (loader->prov != NULL)
        CRYPTO_UP_REF(&loader->refcnt, &ref, loader->lock);
    return 1;
}

void OSSL_STORE_LOADER_free(OSSL_STORE_LOADER *loader)
{
    if (loader != NULL && loader->prov != NULL) {
        int i;

        CRYPTO_DOWN_REF(&loader->refcnt, &i, loader->lock);
        if (i > 0)
            return;
        ossl_provider_free(loader->prov);
        CRYPTO_THREAD_lock_free(loader->lock);
    }
    OPENSSL_free(loader);
}

/*
 * OSSL_STORE_LOADER_new() expects the scheme as a constant string,
 * which we currently don't have, so we need an alternative allocator.
 */
static OSSL_STORE_LOADER *new_loader(OSSL_PROVIDER *prov)
{
    OSSL_STORE_LOADER *loader;

    if ((loader = OPENSSL_zalloc(sizeof(*loader))) == NULL
        || (loader->lock = CRYPTO_THREAD_lock_new()) == NULL) {
        OPENSSL_free(loader);
        return NULL;
    }
    loader->prov = prov;
    ossl_provider_up_ref(prov);
    loader->refcnt = 1;

    return loader;
}

static int up_ref_loader(void *method)
{
    return OSSL_STORE_LOADER_up_ref(method);
}

static void free_loader(void *method)
{
    OSSL_STORE_LOADER_free(method);
}

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

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


static const OSSL_LIB_CTX_METHOD loader_store_method = {
    /* We want loader_store to be cleaned up before the provider store */
    OSSL_LIB_CTX_METHOD_PRIORITY_2,
    loader_store_new,
    loader_store_free,
};

/* Data to be passed through ossl_method_construct() */
struct loader_data_st {
    OSSL_LIB_CTX *libctx;
    int scheme_id;               /* For get_loader_from_store() */
    const char *scheme;          /* For get_loader_from_store() */
    const char *propquery;       /* For get_loader_from_store() */

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

    unsigned int flag_construct_error_occurred : 1;
};

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

/* Temporary loader method store, constructor and destructor */
static void *get_tmp_loader_store(void *data)
{
    struct loader_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_loader_store(void *store)
{
    if (store != NULL)
        ossl_method_store_free(store);
}

/* Get the permanent loader store */
static OSSL_METHOD_STORE *get_loader_store(OSSL_LIB_CTX *libctx)
{
    return ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_STORE_LOADER_STORE_INDEX,
                                &loader_store_method);
}

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

    if ((id = methdata->scheme_id) == 0) {
        OSSL_NAMEMAP *namemap = ossl_namemap_stored(methdata->libctx);

        id = ossl_namemap_name2num(namemap, methdata->scheme);
    }

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

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

static int put_loader_in_store(void *store, void *method,
                               const OSSL_PROVIDER *prov,
                               const char *scheme, const char *propdef,
                               void *data)
{
    struct loader_data_st *methdata = data;
    OSSL_NAMEMAP *namemap;
    int id;

    if ((namemap = ossl_namemap_stored(methdata->libctx)) == NULL
        || (id = ossl_namemap_name2num(namemap, scheme)) == 0)
        return 0;

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

    return ossl_method_store_add(store, prov, id, propdef, method,
                                 up_ref_loader, free_loader);
}

static void *loader_from_algorithm(int scheme_id, const OSSL_ALGORITHM *algodef,
                                   OSSL_PROVIDER *prov)
{
    OSSL_STORE_LOADER *loader = NULL;
    const OSSL_DISPATCH *fns = algodef->implementation;

    if ((loader = new_loader(prov)) == NULL)
        return NULL;
    loader->scheme_id = scheme_id;
    loader->propdef = algodef->property_definition;
    loader->description = algodef->algorithm_description;

    for (; fns->function_id != 0; fns++) {
        switch (fns->function_id) {
        case OSSL_FUNC_STORE_OPEN:
            if (loader->p_open == NULL)
                loader->p_open = OSSL_FUNC_store_open(fns);
            break;
        case OSSL_FUNC_STORE_ATTACH:
            if (loader->p_attach == NULL)
                loader->p_attach = OSSL_FUNC_store_attach(fns);
            break;
        case OSSL_FUNC_STORE_SETTABLE_CTX_PARAMS:
            if (loader->p_settable_ctx_params == NULL)
                loader->p_settable_ctx_params =
                    OSSL_FUNC_store_settable_ctx_params(fns);
            break;
        case OSSL_FUNC_STORE_SET_CTX_PARAMS:
            if (loader->p_set_ctx_params == NULL)
                loader->p_set_ctx_params = OSSL_FUNC_store_set_ctx_params(fns);
            break;
        case OSSL_FUNC_STORE_LOAD:
            if (loader->p_load == NULL)
                loader->p_load = OSSL_FUNC_store_load(fns);
            break;
        case OSSL_FUNC_STORE_EOF:
            if (loader->p_eof == NULL)
                loader->p_eof = OSSL_FUNC_store_eof(fns);
            break;
        case OSSL_FUNC_STORE_CLOSE:
            if (loader->p_close == NULL)
                loader->p_close = OSSL_FUNC_store_close(fns);
            break;
        case OSSL_FUNC_STORE_EXPORT_OBJECT:
            if (loader->p_export_object == NULL)
                loader->p_export_object = OSSL_FUNC_store_export_object(fns);
            break;
        }
    }

    if ((loader->p_open == NULL && loader->p_attach == NULL)
        || loader->p_load == NULL
        || loader->p_eof == NULL
        || loader->p_close == NULL) {
        /* Only set_ctx_params is optionaal */
        OSSL_STORE_LOADER_free(loader);
        ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_LOADER_INCOMPLETE);
        return NULL;
    }
    return loader;
}

/*
 * The core fetching functionality passes the scheme of the implementation.
 * This function is responsible to getting an identity number for them,
 * then call loader_from_algorithm() with that identity number.
 */
static void *construct_loader(const OSSL_ALGORITHM *algodef,
                              OSSL_PROVIDER *prov, void *data)
{
    /*
     * This function is only called if get_loader_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 scheme already exist there, we
     * know that ossl_namemap_add() will return its corresponding number.
     */
    struct loader_data_st *methdata = data;
    OSSL_LIB_CTX *libctx = ossl_provider_libctx(prov);
    OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
    const char *scheme = algodef->algorithm_names;
    int id = ossl_namemap_add_name(namemap, 0, scheme);
    void *method = NULL;

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

    /*
     * Flag to indicate that there was actual construction errors.  This
     * helps inner_loader_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_loader(void *method, void *data)
{
    OSSL_STORE_LOADER_free(method);
}

/* Fetching support.  Can fetch by numeric identity or by scheme */
static OSSL_STORE_LOADER *
inner_loader_fetch(struct loader_data_st *methdata, int id,
                   const char *scheme, const char *properties)
{
    OSSL_METHOD_STORE *store = get_loader_store(methdata->libctx);
    OSSL_NAMEMAP *namemap = ossl_namemap_stored(methdata->libctx);
    void *method = NULL;
    int unsupported = 0;

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

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

    /* If we haven't received a name id yet, try to get one for the name */
    if (id == 0 && scheme != NULL)
        id = ossl_namemap_name2num(namemap, scheme);

    /*
     * 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, properties, &method)) {
        OSSL_METHOD_CONSTRUCT_METHOD mcm = {
            get_tmp_loader_store,
            get_loader_from_store,
            put_loader_in_store,
            construct_loader,
            destruct_loader
        };
        OSSL_PROVIDER *prov = NULL;

        methdata->scheme_id = id;
        methdata->scheme = scheme;
        methdata->propquery = properties;
        methdata->flag_construct_error_occurred = 0;
        if ((method = ossl_method_construct(methdata->libctx, OSSL_OP_STORE,
                                            &prov, 0 /* !force_cache */,
                                            &mcm, methdata)) != NULL) {
            /*
             * If construction did create a method for us, we know that there
             * is a correct scheme_id, since those have already been calculated
             * in get_loader_from_store() and put_loader_in_store() above.
             */
            if (id == 0)
                id = ossl_namemap_name2num(namemap, scheme);
            ossl_method_store_cache_set(store, prov, id, properties, method,
                                        up_ref_loader, free_loader);
        }

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

    if ((id != 0 || scheme != NULL) && method == NULL) {
        int code = unsupported ? ERR_R_UNSUPPORTED : ERR_R_FETCH_FAILED;
        const char *helpful_msg =
            unsupported
            ? ( "No store loader found. For standard store loaders you need "
                "at least one of the default or base providers available. "
                "Did you forget to load them? Info: " )
            : "";

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

    return method;
}

OSSL_STORE_LOADER *OSSL_STORE_LOADER_fetch(OSSL_LIB_CTX *libctx,
                                           const char *scheme,
                                           const char *properties)
{
    struct loader_data_st methdata;
    void *method;

    methdata.libctx = libctx;
    methdata.tmp_store = NULL;
    method = inner_loader_fetch(&methdata, 0, scheme, properties);
    dealloc_tmp_loader_store(methdata.tmp_store);
    return method;
}

OSSL_STORE_LOADER *ossl_store_loader_fetch_by_number(OSSL_LIB_CTX *libctx,
                                                     int scheme_id,
                                                     const char *properties)
{
    struct loader_data_st methdata;
    void *method;

    methdata.libctx = libctx;
    methdata.tmp_store = NULL;
    method = inner_loader_fetch(&methdata, scheme_id, NULL, properties);
    dealloc_tmp_loader_store(methdata.tmp_store);
    return method;
}

/*
 * Library of basic method functions
 */

const OSSL_PROVIDER *OSSL_STORE_LOADER_get0_provider(const OSSL_STORE_LOADER *loader)
{
    if (!ossl_assert(loader != NULL)) {
        ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }

    return loader->prov;
}

const char *OSSL_STORE_LOADER_get0_properties(const OSSL_STORE_LOADER *loader)
{
    if (!ossl_assert(loader != NULL)) {
        ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }

    return loader->propdef;
}

int ossl_store_loader_get_number(const OSSL_STORE_LOADER *loader)
{
    if (!ossl_assert(loader != NULL)) {
        ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }

    return loader->scheme_id;
}

const char *OSSL_STORE_LOADER_get0_description(const OSSL_STORE_LOADER *loader)
{
    return loader->description;
}

int OSSL_STORE_LOADER_is_a(const OSSL_STORE_LOADER *loader, const char *name)
{
    if (loader->prov != NULL) {
        OSSL_LIB_CTX *libctx = ossl_provider_libctx(loader->prov);
        OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);

        return ossl_namemap_name2num(namemap, name) == loader->scheme_id;
    }
    return 0;
}

struct do_one_data_st {
    void (*user_fn)(OSSL_STORE_LOADER *loader, 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_STORE_LOADER_do_all_provided(OSSL_LIB_CTX *libctx,
                                       void (*user_fn)(OSSL_STORE_LOADER *loader,
                                                       void *arg),
                                       void *user_arg)
{
    struct loader_data_st methdata;
    struct do_one_data_st data;

    methdata.libctx = libctx;
    methdata.tmp_store = NULL;
    (void)inner_loader_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_loader_store(libctx), &do_one, &data);
    dealloc_tmp_loader_store(methdata.tmp_store);
}

int OSSL_STORE_LOADER_names_do_all(const OSSL_STORE_LOADER *loader,
                                   void (*fn)(const char *name, void *data),
                                   void *data)
{
    if (loader == NULL)
        return 0;

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

        return ossl_namemap_doall_names(namemap, loader->scheme_id, fn, data);
    }

    return 1;
}
