/*
 * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
 * Copyright 2005 Nokia. 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
 */

/*
 * This file is to enable backwards compatibility for the SRP features of
 * s_client, s_server and ciphers. All of those features are deprecated and will
 * eventually disappear. In the meantime, to continue to support them, we
 * need to access deprecated SRP APIs.
 */
#define OPENSSL_SUPPRESS_DEPRECATED

#include <openssl/bn.h>
#include <openssl/bio.h>
#include <openssl/ssl.h>
#include <openssl/srp.h>
#include "apps_ui.h"
#include "apps.h"
#include "s_apps.h"

static int srp_Verify_N_and_g(const BIGNUM *N, const BIGNUM *g)
{
    BN_CTX *bn_ctx = BN_CTX_new();
    BIGNUM *p = BN_new();
    BIGNUM *r = BN_new();
    int ret =
        g != NULL && N != NULL && bn_ctx != NULL && BN_is_odd(N) &&
        BN_check_prime(N, bn_ctx, NULL) == 1 &&
        p != NULL && BN_rshift1(p, N) &&
        /* p = (N-1)/2 */
        BN_check_prime(p, bn_ctx, NULL) == 1 &&
        r != NULL &&
        /* verify g^((N-1)/2) == -1 (mod N) */
        BN_mod_exp(r, g, p, N, bn_ctx) &&
        BN_add_word(r, 1) && BN_cmp(r, N) == 0;

    BN_free(r);
    BN_free(p);
    BN_CTX_free(bn_ctx);
    return ret;
}

/*-
 * This callback is used here for two purposes:
 * - extended debugging
 * - making some primality tests for unknown groups
 * The callback is only called for a non default group.
 *
 * An application does not need the call back at all if
 * only the standard groups are used.  In real life situations,
 * client and server already share well known groups,
 * thus there is no need to verify them.
 * Furthermore, in case that a server actually proposes a group that
 * is not one of those defined in RFC 5054, it is more appropriate
 * to add the group to a static list and then compare since
 * primality tests are rather cpu consuming.
 */

static int ssl_srp_verify_param_cb(SSL *s, void *arg)
{
    SRP_ARG *srp_arg = (SRP_ARG *)arg;
    BIGNUM *N = NULL, *g = NULL;

    if (((N = SSL_get_srp_N(s)) == NULL) || ((g = SSL_get_srp_g(s)) == NULL))
        return 0;
    if (srp_arg->debug || srp_arg->msg || srp_arg->amp == 1) {
        BIO_printf(bio_err, "SRP parameters:\n");
        BIO_printf(bio_err, "\tN=");
        BN_print(bio_err, N);
        BIO_printf(bio_err, "\n\tg=");
        BN_print(bio_err, g);
        BIO_printf(bio_err, "\n");
    }

    if (SRP_check_known_gN_param(g, N))
        return 1;

    if (srp_arg->amp == 1) {
        if (srp_arg->debug)
            BIO_printf(bio_err,
                       "SRP param N and g are not known params, going to check deeper.\n");

        /*
         * The srp_moregroups is a real debugging feature. Implementors
         * should rather add the value to the known ones. The minimal size
         * has already been tested.
         */
        if (BN_num_bits(g) <= BN_BITS && srp_Verify_N_and_g(N, g))
            return 1;
    }
    BIO_printf(bio_err, "SRP param N and g rejected.\n");
    return 0;
}

#define PWD_STRLEN 1024

static char *ssl_give_srp_client_pwd_cb(SSL *s, void *arg)
{
    SRP_ARG *srp_arg = (SRP_ARG *)arg;
    char *pass = app_malloc(PWD_STRLEN + 1, "SRP password buffer");
    PW_CB_DATA cb_tmp;
    int l;

    cb_tmp.password = (char *)srp_arg->srppassin;
    cb_tmp.prompt_info = "SRP user";
    if ((l = password_callback(pass, PWD_STRLEN, 0, &cb_tmp)) < 0) {
        BIO_printf(bio_err, "Can't read Password\n");
        OPENSSL_free(pass);
        return NULL;
    }
    *(pass + l) = '\0';

    return pass;
}

int set_up_srp_arg(SSL_CTX *ctx, SRP_ARG *srp_arg, int srp_lateuser, int c_msg,
                   int c_debug)
{
    if (!srp_lateuser && !SSL_CTX_set_srp_username(ctx, srp_arg->srplogin)) {
        BIO_printf(bio_err, "Unable to set SRP username\n");
        return 0;
    }
    srp_arg->msg = c_msg;
    srp_arg->debug = c_debug;
    SSL_CTX_set_srp_cb_arg(ctx, &srp_arg);
    SSL_CTX_set_srp_client_pwd_callback(ctx, ssl_give_srp_client_pwd_cb);
    SSL_CTX_set_srp_strength(ctx, srp_arg->strength);
    if (c_msg || c_debug || srp_arg->amp == 0)
        SSL_CTX_set_srp_verify_param_callback(ctx, ssl_srp_verify_param_cb);

    return 1;
}

static char *dummy_srp(SSL *ssl, void *arg)
{
    return "";
}

void set_up_dummy_srp(SSL_CTX *ctx)
{
        SSL_CTX_set_srp_client_pwd_callback(ctx, dummy_srp);
}

/*
 * This callback pretends to require some asynchronous logic in order to
 * obtain a verifier. When the callback is called for a new connection we
 * return with a negative value. This will provoke the accept etc to return
 * with an LOOKUP_X509. The main logic of the reinvokes the suspended call
 * (which would normally occur after a worker has finished) and we set the
 * user parameters.
 */
static int ssl_srp_server_param_cb(SSL *s, int *ad, void *arg)
{
    srpsrvparm *p = (srpsrvparm *) arg;
    int ret = SSL3_AL_FATAL;

    if (p->login == NULL && p->user == NULL) {
        p->login = SSL_get_srp_username(s);
        BIO_printf(bio_err, "SRP username = \"%s\"\n", p->login);
        return -1;
    }

    if (p->user == NULL) {
        BIO_printf(bio_err, "User %s doesn't exist\n", p->login);
        goto err;
    }

    if (SSL_set_srp_server_param
        (s, p->user->N, p->user->g, p->user->s, p->user->v,
         p->user->info) < 0) {
        *ad = SSL_AD_INTERNAL_ERROR;
        goto err;
    }
    BIO_printf(bio_err,
               "SRP parameters set: username = \"%s\" info=\"%s\" \n",
               p->login, p->user->info);
    ret = SSL_ERROR_NONE;

 err:
    SRP_user_pwd_free(p->user);
    p->user = NULL;
    p->login = NULL;
    return ret;
}

int set_up_srp_verifier_file(SSL_CTX *ctx, srpsrvparm *srp_callback_parm,
                             char *srpuserseed, char *srp_verifier_file)
{
    int ret;

    srp_callback_parm->vb = SRP_VBASE_new(srpuserseed);
    srp_callback_parm->user = NULL;
    srp_callback_parm->login = NULL;

    if (srp_callback_parm->vb == NULL) {
        BIO_printf(bio_err, "Failed to initialize SRP verifier file \n");
        return 0;
    }
    if ((ret =
            SRP_VBASE_init(srp_callback_parm->vb,
                           srp_verifier_file)) != SRP_NO_ERROR) {
        BIO_printf(bio_err,
                    "Cannot initialize SRP verifier file \"%s\":ret=%d\n",
                    srp_verifier_file, ret);
        return 0;
    }
    SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, verify_callback);
    SSL_CTX_set_srp_cb_arg(ctx, &srp_callback_parm);
    SSL_CTX_set_srp_username_callback(ctx, ssl_srp_server_param_cb);

    return 1;
}

void lookup_srp_user(srpsrvparm *srp_callback_parm, BIO *bio_s_out)
{
    SRP_user_pwd_free(srp_callback_parm->user);
    srp_callback_parm->user = SRP_VBASE_get1_by_user(srp_callback_parm->vb,
                                                     srp_callback_parm->login);

    if (srp_callback_parm->user != NULL)
        BIO_printf(bio_s_out, "LOOKUP done %s\n",
                    srp_callback_parm->user->info);
    else
        BIO_printf(bio_s_out, "LOOKUP not successful\n");
}
