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