/* ssl/tls_srp.c */
/* Written by Christophe Renou (christophe.renou@edelweb.fr) with 
 * the precious help of Peter Sylvester (peter.sylvester@edelweb.fr) 
 * for the EdelKey project and contributed to the OpenSSL project 2004.
 */
/* ====================================================================
 * Copyright (c) 2004 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    licensing@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */
#include "ssl_locl.h"
#ifndef OPENSSL_NO_SRP

#include <openssl/rand.h>
#include <openssl/srp.h>
#include <openssl/err.h>

int SSL_CTX_SRP_CTX_free(struct ssl_ctx_st *ctx)
	{
	if (ctx == NULL)
		return 0;
	OPENSSL_free(ctx->srp_ctx.login);
	BN_free(ctx->srp_ctx.N);
	BN_free(ctx->srp_ctx.g);
	BN_free(ctx->srp_ctx.s);
	BN_free(ctx->srp_ctx.B);
	BN_free(ctx->srp_ctx.A);
	BN_free(ctx->srp_ctx.a);
	BN_free(ctx->srp_ctx.b);
	BN_free(ctx->srp_ctx.v);
	ctx->srp_ctx.TLS_ext_srp_username_callback = NULL;
	ctx->srp_ctx.SRP_cb_arg = NULL;
	ctx->srp_ctx.SRP_verify_param_callback = NULL;
	ctx->srp_ctx.SRP_give_srp_client_pwd_callback = NULL;
	ctx->srp_ctx.SRP_TLS_ext_missing_srp_client_username_callback = NULL;
	ctx->srp_ctx.N = NULL;
	ctx->srp_ctx.g = NULL;
	ctx->srp_ctx.s = NULL;
	ctx->srp_ctx.B = NULL;
	ctx->srp_ctx.A = NULL;
	ctx->srp_ctx.a = NULL;
	ctx->srp_ctx.b = NULL;
	ctx->srp_ctx.v = NULL;
	ctx->srp_ctx.login = NULL;
	ctx->srp_ctx.info = NULL;
	ctx->srp_ctx.strength = SRP_MINIMAL_N;
	ctx->srp_ctx.srp_Mask = 0;
	return (1);
	}

int SSL_SRP_CTX_free(struct ssl_st *s)
	{
	if (s == NULL)
		return 0;
	OPENSSL_free(s->srp_ctx.login);
	BN_free(s->srp_ctx.N);
	BN_free(s->srp_ctx.g);
	BN_free(s->srp_ctx.s);
	BN_free(s->srp_ctx.B);
	BN_free(s->srp_ctx.A);
	BN_free(s->srp_ctx.a);
	BN_free(s->srp_ctx.b);
	BN_free(s->srp_ctx.v);
	s->srp_ctx.TLS_ext_srp_username_callback = NULL;
	s->srp_ctx.SRP_cb_arg = NULL;
	s->srp_ctx.SRP_verify_param_callback = NULL;
	s->srp_ctx.SRP_give_srp_client_pwd_callback = NULL;
	s->srp_ctx.SRP_TLS_ext_missing_srp_client_username_callback = NULL;
	s->srp_ctx.N = NULL;
	s->srp_ctx.g = NULL;
	s->srp_ctx.s = NULL;
	s->srp_ctx.B = NULL;
	s->srp_ctx.A = NULL;
	s->srp_ctx.a = NULL;
	s->srp_ctx.b = NULL;
	s->srp_ctx.v = NULL;
	s->srp_ctx.login = NULL;
	s->srp_ctx.info = NULL;
	s->srp_ctx.strength = SRP_MINIMAL_N;
	s->srp_ctx.srp_Mask = 0;
	return (1);
	}

int SSL_SRP_CTX_init(struct ssl_st *s)
	{
	SSL_CTX *ctx;

	if ((s == NULL) || ((ctx = s->ctx) == NULL))
		return 0;
	s->srp_ctx.SRP_cb_arg = ctx->srp_ctx.SRP_cb_arg;
	/* set client Hello login callback */
	s->srp_ctx.TLS_ext_srp_username_callback = ctx->srp_ctx.TLS_ext_srp_username_callback;
	/* set SRP N/g param callback for verification */
	s->srp_ctx.SRP_verify_param_callback = ctx->srp_ctx.SRP_verify_param_callback;
	/* set SRP client passwd callback */
	s->srp_ctx.SRP_give_srp_client_pwd_callback = ctx->srp_ctx.SRP_give_srp_client_pwd_callback;
	s->srp_ctx.SRP_TLS_ext_missing_srp_client_username_callback = ctx->srp_ctx.SRP_TLS_ext_missing_srp_client_username_callback;

	s->srp_ctx.N = NULL;
	s->srp_ctx.g = NULL;
	s->srp_ctx.s = NULL;
	s->srp_ctx.B = NULL;
	s->srp_ctx.A = NULL;
	s->srp_ctx.a = NULL;
	s->srp_ctx.b = NULL;
	s->srp_ctx.v = NULL;
	s->srp_ctx.login = NULL;
	s->srp_ctx.info = ctx->srp_ctx.info;
	s->srp_ctx.strength = ctx->srp_ctx.strength;

	if (((ctx->srp_ctx.N != NULL) &&
		 ((s->srp_ctx.N = BN_dup(ctx->srp_ctx.N)) == NULL)) ||
		((ctx->srp_ctx.g != NULL) &&
		 ((s->srp_ctx.g = BN_dup(ctx->srp_ctx.g)) == NULL)) ||
		((ctx->srp_ctx.s != NULL) &&
		 ((s->srp_ctx.s = BN_dup(ctx->srp_ctx.s)) == NULL)) ||
		((ctx->srp_ctx.B != NULL) &&
		 ((s->srp_ctx.B = BN_dup(ctx->srp_ctx.B)) == NULL)) ||
		((ctx->srp_ctx.A != NULL) &&
		 ((s->srp_ctx.A = BN_dup(ctx->srp_ctx.A)) == NULL)) ||
		((ctx->srp_ctx.a != NULL) &&
		 ((s->srp_ctx.a = BN_dup(ctx->srp_ctx.a)) == NULL)) ||
		((ctx->srp_ctx.v != NULL) &&
		 ((s->srp_ctx.v = BN_dup(ctx->srp_ctx.v)) == NULL)) ||
		((ctx->srp_ctx.b != NULL) &&
		 ((s->srp_ctx.b = BN_dup(ctx->srp_ctx.b)) == NULL)))
		{
		SSLerr(SSL_F_SSL_SRP_CTX_INIT,ERR_R_BN_LIB);
		goto err;
		}
	if ((ctx->srp_ctx.login != NULL) && 
		((s->srp_ctx.login = BUF_strdup(ctx->srp_ctx.login)) == NULL))
		{
		SSLerr(SSL_F_SSL_SRP_CTX_INIT,ERR_R_INTERNAL_ERROR);
		goto err;
		}
	s->srp_ctx.srp_Mask = ctx->srp_ctx.srp_Mask;

	return (1);
err:
	OPENSSL_free(s->srp_ctx.login);
	BN_free(s->srp_ctx.N);
	BN_free(s->srp_ctx.g);
	BN_free(s->srp_ctx.s);
	BN_free(s->srp_ctx.B);
	BN_free(s->srp_ctx.A);
	BN_free(s->srp_ctx.a);
	BN_free(s->srp_ctx.b);
	BN_free(s->srp_ctx.v);
	return (0);
	}

int SSL_CTX_SRP_CTX_init(struct ssl_ctx_st *ctx)
	{
	if (ctx == NULL)
		return 0;

	ctx->srp_ctx.SRP_cb_arg = NULL;
	/* set client Hello login callback */
	ctx->srp_ctx.TLS_ext_srp_username_callback = NULL;
	/* set SRP N/g param callback for verification */
	ctx->srp_ctx.SRP_verify_param_callback = NULL;
	/* set SRP client passwd callback */
	ctx->srp_ctx.SRP_give_srp_client_pwd_callback = NULL;
	ctx->srp_ctx.SRP_TLS_ext_missing_srp_client_username_callback = NULL;

	ctx->srp_ctx.N = NULL;
	ctx->srp_ctx.g = NULL;
	ctx->srp_ctx.s = NULL;
	ctx->srp_ctx.B = NULL;
	ctx->srp_ctx.A = NULL;
	ctx->srp_ctx.a = NULL;
	ctx->srp_ctx.b = NULL;
	ctx->srp_ctx.v = NULL;
	ctx->srp_ctx.login = NULL;
	ctx->srp_ctx.srp_Mask = 0;
	ctx->srp_ctx.info = NULL;
	ctx->srp_ctx.strength = SRP_MINIMAL_N;

	return (1);
	}

/* server side */
int SSL_srp_server_param_with_username(SSL *s, int *ad)
	{
	unsigned char b[SSL_MAX_MASTER_KEY_LENGTH];
	int al;

	*ad = SSL_AD_UNKNOWN_SRP_USERNAME;
	if ((s->srp_ctx.TLS_ext_srp_username_callback !=NULL) &&
		((al = s->srp_ctx.TLS_ext_srp_username_callback(s, ad, s->srp_ctx.SRP_cb_arg))!=SSL_ERROR_NONE))
			return al;

	*ad = SSL_AD_INTERNAL_ERROR;
	if ((s->srp_ctx.N == NULL) ||
		(s->srp_ctx.g == NULL) ||
		(s->srp_ctx.s == NULL) ||
		(s->srp_ctx.v == NULL))
		return SSL3_AL_FATAL;

	if (RAND_bytes(b, sizeof(b)) <= 0)
		return SSL3_AL_FATAL;
	s->srp_ctx.b = BN_bin2bn(b,sizeof(b),NULL);
	OPENSSL_cleanse(b,sizeof(b));

	/* Calculate:  B = (kv + g^b) % N  */

	return ((s->srp_ctx.B = SRP_Calc_B(s->srp_ctx.b, s->srp_ctx.N, s->srp_ctx.g, s->srp_ctx.v)) != NULL)?
			SSL_ERROR_NONE:SSL3_AL_FATAL;
	}

/* If the server just has the raw password, make up a verifier entry on the fly */
int SSL_set_srp_server_param_pw(SSL *s, const char *user, const char *pass, const char *grp)
	{
	SRP_gN *GN = SRP_get_default_gN(grp);
	if(GN == NULL) return -1;
	s->srp_ctx.N = BN_dup(GN->N);
	s->srp_ctx.g = BN_dup(GN->g);
	if(s->srp_ctx.v != NULL)
		{
		BN_clear_free(s->srp_ctx.v);
		s->srp_ctx.v = NULL;
		}
	if(s->srp_ctx.s != NULL)
		{
		BN_clear_free(s->srp_ctx.s);
		s->srp_ctx.s = NULL;
		}
	if(!SRP_create_verifier_BN(user, pass, &s->srp_ctx.s, &s->srp_ctx.v, GN->N, GN->g)) return -1;

	return 1;
	}

int SSL_set_srp_server_param(SSL *s, const BIGNUM *N, const BIGNUM *g,
			     BIGNUM *sa, BIGNUM *v, char *info)
	{
	if (N!= NULL)
		{
		if (s->srp_ctx.N != NULL)
			{
			if (!BN_copy(s->srp_ctx.N,N))
				{
				BN_free(s->srp_ctx.N);
				s->srp_ctx.N = NULL;
				}
			}
		else
			s->srp_ctx.N = BN_dup(N);
		}
	if (g!= NULL)
		{
		if (s->srp_ctx.g != NULL)
			{
			if (!BN_copy(s->srp_ctx.g,g))
				{
				BN_free(s->srp_ctx.g);
				s->srp_ctx.g = NULL;
				}
			}
		else
			s->srp_ctx.g = BN_dup(g);
		}
	if (sa!= NULL)
		{
		if (s->srp_ctx.s != NULL)
			{
			if (!BN_copy(s->srp_ctx.s,sa))
				{
				BN_free(s->srp_ctx.s);
				s->srp_ctx.s = NULL;
				}
			}
		else
			s->srp_ctx.s = BN_dup(sa);
		}
	if (v!= NULL)
		{
		if (s->srp_ctx.v != NULL)
			{
			if (!BN_copy(s->srp_ctx.v,v))
				{
				BN_free(s->srp_ctx.v);
				s->srp_ctx.v = NULL;
				}
			}
		else
			s->srp_ctx.v = BN_dup(v);
		}
	s->srp_ctx.info = info;

	if (!(s->srp_ctx.N) ||
		!(s->srp_ctx.g) ||
		!(s->srp_ctx.s) ||
		!(s->srp_ctx.v))
		return -1;

	return 1;
	}

int SRP_generate_server_master_secret(SSL *s,unsigned char *master_key)
	{
	BIGNUM *K = NULL, *u = NULL;
	int ret = -1, tmp_len;
	unsigned char *tmp = NULL;

	if (!SRP_Verify_A_mod_N(s->srp_ctx.A,s->srp_ctx.N))
		goto err;
	if (!(u = SRP_Calc_u(s->srp_ctx.A,s->srp_ctx.B,s->srp_ctx.N)))
		goto err;
	if (!(K = SRP_Calc_server_key(s->srp_ctx.A, s->srp_ctx.v, u, s->srp_ctx.b, s->srp_ctx.N)))
		goto err;

	tmp_len = BN_num_bytes(K);
	if ((tmp = OPENSSL_malloc(tmp_len)) == NULL)
		goto err;
	BN_bn2bin(K, tmp);
	ret = s->method->ssl3_enc->generate_master_secret(s,master_key,tmp,tmp_len);
err:
	if (tmp)
		{
		OPENSSL_cleanse(tmp,tmp_len) ;
		OPENSSL_free(tmp);
		}
	BN_clear_free(K);
	BN_clear_free(u);
	return ret;
	}

/* client side */
int SRP_generate_client_master_secret(SSL *s,unsigned char *master_key)
	{
	BIGNUM *x = NULL, *u = NULL, *K = NULL;
	int ret = -1, tmp_len;
	char *passwd = NULL;
	unsigned char *tmp = NULL;

	/* Checks if b % n == 0
	 */
	if (SRP_Verify_B_mod_N(s->srp_ctx.B,s->srp_ctx.N)==0) goto err;
	if (!(u = SRP_Calc_u(s->srp_ctx.A,s->srp_ctx.B,s->srp_ctx.N))) goto err;
	if (s->srp_ctx.SRP_give_srp_client_pwd_callback == NULL) goto err;
	if (!(passwd = s->srp_ctx.SRP_give_srp_client_pwd_callback(s, s->srp_ctx.SRP_cb_arg))) goto err;
	if (!(x = SRP_Calc_x(s->srp_ctx.s,s->srp_ctx.login,passwd))) goto err;
	if (!(K = SRP_Calc_client_key(s->srp_ctx.N, s->srp_ctx.B, s->srp_ctx.g, x, s->srp_ctx.a, u))) goto err;

	tmp_len = BN_num_bytes(K);
	if ((tmp = OPENSSL_malloc(tmp_len)) == NULL) goto err;
	BN_bn2bin(K, tmp);
	ret = s->method->ssl3_enc->generate_master_secret(s,master_key,tmp,tmp_len);
err:
	if (tmp)
		{
		OPENSSL_cleanse(tmp,tmp_len) ;
		OPENSSL_free(tmp);
		}
	BN_clear_free(K);
	BN_clear_free(x);
	if (passwd)
		{
		OPENSSL_cleanse(passwd,strlen(passwd)) ;
		OPENSSL_free(passwd);
		}
	BN_clear_free(u);
	return ret;
	}

int SRP_Calc_A_param(SSL *s)
	{
	unsigned char rnd[SSL_MAX_MASTER_KEY_LENGTH];

	if (BN_num_bits(s->srp_ctx.N) < s->srp_ctx.strength)
		return 0;

	if (s->srp_ctx.SRP_verify_param_callback ==NULL && 
		!SRP_check_known_gN_param(s->srp_ctx.g,s->srp_ctx.N))
		return 0;

	if (RAND_bytes(rnd, sizeof(rnd)) <= 0)
		return 0;
	s->srp_ctx.a = BN_bin2bn(rnd,sizeof(rnd), s->srp_ctx.a);
	OPENSSL_cleanse(rnd,sizeof(rnd));

	if (!(s->srp_ctx.A = SRP_Calc_A(s->srp_ctx.a,s->srp_ctx.N,s->srp_ctx.g)))
		return 0;

	/* We can have a callback to verify SRP param!! */
	if (s->srp_ctx.SRP_verify_param_callback !=NULL) 
		return s->srp_ctx.SRP_verify_param_callback(s,s->srp_ctx.SRP_cb_arg);

	return 1;
	}

int SRP_have_to_put_srp_username(SSL *s)
	{
	if (s->srp_ctx.SRP_TLS_ext_missing_srp_client_username_callback == NULL)
		return 0;
	if ((s->srp_ctx.login = s->srp_ctx.SRP_TLS_ext_missing_srp_client_username_callback(s,s->srp_ctx.SRP_cb_arg)) == NULL)
		return 0;
	s->srp_ctx.srp_Mask|=SSL_kSRP;
	return 1;
	}

BIGNUM *SSL_get_srp_g(SSL *s)
	{
	if (s->srp_ctx.g != NULL)
		return s->srp_ctx.g;
	return s->ctx->srp_ctx.g;
	}

BIGNUM *SSL_get_srp_N(SSL *s)
	{
	if (s->srp_ctx.N != NULL)
		return s->srp_ctx.N;
	return s->ctx->srp_ctx.N;
	}

char *SSL_get_srp_username(SSL *s)
	{
	if (s->srp_ctx.login != NULL)
		return s->srp_ctx.login;
	return s->ctx->srp_ctx.login;
	}

char *SSL_get_srp_userinfo(SSL *s)
	{
	if (s->srp_ctx.info != NULL)
		return s->srp_ctx.info;
	return s->ctx->srp_ctx.info;
	}

#define tls1_ctx_ctrl ssl3_ctx_ctrl
#define tls1_ctx_callback_ctrl ssl3_ctx_callback_ctrl

int SSL_CTX_set_srp_username(SSL_CTX *ctx,char *name)
	{
	return tls1_ctx_ctrl(ctx,SSL_CTRL_SET_TLS_EXT_SRP_USERNAME,0,name);
	}

int SSL_CTX_set_srp_password(SSL_CTX *ctx,char *password)
	{
	return tls1_ctx_ctrl(ctx,SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD,0,password);
	}

int SSL_CTX_set_srp_strength(SSL_CTX *ctx, int strength)
	{
	return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH, strength,
			     NULL);
	}

int SSL_CTX_set_srp_verify_param_callback(SSL_CTX *ctx, int (*cb)(SSL *,void *))
	{
	return tls1_ctx_callback_ctrl(ctx,SSL_CTRL_SET_SRP_VERIFY_PARAM_CB,
				      (void (*)(void))cb);
	}

int SSL_CTX_set_srp_cb_arg(SSL_CTX *ctx, void *arg)
	{
	return tls1_ctx_ctrl(ctx,SSL_CTRL_SET_SRP_ARG,0,arg);
	}

int SSL_CTX_set_srp_username_callback(SSL_CTX *ctx,
				      int (*cb)(SSL *,int *,void *))
	{
	return tls1_ctx_callback_ctrl(ctx,SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB,
				      (void (*)(void))cb);
	}

int SSL_CTX_set_srp_client_pwd_callback(SSL_CTX *ctx, char *(*cb)(SSL *,void *))
	{
	return tls1_ctx_callback_ctrl(ctx,SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB,
				      (void (*)(void))cb);
	}

int SSL_CTX_set_srp_missing_srp_username_callback(SSL_CTX *ctx,
						  char *(*cb)(SSL *,void *))
	{
	return tls1_ctx_callback_ctrl(ctx,
			    SSL_CTRL_SET_TLS_EXT_SRP_MISSING_CLIENT_USERNAME_CB,
				      (void (*)(void))cb);
	}
#endif
