/*
 * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

#include "internal/e_os.h"                /* strcasecmp on Windows */
#include <openssl/err.h>
#include <openssl/ui.h>
#include <openssl/params.h>
#include <openssl/encoder.h>
#include <openssl/core_names.h>
#include <openssl/provider.h>
#include <openssl/safestack.h>
#include <openssl/trace.h>
#include "internal/provider.h"
#include "internal/property.h"
#include "crypto/evp.h"
#include "encoder_local.h"

DEFINE_STACK_OF(OSSL_ENCODER)

int OSSL_ENCODER_CTX_set_cipher(OSSL_ENCODER_CTX *ctx,
                                const char *cipher_name,
                                const char *propquery)
{
    OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END };

    params[0] =
        OSSL_PARAM_construct_utf8_string(OSSL_ENCODER_PARAM_CIPHER,
                                         (void *)cipher_name, 0);
    params[1] =
        OSSL_PARAM_construct_utf8_string(OSSL_ENCODER_PARAM_PROPERTIES,
                                         (void *)propquery, 0);

    return OSSL_ENCODER_CTX_set_params(ctx, params);
}

int OSSL_ENCODER_CTX_set_passphrase(OSSL_ENCODER_CTX *ctx,
                                    const unsigned char *kstr,
                                    size_t klen)
{
    return ossl_pw_set_passphrase(&ctx->pwdata, kstr, klen);
}

int OSSL_ENCODER_CTX_set_passphrase_ui(OSSL_ENCODER_CTX *ctx,
                                       const UI_METHOD *ui_method,
                                       void *ui_data)
{
    return ossl_pw_set_ui_method(&ctx->pwdata, ui_method, ui_data);
}

int OSSL_ENCODER_CTX_set_pem_password_cb(OSSL_ENCODER_CTX *ctx,
                                         pem_password_cb *cb, void *cbarg)
{
    return ossl_pw_set_pem_password_cb(&ctx->pwdata, cb, cbarg);
}

int OSSL_ENCODER_CTX_set_passphrase_cb(OSSL_ENCODER_CTX *ctx,
                                       OSSL_PASSPHRASE_CALLBACK *cb,
                                       void *cbarg)
{
    return ossl_pw_set_ossl_passphrase_cb(&ctx->pwdata, cb, cbarg);
}

/*
 * Support for OSSL_ENCODER_CTX_new_for_type:
 * finding a suitable encoder
 */

struct collected_encoder_st {
    STACK_OF(OPENSSL_CSTRING) *names;
    const char *output_structure;
    const char *output_type;

    const OSSL_PROVIDER *keymgmt_prov;
    OSSL_ENCODER_CTX *ctx;
    unsigned int flag_find_same_provider:1;

    int error_occurred;
};

static void collect_encoder(OSSL_ENCODER *encoder, void *arg)
{
    struct collected_encoder_st *data = arg;
    size_t i, end_i;

    if (data->error_occurred)
        return;

    data->error_occurred = 1;     /* Assume the worst */

    if (data->names == NULL)
        return;

    end_i = sk_OPENSSL_CSTRING_num(data->names);
    for (i = 0; i < end_i; i++) {
        const char *name = sk_OPENSSL_CSTRING_value(data->names, i);
        const OSSL_PROVIDER *prov = OSSL_ENCODER_get0_provider(encoder);
        void *provctx = OSSL_PROVIDER_get0_provider_ctx(prov);

        /*
         * collect_encoder() is called in two passes, one where the encoders
         * from the same provider as the keymgmt are looked up, and one where
         * the other encoders are looked up.  |data->flag_find_same_provider|
         * tells us which pass we're in.
         */
        if ((data->keymgmt_prov == prov) != data->flag_find_same_provider)
            continue;

        if (!OSSL_ENCODER_is_a(encoder, name)
            || (encoder->does_selection != NULL
                && !encoder->does_selection(provctx, data->ctx->selection))
            || (data->keymgmt_prov != prov
                && encoder->import_object == NULL))
            continue;

        /* Only add each encoder implementation once */
        if (OSSL_ENCODER_CTX_add_encoder(data->ctx, encoder))
            break;
    }

    data->error_occurred = 0;         /* All is good now */
}

struct collected_names_st {
    STACK_OF(OPENSSL_CSTRING) *names;
    unsigned int error_occurred:1;
};

static void collect_name(const char *name, void *arg)
{
    struct collected_names_st *data = arg;

    if (data->error_occurred)
        return;

    data->error_occurred = 1;         /* Assume the worst */

    if (sk_OPENSSL_CSTRING_push(data->names, name) <= 0)
        return;

    data->error_occurred = 0;         /* All is good now */
}

/*
 * Support for OSSL_ENCODER_to_bio:
 * writing callback for the OSSL_PARAM (the implementation doesn't have
 * intimate knowledge of the provider side object)
 */

struct construct_data_st {
    const EVP_PKEY *pk;
    int selection;

    OSSL_ENCODER_INSTANCE *encoder_inst;
    const void *obj;
    void *constructed_obj;
};

static int encoder_import_cb(const OSSL_PARAM params[], void *arg)
{
    struct construct_data_st *construct_data = arg;
    OSSL_ENCODER_INSTANCE *encoder_inst = construct_data->encoder_inst;
    OSSL_ENCODER *encoder = OSSL_ENCODER_INSTANCE_get_encoder(encoder_inst);
    void *encoderctx = OSSL_ENCODER_INSTANCE_get_encoder_ctx(encoder_inst);

    construct_data->constructed_obj =
        encoder->import_object(encoderctx, construct_data->selection, params);

    return (construct_data->constructed_obj != NULL);
}

static const void *
encoder_construct_pkey(OSSL_ENCODER_INSTANCE *encoder_inst, void *arg)
{
    struct construct_data_st *data = arg;

    if (data->obj == NULL) {
        OSSL_ENCODER *encoder =
            OSSL_ENCODER_INSTANCE_get_encoder(encoder_inst);
        const EVP_PKEY *pk = data->pk;
        const OSSL_PROVIDER *k_prov = EVP_KEYMGMT_get0_provider(pk->keymgmt);
        const OSSL_PROVIDER *e_prov = OSSL_ENCODER_get0_provider(encoder);

        if (k_prov != e_prov) {
            data->encoder_inst = encoder_inst;

            if (!evp_keymgmt_export(pk->keymgmt, pk->keydata, data->selection,
                                    &encoder_import_cb, data))
                return NULL;
            data->obj = data->constructed_obj;
        } else {
            data->obj = pk->keydata;
        }
    }

    return data->obj;
}

static void encoder_destruct_pkey(void *arg)
{
    struct construct_data_st *data = arg;

    if (data->encoder_inst != NULL) {
        OSSL_ENCODER *encoder =
            OSSL_ENCODER_INSTANCE_get_encoder(data->encoder_inst);

        encoder->free_object(data->constructed_obj);
    }
    data->constructed_obj = NULL;
}

/*
 * OSSL_ENCODER_CTX_new_for_pkey() returns a ctx with no encoder if
 * it couldn't find a suitable encoder.  This allows a caller to detect if
 * a suitable encoder was found, with OSSL_ENCODER_CTX_get_num_encoder(),
 * and to use fallback methods if the result is NULL.
 */
static int ossl_encoder_ctx_setup_for_pkey(OSSL_ENCODER_CTX *ctx,
                                           const EVP_PKEY *pkey,
                                           int selection,
                                           const char *propquery)
{
    struct construct_data_st *data = NULL;
    const OSSL_PROVIDER *prov = NULL;
    OSSL_LIB_CTX *libctx = NULL;
    int ok = 0;

    if (!ossl_assert(ctx != NULL) || !ossl_assert(pkey != NULL)) {
        ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }

    if (evp_pkey_is_provided(pkey)) {
        prov = EVP_KEYMGMT_get0_provider(pkey->keymgmt);
        libctx = ossl_provider_libctx(prov);
    }

    if (pkey->keymgmt != NULL) {
        struct collected_encoder_st encoder_data;
        struct collected_names_st keymgmt_data;

        if ((data = OPENSSL_zalloc(sizeof(*data))) == NULL) {
            ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_MALLOC_FAILURE);
            goto err;
        }

        /*
         * Select the first encoder implementations in two steps.
         * First, collect the keymgmt names, then the encoders that match.
         */
        keymgmt_data.names = sk_OPENSSL_CSTRING_new_null();
        if (keymgmt_data.names == NULL) {
            ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_MALLOC_FAILURE);
            goto err;
        }

        keymgmt_data.error_occurred = 0;
        EVP_KEYMGMT_names_do_all(pkey->keymgmt, collect_name, &keymgmt_data);
        if (keymgmt_data.error_occurred) {
            sk_OPENSSL_CSTRING_free(keymgmt_data.names);
            goto err;
        }

        encoder_data.names = keymgmt_data.names;
        encoder_data.output_type = ctx->output_type;
        encoder_data.output_structure = ctx->output_structure;
        encoder_data.error_occurred = 0;
        encoder_data.keymgmt_prov = prov;
        encoder_data.ctx = ctx;

        /*
         * Place the encoders with the a different provider as the keymgmt
         * last (the chain is processed in reverse order)
         */
        encoder_data.flag_find_same_provider = 0;
        OSSL_ENCODER_do_all_provided(libctx, collect_encoder, &encoder_data);

        /*
         * Place the encoders with the same provider as the keymgmt first
         * (the chain is processed in reverse order)
         */
        encoder_data.flag_find_same_provider = 1;
        OSSL_ENCODER_do_all_provided(libctx, collect_encoder, &encoder_data);

        sk_OPENSSL_CSTRING_free(keymgmt_data.names);
        if (encoder_data.error_occurred) {
            ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_MALLOC_FAILURE);
            goto err;
        }
    }

    if (data != NULL && OSSL_ENCODER_CTX_get_num_encoders(ctx) != 0) {
        if (!OSSL_ENCODER_CTX_set_construct(ctx, encoder_construct_pkey)
            || !OSSL_ENCODER_CTX_set_construct_data(ctx, data)
            || !OSSL_ENCODER_CTX_set_cleanup(ctx, encoder_destruct_pkey))
            goto err;

        data->pk = pkey;
        data->selection = selection;

        data = NULL;             /* Avoid it being freed */
    }

    ok = 1;
 err:
    if (data != NULL) {
        OSSL_ENCODER_CTX_set_construct_data(ctx, NULL);
        OPENSSL_free(data);
    }
    return ok;
}

OSSL_ENCODER_CTX *OSSL_ENCODER_CTX_new_for_pkey(const EVP_PKEY *pkey,
                                                int selection,
                                                const char *output_type,
                                                const char *output_struct,
                                                const char *propquery)
{
    OSSL_ENCODER_CTX *ctx = NULL;
    OSSL_LIB_CTX *libctx = NULL;

    if (pkey == NULL) {
        ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER);
        return NULL;
    }

    if (!evp_pkey_is_assigned(pkey)) {
        ERR_raise_data(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_INVALID_ARGUMENT,
                       "The passed EVP_PKEY must be assigned a key");
        return NULL;
    }

    if ((ctx = OSSL_ENCODER_CTX_new()) == NULL) {
        ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_MALLOC_FAILURE);
        return NULL;
    }

    if (evp_pkey_is_provided(pkey)) {
        const OSSL_PROVIDER *prov = EVP_KEYMGMT_get0_provider(pkey->keymgmt);

        libctx = ossl_provider_libctx(prov);
    }

    OSSL_TRACE_BEGIN(ENCODER) {
        BIO_printf(trc_out,
                   "(ctx %p) Looking for %s encoders with selection %d\n",
                   (void *)ctx, EVP_PKEY_get0_type_name(pkey), selection);
        BIO_printf(trc_out, "    output type: %s, output structure: %s\n",
                   output_type, output_struct);
    } OSSL_TRACE_END(ENCODER);

    if (OSSL_ENCODER_CTX_set_output_type(ctx, output_type)
        && (output_struct == NULL
            || OSSL_ENCODER_CTX_set_output_structure(ctx, output_struct))
        && OSSL_ENCODER_CTX_set_selection(ctx, selection)
        && ossl_encoder_ctx_setup_for_pkey(ctx, pkey, selection, propquery)
        && OSSL_ENCODER_CTX_add_extra(ctx, libctx, propquery)) {
        OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
        int save_parameters = pkey->save_parameters;

        params[0] = OSSL_PARAM_construct_int(OSSL_ENCODER_PARAM_SAVE_PARAMETERS,
                                             &save_parameters);
        /* ignoring error as this is only auxiliary parameter */
        (void)OSSL_ENCODER_CTX_set_params(ctx, params);

        OSSL_TRACE_BEGIN(ENCODER) {
            BIO_printf(trc_out, "(ctx %p) Got %d encoders\n",
                       (void *)ctx, OSSL_ENCODER_CTX_get_num_encoders(ctx));
        } OSSL_TRACE_END(ENCODER);
        return ctx;
    }

    OSSL_ENCODER_CTX_free(ctx);
    return NULL;
}
