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