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

#include "e_os.h"
#include <string.h>

#include <openssl/core.h>
#include <openssl/core_names.h>
#include <openssl/core_object.h>
#include <openssl/err.h>
#include <openssl/pkcs12.h>
#include <openssl/provider.h>
#include <openssl/decoder.h>
#include <openssl/store.h>
#include "internal/provider.h"
#include "internal/passphrase.h"
#include "crypto/evp.h"
#include "crypto/x509.h"
#include "store_local.h"

#ifndef OSSL_OBJECT_PKCS12
/*
 * The object abstraction doesn't know PKCS#12, but we want to indicate
 * it anyway, so we create our own.  Since the public macros use positive
 * numbers, negative ones should be fine.  They must never slip out from
 * this translation unit anyway.
 */
# define OSSL_OBJECT_PKCS12 -1
#endif

/*
 * ossl_store_handle_load_result() is initially written to be a companion
 * to our 'file:' scheme provider implementation, but has been made generic
 * to serve others as well.
 *
 * This result handler takes any object abstraction (see provider-object(7))
 * and does the best it can with it.  If the object is passed by value (not
 * by reference), the contents are currently expected to be DER encoded.
 * If an object type is specified, that will be respected; otherwise, this
 * handler will guess the contents, by trying the following in order:
 *
 * 1.  Decode it into an EVP_PKEY, using OSSL_DECODER.
 * 2.  Decode it into an X.509 certificate, using d2i_X509 / d2i_X509_AUX.
 * 3.  Decode it into an X.509 CRL, using d2i_X509_CRL.
 * 4.  Decode it into a PKCS#12 structure, using d2i_PKCS12 (*).
 *
 * For the 'file:' scheme implementation, this is division of labor.  Since
 * the libcrypto <-> provider interface currently doesn't support certain
 * structures as first class objects, they must be unpacked from DER here
 * rather than in the provider.  The current exception is asymmetric keys,
 * which can reside within the provider boundary, most of all thanks to
 * OSSL_FUNC_keymgmt_load(), which allows loading the key material by
 * reference.
 */

DEFINE_STACK_OF(X509)

struct extracted_param_data_st {
    int object_type;
    const char *data_type;
    const char *utf8_data;
    const void *octet_data;
    size_t octet_data_size;
    const void *ref;
    size_t ref_size;
    const char *desc;
};

static int try_name(struct extracted_param_data_st *, OSSL_STORE_INFO **);
static int try_key(struct extracted_param_data_st *, OSSL_STORE_INFO **,
                   OSSL_STORE_CTX *, const OSSL_PROVIDER *,
                   OPENSSL_CTX *, const char *);
static int try_cert(struct extracted_param_data_st *, OSSL_STORE_INFO **,
                    OPENSSL_CTX *, const char *);
static int try_crl(struct extracted_param_data_st *, OSSL_STORE_INFO **,
                   OPENSSL_CTX *, const char *);
static int try_pkcs12(struct extracted_param_data_st *, OSSL_STORE_INFO **,
                      OSSL_STORE_CTX *, OPENSSL_CTX *, const char *);

#define SET_ERR_MARK() ERR_set_mark()
#define CLEAR_ERR_MARK()                                                \
    do {                                                                \
        int 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();                                      \
    } while(0)
#define RESET_ERR_MARK()                                                \
    do {                                                                \
        CLEAR_ERR_MARK();                                               \
        SET_ERR_MARK();                                                 \
    } while(0)

int ossl_store_handle_load_result(const OSSL_PARAM params[], void *arg)
{
    struct ossl_load_result_data_st *cbdata = arg;
    OSSL_STORE_INFO **v = &cbdata->v;
    OSSL_STORE_CTX *ctx = cbdata->ctx;
    const OSSL_PROVIDER *provider =
        OSSL_STORE_LOADER_provider(ctx->fetched_loader);
    OPENSSL_CTX *libctx = ossl_provider_library_context(provider);
    const char *propq = ctx->properties;
    const OSSL_PARAM *p;
    struct extracted_param_data_st helper_data;

    memset(&helper_data, 0, sizeof(helper_data));
    helper_data.object_type = OSSL_OBJECT_UNKNOWN;

    if ((p = OSSL_PARAM_locate_const(params, OSSL_OBJECT_PARAM_TYPE)) != NULL
        && !OSSL_PARAM_get_int(p, &helper_data.object_type))
        return 0;
    p = OSSL_PARAM_locate_const(params, OSSL_OBJECT_PARAM_DATA_TYPE);
    if (p != NULL
        && !OSSL_PARAM_get_utf8_string_ptr(p, &helper_data.data_type))
        return 0;
    p = OSSL_PARAM_locate_const(params, OSSL_OBJECT_PARAM_DATA);
    if (p != NULL
        && !OSSL_PARAM_get_octet_string_ptr(p, &helper_data.octet_data,
                                            &helper_data.octet_data_size)
        && !OSSL_PARAM_get_utf8_string_ptr(p, &helper_data.utf8_data))
        return 0;
    p = OSSL_PARAM_locate_const(params, OSSL_OBJECT_PARAM_REFERENCE);
    if (p != NULL && !OSSL_PARAM_get_octet_string_ptr(p, &helper_data.ref,
                                                      &helper_data.ref_size))
        return 0;
    p = OSSL_PARAM_locate_const(params, OSSL_OBJECT_PARAM_DESC);
    if (p != NULL && !OSSL_PARAM_get_utf8_string_ptr(p, &helper_data.desc))
        return 0;

    /*
     * The helper functions return 0 on actual errors, otherwise 1, even if
     * they didn't fill out |*v|.
     */
    SET_ERR_MARK();
    if (!try_name(&helper_data, v))
        goto err;
    RESET_ERR_MARK();
    if (!try_key(&helper_data, v, ctx, provider, libctx, propq))
        goto err;
    RESET_ERR_MARK();
    if (!try_cert(&helper_data, v, libctx, propq))
        goto err;
    RESET_ERR_MARK();
    if (!try_crl(&helper_data, v, libctx, propq))
        goto err;
    RESET_ERR_MARK();
    if (!try_pkcs12(&helper_data, v, ctx, libctx, propq))
        goto err;
    CLEAR_ERR_MARK();

    return (*v != NULL);
 err:
    return 0;
}

static int try_name(struct extracted_param_data_st *data, OSSL_STORE_INFO **v)
{
    if (data->object_type == OSSL_OBJECT_NAME) {
        char *newname = NULL, *newdesc = NULL;

        if (data->utf8_data == NULL)
            return 0;
        if ((newname = OPENSSL_strdup(data->utf8_data)) == NULL
            || (data->desc != NULL
                && (newdesc = OPENSSL_strdup(data->desc)) == NULL)
            || (*v = OSSL_STORE_INFO_new_NAME(newname)) == NULL) {
            OPENSSL_free(newname);
            OPENSSL_free(newdesc);
            return 0;
        }
        OSSL_STORE_INFO_set0_NAME_description(*v, newdesc);
    }
    return 1;
}

/*
 * For the rest of the object types, the provider code may not know what
 * type of data it gave us, so we may need to figure that out on our own.
 * Therefore, we do check for OSSL_OBJECT_UNKNOWN everywhere below, and
 * only return 0 on error if the object type is known.
 */

static EVP_PKEY *try_key_ref(struct extracted_param_data_st *data,
                             OSSL_STORE_CTX *ctx,
                             const OSSL_PROVIDER *provider,
                             OPENSSL_CTX *libctx, const char *propq)
{
    EVP_PKEY *pk = NULL;
    EVP_KEYMGMT *keymgmt = NULL;
    void *keydata = NULL;

    /* If we have an object reference, we must have a data type */
    if (data->data_type == NULL)
        return 0;

    keymgmt = EVP_KEYMGMT_fetch(libctx, data->data_type, propq);
    if (keymgmt != NULL) {
        /*
         * There are two possible cases
         *
         * 1.  The keymgmt is from the same provider as the loader,
         *     so we can use evp_keymgmt_load()
         * 2.  The keymgmt is from another provider, then we must
         *     do the export/import dance.
         */
        if (EVP_KEYMGMT_provider(keymgmt) == provider) {
            keydata = evp_keymgmt_load(keymgmt, data->ref, data->ref_size);
        } else {
            struct evp_keymgmt_util_try_import_data_st import_data;
            OSSL_FUNC_store_export_object_fn *export_object =
                ctx->fetched_loader->p_export_object;

            import_data.keymgmt = keymgmt;
            import_data.keydata = NULL;
            import_data.selection = OSSL_KEYMGMT_SELECT_ALL;

            if (export_object != NULL) {
                /*
                 * No need to check for errors here, the value of
                 * |import_data.keydata| is as much an indicator.
                 */
                (void)export_object(ctx->loader_ctx,
                                    data->ref, data->ref_size,
                                    &evp_keymgmt_util_try_import,
                                    &import_data);
            }

            keydata = import_data.keydata;
        }
    }
    if (keydata != NULL)
        pk = evp_keymgmt_util_make_pkey(keymgmt, keydata);
    EVP_KEYMGMT_free(keymgmt);

    return pk;
}

static EVP_PKEY *try_key_value(struct extracted_param_data_st *data,
                               OSSL_STORE_CTX *ctx,
                               OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg,
                               OPENSSL_CTX *libctx, const char *propq)
{
    EVP_PKEY *pk = NULL;
    OSSL_DECODER_CTX *decoderctx = NULL;
    BIO *membio =
        BIO_new_mem_buf(data->octet_data, (int)data->octet_data_size);

    if (membio == NULL)
        return 0;

    decoderctx = OSSL_DECODER_CTX_new_by_EVP_PKEY(&pk, "DER", libctx, propq);
    (void)OSSL_DECODER_CTX_set_passphrase_cb(decoderctx, cb, cbarg);

    /* No error if this couldn't be decoded */
    (void)OSSL_DECODER_from_bio(decoderctx, membio);

    OSSL_DECODER_CTX_free(decoderctx);
    BIO_free(membio);

    return pk;
}

typedef OSSL_STORE_INFO *store_info_new_fn(EVP_PKEY *);

static EVP_PKEY *try_key_value_legacy(struct extracted_param_data_st *data,
                                      store_info_new_fn **store_info_new,
                                      OSSL_STORE_CTX *ctx,
                                      OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg,
                                      OPENSSL_CTX *libctx, const char *propq)
{
    EVP_PKEY *pk = NULL;
    const unsigned char *der = data->octet_data, *derp;
    long der_len = (long)data->octet_data_size;

    /* Try PUBKEY first, that's a real easy target */
    derp = der;
    pk = d2i_PUBKEY_ex(NULL, &derp, der_len, libctx, propq);
    if (pk != NULL)
        *store_info_new = OSSL_STORE_INFO_new_PUBKEY;

    /* Try private keys next */
    if (pk == NULL) {
        unsigned char *new_der = NULL;
        X509_SIG *p8 = NULL;
        PKCS8_PRIV_KEY_INFO *p8info = NULL;

        /* See if it's an encrypted PKCS#8 and decrypt it */
        derp = der;
        if ((p8 = d2i_X509_SIG(NULL, &derp, der_len)) != NULL) {
            char pbuf[PEM_BUFSIZE];
            size_t plen = 0;

            if (!cb(pbuf, sizeof(pbuf), &plen, NULL, cbarg)) {
                ERR_raise(ERR_LIB_OSSL_STORE,
                          OSSL_STORE_R_BAD_PASSWORD_READ);
            } else {
                const X509_ALGOR *alg = NULL;
                const ASN1_OCTET_STRING *oct = NULL;
                int len = 0;

                X509_SIG_get0(p8, &alg, &oct);

                /*
                 * No need to check the returned value, |new_der|
                 * will be NULL on error anyway.
                 */
                PKCS12_pbe_crypt(alg, pbuf, plen,
                                 oct->data, oct->length,
                                 &new_der, &len, 0);
                der_len = len;
                der = new_der;
            }
            X509_SIG_free(p8);
        }

        /*
         * If the encrypted PKCS#8 couldn't be decrypted,
         * |der| is NULL
         */
        if (der != NULL) {
            /* Try to unpack an unencrypted PKCS#8, that's easy */
            derp = der;
            p8info = d2i_PKCS8_PRIV_KEY_INFO(NULL, &derp, der_len);
            if (p8info != NULL) {
                pk = EVP_PKCS82PKEY_with_libctx(p8info, libctx, propq);
                PKCS8_PRIV_KEY_INFO_free(p8info);
            }

            /*
             * It wasn't PKCS#8, so we must try the hard way.
             * However, we can cheat a little bit, because we know
             * what's not yet fully supported in out decoders.
             * TODO(3.0) Eliminate these when we have decoder support.
             */
            if (pk == NULL) {
                derp = der;
                pk = d2i_PrivateKey_ex(EVP_PKEY_SM2, NULL,
                                       &derp, der_len,
                                       libctx, NULL);
            }
        }

        if (pk != NULL)
            *store_info_new = OSSL_STORE_INFO_new_PKEY;

        OPENSSL_free(new_der);
        der = data->octet_data;
        der_len = (long)data->octet_data_size;
    }

    /*
     * Last, we try parameters.  We cheat the same way we do for
     * private keys above.
     * TODO(3.0) Eliminate these when we have decoder support.
     */
    if (pk == NULL) {
        derp = der;
        pk = d2i_KeyParams(EVP_PKEY_SM2, NULL, &derp, der_len);
        if (pk != NULL)
            *store_info_new = OSSL_STORE_INFO_new_PARAMS;
    }

    return pk;
}

static int try_key(struct extracted_param_data_st *data, OSSL_STORE_INFO **v,
                   OSSL_STORE_CTX *ctx, const OSSL_PROVIDER *provider,
                   OPENSSL_CTX *libctx, const char *propq)
{
    store_info_new_fn *store_info_new = NULL;

    if (data->object_type == OSSL_OBJECT_UNKNOWN
        || data->object_type == OSSL_OBJECT_PKEY) {
        EVP_PKEY *pk = NULL;

        /* Prefer key by reference than key by value */
        if (data->object_type == OSSL_OBJECT_PKEY && data->ref != NULL) {
            pk = try_key_ref(data, ctx, provider, libctx, propq);

            /*
             * If for some reason we couldn't get a key, it's an error.
             * It indicates that while decoders could make a key reference,
             * the keymgmt somehow couldn't handle it, or doesn't have a
             * OSSL_FUNC_keymgmt_load function.
             */
            if (pk == NULL)
                return 0;
        } else if (data->octet_data != NULL) {
            OSSL_PASSPHRASE_CALLBACK *cb = ossl_pw_passphrase_callback_dec;
            void *cbarg = &ctx->pwdata;

            pk = try_key_value(data, ctx, cb, cbarg, libctx, propq);

            /*
             * Desperate last maneuver, in case the decoders don't support
             * the data we have, then we try on our own to at least get a
             * legacy key.
             * This is the same as der2key_decode() does, but in a limited
             * way and within the walls of libcrypto.
             *
             * TODO Remove this when #legacy keys are gone
             */
            if (pk == NULL)
                pk = try_key_value_legacy(data, &store_info_new, ctx,
                                          cb, cbarg, libctx, propq);
        }

        if (pk != NULL) {
            data->object_type = OSSL_OBJECT_PKEY;

            if (store_info_new == NULL) {
                /*
                 * We determined the object type for OSSL_STORE_INFO, which
                 * makes an explicit difference between an EVP_PKEY with just
                 * (domain) parameters and an EVP_PKEY with actual key
                 * material.
                 * The logic is that an EVP_PKEY with actual key material
                 * always has the public half.
                 */
                if (evp_keymgmt_util_has(pk, OSSL_KEYMGMT_SELECT_PRIVATE_KEY))
                    store_info_new = OSSL_STORE_INFO_new_PKEY;
                else if (evp_keymgmt_util_has(pk,
                                              OSSL_KEYMGMT_SELECT_PUBLIC_KEY))
                    store_info_new = OSSL_STORE_INFO_new_PUBKEY;
                else
                    store_info_new = OSSL_STORE_INFO_new_PARAMS;
            }
            *v = store_info_new(pk);
        }

        if (*v == NULL)
            EVP_PKEY_free(pk);
    }

    return 1;
}

static int try_cert(struct extracted_param_data_st *data, OSSL_STORE_INFO **v,
                    OPENSSL_CTX *libctx, const char *propq)
{
    if (data->object_type == OSSL_OBJECT_UNKNOWN
        || data->object_type == OSSL_OBJECT_CERT) {
        X509 *cert;

        /*
         * 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
         * |data_type| (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 we have a data type, it should be a PEM name */
        if (data->data_type != NULL
            && (strcasecmp(data->data_type, PEM_STRING_X509_TRUSTED) == 0))
            ignore_trusted = 0;

        cert = d2i_X509_AUX(NULL, (const unsigned char **)&data->octet_data,
                            data->octet_data_size);
        if (cert == NULL && ignore_trusted)
            cert = d2i_X509(NULL, (const unsigned char **)&data->octet_data,
                            data->octet_data_size);

        if (cert != NULL)
            /* We determined the object type */
            data->object_type = OSSL_OBJECT_CERT;

        if (cert != NULL && !x509_set0_libctx(cert, libctx, propq)) {
            X509_free(cert);
            cert = NULL;
        }

        if (cert != NULL)
            *v = OSSL_STORE_INFO_new_CERT(cert);
        if (*v == NULL)
            X509_free(cert);
    }

    return 1;
}

static int try_crl(struct extracted_param_data_st *data, OSSL_STORE_INFO **v,
                   OPENSSL_CTX *libctx, const char *propq)
{
    if (data->object_type == OSSL_OBJECT_UNKNOWN
        || data->object_type == OSSL_OBJECT_CRL) {
        X509_CRL *crl;

        crl = d2i_X509_CRL(NULL, (const unsigned char **)&data->octet_data,
                           data->octet_data_size);
        if (crl != NULL)
            /* We determined the object type */
            data->object_type = OSSL_OBJECT_CRL;

        if (crl != NULL && !x509_crl_set0_libctx(crl, libctx, propq)) {
            X509_CRL_free(crl);
            crl = NULL;
        }

        if (crl != NULL)
            *v = OSSL_STORE_INFO_new_CRL(crl);
        if (*v == NULL)
            X509_CRL_free(crl);
    }

    return 1;
}

static int try_pkcs12(struct extracted_param_data_st *data, OSSL_STORE_INFO **v,
                      OSSL_STORE_CTX *ctx,
                      OPENSSL_CTX *libctx, const char *propq)
{
    /* There is no specific object type for PKCS12 */
    if (data->object_type == OSSL_OBJECT_UNKNOWN) {
        /* Initial parsing */
        PKCS12 *p12;

        if ((p12 = d2i_PKCS12(NULL, (const unsigned char **)&data->octet_data,
                              data->octet_data_size)) != NULL) {
            char *pass = NULL;
            char tpass[PEM_BUFSIZE];
            size_t tpass_len;
            EVP_PKEY *pkey = NULL;
            X509 *cert = NULL;
            STACK_OF(X509) *chain = NULL;

            data->object_type = OSSL_OBJECT_PKCS12;

            if (PKCS12_verify_mac(p12, "", 0)
                || PKCS12_verify_mac(p12, NULL, 0)) {
                pass = "";
            } else {
                static char prompt_info[] = "PKCS12 import pass phrase";
                OSSL_PARAM pw_params[] = {
                    OSSL_PARAM_utf8_string(OSSL_PASSPHRASE_PARAM_INFO,
                                           prompt_info,
                                           sizeof(prompt_info) - 1),
                    OSSL_PARAM_END
                };

                if (!ossl_pw_get_passphrase(tpass, sizeof(tpass), &tpass_len,
                                            pw_params, 0, &ctx->pwdata)) {
                    ERR_raise(ERR_LIB_OSSL_STORE,
                              OSSL_STORE_R_PASSPHRASE_CALLBACK_ERROR);
                    goto p12_end;
                }
                pass = tpass;
                if (!PKCS12_verify_mac(p12, pass, strlen(pass))) {
                    ERR_raise(ERR_LIB_OSSL_STORE,
                              OSSL_STORE_R_ERROR_VERIFYING_PKCS12_MAC);
                    goto p12_end;
                }
            }

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

                if ((infos = 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(infos, 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(infos, 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(infos, osi_ca) != 0)
                            osi_ca = NULL;
                        else
                            ok = 0;
                    }
                }
                EVP_PKEY_free(pkey);
                X509_free(cert);
                sk_X509_pop_free(chain, X509_free);
                OSSL_STORE_INFO_free(osi_pkey);
                OSSL_STORE_INFO_free(osi_cert);
                OSSL_STORE_INFO_free(osi_ca);
                if (!ok) {
                    sk_OSSL_STORE_INFO_pop_free(infos, OSSL_STORE_INFO_free);
                    infos = NULL;
                }
                ctx->cached_info = infos;
            }
        }
     p12_end:
        PKCS12_free(p12);
        *v = sk_OSSL_STORE_INFO_shift(ctx->cached_info);
    }

    return 1;
}
