2 /* Written by Christophe Renou (christophe.renou@edelweb.fr) with
3 * the precious help of Peter Sylvester (peter.sylvester@edelweb.fr)
4 * for the 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 #ifndef OPENSSL_NO_SRP
62 #include <openssl/rand.h>
63 #include <openssl/srp.h>
64 #include <openssl/err.h>
66 int SSL_CTX_SRP_CTX_free(struct ssl_ctx_st
*ctx
)
70 OPENSSL_free(ctx
->srp_ctx
.login
);
71 BN_free(ctx
->srp_ctx
.N
);
72 BN_free(ctx
->srp_ctx
.g
);
73 BN_free(ctx
->srp_ctx
.s
);
74 BN_free(ctx
->srp_ctx
.B
);
75 BN_free(ctx
->srp_ctx
.A
);
76 BN_free(ctx
->srp_ctx
.a
);
77 BN_free(ctx
->srp_ctx
.b
);
78 BN_free(ctx
->srp_ctx
.v
);
79 ctx
->srp_ctx
.TLS_ext_srp_username_callback
= NULL
;
80 ctx
->srp_ctx
.SRP_cb_arg
= NULL
;
81 ctx
->srp_ctx
.SRP_verify_param_callback
= NULL
;
82 ctx
->srp_ctx
.SRP_give_srp_client_pwd_callback
= NULL
;
83 ctx
->srp_ctx
.N
= NULL
;
84 ctx
->srp_ctx
.g
= NULL
;
85 ctx
->srp_ctx
.s
= NULL
;
86 ctx
->srp_ctx
.B
= NULL
;
87 ctx
->srp_ctx
.A
= NULL
;
88 ctx
->srp_ctx
.a
= NULL
;
89 ctx
->srp_ctx
.b
= NULL
;
90 ctx
->srp_ctx
.v
= NULL
;
91 ctx
->srp_ctx
.login
= NULL
;
92 ctx
->srp_ctx
.info
= NULL
;
93 ctx
->srp_ctx
.strength
= SRP_MINIMAL_N
;
94 ctx
->srp_ctx
.srp_Mask
= 0;
98 int SSL_SRP_CTX_free(struct ssl_st
*s
)
102 OPENSSL_free(s
->srp_ctx
.login
);
103 BN_free(s
->srp_ctx
.N
);
104 BN_free(s
->srp_ctx
.g
);
105 BN_free(s
->srp_ctx
.s
);
106 BN_free(s
->srp_ctx
.B
);
107 BN_free(s
->srp_ctx
.A
);
108 BN_free(s
->srp_ctx
.a
);
109 BN_free(s
->srp_ctx
.b
);
110 BN_free(s
->srp_ctx
.v
);
111 s
->srp_ctx
.TLS_ext_srp_username_callback
= NULL
;
112 s
->srp_ctx
.SRP_cb_arg
= NULL
;
113 s
->srp_ctx
.SRP_verify_param_callback
= NULL
;
114 s
->srp_ctx
.SRP_give_srp_client_pwd_callback
= NULL
;
123 s
->srp_ctx
.login
= NULL
;
124 s
->srp_ctx
.info
= NULL
;
125 s
->srp_ctx
.strength
= SRP_MINIMAL_N
;
126 s
->srp_ctx
.srp_Mask
= 0;
130 int SSL_SRP_CTX_init(struct ssl_st
*s
)
134 if ((s
== NULL
) || ((ctx
= s
->ctx
) == NULL
))
136 s
->srp_ctx
.SRP_cb_arg
= ctx
->srp_ctx
.SRP_cb_arg
;
137 /* set client Hello login callback */
138 s
->srp_ctx
.TLS_ext_srp_username_callback
= ctx
->srp_ctx
.TLS_ext_srp_username_callback
;
139 /* set SRP N/g param callback for verification */
140 s
->srp_ctx
.SRP_verify_param_callback
= ctx
->srp_ctx
.SRP_verify_param_callback
;
141 /* set SRP client passwd callback */
142 s
->srp_ctx
.SRP_give_srp_client_pwd_callback
= ctx
->srp_ctx
.SRP_give_srp_client_pwd_callback
;
152 s
->srp_ctx
.login
= NULL
;
153 s
->srp_ctx
.info
= ctx
->srp_ctx
.info
;
154 s
->srp_ctx
.strength
= ctx
->srp_ctx
.strength
;
156 if (((ctx
->srp_ctx
.N
!= NULL
) &&
157 ((s
->srp_ctx
.N
= BN_dup(ctx
->srp_ctx
.N
)) == NULL
)) ||
158 ((ctx
->srp_ctx
.g
!= NULL
) &&
159 ((s
->srp_ctx
.g
= BN_dup(ctx
->srp_ctx
.g
)) == NULL
)) ||
160 ((ctx
->srp_ctx
.s
!= NULL
) &&
161 ((s
->srp_ctx
.s
= BN_dup(ctx
->srp_ctx
.s
)) == NULL
)) ||
162 ((ctx
->srp_ctx
.B
!= NULL
) &&
163 ((s
->srp_ctx
.B
= BN_dup(ctx
->srp_ctx
.B
)) == NULL
)) ||
164 ((ctx
->srp_ctx
.A
!= NULL
) &&
165 ((s
->srp_ctx
.A
= BN_dup(ctx
->srp_ctx
.A
)) == NULL
)) ||
166 ((ctx
->srp_ctx
.a
!= NULL
) &&
167 ((s
->srp_ctx
.a
= BN_dup(ctx
->srp_ctx
.a
)) == NULL
)) ||
168 ((ctx
->srp_ctx
.v
!= NULL
) &&
169 ((s
->srp_ctx
.v
= BN_dup(ctx
->srp_ctx
.v
)) == NULL
)) ||
170 ((ctx
->srp_ctx
.b
!= NULL
) &&
171 ((s
->srp_ctx
.b
= BN_dup(ctx
->srp_ctx
.b
)) == NULL
)))
173 SSLerr(SSL_F_SSL_SRP_CTX_INIT
,ERR_R_BN_LIB
);
176 if ((ctx
->srp_ctx
.login
!= NULL
) &&
177 ((s
->srp_ctx
.login
= BUF_strdup(ctx
->srp_ctx
.login
)) == NULL
))
179 SSLerr(SSL_F_SSL_SRP_CTX_INIT
,ERR_R_INTERNAL_ERROR
);
182 s
->srp_ctx
.srp_Mask
= ctx
->srp_ctx
.srp_Mask
;
186 OPENSSL_free(s
->srp_ctx
.login
);
187 BN_free(s
->srp_ctx
.N
);
188 BN_free(s
->srp_ctx
.g
);
189 BN_free(s
->srp_ctx
.s
);
190 BN_free(s
->srp_ctx
.B
);
191 BN_free(s
->srp_ctx
.A
);
192 BN_free(s
->srp_ctx
.a
);
193 BN_free(s
->srp_ctx
.b
);
194 BN_free(s
->srp_ctx
.v
);
198 int SSL_CTX_SRP_CTX_init(struct ssl_ctx_st
*ctx
)
203 ctx
->srp_ctx
.SRP_cb_arg
= NULL
;
204 /* set client Hello login callback */
205 ctx
->srp_ctx
.TLS_ext_srp_username_callback
= NULL
;
206 /* set SRP N/g param callback for verification */
207 ctx
->srp_ctx
.SRP_verify_param_callback
= NULL
;
208 /* set SRP client passwd callback */
209 ctx
->srp_ctx
.SRP_give_srp_client_pwd_callback
= NULL
;
211 ctx
->srp_ctx
.N
= NULL
;
212 ctx
->srp_ctx
.g
= NULL
;
213 ctx
->srp_ctx
.s
= NULL
;
214 ctx
->srp_ctx
.B
= NULL
;
215 ctx
->srp_ctx
.A
= NULL
;
216 ctx
->srp_ctx
.a
= NULL
;
217 ctx
->srp_ctx
.b
= NULL
;
218 ctx
->srp_ctx
.v
= NULL
;
219 ctx
->srp_ctx
.login
= NULL
;
220 ctx
->srp_ctx
.srp_Mask
= 0;
221 ctx
->srp_ctx
.info
= NULL
;
222 ctx
->srp_ctx
.strength
= SRP_MINIMAL_N
;
228 int SSL_srp_server_param_with_username(SSL
*s
, int *ad
)
230 unsigned char b
[SSL_MAX_MASTER_KEY_LENGTH
];
233 *ad
= SSL_AD_UNKNOWN_PSK_IDENTITY
;
234 if ((s
->srp_ctx
.TLS_ext_srp_username_callback
!=NULL
) &&
235 ((al
= s
->srp_ctx
.TLS_ext_srp_username_callback(s
, ad
, s
->srp_ctx
.SRP_cb_arg
))!=SSL_ERROR_NONE
))
238 *ad
= SSL_AD_INTERNAL_ERROR
;
239 if ((s
->srp_ctx
.N
== NULL
) ||
240 (s
->srp_ctx
.g
== NULL
) ||
241 (s
->srp_ctx
.s
== NULL
) ||
242 (s
->srp_ctx
.v
== NULL
))
243 return SSL3_AL_FATAL
;
245 if (RAND_bytes(b
, sizeof(b
)) <= 0)
246 return SSL3_AL_FATAL
;
247 s
->srp_ctx
.b
= BN_bin2bn(b
,sizeof(b
),NULL
);
248 OPENSSL_cleanse(b
,sizeof(b
));
250 /* Calculate: B = (kv + g^b) % N */
252 return ((s
->srp_ctx
.B
= SRP_Calc_B(s
->srp_ctx
.b
, s
->srp_ctx
.N
, s
->srp_ctx
.g
, s
->srp_ctx
.v
)) != NULL
)?
253 SSL_ERROR_NONE
:SSL3_AL_FATAL
;
256 /* If the server just has the raw password, make up a verifier entry on the fly */
257 int SSL_set_srp_server_param_pw(SSL
*s
, const char *user
, const char *pass
, const char *grp
)
259 SRP_gN
*GN
= SRP_get_default_gN(grp
);
260 if(GN
== NULL
) return -1;
261 s
->srp_ctx
.N
= BN_dup(GN
->N
);
262 s
->srp_ctx
.g
= BN_dup(GN
->g
);
263 if(s
->srp_ctx
.v
!= NULL
)
265 BN_clear_free(s
->srp_ctx
.v
);
268 if(s
->srp_ctx
.s
!= NULL
)
270 BN_clear_free(s
->srp_ctx
.s
);
273 if(!SRP_create_verifier_BN(user
, pass
, &s
->srp_ctx
.s
, &s
->srp_ctx
.v
, GN
->N
, GN
->g
)) return -1;
278 int SSL_set_srp_server_param(SSL
*s
, const BIGNUM
*N
, const BIGNUM
*g
,
279 BIGNUM
*sa
, BIGNUM
*v
, char *info
)
283 if (s
->srp_ctx
.N
!= NULL
)
285 if (!BN_copy(s
->srp_ctx
.N
,N
))
287 BN_free(s
->srp_ctx
.N
);
292 s
->srp_ctx
.N
= BN_dup(N
);
296 if (s
->srp_ctx
.g
!= NULL
)
298 if (!BN_copy(s
->srp_ctx
.g
,g
))
300 BN_free(s
->srp_ctx
.g
);
305 s
->srp_ctx
.g
= BN_dup(g
);
309 if (s
->srp_ctx
.s
!= NULL
)
311 if (!BN_copy(s
->srp_ctx
.s
,sa
))
313 BN_free(s
->srp_ctx
.s
);
318 s
->srp_ctx
.s
= BN_dup(sa
);
322 if (s
->srp_ctx
.v
!= NULL
)
324 if (!BN_copy(s
->srp_ctx
.v
,v
))
326 BN_free(s
->srp_ctx
.v
);
331 s
->srp_ctx
.v
= BN_dup(v
);
333 s
->srp_ctx
.info
= info
;
335 if (!(s
->srp_ctx
.N
) ||
344 int SRP_generate_server_master_secret(SSL
*s
,unsigned char *master_key
)
346 BIGNUM
*K
= NULL
, *u
= NULL
;
347 int ret
= -1, tmp_len
;
348 unsigned char *tmp
= NULL
;
350 if (!SRP_Verify_A_mod_N(s
->srp_ctx
.A
,s
->srp_ctx
.N
))
352 if (!(u
= SRP_Calc_u(s
->srp_ctx
.A
,s
->srp_ctx
.B
,s
->srp_ctx
.N
)))
354 if (!(K
= SRP_Calc_server_key(s
->srp_ctx
.A
, s
->srp_ctx
.v
, u
, s
->srp_ctx
.b
, s
->srp_ctx
.N
)))
357 tmp_len
= BN_num_bytes(K
);
358 if ((tmp
= OPENSSL_malloc(tmp_len
)) == NULL
)
361 ret
= s
->method
->ssl3_enc
->generate_master_secret(s
,master_key
,tmp
,tmp_len
);
365 OPENSSL_cleanse(tmp
,tmp_len
) ;
374 int SRP_generate_client_master_secret(SSL
*s
,unsigned char *master_key
)
376 BIGNUM
*x
= NULL
, *u
= NULL
, *K
= NULL
;
377 int ret
= -1, tmp_len
;
379 unsigned char *tmp
= NULL
;
381 /* Checks if b % n == 0
383 if (SRP_Verify_B_mod_N(s
->srp_ctx
.B
,s
->srp_ctx
.N
)==0) goto err
;
384 if (!(u
= SRP_Calc_u(s
->srp_ctx
.A
,s
->srp_ctx
.B
,s
->srp_ctx
.N
))) goto err
;
385 if (s
->srp_ctx
.SRP_give_srp_client_pwd_callback
== NULL
) goto err
;
386 if (!(passwd
= s
->srp_ctx
.SRP_give_srp_client_pwd_callback(s
, s
->srp_ctx
.SRP_cb_arg
))) goto err
;
387 if (!(x
= SRP_Calc_x(s
->srp_ctx
.s
,s
->srp_ctx
.login
,passwd
))) goto err
;
388 if (!(K
= SRP_Calc_client_key(s
->srp_ctx
.N
, s
->srp_ctx
.B
, s
->srp_ctx
.g
, x
, s
->srp_ctx
.a
, u
))) goto err
;
390 tmp_len
= BN_num_bytes(K
);
391 if ((tmp
= OPENSSL_malloc(tmp_len
)) == NULL
) goto err
;
393 ret
= s
->method
->ssl3_enc
->generate_master_secret(s
,master_key
,tmp
,tmp_len
);
397 OPENSSL_cleanse(tmp
,tmp_len
) ;
404 OPENSSL_cleanse(passwd
,strlen(passwd
)) ;
405 OPENSSL_free(passwd
);
411 int SRP_Calc_A_param(SSL
*s
)
413 unsigned char rnd
[SSL_MAX_MASTER_KEY_LENGTH
];
415 if (BN_num_bits(s
->srp_ctx
.N
) < s
->srp_ctx
.strength
)
418 if (s
->srp_ctx
.SRP_verify_param_callback
==NULL
&&
419 !SRP_check_known_gN_param(s
->srp_ctx
.g
,s
->srp_ctx
.N
))
422 RAND_bytes(rnd
, sizeof(rnd
));
423 s
->srp_ctx
.a
= BN_bin2bn(rnd
, sizeof(rnd
), s
->srp_ctx
.a
);
424 OPENSSL_cleanse(rnd
, sizeof(rnd
));
426 if (!(s
->srp_ctx
.A
= SRP_Calc_A(s
->srp_ctx
.a
,s
->srp_ctx
.N
,s
->srp_ctx
.g
)))
429 /* We can have a callback to verify SRP param!! */
430 if (s
->srp_ctx
.SRP_verify_param_callback
!=NULL
)
431 return s
->srp_ctx
.SRP_verify_param_callback(s
,s
->srp_ctx
.SRP_cb_arg
);
436 BIGNUM
*SSL_get_srp_g(SSL
*s
)
438 if (s
->srp_ctx
.g
!= NULL
)
440 return s
->ctx
->srp_ctx
.g
;
443 BIGNUM
*SSL_get_srp_N(SSL
*s
)
445 if (s
->srp_ctx
.N
!= NULL
)
447 return s
->ctx
->srp_ctx
.N
;
450 char *SSL_get_srp_username(SSL
*s
)
452 if (s
->srp_ctx
.login
!= NULL
)
453 return s
->srp_ctx
.login
;
454 return s
->ctx
->srp_ctx
.login
;
457 char *SSL_get_srp_userinfo(SSL
*s
)
459 if (s
->srp_ctx
.info
!= NULL
)
460 return s
->srp_ctx
.info
;
461 return s
->ctx
->srp_ctx
.info
;
464 #define tls1_ctx_ctrl ssl3_ctx_ctrl
465 #define tls1_ctx_callback_ctrl ssl3_ctx_callback_ctrl
467 int SSL_CTX_set_srp_username(SSL_CTX
*ctx
,char *name
)
469 return tls1_ctx_ctrl(ctx
,SSL_CTRL_SET_TLS_EXT_SRP_USERNAME
,0,name
);
472 int SSL_CTX_set_srp_password(SSL_CTX
*ctx
,char *password
)
474 return tls1_ctx_ctrl(ctx
,SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD
,0,password
);
477 int SSL_CTX_set_srp_strength(SSL_CTX
*ctx
, int strength
)
479 return tls1_ctx_ctrl(ctx
, SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH
, strength
,
483 int SSL_CTX_set_srp_verify_param_callback(SSL_CTX
*ctx
, int (*cb
)(SSL
*,void *))
485 return tls1_ctx_callback_ctrl(ctx
,SSL_CTRL_SET_SRP_VERIFY_PARAM_CB
,
489 int SSL_CTX_set_srp_cb_arg(SSL_CTX
*ctx
, void *arg
)
491 return tls1_ctx_ctrl(ctx
,SSL_CTRL_SET_SRP_ARG
,0,arg
);
494 int SSL_CTX_set_srp_username_callback(SSL_CTX
*ctx
,
495 int (*cb
)(SSL
*,int *,void *))
497 return tls1_ctx_callback_ctrl(ctx
,SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB
,
501 int SSL_CTX_set_srp_client_pwd_callback(SSL_CTX
*ctx
, char *(*cb
)(SSL
*,void *))
503 return tls1_ctx_callback_ctrl(ctx
,SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB
,