/*
 * 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 <openssl/err.h>
#include <openssl/ui.h>
#include <openssl/core_names.h>
#include "internal/cryptlib.h"
#include "internal/passphrase.h"

void ossl_pw_clear_passphrase_data(struct ossl_passphrase_data_st *data)
{
    if (data != NULL) {
        if (data->type == is_expl_passphrase)
            OPENSSL_clear_free(data->_.expl_passphrase.passphrase_copy,
                               data->_.expl_passphrase.passphrase_len);
        ossl_pw_clear_passphrase_cache(data);
        memset(data, 0, sizeof(*data));
    }
}

void ossl_pw_clear_passphrase_cache(struct ossl_passphrase_data_st *data)
{
    OPENSSL_clear_free(data->cached_passphrase, data->cached_passphrase_len);
    data->cached_passphrase = NULL;
}

int ossl_pw_set_passphrase(struct ossl_passphrase_data_st *data,
                           const unsigned char *passphrase,
                           size_t passphrase_len)
{
    if (!ossl_assert(data != NULL && passphrase != NULL)) {
        ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }
    ossl_pw_clear_passphrase_data(data);
    data->type = is_expl_passphrase;
    data->_.expl_passphrase.passphrase_copy =
        OPENSSL_memdup(passphrase, passphrase_len);
    if (data->_.expl_passphrase.passphrase_copy == NULL) {
        ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE);
        return 0;
    }
    data->_.expl_passphrase.passphrase_len = passphrase_len;
    return 1;
}

int ossl_pw_set_pem_password_cb(struct ossl_passphrase_data_st *data,
                                pem_password_cb *cb, void *cbarg)
{
    if (!ossl_assert(data != NULL && cb != NULL)) {
        ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }
    ossl_pw_clear_passphrase_data(data);
    data->type = is_pem_password;
    data->_.pem_password.password_cb = cb;
    data->_.pem_password.password_cbarg = cbarg;
    return 1;
}

int ossl_pw_set_ossl_passphrase_cb(struct ossl_passphrase_data_st *data,
                                   OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
    if (!ossl_assert(data != NULL && cb != NULL)) {
        ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }
    ossl_pw_clear_passphrase_data(data);
    data->type = is_ossl_passphrase;
    data->_.ossl_passphrase.passphrase_cb = cb;
    data->_.ossl_passphrase.passphrase_cbarg = cbarg;
    return 1;
}

int ossl_pw_set_ui_method(struct ossl_passphrase_data_st *data,
                          const UI_METHOD *ui_method, void *ui_data)
{
    if (!ossl_assert(data != NULL && ui_method != NULL)) {
        ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }
    ossl_pw_clear_passphrase_data(data);
    data->type = is_ui_method;
    data->_.ui_method.ui_method = ui_method;
    data->_.ui_method.ui_method_data = ui_data;
    return 1;
}

int ossl_pw_enable_passphrase_caching(struct ossl_passphrase_data_st *data)
{
    data->flag_cache_passphrase = 1;
    return 1;
}

int ossl_pw_disable_passphrase_caching(struct ossl_passphrase_data_st *data)
{
    data->flag_cache_passphrase = 0;
    return 1;
}


/*-
 * UI_METHOD processor.  It differs from UI_UTIL_read_pw() like this:
 *
 * 1.  It constructs a prompt on its own, based on |prompt_info|.
 * 2.  It allocates a buffer for verification on its own.
 * 3.  It raises errors.
 * 4.  It reports back the length of the prompted pass phrase.
 */
static int do_ui_passphrase(char *pass, size_t pass_size, size_t *pass_len,
                            const char *prompt_info, int verify,
                            const UI_METHOD *ui_method, void *ui_data)
{
    char *prompt = NULL, *vpass = NULL;
    int prompt_idx = -1, verify_idx = -1;
    UI *ui = NULL;
    int ret = 0;

    if (!ossl_assert(pass != NULL && pass_size != 0 && pass_len != NULL)) {
        ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }

    if ((ui = UI_new()) == NULL) {
        ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE);
        return 0;
    }

    if (ui_method != NULL) {
        UI_set_method(ui, ui_method);
        if (ui_data != NULL)
            UI_add_user_data(ui, ui_data);
    }

    /* Get an application constructed prompt */
    prompt = UI_construct_prompt(ui, "pass phrase", prompt_info);
    if (prompt == NULL) {
        ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE);
        goto end;
    }

    prompt_idx = UI_add_input_string(ui, prompt,
                                     UI_INPUT_FLAG_DEFAULT_PWD,
                                     pass, 0, pass_size - 1) - 1;
    if (prompt_idx < 0) {
        ERR_raise(ERR_LIB_CRYPTO, ERR_R_UI_LIB);
        goto end;
    }

    if (verify) {
        /* Get a buffer for verification prompt */
        vpass = OPENSSL_zalloc(pass_size);
        if (vpass == NULL) {
            ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE);
            goto end;
        }
        verify_idx = UI_add_verify_string(ui, prompt,
                                          UI_INPUT_FLAG_DEFAULT_PWD,
                                          vpass, 0, pass_size - 1,
                                          pass) - 1;
        if (verify_idx < 0) {
            ERR_raise(ERR_LIB_CRYPTO, ERR_R_UI_LIB);
            goto end;
        }
    }

    switch (UI_process(ui)) {
    case -2:
        ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERRUPTED_OR_CANCELLED);
        break;
    case -1:
        ERR_raise(ERR_LIB_CRYPTO, ERR_R_UI_LIB);
        break;
    default:
        *pass_len = (size_t)UI_get_result_length(ui, prompt_idx);
        ret = 1;
        break;
    }

 end:
    OPENSSL_free(vpass);
    OPENSSL_free(prompt);
    UI_free(ui);
    return ret;
}

/* Central pw prompting dispatcher */
int ossl_pw_get_passphrase(char *pass, size_t pass_size, size_t *pass_len,
                           const OSSL_PARAM params[], int verify,
                           struct ossl_passphrase_data_st *data)
{
    const char *source = NULL;
    size_t source_len = 0;
    const char *prompt_info = NULL;
    const UI_METHOD *ui_method = NULL;
    UI_METHOD *allocated_ui_method = NULL;
    void *ui_data = NULL;
    const OSSL_PARAM *p = NULL;
    int ret;

    /* Handle explicit and cached passphrases */

    if (data->type == is_expl_passphrase) {
        source = data->_.expl_passphrase.passphrase_copy;
        source_len = data->_.expl_passphrase.passphrase_len;
    } else if (data->flag_cache_passphrase && data->cached_passphrase != NULL) {
        source = data->cached_passphrase;
        source_len = data->cached_passphrase_len;
    }

    if (source != NULL) {
        if (source_len > pass_size)
            source_len = pass_size;
        memcpy(pass, source, source_len);
        *pass_len = source_len;
        return 1;
    }

    /* Handle the is_ossl_passphrase case...  that's pretty direct */

    if (data->type == is_ossl_passphrase) {
        OSSL_PASSPHRASE_CALLBACK *cb = data->_.ossl_passphrase.passphrase_cb;
        void *cbarg = data->_.ossl_passphrase.passphrase_cbarg;

        ret = cb(pass, pass_size, pass_len, params, cbarg);
        goto do_cache;
    }

    /* Handle the is_pem_password and is_ui_method cases */

    if ((p = OSSL_PARAM_locate_const(params,
                                     OSSL_PASSPHRASE_PARAM_INFO)) != NULL) {
        if (p->data_type != OSSL_PARAM_UTF8_STRING) {
            ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT,
                           "Prompt info data type incorrect");
            return 0;
        }
        prompt_info = p->data;
    }

    if (data->type == is_pem_password) {
        /* We use a UI wrapper for PEM */
        pem_password_cb *cb = data->_.pem_password.password_cb;

        ui_method = allocated_ui_method =
            UI_UTIL_wrap_read_pem_callback(cb, verify);
        ui_data = data->_.pem_password.password_cbarg;

        if (ui_method == NULL) {
            ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE);
            return 0;
        }
    } else if (data->type == is_ui_method) {
        ui_method = data->_.ui_method.ui_method;
        ui_data = data->_.ui_method.ui_method_data;
    }

    if (ui_method == NULL) {
        ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT,
                       "No password method specified");
        return 0;
    }

    ret = do_ui_passphrase(pass, pass_size, pass_len, prompt_info, verify,
                           ui_method, ui_data);

    UI_destroy_method(allocated_ui_method);

 do_cache:
    if (ret && data->flag_cache_passphrase) {
        if (data->cached_passphrase == NULL
            || *pass_len > data->cached_passphrase_len) {
            void *new_cache =
                OPENSSL_clear_realloc(data->cached_passphrase,
                                      data->cached_passphrase_len,
                                      *pass_len + 1);

            if (new_cache == NULL) {
                OPENSSL_cleanse(pass, *pass_len);
                ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE);
                return 0;
            }
            data->cached_passphrase = new_cache;
        }
        memcpy(data->cached_passphrase, pass, *pass_len);
        data->cached_passphrase[*pass_len] = '\0';
        data->cached_passphrase_len = *pass_len;
    }

    return ret;
}

int ossl_pw_pem_password(char *buf, int size, int rwflag, void *userdata)
{
    size_t password_len = 0;
    OSSL_PARAM params[] = {
        OSSL_PARAM_utf8_string(OSSL_PASSPHRASE_PARAM_INFO, NULL, 0),
        OSSL_PARAM_END
    };

    params[0].data = "PEM";
    if (ossl_pw_get_passphrase(buf, (size_t)size, &password_len, params,
                               rwflag, userdata))
        return (int)password_len;
    return -1;
}

int ossl_pw_passphrase_callback_enc(char *pass, size_t pass_size,
                                    size_t *pass_len,
                                    const OSSL_PARAM params[], void *arg)
{
    return ossl_pw_get_passphrase(pass, pass_size, pass_len, params, 1, arg);
}

int ossl_pw_passphrase_callback_dec(char *pass, size_t pass_size,
                                    size_t *pass_len,
                                    const OSSL_PARAM params[], void *arg)
{
    return ossl_pw_get_passphrase(pass, pass_size, pass_len, params, 0, arg);
}
