1238384Sjkim/* ssl/tls_srp.c */ 2280304Sjkim/* 3280304Sjkim * Written by Christophe Renou (christophe.renou@edelweb.fr) with the 4280304Sjkim * precious help of Peter Sylvester (peter.sylvester@edelweb.fr) for the 5280304Sjkim * EdelKey project and contributed to the OpenSSL project 2004. 6238384Sjkim */ 7238384Sjkim/* ==================================================================== 8238384Sjkim * Copyright (c) 2004-2011 The OpenSSL Project. All rights reserved. 9238384Sjkim * 10238384Sjkim * Redistribution and use in source and binary forms, with or without 11238384Sjkim * modification, are permitted provided that the following conditions 12238384Sjkim * are met: 13238384Sjkim * 14238384Sjkim * 1. Redistributions of source code must retain the above copyright 15280304Sjkim * notice, this list of conditions and the following disclaimer. 16238384Sjkim * 17238384Sjkim * 2. Redistributions in binary form must reproduce the above copyright 18238384Sjkim * notice, this list of conditions and the following disclaimer in 19238384Sjkim * the documentation and/or other materials provided with the 20238384Sjkim * distribution. 21238384Sjkim * 22238384Sjkim * 3. All advertising materials mentioning features or use of this 23238384Sjkim * software must display the following acknowledgment: 24238384Sjkim * "This product includes software developed by the OpenSSL Project 25238384Sjkim * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 26238384Sjkim * 27238384Sjkim * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 28238384Sjkim * endorse or promote products derived from this software without 29238384Sjkim * prior written permission. For written permission, please contact 30238384Sjkim * licensing@OpenSSL.org. 31238384Sjkim * 32238384Sjkim * 5. Products derived from this software may not be called "OpenSSL" 33238384Sjkim * nor may "OpenSSL" appear in their names without prior written 34238384Sjkim * permission of the OpenSSL Project. 35238384Sjkim * 36238384Sjkim * 6. Redistributions of any form whatsoever must retain the following 37238384Sjkim * acknowledgment: 38238384Sjkim * "This product includes software developed by the OpenSSL Project 39238384Sjkim * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 40238384Sjkim * 41238384Sjkim * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 42238384Sjkim * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43238384Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 44238384Sjkim * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 45238384Sjkim * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 46238384Sjkim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 47238384Sjkim * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 48238384Sjkim * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 49238384Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 50238384Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 51238384Sjkim * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 52238384Sjkim * OF THE POSSIBILITY OF SUCH DAMAGE. 53238384Sjkim * ==================================================================== 54238384Sjkim * 55238384Sjkim * This product includes cryptographic software written by Eric Young 56238384Sjkim * (eay@cryptsoft.com). This product includes software written by Tim 57238384Sjkim * Hudson (tjh@cryptsoft.com). 58238384Sjkim * 59238384Sjkim */ 60238384Sjkim#include "ssl_locl.h" 61238384Sjkim#ifndef OPENSSL_NO_SRP 62238384Sjkim 63280304Sjkim# include <openssl/rand.h> 64280304Sjkim# include <openssl/srp.h> 65280304Sjkim# include <openssl/err.h> 66238384Sjkim 67238384Sjkimint SSL_CTX_SRP_CTX_free(struct ssl_ctx_st *ctx) 68280304Sjkim{ 69280304Sjkim if (ctx == NULL) 70280304Sjkim return 0; 71280304Sjkim OPENSSL_free(ctx->srp_ctx.login); 72280304Sjkim BN_free(ctx->srp_ctx.N); 73280304Sjkim BN_free(ctx->srp_ctx.g); 74280304Sjkim BN_free(ctx->srp_ctx.s); 75280304Sjkim BN_free(ctx->srp_ctx.B); 76280304Sjkim BN_free(ctx->srp_ctx.A); 77280304Sjkim BN_free(ctx->srp_ctx.a); 78280304Sjkim BN_free(ctx->srp_ctx.b); 79280304Sjkim BN_free(ctx->srp_ctx.v); 80280304Sjkim ctx->srp_ctx.TLS_ext_srp_username_callback = NULL; 81280304Sjkim ctx->srp_ctx.SRP_cb_arg = NULL; 82280304Sjkim ctx->srp_ctx.SRP_verify_param_callback = NULL; 83280304Sjkim ctx->srp_ctx.SRP_give_srp_client_pwd_callback = NULL; 84280304Sjkim ctx->srp_ctx.N = NULL; 85280304Sjkim ctx->srp_ctx.g = NULL; 86280304Sjkim ctx->srp_ctx.s = NULL; 87280304Sjkim ctx->srp_ctx.B = NULL; 88280304Sjkim ctx->srp_ctx.A = NULL; 89280304Sjkim ctx->srp_ctx.a = NULL; 90280304Sjkim ctx->srp_ctx.b = NULL; 91280304Sjkim ctx->srp_ctx.v = NULL; 92280304Sjkim ctx->srp_ctx.login = NULL; 93280304Sjkim ctx->srp_ctx.info = NULL; 94280304Sjkim ctx->srp_ctx.strength = SRP_MINIMAL_N; 95280304Sjkim ctx->srp_ctx.srp_Mask = 0; 96280304Sjkim return (1); 97280304Sjkim} 98238384Sjkim 99238384Sjkimint SSL_SRP_CTX_free(struct ssl_st *s) 100280304Sjkim{ 101280304Sjkim if (s == NULL) 102280304Sjkim return 0; 103280304Sjkim OPENSSL_free(s->srp_ctx.login); 104280304Sjkim BN_free(s->srp_ctx.N); 105280304Sjkim BN_free(s->srp_ctx.g); 106280304Sjkim BN_free(s->srp_ctx.s); 107280304Sjkim BN_free(s->srp_ctx.B); 108280304Sjkim BN_free(s->srp_ctx.A); 109280304Sjkim BN_free(s->srp_ctx.a); 110280304Sjkim BN_free(s->srp_ctx.b); 111280304Sjkim BN_free(s->srp_ctx.v); 112280304Sjkim s->srp_ctx.TLS_ext_srp_username_callback = NULL; 113280304Sjkim s->srp_ctx.SRP_cb_arg = NULL; 114280304Sjkim s->srp_ctx.SRP_verify_param_callback = NULL; 115280304Sjkim s->srp_ctx.SRP_give_srp_client_pwd_callback = NULL; 116280304Sjkim s->srp_ctx.N = NULL; 117280304Sjkim s->srp_ctx.g = NULL; 118280304Sjkim s->srp_ctx.s = NULL; 119280304Sjkim s->srp_ctx.B = NULL; 120280304Sjkim s->srp_ctx.A = NULL; 121280304Sjkim s->srp_ctx.a = NULL; 122280304Sjkim s->srp_ctx.b = NULL; 123280304Sjkim s->srp_ctx.v = NULL; 124280304Sjkim s->srp_ctx.login = NULL; 125280304Sjkim s->srp_ctx.info = NULL; 126280304Sjkim s->srp_ctx.strength = SRP_MINIMAL_N; 127280304Sjkim s->srp_ctx.srp_Mask = 0; 128280304Sjkim return (1); 129280304Sjkim} 130238384Sjkim 131238384Sjkimint SSL_SRP_CTX_init(struct ssl_st *s) 132280304Sjkim{ 133280304Sjkim SSL_CTX *ctx; 134238384Sjkim 135280304Sjkim if ((s == NULL) || ((ctx = s->ctx) == NULL)) 136280304Sjkim return 0; 137280304Sjkim s->srp_ctx.SRP_cb_arg = ctx->srp_ctx.SRP_cb_arg; 138280304Sjkim /* set client Hello login callback */ 139280304Sjkim s->srp_ctx.TLS_ext_srp_username_callback = 140280304Sjkim ctx->srp_ctx.TLS_ext_srp_username_callback; 141280304Sjkim /* set SRP N/g param callback for verification */ 142280304Sjkim s->srp_ctx.SRP_verify_param_callback = 143280304Sjkim ctx->srp_ctx.SRP_verify_param_callback; 144280304Sjkim /* set SRP client passwd callback */ 145280304Sjkim s->srp_ctx.SRP_give_srp_client_pwd_callback = 146280304Sjkim ctx->srp_ctx.SRP_give_srp_client_pwd_callback; 147238384Sjkim 148280304Sjkim s->srp_ctx.N = NULL; 149280304Sjkim s->srp_ctx.g = NULL; 150280304Sjkim s->srp_ctx.s = NULL; 151280304Sjkim s->srp_ctx.B = NULL; 152280304Sjkim s->srp_ctx.A = NULL; 153280304Sjkim s->srp_ctx.a = NULL; 154280304Sjkim s->srp_ctx.b = NULL; 155280304Sjkim s->srp_ctx.v = NULL; 156280304Sjkim s->srp_ctx.login = NULL; 157280304Sjkim s->srp_ctx.info = ctx->srp_ctx.info; 158280304Sjkim s->srp_ctx.strength = ctx->srp_ctx.strength; 159238384Sjkim 160280304Sjkim if (((ctx->srp_ctx.N != NULL) && 161280304Sjkim ((s->srp_ctx.N = BN_dup(ctx->srp_ctx.N)) == NULL)) || 162280304Sjkim ((ctx->srp_ctx.g != NULL) && 163280304Sjkim ((s->srp_ctx.g = BN_dup(ctx->srp_ctx.g)) == NULL)) || 164280304Sjkim ((ctx->srp_ctx.s != NULL) && 165280304Sjkim ((s->srp_ctx.s = BN_dup(ctx->srp_ctx.s)) == NULL)) || 166280304Sjkim ((ctx->srp_ctx.B != NULL) && 167280304Sjkim ((s->srp_ctx.B = BN_dup(ctx->srp_ctx.B)) == NULL)) || 168280304Sjkim ((ctx->srp_ctx.A != NULL) && 169280304Sjkim ((s->srp_ctx.A = BN_dup(ctx->srp_ctx.A)) == NULL)) || 170280304Sjkim ((ctx->srp_ctx.a != NULL) && 171280304Sjkim ((s->srp_ctx.a = BN_dup(ctx->srp_ctx.a)) == NULL)) || 172280304Sjkim ((ctx->srp_ctx.v != NULL) && 173280304Sjkim ((s->srp_ctx.v = BN_dup(ctx->srp_ctx.v)) == NULL)) || 174280304Sjkim ((ctx->srp_ctx.b != NULL) && 175280304Sjkim ((s->srp_ctx.b = BN_dup(ctx->srp_ctx.b)) == NULL))) { 176280304Sjkim SSLerr(SSL_F_SSL_SRP_CTX_INIT, ERR_R_BN_LIB); 177280304Sjkim goto err; 178280304Sjkim } 179280304Sjkim if ((ctx->srp_ctx.login != NULL) && 180280304Sjkim ((s->srp_ctx.login = BUF_strdup(ctx->srp_ctx.login)) == NULL)) { 181280304Sjkim SSLerr(SSL_F_SSL_SRP_CTX_INIT, ERR_R_INTERNAL_ERROR); 182280304Sjkim goto err; 183280304Sjkim } 184280304Sjkim s->srp_ctx.srp_Mask = ctx->srp_ctx.srp_Mask; 185238384Sjkim 186280304Sjkim return (1); 187280304Sjkim err: 188280304Sjkim OPENSSL_free(s->srp_ctx.login); 189280304Sjkim BN_free(s->srp_ctx.N); 190280304Sjkim BN_free(s->srp_ctx.g); 191280304Sjkim BN_free(s->srp_ctx.s); 192280304Sjkim BN_free(s->srp_ctx.B); 193280304Sjkim BN_free(s->srp_ctx.A); 194280304Sjkim BN_free(s->srp_ctx.a); 195280304Sjkim BN_free(s->srp_ctx.b); 196280304Sjkim BN_free(s->srp_ctx.v); 197280304Sjkim return (0); 198280304Sjkim} 199238384Sjkim 200238384Sjkimint SSL_CTX_SRP_CTX_init(struct ssl_ctx_st *ctx) 201280304Sjkim{ 202280304Sjkim if (ctx == NULL) 203280304Sjkim return 0; 204238384Sjkim 205280304Sjkim ctx->srp_ctx.SRP_cb_arg = NULL; 206280304Sjkim /* set client Hello login callback */ 207280304Sjkim ctx->srp_ctx.TLS_ext_srp_username_callback = NULL; 208280304Sjkim /* set SRP N/g param callback for verification */ 209280304Sjkim ctx->srp_ctx.SRP_verify_param_callback = NULL; 210280304Sjkim /* set SRP client passwd callback */ 211280304Sjkim ctx->srp_ctx.SRP_give_srp_client_pwd_callback = NULL; 212238384Sjkim 213280304Sjkim ctx->srp_ctx.N = NULL; 214280304Sjkim ctx->srp_ctx.g = NULL; 215280304Sjkim ctx->srp_ctx.s = NULL; 216280304Sjkim ctx->srp_ctx.B = NULL; 217280304Sjkim ctx->srp_ctx.A = NULL; 218280304Sjkim ctx->srp_ctx.a = NULL; 219280304Sjkim ctx->srp_ctx.b = NULL; 220280304Sjkim ctx->srp_ctx.v = NULL; 221280304Sjkim ctx->srp_ctx.login = NULL; 222280304Sjkim ctx->srp_ctx.srp_Mask = 0; 223280304Sjkim ctx->srp_ctx.info = NULL; 224280304Sjkim ctx->srp_ctx.strength = SRP_MINIMAL_N; 225238384Sjkim 226280304Sjkim return (1); 227280304Sjkim} 228238384Sjkim 229238384Sjkim/* server side */ 230238384Sjkimint SSL_srp_server_param_with_username(SSL *s, int *ad) 231280304Sjkim{ 232280304Sjkim unsigned char b[SSL_MAX_MASTER_KEY_LENGTH]; 233280304Sjkim int al; 234238384Sjkim 235280304Sjkim *ad = SSL_AD_UNKNOWN_PSK_IDENTITY; 236280304Sjkim if ((s->srp_ctx.TLS_ext_srp_username_callback != NULL) && 237280304Sjkim ((al = 238280304Sjkim s->srp_ctx.TLS_ext_srp_username_callback(s, ad, 239280304Sjkim s->srp_ctx.SRP_cb_arg)) != 240280304Sjkim SSL_ERROR_NONE)) 241280304Sjkim return al; 242238384Sjkim 243280304Sjkim *ad = SSL_AD_INTERNAL_ERROR; 244280304Sjkim if ((s->srp_ctx.N == NULL) || 245280304Sjkim (s->srp_ctx.g == NULL) || 246280304Sjkim (s->srp_ctx.s == NULL) || (s->srp_ctx.v == NULL)) 247280304Sjkim return SSL3_AL_FATAL; 248238384Sjkim 249280304Sjkim if (RAND_bytes(b, sizeof(b)) <= 0) 250280304Sjkim return SSL3_AL_FATAL; 251280304Sjkim s->srp_ctx.b = BN_bin2bn(b, sizeof(b), NULL); 252280304Sjkim OPENSSL_cleanse(b, sizeof(b)); 253238384Sjkim 254280304Sjkim /* Calculate: B = (kv + g^b) % N */ 255238384Sjkim 256280304Sjkim return ((s->srp_ctx.B = 257280304Sjkim SRP_Calc_B(s->srp_ctx.b, s->srp_ctx.N, s->srp_ctx.g, 258280304Sjkim s->srp_ctx.v)) != 259280304Sjkim NULL) ? SSL_ERROR_NONE : SSL3_AL_FATAL; 260280304Sjkim} 261238384Sjkim 262280304Sjkim/* 263280304Sjkim * If the server just has the raw password, make up a verifier entry on the 264280304Sjkim * fly 265280304Sjkim */ 266280304Sjkimint SSL_set_srp_server_param_pw(SSL *s, const char *user, const char *pass, 267280304Sjkim const char *grp) 268280304Sjkim{ 269280304Sjkim SRP_gN *GN = SRP_get_default_gN(grp); 270280304Sjkim if (GN == NULL) 271280304Sjkim return -1; 272280304Sjkim s->srp_ctx.N = BN_dup(GN->N); 273280304Sjkim s->srp_ctx.g = BN_dup(GN->g); 274280304Sjkim if (s->srp_ctx.v != NULL) { 275280304Sjkim BN_clear_free(s->srp_ctx.v); 276280304Sjkim s->srp_ctx.v = NULL; 277280304Sjkim } 278280304Sjkim if (s->srp_ctx.s != NULL) { 279280304Sjkim BN_clear_free(s->srp_ctx.s); 280280304Sjkim s->srp_ctx.s = NULL; 281280304Sjkim } 282280304Sjkim if (!SRP_create_verifier_BN 283280304Sjkim (user, pass, &s->srp_ctx.s, &s->srp_ctx.v, GN->N, GN->g)) 284280304Sjkim return -1; 285238384Sjkim 286280304Sjkim return 1; 287280304Sjkim} 288238384Sjkim 289238384Sjkimint SSL_set_srp_server_param(SSL *s, const BIGNUM *N, const BIGNUM *g, 290280304Sjkim BIGNUM *sa, BIGNUM *v, char *info) 291280304Sjkim{ 292280304Sjkim if (N != NULL) { 293280304Sjkim if (s->srp_ctx.N != NULL) { 294280304Sjkim if (!BN_copy(s->srp_ctx.N, N)) { 295280304Sjkim BN_free(s->srp_ctx.N); 296280304Sjkim s->srp_ctx.N = NULL; 297280304Sjkim } 298280304Sjkim } else 299280304Sjkim s->srp_ctx.N = BN_dup(N); 300280304Sjkim } 301280304Sjkim if (g != NULL) { 302280304Sjkim if (s->srp_ctx.g != NULL) { 303280304Sjkim if (!BN_copy(s->srp_ctx.g, g)) { 304280304Sjkim BN_free(s->srp_ctx.g); 305280304Sjkim s->srp_ctx.g = NULL; 306280304Sjkim } 307280304Sjkim } else 308280304Sjkim s->srp_ctx.g = BN_dup(g); 309280304Sjkim } 310280304Sjkim if (sa != NULL) { 311280304Sjkim if (s->srp_ctx.s != NULL) { 312280304Sjkim if (!BN_copy(s->srp_ctx.s, sa)) { 313280304Sjkim BN_free(s->srp_ctx.s); 314280304Sjkim s->srp_ctx.s = NULL; 315280304Sjkim } 316280304Sjkim } else 317280304Sjkim s->srp_ctx.s = BN_dup(sa); 318280304Sjkim } 319280304Sjkim if (v != NULL) { 320280304Sjkim if (s->srp_ctx.v != NULL) { 321280304Sjkim if (!BN_copy(s->srp_ctx.v, v)) { 322280304Sjkim BN_free(s->srp_ctx.v); 323280304Sjkim s->srp_ctx.v = NULL; 324280304Sjkim } 325280304Sjkim } else 326280304Sjkim s->srp_ctx.v = BN_dup(v); 327280304Sjkim } 328280304Sjkim s->srp_ctx.info = info; 329238384Sjkim 330280304Sjkim if (!(s->srp_ctx.N) || 331280304Sjkim !(s->srp_ctx.g) || !(s->srp_ctx.s) || !(s->srp_ctx.v)) 332280304Sjkim return -1; 333238384Sjkim 334280304Sjkim return 1; 335280304Sjkim} 336238384Sjkim 337280304Sjkimint SRP_generate_server_master_secret(SSL *s, unsigned char *master_key) 338280304Sjkim{ 339280304Sjkim BIGNUM *K = NULL, *u = NULL; 340280304Sjkim int ret = -1, tmp_len; 341280304Sjkim unsigned char *tmp = NULL; 342238384Sjkim 343280304Sjkim if (!SRP_Verify_A_mod_N(s->srp_ctx.A, s->srp_ctx.N)) 344280304Sjkim goto err; 345280304Sjkim if (!(u = SRP_Calc_u(s->srp_ctx.A, s->srp_ctx.B, s->srp_ctx.N))) 346280304Sjkim goto err; 347280304Sjkim if (! 348280304Sjkim (K = 349280304Sjkim SRP_Calc_server_key(s->srp_ctx.A, s->srp_ctx.v, u, s->srp_ctx.b, 350280304Sjkim s->srp_ctx.N))) 351280304Sjkim goto err; 352238384Sjkim 353280304Sjkim tmp_len = BN_num_bytes(K); 354280304Sjkim if ((tmp = OPENSSL_malloc(tmp_len)) == NULL) 355280304Sjkim goto err; 356280304Sjkim BN_bn2bin(K, tmp); 357280304Sjkim ret = 358280304Sjkim s->method->ssl3_enc->generate_master_secret(s, master_key, tmp, 359280304Sjkim tmp_len); 360280304Sjkim err: 361280304Sjkim if (tmp) { 362280304Sjkim OPENSSL_cleanse(tmp, tmp_len); 363280304Sjkim OPENSSL_free(tmp); 364280304Sjkim } 365280304Sjkim BN_clear_free(K); 366280304Sjkim BN_clear_free(u); 367280304Sjkim return ret; 368280304Sjkim} 369238384Sjkim 370238384Sjkim/* client side */ 371280304Sjkimint SRP_generate_client_master_secret(SSL *s, unsigned char *master_key) 372280304Sjkim{ 373280304Sjkim BIGNUM *x = NULL, *u = NULL, *K = NULL; 374280304Sjkim int ret = -1, tmp_len; 375280304Sjkim char *passwd = NULL; 376280304Sjkim unsigned char *tmp = NULL; 377238384Sjkim 378280304Sjkim /* 379280304Sjkim * Checks if b % n == 0 380280304Sjkim */ 381280304Sjkim if (SRP_Verify_B_mod_N(s->srp_ctx.B, s->srp_ctx.N) == 0) 382280304Sjkim goto err; 383280304Sjkim if (!(u = SRP_Calc_u(s->srp_ctx.A, s->srp_ctx.B, s->srp_ctx.N))) 384280304Sjkim goto err; 385280304Sjkim if (s->srp_ctx.SRP_give_srp_client_pwd_callback == NULL) 386280304Sjkim goto err; 387280304Sjkim if (! 388280304Sjkim (passwd = 389280304Sjkim s->srp_ctx.SRP_give_srp_client_pwd_callback(s, 390280304Sjkim s->srp_ctx.SRP_cb_arg))) 391280304Sjkim goto err; 392280304Sjkim if (!(x = SRP_Calc_x(s->srp_ctx.s, s->srp_ctx.login, passwd))) 393280304Sjkim goto err; 394280304Sjkim if (! 395280304Sjkim (K = 396280304Sjkim SRP_Calc_client_key(s->srp_ctx.N, s->srp_ctx.B, s->srp_ctx.g, x, 397280304Sjkim s->srp_ctx.a, u))) 398280304Sjkim goto err; 399238384Sjkim 400280304Sjkim tmp_len = BN_num_bytes(K); 401280304Sjkim if ((tmp = OPENSSL_malloc(tmp_len)) == NULL) 402280304Sjkim goto err; 403280304Sjkim BN_bn2bin(K, tmp); 404280304Sjkim ret = 405280304Sjkim s->method->ssl3_enc->generate_master_secret(s, master_key, tmp, 406280304Sjkim tmp_len); 407280304Sjkim err: 408280304Sjkim if (tmp) { 409280304Sjkim OPENSSL_cleanse(tmp, tmp_len); 410280304Sjkim OPENSSL_free(tmp); 411280304Sjkim } 412280304Sjkim BN_clear_free(K); 413280304Sjkim BN_clear_free(x); 414280304Sjkim if (passwd) { 415280304Sjkim OPENSSL_cleanse(passwd, strlen(passwd)); 416280304Sjkim OPENSSL_free(passwd); 417280304Sjkim } 418280304Sjkim BN_clear_free(u); 419280304Sjkim return ret; 420280304Sjkim} 421238384Sjkim 422269686Sjkimint srp_verify_server_param(SSL *s, int *al) 423280304Sjkim{ 424280304Sjkim SRP_CTX *srp = &s->srp_ctx; 425280304Sjkim /* 426280304Sjkim * Sanity check parameters: we can quickly check B % N == 0 by checking B 427280304Sjkim * != 0 since B < N 428280304Sjkim */ 429280304Sjkim if (BN_ucmp(srp->g, srp->N) >= 0 || BN_ucmp(srp->B, srp->N) >= 0 430280304Sjkim || BN_is_zero(srp->B)) { 431280304Sjkim *al = SSL3_AD_ILLEGAL_PARAMETER; 432280304Sjkim return 0; 433280304Sjkim } 434269686Sjkim 435280304Sjkim if (BN_num_bits(srp->N) < srp->strength) { 436280304Sjkim *al = TLS1_AD_INSUFFICIENT_SECURITY; 437280304Sjkim return 0; 438280304Sjkim } 439269686Sjkim 440280304Sjkim if (srp->SRP_verify_param_callback) { 441280304Sjkim if (srp->SRP_verify_param_callback(s, srp->SRP_cb_arg) <= 0) { 442280304Sjkim *al = TLS1_AD_INSUFFICIENT_SECURITY; 443280304Sjkim return 0; 444280304Sjkim } 445280304Sjkim } else if (!SRP_check_known_gN_param(srp->g, srp->N)) { 446280304Sjkim *al = TLS1_AD_INSUFFICIENT_SECURITY; 447280304Sjkim return 0; 448280304Sjkim } 449269686Sjkim 450280304Sjkim return 1; 451280304Sjkim} 452269686Sjkim 453238384Sjkimint SRP_Calc_A_param(SSL *s) 454280304Sjkim{ 455280304Sjkim unsigned char rnd[SSL_MAX_MASTER_KEY_LENGTH]; 456238384Sjkim 457284285Sjkim if (RAND_bytes(rnd, sizeof(rnd)) <= 0) 458284285Sjkim return -1; 459280304Sjkim s->srp_ctx.a = BN_bin2bn(rnd, sizeof(rnd), s->srp_ctx.a); 460280304Sjkim OPENSSL_cleanse(rnd, sizeof(rnd)); 461238384Sjkim 462280304Sjkim if (! 463280304Sjkim (s->srp_ctx.A = SRP_Calc_A(s->srp_ctx.a, s->srp_ctx.N, s->srp_ctx.g))) 464280304Sjkim return -1; 465238384Sjkim 466280304Sjkim return 1; 467280304Sjkim} 468238384Sjkim 469238384SjkimBIGNUM *SSL_get_srp_g(SSL *s) 470280304Sjkim{ 471280304Sjkim if (s->srp_ctx.g != NULL) 472280304Sjkim return s->srp_ctx.g; 473280304Sjkim return s->ctx->srp_ctx.g; 474280304Sjkim} 475238384Sjkim 476238384SjkimBIGNUM *SSL_get_srp_N(SSL *s) 477280304Sjkim{ 478280304Sjkim if (s->srp_ctx.N != NULL) 479280304Sjkim return s->srp_ctx.N; 480280304Sjkim return s->ctx->srp_ctx.N; 481280304Sjkim} 482238384Sjkim 483238384Sjkimchar *SSL_get_srp_username(SSL *s) 484280304Sjkim{ 485280304Sjkim if (s->srp_ctx.login != NULL) 486280304Sjkim return s->srp_ctx.login; 487280304Sjkim return s->ctx->srp_ctx.login; 488280304Sjkim} 489238384Sjkim 490238384Sjkimchar *SSL_get_srp_userinfo(SSL *s) 491280304Sjkim{ 492280304Sjkim if (s->srp_ctx.info != NULL) 493280304Sjkim return s->srp_ctx.info; 494280304Sjkim return s->ctx->srp_ctx.info; 495280304Sjkim} 496238384Sjkim 497280304Sjkim# define tls1_ctx_ctrl ssl3_ctx_ctrl 498280304Sjkim# define tls1_ctx_callback_ctrl ssl3_ctx_callback_ctrl 499238384Sjkim 500280304Sjkimint SSL_CTX_set_srp_username(SSL_CTX *ctx, char *name) 501280304Sjkim{ 502280304Sjkim return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_USERNAME, 0, name); 503280304Sjkim} 504238384Sjkim 505280304Sjkimint SSL_CTX_set_srp_password(SSL_CTX *ctx, char *password) 506280304Sjkim{ 507280304Sjkim return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD, 0, password); 508280304Sjkim} 509238384Sjkim 510238384Sjkimint SSL_CTX_set_srp_strength(SSL_CTX *ctx, int strength) 511280304Sjkim{ 512280304Sjkim return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH, strength, 513280304Sjkim NULL); 514280304Sjkim} 515238384Sjkim 516280304Sjkimint SSL_CTX_set_srp_verify_param_callback(SSL_CTX *ctx, 517280304Sjkim int (*cb) (SSL *, void *)) 518280304Sjkim{ 519280304Sjkim return tls1_ctx_callback_ctrl(ctx, SSL_CTRL_SET_SRP_VERIFY_PARAM_CB, 520280304Sjkim (void (*)(void))cb); 521280304Sjkim} 522238384Sjkim 523238384Sjkimint SSL_CTX_set_srp_cb_arg(SSL_CTX *ctx, void *arg) 524280304Sjkim{ 525280304Sjkim return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_SRP_ARG, 0, arg); 526280304Sjkim} 527238384Sjkim 528238384Sjkimint SSL_CTX_set_srp_username_callback(SSL_CTX *ctx, 529280304Sjkim int (*cb) (SSL *, int *, void *)) 530280304Sjkim{ 531280304Sjkim return tls1_ctx_callback_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB, 532280304Sjkim (void (*)(void))cb); 533280304Sjkim} 534238384Sjkim 535280304Sjkimint SSL_CTX_set_srp_client_pwd_callback(SSL_CTX *ctx, 536280304Sjkim char *(*cb) (SSL *, void *)) 537280304Sjkim{ 538280304Sjkim return tls1_ctx_callback_ctrl(ctx, SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB, 539280304Sjkim (void (*)(void))cb); 540280304Sjkim} 541238384Sjkim 542238384Sjkim#endif 543