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