Coverage Report

Created: 2025-12-31 06:58

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