/*
 * Copyright 2019-2022 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 <assert.h>
#include <openssl/crypto.h>
#include <openssl/core_dispatch.h>
#include <openssl/core_names.h>
#include <openssl/provider.h>
#include <openssl/evp.h>
#include "internal/provider.h"
#include "internal/cryptlib.h"
#include "crypto/evp.h"
#include "crypto/context.h"

DEFINE_STACK_OF(OSSL_PROVIDER)

struct child_prov_globals {
    const OSSL_CORE_HANDLE *handle;
    const OSSL_CORE_HANDLE *curr_prov;
    CRYPTO_RWLOCK *lock;
    OSSL_FUNC_core_get_libctx_fn *c_get_libctx;
    OSSL_FUNC_provider_register_child_cb_fn *c_provider_register_child_cb;
    OSSL_FUNC_provider_deregister_child_cb_fn *c_provider_deregister_child_cb;
    OSSL_FUNC_provider_name_fn *c_prov_name;
    OSSL_FUNC_provider_get0_provider_ctx_fn *c_prov_get0_provider_ctx;
    OSSL_FUNC_provider_get0_dispatch_fn *c_prov_get0_dispatch;
    OSSL_FUNC_provider_up_ref_fn *c_prov_up_ref;
    OSSL_FUNC_provider_free_fn *c_prov_free;
};

void *ossl_child_prov_ctx_new(OSSL_LIB_CTX *libctx)
{
    return OPENSSL_zalloc(sizeof(struct child_prov_globals));
}

void ossl_child_prov_ctx_free(void *vgbl)
{
    struct child_prov_globals *gbl = vgbl;

    CRYPTO_THREAD_lock_free(gbl->lock);
    OPENSSL_free(gbl);
}

static OSSL_provider_init_fn ossl_child_provider_init;

static int ossl_child_provider_init(const OSSL_CORE_HANDLE *handle,
                                    const OSSL_DISPATCH *in,
                                    const OSSL_DISPATCH **out,
                                    void **provctx)
{
    OSSL_FUNC_core_get_libctx_fn *c_get_libctx = NULL;
    OSSL_LIB_CTX *ctx;
    struct child_prov_globals *gbl;

    for (; in->function_id != 0; in++) {
        switch (in->function_id) {
        case OSSL_FUNC_CORE_GET_LIBCTX:
            c_get_libctx = OSSL_FUNC_core_get_libctx(in);
            break;
        default:
            /* Just ignore anything we don't understand */
            break;
        }
    }

    if (c_get_libctx == NULL)
        return 0;

    /*
     * We need an OSSL_LIB_CTX but c_get_libctx returns OPENSSL_CORE_CTX. We are
     * a built-in provider and so we can get away with this cast. Normal
     * providers can't do this.
     */
    ctx = (OSSL_LIB_CTX *)c_get_libctx(handle);

    gbl = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_CHILD_PROVIDER_INDEX);
    if (gbl == NULL)
        return 0;

    *provctx = gbl->c_prov_get0_provider_ctx(gbl->curr_prov);
    *out = gbl->c_prov_get0_dispatch(gbl->curr_prov);

    return 1;
}

static int provider_create_child_cb(const OSSL_CORE_HANDLE *prov, void *cbdata)
{
    OSSL_LIB_CTX *ctx = cbdata;
    struct child_prov_globals *gbl;
    const char *provname;
    OSSL_PROVIDER *cprov;
    int ret = 0;

    gbl = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_CHILD_PROVIDER_INDEX);
    if (gbl == NULL)
        return 0;

    if (!CRYPTO_THREAD_write_lock(gbl->lock))
        return 0;

    provname = gbl->c_prov_name(prov);

    /*
     * We're operating under a lock so we can store the "current" provider in
     * the global data.
     */
    gbl->curr_prov = prov;

    if ((cprov = ossl_provider_find(ctx, provname, 1)) != NULL) {
        /*
         * We free the newly created ref. We rely on the provider sticking around
         * in the provider store.
         */
        ossl_provider_free(cprov);

        /*
         * The provider already exists. It could be a previously created child,
         * or it could have been explicitly loaded. If explicitly loaded we
         * ignore it - i.e. we don't start treating it like a child.
         */
        if (!ossl_provider_activate(cprov, 0, 1))
            goto err;
    } else {
        /*
         * Create it - passing 1 as final param so we don't try and recursively
         * init children
         */
        if ((cprov = ossl_provider_new(ctx, provname, ossl_child_provider_init,
                                       1)) == NULL)
            goto err;

        if (!ossl_provider_activate(cprov, 0, 0))
            goto err;

        if (!ossl_provider_set_child(cprov, prov)
            || !ossl_provider_add_to_store(cprov, NULL, 0)) {
            ossl_provider_deactivate(cprov, 0);
            ossl_provider_free(cprov);
            goto err;
        }
    }

    ret = 1;
 err:
    CRYPTO_THREAD_unlock(gbl->lock);
    return ret;
}

static int provider_remove_child_cb(const OSSL_CORE_HANDLE *prov, void *cbdata)
{
    OSSL_LIB_CTX *ctx = cbdata;
    struct child_prov_globals *gbl;
    const char *provname;
    OSSL_PROVIDER *cprov;

    gbl = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_CHILD_PROVIDER_INDEX);
    if (gbl == NULL)
        return 0;

    provname = gbl->c_prov_name(prov);
    cprov = ossl_provider_find(ctx, provname, 1);
    if (cprov == NULL)
        return 0;
    /*
     * ossl_provider_find ups the ref count, so we free it again here. We can
     * rely on the provider store reference count.
     */
    ossl_provider_free(cprov);
    if (ossl_provider_is_child(cprov)
            && !ossl_provider_deactivate(cprov, 1))
        return 0;

    return 1;
}

static int provider_global_props_cb(const char *props, void *cbdata)
{
    OSSL_LIB_CTX *ctx = cbdata;

    return evp_set_default_properties_int(ctx, props, 0, 1);
}

int ossl_provider_init_as_child(OSSL_LIB_CTX *ctx,
                                const OSSL_CORE_HANDLE *handle,
                                const OSSL_DISPATCH *in)
{
    struct child_prov_globals *gbl;

    if (ctx == NULL)
        return 0;

    gbl = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_CHILD_PROVIDER_INDEX);
    if (gbl == NULL)
        return 0;

    gbl->handle = handle;
    for (; in->function_id != 0; in++) {
        switch (in->function_id) {
        case OSSL_FUNC_CORE_GET_LIBCTX:
            gbl->c_get_libctx = OSSL_FUNC_core_get_libctx(in);
            break;
        case OSSL_FUNC_PROVIDER_REGISTER_CHILD_CB:
            gbl->c_provider_register_child_cb
                = OSSL_FUNC_provider_register_child_cb(in);
            break;
        case OSSL_FUNC_PROVIDER_DEREGISTER_CHILD_CB:
            gbl->c_provider_deregister_child_cb
                = OSSL_FUNC_provider_deregister_child_cb(in);
            break;
        case OSSL_FUNC_PROVIDER_NAME:
            gbl->c_prov_name = OSSL_FUNC_provider_name(in);
            break;
        case OSSL_FUNC_PROVIDER_GET0_PROVIDER_CTX:
            gbl->c_prov_get0_provider_ctx
                = OSSL_FUNC_provider_get0_provider_ctx(in);
            break;
        case OSSL_FUNC_PROVIDER_GET0_DISPATCH:
            gbl->c_prov_get0_dispatch = OSSL_FUNC_provider_get0_dispatch(in);
            break;
        case OSSL_FUNC_PROVIDER_UP_REF:
            gbl->c_prov_up_ref
                = OSSL_FUNC_provider_up_ref(in);
            break;
        case OSSL_FUNC_PROVIDER_FREE:
            gbl->c_prov_free = OSSL_FUNC_provider_free(in);
            break;
        default:
            /* Just ignore anything we don't understand */
            break;
        }
    }

    if (gbl->c_get_libctx == NULL
            || gbl->c_provider_register_child_cb == NULL
            || gbl->c_prov_name == NULL
            || gbl->c_prov_get0_provider_ctx == NULL
            || gbl->c_prov_get0_dispatch == NULL
            || gbl->c_prov_up_ref == NULL
            || gbl->c_prov_free == NULL)
        return 0;

    gbl->lock = CRYPTO_THREAD_lock_new();
    if (gbl->lock == NULL)
        return 0;

    if (!gbl->c_provider_register_child_cb(gbl->handle,
                                           provider_create_child_cb,
                                           provider_remove_child_cb,
                                           provider_global_props_cb,
                                           ctx))
        return 0;

    return 1;
}

void ossl_provider_deinit_child(OSSL_LIB_CTX *ctx)
{
    struct child_prov_globals *gbl
        = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_CHILD_PROVIDER_INDEX);
    if (gbl == NULL)
        return;

    gbl->c_provider_deregister_child_cb(gbl->handle);
}

/*
 * ossl_provider_up_ref_parent() and ossl_provider_free_parent() do
 * nothing in "self-referencing" child providers, i.e. when the parent
 * of the child provider is the same as the provider where this child
 * provider was created.
 * This allows the teardown function in the parent provider to be called
 * at the correct moment.
 * For child providers in other providers, the reference count is done to
 * ensure that cross referencing is recorded.  These should be cleared up
 * through that providers teardown, as part of freeing its child libctx.
 */

int ossl_provider_up_ref_parent(OSSL_PROVIDER *prov, int activate)
{
    struct child_prov_globals *gbl;
    const OSSL_CORE_HANDLE *parent_handle;

    gbl = ossl_lib_ctx_get_data(ossl_provider_libctx(prov),
                                OSSL_LIB_CTX_CHILD_PROVIDER_INDEX);
    if (gbl == NULL)
        return 0;

    parent_handle = ossl_provider_get_parent(prov);
    if (parent_handle == gbl->handle)
        return 1;
    return gbl->c_prov_up_ref(parent_handle, activate);
}

int ossl_provider_free_parent(OSSL_PROVIDER *prov, int deactivate)
{
    struct child_prov_globals *gbl;
    const OSSL_CORE_HANDLE *parent_handle;

    gbl = ossl_lib_ctx_get_data(ossl_provider_libctx(prov),
                                OSSL_LIB_CTX_CHILD_PROVIDER_INDEX);
    if (gbl == NULL)
        return 0;

    parent_handle = ossl_provider_get_parent(prov);
    if (parent_handle == gbl->handle)
        return 1;
    return gbl->c_prov_free(ossl_provider_get_parent(prov), deactivate);
}
