/*
 * 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 <stddef.h>

#include <openssl/core.h>
#include "internal/cryptlib.h"
#include "internal/core.h"
#include "internal/property.h"
#include "internal/provider.h"

struct construct_data_st {
    OSSL_LIB_CTX *libctx;
    OSSL_METHOD_STORE *store;
    int operation_id;
    int force_store;
    OSSL_METHOD_CONSTRUCT_METHOD *mcm;
    void *mcm_data;
};

static int is_temporary_method_store(int no_store, void *cbdata)
{
    struct construct_data_st *data = cbdata;

    return no_store && !data->force_store;
}

static int ossl_method_construct_precondition(OSSL_PROVIDER *provider,
                                              int operation_id, int no_store,
                                              void *cbdata, int *result)
{
    if (!ossl_assert(result != NULL)) {
        ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }

    /* Assume that no bits are set */
    *result = 0;

    /* No flag bits for temporary stores */
    if (!is_temporary_method_store(no_store, cbdata)
        && !ossl_provider_test_operation_bit(provider, operation_id, result))
        return 0;

    /*
     * The result we get tells if methods have already been constructed.
     * However, we want to tell whether construction should happen (true)
     * or not (false), which is the opposite of what we got.
     */
    *result = !*result;

    return 1;
}

static int ossl_method_construct_postcondition(OSSL_PROVIDER *provider,
                                               int operation_id, int no_store,
                                               void *cbdata, int *result)
{
    if (!ossl_assert(result != NULL)) {
        ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }

    *result = 1;

    /* No flag bits for temporary stores */
    return is_temporary_method_store(no_store, cbdata)
        || ossl_provider_set_operation_bit(provider, operation_id);
}

static void ossl_method_construct_this(OSSL_PROVIDER *provider,
                                       const OSSL_ALGORITHM *algo,
                                       int no_store, void *cbdata)
{
    struct construct_data_st *data = cbdata;
    void *method = NULL;

    if ((method = data->mcm->construct(algo, provider, data->mcm_data))
        == NULL)
        return;

    /*
     * Note regarding putting the method in stores:
     *
     * we don't need to care if it actually got in or not here.
     * If it didn't get in, it will simply not be available when
     * ossl_method_construct() tries to get it from the store.
     *
     * It is *expected* that the put function increments the refcnt
     * of the passed method.
     */

    if (!is_temporary_method_store(no_store, data)) {
        /* If we haven't been told not to store, add to the global store */
        data->mcm->put(NULL, method, provider, algo->algorithm_names,
                       algo->property_definition, data->mcm_data);
    } else {
        /*
         * If we have been told not to store the method "permanently", we
         * ask for a temporary store, and store the method there.
         * The owner of |data->mcm| is completely responsible for managing
         * that temporary store.
         */
        if ((data->store = data->mcm->get_tmp_store(data->mcm_data)) == NULL)
            return;

        data->mcm->put(data->store, method, provider, algo->algorithm_names,
                       algo->property_definition, data->mcm_data);
    }

    /* refcnt-- because we're dropping the reference */
    data->mcm->destruct(method, data->mcm_data);
}

void *ossl_method_construct(OSSL_LIB_CTX *libctx, int operation_id,
                            OSSL_PROVIDER **provider_rw, int force_store,
                            OSSL_METHOD_CONSTRUCT_METHOD *mcm, void *mcm_data)
{
    void *method = NULL;
    OSSL_PROVIDER *provider = provider_rw != NULL ? *provider_rw : NULL;
    struct construct_data_st cbdata;

    /*
     * We might be tempted to try to look into the method store without
     * constructing to see if we can find our method there already.
     * Unfortunately that does not work well if the query contains
     * optional properties as newly loaded providers can match them better.
     * We trust that ossl_method_construct_precondition() and
     * ossl_method_construct_postcondition() make sure that the
     * ossl_algorithm_do_all() does very little when methods from
     * a provider have already been constructed.
     */

    cbdata.store = NULL;
    cbdata.force_store = force_store;
    cbdata.mcm = mcm;
    cbdata.mcm_data = mcm_data;
    ossl_algorithm_do_all(libctx, operation_id, provider,
                          ossl_method_construct_precondition,
                          ossl_method_construct_this,
                          ossl_method_construct_postcondition,
                          &cbdata);

    /* If there is a temporary store, try there first */
    if (cbdata.store != NULL)
        method = mcm->get(cbdata.store, (const OSSL_PROVIDER **)provider_rw,
                          mcm_data);

    /* If no method was found yet, try the global store */
    if (method == NULL)
        method = mcm->get(NULL, (const OSSL_PROVIDER **)provider_rw, mcm_data);

    return method;
}
