Coverage Report

Created: 2025-12-31 06:58

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