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