/*
 * Copyright 2016-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 <stdlib.h>
#include <string.h>
#include <assert.h>

/* We need to use some STORE deprecated APIs */
#define OPENSSL_SUPPRESS_DEPRECATED

#include "internal/e_os.h"

#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/trace.h>
#include <openssl/core_names.h>
#include <openssl/provider.h>
#include <openssl/param_build.h>
#include <openssl/store.h>
#include "internal/thread_once.h"
#include "internal/cryptlib.h"
#include "internal/provider.h"
#include "internal/bio.h"
#include "crypto/store.h"
#include "store_local.h"

static int ossl_store_close_it(OSSL_STORE_CTX *ctx);

static int loader_set_params(OSSL_STORE_LOADER *loader,
                             OSSL_STORE_LOADER_CTX *loader_ctx,
                             const OSSL_PARAM params[], const char *propq)
{
   if (params != NULL) {
       if (!loader->p_set_ctx_params(loader_ctx, params))
           return 0;
   }

   if (propq != NULL) {
       OSSL_PARAM propp[2];

       if (OSSL_PARAM_locate_const(params,
                                   OSSL_STORE_PARAM_PROPERTIES) != NULL)
           /* use the propq from params */
           return 1;

       propp[0] = OSSL_PARAM_construct_utf8_string(OSSL_STORE_PARAM_PROPERTIES,
                                                   (char *)propq, 0);
       propp[1] = OSSL_PARAM_construct_end();

       if (!loader->p_set_ctx_params(loader_ctx, propp))
           return 0;
    }
    return 1;
}

OSSL_STORE_CTX *
OSSL_STORE_open_ex(const char *uri, OSSL_LIB_CTX *libctx, const char *propq,
                   const UI_METHOD *ui_method, void *ui_data,
                   const OSSL_PARAM params[],
                   OSSL_STORE_post_process_info_fn post_process,
                   void *post_process_data)
{
    const OSSL_STORE_LOADER *loader = NULL;
    OSSL_STORE_LOADER *fetched_loader = NULL;
    OSSL_STORE_LOADER_CTX *loader_ctx = NULL;
    OSSL_STORE_CTX *ctx = NULL;
    char *propq_copy = NULL;
    int no_loader_found = 1;
    char scheme_copy[256], *p, *schemes[2], *scheme = NULL;
    size_t schemes_n = 0;
    size_t i;

    /*
     * Put the file scheme first.  If the uri does represent an existing file,
     * possible device name and all, then it should be loaded.  Only a failed
     * attempt at loading a local file should have us try something else.
     */
    schemes[schemes_n++] = "file";

    /*
     * Now, check if we have something that looks like a scheme, and add it
     * as a second scheme.  However, also check if there's an authority start
     * (://), because that will invalidate the previous file scheme.  Also,
     * check that this isn't actually the file scheme, as there's no point
     * going through that one twice!
     */
    OPENSSL_strlcpy(scheme_copy, uri, sizeof(scheme_copy));
    if ((p = strchr(scheme_copy, ':')) != NULL) {
        *p++ = '\0';
        if (OPENSSL_strcasecmp(scheme_copy, "file") != 0) {
            if (HAS_PREFIX(p, "//"))
                schemes_n--;         /* Invalidate the file scheme */
            schemes[schemes_n++] = scheme_copy;
        }
    }

    ERR_set_mark();

    /*
     * Try each scheme until we find one that could open the URI.
     *
     * For each scheme, we look for the engine implementation first, and
     * failing that, we then try to fetch a provided implementation.
     * This is consistent with how we handle legacy / engine implementations
     * elsewhere.
     */
    for (i = 0; loader_ctx == NULL && i < schemes_n; i++) {
        scheme = schemes[i];
        OSSL_TRACE1(STORE, "Looking up scheme %s\n", scheme);
#ifndef OPENSSL_NO_DEPRECATED_3_0
        ERR_set_mark();
        if ((loader = ossl_store_get0_loader_int(scheme)) != NULL) {
            ERR_clear_last_mark();
            no_loader_found = 0;
            if (loader->open_ex != NULL)
                loader_ctx = loader->open_ex(loader, uri, libctx, propq,
                                             ui_method, ui_data);
            else
                loader_ctx = loader->open(loader, uri, ui_method, ui_data);
        } else {
            ERR_pop_to_mark();
        }
#endif
        if (loader == NULL
            && (fetched_loader =
                OSSL_STORE_LOADER_fetch(libctx, scheme, propq)) != NULL) {
            const OSSL_PROVIDER *provider =
                OSSL_STORE_LOADER_get0_provider(fetched_loader);
            void *provctx = OSSL_PROVIDER_get0_provider_ctx(provider);

            no_loader_found = 0;
            loader_ctx = fetched_loader->p_open(provctx, uri);
            if (loader_ctx == NULL) {
                OSSL_STORE_LOADER_free(fetched_loader);
                fetched_loader = NULL;
            } else if (!loader_set_params(fetched_loader, loader_ctx,
                                          params, propq)) {
                (void)fetched_loader->p_close(loader_ctx);
                OSSL_STORE_LOADER_free(fetched_loader);
                fetched_loader = NULL;
            }
            loader = fetched_loader;
        }
    }

    if (no_loader_found)
        /*
         * It's assumed that ossl_store_get0_loader_int() and
         * OSSL_STORE_LOADER_fetch() report their own errors
         */
        goto err;

    OSSL_TRACE1(STORE, "Found loader for scheme %s\n", scheme);

    if (loader_ctx == NULL)
        /*
         * It's assumed that the loader's open() method reports its own
         * errors
         */
        goto err;

    OSSL_TRACE2(STORE, "Opened %s => %p\n", uri, (void *)loader_ctx);

    if ((propq != NULL && (propq_copy = OPENSSL_strdup(propq)) == NULL)
        || (ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) {
        ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    if (ui_method != NULL
        && (!ossl_pw_set_ui_method(&ctx->pwdata, ui_method, ui_data)
            || !ossl_pw_enable_passphrase_caching(&ctx->pwdata))) {
        ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_CRYPTO_LIB);
        goto err;
    }
    ctx->properties = propq_copy;
    ctx->fetched_loader = fetched_loader;
    ctx->loader = loader;
    ctx->loader_ctx = loader_ctx;
    ctx->post_process = post_process;
    ctx->post_process_data = post_process_data;

    /*
     * If the attempt to open with the 'file' scheme loader failed and the
     * other scheme loader succeeded, the failure to open with the 'file'
     * scheme loader leaves an error on the error stack.  Let's remove it.
     */
    ERR_pop_to_mark();

    return ctx;

 err:
    ERR_clear_last_mark();
    if (loader_ctx != NULL) {
        /*
         * Temporary structure so OSSL_STORE_close() can work even when
         * |ctx| couldn't be allocated properly
         */
        OSSL_STORE_CTX tmpctx = { NULL, };

        tmpctx.fetched_loader = fetched_loader;
        tmpctx.loader = loader;
        tmpctx.loader_ctx = loader_ctx;

        /*
         * We ignore a returned error because we will return NULL anyway in
         * this case, so if something goes wrong when closing, that'll simply
         * just add another entry on the error stack.
         */
        (void)ossl_store_close_it(&tmpctx);
    }
    /* Coverity false positive, the reference counting is confusing it */
    /* coverity[pass_freed_arg] */
    OSSL_STORE_LOADER_free(fetched_loader);
    OPENSSL_free(propq_copy);
    OPENSSL_free(ctx);
    return NULL;
}

OSSL_STORE_CTX *OSSL_STORE_open(const char *uri,
                                const UI_METHOD *ui_method, void *ui_data,
                                OSSL_STORE_post_process_info_fn post_process,
                                void *post_process_data)
{
    return OSSL_STORE_open_ex(uri, NULL, NULL, ui_method, ui_data, NULL,
                              post_process, post_process_data);
}

#ifndef OPENSSL_NO_DEPRECATED_3_0
int OSSL_STORE_ctrl(OSSL_STORE_CTX *ctx, int cmd, ...)
{
    va_list args;
    int ret;

    va_start(args, cmd);
    ret = OSSL_STORE_vctrl(ctx, cmd, args);
    va_end(args);

    return ret;
}

int OSSL_STORE_vctrl(OSSL_STORE_CTX *ctx, int cmd, va_list args)
{
    if (ctx->fetched_loader != NULL) {
        if (ctx->fetched_loader->p_set_ctx_params != NULL) {
            OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };

            switch (cmd) {
            case OSSL_STORE_C_USE_SECMEM:
                {
                    int on = *(va_arg(args, int *));

                    params[0] = OSSL_PARAM_construct_int("use_secmem", &on);
                }
                break;
            default:
                break;
            }

            return ctx->fetched_loader->p_set_ctx_params(ctx->loader_ctx,
                                                         params);
        }
    } else if (ctx->loader->ctrl != NULL) {
        return ctx->loader->ctrl(ctx->loader_ctx, cmd, args);
    }

    /*
     * If the fetched loader doesn't have a set_ctx_params or a ctrl, it's as
     * if there was one that ignored our params, which usually returns 1.
     */
    return 1;
}
#endif

int OSSL_STORE_expect(OSSL_STORE_CTX *ctx, int expected_type)
{
    int ret = 1;

    if (ctx == NULL
            || expected_type < 0 || expected_type > OSSL_STORE_INFO_CRL) {
        ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_PASSED_INVALID_ARGUMENT);
        return 0;
    }
    if (ctx->loading) {
        ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_LOADING_STARTED);
        return 0;
    }

    ctx->expected_type = expected_type;
    if (ctx->fetched_loader != NULL
        && ctx->fetched_loader->p_set_ctx_params != NULL) {
        OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };

        params[0] =
            OSSL_PARAM_construct_int(OSSL_STORE_PARAM_EXPECT, &expected_type);
        ret = ctx->fetched_loader->p_set_ctx_params(ctx->loader_ctx, params);
    }
#ifndef OPENSSL_NO_DEPRECATED_3_0
    if (ctx->fetched_loader == NULL
        && ctx->loader->expect != NULL) {
        ret = ctx->loader->expect(ctx->loader_ctx, expected_type);
    }
#endif
    return ret;
}

int OSSL_STORE_find(OSSL_STORE_CTX *ctx, const OSSL_STORE_SEARCH *search)
{
    int ret = 1;

    if (ctx->loading) {
        ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_LOADING_STARTED);
        return 0;
    }
    if (search == NULL) {
        ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }

    if (ctx->fetched_loader != NULL) {
        OSSL_PARAM_BLD *bld;
        OSSL_PARAM *params;
        /* OSSL_STORE_SEARCH_BY_NAME, OSSL_STORE_SEARCH_BY_ISSUER_SERIAL*/
        void *name_der = NULL;
        int name_der_sz;
        /* OSSL_STORE_SEARCH_BY_ISSUER_SERIAL */
        BIGNUM *number = NULL;

        if (ctx->fetched_loader->p_set_ctx_params == NULL) {
            ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_UNSUPPORTED_OPERATION);
            return 0;
        }

        if ((bld = OSSL_PARAM_BLD_new()) == NULL) {
            ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE);
            return 0;
        }

        ret = 0;                 /* Assume the worst */

        switch (search->search_type) {
        case OSSL_STORE_SEARCH_BY_NAME:
            if ((name_der_sz = i2d_X509_NAME(search->name,
                                             (unsigned char **)&name_der)) > 0
                && OSSL_PARAM_BLD_push_octet_string(bld,
                                                    OSSL_STORE_PARAM_SUBJECT,
                                                    name_der, name_der_sz))
                ret = 1;
            break;
        case OSSL_STORE_SEARCH_BY_ISSUER_SERIAL:
            if ((name_der_sz = i2d_X509_NAME(search->name,
                                             (unsigned char **)&name_der)) > 0
                && (number = ASN1_INTEGER_to_BN(search->serial, NULL)) != NULL
                && OSSL_PARAM_BLD_push_octet_string(bld,
                                                    OSSL_STORE_PARAM_ISSUER,
                                                    name_der, name_der_sz)
                && OSSL_PARAM_BLD_push_BN(bld, OSSL_STORE_PARAM_SERIAL,
                                          number))
                ret = 1;
            break;
        case OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT:
            if (OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_STORE_PARAM_DIGEST,
                                                EVP_MD_get0_name(search->digest),
                                                0)
                && OSSL_PARAM_BLD_push_octet_string(bld,
                                                    OSSL_STORE_PARAM_FINGERPRINT,
                                                    search->string,
                                                    search->stringlength))
                ret = 1;
            break;
        case OSSL_STORE_SEARCH_BY_ALIAS:
            if (OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_STORE_PARAM_ALIAS,
                                                (char *)search->string,
                                                search->stringlength))
                ret = 1;
            break;
        }
        if (ret) {
            params = OSSL_PARAM_BLD_to_param(bld);
            ret = ctx->fetched_loader->p_set_ctx_params(ctx->loader_ctx,
                                                        params);
            OSSL_PARAM_free(params);
        }
        OSSL_PARAM_BLD_free(bld);
        OPENSSL_free(name_der);
        BN_free(number);
    } else {
#ifndef OPENSSL_NO_DEPRECATED_3_0
        /* legacy loader section */
        if (ctx->loader->find == NULL) {
            ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_UNSUPPORTED_OPERATION);
            return 0;
        }
        ret = ctx->loader->find(ctx->loader_ctx, search);
#endif
    }

    return ret;
}

OSSL_STORE_INFO *OSSL_STORE_load(OSSL_STORE_CTX *ctx)
{
    OSSL_STORE_INFO *v = NULL;

    ctx->loading = 1;
 again:
    if (OSSL_STORE_eof(ctx))
        return NULL;

    if (ctx->loader != NULL)
        OSSL_TRACE(STORE, "Loading next object\n");

    if (ctx->cached_info != NULL
        && sk_OSSL_STORE_INFO_num(ctx->cached_info) == 0) {
        sk_OSSL_STORE_INFO_free(ctx->cached_info);
        ctx->cached_info = NULL;
    }

    if (ctx->cached_info != NULL) {
        v = sk_OSSL_STORE_INFO_shift(ctx->cached_info);
    } else {
        if (ctx->fetched_loader != NULL) {
            struct ossl_load_result_data_st load_data;

            load_data.v = NULL;
            load_data.ctx = ctx;

            if (!ctx->fetched_loader->p_load(ctx->loader_ctx,
                                             ossl_store_handle_load_result,
                                             &load_data,
                                             ossl_pw_passphrase_callback_dec,
                                             &ctx->pwdata)) {
                if (!OSSL_STORE_eof(ctx))
                    ctx->error_flag = 1;
                return NULL;
            }
            v = load_data.v;
        }
#ifndef OPENSSL_NO_DEPRECATED_3_0
        if (ctx->fetched_loader == NULL)
            v = ctx->loader->load(ctx->loader_ctx,
                                  ctx->pwdata._.ui_method.ui_method,
                                  ctx->pwdata._.ui_method.ui_method_data);
#endif
    }

    if (ctx->post_process != NULL && v != NULL) {
        v = ctx->post_process(v, ctx->post_process_data);

        /*
         * By returning NULL, the callback decides that this object should
         * be ignored.
         */
        if (v == NULL)
            goto again;
    }

    /* Clear any internally cached passphrase */
    (void)ossl_pw_clear_passphrase_cache(&ctx->pwdata);

    if (v != NULL && ctx->expected_type != 0) {
        int returned_type = OSSL_STORE_INFO_get_type(v);

        if (returned_type != OSSL_STORE_INFO_NAME && returned_type != 0) {
            if (ctx->expected_type != returned_type) {
                OSSL_STORE_INFO_free(v);
                goto again;
            }
        }
    }

    if (v != NULL)
        OSSL_TRACE1(STORE, "Got a %s\n",
                    OSSL_STORE_INFO_type_string(OSSL_STORE_INFO_get_type(v)));

    return v;
}

int OSSL_STORE_error(OSSL_STORE_CTX *ctx)
{
    int ret = 1;

    if (ctx->fetched_loader != NULL)
        ret = ctx->error_flag;
#ifndef OPENSSL_NO_DEPRECATED_3_0
    if (ctx->fetched_loader == NULL)
        ret = ctx->loader->error(ctx->loader_ctx);
#endif
    return ret;
}

int OSSL_STORE_eof(OSSL_STORE_CTX *ctx)
{
    int ret = 1;

    if (ctx->fetched_loader != NULL)
        ret = ctx->loader->p_eof(ctx->loader_ctx);
#ifndef OPENSSL_NO_DEPRECATED_3_0
    if (ctx->fetched_loader == NULL)
        ret = ctx->loader->eof(ctx->loader_ctx);
#endif
    return ret != 0;
}

static int ossl_store_close_it(OSSL_STORE_CTX *ctx)
{
    int ret = 0;

    if (ctx == NULL)
        return 1;
    OSSL_TRACE1(STORE, "Closing %p\n", (void *)ctx->loader_ctx);

    if (ctx->fetched_loader != NULL)
        ret = ctx->loader->p_close(ctx->loader_ctx);
#ifndef OPENSSL_NO_DEPRECATED_3_0
    if (ctx->fetched_loader == NULL)
        ret = ctx->loader->closefn(ctx->loader_ctx);
#endif

    sk_OSSL_STORE_INFO_pop_free(ctx->cached_info, OSSL_STORE_INFO_free);
    OSSL_STORE_LOADER_free(ctx->fetched_loader);
    OPENSSL_free(ctx->properties);
    ossl_pw_clear_passphrase_data(&ctx->pwdata);
    return ret;
}

int OSSL_STORE_close(OSSL_STORE_CTX *ctx)
{
    int ret = ossl_store_close_it(ctx);

    OPENSSL_free(ctx);
    return ret;
}

/*
 * Functions to generate OSSL_STORE_INFOs, one function for each type we
 * support having in them as well as a generic constructor.
 *
 * In all cases, ownership of the object is transferred to the OSSL_STORE_INFO
 * and will therefore be freed when the OSSL_STORE_INFO is freed.
 */
OSSL_STORE_INFO *OSSL_STORE_INFO_new(int type, void *data)
{
    OSSL_STORE_INFO *info = OPENSSL_zalloc(sizeof(*info));

    if (info == NULL)
        return NULL;

    info->type = type;
    info->_.data = data;
    return info;
}

OSSL_STORE_INFO *OSSL_STORE_INFO_new_NAME(char *name)
{
    OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_NAME, NULL);

    if (info == NULL) {
        ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE);
        return NULL;
    }

    info->_.name.name = name;
    info->_.name.desc = NULL;

    return info;
}

int OSSL_STORE_INFO_set0_NAME_description(OSSL_STORE_INFO *info, char *desc)
{
    if (info->type != OSSL_STORE_INFO_NAME) {
        ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_PASSED_INVALID_ARGUMENT);
        return 0;
    }

    info->_.name.desc = desc;

    return 1;
}
OSSL_STORE_INFO *OSSL_STORE_INFO_new_PARAMS(EVP_PKEY *params)
{
    OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_PARAMS, params);

    if (info == NULL)
        ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE);
    return info;
}

OSSL_STORE_INFO *OSSL_STORE_INFO_new_PUBKEY(EVP_PKEY *pkey)
{
    OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_PUBKEY, pkey);

    if (info == NULL)
        ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE);
    return info;
}

OSSL_STORE_INFO *OSSL_STORE_INFO_new_PKEY(EVP_PKEY *pkey)
{
    OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_PKEY, pkey);

    if (info == NULL)
        ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE);
    return info;
}

OSSL_STORE_INFO *OSSL_STORE_INFO_new_CERT(X509 *x509)
{
    OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_CERT, x509);

    if (info == NULL)
        ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE);
    return info;
}

OSSL_STORE_INFO *OSSL_STORE_INFO_new_CRL(X509_CRL *crl)
{
    OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_CRL, crl);

    if (info == NULL)
        ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE);
    return info;
}

/*
 * Functions to try to extract data from a OSSL_STORE_INFO.
 */
int OSSL_STORE_INFO_get_type(const OSSL_STORE_INFO *info)
{
    return info->type;
}

void *OSSL_STORE_INFO_get0_data(int type, const OSSL_STORE_INFO *info)
{
    if (info->type == type)
        return info->_.data;
    return NULL;
}

const char *OSSL_STORE_INFO_get0_NAME(const OSSL_STORE_INFO *info)
{
    if (info->type == OSSL_STORE_INFO_NAME)
        return info->_.name.name;
    return NULL;
}

char *OSSL_STORE_INFO_get1_NAME(const OSSL_STORE_INFO *info)
{
    if (info->type == OSSL_STORE_INFO_NAME) {
        char *ret = OPENSSL_strdup(info->_.name.name);

        if (ret == NULL)
            ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE);
        return ret;
    }
    ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_NAME);
    return NULL;
}

const char *OSSL_STORE_INFO_get0_NAME_description(const OSSL_STORE_INFO *info)
{
    if (info->type == OSSL_STORE_INFO_NAME)
        return info->_.name.desc;
    return NULL;
}

char *OSSL_STORE_INFO_get1_NAME_description(const OSSL_STORE_INFO *info)
{
    if (info->type == OSSL_STORE_INFO_NAME) {
        char *ret = OPENSSL_strdup(info->_.name.desc
                                   ? info->_.name.desc : "");

        if (ret == NULL)
            ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE);
        return ret;
    }
    ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_NAME);
    return NULL;
}

EVP_PKEY *OSSL_STORE_INFO_get0_PARAMS(const OSSL_STORE_INFO *info)
{
    if (info->type == OSSL_STORE_INFO_PARAMS)
        return info->_.params;
    return NULL;
}

EVP_PKEY *OSSL_STORE_INFO_get1_PARAMS(const OSSL_STORE_INFO *info)
{
    if (info->type == OSSL_STORE_INFO_PARAMS) {
        EVP_PKEY_up_ref(info->_.params);
        return info->_.params;
    }
    ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_PARAMETERS);
    return NULL;
}

EVP_PKEY *OSSL_STORE_INFO_get0_PUBKEY(const OSSL_STORE_INFO *info)
{
    if (info->type == OSSL_STORE_INFO_PUBKEY)
        return info->_.pubkey;
    return NULL;
}

EVP_PKEY *OSSL_STORE_INFO_get1_PUBKEY(const OSSL_STORE_INFO *info)
{
    if (info->type == OSSL_STORE_INFO_PUBKEY) {
        EVP_PKEY_up_ref(info->_.pubkey);
        return info->_.pubkey;
    }
    ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_PUBLIC_KEY);
    return NULL;
}

EVP_PKEY *OSSL_STORE_INFO_get0_PKEY(const OSSL_STORE_INFO *info)
{
    if (info->type == OSSL_STORE_INFO_PKEY)
        return info->_.pkey;
    return NULL;
}

EVP_PKEY *OSSL_STORE_INFO_get1_PKEY(const OSSL_STORE_INFO *info)
{
    if (info->type == OSSL_STORE_INFO_PKEY) {
        EVP_PKEY_up_ref(info->_.pkey);
        return info->_.pkey;
    }
    ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_PRIVATE_KEY);
    return NULL;
}

X509 *OSSL_STORE_INFO_get0_CERT(const OSSL_STORE_INFO *info)
{
    if (info->type == OSSL_STORE_INFO_CERT)
        return info->_.x509;
    return NULL;
}

X509 *OSSL_STORE_INFO_get1_CERT(const OSSL_STORE_INFO *info)
{
    if (info->type == OSSL_STORE_INFO_CERT) {
        X509_up_ref(info->_.x509);
        return info->_.x509;
    }
    ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_CERTIFICATE);
    return NULL;
}

X509_CRL *OSSL_STORE_INFO_get0_CRL(const OSSL_STORE_INFO *info)
{
    if (info->type == OSSL_STORE_INFO_CRL)
        return info->_.crl;
    return NULL;
}

X509_CRL *OSSL_STORE_INFO_get1_CRL(const OSSL_STORE_INFO *info)
{
    if (info->type == OSSL_STORE_INFO_CRL) {
        X509_CRL_up_ref(info->_.crl);
        return info->_.crl;
    }
    ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_CRL);
    return NULL;
}

/*
 * Free the OSSL_STORE_INFO
 */
void OSSL_STORE_INFO_free(OSSL_STORE_INFO *info)
{
    if (info != NULL) {
        switch (info->type) {
        case OSSL_STORE_INFO_NAME:
            OPENSSL_free(info->_.name.name);
            OPENSSL_free(info->_.name.desc);
            break;
        case OSSL_STORE_INFO_PARAMS:
            EVP_PKEY_free(info->_.params);
            break;
        case OSSL_STORE_INFO_PUBKEY:
            EVP_PKEY_free(info->_.pubkey);
            break;
        case OSSL_STORE_INFO_PKEY:
            EVP_PKEY_free(info->_.pkey);
            break;
        case OSSL_STORE_INFO_CERT:
            X509_free(info->_.x509);
            break;
        case OSSL_STORE_INFO_CRL:
            X509_CRL_free(info->_.crl);
            break;
        }
        OPENSSL_free(info);
    }
}

int OSSL_STORE_supports_search(OSSL_STORE_CTX *ctx, int search_type)
{
    int ret = 0;

    if (ctx->fetched_loader != NULL) {
        void *provctx =
            ossl_provider_ctx(OSSL_STORE_LOADER_get0_provider(ctx->fetched_loader));
        const OSSL_PARAM *params;
        const OSSL_PARAM *p_subject = NULL;
        const OSSL_PARAM *p_issuer = NULL;
        const OSSL_PARAM *p_serial = NULL;
        const OSSL_PARAM *p_fingerprint = NULL;
        const OSSL_PARAM *p_alias = NULL;

        if (ctx->fetched_loader->p_settable_ctx_params == NULL)
            return 0;

        params = ctx->fetched_loader->p_settable_ctx_params(provctx);
        p_subject = OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_SUBJECT);
        p_issuer = OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_ISSUER);
        p_serial = OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_SERIAL);
        p_fingerprint =
            OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_FINGERPRINT);
        p_alias = OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_ALIAS);

        switch (search_type) {
        case OSSL_STORE_SEARCH_BY_NAME:
            ret = (p_subject != NULL);
            break;
        case OSSL_STORE_SEARCH_BY_ISSUER_SERIAL:
            ret = (p_issuer != NULL && p_serial != NULL);
            break;
        case OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT:
            ret = (p_fingerprint != NULL);
            break;
        case OSSL_STORE_SEARCH_BY_ALIAS:
            ret = (p_alias != NULL);
            break;
        }
    }
#ifndef OPENSSL_NO_DEPRECATED_3_0
    if (ctx->fetched_loader == NULL) {
        OSSL_STORE_SEARCH tmp_search;

        if (ctx->loader->find == NULL)
            return 0;
        tmp_search.search_type = search_type;
        ret = ctx->loader->find(NULL, &tmp_search);
    }
#endif
    return ret;
}

/* Search term constructors */
OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_name(X509_NAME *name)
{
    OSSL_STORE_SEARCH *search = OPENSSL_zalloc(sizeof(*search));

    if (search == NULL) {
        ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE);
        return NULL;
    }

    search->search_type = OSSL_STORE_SEARCH_BY_NAME;
    search->name = name;
    return search;
}

OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_issuer_serial(X509_NAME *name,
                                                      const ASN1_INTEGER *serial)
{
    OSSL_STORE_SEARCH *search = OPENSSL_zalloc(sizeof(*search));

    if (search == NULL) {
        ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE);
        return NULL;
    }

    search->search_type = OSSL_STORE_SEARCH_BY_ISSUER_SERIAL;
    search->name = name;
    search->serial = serial;
    return search;
}

OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_key_fingerprint(const EVP_MD *digest,
                                                        const unsigned char
                                                        *bytes, size_t len)
{
    OSSL_STORE_SEARCH *search = OPENSSL_zalloc(sizeof(*search));

    if (search == NULL) {
        ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE);
        return NULL;
    }

    if (digest != NULL && len != (size_t)EVP_MD_get_size(digest)) {
        ERR_raise_data(ERR_LIB_OSSL_STORE,
                       OSSL_STORE_R_FINGERPRINT_SIZE_DOES_NOT_MATCH_DIGEST,
                       "%s size is %d, fingerprint size is %zu",
                       EVP_MD_get0_name(digest), EVP_MD_get_size(digest), len);
        OPENSSL_free(search);
        return NULL;
    }

    search->search_type = OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT;
    search->digest = digest;
    search->string = bytes;
    search->stringlength = len;
    return search;
}

OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_alias(const char *alias)
{
    OSSL_STORE_SEARCH *search = OPENSSL_zalloc(sizeof(*search));

    if (search == NULL) {
        ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE);
        return NULL;
    }

    search->search_type = OSSL_STORE_SEARCH_BY_ALIAS;
    search->string = (const unsigned char *)alias;
    search->stringlength = strlen(alias);
    return search;
}

/* Search term destructor */
void OSSL_STORE_SEARCH_free(OSSL_STORE_SEARCH *search)
{
    OPENSSL_free(search);
}

/* Search term accessors */
int OSSL_STORE_SEARCH_get_type(const OSSL_STORE_SEARCH *criterion)
{
    return criterion->search_type;
}

X509_NAME *OSSL_STORE_SEARCH_get0_name(const OSSL_STORE_SEARCH *criterion)
{
    return criterion->name;
}

const ASN1_INTEGER *OSSL_STORE_SEARCH_get0_serial(const OSSL_STORE_SEARCH
                                                  *criterion)
{
    return criterion->serial;
}

const unsigned char *OSSL_STORE_SEARCH_get0_bytes(const OSSL_STORE_SEARCH
                                                  *criterion, size_t *length)
{
    *length = criterion->stringlength;
    return criterion->string;
}

const char *OSSL_STORE_SEARCH_get0_string(const OSSL_STORE_SEARCH *criterion)
{
    return (const char *)criterion->string;
}

const EVP_MD *OSSL_STORE_SEARCH_get0_digest(const OSSL_STORE_SEARCH *criterion)
{
    return criterion->digest;
}

OSSL_STORE_CTX *OSSL_STORE_attach(BIO *bp, const char *scheme,
                                  OSSL_LIB_CTX *libctx, const char *propq,
                                  const UI_METHOD *ui_method, void *ui_data,
                                  const OSSL_PARAM params[],
                                  OSSL_STORE_post_process_info_fn post_process,
                                  void *post_process_data)
{
    const OSSL_STORE_LOADER *loader = NULL;
    OSSL_STORE_LOADER *fetched_loader = NULL;
    OSSL_STORE_LOADER_CTX *loader_ctx = NULL;
    OSSL_STORE_CTX *ctx = NULL;

    if (scheme == NULL)
        scheme = "file";

    OSSL_TRACE1(STORE, "Looking up scheme %s\n", scheme);
    ERR_set_mark();
#ifndef OPENSSL_NO_DEPRECATED_3_0
    if ((loader = ossl_store_get0_loader_int(scheme)) != NULL)
        loader_ctx = loader->attach(loader, bp, libctx, propq,
                                    ui_method, ui_data);
#endif
    if (loader == NULL
        && (fetched_loader =
            OSSL_STORE_LOADER_fetch(libctx, scheme, propq)) != NULL) {
        const OSSL_PROVIDER *provider =
            OSSL_STORE_LOADER_get0_provider(fetched_loader);
        void *provctx = OSSL_PROVIDER_get0_provider_ctx(provider);
        OSSL_CORE_BIO *cbio = ossl_core_bio_new_from_bio(bp);

        if (cbio == NULL
            || (loader_ctx = fetched_loader->p_attach(provctx, cbio)) == NULL) {
            OSSL_STORE_LOADER_free(fetched_loader);
            fetched_loader = NULL;
        } else if (!loader_set_params(fetched_loader, loader_ctx,
                                      params, propq)) {
            (void)fetched_loader->p_close(loader_ctx);
            OSSL_STORE_LOADER_free(fetched_loader);
            fetched_loader = NULL;
        }
        loader = fetched_loader;
        ossl_core_bio_free(cbio);
    }

    if (loader_ctx == NULL) {
        ERR_clear_last_mark();
        return NULL;
    }

    if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) {
        ERR_clear_last_mark();
        ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE);
        return NULL;
    }

    if (ui_method != NULL
        && !ossl_pw_set_ui_method(&ctx->pwdata, ui_method, ui_data)) {
        ERR_clear_last_mark();
        OPENSSL_free(ctx);
        return NULL;
    }

    ctx->fetched_loader = fetched_loader;
    ctx->loader = loader;
    ctx->loader_ctx = loader_ctx;
    ctx->post_process = post_process;
    ctx->post_process_data = post_process_data;

    /*
     * ossl_store_get0_loader_int will raise an error if the loader for the
     * the scheme cannot be retrieved. But if a loader was successfully
     * fetched then we remove this error from the error stack.
     */
    ERR_pop_to_mark();

    return ctx;
}
