/*
 * Copyright 2019-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"                /* 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_by_TYPE:
 * finding a suitable encoder
 */

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

    OSSL_ENCODER_CTX *ctx;

    int error_occured;
};

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

    if (data->error_occured)
        return;

    data->error_occured = 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_provider(encoder);
        void *provctx = OSSL_PROVIDER_get0_provider_ctx(prov);

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

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

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

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

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

    if (data->error_occured)
        return;

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

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

    data->error_occured = 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_EVP_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_provider(pk->keymgmt);
        const OSSL_PROVIDER *e_prov = OSSL_ENCODER_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_EVP_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_by_EVP_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_EVP_PKEY(OSSL_ENCODER_CTX *ctx,
                                               const EVP_PKEY *pkey,
                                               int selection,
                                               OSSL_LIB_CTX *libctx,
                                               const char *propquery)
{
    struct construct_data_st *data = 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 (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();
        keymgmt_data.error_occured = 0;
        EVP_KEYMGMT_names_do_all(pkey->keymgmt, collect_name, &keymgmt_data);
        if (keymgmt_data.error_occured) {
            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_occured = 0;
        encoder_data.ctx = ctx;
        OSSL_ENCODER_do_all_provided(libctx, collect_encoder, &encoder_data);
        sk_OPENSSL_CSTRING_free(keymgmt_data.names);
        if (encoder_data.error_occured) {
            ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_MALLOC_FAILURE);
            goto err;
        }
    }

    if (OSSL_ENCODER_CTX_get_num_encoders(ctx) != 0) {
        if (!OSSL_ENCODER_CTX_set_construct(ctx, encoder_construct_EVP_PKEY)
            || !OSSL_ENCODER_CTX_set_construct_data(ctx, data)
            || !OSSL_ENCODER_CTX_set_cleanup(ctx, encoder_destruct_EVP_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_by_EVP_PKEY(const EVP_PKEY *pkey,
                                                   int selection,
                                                   const char *output_type,
                                                   const char *output_struct,
                                                   OSSL_LIB_CTX *libctx,
                                                   const char *propquery)
{
    OSSL_ENCODER_CTX *ctx = NULL;

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

    OSSL_TRACE_BEGIN(ENCODER) {
        BIO_printf(trc_out,
                   "(ctx %p) Looking for %s encoders with selection %d\n",
                   (void *)ctx, EVP_PKEY_get0_first_alg_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_EVP_PKEY(ctx, pkey, selection,
                                               libctx, propquery)
        && OSSL_ENCODER_CTX_add_extra(ctx, libctx, propquery)) {
        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;
}
