2 * Written by Christophe Renou (christophe.renou@edelweb.fr) with the
3 * precious help of Peter Sylvester (peter.sylvester@edelweb.fr) for the
4 * EdelKey project and contributed to the OpenSSL project 2004.
6 /* ====================================================================
7 * Copyright (c) 2004-2011 The OpenSSL Project. All rights reserved.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
21 * 3. All advertising materials mentioning features or use of this
22 * software must display the following acknowledgment:
23 * "This product includes software developed by the OpenSSL Project
24 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
26 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27 * endorse or promote products derived from this software without
28 * prior written permission. For written permission, please contact
29 * licensing@OpenSSL.org.
31 * 5. Products derived from this software may not be called "OpenSSL"
32 * nor may "OpenSSL" appear in their names without prior written
33 * permission of the OpenSSL Project.
35 * 6. Redistributions of any form whatsoever must retain the following
37 * "This product includes software developed by the OpenSSL Project
38 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
40 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51 * OF THE POSSIBILITY OF SUCH DAMAGE.
52 * ====================================================================
54 * This product includes cryptographic software written by Eric Young
55 * (eay@cryptsoft.com). This product includes software written by Tim
56 * Hudson (tjh@cryptsoft.com).
60 #include <openssl/crypto.h>
61 #include <openssl/rand.h>
62 #include <openssl/err.h>
65 #ifndef OPENSSL_NO_SRP
66 #include <openssl/srp.h>
68 int SSL_CTX_SRP_CTX_free(struct ssl_ctx_st
*ctx
)
72 OPENSSL_free(ctx
->srp_ctx
.login
);
73 BN_free(ctx
->srp_ctx
.N
);
74 BN_free(ctx
->srp_ctx
.g
);
75 BN_free(ctx
->srp_ctx
.s
);
76 BN_free(ctx
->srp_ctx
.B
);
77 BN_free(ctx
->srp_ctx
.A
);
78 BN_free(ctx
->srp_ctx
.a
);
79 BN_free(ctx
->srp_ctx
.b
);
80 BN_free(ctx
->srp_ctx
.v
);
81 ctx
->srp_ctx
.TLS_ext_srp_username_callback
= NULL
;
82 ctx
->srp_ctx
.SRP_cb_arg
= NULL
;
83 ctx
->srp_ctx
.SRP_verify_param_callback
= NULL
;
84 ctx
->srp_ctx
.SRP_give_srp_client_pwd_callback
= NULL
;
85 ctx
->srp_ctx
.N
= NULL
;
86 ctx
->srp_ctx
.g
= NULL
;
87 ctx
->srp_ctx
.s
= NULL
;
88 ctx
->srp_ctx
.B
= NULL
;
89 ctx
->srp_ctx
.A
= NULL
;
90 ctx
->srp_ctx
.a
= NULL
;
91 ctx
->srp_ctx
.b
= NULL
;
92 ctx
->srp_ctx
.v
= NULL
;
93 ctx
->srp_ctx
.login
= NULL
;
94 ctx
->srp_ctx
.info
= NULL
;
95 ctx
->srp_ctx
.strength
= SRP_MINIMAL_N
;
96 ctx
->srp_ctx
.srp_Mask
= 0;
100 int SSL_SRP_CTX_free(struct ssl_st
*s
)
104 OPENSSL_free(s
->srp_ctx
.login
);
105 BN_free(s
->srp_ctx
.N
);
106 BN_free(s
->srp_ctx
.g
);
107 BN_free(s
->srp_ctx
.s
);
108 BN_free(s
->srp_ctx
.B
);
109 BN_free(s
->srp_ctx
.A
);
110 BN_free(s
->srp_ctx
.a
);
111 BN_free(s
->srp_ctx
.b
);
112 BN_free(s
->srp_ctx
.v
);
113 s
->srp_ctx
.TLS_ext_srp_username_callback
= NULL
;
114 s
->srp_ctx
.SRP_cb_arg
= NULL
;
115 s
->srp_ctx
.SRP_verify_param_callback
= NULL
;
116 s
->srp_ctx
.SRP_give_srp_client_pwd_callback
= NULL
;
125 s
->srp_ctx
.login
= NULL
;
126 s
->srp_ctx
.info
= NULL
;
127 s
->srp_ctx
.strength
= SRP_MINIMAL_N
;
128 s
->srp_ctx
.srp_Mask
= 0;
132 int SSL_SRP_CTX_init(struct ssl_st
*s
)
136 if ((s
== NULL
) || ((ctx
= s
->ctx
) == NULL
))
138 s
->srp_ctx
.SRP_cb_arg
= ctx
->srp_ctx
.SRP_cb_arg
;
139 /* set client Hello login callback */
140 s
->srp_ctx
.TLS_ext_srp_username_callback
=
141 ctx
->srp_ctx
.TLS_ext_srp_username_callback
;
142 /* set SRP N/g param callback for verification */
143 s
->srp_ctx
.SRP_verify_param_callback
=
144 ctx
->srp_ctx
.SRP_verify_param_callback
;
145 /* set SRP client passwd callback */
146 s
->srp_ctx
.SRP_give_srp_client_pwd_callback
=
147 ctx
->srp_ctx
.SRP_give_srp_client_pwd_callback
;
157 s
->srp_ctx
.login
= NULL
;
158 s
->srp_ctx
.info
= ctx
->srp_ctx
.info
;
159 s
->srp_ctx
.strength
= ctx
->srp_ctx
.strength
;
161 if (((ctx
->srp_ctx
.N
!= NULL
) &&
162 ((s
->srp_ctx
.N
= BN_dup(ctx
->srp_ctx
.N
)) == NULL
)) ||
163 ((ctx
->srp_ctx
.g
!= NULL
) &&
164 ((s
->srp_ctx
.g
= BN_dup(ctx
->srp_ctx
.g
)) == NULL
)) ||
165 ((ctx
->srp_ctx
.s
!= NULL
) &&
166 ((s
->srp_ctx
.s
= BN_dup(ctx
->srp_ctx
.s
)) == NULL
)) ||
167 ((ctx
->srp_ctx
.B
!= NULL
) &&
168 ((s
->srp_ctx
.B
= BN_dup(ctx
->srp_ctx
.B
)) == NULL
)) ||
169 ((ctx
->srp_ctx
.A
!= NULL
) &&
170 ((s
->srp_ctx
.A
= BN_dup(ctx
->srp_ctx
.A
)) == NULL
)) ||
171 ((ctx
->srp_ctx
.a
!= NULL
) &&
172 ((s
->srp_ctx
.a
= BN_dup(ctx
->srp_ctx
.a
)) == NULL
)) ||
173 ((ctx
->srp_ctx
.v
!= NULL
) &&
174 ((s
->srp_ctx
.v
= BN_dup(ctx
->srp_ctx
.v
)) == NULL
)) ||
175 ((ctx
->srp_ctx
.b
!= NULL
) &&
176 ((s
->srp_ctx
.b
= BN_dup(ctx
->srp_ctx
.b
)) == NULL
))) {
177 SSLerr(SSL_F_SSL_SRP_CTX_INIT
, ERR_R_BN_LIB
);
180 if ((ctx
->srp_ctx
.login
!= NULL
) &&
181 ((s
->srp_ctx
.login
= OPENSSL_strdup(ctx
->srp_ctx
.login
)) == NULL
)) {
182 SSLerr(SSL_F_SSL_SRP_CTX_INIT
, ERR_R_INTERNAL_ERROR
);
185 s
->srp_ctx
.srp_Mask
= ctx
->srp_ctx
.srp_Mask
;
189 OPENSSL_free(s
->srp_ctx
.login
);
190 BN_free(s
->srp_ctx
.N
);
191 BN_free(s
->srp_ctx
.g
);
192 BN_free(s
->srp_ctx
.s
);
193 BN_free(s
->srp_ctx
.B
);
194 BN_free(s
->srp_ctx
.A
);
195 BN_free(s
->srp_ctx
.a
);
196 BN_free(s
->srp_ctx
.b
);
197 BN_free(s
->srp_ctx
.v
);
201 int SSL_CTX_SRP_CTX_init(struct ssl_ctx_st
*ctx
)
206 ctx
->srp_ctx
.SRP_cb_arg
= NULL
;
207 /* set client Hello login callback */
208 ctx
->srp_ctx
.TLS_ext_srp_username_callback
= NULL
;
209 /* set SRP N/g param callback for verification */
210 ctx
->srp_ctx
.SRP_verify_param_callback
= NULL
;
211 /* set SRP client passwd callback */
212 ctx
->srp_ctx
.SRP_give_srp_client_pwd_callback
= NULL
;
214 ctx
->srp_ctx
.N
= NULL
;
215 ctx
->srp_ctx
.g
= NULL
;
216 ctx
->srp_ctx
.s
= NULL
;
217 ctx
->srp_ctx
.B
= NULL
;
218 ctx
->srp_ctx
.A
= NULL
;
219 ctx
->srp_ctx
.a
= NULL
;
220 ctx
->srp_ctx
.b
= NULL
;
221 ctx
->srp_ctx
.v
= NULL
;
222 ctx
->srp_ctx
.login
= NULL
;
223 ctx
->srp_ctx
.srp_Mask
= 0;
224 ctx
->srp_ctx
.info
= NULL
;
225 ctx
->srp_ctx
.strength
= SRP_MINIMAL_N
;
231 int SSL_srp_server_param_with_username(SSL
*s
, int *ad
)
233 unsigned char b
[SSL_MAX_MASTER_KEY_LENGTH
];
236 *ad
= SSL_AD_UNKNOWN_PSK_IDENTITY
;
237 if ((s
->srp_ctx
.TLS_ext_srp_username_callback
!= NULL
) &&
239 s
->srp_ctx
.TLS_ext_srp_username_callback(s
, ad
,
240 s
->srp_ctx
.SRP_cb_arg
)) !=
244 *ad
= SSL_AD_INTERNAL_ERROR
;
245 if ((s
->srp_ctx
.N
== NULL
) ||
246 (s
->srp_ctx
.g
== NULL
) ||
247 (s
->srp_ctx
.s
== NULL
) || (s
->srp_ctx
.v
== NULL
))
248 return SSL3_AL_FATAL
;
250 if (RAND_bytes(b
, sizeof(b
)) <= 0)
251 return SSL3_AL_FATAL
;
252 s
->srp_ctx
.b
= BN_bin2bn(b
, sizeof(b
), NULL
);
253 OPENSSL_cleanse(b
, sizeof(b
));
255 /* Calculate: B = (kv + g^b) % N */
257 return ((s
->srp_ctx
.B
=
258 SRP_Calc_B(s
->srp_ctx
.b
, s
->srp_ctx
.N
, s
->srp_ctx
.g
,
260 NULL
) ? SSL_ERROR_NONE
: SSL3_AL_FATAL
;
264 * If the server just has the raw password, make up a verifier entry on the
267 int SSL_set_srp_server_param_pw(SSL
*s
, const char *user
, const char *pass
,
270 SRP_gN
*GN
= SRP_get_default_gN(grp
);
273 s
->srp_ctx
.N
= BN_dup(GN
->N
);
274 s
->srp_ctx
.g
= BN_dup(GN
->g
);
275 BN_clear_free(s
->srp_ctx
.v
);
277 BN_clear_free(s
->srp_ctx
.s
);
279 if (!SRP_create_verifier_BN
280 (user
, pass
, &s
->srp_ctx
.s
, &s
->srp_ctx
.v
, GN
->N
, GN
->g
))
286 int SSL_set_srp_server_param(SSL
*s
, const BIGNUM
*N
, const BIGNUM
*g
,
287 BIGNUM
*sa
, BIGNUM
*v
, char *info
)
290 if (s
->srp_ctx
.N
!= NULL
) {
291 if (!BN_copy(s
->srp_ctx
.N
, N
)) {
292 BN_free(s
->srp_ctx
.N
);
296 s
->srp_ctx
.N
= BN_dup(N
);
299 if (s
->srp_ctx
.g
!= NULL
) {
300 if (!BN_copy(s
->srp_ctx
.g
, g
)) {
301 BN_free(s
->srp_ctx
.g
);
305 s
->srp_ctx
.g
= BN_dup(g
);
308 if (s
->srp_ctx
.s
!= NULL
) {
309 if (!BN_copy(s
->srp_ctx
.s
, sa
)) {
310 BN_free(s
->srp_ctx
.s
);
314 s
->srp_ctx
.s
= BN_dup(sa
);
317 if (s
->srp_ctx
.v
!= NULL
) {
318 if (!BN_copy(s
->srp_ctx
.v
, v
)) {
319 BN_free(s
->srp_ctx
.v
);
323 s
->srp_ctx
.v
= BN_dup(v
);
325 s
->srp_ctx
.info
= info
;
327 if (!(s
->srp_ctx
.N
) ||
328 !(s
->srp_ctx
.g
) || !(s
->srp_ctx
.s
) || !(s
->srp_ctx
.v
))
334 int srp_generate_server_master_secret(SSL
*s
)
336 BIGNUM
*K
= NULL
, *u
= NULL
;
337 int ret
= -1, tmp_len
= 0;
338 unsigned char *tmp
= NULL
;
340 if (!SRP_Verify_A_mod_N(s
->srp_ctx
.A
, s
->srp_ctx
.N
))
342 if ((u
= SRP_Calc_u(s
->srp_ctx
.A
, s
->srp_ctx
.B
, s
->srp_ctx
.N
)) == NULL
)
344 if ((K
= SRP_Calc_server_key(s
->srp_ctx
.A
, s
->srp_ctx
.v
, u
, s
->srp_ctx
.b
,
345 s
->srp_ctx
.N
)) == NULL
)
348 tmp_len
= BN_num_bytes(K
);
349 if ((tmp
= OPENSSL_malloc(tmp_len
)) == NULL
)
352 ret
= ssl_generate_master_secret(s
, tmp
, tmp_len
, 1);
360 int srp_generate_client_master_secret(SSL
*s
)
362 BIGNUM
*x
= NULL
, *u
= NULL
, *K
= NULL
;
363 int ret
= -1, tmp_len
= 0;
365 unsigned char *tmp
= NULL
;
368 * Checks if b % n == 0
370 if (SRP_Verify_B_mod_N(s
->srp_ctx
.B
, s
->srp_ctx
.N
) == 0)
372 if ((u
= SRP_Calc_u(s
->srp_ctx
.A
, s
->srp_ctx
.B
, s
->srp_ctx
.N
)) == NULL
)
374 if (s
->srp_ctx
.SRP_give_srp_client_pwd_callback
== NULL
)
378 s
->srp_ctx
.SRP_give_srp_client_pwd_callback(s
,
379 s
->srp_ctx
.SRP_cb_arg
)))
381 if ((x
= SRP_Calc_x(s
->srp_ctx
.s
, s
->srp_ctx
.login
, passwd
)) == NULL
)
383 if ((K
= SRP_Calc_client_key(s
->srp_ctx
.N
, s
->srp_ctx
.B
, s
->srp_ctx
.g
, x
,
384 s
->srp_ctx
.a
, u
)) == NULL
)
387 tmp_len
= BN_num_bytes(K
);
388 if ((tmp
= OPENSSL_malloc(tmp_len
)) == NULL
)
391 ret
= ssl_generate_master_secret(s
, tmp
, tmp_len
, 1);
396 OPENSSL_clear_free(passwd
, strlen(passwd
));
401 int srp_verify_server_param(SSL
*s
, int *al
)
403 SRP_CTX
*srp
= &s
->srp_ctx
;
405 * Sanity check parameters: we can quickly check B % N == 0 by checking B
408 if (BN_ucmp(srp
->g
, srp
->N
) >= 0 || BN_ucmp(srp
->B
, srp
->N
) >= 0
409 || BN_is_zero(srp
->B
)) {
410 *al
= SSL3_AD_ILLEGAL_PARAMETER
;
414 if (BN_num_bits(srp
->N
) < srp
->strength
) {
415 *al
= TLS1_AD_INSUFFICIENT_SECURITY
;
419 if (srp
->SRP_verify_param_callback
) {
420 if (srp
->SRP_verify_param_callback(s
, srp
->SRP_cb_arg
) <= 0) {
421 *al
= TLS1_AD_INSUFFICIENT_SECURITY
;
424 } else if (!SRP_check_known_gN_param(srp
->g
, srp
->N
)) {
425 *al
= TLS1_AD_INSUFFICIENT_SECURITY
;
432 int SRP_Calc_A_param(SSL
*s
)
434 unsigned char rnd
[SSL_MAX_MASTER_KEY_LENGTH
];
436 if (RAND_bytes(rnd
, sizeof(rnd
)) <= 0)
438 s
->srp_ctx
.a
= BN_bin2bn(rnd
, sizeof(rnd
), s
->srp_ctx
.a
);
439 OPENSSL_cleanse(rnd
, sizeof(rnd
));
442 (s
->srp_ctx
.A
= SRP_Calc_A(s
->srp_ctx
.a
, s
->srp_ctx
.N
, s
->srp_ctx
.g
)))
448 BIGNUM
*SSL_get_srp_g(SSL
*s
)
450 if (s
->srp_ctx
.g
!= NULL
)
452 return s
->ctx
->srp_ctx
.g
;
455 BIGNUM
*SSL_get_srp_N(SSL
*s
)
457 if (s
->srp_ctx
.N
!= NULL
)
459 return s
->ctx
->srp_ctx
.N
;
462 char *SSL_get_srp_username(SSL
*s
)
464 if (s
->srp_ctx
.login
!= NULL
)
465 return s
->srp_ctx
.login
;
466 return s
->ctx
->srp_ctx
.login
;
469 char *SSL_get_srp_userinfo(SSL
*s
)
471 if (s
->srp_ctx
.info
!= NULL
)
472 return s
->srp_ctx
.info
;
473 return s
->ctx
->srp_ctx
.info
;
476 # define tls1_ctx_ctrl ssl3_ctx_ctrl
477 # define tls1_ctx_callback_ctrl ssl3_ctx_callback_ctrl
479 int SSL_CTX_set_srp_username(SSL_CTX
*ctx
, char *name
)
481 return tls1_ctx_ctrl(ctx
, SSL_CTRL_SET_TLS_EXT_SRP_USERNAME
, 0, name
);
484 int SSL_CTX_set_srp_password(SSL_CTX
*ctx
, char *password
)
486 return tls1_ctx_ctrl(ctx
, SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD
, 0, password
);
489 int SSL_CTX_set_srp_strength(SSL_CTX
*ctx
, int strength
)
491 return tls1_ctx_ctrl(ctx
, SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH
, strength
,
495 int SSL_CTX_set_srp_verify_param_callback(SSL_CTX
*ctx
,
496 int (*cb
) (SSL
*, void *))
498 return tls1_ctx_callback_ctrl(ctx
, SSL_CTRL_SET_SRP_VERIFY_PARAM_CB
,
502 int SSL_CTX_set_srp_cb_arg(SSL_CTX
*ctx
, void *arg
)
504 return tls1_ctx_ctrl(ctx
, SSL_CTRL_SET_SRP_ARG
, 0, arg
);
507 int SSL_CTX_set_srp_username_callback(SSL_CTX
*ctx
,
508 int (*cb
) (SSL
*, int *, void *))
510 return tls1_ctx_callback_ctrl(ctx
, SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB
,
514 int SSL_CTX_set_srp_client_pwd_callback(SSL_CTX
*ctx
,
515 char *(*cb
) (SSL
*, void *))
517 return tls1_ctx_callback_ctrl(ctx
, SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB
,