/*
 * 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 <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;
}
