tls_srp.c revision 296341
1/* ssl/tls_srp.c */
2/*
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.
6 */
7/* ====================================================================
8 * Copyright (c) 2004-2011 The OpenSSL Project.  All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 *
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions and the following disclaimer.
16 *
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
20 *    distribution.
21 *
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/)"
26 *
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.
31 *
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.
35 *
36 * 6. Redistributions of any form whatsoever must retain the following
37 *    acknowledgment:
38 *    "This product includes software developed by the OpenSSL Project
39 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
40 *
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 * ====================================================================
54 *
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).
58 *
59 */
60#include "ssl_locl.h"
61#ifndef OPENSSL_NO_SRP
62
63# include <openssl/rand.h>
64# include <openssl/srp.h>
65# include <openssl/err.h>
66
67int SSL_CTX_SRP_CTX_free(struct ssl_ctx_st *ctx)
68{
69    if (ctx == NULL)
70        return 0;
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;
96    return (1);
97}
98
99int SSL_SRP_CTX_free(struct ssl_st *s)
100{
101    if (s == NULL)
102        return 0;
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;
116    s->srp_ctx.N = NULL;
117    s->srp_ctx.g = NULL;
118    s->srp_ctx.s = NULL;
119    s->srp_ctx.B = NULL;
120    s->srp_ctx.A = NULL;
121    s->srp_ctx.a = NULL;
122    s->srp_ctx.b = NULL;
123    s->srp_ctx.v = 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;
128    return (1);
129}
130
131int SSL_SRP_CTX_init(struct ssl_st *s)
132{
133    SSL_CTX *ctx;
134
135    if ((s == NULL) || ((ctx = s->ctx) == NULL))
136        return 0;
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;
147
148    s->srp_ctx.N = NULL;
149    s->srp_ctx.g = NULL;
150    s->srp_ctx.s = NULL;
151    s->srp_ctx.B = NULL;
152    s->srp_ctx.A = NULL;
153    s->srp_ctx.a = NULL;
154    s->srp_ctx.b = NULL;
155    s->srp_ctx.v = NULL;
156    s->srp_ctx.login = NULL;
157    s->srp_ctx.info = ctx->srp_ctx.info;
158    s->srp_ctx.strength = ctx->srp_ctx.strength;
159
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);
177        goto err;
178    }
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);
182        goto err;
183    }
184    s->srp_ctx.srp_Mask = ctx->srp_ctx.srp_Mask;
185
186    return (1);
187 err:
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);
197    return (0);
198}
199
200int SSL_CTX_SRP_CTX_init(struct ssl_ctx_st *ctx)
201{
202    if (ctx == NULL)
203        return 0;
204
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;
212
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;
225
226    return (1);
227}
228
229/* server side */
230int SSL_srp_server_param_with_username(SSL *s, int *ad)
231{
232    unsigned char b[SSL_MAX_MASTER_KEY_LENGTH];
233    int al;
234
235    *ad = SSL_AD_UNKNOWN_PSK_IDENTITY;
236    if ((s->srp_ctx.TLS_ext_srp_username_callback != NULL) &&
237        ((al =
238          s->srp_ctx.TLS_ext_srp_username_callback(s, ad,
239                                                   s->srp_ctx.SRP_cb_arg)) !=
240         SSL_ERROR_NONE))
241        return al;
242
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;
248
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));
253
254    /* Calculate:  B = (kv + g^b) % N  */
255
256    return ((s->srp_ctx.B =
257             SRP_Calc_B(s->srp_ctx.b, s->srp_ctx.N, s->srp_ctx.g,
258                        s->srp_ctx.v)) !=
259            NULL) ? SSL_ERROR_NONE : SSL3_AL_FATAL;
260}
261
262/*
263 * If the server just has the raw password, make up a verifier entry on the
264 * fly
265 */
266int SSL_set_srp_server_param_pw(SSL *s, const char *user, const char *pass,
267                                const char *grp)
268{
269    SRP_gN *GN = SRP_get_default_gN(grp);
270    if (GN == NULL)
271        return -1;
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);
276        s->srp_ctx.v = NULL;
277    }
278    if (s->srp_ctx.s != NULL) {
279        BN_clear_free(s->srp_ctx.s);
280        s->srp_ctx.s = NULL;
281    }
282    if (!SRP_create_verifier_BN
283        (user, pass, &s->srp_ctx.s, &s->srp_ctx.v, GN->N, GN->g))
284        return -1;
285
286    return 1;
287}
288
289int SSL_set_srp_server_param(SSL *s, const BIGNUM *N, const BIGNUM *g,
290                             BIGNUM *sa, BIGNUM *v, char *info)
291{
292    if (N != NULL) {
293        if (s->srp_ctx.N != NULL) {
294            if (!BN_copy(s->srp_ctx.N, N)) {
295                BN_free(s->srp_ctx.N);
296                s->srp_ctx.N = NULL;
297            }
298        } else
299            s->srp_ctx.N = BN_dup(N);
300    }
301    if (g != NULL) {
302        if (s->srp_ctx.g != NULL) {
303            if (!BN_copy(s->srp_ctx.g, g)) {
304                BN_free(s->srp_ctx.g);
305                s->srp_ctx.g = NULL;
306            }
307        } else
308            s->srp_ctx.g = BN_dup(g);
309    }
310    if (sa != NULL) {
311        if (s->srp_ctx.s != NULL) {
312            if (!BN_copy(s->srp_ctx.s, sa)) {
313                BN_free(s->srp_ctx.s);
314                s->srp_ctx.s = NULL;
315            }
316        } else
317            s->srp_ctx.s = BN_dup(sa);
318    }
319    if (v != NULL) {
320        if (s->srp_ctx.v != NULL) {
321            if (!BN_copy(s->srp_ctx.v, v)) {
322                BN_free(s->srp_ctx.v);
323                s->srp_ctx.v = NULL;
324            }
325        } else
326            s->srp_ctx.v = BN_dup(v);
327    }
328    s->srp_ctx.info = info;
329
330    if (!(s->srp_ctx.N) ||
331        !(s->srp_ctx.g) || !(s->srp_ctx.s) || !(s->srp_ctx.v))
332        return -1;
333
334    return 1;
335}
336
337int SRP_generate_server_master_secret(SSL *s, unsigned char *master_key)
338{
339    BIGNUM *K = NULL, *u = NULL;
340    int ret = -1, tmp_len;
341    unsigned char *tmp = NULL;
342
343    if (!SRP_Verify_A_mod_N(s->srp_ctx.A, s->srp_ctx.N))
344        goto err;
345    if (!(u = SRP_Calc_u(s->srp_ctx.A, s->srp_ctx.B, s->srp_ctx.N)))
346        goto err;
347    if (!
348        (K =
349         SRP_Calc_server_key(s->srp_ctx.A, s->srp_ctx.v, u, s->srp_ctx.b,
350                             s->srp_ctx.N)))
351        goto err;
352
353    tmp_len = BN_num_bytes(K);
354    if ((tmp = OPENSSL_malloc(tmp_len)) == NULL)
355        goto err;
356    BN_bn2bin(K, tmp);
357    ret =
358        s->method->ssl3_enc->generate_master_secret(s, master_key, tmp,
359                                                    tmp_len);
360 err:
361    if (tmp) {
362        OPENSSL_cleanse(tmp, tmp_len);
363        OPENSSL_free(tmp);
364    }
365    BN_clear_free(K);
366    BN_clear_free(u);
367    return ret;
368}
369
370/* client side */
371int SRP_generate_client_master_secret(SSL *s, unsigned char *master_key)
372{
373    BIGNUM *x = NULL, *u = NULL, *K = NULL;
374    int ret = -1, tmp_len;
375    char *passwd = NULL;
376    unsigned char *tmp = NULL;
377
378    /*
379     * Checks if b % n == 0
380     */
381    if (SRP_Verify_B_mod_N(s->srp_ctx.B, s->srp_ctx.N) == 0)
382        goto err;
383    if (!(u = SRP_Calc_u(s->srp_ctx.A, s->srp_ctx.B, s->srp_ctx.N)))
384        goto err;
385    if (s->srp_ctx.SRP_give_srp_client_pwd_callback == NULL)
386        goto err;
387    if (!
388        (passwd =
389         s->srp_ctx.SRP_give_srp_client_pwd_callback(s,
390                                                     s->srp_ctx.SRP_cb_arg)))
391        goto err;
392    if (!(x = SRP_Calc_x(s->srp_ctx.s, s->srp_ctx.login, passwd)))
393        goto err;
394    if (!
395        (K =
396         SRP_Calc_client_key(s->srp_ctx.N, s->srp_ctx.B, s->srp_ctx.g, x,
397                             s->srp_ctx.a, u)))
398        goto err;
399
400    tmp_len = BN_num_bytes(K);
401    if ((tmp = OPENSSL_malloc(tmp_len)) == NULL)
402        goto err;
403    BN_bn2bin(K, tmp);
404    ret =
405        s->method->ssl3_enc->generate_master_secret(s, master_key, tmp,
406                                                    tmp_len);
407 err:
408    if (tmp) {
409        OPENSSL_cleanse(tmp, tmp_len);
410        OPENSSL_free(tmp);
411    }
412    BN_clear_free(K);
413    BN_clear_free(x);
414    if (passwd) {
415        OPENSSL_cleanse(passwd, strlen(passwd));
416        OPENSSL_free(passwd);
417    }
418    BN_clear_free(u);
419    return ret;
420}
421
422int srp_verify_server_param(SSL *s, int *al)
423{
424    SRP_CTX *srp = &s->srp_ctx;
425    /*
426     * Sanity check parameters: we can quickly check B % N == 0 by checking B
427     * != 0 since B < N
428     */
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;
432        return 0;
433    }
434
435    if (BN_num_bits(srp->N) < srp->strength) {
436        *al = TLS1_AD_INSUFFICIENT_SECURITY;
437        return 0;
438    }
439
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;
443            return 0;
444        }
445    } else if (!SRP_check_known_gN_param(srp->g, srp->N)) {
446        *al = TLS1_AD_INSUFFICIENT_SECURITY;
447        return 0;
448    }
449
450    return 1;
451}
452
453int SRP_Calc_A_param(SSL *s)
454{
455    unsigned char rnd[SSL_MAX_MASTER_KEY_LENGTH];
456
457    if (RAND_bytes(rnd, sizeof(rnd)) <= 0)
458        return -1;
459    s->srp_ctx.a = BN_bin2bn(rnd, sizeof(rnd), s->srp_ctx.a);
460    OPENSSL_cleanse(rnd, sizeof(rnd));
461
462    if (!
463        (s->srp_ctx.A = SRP_Calc_A(s->srp_ctx.a, s->srp_ctx.N, s->srp_ctx.g)))
464        return -1;
465
466    return 1;
467}
468
469BIGNUM *SSL_get_srp_g(SSL *s)
470{
471    if (s->srp_ctx.g != NULL)
472        return s->srp_ctx.g;
473    return s->ctx->srp_ctx.g;
474}
475
476BIGNUM *SSL_get_srp_N(SSL *s)
477{
478    if (s->srp_ctx.N != NULL)
479        return s->srp_ctx.N;
480    return s->ctx->srp_ctx.N;
481}
482
483char *SSL_get_srp_username(SSL *s)
484{
485    if (s->srp_ctx.login != NULL)
486        return s->srp_ctx.login;
487    return s->ctx->srp_ctx.login;
488}
489
490char *SSL_get_srp_userinfo(SSL *s)
491{
492    if (s->srp_ctx.info != NULL)
493        return s->srp_ctx.info;
494    return s->ctx->srp_ctx.info;
495}
496
497# define tls1_ctx_ctrl ssl3_ctx_ctrl
498# define tls1_ctx_callback_ctrl ssl3_ctx_callback_ctrl
499
500int SSL_CTX_set_srp_username(SSL_CTX *ctx, char *name)
501{
502    return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_USERNAME, 0, name);
503}
504
505int SSL_CTX_set_srp_password(SSL_CTX *ctx, char *password)
506{
507    return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD, 0, password);
508}
509
510int SSL_CTX_set_srp_strength(SSL_CTX *ctx, int strength)
511{
512    return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH, strength,
513                         NULL);
514}
515
516int SSL_CTX_set_srp_verify_param_callback(SSL_CTX *ctx,
517                                          int (*cb) (SSL *, void *))
518{
519    return tls1_ctx_callback_ctrl(ctx, SSL_CTRL_SET_SRP_VERIFY_PARAM_CB,
520                                  (void (*)(void))cb);
521}
522
523int SSL_CTX_set_srp_cb_arg(SSL_CTX *ctx, void *arg)
524{
525    return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_SRP_ARG, 0, arg);
526}
527
528int SSL_CTX_set_srp_username_callback(SSL_CTX *ctx,
529                                      int (*cb) (SSL *, int *, void *))
530{
531    return tls1_ctx_callback_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB,
532                                  (void (*)(void))cb);
533}
534
535int SSL_CTX_set_srp_client_pwd_callback(SSL_CTX *ctx,
536                                        char *(*cb) (SSL *, void *))
537{
538    return tls1_ctx_callback_ctrl(ctx, SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB,
539                                  (void (*)(void))cb);
540}
541
542#endif
543