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