1 1.1 christos /* 2 1.1 christos * Copyright 2004-2025 The OpenSSL Project Authors. All Rights Reserved. 3 1.1 christos * Copyright (c) 2004, EdelKey Project. All Rights Reserved. 4 1.1 christos * 5 1.1 christos * Licensed under the Apache License 2.0 (the "License"). You may not use 6 1.1 christos * this file except in compliance with the License. You can obtain a copy 7 1.1 christos * in the file LICENSE in the source distribution or at 8 1.1 christos * https://www.openssl.org/source/license.html 9 1.1 christos * 10 1.1 christos * Originally written by Christophe Renou and Peter Sylvester, 11 1.1 christos * for the EdelKey project. 12 1.1 christos */ 13 1.1 christos 14 1.1 christos /* 15 1.1 christos * We need to use the SRP deprecated APIs in order to implement the SSL SRP 16 1.1 christos * APIs - which are themselves deprecated. 17 1.1 christos */ 18 1.1 christos #define OPENSSL_SUPPRESS_DEPRECATED 19 1.1 christos 20 1.1 christos #include <openssl/crypto.h> 21 1.1 christos #include <openssl/rand.h> 22 1.1 christos #include <openssl/err.h> 23 1.1 christos #include "ssl_local.h" 24 1.1 christos #include "internal/ssl_unwrap.h" 25 1.1 christos 26 1.1 christos #ifndef OPENSSL_NO_SRP 27 1.1.1.2 christos #include <openssl/srp.h> 28 1.1 christos 29 1.1 christos /* 30 1.1 christos * The public API SSL_CTX_SRP_CTX_free() is deprecated so we use 31 1.1 christos * ssl_ctx_srp_ctx_free_intern() internally. 32 1.1 christos */ 33 1.1 christos int ssl_ctx_srp_ctx_free_intern(SSL_CTX *ctx) 34 1.1 christos { 35 1.1 christos if (ctx == NULL) 36 1.1 christos return 0; 37 1.1 christos OPENSSL_free(ctx->srp_ctx.login); 38 1.1 christos OPENSSL_free(ctx->srp_ctx.info); 39 1.1 christos BN_free(ctx->srp_ctx.N); 40 1.1 christos BN_free(ctx->srp_ctx.g); 41 1.1 christos BN_free(ctx->srp_ctx.s); 42 1.1 christos BN_free(ctx->srp_ctx.B); 43 1.1 christos BN_free(ctx->srp_ctx.A); 44 1.1 christos BN_free(ctx->srp_ctx.a); 45 1.1 christos BN_free(ctx->srp_ctx.b); 46 1.1 christos BN_free(ctx->srp_ctx.v); 47 1.1 christos memset(&ctx->srp_ctx, 0, sizeof(ctx->srp_ctx)); 48 1.1 christos ctx->srp_ctx.strength = SRP_MINIMAL_N; 49 1.1 christos return 1; 50 1.1 christos } 51 1.1 christos 52 1.1 christos int SSL_CTX_SRP_CTX_free(SSL_CTX *ctx) 53 1.1 christos { 54 1.1 christos return ssl_ctx_srp_ctx_free_intern(ctx); 55 1.1 christos } 56 1.1 christos 57 1.1 christos /* 58 1.1 christos * The public API SSL_SRP_CTX_free() is deprecated so we use 59 1.1 christos * ssl_srp_ctx_free_intern() internally. 60 1.1 christos */ 61 1.1 christos int ssl_srp_ctx_free_intern(SSL_CONNECTION *s) 62 1.1 christos { 63 1.1 christos if (s == NULL) 64 1.1 christos return 0; 65 1.1 christos OPENSSL_free(s->srp_ctx.login); 66 1.1 christos OPENSSL_free(s->srp_ctx.info); 67 1.1 christos BN_free(s->srp_ctx.N); 68 1.1 christos BN_free(s->srp_ctx.g); 69 1.1 christos BN_free(s->srp_ctx.s); 70 1.1 christos BN_free(s->srp_ctx.B); 71 1.1 christos BN_free(s->srp_ctx.A); 72 1.1 christos BN_free(s->srp_ctx.a); 73 1.1 christos BN_free(s->srp_ctx.b); 74 1.1 christos BN_free(s->srp_ctx.v); 75 1.1 christos memset(&s->srp_ctx, 0, sizeof(s->srp_ctx)); 76 1.1 christos s->srp_ctx.strength = SRP_MINIMAL_N; 77 1.1 christos return 1; 78 1.1 christos } 79 1.1 christos 80 1.1 christos int SSL_SRP_CTX_free(SSL *s) 81 1.1 christos { 82 1.1 christos SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); 83 1.1 christos 84 1.1 christos /* the call works with NULL sc */ 85 1.1 christos return ssl_srp_ctx_free_intern(sc); 86 1.1 christos } 87 1.1 christos 88 1.1 christos /* 89 1.1 christos * The public API SSL_SRP_CTX_init() is deprecated so we use 90 1.1 christos * ssl_srp_ctx_init_intern() internally. 91 1.1 christos */ 92 1.1 christos int ssl_srp_ctx_init_intern(SSL_CONNECTION *s) 93 1.1 christos { 94 1.1 christos SSL_CTX *ctx; 95 1.1 christos 96 1.1 christos if (s == NULL || (ctx = SSL_CONNECTION_GET_CTX(s)) == NULL) 97 1.1 christos return 0; 98 1.1 christos 99 1.1 christos memset(&s->srp_ctx, 0, sizeof(s->srp_ctx)); 100 1.1 christos 101 1.1 christos s->srp_ctx.SRP_cb_arg = ctx->srp_ctx.SRP_cb_arg; 102 1.1 christos /* set client Hello login callback */ 103 1.1.1.2 christos s->srp_ctx.TLS_ext_srp_username_callback = ctx->srp_ctx.TLS_ext_srp_username_callback; 104 1.1 christos /* set SRP N/g param callback for verification */ 105 1.1.1.2 christos s->srp_ctx.SRP_verify_param_callback = ctx->srp_ctx.SRP_verify_param_callback; 106 1.1 christos /* set SRP client passwd callback */ 107 1.1.1.2 christos s->srp_ctx.SRP_give_srp_client_pwd_callback = ctx->srp_ctx.SRP_give_srp_client_pwd_callback; 108 1.1 christos 109 1.1 christos s->srp_ctx.strength = ctx->srp_ctx.strength; 110 1.1 christos 111 1.1.1.2 christos 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))) { 112 1.1 christos ERR_raise(ERR_LIB_SSL, ERR_R_BN_LIB); 113 1.1 christos goto err; 114 1.1 christos } 115 1.1.1.2 christos if ((ctx->srp_ctx.login != NULL) && ((s->srp_ctx.login = OPENSSL_strdup(ctx->srp_ctx.login)) == NULL)) { 116 1.1 christos ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); 117 1.1 christos goto err; 118 1.1 christos } 119 1.1.1.2 christos if ((ctx->srp_ctx.info != NULL) && ((s->srp_ctx.info = OPENSSL_strdup(ctx->srp_ctx.info)) == NULL)) { 120 1.1 christos ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); 121 1.1 christos goto err; 122 1.1 christos } 123 1.1 christos s->srp_ctx.srp_Mask = ctx->srp_ctx.srp_Mask; 124 1.1 christos 125 1.1 christos return 1; 126 1.1.1.2 christos err: 127 1.1 christos OPENSSL_free(s->srp_ctx.login); 128 1.1 christos OPENSSL_free(s->srp_ctx.info); 129 1.1 christos BN_free(s->srp_ctx.N); 130 1.1 christos BN_free(s->srp_ctx.g); 131 1.1 christos BN_free(s->srp_ctx.s); 132 1.1 christos BN_free(s->srp_ctx.B); 133 1.1 christos BN_free(s->srp_ctx.A); 134 1.1 christos BN_free(s->srp_ctx.a); 135 1.1 christos BN_free(s->srp_ctx.b); 136 1.1 christos BN_free(s->srp_ctx.v); 137 1.1 christos memset(&s->srp_ctx, 0, sizeof(s->srp_ctx)); 138 1.1 christos return 0; 139 1.1 christos } 140 1.1 christos 141 1.1 christos int SSL_SRP_CTX_init(SSL *s) 142 1.1 christos { 143 1.1 christos SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); 144 1.1 christos 145 1.1 christos /* the call works with NULL sc */ 146 1.1 christos return ssl_srp_ctx_init_intern(sc); 147 1.1 christos } 148 1.1 christos 149 1.1 christos /* 150 1.1 christos * The public API SSL_CTX_SRP_CTX_init() is deprecated so we use 151 1.1 christos * ssl_ctx_srp_ctx_init_intern() internally. 152 1.1 christos */ 153 1.1 christos int ssl_ctx_srp_ctx_init_intern(SSL_CTX *ctx) 154 1.1 christos { 155 1.1 christos if (ctx == NULL) 156 1.1 christos return 0; 157 1.1 christos 158 1.1 christos memset(&ctx->srp_ctx, 0, sizeof(ctx->srp_ctx)); 159 1.1 christos ctx->srp_ctx.strength = SRP_MINIMAL_N; 160 1.1 christos 161 1.1 christos return 1; 162 1.1 christos } 163 1.1 christos 164 1.1 christos int SSL_CTX_SRP_CTX_init(SSL_CTX *ctx) 165 1.1 christos { 166 1.1 christos return ssl_ctx_srp_ctx_init_intern(ctx); 167 1.1 christos } 168 1.1 christos 169 1.1 christos /* server side */ 170 1.1 christos /* 171 1.1 christos * The public API SSL_srp_server_param_with_username() is deprecated so we use 172 1.1 christos * ssl_srp_server_param_with_username_intern() internally. 173 1.1 christos */ 174 1.1 christos int ssl_srp_server_param_with_username_intern(SSL_CONNECTION *s, int *ad) 175 1.1 christos { 176 1.1 christos unsigned char b[SSL_MAX_MASTER_KEY_LENGTH]; 177 1.1 christos int al; 178 1.1 christos SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); 179 1.1 christos 180 1.1 christos *ad = SSL_AD_UNKNOWN_PSK_IDENTITY; 181 1.1.1.2 christos if ((s->srp_ctx.TLS_ext_srp_username_callback != NULL) && ((al = s->srp_ctx.TLS_ext_srp_username_callback(SSL_CONNECTION_GET_USER_SSL(s), ad, s->srp_ctx.SRP_cb_arg)) != SSL_ERROR_NONE)) 182 1.1 christos return al; 183 1.1 christos 184 1.1 christos *ad = SSL_AD_INTERNAL_ERROR; 185 1.1.1.2 christos if ((s->srp_ctx.N == NULL) || (s->srp_ctx.g == NULL) || (s->srp_ctx.s == NULL) || (s->srp_ctx.v == NULL)) 186 1.1 christos return SSL3_AL_FATAL; 187 1.1 christos 188 1.1 christos if (RAND_priv_bytes_ex(SSL_CONNECTION_GET_CTX(s)->libctx, b, sizeof(b), 189 1.1.1.2 christos 0) 190 1.1.1.2 christos <= 0) 191 1.1 christos return SSL3_AL_FATAL; 192 1.1 christos s->srp_ctx.b = BN_bin2bn(b, sizeof(b), NULL); 193 1.1 christos OPENSSL_cleanse(b, sizeof(b)); 194 1.1 christos 195 1.1 christos /* Calculate: B = (kv + g^b) % N */ 196 1.1 christos 197 1.1.1.2 christos return ((s->srp_ctx.B = SRP_Calc_B_ex(s->srp_ctx.b, s->srp_ctx.N, s->srp_ctx.g, 198 1.1.1.2 christos s->srp_ctx.v, sctx->libctx, sctx->propq)) 199 1.1.1.2 christos != NULL) 200 1.1.1.2 christos ? SSL_ERROR_NONE 201 1.1.1.2 christos : SSL3_AL_FATAL; 202 1.1 christos } 203 1.1 christos 204 1.1 christos int SSL_srp_server_param_with_username(SSL *s, int *ad) 205 1.1 christos { 206 1.1 christos SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); 207 1.1 christos 208 1.1 christos if (sc == NULL) 209 1.1 christos return SSL3_AL_FATAL; 210 1.1 christos 211 1.1 christos return ssl_srp_server_param_with_username_intern(sc, ad); 212 1.1 christos } 213 1.1 christos 214 1.1 christos /* 215 1.1 christos * If the server just has the raw password, make up a verifier entry on the 216 1.1 christos * fly 217 1.1 christos */ 218 1.1 christos int SSL_set_srp_server_param_pw(SSL *s, const char *user, const char *pass, 219 1.1.1.2 christos const char *grp) 220 1.1 christos { 221 1.1 christos SRP_gN *GN; 222 1.1 christos SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); 223 1.1 christos 224 1.1 christos if (sc == NULL) 225 1.1 christos return -1; 226 1.1 christos 227 1.1 christos GN = SRP_get_default_gN(grp); 228 1.1 christos if (GN == NULL) 229 1.1 christos return -1; 230 1.1 christos sc->srp_ctx.N = BN_dup(GN->N); 231 1.1 christos sc->srp_ctx.g = BN_dup(GN->g); 232 1.1 christos BN_clear_free(sc->srp_ctx.v); 233 1.1 christos sc->srp_ctx.v = NULL; 234 1.1 christos BN_clear_free(sc->srp_ctx.s); 235 1.1 christos sc->srp_ctx.s = NULL; 236 1.1 christos if (!SRP_create_verifier_BN_ex(user, pass, &sc->srp_ctx.s, &sc->srp_ctx.v, 237 1.1.1.2 christos sc->srp_ctx.N, sc->srp_ctx.g, s->ctx->libctx, 238 1.1.1.2 christos s->ctx->propq)) 239 1.1 christos return -1; 240 1.1 christos 241 1.1 christos return 1; 242 1.1 christos } 243 1.1 christos 244 1.1 christos int SSL_set_srp_server_param(SSL *s, const BIGNUM *N, const BIGNUM *g, 245 1.1.1.2 christos BIGNUM *sa, BIGNUM *v, char *info) 246 1.1 christos { 247 1.1 christos SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); 248 1.1 christos 249 1.1 christos if (sc == NULL) 250 1.1 christos return -1; 251 1.1 christos 252 1.1 christos if (N != NULL) { 253 1.1 christos if (sc->srp_ctx.N != NULL) { 254 1.1 christos if (!BN_copy(sc->srp_ctx.N, N)) { 255 1.1 christos BN_free(sc->srp_ctx.N); 256 1.1 christos sc->srp_ctx.N = NULL; 257 1.1 christos } 258 1.1 christos } else 259 1.1 christos sc->srp_ctx.N = BN_dup(N); 260 1.1 christos } 261 1.1 christos if (g != NULL) { 262 1.1 christos if (sc->srp_ctx.g != NULL) { 263 1.1 christos if (!BN_copy(sc->srp_ctx.g, g)) { 264 1.1 christos BN_free(sc->srp_ctx.g); 265 1.1 christos sc->srp_ctx.g = NULL; 266 1.1 christos } 267 1.1 christos } else 268 1.1 christos sc->srp_ctx.g = BN_dup(g); 269 1.1 christos } 270 1.1 christos if (sa != NULL) { 271 1.1 christos if (sc->srp_ctx.s != NULL) { 272 1.1 christos if (!BN_copy(sc->srp_ctx.s, sa)) { 273 1.1 christos BN_free(sc->srp_ctx.s); 274 1.1 christos sc->srp_ctx.s = NULL; 275 1.1 christos } 276 1.1 christos } else 277 1.1 christos sc->srp_ctx.s = BN_dup(sa); 278 1.1 christos } 279 1.1 christos if (v != NULL) { 280 1.1 christos if (sc->srp_ctx.v != NULL) { 281 1.1 christos if (!BN_copy(sc->srp_ctx.v, v)) { 282 1.1 christos BN_free(sc->srp_ctx.v); 283 1.1 christos sc->srp_ctx.v = NULL; 284 1.1 christos } 285 1.1 christos } else 286 1.1 christos sc->srp_ctx.v = BN_dup(v); 287 1.1 christos } 288 1.1 christos if (info != NULL) { 289 1.1 christos if (sc->srp_ctx.info) 290 1.1 christos OPENSSL_free(sc->srp_ctx.info); 291 1.1 christos if ((sc->srp_ctx.info = OPENSSL_strdup(info)) == NULL) 292 1.1 christos return -1; 293 1.1 christos } 294 1.1 christos 295 1.1.1.2 christos if (!(sc->srp_ctx.N) || !(sc->srp_ctx.g) || !(sc->srp_ctx.s) || !(sc->srp_ctx.v)) 296 1.1 christos return -1; 297 1.1 christos 298 1.1 christos return 1; 299 1.1 christos } 300 1.1 christos 301 1.1 christos int srp_generate_server_master_secret(SSL_CONNECTION *s) 302 1.1 christos { 303 1.1 christos BIGNUM *K = NULL, *u = NULL; 304 1.1 christos int ret = 0, tmp_len = 0; 305 1.1 christos unsigned char *tmp = NULL; 306 1.1 christos SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); 307 1.1 christos 308 1.1 christos if (!SRP_Verify_A_mod_N(s->srp_ctx.A, s->srp_ctx.N)) 309 1.1 christos goto err; 310 1.1 christos if ((u = SRP_Calc_u_ex(s->srp_ctx.A, s->srp_ctx.B, s->srp_ctx.N, 311 1.1.1.2 christos sctx->libctx, sctx->propq)) 312 1.1.1.2 christos == NULL) 313 1.1 christos goto err; 314 1.1 christos if ((K = SRP_Calc_server_key(s->srp_ctx.A, s->srp_ctx.v, u, s->srp_ctx.b, 315 1.1.1.2 christos s->srp_ctx.N)) 316 1.1.1.2 christos == NULL) 317 1.1 christos goto err; 318 1.1 christos 319 1.1 christos tmp_len = BN_num_bytes(K); 320 1.1 christos if ((tmp = OPENSSL_malloc(tmp_len)) == NULL) { 321 1.1 christos SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB); 322 1.1 christos goto err; 323 1.1 christos } 324 1.1 christos BN_bn2bin(K, tmp); 325 1.1 christos /* Calls SSLfatal() as required */ 326 1.1 christos ret = ssl_generate_master_secret(s, tmp, tmp_len, 1); 327 1.1.1.2 christos err: 328 1.1 christos BN_clear_free(K); 329 1.1 christos BN_clear_free(u); 330 1.1 christos return ret; 331 1.1 christos } 332 1.1 christos 333 1.1 christos /* client side */ 334 1.1 christos int srp_generate_client_master_secret(SSL_CONNECTION *s) 335 1.1 christos { 336 1.1 christos BIGNUM *x = NULL, *u = NULL, *K = NULL; 337 1.1 christos int ret = 0, tmp_len = 0; 338 1.1 christos char *passwd = NULL; 339 1.1 christos unsigned char *tmp = NULL; 340 1.1 christos SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); 341 1.1 christos 342 1.1 christos /* 343 1.1 christos * Checks if b % n == 0 344 1.1 christos */ 345 1.1 christos if (SRP_Verify_B_mod_N(s->srp_ctx.B, s->srp_ctx.N) == 0 346 1.1.1.2 christos || (u = SRP_Calc_u_ex(s->srp_ctx.A, s->srp_ctx.B, s->srp_ctx.N, 347 1.1.1.2 christos sctx->libctx, sctx->propq)) 348 1.1.1.2 christos == NULL 349 1.1.1.2 christos || s->srp_ctx.SRP_give_srp_client_pwd_callback == NULL) { 350 1.1 christos SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); 351 1.1 christos goto err; 352 1.1 christos } 353 1.1 christos if ((passwd = s->srp_ctx.SRP_give_srp_client_pwd_callback(SSL_CONNECTION_GET_USER_SSL(s), 354 1.1.1.2 christos s->srp_ctx.SRP_cb_arg)) 355 1.1.1.2 christos == NULL) { 356 1.1 christos SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_CALLBACK_FAILED); 357 1.1 christos goto err; 358 1.1 christos } 359 1.1 christos if ((x = SRP_Calc_x_ex(s->srp_ctx.s, s->srp_ctx.login, passwd, 360 1.1.1.2 christos sctx->libctx, sctx->propq)) 361 1.1.1.2 christos == NULL 362 1.1.1.2 christos || (K = SRP_Calc_client_key_ex(s->srp_ctx.N, s->srp_ctx.B, 363 1.1.1.2 christos s->srp_ctx.g, x, 364 1.1.1.2 christos s->srp_ctx.a, u, 365 1.1.1.2 christos sctx->libctx, 366 1.1.1.2 christos sctx->propq)) 367 1.1.1.2 christos == NULL) { 368 1.1 christos SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); 369 1.1 christos goto err; 370 1.1 christos } 371 1.1 christos 372 1.1 christos tmp_len = BN_num_bytes(K); 373 1.1 christos if ((tmp = OPENSSL_malloc(tmp_len)) == NULL) { 374 1.1 christos SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB); 375 1.1 christos goto err; 376 1.1 christos } 377 1.1 christos BN_bn2bin(K, tmp); 378 1.1 christos /* Calls SSLfatal() as required */ 379 1.1 christos ret = ssl_generate_master_secret(s, tmp, tmp_len, 1); 380 1.1.1.2 christos err: 381 1.1 christos BN_clear_free(K); 382 1.1 christos BN_clear_free(x); 383 1.1 christos if (passwd != NULL) 384 1.1 christos OPENSSL_clear_free(passwd, strlen(passwd)); 385 1.1 christos BN_clear_free(u); 386 1.1 christos return ret; 387 1.1 christos } 388 1.1 christos 389 1.1 christos int srp_verify_server_param(SSL_CONNECTION *s) 390 1.1 christos { 391 1.1 christos SRP_CTX *srp = &s->srp_ctx; 392 1.1 christos /* 393 1.1 christos * Sanity check parameters: we can quickly check B % N == 0 by checking B 394 1.1 christos * != 0 since B < N 395 1.1 christos */ 396 1.1 christos if (BN_ucmp(srp->g, srp->N) >= 0 || BN_ucmp(srp->B, srp->N) >= 0 397 1.1 christos || BN_is_zero(srp->B)) { 398 1.1 christos SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_DATA); 399 1.1 christos return 0; 400 1.1 christos } 401 1.1 christos 402 1.1 christos if (BN_num_bits(srp->N) < srp->strength) { 403 1.1 christos SSLfatal(s, SSL_AD_INSUFFICIENT_SECURITY, SSL_R_INSUFFICIENT_SECURITY); 404 1.1 christos return 0; 405 1.1 christos } 406 1.1 christos 407 1.1 christos if (srp->SRP_verify_param_callback) { 408 1.1 christos if (srp->SRP_verify_param_callback(SSL_CONNECTION_GET_USER_SSL(s), 409 1.1.1.2 christos srp->SRP_cb_arg) 410 1.1.1.2 christos <= 0) { 411 1.1 christos SSLfatal(s, SSL_AD_INSUFFICIENT_SECURITY, SSL_R_CALLBACK_FAILED); 412 1.1 christos return 0; 413 1.1 christos } 414 1.1 christos } else if (!SRP_check_known_gN_param(srp->g, srp->N)) { 415 1.1 christos SSLfatal(s, SSL_AD_INSUFFICIENT_SECURITY, 416 1.1.1.2 christos SSL_R_INSUFFICIENT_SECURITY); 417 1.1 christos return 0; 418 1.1 christos } 419 1.1 christos 420 1.1 christos return 1; 421 1.1 christos } 422 1.1 christos 423 1.1 christos /* 424 1.1 christos * The public API SRP_Calc_A_param() is deprecated so we use 425 1.1 christos * ssl_srp_calc_a_param_intern() internally. 426 1.1 christos */ 427 1.1 christos int ssl_srp_calc_a_param_intern(SSL_CONNECTION *s) 428 1.1 christos { 429 1.1 christos unsigned char rnd[SSL_MAX_MASTER_KEY_LENGTH]; 430 1.1 christos 431 1.1 christos if (RAND_priv_bytes_ex(SSL_CONNECTION_GET_CTX(s)->libctx, 432 1.1.1.2 christos rnd, sizeof(rnd), 0) 433 1.1.1.2 christos <= 0) 434 1.1 christos return 0; 435 1.1 christos s->srp_ctx.a = BN_bin2bn(rnd, sizeof(rnd), s->srp_ctx.a); 436 1.1 christos OPENSSL_cleanse(rnd, sizeof(rnd)); 437 1.1 christos 438 1.1 christos if (!(s->srp_ctx.A = SRP_Calc_A(s->srp_ctx.a, s->srp_ctx.N, s->srp_ctx.g))) 439 1.1 christos return 0; 440 1.1 christos 441 1.1 christos return 1; 442 1.1 christos } 443 1.1 christos 444 1.1 christos int SRP_Calc_A_param(SSL *s) 445 1.1 christos { 446 1.1 christos SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); 447 1.1 christos 448 1.1 christos if (sc == NULL) 449 1.1 christos return 0; 450 1.1 christos 451 1.1 christos return ssl_srp_calc_a_param_intern(sc); 452 1.1 christos } 453 1.1 christos 454 1.1 christos BIGNUM *SSL_get_srp_g(SSL *s) 455 1.1 christos { 456 1.1 christos SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); 457 1.1 christos 458 1.1 christos if (sc == NULL) 459 1.1 christos return NULL; 460 1.1 christos 461 1.1 christos if (sc->srp_ctx.g != NULL) 462 1.1 christos return sc->srp_ctx.g; 463 1.1 christos return s->ctx->srp_ctx.g; 464 1.1 christos } 465 1.1 christos 466 1.1 christos BIGNUM *SSL_get_srp_N(SSL *s) 467 1.1 christos { 468 1.1 christos SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); 469 1.1 christos 470 1.1 christos if (sc == NULL) 471 1.1 christos return NULL; 472 1.1 christos 473 1.1 christos if (sc->srp_ctx.N != NULL) 474 1.1 christos return sc->srp_ctx.N; 475 1.1 christos return s->ctx->srp_ctx.N; 476 1.1 christos } 477 1.1 christos 478 1.1 christos char *SSL_get_srp_username(SSL *s) 479 1.1 christos { 480 1.1 christos SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); 481 1.1 christos 482 1.1 christos if (sc == NULL) 483 1.1 christos return NULL; 484 1.1 christos 485 1.1 christos if (sc->srp_ctx.login != NULL) 486 1.1 christos return sc->srp_ctx.login; 487 1.1 christos return s->ctx->srp_ctx.login; 488 1.1 christos } 489 1.1 christos 490 1.1 christos char *SSL_get_srp_userinfo(SSL *s) 491 1.1 christos { 492 1.1 christos SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); 493 1.1 christos 494 1.1 christos if (sc == NULL) 495 1.1 christos return NULL; 496 1.1 christos 497 1.1 christos if (sc->srp_ctx.info != NULL) 498 1.1 christos return sc->srp_ctx.info; 499 1.1 christos return s->ctx->srp_ctx.info; 500 1.1 christos } 501 1.1 christos 502 1.1.1.2 christos #define tls1_ctx_ctrl ssl3_ctx_ctrl 503 1.1.1.2 christos #define tls1_ctx_callback_ctrl ssl3_ctx_callback_ctrl 504 1.1 christos 505 1.1 christos int SSL_CTX_set_srp_username(SSL_CTX *ctx, char *name) 506 1.1 christos { 507 1.1 christos return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_USERNAME, 0, name); 508 1.1 christos } 509 1.1 christos 510 1.1 christos int SSL_CTX_set_srp_password(SSL_CTX *ctx, char *password) 511 1.1 christos { 512 1.1 christos return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD, 0, password); 513 1.1 christos } 514 1.1 christos 515 1.1 christos int SSL_CTX_set_srp_strength(SSL_CTX *ctx, int strength) 516 1.1 christos { 517 1.1 christos return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH, strength, 518 1.1.1.2 christos NULL); 519 1.1 christos } 520 1.1 christos 521 1.1 christos int SSL_CTX_set_srp_verify_param_callback(SSL_CTX *ctx, 522 1.1.1.2 christos int (*cb)(SSL *, void *)) 523 1.1 christos { 524 1.1 christos return tls1_ctx_callback_ctrl(ctx, SSL_CTRL_SET_SRP_VERIFY_PARAM_CB, 525 1.1.1.2 christos (void (*)(void))cb); 526 1.1 christos } 527 1.1 christos 528 1.1 christos int SSL_CTX_set_srp_cb_arg(SSL_CTX *ctx, void *arg) 529 1.1 christos { 530 1.1 christos return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_SRP_ARG, 0, arg); 531 1.1 christos } 532 1.1 christos 533 1.1 christos int SSL_CTX_set_srp_username_callback(SSL_CTX *ctx, 534 1.1.1.2 christos int (*cb)(SSL *, int *, void *)) 535 1.1 christos { 536 1.1 christos return tls1_ctx_callback_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB, 537 1.1.1.2 christos (void (*)(void))cb); 538 1.1 christos } 539 1.1 christos 540 1.1 christos int SSL_CTX_set_srp_client_pwd_callback(SSL_CTX *ctx, 541 1.1.1.2 christos char *(*cb)(SSL *, void *)) 542 1.1 christos { 543 1.1 christos return tls1_ctx_callback_ctrl(ctx, SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB, 544 1.1.1.2 christos (void (*)(void))cb); 545 1.1 christos } 546 1.1 christos 547 1.1 christos #endif 548