1 /* ssl/tls_srp.c */ 2 /* 3 * Written by Christophe Renou (christophe.renou@edelweb.fr) with the 4 * precious help of Peter Sylvester (peter.sylvester@edelweb.fr) for the 5 * EdelKey project and contributed to the OpenSSL project 2004. 6 */ 7 /* ==================================================================== 8 * Copyright (c) 2004-2011 The OpenSSL Project. All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in 19 * the documentation and/or other materials provided with the 20 * distribution. 21 * 22 * 3. All advertising materials mentioning features or use of this 23 * software must display the following acknowledgment: 24 * "This product includes software developed by the OpenSSL Project 25 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 26 * 27 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 28 * endorse or promote products derived from this software without 29 * prior written permission. For written permission, please contact 30 * licensing@OpenSSL.org. 31 * 32 * 5. Products derived from this software may not be called "OpenSSL" 33 * nor may "OpenSSL" appear in their names without prior written 34 * permission of the OpenSSL Project. 35 * 36 * 6. Redistributions of any form whatsoever must retain the following 37 * acknowledgment: 38 * "This product includes software developed by the OpenSSL Project 39 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 40 * 41 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 42 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 44 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 45 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 46 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 47 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 48 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 49 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 50 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 51 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 52 * OF THE POSSIBILITY OF SUCH DAMAGE. 53 * ==================================================================== 54 * 55 * This product includes cryptographic software written by Eric Young 56 * (eay@cryptsoft.com). This product includes software written by Tim 57 * Hudson (tjh@cryptsoft.com). 58 * 59 */ 60 #include "ssl_locl.h" 61 #ifndef OPENSSL_NO_SRP 62 63 # include <openssl/rand.h> 64 # include <openssl/srp.h> 65 # include <openssl/err.h> 66 67 int SSL_CTX_SRP_CTX_free(struct ssl_ctx_st *ctx) 68 { 69 if (ctx == NULL) 70 return 0; 71 OPENSSL_free(ctx->srp_ctx.login); 72 BN_free(ctx->srp_ctx.N); 73 BN_free(ctx->srp_ctx.g); 74 BN_free(ctx->srp_ctx.s); 75 BN_free(ctx->srp_ctx.B); 76 BN_free(ctx->srp_ctx.A); 77 BN_free(ctx->srp_ctx.a); 78 BN_free(ctx->srp_ctx.b); 79 BN_free(ctx->srp_ctx.v); 80 ctx->srp_ctx.TLS_ext_srp_username_callback = NULL; 81 ctx->srp_ctx.SRP_cb_arg = NULL; 82 ctx->srp_ctx.SRP_verify_param_callback = NULL; 83 ctx->srp_ctx.SRP_give_srp_client_pwd_callback = NULL; 84 ctx->srp_ctx.N = NULL; 85 ctx->srp_ctx.g = NULL; 86 ctx->srp_ctx.s = NULL; 87 ctx->srp_ctx.B = NULL; 88 ctx->srp_ctx.A = NULL; 89 ctx->srp_ctx.a = NULL; 90 ctx->srp_ctx.b = NULL; 91 ctx->srp_ctx.v = NULL; 92 ctx->srp_ctx.login = NULL; 93 ctx->srp_ctx.info = NULL; 94 ctx->srp_ctx.strength = SRP_MINIMAL_N; 95 ctx->srp_ctx.srp_Mask = 0; 96 return (1); 97 } 98 99 int SSL_SRP_CTX_free(struct ssl_st *s) 100 { 101 if (s == NULL) 102 return 0; 103 OPENSSL_free(s->srp_ctx.login); 104 BN_free(s->srp_ctx.N); 105 BN_free(s->srp_ctx.g); 106 BN_free(s->srp_ctx.s); 107 BN_free(s->srp_ctx.B); 108 BN_free(s->srp_ctx.A); 109 BN_free(s->srp_ctx.a); 110 BN_free(s->srp_ctx.b); 111 BN_free(s->srp_ctx.v); 112 s->srp_ctx.TLS_ext_srp_username_callback = NULL; 113 s->srp_ctx.SRP_cb_arg = NULL; 114 s->srp_ctx.SRP_verify_param_callback = NULL; 115 s->srp_ctx.SRP_give_srp_client_pwd_callback = NULL; 116 s->srp_ctx.N = NULL; 117 s->srp_ctx.g = NULL; 118 s->srp_ctx.s = NULL; 119 s->srp_ctx.B = NULL; 120 s->srp_ctx.A = NULL; 121 s->srp_ctx.a = NULL; 122 s->srp_ctx.b = NULL; 123 s->srp_ctx.v = NULL; 124 s->srp_ctx.login = NULL; 125 s->srp_ctx.info = NULL; 126 s->srp_ctx.strength = SRP_MINIMAL_N; 127 s->srp_ctx.srp_Mask = 0; 128 return (1); 129 } 130 131 int SSL_SRP_CTX_init(struct ssl_st *s) 132 { 133 SSL_CTX *ctx; 134 135 if ((s == NULL) || ((ctx = s->ctx) == NULL)) 136 return 0; 137 s->srp_ctx.SRP_cb_arg = ctx->srp_ctx.SRP_cb_arg; 138 /* set client Hello login callback */ 139 s->srp_ctx.TLS_ext_srp_username_callback = 140 ctx->srp_ctx.TLS_ext_srp_username_callback; 141 /* set SRP N/g param callback for verification */ 142 s->srp_ctx.SRP_verify_param_callback = 143 ctx->srp_ctx.SRP_verify_param_callback; 144 /* set SRP client passwd callback */ 145 s->srp_ctx.SRP_give_srp_client_pwd_callback = 146 ctx->srp_ctx.SRP_give_srp_client_pwd_callback; 147 148 s->srp_ctx.N = NULL; 149 s->srp_ctx.g = NULL; 150 s->srp_ctx.s = NULL; 151 s->srp_ctx.B = NULL; 152 s->srp_ctx.A = NULL; 153 s->srp_ctx.a = NULL; 154 s->srp_ctx.b = NULL; 155 s->srp_ctx.v = NULL; 156 s->srp_ctx.login = NULL; 157 s->srp_ctx.info = ctx->srp_ctx.info; 158 s->srp_ctx.strength = ctx->srp_ctx.strength; 159 160 if (((ctx->srp_ctx.N != NULL) && 161 ((s->srp_ctx.N = BN_dup(ctx->srp_ctx.N)) == NULL)) || 162 ((ctx->srp_ctx.g != NULL) && 163 ((s->srp_ctx.g = BN_dup(ctx->srp_ctx.g)) == NULL)) || 164 ((ctx->srp_ctx.s != NULL) && 165 ((s->srp_ctx.s = BN_dup(ctx->srp_ctx.s)) == NULL)) || 166 ((ctx->srp_ctx.B != NULL) && 167 ((s->srp_ctx.B = BN_dup(ctx->srp_ctx.B)) == NULL)) || 168 ((ctx->srp_ctx.A != NULL) && 169 ((s->srp_ctx.A = BN_dup(ctx->srp_ctx.A)) == NULL)) || 170 ((ctx->srp_ctx.a != NULL) && 171 ((s->srp_ctx.a = BN_dup(ctx->srp_ctx.a)) == NULL)) || 172 ((ctx->srp_ctx.v != NULL) && 173 ((s->srp_ctx.v = BN_dup(ctx->srp_ctx.v)) == NULL)) || 174 ((ctx->srp_ctx.b != NULL) && 175 ((s->srp_ctx.b = BN_dup(ctx->srp_ctx.b)) == NULL))) { 176 SSLerr(SSL_F_SSL_SRP_CTX_INIT, ERR_R_BN_LIB); 177 goto err; 178 } 179 if ((ctx->srp_ctx.login != NULL) && 180 ((s->srp_ctx.login = BUF_strdup(ctx->srp_ctx.login)) == NULL)) { 181 SSLerr(SSL_F_SSL_SRP_CTX_INIT, ERR_R_INTERNAL_ERROR); 182 goto err; 183 } 184 s->srp_ctx.srp_Mask = ctx->srp_ctx.srp_Mask; 185 186 return (1); 187 err: 188 OPENSSL_free(s->srp_ctx.login); 189 BN_free(s->srp_ctx.N); 190 BN_free(s->srp_ctx.g); 191 BN_free(s->srp_ctx.s); 192 BN_free(s->srp_ctx.B); 193 BN_free(s->srp_ctx.A); 194 BN_free(s->srp_ctx.a); 195 BN_free(s->srp_ctx.b); 196 BN_free(s->srp_ctx.v); 197 return (0); 198 } 199 200 int SSL_CTX_SRP_CTX_init(struct ssl_ctx_st *ctx) 201 { 202 if (ctx == NULL) 203 return 0; 204 205 ctx->srp_ctx.SRP_cb_arg = NULL; 206 /* set client Hello login callback */ 207 ctx->srp_ctx.TLS_ext_srp_username_callback = NULL; 208 /* set SRP N/g param callback for verification */ 209 ctx->srp_ctx.SRP_verify_param_callback = NULL; 210 /* set SRP client passwd callback */ 211 ctx->srp_ctx.SRP_give_srp_client_pwd_callback = NULL; 212 213 ctx->srp_ctx.N = NULL; 214 ctx->srp_ctx.g = NULL; 215 ctx->srp_ctx.s = NULL; 216 ctx->srp_ctx.B = NULL; 217 ctx->srp_ctx.A = NULL; 218 ctx->srp_ctx.a = NULL; 219 ctx->srp_ctx.b = NULL; 220 ctx->srp_ctx.v = NULL; 221 ctx->srp_ctx.login = NULL; 222 ctx->srp_ctx.srp_Mask = 0; 223 ctx->srp_ctx.info = NULL; 224 ctx->srp_ctx.strength = SRP_MINIMAL_N; 225 226 return (1); 227 } 228 229 /* server side */ 230 int SSL_srp_server_param_with_username(SSL *s, int *ad) 231 { 232 unsigned char b[SSL_MAX_MASTER_KEY_LENGTH]; 233 int al; 234 235 *ad = SSL_AD_UNKNOWN_PSK_IDENTITY; 236 if ((s->srp_ctx.TLS_ext_srp_username_callback != NULL) && 237 ((al = 238 s->srp_ctx.TLS_ext_srp_username_callback(s, ad, 239 s->srp_ctx.SRP_cb_arg)) != 240 SSL_ERROR_NONE)) 241 return al; 242 243 *ad = SSL_AD_INTERNAL_ERROR; 244 if ((s->srp_ctx.N == NULL) || 245 (s->srp_ctx.g == NULL) || 246 (s->srp_ctx.s == NULL) || (s->srp_ctx.v == NULL)) 247 return SSL3_AL_FATAL; 248 249 if (RAND_bytes(b, sizeof(b)) <= 0) 250 return SSL3_AL_FATAL; 251 s->srp_ctx.b = BN_bin2bn(b, sizeof(b), NULL); 252 OPENSSL_cleanse(b, sizeof(b)); 253 254 /* Calculate: B = (kv + g^b) % N */ 255 256 return ((s->srp_ctx.B = 257 SRP_Calc_B(s->srp_ctx.b, s->srp_ctx.N, s->srp_ctx.g, 258 s->srp_ctx.v)) != 259 NULL) ? SSL_ERROR_NONE : SSL3_AL_FATAL; 260 } 261 262 /* 263 * If the server just has the raw password, make up a verifier entry on the 264 * fly 265 */ 266 int SSL_set_srp_server_param_pw(SSL *s, const char *user, const char *pass, 267 const char *grp) 268 { 269 SRP_gN *GN = SRP_get_default_gN(grp); 270 if (GN == NULL) 271 return -1; 272 s->srp_ctx.N = BN_dup(GN->N); 273 s->srp_ctx.g = BN_dup(GN->g); 274 if (s->srp_ctx.v != NULL) { 275 BN_clear_free(s->srp_ctx.v); 276 s->srp_ctx.v = NULL; 277 } 278 if (s->srp_ctx.s != NULL) { 279 BN_clear_free(s->srp_ctx.s); 280 s->srp_ctx.s = NULL; 281 } 282 if (!SRP_create_verifier_BN 283 (user, pass, &s->srp_ctx.s, &s->srp_ctx.v, GN->N, GN->g)) 284 return -1; 285 286 return 1; 287 } 288 289 int SSL_set_srp_server_param(SSL *s, const BIGNUM *N, const BIGNUM *g, 290 BIGNUM *sa, BIGNUM *v, char *info) 291 { 292 if (N != NULL) { 293 if (s->srp_ctx.N != NULL) { 294 if (!BN_copy(s->srp_ctx.N, N)) { 295 BN_free(s->srp_ctx.N); 296 s->srp_ctx.N = NULL; 297 } 298 } else 299 s->srp_ctx.N = BN_dup(N); 300 } 301 if (g != NULL) { 302 if (s->srp_ctx.g != NULL) { 303 if (!BN_copy(s->srp_ctx.g, g)) { 304 BN_free(s->srp_ctx.g); 305 s->srp_ctx.g = NULL; 306 } 307 } else 308 s->srp_ctx.g = BN_dup(g); 309 } 310 if (sa != NULL) { 311 if (s->srp_ctx.s != NULL) { 312 if (!BN_copy(s->srp_ctx.s, sa)) { 313 BN_free(s->srp_ctx.s); 314 s->srp_ctx.s = NULL; 315 } 316 } else 317 s->srp_ctx.s = BN_dup(sa); 318 } 319 if (v != NULL) { 320 if (s->srp_ctx.v != NULL) { 321 if (!BN_copy(s->srp_ctx.v, v)) { 322 BN_free(s->srp_ctx.v); 323 s->srp_ctx.v = NULL; 324 } 325 } else 326 s->srp_ctx.v = BN_dup(v); 327 } 328 s->srp_ctx.info = info; 329 330 if (!(s->srp_ctx.N) || 331 !(s->srp_ctx.g) || !(s->srp_ctx.s) || !(s->srp_ctx.v)) 332 return -1; 333 334 return 1; 335 } 336 337 int SRP_generate_server_master_secret(SSL *s, unsigned char *master_key) 338 { 339 BIGNUM *K = NULL, *u = NULL; 340 int ret = -1, tmp_len; 341 unsigned char *tmp = NULL; 342 343 if (!SRP_Verify_A_mod_N(s->srp_ctx.A, s->srp_ctx.N)) 344 goto err; 345 if (!(u = SRP_Calc_u(s->srp_ctx.A, s->srp_ctx.B, s->srp_ctx.N))) 346 goto err; 347 if (! 348 (K = 349 SRP_Calc_server_key(s->srp_ctx.A, s->srp_ctx.v, u, s->srp_ctx.b, 350 s->srp_ctx.N))) 351 goto err; 352 353 tmp_len = BN_num_bytes(K); 354 if ((tmp = OPENSSL_malloc(tmp_len)) == NULL) 355 goto err; 356 BN_bn2bin(K, tmp); 357 ret = 358 s->method->ssl3_enc->generate_master_secret(s, master_key, tmp, 359 tmp_len); 360 err: 361 if (tmp) { 362 OPENSSL_cleanse(tmp, tmp_len); 363 OPENSSL_free(tmp); 364 } 365 BN_clear_free(K); 366 BN_clear_free(u); 367 return ret; 368 } 369 370 /* client side */ 371 int SRP_generate_client_master_secret(SSL *s, unsigned char *master_key) 372 { 373 BIGNUM *x = NULL, *u = NULL, *K = NULL; 374 int ret = -1, tmp_len; 375 char *passwd = NULL; 376 unsigned char *tmp = NULL; 377 378 /* 379 * Checks if b % n == 0 380 */ 381 if (SRP_Verify_B_mod_N(s->srp_ctx.B, s->srp_ctx.N) == 0) 382 goto err; 383 if (!(u = SRP_Calc_u(s->srp_ctx.A, s->srp_ctx.B, s->srp_ctx.N))) 384 goto err; 385 if (s->srp_ctx.SRP_give_srp_client_pwd_callback == NULL) 386 goto err; 387 if (! 388 (passwd = 389 s->srp_ctx.SRP_give_srp_client_pwd_callback(s, 390 s->srp_ctx.SRP_cb_arg))) 391 goto err; 392 if (!(x = SRP_Calc_x(s->srp_ctx.s, s->srp_ctx.login, passwd))) 393 goto err; 394 if (! 395 (K = 396 SRP_Calc_client_key(s->srp_ctx.N, s->srp_ctx.B, s->srp_ctx.g, x, 397 s->srp_ctx.a, u))) 398 goto err; 399 400 tmp_len = BN_num_bytes(K); 401 if ((tmp = OPENSSL_malloc(tmp_len)) == NULL) 402 goto err; 403 BN_bn2bin(K, tmp); 404 ret = 405 s->method->ssl3_enc->generate_master_secret(s, master_key, tmp, 406 tmp_len); 407 err: 408 if (tmp) { 409 OPENSSL_cleanse(tmp, tmp_len); 410 OPENSSL_free(tmp); 411 } 412 BN_clear_free(K); 413 BN_clear_free(x); 414 if (passwd) { 415 OPENSSL_cleanse(passwd, strlen(passwd)); 416 OPENSSL_free(passwd); 417 } 418 BN_clear_free(u); 419 return ret; 420 } 421 422 int srp_verify_server_param(SSL *s, int *al) 423 { 424 SRP_CTX *srp = &s->srp_ctx; 425 /* 426 * Sanity check parameters: we can quickly check B % N == 0 by checking B 427 * != 0 since B < N 428 */ 429 if (BN_ucmp(srp->g, srp->N) >= 0 || BN_ucmp(srp->B, srp->N) >= 0 430 || BN_is_zero(srp->B)) { 431 *al = SSL3_AD_ILLEGAL_PARAMETER; 432 return 0; 433 } 434 435 if (BN_num_bits(srp->N) < srp->strength) { 436 *al = TLS1_AD_INSUFFICIENT_SECURITY; 437 return 0; 438 } 439 440 if (srp->SRP_verify_param_callback) { 441 if (srp->SRP_verify_param_callback(s, srp->SRP_cb_arg) <= 0) { 442 *al = TLS1_AD_INSUFFICIENT_SECURITY; 443 return 0; 444 } 445 } else if (!SRP_check_known_gN_param(srp->g, srp->N)) { 446 *al = TLS1_AD_INSUFFICIENT_SECURITY; 447 return 0; 448 } 449 450 return 1; 451 } 452 453 int SRP_Calc_A_param(SSL *s) 454 { 455 unsigned char rnd[SSL_MAX_MASTER_KEY_LENGTH]; 456 457 if (RAND_bytes(rnd, sizeof(rnd)) <= 0) 458 return -1; 459 s->srp_ctx.a = BN_bin2bn(rnd, sizeof(rnd), s->srp_ctx.a); 460 OPENSSL_cleanse(rnd, sizeof(rnd)); 461 462 if (! 463 (s->srp_ctx.A = SRP_Calc_A(s->srp_ctx.a, s->srp_ctx.N, s->srp_ctx.g))) 464 return -1; 465 466 return 1; 467 } 468 469 BIGNUM *SSL_get_srp_g(SSL *s) 470 { 471 if (s->srp_ctx.g != NULL) 472 return s->srp_ctx.g; 473 return s->ctx->srp_ctx.g; 474 } 475 476 BIGNUM *SSL_get_srp_N(SSL *s) 477 { 478 if (s->srp_ctx.N != NULL) 479 return s->srp_ctx.N; 480 return s->ctx->srp_ctx.N; 481 } 482 483 char *SSL_get_srp_username(SSL *s) 484 { 485 if (s->srp_ctx.login != NULL) 486 return s->srp_ctx.login; 487 return s->ctx->srp_ctx.login; 488 } 489 490 char *SSL_get_srp_userinfo(SSL *s) 491 { 492 if (s->srp_ctx.info != NULL) 493 return s->srp_ctx.info; 494 return s->ctx->srp_ctx.info; 495 } 496 497 # define tls1_ctx_ctrl ssl3_ctx_ctrl 498 # define tls1_ctx_callback_ctrl ssl3_ctx_callback_ctrl 499 500 int SSL_CTX_set_srp_username(SSL_CTX *ctx, char *name) 501 { 502 return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_USERNAME, 0, name); 503 } 504 505 int SSL_CTX_set_srp_password(SSL_CTX *ctx, char *password) 506 { 507 return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD, 0, password); 508 } 509 510 int SSL_CTX_set_srp_strength(SSL_CTX *ctx, int strength) 511 { 512 return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH, strength, 513 NULL); 514 } 515 516 int SSL_CTX_set_srp_verify_param_callback(SSL_CTX *ctx, 517 int (*cb) (SSL *, void *)) 518 { 519 return tls1_ctx_callback_ctrl(ctx, SSL_CTRL_SET_SRP_VERIFY_PARAM_CB, 520 (void (*)(void))cb); 521 } 522 523 int SSL_CTX_set_srp_cb_arg(SSL_CTX *ctx, void *arg) 524 { 525 return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_SRP_ARG, 0, arg); 526 } 527 528 int SSL_CTX_set_srp_username_callback(SSL_CTX *ctx, 529 int (*cb) (SSL *, int *, void *)) 530 { 531 return tls1_ctx_callback_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB, 532 (void (*)(void))cb); 533 } 534 535 int SSL_CTX_set_srp_client_pwd_callback(SSL_CTX *ctx, 536 char *(*cb) (SSL *, void *)) 537 { 538 return tls1_ctx_callback_ctrl(ctx, SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB, 539 (void (*)(void))cb); 540 } 541 542 #endif 543