/*
 * Copyright 2016-2020 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
 */

/* THIS ENGINE IS FOR TESTING PURPOSES ONLY. */

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

/* #include "e_os.h" */
#include <string.h>
#include <sys/stat.h>
#include <ctype.h>
#include <assert.h>

#include <openssl/bio.h>
#include <openssl/dsa.h>         /* For d2i_DSAPrivateKey */
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/pkcs12.h>      /* For the PKCS8 stuff o.O */
#include <openssl/rsa.h>         /* For d2i_RSAPrivateKey */
#include <openssl/safestack.h>
#include <openssl/store.h>
#include <openssl/ui.h>
#include <openssl/engine.h>
#include <openssl/x509.h>        /* For the PKCS8 stuff o.O */
#include "internal/asn1.h"       /* For asn1_d2i_read_bio */
#include "internal/o_dir.h"
#include "internal/cryptlib.h"
#include "crypto/pem.h"          /* For PVK and "blob" PEM headers */

#include "e_loader_attic_err.c"

DEFINE_STACK_OF(OSSL_STORE_INFO)

#ifdef _WIN32
# define stat _stat
# define strncasecmp _strnicmp
#endif

#ifndef S_ISDIR
# define S_ISDIR(a) (((a) & S_IFMT) == S_IFDIR)
#endif

/*-
 *  Password prompting
 *  ------------------
 */

static char *file_get_pass(const UI_METHOD *ui_method, char *pass,
                           size_t maxsize, const char *desc, const char *info,
                           void *data)
{
    UI *ui = UI_new();
    char *prompt = NULL;

    if (ui == NULL) {
        ATTICerr(0, ERR_R_MALLOC_FAILURE);
        return NULL;
    }

    if (ui_method != NULL)
        UI_set_method(ui, ui_method);
    UI_add_user_data(ui, data);

    if ((prompt = UI_construct_prompt(ui, desc, info)) == NULL) {
        ATTICerr(0, ERR_R_MALLOC_FAILURE);
        pass = NULL;
    } else if (!UI_add_input_string(ui, prompt, UI_INPUT_FLAG_DEFAULT_PWD,
                                    pass, 0, maxsize - 1)) {
        ATTICerr(0, ERR_R_UI_LIB);
        pass = NULL;
    } else {
        switch (UI_process(ui)) {
        case -2:
            ATTICerr(0, ATTIC_R_UI_PROCESS_INTERRUPTED_OR_CANCELLED);
            pass = NULL;
            break;
        case -1:
            ATTICerr(0, ERR_R_UI_LIB);
            pass = NULL;
            break;
        default:
            break;
        }
    }

    OPENSSL_free(prompt);
    UI_free(ui);
    return pass;
}

struct pem_pass_data {
    const UI_METHOD *ui_method;
    void *data;
    const char *prompt_desc;
    const char *prompt_info;
};

static int file_fill_pem_pass_data(struct pem_pass_data *pass_data,
                                   const char *desc, const char *info,
                                   const UI_METHOD *ui_method, void *ui_data)
{
    if (pass_data == NULL)
        return 0;
    pass_data->ui_method = ui_method;
    pass_data->data = ui_data;
    pass_data->prompt_desc = desc;
    pass_data->prompt_info = info;
    return 1;
}

/* This is used anywhere a pem_password_cb is needed */
static int file_get_pem_pass(char *buf, int num, int w, void *data)
{
    struct pem_pass_data *pass_data = data;
    char *pass = file_get_pass(pass_data->ui_method, buf, num,
                               pass_data->prompt_desc, pass_data->prompt_info,
                               pass_data->data);

    return pass == NULL ? 0 : strlen(pass);
}

/*
 * Check if |str| ends with |suffix| preceded by a space, and if it does,
 * return the index of that space.  If there is no such suffix in |str|,
 * return -1.
 * For |str| == "FOO BAR" and |suffix| == "BAR", the returned value is 3.
 */
static int check_suffix(const char *str, const char *suffix)
{
    int str_len = strlen(str);
    int suffix_len = strlen(suffix) + 1;
    const char *p = NULL;

    if (suffix_len >= str_len)
        return -1;
    p = str + str_len - suffix_len;
    if (*p != ' '
        || strcmp(p + 1, suffix) != 0)
        return -1;
    return p - str;
}

/*
 * EMBEDDED is a special type of OSSL_STORE_INFO, specially for the file
 * handlers, so we define it internally.  This uses the possibility to
 * create an OSSL_STORE_INFO with a generic data pointer and arbitrary
 * type number.
 *
 * This is used by a FILE_HANDLER's try_decode function to signal that it
 * has decoded the incoming blob into a new blob, and that the attempted
 * decoding should be immediately restarted with the new blob, using the
 * new PEM name.
 */
/* Negative numbers are never used for public OSSL_STORE_INFO types */
#define STORE_INFO_EMBEDDED       -1

/* This is the embedded data */
struct embedded_st {
    BUF_MEM *blob;
    char *pem_name;
};

/* Helper functions */
static struct embedded_st *get0_EMBEDDED(OSSL_STORE_INFO *info)
{
    return OSSL_STORE_INFO_get0_data(STORE_INFO_EMBEDDED, info);
}

static void store_info_free(OSSL_STORE_INFO *info)
{
    struct embedded_st *data;

    if (info != NULL && (data = get0_EMBEDDED(info)) != NULL) {
        BUF_MEM_free(data->blob);
        OPENSSL_free(data->pem_name);
        OPENSSL_free(data);
    }
    OSSL_STORE_INFO_free(info);
}

static OSSL_STORE_INFO *new_EMBEDDED(const char *new_pem_name,
                                     BUF_MEM *embedded)
{
    OSSL_STORE_INFO *info = NULL;
    struct embedded_st *data = NULL;

    if ((data = OPENSSL_zalloc(sizeof(*data))) == NULL
        || (info = OSSL_STORE_INFO_new(STORE_INFO_EMBEDDED, data)) == NULL) {
        ATTICerr(0, ERR_R_MALLOC_FAILURE);
        OPENSSL_free(data);
        return NULL;
    }

    data->pem_name =
        new_pem_name == NULL ? NULL : OPENSSL_strdup(new_pem_name);

    if (new_pem_name != NULL && data->pem_name == NULL) {
        ATTICerr(0, ERR_R_MALLOC_FAILURE);
        store_info_free(info);
        info = NULL;
    }
    data->blob = embedded;

    return info;
}

/*-
 *  The file scheme decoders
 *  ------------------------
 *
 *  Each possible data type has its own decoder, which either operates
 *  through a given PEM name, or attempts to decode to see if the blob
 *  it's given is decodable for its data type.  The assumption is that
 *  only the correct data type will match the content.
 */

/*-
 * The try_decode function is called to check if the blob of data can
 * be used by this handler, and if it can, decodes it into a supported
 * OpenSSL type and returns a OSSL_STORE_INFO with the decoded data.
 * Input:
 *    pem_name:     If this blob comes from a PEM file, this holds
 *                  the PEM name.  If it comes from another type of
 *                  file, this is NULL.
 *    pem_header:   If this blob comes from a PEM file, this holds
 *                  the PEM headers.  If it comes from another type of
 *                  file, this is NULL.
 *    blob:         The blob of data to match with what this handler
 *                  can use.
 *    len:          The length of the blob.
 *    handler_ctx:  For a handler marked repeatable, this pointer can
 *                  be used to create a context for the handler.  IT IS
 *                  THE HANDLER'S RESPONSIBILITY TO CREATE AND DESTROY
 *                  THIS CONTEXT APPROPRIATELY, i.e. create on first call
 *                  and destroy when about to return NULL.
 *    matchcount:   A pointer to an int to count matches for this data.
 *                  Usually becomes 0 (no match) or 1 (match!), but may
 *                  be higher in the (unlikely) event that the data matches
 *                  more than one possibility.  The int will always be
 *                  zero when the function is called.
 *    ui_method:    Application UI method for getting a password, pin
 *                  or any other interactive data.
 *    ui_data:      Application data to be passed to ui_method when
 *                  it's called.
 *    libctx:       The library context to be used if applicable
 *    propq:        The property query string for any algorithm fetches
 * Output:
 *    a OSSL_STORE_INFO
 */
typedef OSSL_STORE_INFO *(*file_try_decode_fn)(const char *pem_name,
                                               const char *pem_header,
                                               const unsigned char *blob,
                                               size_t len, void **handler_ctx,
                                               int *matchcount,
                                               const UI_METHOD *ui_method,
                                               void *ui_data, const char *uri,
                                               OSSL_LIB_CTX *libctx,
                                               const char *propq);
/*
 * The eof function should return 1 if there's no more data to be found
 * with the handler_ctx, otherwise 0.  This is only used when the handler is
 * marked repeatable.
 */
typedef int (*file_eof_fn)(void *handler_ctx);
/*
 * The destroy_ctx function is used to destroy the handler_ctx that was
 * initiated by a repeatable try_decode function.  This is only used when
 * the handler is marked repeatable.
 */
typedef void (*file_destroy_ctx_fn)(void **handler_ctx);

typedef struct file_handler_st {
    const char *name;
    file_try_decode_fn try_decode;
    file_eof_fn eof;
    file_destroy_ctx_fn destroy_ctx;

    /* flags */
    int repeatable;
} FILE_HANDLER;

/*
 * PKCS#12 decoder.  It operates by decoding all of the blob content,
 * extracting all the interesting data from it and storing them internally,
 * then serving them one piece at a time.
 */
static OSSL_STORE_INFO *try_decode_PKCS12(const char *pem_name,
                                          const char *pem_header,
                                          const unsigned char *blob,
                                          size_t len, void **pctx,
                                          int *matchcount,
                                          const UI_METHOD *ui_method,
                                          void *ui_data, const char *uri,
                                          OSSL_LIB_CTX *libctx,
                                          const char *propq)
{
    OSSL_STORE_INFO *store_info = NULL;
    STACK_OF(OSSL_STORE_INFO) *ctx = *pctx;

    if (ctx == NULL) {
        /* Initial parsing */
        PKCS12 *p12;

        if (pem_name != NULL)
            /* No match, there is no PEM PKCS12 tag */
            return NULL;

        if ((p12 = d2i_PKCS12(NULL, &blob, len)) != NULL) {
            char *pass = NULL;
            char tpass[PEM_BUFSIZE];
            EVP_PKEY *pkey = NULL;
            X509 *cert = NULL;
            STACK_OF(X509) *chain = NULL;

            *matchcount = 1;

            if (!PKCS12_mac_present(p12)
                || PKCS12_verify_mac(p12, "", 0)
                || PKCS12_verify_mac(p12, NULL, 0)) {
                pass = "";
            } else {
                if ((pass = file_get_pass(ui_method, tpass, PEM_BUFSIZE,
                                          "PKCS12 import", uri,
                                          ui_data)) == NULL) {
                    ATTICerr(0, ATTIC_R_PASSPHRASE_CALLBACK_ERROR);
                    goto p12_end;
                }
                if (!PKCS12_verify_mac(p12, pass, strlen(pass))) {
                    ATTICerr(0, ATTIC_R_ERROR_VERIFYING_PKCS12_MAC);
                    goto p12_end;
                }
            }

            if (PKCS12_parse(p12, pass, &pkey, &cert, &chain)) {
                OSSL_STORE_INFO *osi_pkey = NULL;
                OSSL_STORE_INFO *osi_cert = NULL;
                OSSL_STORE_INFO *osi_ca = NULL;
                int ok = 1;

                if ((ctx = sk_OSSL_STORE_INFO_new_null()) != NULL) {
                    if (pkey != NULL) {
                        if ((osi_pkey = OSSL_STORE_INFO_new_PKEY(pkey)) != NULL
                            /* clearing pkey here avoids case distinctions */
                            && (pkey = NULL) == NULL
                            && sk_OSSL_STORE_INFO_push(ctx, osi_pkey) != 0)
                            osi_pkey = NULL;
                        else
                            ok = 0;
                    }
                    if (ok && cert != NULL) {
                        if ((osi_cert = OSSL_STORE_INFO_new_CERT(cert)) != NULL
                            /* clearing cert here avoids case distinctions */
                            && (cert = NULL) == NULL
                            && sk_OSSL_STORE_INFO_push(ctx, osi_cert) != 0)
                            osi_cert = NULL;
                        else
                            ok = 0;
                    }
                    while (ok && sk_X509_num(chain) > 0) {
                        X509 *ca = sk_X509_value(chain, 0);

                        if ((osi_ca = OSSL_STORE_INFO_new_CERT(ca)) != NULL
                            && sk_X509_shift(chain) != NULL
                            && sk_OSSL_STORE_INFO_push(ctx, osi_ca) != 0)
                            osi_ca = NULL;
                        else
                            ok = 0;
                    }
                }
                EVP_PKEY_free(pkey);
                X509_free(cert);
                sk_X509_pop_free(chain, X509_free);
                store_info_free(osi_pkey);
                store_info_free(osi_cert);
                store_info_free(osi_ca);
                if (!ok) {
                    sk_OSSL_STORE_INFO_pop_free(ctx, store_info_free);
                    ctx = NULL;
                }
                *pctx = ctx;
            }
        }
     p12_end:
        PKCS12_free(p12);
        if (ctx == NULL)
            return NULL;
    }

    *matchcount = 1;
    store_info = sk_OSSL_STORE_INFO_shift(ctx);
    return store_info;
}

static int eof_PKCS12(void *ctx_)
{
    STACK_OF(OSSL_STORE_INFO) *ctx = ctx_;

    return ctx == NULL || sk_OSSL_STORE_INFO_num(ctx) == 0;
}

static void destroy_ctx_PKCS12(void **pctx)
{
    STACK_OF(OSSL_STORE_INFO) *ctx = *pctx;

    sk_OSSL_STORE_INFO_pop_free(ctx, store_info_free);
    *pctx = NULL;
}

static FILE_HANDLER PKCS12_handler = {
    "PKCS12",
    try_decode_PKCS12,
    eof_PKCS12,
    destroy_ctx_PKCS12,
    1 /* repeatable */
};

/*
 * Encrypted PKCS#8 decoder.  It operates by just decrypting the given blob
 * into a new blob, which is returned as an EMBEDDED STORE_INFO.  The whole
 * decoding process will then start over with the new blob.
 */
static OSSL_STORE_INFO *try_decode_PKCS8Encrypted(const char *pem_name,
                                                  const char *pem_header,
                                                  const unsigned char *blob,
                                                  size_t len, void **pctx,
                                                  int *matchcount,
                                                  const UI_METHOD *ui_method,
                                                  void *ui_data,
                                                  const char *uri,
                                                  OSSL_LIB_CTX *libctx,
                                                  const char *propq)
{
    X509_SIG *p8 = NULL;
    char kbuf[PEM_BUFSIZE];
    char *pass = NULL;
    const X509_ALGOR *dalg = NULL;
    const ASN1_OCTET_STRING *doct = NULL;
    OSSL_STORE_INFO *store_info = NULL;
    BUF_MEM *mem = NULL;
    unsigned char *new_data = NULL;
    int new_data_len;

    if (pem_name != NULL) {
        if (strcmp(pem_name, PEM_STRING_PKCS8) != 0)
            return NULL;
        *matchcount = 1;
    }

    if ((p8 = d2i_X509_SIG(NULL, &blob, len)) == NULL)
        return NULL;

    *matchcount = 1;

    if ((mem = BUF_MEM_new()) == NULL) {
        ATTICerr(0, ERR_R_MALLOC_FAILURE);
        goto nop8;
    }

    if ((pass = file_get_pass(ui_method, kbuf, PEM_BUFSIZE,
                              "PKCS8 decrypt pass phrase", uri,
                              ui_data)) == NULL) {
        ATTICerr(0, ATTIC_R_BAD_PASSWORD_READ);
        goto nop8;
    }

    X509_SIG_get0(p8, &dalg, &doct);
    if (!PKCS12_pbe_crypt(dalg, pass, strlen(pass), doct->data, doct->length,
                          &new_data, &new_data_len, 0))
        goto nop8;

    mem->data = (char *)new_data;
    mem->max = mem->length = (size_t)new_data_len;
    X509_SIG_free(p8);

    store_info = new_EMBEDDED(PEM_STRING_PKCS8INF, mem);
    if (store_info == NULL) {
        ATTICerr(0, ERR_R_MALLOC_FAILURE);
        goto nop8;
    }

    return store_info;
 nop8:
    X509_SIG_free(p8);
    BUF_MEM_free(mem);
    return NULL;
}

static FILE_HANDLER PKCS8Encrypted_handler = {
    "PKCS8Encrypted",
    try_decode_PKCS8Encrypted
};

/*
 * Private key decoder.  Decodes all sorts of private keys, both PKCS#8
 * encoded ones and old style PEM ones (with the key type is encoded into
 * the PEM name).
 */
static OSSL_STORE_INFO *try_decode_PrivateKey(const char *pem_name,
                                              const char *pem_header,
                                              const unsigned char *blob,
                                              size_t len, void **pctx,
                                              int *matchcount,
                                              const UI_METHOD *ui_method,
                                              void *ui_data, const char *uri,
                                              OSSL_LIB_CTX *libctx,
                                              const char *propq)
{
    OSSL_STORE_INFO *store_info = NULL;
    EVP_PKEY *pkey = NULL;
    const EVP_PKEY_ASN1_METHOD *ameth = NULL;

    if (pem_name != NULL) {
        if (strcmp(pem_name, PEM_STRING_PKCS8INF) == 0) {
            PKCS8_PRIV_KEY_INFO *p8inf =
                d2i_PKCS8_PRIV_KEY_INFO(NULL, &blob, len);

            *matchcount = 1;
            if (p8inf != NULL)
                pkey = EVP_PKCS82PKEY_ex(p8inf, libctx, propq);
            PKCS8_PRIV_KEY_INFO_free(p8inf);
        } else {
            int slen;
            int pkey_id;

            if ((slen = check_suffix(pem_name, "PRIVATE KEY")) > 0
                && (ameth = EVP_PKEY_asn1_find_str(NULL, pem_name,
                                                   slen)) != NULL
                && EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL,
                                           ameth)) {
                *matchcount = 1;
                pkey = d2i_PrivateKey_ex(pkey_id, NULL, &blob, len,
                                         libctx, propq);
            }
        }
    } else {
        int i;
#ifndef OPENSSL_NO_ENGINE
        ENGINE *curengine = ENGINE_get_first();

        while (curengine != NULL) {
            ENGINE_PKEY_ASN1_METHS_PTR asn1meths =
                ENGINE_get_pkey_asn1_meths(curengine);

            if (asn1meths != NULL) {
                const int *nids = NULL;
                int nids_n = asn1meths(curengine, NULL, &nids, 0);

                for (i = 0; i < nids_n; i++) {
                    EVP_PKEY_ASN1_METHOD *ameth2 = NULL;
                    EVP_PKEY *tmp_pkey = NULL;
                    const unsigned char *tmp_blob = blob;
                    int pkey_id, pkey_flags;

                    if (!asn1meths(curengine, &ameth2, NULL, nids[i])
                        || !EVP_PKEY_asn1_get0_info(&pkey_id, NULL,
                                                    &pkey_flags, NULL, NULL,
                                                    ameth2)
                        || (pkey_flags & ASN1_PKEY_ALIAS) != 0)
                        continue;

                    ERR_set_mark(); /* prevent flooding error queue */
                    tmp_pkey = d2i_PrivateKey_ex(pkey_id, NULL,
                                                 &tmp_blob, len,
                                                 libctx, propq);
                    if (tmp_pkey != NULL) {
                        if (pkey != NULL)
                            EVP_PKEY_free(tmp_pkey);
                        else
                            pkey = tmp_pkey;
                        (*matchcount)++;
                    }
                    ERR_pop_to_mark();
                }
            }
            curengine = ENGINE_get_next(curengine);
        }
#endif

        for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) {
            EVP_PKEY *tmp_pkey = NULL;
            const unsigned char *tmp_blob = blob;
            int pkey_id, pkey_flags;

            ameth = EVP_PKEY_asn1_get0(i);
            if (!EVP_PKEY_asn1_get0_info(&pkey_id, NULL, &pkey_flags, NULL,
                                         NULL, ameth)
                || (pkey_flags & ASN1_PKEY_ALIAS) != 0)
                continue;

            ERR_set_mark(); /* prevent flooding error queue */
            tmp_pkey = d2i_PrivateKey_ex(pkey_id, NULL, &tmp_blob, len,
                                         libctx, propq);
            if (tmp_pkey != NULL) {
                if (pkey != NULL)
                    EVP_PKEY_free(tmp_pkey);
                else
                    pkey = tmp_pkey;
                (*matchcount)++;
            }
            ERR_pop_to_mark();
        }

        if (*matchcount > 1) {
            EVP_PKEY_free(pkey);
            pkey = NULL;
        }
    }
    if (pkey == NULL)
        /* No match */
        return NULL;

    store_info = OSSL_STORE_INFO_new_PKEY(pkey);
    if (store_info == NULL)
        EVP_PKEY_free(pkey);

    return store_info;
}

static FILE_HANDLER PrivateKey_handler = {
    "PrivateKey",
    try_decode_PrivateKey
};

/*
 * Public key decoder.  Only supports SubjectPublicKeyInfo formatted keys.
 */
static OSSL_STORE_INFO *try_decode_PUBKEY(const char *pem_name,
                                          const char *pem_header,
                                          const unsigned char *blob,
                                          size_t len, void **pctx,
                                          int *matchcount,
                                          const UI_METHOD *ui_method,
                                          void *ui_data, const char *uri,
                                          OSSL_LIB_CTX *libctx,
                                          const char *propq)
{
    OSSL_STORE_INFO *store_info = NULL;
    EVP_PKEY *pkey = NULL;

    if (pem_name != NULL) {
        if (strcmp(pem_name, PEM_STRING_PUBLIC) != 0)
            /* No match */
            return NULL;
        *matchcount = 1;
    }

    if ((pkey = d2i_PUBKEY(NULL, &blob, len)) != NULL) {
        *matchcount = 1;
        store_info = OSSL_STORE_INFO_new_PUBKEY(pkey);
    }

    return store_info;
}

static FILE_HANDLER PUBKEY_handler = {
    "PUBKEY",
    try_decode_PUBKEY
};

/*
 * Key parameter decoder.
 */
static OSSL_STORE_INFO *try_decode_params(const char *pem_name,
                                          const char *pem_header,
                                          const unsigned char *blob,
                                          size_t len, void **pctx,
                                          int *matchcount,
                                          const UI_METHOD *ui_method,
                                          void *ui_data, const char *uri,
                                          OSSL_LIB_CTX *libctx,
                                          const char *propq)
{
    OSSL_STORE_INFO *store_info = NULL;
    EVP_PKEY *pkey = NULL;
    const EVP_PKEY_ASN1_METHOD *ameth = NULL;

    if (pem_name != NULL) {
        int slen;
        int pkey_id;

        if ((slen = check_suffix(pem_name, "PARAMETERS")) > 0
            && (ameth = EVP_PKEY_asn1_find_str(NULL, pem_name, slen)) != NULL
            && EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL,
                                       ameth)) {
            *matchcount = 1;
            pkey = d2i_KeyParams(pkey_id, NULL, &blob, len);
        }
    } else {
        int i;

        for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) {
            EVP_PKEY *tmp_pkey = NULL;
            const unsigned char *tmp_blob = blob;
            int pkey_id, pkey_flags;

            ameth = EVP_PKEY_asn1_get0(i);
            if (!EVP_PKEY_asn1_get0_info(&pkey_id, NULL, &pkey_flags, NULL,
                                         NULL, ameth)
                || (pkey_flags & ASN1_PKEY_ALIAS) != 0)
                continue;

            ERR_set_mark(); /* prevent flooding error queue */

            tmp_pkey = d2i_KeyParams(pkey_id, NULL, &tmp_blob, len);

            if (tmp_pkey != NULL) {
                if (pkey != NULL)
                    EVP_PKEY_free(tmp_pkey);
                else
                    pkey = tmp_pkey;
                (*matchcount)++;
            }
            ERR_pop_to_mark();
        }

        if (*matchcount > 1) {
            EVP_PKEY_free(pkey);
            pkey = NULL;
        }
    }
    if (pkey == NULL)
        /* No match */
        return NULL;

    store_info = OSSL_STORE_INFO_new_PARAMS(pkey);
    if (store_info == NULL)
        EVP_PKEY_free(pkey);

    return store_info;
}

static FILE_HANDLER params_handler = {
    "params",
    try_decode_params
};

/*
 * X.509 certificate decoder.
 */
static OSSL_STORE_INFO *try_decode_X509Certificate(const char *pem_name,
                                                   const char *pem_header,
                                                   const unsigned char *blob,
                                                   size_t len, void **pctx,
                                                   int *matchcount,
                                                   const UI_METHOD *ui_method,
                                                   void *ui_data,
                                                   const char *uri,
                                                   OSSL_LIB_CTX *libctx,
                                                   const char *propq)
{
    OSSL_STORE_INFO *store_info = NULL;
    X509 *cert = NULL;

    /*
     * In most cases, we can try to interpret the serialized data as a trusted
     * cert (X509 + X509_AUX) and fall back to reading it as a normal cert
     * (just X509), but if the PEM name specifically declares it as a trusted
     * cert, then no fallback should be engaged.  |ignore_trusted| tells if
     * the fallback can be used (1) or not (0).
     */
    int ignore_trusted = 1;

    if (pem_name != NULL) {
        if (strcmp(pem_name, PEM_STRING_X509_TRUSTED) == 0)
            ignore_trusted = 0;
        else if (strcmp(pem_name, PEM_STRING_X509_OLD) != 0
                 && strcmp(pem_name, PEM_STRING_X509) != 0)
            /* No match */
            return NULL;
        *matchcount = 1;
    }

    cert = X509_new_ex(libctx, propq);
    if (cert == NULL)
        return NULL;

    if ((d2i_X509_AUX(&cert, &blob, len)) != NULL
        || (ignore_trusted && (d2i_X509(&cert, &blob, len)) != NULL)) {
        *matchcount = 1;
        store_info = OSSL_STORE_INFO_new_CERT(cert);
    }

    if (store_info == NULL)
        X509_free(cert);

    return store_info;
}

static FILE_HANDLER X509Certificate_handler = {
    "X509Certificate",
    try_decode_X509Certificate
};

/*
 * X.509 CRL decoder.
 */
static OSSL_STORE_INFO *try_decode_X509CRL(const char *pem_name,
                                           const char *pem_header,
                                           const unsigned char *blob,
                                           size_t len, void **pctx,
                                           int *matchcount,
                                           const UI_METHOD *ui_method,
                                           void *ui_data, const char *uri,
                                           OSSL_LIB_CTX *libctx,
                                           const char *propq)
{
    OSSL_STORE_INFO *store_info = NULL;
    X509_CRL *crl = NULL;

    if (pem_name != NULL) {
        if (strcmp(pem_name, PEM_STRING_X509_CRL) != 0)
            /* No match */
            return NULL;
        *matchcount = 1;
    }

    if ((crl = d2i_X509_CRL(NULL, &blob, len)) != NULL) {
        *matchcount = 1;
        store_info = OSSL_STORE_INFO_new_CRL(crl);
    }

    if (store_info == NULL)
        X509_CRL_free(crl);

    return store_info;
}

static FILE_HANDLER X509CRL_handler = {
    "X509CRL",
    try_decode_X509CRL
};

/*
 * To finish it all off, we collect all the handlers.
 */
static const FILE_HANDLER *file_handlers[] = {
    &PKCS12_handler,
    &PKCS8Encrypted_handler,
    &X509Certificate_handler,
    &X509CRL_handler,
    &params_handler,
    &PUBKEY_handler,
    &PrivateKey_handler,
};


/*-
 *  The loader itself
 *  -----------------
 */

struct ossl_store_loader_ctx_st {
    char *uri;                   /* The URI we currently try to load */
    enum {
        is_raw = 0,
        is_pem,
        is_dir
    } type;
    int errcnt;
#define FILE_FLAG_SECMEM         (1<<0)
#define FILE_FLAG_ATTACHED       (1<<1)
    unsigned int flags;
    union {
        struct { /* Used with is_raw and is_pem */
            BIO *file;

            /*
             * The following are used when the handler is marked as
             * repeatable
             */
            const FILE_HANDLER *last_handler;
            void *last_handler_ctx;
        } file;
        struct { /* Used with is_dir */
            OPENSSL_DIR_CTX *ctx;
            int end_reached;

            /*
             * When a search expression is given, these are filled in.
             * |search_name| contains the file basename to look for.
             * The string is exactly 8 characters long.
             */
            char search_name[9];

            /*
             * The directory reading utility we have combines opening with
             * reading the first name.  To make sure we can detect the end
             * at the right time, we read early and cache the name.
             */
            const char *last_entry;
            int last_errno;
        } dir;
    } _;

    /* Expected object type.  May be unspecified */
    int expected_type;

    OSSL_LIB_CTX *libctx;
    char *propq;
};

static void OSSL_STORE_LOADER_CTX_free(OSSL_STORE_LOADER_CTX *ctx)
{
    if (ctx == NULL)
        return;

    OPENSSL_free(ctx->propq);
    OPENSSL_free(ctx->uri);
    if (ctx->type != is_dir) {
        if (ctx->_.file.last_handler != NULL) {
            ctx->_.file.last_handler->destroy_ctx(&ctx->_.file.last_handler_ctx);
            ctx->_.file.last_handler_ctx = NULL;
            ctx->_.file.last_handler = NULL;
        }
    }
    OPENSSL_free(ctx);
}

static int file_find_type(OSSL_STORE_LOADER_CTX *ctx)
{
    BIO *buff = NULL;
    char peekbuf[4096] = { 0, };

    if ((buff = BIO_new(BIO_f_buffer())) == NULL)
        return 0;

    ctx->_.file.file = BIO_push(buff, ctx->_.file.file);
    if (BIO_buffer_peek(ctx->_.file.file, peekbuf, sizeof(peekbuf) - 1) > 0) {
        peekbuf[sizeof(peekbuf) - 1] = '\0';
        if (strstr(peekbuf, "-----BEGIN ") != NULL)
            ctx->type = is_pem;
    }
    return 1;
}

static OSSL_STORE_LOADER_CTX *file_open_ex
    (const OSSL_STORE_LOADER *loader, const char *uri,
     OSSL_LIB_CTX *libctx, const char *propq,
     const UI_METHOD *ui_method, void *ui_data)
{
    OSSL_STORE_LOADER_CTX *ctx = NULL;
    struct stat st;
    struct {
        const char *path;
        unsigned int check_absolute:1;
    } path_data[2];
    size_t path_data_n = 0, i;
    const char *path;

    /*
     * First step, just take the URI as is.
     */
    path_data[path_data_n].check_absolute = 0;
    path_data[path_data_n++].path = uri;

    /*
     * Second step, if the URI appears to start with the 'file' scheme,
     * extract the path and make that the second path to check.
     * There's a special case if the URI also contains an authority, then
     * the full URI shouldn't be used as a path anywhere.
     */
    if (strncasecmp(uri, "file:", 5) == 0) {
        const char *p = &uri[5];

        if (strncmp(&uri[5], "//", 2) == 0) {
            path_data_n--;           /* Invalidate using the full URI */
            if (strncasecmp(&uri[7], "localhost/", 10) == 0) {
                p = &uri[16];
            } else if (uri[7] == '/') {
                p = &uri[7];
            } else {
                ATTICerr(0, ATTIC_R_URI_AUTHORITY_UNSUPPORTED);
                return NULL;
            }
        }

        path_data[path_data_n].check_absolute = 1;
#ifdef _WIN32
        /* Windows file: URIs with a drive letter start with a / */
        if (p[0] == '/' && p[2] == ':' && p[3] == '/') {
            char c = tolower(p[1]);

            if (c >= 'a' && c <= 'z') {
                p++;
                /* We know it's absolute, so no need to check */
                path_data[path_data_n].check_absolute = 0;
            }
        }
#endif
        path_data[path_data_n++].path = p;
    }


    for (i = 0, path = NULL; path == NULL && i < path_data_n; i++) {
        /*
         * If the scheme "file" was an explicit part of the URI, the path must
         * be absolute.  So says RFC 8089
         */
        if (path_data[i].check_absolute && path_data[i].path[0] != '/') {
            ATTICerr(0, ATTIC_R_PATH_MUST_BE_ABSOLUTE);
            ERR_add_error_data(1, path_data[i].path);
            return NULL;
        }

        if (stat(path_data[i].path, &st) < 0) {
            ERR_raise_data(ERR_LIB_SYS, errno,
                           "calling stat(%s)",
                           path_data[i].path);
        } else {
            path = path_data[i].path;
        }
    }
    if (path == NULL) {
        return NULL;
    }

    /* Successfully found a working path */

    ctx = OPENSSL_zalloc(sizeof(*ctx));
    if (ctx == NULL) {
        ATTICerr(0, ERR_R_MALLOC_FAILURE);
        return NULL;
    }
    ctx->uri = OPENSSL_strdup(uri);
    if (ctx->uri == NULL) {
        ATTICerr(0, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    if (S_ISDIR(st.st_mode)) {
        ctx->type = is_dir;
        ctx->_.dir.last_entry = OPENSSL_DIR_read(&ctx->_.dir.ctx, path);
        ctx->_.dir.last_errno = errno;
        if (ctx->_.dir.last_entry == NULL) {
            if (ctx->_.dir.last_errno != 0) {
                ERR_raise(ERR_LIB_SYS, ctx->_.dir.last_errno);
                goto err;
            }
            ctx->_.dir.end_reached = 1;
        }
    } else if ((ctx->_.file.file = BIO_new_file(path, "rb")) == NULL
               || !file_find_type(ctx)) {
        BIO_free_all(ctx->_.file.file);
        goto err;
    }
    if (propq != NULL) {
        ctx->propq = OPENSSL_strdup(propq);
        if (ctx->propq == NULL) {
            ATTICerr(0, ERR_R_MALLOC_FAILURE);
            goto err;
        }
    }
    ctx->libctx = libctx;

    return ctx;
 err:
    OSSL_STORE_LOADER_CTX_free(ctx);
    return NULL;
}

static OSSL_STORE_LOADER_CTX *file_open
    (const OSSL_STORE_LOADER *loader, const char *uri,
     const UI_METHOD *ui_method, void *ui_data)
{
    return file_open_ex(loader, uri, NULL, NULL, ui_method, ui_data);
}

static OSSL_STORE_LOADER_CTX *file_attach
    (const OSSL_STORE_LOADER *loader, BIO *bp,
     OSSL_LIB_CTX *libctx, const char *propq,
     const UI_METHOD *ui_method, void *ui_data)
{
    OSSL_STORE_LOADER_CTX *ctx = NULL;

    if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL
        || (propq != NULL && (ctx->propq = OPENSSL_strdup(propq)) == NULL)) {
        ATTICerr(0, ERR_R_MALLOC_FAILURE);
        OSSL_STORE_LOADER_CTX_free(ctx);
        return NULL;
    }
    ctx->libctx = libctx;
    ctx->flags |= FILE_FLAG_ATTACHED;
    ctx->_.file.file = bp;
    if (!file_find_type(ctx)) {
        /* Safety measure */
        ctx->_.file.file = NULL;
        goto err;
    }
    return ctx;
err:
    OSSL_STORE_LOADER_CTX_free(ctx);
    return NULL;
}

static int file_ctrl(OSSL_STORE_LOADER_CTX *ctx, int cmd, va_list args)
{
    int ret = 1;

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

            switch (on) {
            case 0:
                ctx->flags &= ~FILE_FLAG_SECMEM;
                break;
            case 1:
                ctx->flags |= FILE_FLAG_SECMEM;
                break;
            default:
                ATTICerr(0, ERR_R_PASSED_INVALID_ARGUMENT);
                ret = 0;
                break;
            }
        }
        break;
    default:
        break;
    }

    return ret;
}

static int file_expect(OSSL_STORE_LOADER_CTX *ctx, int expected)
{
    ctx->expected_type = expected;
    return 1;
}

static int file_find(OSSL_STORE_LOADER_CTX *ctx,
                     const OSSL_STORE_SEARCH *search)
{
    /*
     * If ctx == NULL, the library is looking to know if this loader supports
     * the given search type.
     */

    if (OSSL_STORE_SEARCH_get_type(search) == OSSL_STORE_SEARCH_BY_NAME) {
        unsigned long hash = 0;

        if (ctx == NULL)
            return 1;

        if (ctx->type != is_dir) {
            ATTICerr(0, ATTIC_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES);
            return 0;
        }

        hash = X509_NAME_hash(OSSL_STORE_SEARCH_get0_name(search));
        BIO_snprintf(ctx->_.dir.search_name, sizeof(ctx->_.dir.search_name),
                     "%08lx", hash);
        return 1;
    }

    if (ctx != NULL)
        ATTICerr(0, ATTIC_R_UNSUPPORTED_SEARCH_TYPE);
    return 0;
}

static OSSL_STORE_INFO *file_load_try_decode(OSSL_STORE_LOADER_CTX *ctx,
                                             const char *pem_name,
                                             const char *pem_header,
                                             unsigned char *data, size_t len,
                                             const UI_METHOD *ui_method,
                                             void *ui_data, int *matchcount)
{
    OSSL_STORE_INFO *result = NULL;
    BUF_MEM *new_mem = NULL;
    char *new_pem_name = NULL;
    int t = 0;

 again:
    {
        size_t i = 0;
        void *handler_ctx = NULL;
        const FILE_HANDLER **matching_handlers =
            OPENSSL_zalloc(sizeof(*matching_handlers)
                           * OSSL_NELEM(file_handlers));

        if (matching_handlers == NULL) {
            ATTICerr(0, ERR_R_MALLOC_FAILURE);
            goto err;
        }

        *matchcount = 0;
        for (i = 0; i < OSSL_NELEM(file_handlers); i++) {
            const FILE_HANDLER *handler = file_handlers[i];
            int try_matchcount = 0;
            void *tmp_handler_ctx = NULL;
            OSSL_STORE_INFO *tmp_result;
            unsigned long err;

            ERR_set_mark();
            tmp_result =
                handler->try_decode(pem_name, pem_header, data, len,
                                    &tmp_handler_ctx, &try_matchcount,
                                    ui_method, ui_data, ctx->uri,
                                    ctx->libctx, ctx->propq);
            /* avoid flooding error queue with low-level ASN.1 parse errors */
            err = ERR_peek_last_error();
            if (ERR_GET_LIB(err) == ERR_LIB_ASN1
                    && ERR_GET_REASON(err) == ERR_R_NESTED_ASN1_ERROR)
                ERR_pop_to_mark();
            else
                ERR_clear_last_mark();

            if (try_matchcount > 0) {

                matching_handlers[*matchcount] = handler;

                if (handler_ctx)
                    handler->destroy_ctx(&handler_ctx);
                handler_ctx = tmp_handler_ctx;

                if ((*matchcount += try_matchcount) > 1) {
                    /* more than one match => ambiguous, kill any result */
                    store_info_free(result);
                    store_info_free(tmp_result);
                    if (handler->destroy_ctx != NULL)
                        handler->destroy_ctx(&handler_ctx);
                    handler_ctx = NULL;
                    tmp_result = NULL;
                    result = NULL;
                }
                if (result == NULL)
                    result = tmp_result;
                if (result == NULL) /* e.g., PKCS#12 file decryption error */
                    break;
            }
        }

        if (result != NULL
                && *matchcount == 1 && matching_handlers[0]->repeatable) {
            ctx->_.file.last_handler = matching_handlers[0];
            ctx->_.file.last_handler_ctx = handler_ctx;
        }

        OPENSSL_free(matching_handlers);
    }

 err:
    OPENSSL_free(new_pem_name);
    BUF_MEM_free(new_mem);

    if (result != NULL
        && (t = OSSL_STORE_INFO_get_type(result)) == STORE_INFO_EMBEDDED) {
        struct embedded_st *embedded = get0_EMBEDDED(result);

        /* "steal" the embedded data */
        pem_name = new_pem_name = embedded->pem_name;
        new_mem = embedded->blob;
        data = (unsigned char *)new_mem->data;
        len = new_mem->length;
        embedded->pem_name = NULL;
        embedded->blob = NULL;

        store_info_free(result);
        result = NULL;
        goto again;
    }

    return result;
}

static OSSL_STORE_INFO *file_load_try_repeat(OSSL_STORE_LOADER_CTX *ctx,
                                             const UI_METHOD *ui_method,
                                             void *ui_data)
{
    OSSL_STORE_INFO *result = NULL;
    int try_matchcount = 0;

    if (ctx->_.file.last_handler != NULL) {
        result =
            ctx->_.file.last_handler->try_decode(NULL, NULL, NULL, 0,
                                                 &ctx->_.file.last_handler_ctx,
                                                 &try_matchcount,
                                                 ui_method, ui_data, ctx->uri,
                                                 ctx->libctx, ctx->propq);

        if (result == NULL) {
            ctx->_.file.last_handler->destroy_ctx(&ctx->_.file.last_handler_ctx);
            ctx->_.file.last_handler_ctx = NULL;
            ctx->_.file.last_handler = NULL;
        }
    }
    return result;
}

static void pem_free_flag(void *pem_data, int secure, size_t num)
{
    if (secure)
        OPENSSL_secure_clear_free(pem_data, num);
    else
        OPENSSL_free(pem_data);
}
static int file_read_pem(BIO *bp, char **pem_name, char **pem_header,
                         unsigned char **data, long *len,
                         const UI_METHOD *ui_method, void *ui_data,
                         const char *uri, int secure)
{
    int i = secure
        ? PEM_read_bio_ex(bp, pem_name, pem_header, data, len,
                          PEM_FLAG_SECURE | PEM_FLAG_EAY_COMPATIBLE)
        : PEM_read_bio(bp, pem_name, pem_header, data, len);

    if (i <= 0)
        return 0;

    /*
     * 10 is the number of characters in "Proc-Type:", which
     * PEM_get_EVP_CIPHER_INFO() requires to be present.
     * If the PEM header has less characters than that, it's
     * not worth spending cycles on it.
     */
    if (strlen(*pem_header) > 10) {
        EVP_CIPHER_INFO cipher;
        struct pem_pass_data pass_data;

        if (!PEM_get_EVP_CIPHER_INFO(*pem_header, &cipher)
            || !file_fill_pem_pass_data(&pass_data, "PEM pass phrase", uri,
                                        ui_method, ui_data)
            || !PEM_do_header(&cipher, *data, len, file_get_pem_pass,
                              &pass_data)) {
            return 0;
        }
    }
    return 1;
}

static OSSL_STORE_INFO *file_try_read_msblob(BIO *bp, int *matchcount)
{
#ifdef OPENSSL_NO_DSA
    return NULL;
#else
    OSSL_STORE_INFO *result = NULL;
    int ispub = -1;

    {
        unsigned int magic = 0, bitlen = 0;
        int isdss = 0;
        unsigned char peekbuf[16] = { 0, };
        const unsigned char *p = peekbuf;

        if (BIO_buffer_peek(bp, peekbuf, sizeof(peekbuf)) <= 0)
            return 0;
        if (!ossl_do_blob_header(&p, sizeof(peekbuf), &magic, &bitlen,
                                 &isdss, &ispub))
            return 0;
    }

    (*matchcount)++;

    {
        EVP_PKEY *tmp = ispub
            ? b2i_PublicKey_bio(bp)
            : b2i_PrivateKey_bio(bp);

        if (tmp == NULL
            || (result = OSSL_STORE_INFO_new_PKEY(tmp)) == NULL) {
            EVP_PKEY_free(tmp);
            return 0;
        }
    }

    return result;
#endif
}

static OSSL_STORE_INFO *file_try_read_PVK(BIO *bp, const UI_METHOD *ui_method,
                                          void *ui_data, const char *uri,
                                          int *matchcount)
{
#if defined(OPENSSL_NO_DSA) || defined(OPENSSL_NO_RC4)
    return NULL;
#else
    OSSL_STORE_INFO *result = NULL;

    {
        unsigned int saltlen = 0, keylen = 0;
        unsigned char peekbuf[24] = { 0, };
        const unsigned char *p = peekbuf;

        if (BIO_buffer_peek(bp, peekbuf, sizeof(peekbuf)) <= 0)
            return 0;
        if (!ossl_do_PVK_header(&p, sizeof(peekbuf), 0, &saltlen, &keylen))
            return 0;
    }

    (*matchcount)++;

    {
        EVP_PKEY *tmp = NULL;
        struct pem_pass_data pass_data;

        if (!file_fill_pem_pass_data(&pass_data, "PVK pass phrase", uri,
                                     ui_method, ui_data)
            || (tmp = b2i_PVK_bio(bp, file_get_pem_pass, &pass_data)) == NULL
            || (result = OSSL_STORE_INFO_new_PKEY(tmp)) == NULL) {
            EVP_PKEY_free(tmp);
            return 0;
        }
    }

    return result;
#endif
}

static int file_read_asn1(BIO *bp, unsigned char **data, long *len)
{
    BUF_MEM *mem = NULL;

    if (asn1_d2i_read_bio(bp, &mem) < 0)
        return 0;

    *data = (unsigned char *)mem->data;
    *len = (long)mem->length;
    OPENSSL_free(mem);

    return 1;
}

static int file_name_to_uri(OSSL_STORE_LOADER_CTX *ctx, const char *name,
                            char **data)
{
    assert(name != NULL);
    assert(data != NULL);
    {
        const char *pathsep = ossl_ends_with_dirsep(ctx->uri) ? "" : "/";
        long calculated_length = strlen(ctx->uri) + strlen(pathsep)
            + strlen(name) + 1 /* \0 */;

        *data = OPENSSL_zalloc(calculated_length);
        if (*data == NULL) {
            ATTICerr(0, ERR_R_MALLOC_FAILURE);
            return 0;
        }

        OPENSSL_strlcat(*data, ctx->uri, calculated_length);
        OPENSSL_strlcat(*data, pathsep, calculated_length);
        OPENSSL_strlcat(*data, name, calculated_length);
    }
    return 1;
}

static int file_name_check(OSSL_STORE_LOADER_CTX *ctx, const char *name)
{
    const char *p = NULL;

    /* If there are no search criteria, all names are accepted */
    if (ctx->_.dir.search_name[0] == '\0')
        return 1;

    /* If the expected type isn't supported, no name is accepted */
    if (ctx->expected_type != 0
        && ctx->expected_type != OSSL_STORE_INFO_CERT
        && ctx->expected_type != OSSL_STORE_INFO_CRL)
        return 0;

    /*
     * First, check the basename
     */
    if (strncasecmp(name, ctx->_.dir.search_name,
                    sizeof(ctx->_.dir.search_name) - 1) != 0
        || name[sizeof(ctx->_.dir.search_name) - 1] != '.')
        return 0;
    p = &name[sizeof(ctx->_.dir.search_name)];

    /*
     * Then, if the expected type is a CRL, check that the extension starts
     * with 'r'
     */
    if (*p == 'r') {
        p++;
        if (ctx->expected_type != 0
            && ctx->expected_type != OSSL_STORE_INFO_CRL)
            return 0;
    } else if (ctx->expected_type == OSSL_STORE_INFO_CRL) {
        return 0;
    }

    /*
     * Last, check that the rest of the extension is a decimal number, at
     * least one digit long.
     */
    if (!isdigit(*p))
        return 0;
    while (isdigit(*p))
        p++;

#ifdef __VMS
    /*
     * One extra step here, check for a possible generation number.
     */
    if (*p == ';')
        for (p++; *p != '\0'; p++)
            if (!ossl_isdigit(*p))
                break;
#endif

    /*
     * If we've reached the end of the string at this point, we've successfully
     * found a fitting file name.
     */
    return *p == '\0';
}

static int file_eof(OSSL_STORE_LOADER_CTX *ctx);
static int file_error(OSSL_STORE_LOADER_CTX *ctx);
static OSSL_STORE_INFO *file_load(OSSL_STORE_LOADER_CTX *ctx,
                                  const UI_METHOD *ui_method,
                                  void *ui_data)
{
    OSSL_STORE_INFO *result = NULL;

    ctx->errcnt = 0;

    if (ctx->type == is_dir) {
        do {
            char *newname = NULL;

            if (ctx->_.dir.last_entry == NULL) {
                if (!ctx->_.dir.end_reached) {
                    assert(ctx->_.dir.last_errno != 0);
                    ERR_raise(ERR_LIB_SYS, ctx->_.dir.last_errno);
                    ctx->errcnt++;
                }
                return NULL;
            }

            if (ctx->_.dir.last_entry[0] != '.'
                && file_name_check(ctx, ctx->_.dir.last_entry)
                && !file_name_to_uri(ctx, ctx->_.dir.last_entry, &newname))
                return NULL;

            /*
             * On the first call (with a NULL context), OPENSSL_DIR_read()
             * cares about the second argument.  On the following calls, it
             * only cares that it isn't NULL.  Therefore, we can safely give
             * it our URI here.
             */
            ctx->_.dir.last_entry = OPENSSL_DIR_read(&ctx->_.dir.ctx, ctx->uri);
            ctx->_.dir.last_errno = errno;
            if (ctx->_.dir.last_entry == NULL && ctx->_.dir.last_errno == 0)
                ctx->_.dir.end_reached = 1;

            if (newname != NULL
                && (result = OSSL_STORE_INFO_new_NAME(newname)) == NULL) {
                OPENSSL_free(newname);
                ATTICerr(0, ERR_R_OSSL_STORE_LIB);
                return NULL;
            }
        } while (result == NULL && !file_eof(ctx));
    } else {
        int matchcount = -1;

     again:
        result = file_load_try_repeat(ctx, ui_method, ui_data);
        if (result != NULL)
            return result;

        if (file_eof(ctx))
            return NULL;

        do {
            char *pem_name = NULL;      /* PEM record name */
            char *pem_header = NULL;    /* PEM record header */
            unsigned char *data = NULL; /* DER encoded data */
            long len = 0;               /* DER encoded data length */

            matchcount = -1;
            if (ctx->type == is_pem) {
                if (!file_read_pem(ctx->_.file.file, &pem_name, &pem_header,
                                   &data, &len, ui_method, ui_data, ctx->uri,
                                   (ctx->flags & FILE_FLAG_SECMEM) != 0)) {
                    ctx->errcnt++;
                    goto endloop;
                }
            } else {
                if ((result = file_try_read_msblob(ctx->_.file.file,
                                                   &matchcount)) != NULL
                    || (result = file_try_read_PVK(ctx->_.file.file,
                                                   ui_method, ui_data, ctx->uri,
                                                   &matchcount)) != NULL)
                    goto endloop;

                if (!file_read_asn1(ctx->_.file.file, &data, &len)) {
                    ctx->errcnt++;
                    goto endloop;
                }
            }

            result = file_load_try_decode(ctx, pem_name, pem_header, data, len,
                                          ui_method, ui_data, &matchcount);

            if (result != NULL)
                goto endloop;

            /*
             * If a PEM name matches more than one handler, the handlers are
             * badly coded.
             */
            if (!ossl_assert(pem_name == NULL || matchcount <= 1)) {
                ctx->errcnt++;
                goto endloop;
            }

            if (matchcount > 1) {
                ATTICerr(0, ATTIC_R_AMBIGUOUS_CONTENT_TYPE);
            } else if (matchcount == 1) {
                /*
                 * If there are other errors on the stack, they already show
                 * what the problem is.
                 */
                if (ERR_peek_error() == 0) {
                    ATTICerr(0, ATTIC_R_UNSUPPORTED_CONTENT_TYPE);
                    if (pem_name != NULL)
                        ERR_add_error_data(3, "PEM type is '", pem_name, "'");
                }
            }
            if (matchcount > 0)
                ctx->errcnt++;

         endloop:
            pem_free_flag(pem_name, (ctx->flags & FILE_FLAG_SECMEM) != 0, 0);
            pem_free_flag(pem_header, (ctx->flags & FILE_FLAG_SECMEM) != 0, 0);
            pem_free_flag(data, (ctx->flags & FILE_FLAG_SECMEM) != 0, len);
        } while (matchcount == 0 && !file_eof(ctx) && !file_error(ctx));

        /* We bail out on ambiguity */
        if (matchcount > 1) {
            store_info_free(result);
            return NULL;
        }

        if (result != NULL
            && ctx->expected_type != 0
            && ctx->expected_type != OSSL_STORE_INFO_get_type(result)) {
            store_info_free(result);
            goto again;
        }
    }

    return result;
}

static int file_error(OSSL_STORE_LOADER_CTX *ctx)
{
    return ctx->errcnt > 0;
}

static int file_eof(OSSL_STORE_LOADER_CTX *ctx)
{
    if (ctx->type == is_dir)
        return ctx->_.dir.end_reached;

    if (ctx->_.file.last_handler != NULL
        && !ctx->_.file.last_handler->eof(ctx->_.file.last_handler_ctx))
        return 0;
    return BIO_eof(ctx->_.file.file);
}

static int file_close(OSSL_STORE_LOADER_CTX *ctx)
{
    if ((ctx->flags & FILE_FLAG_ATTACHED) == 0) {
        if (ctx->type == is_dir)
            OPENSSL_DIR_end(&ctx->_.dir.ctx);
        else
            BIO_free_all(ctx->_.file.file);
    } else {
        /*
         * Because file_attach() called file_find_type(), we know that a
         * BIO_f_buffer() has been pushed on top of the regular BIO.
         */
        BIO *buff = ctx->_.file.file;

        /* Detach buff */
        (void)BIO_pop(ctx->_.file.file);
        /* Safety measure */
        ctx->_.file.file = NULL;

        BIO_free(buff);
    }
    OSSL_STORE_LOADER_CTX_free(ctx);
    return 1;
}

/*-
 * ENGINE management
 */

static const char *loader_attic_id = "loader_attic";
static const char *loader_attic_name = "'file:' loader";

static OSSL_STORE_LOADER *loader_attic = NULL;

static int loader_attic_init(ENGINE *e)
{
    return 1;
}


static int loader_attic_finish(ENGINE *e)
{
    return 1;
}


static int loader_attic_destroy(ENGINE *e)
{
    OSSL_STORE_LOADER *loader = OSSL_STORE_unregister_loader("file");

    if (loader == NULL)
        return 0;

    ERR_unload_ATTIC_strings();
    OSSL_STORE_LOADER_free(loader);
    return 1;
}

static int bind_loader_attic(ENGINE *e)
{

    /* Ensure the ATTIC error handling is set up on best effort basis */
    ERR_load_ATTIC_strings();

    if (/* Create the OSSL_STORE_LOADER */
        (loader_attic = OSSL_STORE_LOADER_new(e, "file")) == NULL
        || !OSSL_STORE_LOADER_set_open_ex(loader_attic, file_open_ex)
        || !OSSL_STORE_LOADER_set_open(loader_attic, file_open)
        || !OSSL_STORE_LOADER_set_attach(loader_attic, file_attach)
        || !OSSL_STORE_LOADER_set_ctrl(loader_attic, file_ctrl)
        || !OSSL_STORE_LOADER_set_expect(loader_attic, file_expect)
        || !OSSL_STORE_LOADER_set_find(loader_attic, file_find)
        || !OSSL_STORE_LOADER_set_load(loader_attic, file_load)
        || !OSSL_STORE_LOADER_set_eof(loader_attic, file_eof)
        || !OSSL_STORE_LOADER_set_error(loader_attic, file_error)
        || !OSSL_STORE_LOADER_set_close(loader_attic, file_close)
        /* Init the engine itself */
        || !ENGINE_set_id(e, loader_attic_id)
        || !ENGINE_set_name(e, loader_attic_name)
        || !ENGINE_set_destroy_function(e, loader_attic_destroy)
        || !ENGINE_set_init_function(e, loader_attic_init)
        || !ENGINE_set_finish_function(e, loader_attic_finish)
        /* Finally, register the method with libcrypto */
        || !OSSL_STORE_register_loader(loader_attic)) {
        OSSL_STORE_LOADER_free(loader_attic);
        loader_attic = NULL;
        ATTICerr(0, ATTIC_R_INIT_FAILED);
        return 0;
    }

    return 1;
}

#ifdef OPENSSL_NO_DYNAMIC_ENGINE
# error "Only allowed as dynamically shared object"
#endif

static int bind_helper(ENGINE *e, const char *id)
{
    if (id && (strcmp(id, loader_attic_id) != 0))
        return 0;
    if (!bind_loader_attic(e))
        return 0;
    return 1;
}

IMPLEMENT_DYNAMIC_CHECK_FN()
    IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
