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 #include <openssl/crypto.h>
62 #include <openssl/rand.h>
63 #include <openssl/err.h>
66 #ifndef OPENSSL_NO_SRP
67 #include <openssl/srp.h>
69 int SSL_CTX_SRP_CTX_free(struct ssl_ctx_st
*ctx
)
73 OPENSSL_free(ctx
->srp_ctx
.login
);
74 BN_free(ctx
->srp_ctx
.N
);
75 BN_free(ctx
->srp_ctx
.g
);
76 BN_free(ctx
->srp_ctx
.s
);
77 BN_free(ctx
->srp_ctx
.B
);
78 BN_free(ctx
->srp_ctx
.A
);
79 BN_free(ctx
->srp_ctx
.a
);
80 BN_free(ctx
->srp_ctx
.b
);
81 BN_free(ctx
->srp_ctx
.v
);
82 ctx
->srp_ctx
.TLS_ext_srp_username_callback
= NULL
;
83 ctx
->srp_ctx
.SRP_cb_arg
= NULL
;
84 ctx
->srp_ctx
.SRP_verify_param_callback
= NULL
;
85 ctx
->srp_ctx
.SRP_give_srp_client_pwd_callback
= NULL
;
86 ctx
->srp_ctx
.N
= NULL
;
87 ctx
->srp_ctx
.g
= NULL
;
88 ctx
->srp_ctx
.s
= NULL
;
89 ctx
->srp_ctx
.B
= NULL
;
90 ctx
->srp_ctx
.A
= NULL
;
91 ctx
->srp_ctx
.a
= NULL
;
92 ctx
->srp_ctx
.b
= NULL
;
93 ctx
->srp_ctx
.v
= NULL
;
94 ctx
->srp_ctx
.login
= NULL
;
95 ctx
->srp_ctx
.info
= NULL
;
96 ctx
->srp_ctx
.strength
= SRP_MINIMAL_N
;
97 ctx
->srp_ctx
.srp_Mask
= 0;
101 int SSL_SRP_CTX_free(struct ssl_st
*s
)
105 OPENSSL_free(s
->srp_ctx
.login
);
106 BN_free(s
->srp_ctx
.N
);
107 BN_free(s
->srp_ctx
.g
);
108 BN_free(s
->srp_ctx
.s
);
109 BN_free(s
->srp_ctx
.B
);
110 BN_free(s
->srp_ctx
.A
);
111 BN_free(s
->srp_ctx
.a
);
112 BN_free(s
->srp_ctx
.b
);
113 BN_free(s
->srp_ctx
.v
);
114 s
->srp_ctx
.TLS_ext_srp_username_callback
= NULL
;
115 s
->srp_ctx
.SRP_cb_arg
= NULL
;
116 s
->srp_ctx
.SRP_verify_param_callback
= NULL
;
117 s
->srp_ctx
.SRP_give_srp_client_pwd_callback
= NULL
;
126 s
->srp_ctx
.login
= NULL
;
127 s
->srp_ctx
.info
= NULL
;
128 s
->srp_ctx
.strength
= SRP_MINIMAL_N
;
129 s
->srp_ctx
.srp_Mask
= 0;
133 int SSL_SRP_CTX_init(struct ssl_st
*s
)
137 if ((s
== NULL
) || ((ctx
= s
->ctx
) == NULL
))
139 s
->srp_ctx
.SRP_cb_arg
= ctx
->srp_ctx
.SRP_cb_arg
;
140 /* set client Hello login callback */
141 s
->srp_ctx
.TLS_ext_srp_username_callback
=
142 ctx
->srp_ctx
.TLS_ext_srp_username_callback
;
143 /* set SRP N/g param callback for verification */
144 s
->srp_ctx
.SRP_verify_param_callback
=
145 ctx
->srp_ctx
.SRP_verify_param_callback
;
146 /* set SRP client passwd callback */
147 s
->srp_ctx
.SRP_give_srp_client_pwd_callback
=
148 ctx
->srp_ctx
.SRP_give_srp_client_pwd_callback
;
158 s
->srp_ctx
.login
= NULL
;
159 s
->srp_ctx
.info
= ctx
->srp_ctx
.info
;
160 s
->srp_ctx
.strength
= ctx
->srp_ctx
.strength
;
162 if (((ctx
->srp_ctx
.N
!= NULL
) &&
163 ((s
->srp_ctx
.N
= BN_dup(ctx
->srp_ctx
.N
)) == NULL
)) ||
164 ((ctx
->srp_ctx
.g
!= NULL
) &&
165 ((s
->srp_ctx
.g
= BN_dup(ctx
->srp_ctx
.g
)) == NULL
)) ||
166 ((ctx
->srp_ctx
.s
!= NULL
) &&
167 ((s
->srp_ctx
.s
= BN_dup(ctx
->srp_ctx
.s
)) == NULL
)) ||
168 ((ctx
->srp_ctx
.B
!= NULL
) &&
169 ((s
->srp_ctx
.B
= BN_dup(ctx
->srp_ctx
.B
)) == NULL
)) ||
170 ((ctx
->srp_ctx
.A
!= NULL
) &&
171 ((s
->srp_ctx
.A
= BN_dup(ctx
->srp_ctx
.A
)) == NULL
)) ||
172 ((ctx
->srp_ctx
.a
!= NULL
) &&
173 ((s
->srp_ctx
.a
= BN_dup(ctx
->srp_ctx
.a
)) == NULL
)) ||
174 ((ctx
->srp_ctx
.v
!= NULL
) &&
175 ((s
->srp_ctx
.v
= BN_dup(ctx
->srp_ctx
.v
)) == NULL
)) ||
176 ((ctx
->srp_ctx
.b
!= NULL
) &&
177 ((s
->srp_ctx
.b
= BN_dup(ctx
->srp_ctx
.b
)) == NULL
))) {
178 SSLerr(SSL_F_SSL_SRP_CTX_INIT
, ERR_R_BN_LIB
);
181 if ((ctx
->srp_ctx
.login
!= NULL
) &&
182 ((s
->srp_ctx
.login
= BUF_strdup(ctx
->srp_ctx
.login
)) == NULL
)) {
183 SSLerr(SSL_F_SSL_SRP_CTX_INIT
, ERR_R_INTERNAL_ERROR
);
186 s
->srp_ctx
.srp_Mask
= ctx
->srp_ctx
.srp_Mask
;
190 OPENSSL_free(s
->srp_ctx
.login
);
191 BN_free(s
->srp_ctx
.N
);
192 BN_free(s
->srp_ctx
.g
);
193 BN_free(s
->srp_ctx
.s
);
194 BN_free(s
->srp_ctx
.B
);
195 BN_free(s
->srp_ctx
.A
);
196 BN_free(s
->srp_ctx
.a
);
197 BN_free(s
->srp_ctx
.b
);
198 BN_free(s
->srp_ctx
.v
);
202 int SSL_CTX_SRP_CTX_init(struct ssl_ctx_st
*ctx
)
207 ctx
->srp_ctx
.SRP_cb_arg
= NULL
;
208 /* set client Hello login callback */
209 ctx
->srp_ctx
.TLS_ext_srp_username_callback
= NULL
;
210 /* set SRP N/g param callback for verification */
211 ctx
->srp_ctx
.SRP_verify_param_callback
= NULL
;
212 /* set SRP client passwd callback */
213 ctx
->srp_ctx
.SRP_give_srp_client_pwd_callback
= NULL
;
215 ctx
->srp_ctx
.N
= NULL
;
216 ctx
->srp_ctx
.g
= NULL
;
217 ctx
->srp_ctx
.s
= NULL
;
218 ctx
->srp_ctx
.B
= NULL
;
219 ctx
->srp_ctx
.A
= NULL
;
220 ctx
->srp_ctx
.a
= NULL
;
221 ctx
->srp_ctx
.b
= NULL
;
222 ctx
->srp_ctx
.v
= NULL
;
223 ctx
->srp_ctx
.login
= NULL
;
224 ctx
->srp_ctx
.srp_Mask
= 0;
225 ctx
->srp_ctx
.info
= NULL
;
226 ctx
->srp_ctx
.strength
= SRP_MINIMAL_N
;
232 int SSL_srp_server_param_with_username(SSL
*s
, int *ad
)
234 unsigned char b
[SSL_MAX_MASTER_KEY_LENGTH
];
237 *ad
= SSL_AD_UNKNOWN_PSK_IDENTITY
;
238 if ((s
->srp_ctx
.TLS_ext_srp_username_callback
!= NULL
) &&
240 s
->srp_ctx
.TLS_ext_srp_username_callback(s
, ad
,
241 s
->srp_ctx
.SRP_cb_arg
)) !=
245 *ad
= SSL_AD_INTERNAL_ERROR
;
246 if ((s
->srp_ctx
.N
== NULL
) ||
247 (s
->srp_ctx
.g
== NULL
) ||
248 (s
->srp_ctx
.s
== NULL
) || (s
->srp_ctx
.v
== NULL
))
249 return SSL3_AL_FATAL
;
251 if (RAND_bytes(b
, sizeof(b
)) <= 0)
252 return SSL3_AL_FATAL
;
253 s
->srp_ctx
.b
= BN_bin2bn(b
, sizeof(b
), NULL
);
254 OPENSSL_cleanse(b
, sizeof(b
));
256 /* Calculate: B = (kv + g^b) % N */
258 return ((s
->srp_ctx
.B
=
259 SRP_Calc_B(s
->srp_ctx
.b
, s
->srp_ctx
.N
, s
->srp_ctx
.g
,
261 NULL
) ? SSL_ERROR_NONE
: SSL3_AL_FATAL
;
265 * If the server just has the raw password, make up a verifier entry on the
268 int SSL_set_srp_server_param_pw(SSL
*s
, const char *user
, const char *pass
,
271 SRP_gN
*GN
= SRP_get_default_gN(grp
);
274 s
->srp_ctx
.N
= BN_dup(GN
->N
);
275 s
->srp_ctx
.g
= BN_dup(GN
->g
);
276 BN_clear_free(s
->srp_ctx
.v
);
278 BN_clear_free(s
->srp_ctx
.s
);
280 if (!SRP_create_verifier_BN
281 (user
, pass
, &s
->srp_ctx
.s
, &s
->srp_ctx
.v
, GN
->N
, GN
->g
))
287 int SSL_set_srp_server_param(SSL
*s
, const BIGNUM
*N
, const BIGNUM
*g
,
288 BIGNUM
*sa
, BIGNUM
*v
, char *info
)
291 if (s
->srp_ctx
.N
!= NULL
) {
292 if (!BN_copy(s
->srp_ctx
.N
, N
)) {
293 BN_free(s
->srp_ctx
.N
);
297 s
->srp_ctx
.N
= BN_dup(N
);
300 if (s
->srp_ctx
.g
!= NULL
) {
301 if (!BN_copy(s
->srp_ctx
.g
, g
)) {
302 BN_free(s
->srp_ctx
.g
);
306 s
->srp_ctx
.g
= BN_dup(g
);
309 if (s
->srp_ctx
.s
!= NULL
) {
310 if (!BN_copy(s
->srp_ctx
.s
, sa
)) {
311 BN_free(s
->srp_ctx
.s
);
315 s
->srp_ctx
.s
= BN_dup(sa
);
318 if (s
->srp_ctx
.v
!= NULL
) {
319 if (!BN_copy(s
->srp_ctx
.v
, v
)) {
320 BN_free(s
->srp_ctx
.v
);
324 s
->srp_ctx
.v
= BN_dup(v
);
326 s
->srp_ctx
.info
= info
;
328 if (!(s
->srp_ctx
.N
) ||
329 !(s
->srp_ctx
.g
) || !(s
->srp_ctx
.s
) || !(s
->srp_ctx
.v
))
335 int srp_generate_server_master_secret(SSL
*s
)
337 BIGNUM
*K
= NULL
, *u
= NULL
;
338 int ret
= -1, tmp_len
= 0;
339 unsigned char *tmp
= NULL
;
341 if (!SRP_Verify_A_mod_N(s
->srp_ctx
.A
, s
->srp_ctx
.N
))
343 if ((u
= SRP_Calc_u(s
->srp_ctx
.A
, s
->srp_ctx
.B
, s
->srp_ctx
.N
)) == NULL
)
345 if ((K
= SRP_Calc_server_key(s
->srp_ctx
.A
, s
->srp_ctx
.v
, u
, s
->srp_ctx
.b
,
346 s
->srp_ctx
.N
)) == NULL
)
349 tmp_len
= BN_num_bytes(K
);
350 if ((tmp
= OPENSSL_malloc(tmp_len
)) == NULL
)
353 ret
= ssl_generate_master_secret(s
, tmp
, tmp_len
, 1);
361 int srp_generate_client_master_secret(SSL
*s
)
363 BIGNUM
*x
= NULL
, *u
= NULL
, *K
= NULL
;
364 int ret
= -1, tmp_len
= 0;
366 unsigned char *tmp
= NULL
;
369 * Checks if b % n == 0
371 if (SRP_Verify_B_mod_N(s
->srp_ctx
.B
, s
->srp_ctx
.N
) == 0)
373 if ((u
= SRP_Calc_u(s
->srp_ctx
.A
, s
->srp_ctx
.B
, s
->srp_ctx
.N
)) == NULL
)
375 if (s
->srp_ctx
.SRP_give_srp_client_pwd_callback
== NULL
)
379 s
->srp_ctx
.SRP_give_srp_client_pwd_callback(s
,
380 s
->srp_ctx
.SRP_cb_arg
)))
382 if ((x
= SRP_Calc_x(s
->srp_ctx
.s
, s
->srp_ctx
.login
, passwd
)) == NULL
)
384 if ((K
= SRP_Calc_client_key(s
->srp_ctx
.N
, s
->srp_ctx
.B
, s
->srp_ctx
.g
, x
,
385 s
->srp_ctx
.a
, u
)) == NULL
)
388 tmp_len
= BN_num_bytes(K
);
389 if ((tmp
= OPENSSL_malloc(tmp_len
)) == NULL
)
392 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
,