3 * Written by Christophe Renou (christophe.renou@edelweb.fr) with the
4 * precious help of Peter Sylvester (peter.sylvester@edelweb.fr) for the
5 * EdelKey project and contributed to the OpenSSL project 2004.
7 /* ====================================================================
8 * Copyright (c) 2004-2011 The OpenSSL Project. All rights reserved.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in
19 * the documentation and/or other materials provided with the
22 * 3. All advertising materials mentioning features or use of this
23 * software must display the following acknowledgment:
24 * "This product includes software developed by the OpenSSL Project
25 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
27 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
28 * endorse or promote products derived from this software without
29 * prior written permission. For written permission, please contact
30 * licensing@OpenSSL.org.
32 * 5. Products derived from this software may not be called "OpenSSL"
33 * nor may "OpenSSL" appear in their names without prior written
34 * permission of the OpenSSL Project.
36 * 6. Redistributions of any form whatsoever must retain the following
38 * "This product includes software developed by the OpenSSL Project
39 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
41 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
42 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
44 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
45 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
46 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
47 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
48 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
49 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
50 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
51 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
52 * OF THE POSSIBILITY OF SUCH DAMAGE.
53 * ====================================================================
55 * This product includes cryptographic software written by Eric Young
56 * (eay@cryptsoft.com). This product includes software written by Tim
57 * Hudson (tjh@cryptsoft.com).
61 #ifndef OPENSSL_NO_SRP
63 # include <openssl/rand.h>
64 # include <openssl/srp.h>
65 # include <openssl/err.h>
67 int SSL_CTX_SRP_CTX_free(struct ssl_ctx_st
*ctx
)
71 OPENSSL_free(ctx
->srp_ctx
.login
);
72 BN_free(ctx
->srp_ctx
.N
);
73 BN_free(ctx
->srp_ctx
.g
);
74 BN_free(ctx
->srp_ctx
.s
);
75 BN_free(ctx
->srp_ctx
.B
);
76 BN_free(ctx
->srp_ctx
.A
);
77 BN_free(ctx
->srp_ctx
.a
);
78 BN_free(ctx
->srp_ctx
.b
);
79 BN_free(ctx
->srp_ctx
.v
);
80 ctx
->srp_ctx
.TLS_ext_srp_username_callback
= NULL
;
81 ctx
->srp_ctx
.SRP_cb_arg
= NULL
;
82 ctx
->srp_ctx
.SRP_verify_param_callback
= NULL
;
83 ctx
->srp_ctx
.SRP_give_srp_client_pwd_callback
= NULL
;
84 ctx
->srp_ctx
.N
= NULL
;
85 ctx
->srp_ctx
.g
= NULL
;
86 ctx
->srp_ctx
.s
= NULL
;
87 ctx
->srp_ctx
.B
= NULL
;
88 ctx
->srp_ctx
.A
= NULL
;
89 ctx
->srp_ctx
.a
= NULL
;
90 ctx
->srp_ctx
.b
= NULL
;
91 ctx
->srp_ctx
.v
= NULL
;
92 ctx
->srp_ctx
.login
= NULL
;
93 ctx
->srp_ctx
.info
= NULL
;
94 ctx
->srp_ctx
.strength
= SRP_MINIMAL_N
;
95 ctx
->srp_ctx
.srp_Mask
= 0;
99 int SSL_SRP_CTX_free(struct ssl_st
*s
)
103 OPENSSL_free(s
->srp_ctx
.login
);
104 BN_free(s
->srp_ctx
.N
);
105 BN_free(s
->srp_ctx
.g
);
106 BN_free(s
->srp_ctx
.s
);
107 BN_free(s
->srp_ctx
.B
);
108 BN_free(s
->srp_ctx
.A
);
109 BN_free(s
->srp_ctx
.a
);
110 BN_free(s
->srp_ctx
.b
);
111 BN_free(s
->srp_ctx
.v
);
112 s
->srp_ctx
.TLS_ext_srp_username_callback
= NULL
;
113 s
->srp_ctx
.SRP_cb_arg
= NULL
;
114 s
->srp_ctx
.SRP_verify_param_callback
= NULL
;
115 s
->srp_ctx
.SRP_give_srp_client_pwd_callback
= NULL
;
124 s
->srp_ctx
.login
= NULL
;
125 s
->srp_ctx
.info
= NULL
;
126 s
->srp_ctx
.strength
= SRP_MINIMAL_N
;
127 s
->srp_ctx
.srp_Mask
= 0;
131 int SSL_SRP_CTX_init(struct ssl_st
*s
)
135 if ((s
== NULL
) || ((ctx
= s
->ctx
) == NULL
))
137 s
->srp_ctx
.SRP_cb_arg
= ctx
->srp_ctx
.SRP_cb_arg
;
138 /* set client Hello login callback */
139 s
->srp_ctx
.TLS_ext_srp_username_callback
=
140 ctx
->srp_ctx
.TLS_ext_srp_username_callback
;
141 /* set SRP N/g param callback for verification */
142 s
->srp_ctx
.SRP_verify_param_callback
=
143 ctx
->srp_ctx
.SRP_verify_param_callback
;
144 /* set SRP client passwd callback */
145 s
->srp_ctx
.SRP_give_srp_client_pwd_callback
=
146 ctx
->srp_ctx
.SRP_give_srp_client_pwd_callback
;
156 s
->srp_ctx
.login
= NULL
;
157 s
->srp_ctx
.info
= ctx
->srp_ctx
.info
;
158 s
->srp_ctx
.strength
= ctx
->srp_ctx
.strength
;
160 if (((ctx
->srp_ctx
.N
!= NULL
) &&
161 ((s
->srp_ctx
.N
= BN_dup(ctx
->srp_ctx
.N
)) == NULL
)) ||
162 ((ctx
->srp_ctx
.g
!= NULL
) &&
163 ((s
->srp_ctx
.g
= BN_dup(ctx
->srp_ctx
.g
)) == NULL
)) ||
164 ((ctx
->srp_ctx
.s
!= NULL
) &&
165 ((s
->srp_ctx
.s
= BN_dup(ctx
->srp_ctx
.s
)) == NULL
)) ||
166 ((ctx
->srp_ctx
.B
!= NULL
) &&
167 ((s
->srp_ctx
.B
= BN_dup(ctx
->srp_ctx
.B
)) == NULL
)) ||
168 ((ctx
->srp_ctx
.A
!= NULL
) &&
169 ((s
->srp_ctx
.A
= BN_dup(ctx
->srp_ctx
.A
)) == NULL
)) ||
170 ((ctx
->srp_ctx
.a
!= NULL
) &&
171 ((s
->srp_ctx
.a
= BN_dup(ctx
->srp_ctx
.a
)) == NULL
)) ||
172 ((ctx
->srp_ctx
.v
!= NULL
) &&
173 ((s
->srp_ctx
.v
= BN_dup(ctx
->srp_ctx
.v
)) == NULL
)) ||
174 ((ctx
->srp_ctx
.b
!= NULL
) &&
175 ((s
->srp_ctx
.b
= BN_dup(ctx
->srp_ctx
.b
)) == NULL
))) {
176 SSLerr(SSL_F_SSL_SRP_CTX_INIT
, ERR_R_BN_LIB
);
179 if ((ctx
->srp_ctx
.login
!= NULL
) &&
180 ((s
->srp_ctx
.login
= BUF_strdup(ctx
->srp_ctx
.login
)) == NULL
)) {
181 SSLerr(SSL_F_SSL_SRP_CTX_INIT
, ERR_R_INTERNAL_ERROR
);
184 s
->srp_ctx
.srp_Mask
= ctx
->srp_ctx
.srp_Mask
;
188 OPENSSL_free(s
->srp_ctx
.login
);
189 BN_free(s
->srp_ctx
.N
);
190 BN_free(s
->srp_ctx
.g
);
191 BN_free(s
->srp_ctx
.s
);
192 BN_free(s
->srp_ctx
.B
);
193 BN_free(s
->srp_ctx
.A
);
194 BN_free(s
->srp_ctx
.a
);
195 BN_free(s
->srp_ctx
.b
);
196 BN_free(s
->srp_ctx
.v
);
200 int SSL_CTX_SRP_CTX_init(struct ssl_ctx_st
*ctx
)
205 ctx
->srp_ctx
.SRP_cb_arg
= NULL
;
206 /* set client Hello login callback */
207 ctx
->srp_ctx
.TLS_ext_srp_username_callback
= NULL
;
208 /* set SRP N/g param callback for verification */
209 ctx
->srp_ctx
.SRP_verify_param_callback
= NULL
;
210 /* set SRP client passwd callback */
211 ctx
->srp_ctx
.SRP_give_srp_client_pwd_callback
= NULL
;
213 ctx
->srp_ctx
.N
= NULL
;
214 ctx
->srp_ctx
.g
= NULL
;
215 ctx
->srp_ctx
.s
= NULL
;
216 ctx
->srp_ctx
.B
= NULL
;
217 ctx
->srp_ctx
.A
= NULL
;
218 ctx
->srp_ctx
.a
= NULL
;
219 ctx
->srp_ctx
.b
= NULL
;
220 ctx
->srp_ctx
.v
= NULL
;
221 ctx
->srp_ctx
.login
= NULL
;
222 ctx
->srp_ctx
.srp_Mask
= 0;
223 ctx
->srp_ctx
.info
= NULL
;
224 ctx
->srp_ctx
.strength
= SRP_MINIMAL_N
;
230 int SSL_srp_server_param_with_username(SSL
*s
, int *ad
)
232 unsigned char b
[SSL_MAX_MASTER_KEY_LENGTH
];
235 *ad
= SSL_AD_UNKNOWN_PSK_IDENTITY
;
236 if ((s
->srp_ctx
.TLS_ext_srp_username_callback
!= NULL
) &&
238 s
->srp_ctx
.TLS_ext_srp_username_callback(s
, ad
,
239 s
->srp_ctx
.SRP_cb_arg
)) !=
243 *ad
= SSL_AD_INTERNAL_ERROR
;
244 if ((s
->srp_ctx
.N
== NULL
) ||
245 (s
->srp_ctx
.g
== NULL
) ||
246 (s
->srp_ctx
.s
== NULL
) || (s
->srp_ctx
.v
== NULL
))
247 return SSL3_AL_FATAL
;
249 if (RAND_bytes(b
, sizeof(b
)) <= 0)
250 return SSL3_AL_FATAL
;
251 s
->srp_ctx
.b
= BN_bin2bn(b
, sizeof(b
), NULL
);
252 OPENSSL_cleanse(b
, sizeof(b
));
254 /* Calculate: B = (kv + g^b) % N */
256 return ((s
->srp_ctx
.B
=
257 SRP_Calc_B(s
->srp_ctx
.b
, s
->srp_ctx
.N
, s
->srp_ctx
.g
,
259 NULL
) ? SSL_ERROR_NONE
: SSL3_AL_FATAL
;
263 * If the server just has the raw password, make up a verifier entry on the
266 int SSL_set_srp_server_param_pw(SSL
*s
, const char *user
, const char *pass
,
269 SRP_gN
*GN
= SRP_get_default_gN(grp
);
272 s
->srp_ctx
.N
= BN_dup(GN
->N
);
273 s
->srp_ctx
.g
= BN_dup(GN
->g
);
274 if (s
->srp_ctx
.v
!= NULL
) {
275 BN_clear_free(s
->srp_ctx
.v
);
278 if (s
->srp_ctx
.s
!= NULL
) {
279 BN_clear_free(s
->srp_ctx
.s
);
282 if (!SRP_create_verifier_BN
283 (user
, pass
, &s
->srp_ctx
.s
, &s
->srp_ctx
.v
, GN
->N
, GN
->g
))
289 int SSL_set_srp_server_param(SSL
*s
, const BIGNUM
*N
, const BIGNUM
*g
,
290 BIGNUM
*sa
, BIGNUM
*v
, char *info
)
293 if (s
->srp_ctx
.N
!= NULL
) {
294 if (!BN_copy(s
->srp_ctx
.N
, N
)) {
295 BN_free(s
->srp_ctx
.N
);
299 s
->srp_ctx
.N
= BN_dup(N
);
302 if (s
->srp_ctx
.g
!= NULL
) {
303 if (!BN_copy(s
->srp_ctx
.g
, g
)) {
304 BN_free(s
->srp_ctx
.g
);
308 s
->srp_ctx
.g
= BN_dup(g
);
311 if (s
->srp_ctx
.s
!= NULL
) {
312 if (!BN_copy(s
->srp_ctx
.s
, sa
)) {
313 BN_free(s
->srp_ctx
.s
);
317 s
->srp_ctx
.s
= BN_dup(sa
);
320 if (s
->srp_ctx
.v
!= NULL
) {
321 if (!BN_copy(s
->srp_ctx
.v
, v
)) {
322 BN_free(s
->srp_ctx
.v
);
326 s
->srp_ctx
.v
= BN_dup(v
);
328 s
->srp_ctx
.info
= info
;
330 if (!(s
->srp_ctx
.N
) ||
331 !(s
->srp_ctx
.g
) || !(s
->srp_ctx
.s
) || !(s
->srp_ctx
.v
))
337 int SRP_generate_server_master_secret(SSL
*s
, unsigned char *master_key
)
339 BIGNUM
*K
= NULL
, *u
= NULL
;
340 int ret
= -1, tmp_len
;
341 unsigned char *tmp
= NULL
;
343 if (!SRP_Verify_A_mod_N(s
->srp_ctx
.A
, s
->srp_ctx
.N
))
345 if (!(u
= SRP_Calc_u(s
->srp_ctx
.A
, s
->srp_ctx
.B
, s
->srp_ctx
.N
)))
349 SRP_Calc_server_key(s
->srp_ctx
.A
, s
->srp_ctx
.v
, u
, s
->srp_ctx
.b
,
353 tmp_len
= BN_num_bytes(K
);
354 if ((tmp
= OPENSSL_malloc(tmp_len
)) == NULL
)
358 s
->method
->ssl3_enc
->generate_master_secret(s
, master_key
, tmp
,
362 OPENSSL_cleanse(tmp
, tmp_len
);
371 int SRP_generate_client_master_secret(SSL
*s
, unsigned char *master_key
)
373 BIGNUM
*x
= NULL
, *u
= NULL
, *K
= NULL
;
374 int ret
= -1, tmp_len
;
376 unsigned char *tmp
= NULL
;
379 * Checks if b % n == 0
381 if (SRP_Verify_B_mod_N(s
->srp_ctx
.B
, s
->srp_ctx
.N
) == 0)
383 if (!(u
= SRP_Calc_u(s
->srp_ctx
.A
, s
->srp_ctx
.B
, s
->srp_ctx
.N
)))
385 if (s
->srp_ctx
.SRP_give_srp_client_pwd_callback
== NULL
)
389 s
->srp_ctx
.SRP_give_srp_client_pwd_callback(s
,
390 s
->srp_ctx
.SRP_cb_arg
)))
392 if (!(x
= SRP_Calc_x(s
->srp_ctx
.s
, s
->srp_ctx
.login
, passwd
)))
396 SRP_Calc_client_key(s
->srp_ctx
.N
, s
->srp_ctx
.B
, s
->srp_ctx
.g
, x
,
400 tmp_len
= BN_num_bytes(K
);
401 if ((tmp
= OPENSSL_malloc(tmp_len
)) == NULL
)
405 s
->method
->ssl3_enc
->generate_master_secret(s
, master_key
, tmp
,
409 OPENSSL_cleanse(tmp
, tmp_len
);
415 OPENSSL_cleanse(passwd
, strlen(passwd
));
416 OPENSSL_free(passwd
);
422 int srp_verify_server_param(SSL
*s
, int *al
)
424 SRP_CTX
*srp
= &s
->srp_ctx
;
426 * Sanity check parameters: we can quickly check B % N == 0 by checking B
429 if (BN_ucmp(srp
->g
, srp
->N
) >= 0 || BN_ucmp(srp
->B
, srp
->N
) >= 0
430 || BN_is_zero(srp
->B
)) {
431 *al
= SSL3_AD_ILLEGAL_PARAMETER
;
435 if (BN_num_bits(srp
->N
) < srp
->strength
) {
436 *al
= TLS1_AD_INSUFFICIENT_SECURITY
;
440 if (srp
->SRP_verify_param_callback
) {
441 if (srp
->SRP_verify_param_callback(s
, srp
->SRP_cb_arg
) <= 0) {
442 *al
= TLS1_AD_INSUFFICIENT_SECURITY
;
445 } else if (!SRP_check_known_gN_param(srp
->g
, srp
->N
)) {
446 *al
= TLS1_AD_INSUFFICIENT_SECURITY
;
453 int SRP_Calc_A_param(SSL
*s
)
455 unsigned char rnd
[SSL_MAX_MASTER_KEY_LENGTH
];
457 if (RAND_bytes(rnd
, sizeof(rnd
)) <= 0)
459 s
->srp_ctx
.a
= BN_bin2bn(rnd
, sizeof(rnd
), s
->srp_ctx
.a
);
460 OPENSSL_cleanse(rnd
, sizeof(rnd
));
463 (s
->srp_ctx
.A
= SRP_Calc_A(s
->srp_ctx
.a
, s
->srp_ctx
.N
, s
->srp_ctx
.g
)))
469 BIGNUM
*SSL_get_srp_g(SSL
*s
)
471 if (s
->srp_ctx
.g
!= NULL
)
473 return s
->ctx
->srp_ctx
.g
;
476 BIGNUM
*SSL_get_srp_N(SSL
*s
)
478 if (s
->srp_ctx
.N
!= NULL
)
480 return s
->ctx
->srp_ctx
.N
;
483 char *SSL_get_srp_username(SSL
*s
)
485 if (s
->srp_ctx
.login
!= NULL
)
486 return s
->srp_ctx
.login
;
487 return s
->ctx
->srp_ctx
.login
;
490 char *SSL_get_srp_userinfo(SSL
*s
)
492 if (s
->srp_ctx
.info
!= NULL
)
493 return s
->srp_ctx
.info
;
494 return s
->ctx
->srp_ctx
.info
;
497 # define tls1_ctx_ctrl ssl3_ctx_ctrl
498 # define tls1_ctx_callback_ctrl ssl3_ctx_callback_ctrl
500 int SSL_CTX_set_srp_username(SSL_CTX
*ctx
, char *name
)
502 return tls1_ctx_ctrl(ctx
, SSL_CTRL_SET_TLS_EXT_SRP_USERNAME
, 0, name
);
505 int SSL_CTX_set_srp_password(SSL_CTX
*ctx
, char *password
)
507 return tls1_ctx_ctrl(ctx
, SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD
, 0, password
);
510 int SSL_CTX_set_srp_strength(SSL_CTX
*ctx
, int strength
)
512 return tls1_ctx_ctrl(ctx
, SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH
, strength
,
516 int SSL_CTX_set_srp_verify_param_callback(SSL_CTX
*ctx
,
517 int (*cb
) (SSL
*, void *))
519 return tls1_ctx_callback_ctrl(ctx
, SSL_CTRL_SET_SRP_VERIFY_PARAM_CB
,
523 int SSL_CTX_set_srp_cb_arg(SSL_CTX
*ctx
, void *arg
)
525 return tls1_ctx_ctrl(ctx
, SSL_CTRL_SET_SRP_ARG
, 0, arg
);
528 int SSL_CTX_set_srp_username_callback(SSL_CTX
*ctx
,
529 int (*cb
) (SSL
*, int *, void *))
531 return tls1_ctx_callback_ctrl(ctx
, SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB
,
535 int SSL_CTX_set_srp_client_pwd_callback(SSL_CTX
*ctx
,
536 char *(*cb
) (SSL
*, void *))
538 return tls1_ctx_callback_ctrl(ctx
, SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB
,