Home | History | Annotate | Line # | Download | only in ssl
tls_srp.c revision 1.1
      1  1.1  christos /* ssl/tls_srp.c */
      2  1.1  christos /*
      3  1.1  christos  * Written by Christophe Renou (christophe.renou (at) edelweb.fr) with the
      4  1.1  christos  * precious help of Peter Sylvester (peter.sylvester (at) edelweb.fr) for the
      5  1.1  christos  * EdelKey project and contributed to the OpenSSL project 2004.
      6  1.1  christos  */
      7  1.1  christos /* ====================================================================
      8  1.1  christos  * Copyright (c) 2004-2011 The OpenSSL Project.  All rights reserved.
      9  1.1  christos  *
     10  1.1  christos  * Redistribution and use in source and binary forms, with or without
     11  1.1  christos  * modification, are permitted provided that the following conditions
     12  1.1  christos  * are met:
     13  1.1  christos  *
     14  1.1  christos  * 1. Redistributions of source code must retain the above copyright
     15  1.1  christos  *    notice, this list of conditions and the following disclaimer.
     16  1.1  christos  *
     17  1.1  christos  * 2. Redistributions in binary form must reproduce the above copyright
     18  1.1  christos  *    notice, this list of conditions and the following disclaimer in
     19  1.1  christos  *    the documentation and/or other materials provided with the
     20  1.1  christos  *    distribution.
     21  1.1  christos  *
     22  1.1  christos  * 3. All advertising materials mentioning features or use of this
     23  1.1  christos  *    software must display the following acknowledgment:
     24  1.1  christos  *    "This product includes software developed by the OpenSSL Project
     25  1.1  christos  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
     26  1.1  christos  *
     27  1.1  christos  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
     28  1.1  christos  *    endorse or promote products derived from this software without
     29  1.1  christos  *    prior written permission. For written permission, please contact
     30  1.1  christos  *    licensing (at) OpenSSL.org.
     31  1.1  christos  *
     32  1.1  christos  * 5. Products derived from this software may not be called "OpenSSL"
     33  1.1  christos  *    nor may "OpenSSL" appear in their names without prior written
     34  1.1  christos  *    permission of the OpenSSL Project.
     35  1.1  christos  *
     36  1.1  christos  * 6. Redistributions of any form whatsoever must retain the following
     37  1.1  christos  *    acknowledgment:
     38  1.1  christos  *    "This product includes software developed by the OpenSSL Project
     39  1.1  christos  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
     40  1.1  christos  *
     41  1.1  christos  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
     42  1.1  christos  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     43  1.1  christos  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     44  1.1  christos  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
     45  1.1  christos  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     46  1.1  christos  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     47  1.1  christos  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     48  1.1  christos  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     49  1.1  christos  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     50  1.1  christos  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     51  1.1  christos  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
     52  1.1  christos  * OF THE POSSIBILITY OF SUCH DAMAGE.
     53  1.1  christos  * ====================================================================
     54  1.1  christos  *
     55  1.1  christos  * This product includes cryptographic software written by Eric Young
     56  1.1  christos  * (eay (at) cryptsoft.com).  This product includes software written by Tim
     57  1.1  christos  * Hudson (tjh (at) cryptsoft.com).
     58  1.1  christos  *
     59  1.1  christos  */
     60  1.1  christos #include "ssl_locl.h"
     61  1.1  christos #ifndef OPENSSL_NO_SRP
     62  1.1  christos 
     63  1.1  christos # include <openssl/rand.h>
     64  1.1  christos # include <openssl/srp.h>
     65  1.1  christos # include <openssl/err.h>
     66  1.1  christos 
     67  1.1  christos int SSL_CTX_SRP_CTX_free(struct ssl_ctx_st *ctx)
     68  1.1  christos {
     69  1.1  christos     if (ctx == NULL)
     70  1.1  christos         return 0;
     71  1.1  christos     OPENSSL_free(ctx->srp_ctx.login);
     72  1.1  christos     BN_free(ctx->srp_ctx.N);
     73  1.1  christos     BN_free(ctx->srp_ctx.g);
     74  1.1  christos     BN_free(ctx->srp_ctx.s);
     75  1.1  christos     BN_free(ctx->srp_ctx.B);
     76  1.1  christos     BN_free(ctx->srp_ctx.A);
     77  1.1  christos     BN_free(ctx->srp_ctx.a);
     78  1.1  christos     BN_free(ctx->srp_ctx.b);
     79  1.1  christos     BN_free(ctx->srp_ctx.v);
     80  1.1  christos     ctx->srp_ctx.TLS_ext_srp_username_callback = NULL;
     81  1.1  christos     ctx->srp_ctx.SRP_cb_arg = NULL;
     82  1.1  christos     ctx->srp_ctx.SRP_verify_param_callback = NULL;
     83  1.1  christos     ctx->srp_ctx.SRP_give_srp_client_pwd_callback = NULL;
     84  1.1  christos     ctx->srp_ctx.N = NULL;
     85  1.1  christos     ctx->srp_ctx.g = NULL;
     86  1.1  christos     ctx->srp_ctx.s = NULL;
     87  1.1  christos     ctx->srp_ctx.B = NULL;
     88  1.1  christos     ctx->srp_ctx.A = NULL;
     89  1.1  christos     ctx->srp_ctx.a = NULL;
     90  1.1  christos     ctx->srp_ctx.b = NULL;
     91  1.1  christos     ctx->srp_ctx.v = NULL;
     92  1.1  christos     ctx->srp_ctx.login = NULL;
     93  1.1  christos     ctx->srp_ctx.info = NULL;
     94  1.1  christos     ctx->srp_ctx.strength = SRP_MINIMAL_N;
     95  1.1  christos     ctx->srp_ctx.srp_Mask = 0;
     96  1.1  christos     return (1);
     97  1.1  christos }
     98  1.1  christos 
     99  1.1  christos int SSL_SRP_CTX_free(struct ssl_st *s)
    100  1.1  christos {
    101  1.1  christos     if (s == NULL)
    102  1.1  christos         return 0;
    103  1.1  christos     OPENSSL_free(s->srp_ctx.login);
    104  1.1  christos     BN_free(s->srp_ctx.N);
    105  1.1  christos     BN_free(s->srp_ctx.g);
    106  1.1  christos     BN_free(s->srp_ctx.s);
    107  1.1  christos     BN_free(s->srp_ctx.B);
    108  1.1  christos     BN_free(s->srp_ctx.A);
    109  1.1  christos     BN_free(s->srp_ctx.a);
    110  1.1  christos     BN_free(s->srp_ctx.b);
    111  1.1  christos     BN_free(s->srp_ctx.v);
    112  1.1  christos     s->srp_ctx.TLS_ext_srp_username_callback = NULL;
    113  1.1  christos     s->srp_ctx.SRP_cb_arg = NULL;
    114  1.1  christos     s->srp_ctx.SRP_verify_param_callback = NULL;
    115  1.1  christos     s->srp_ctx.SRP_give_srp_client_pwd_callback = NULL;
    116  1.1  christos     s->srp_ctx.N = NULL;
    117  1.1  christos     s->srp_ctx.g = NULL;
    118  1.1  christos     s->srp_ctx.s = NULL;
    119  1.1  christos     s->srp_ctx.B = NULL;
    120  1.1  christos     s->srp_ctx.A = NULL;
    121  1.1  christos     s->srp_ctx.a = NULL;
    122  1.1  christos     s->srp_ctx.b = NULL;
    123  1.1  christos     s->srp_ctx.v = NULL;
    124  1.1  christos     s->srp_ctx.login = NULL;
    125  1.1  christos     s->srp_ctx.info = NULL;
    126  1.1  christos     s->srp_ctx.strength = SRP_MINIMAL_N;
    127  1.1  christos     s->srp_ctx.srp_Mask = 0;
    128  1.1  christos     return (1);
    129  1.1  christos }
    130  1.1  christos 
    131  1.1  christos int SSL_SRP_CTX_init(struct ssl_st *s)
    132  1.1  christos {
    133  1.1  christos     SSL_CTX *ctx;
    134  1.1  christos 
    135  1.1  christos     if ((s == NULL) || ((ctx = s->ctx) == NULL))
    136  1.1  christos         return 0;
    137  1.1  christos     s->srp_ctx.SRP_cb_arg = ctx->srp_ctx.SRP_cb_arg;
    138  1.1  christos     /* set client Hello login callback */
    139  1.1  christos     s->srp_ctx.TLS_ext_srp_username_callback =
    140  1.1  christos         ctx->srp_ctx.TLS_ext_srp_username_callback;
    141  1.1  christos     /* set SRP N/g param callback for verification */
    142  1.1  christos     s->srp_ctx.SRP_verify_param_callback =
    143  1.1  christos         ctx->srp_ctx.SRP_verify_param_callback;
    144  1.1  christos     /* set SRP client passwd callback */
    145  1.1  christos     s->srp_ctx.SRP_give_srp_client_pwd_callback =
    146  1.1  christos         ctx->srp_ctx.SRP_give_srp_client_pwd_callback;
    147  1.1  christos 
    148  1.1  christos     s->srp_ctx.N = NULL;
    149  1.1  christos     s->srp_ctx.g = NULL;
    150  1.1  christos     s->srp_ctx.s = NULL;
    151  1.1  christos     s->srp_ctx.B = NULL;
    152  1.1  christos     s->srp_ctx.A = NULL;
    153  1.1  christos     s->srp_ctx.a = NULL;
    154  1.1  christos     s->srp_ctx.b = NULL;
    155  1.1  christos     s->srp_ctx.v = NULL;
    156  1.1  christos     s->srp_ctx.login = NULL;
    157  1.1  christos     s->srp_ctx.info = ctx->srp_ctx.info;
    158  1.1  christos     s->srp_ctx.strength = ctx->srp_ctx.strength;
    159  1.1  christos 
    160  1.1  christos     if (((ctx->srp_ctx.N != NULL) &&
    161  1.1  christos          ((s->srp_ctx.N = BN_dup(ctx->srp_ctx.N)) == NULL)) ||
    162  1.1  christos         ((ctx->srp_ctx.g != NULL) &&
    163  1.1  christos          ((s->srp_ctx.g = BN_dup(ctx->srp_ctx.g)) == NULL)) ||
    164  1.1  christos         ((ctx->srp_ctx.s != NULL) &&
    165  1.1  christos          ((s->srp_ctx.s = BN_dup(ctx->srp_ctx.s)) == NULL)) ||
    166  1.1  christos         ((ctx->srp_ctx.B != NULL) &&
    167  1.1  christos          ((s->srp_ctx.B = BN_dup(ctx->srp_ctx.B)) == NULL)) ||
    168  1.1  christos         ((ctx->srp_ctx.A != NULL) &&
    169  1.1  christos          ((s->srp_ctx.A = BN_dup(ctx->srp_ctx.A)) == NULL)) ||
    170  1.1  christos         ((ctx->srp_ctx.a != NULL) &&
    171  1.1  christos          ((s->srp_ctx.a = BN_dup(ctx->srp_ctx.a)) == NULL)) ||
    172  1.1  christos         ((ctx->srp_ctx.v != NULL) &&
    173  1.1  christos          ((s->srp_ctx.v = BN_dup(ctx->srp_ctx.v)) == NULL)) ||
    174  1.1  christos         ((ctx->srp_ctx.b != NULL) &&
    175  1.1  christos          ((s->srp_ctx.b = BN_dup(ctx->srp_ctx.b)) == NULL))) {
    176  1.1  christos         SSLerr(SSL_F_SSL_SRP_CTX_INIT, ERR_R_BN_LIB);
    177  1.1  christos         goto err;
    178  1.1  christos     }
    179  1.1  christos     if ((ctx->srp_ctx.login != NULL) &&
    180  1.1  christos         ((s->srp_ctx.login = BUF_strdup(ctx->srp_ctx.login)) == NULL)) {
    181  1.1  christos         SSLerr(SSL_F_SSL_SRP_CTX_INIT, ERR_R_INTERNAL_ERROR);
    182  1.1  christos         goto err;
    183  1.1  christos     }
    184  1.1  christos     s->srp_ctx.srp_Mask = ctx->srp_ctx.srp_Mask;
    185  1.1  christos 
    186  1.1  christos     return (1);
    187  1.1  christos  err:
    188  1.1  christos     OPENSSL_free(s->srp_ctx.login);
    189  1.1  christos     BN_free(s->srp_ctx.N);
    190  1.1  christos     BN_free(s->srp_ctx.g);
    191  1.1  christos     BN_free(s->srp_ctx.s);
    192  1.1  christos     BN_free(s->srp_ctx.B);
    193  1.1  christos     BN_free(s->srp_ctx.A);
    194  1.1  christos     BN_free(s->srp_ctx.a);
    195  1.1  christos     BN_free(s->srp_ctx.b);
    196  1.1  christos     BN_free(s->srp_ctx.v);
    197  1.1  christos     return (0);
    198  1.1  christos }
    199  1.1  christos 
    200  1.1  christos int SSL_CTX_SRP_CTX_init(struct ssl_ctx_st *ctx)
    201  1.1  christos {
    202  1.1  christos     if (ctx == NULL)
    203  1.1  christos         return 0;
    204  1.1  christos 
    205  1.1  christos     ctx->srp_ctx.SRP_cb_arg = NULL;
    206  1.1  christos     /* set client Hello login callback */
    207  1.1  christos     ctx->srp_ctx.TLS_ext_srp_username_callback = NULL;
    208  1.1  christos     /* set SRP N/g param callback for verification */
    209  1.1  christos     ctx->srp_ctx.SRP_verify_param_callback = NULL;
    210  1.1  christos     /* set SRP client passwd callback */
    211  1.1  christos     ctx->srp_ctx.SRP_give_srp_client_pwd_callback = NULL;
    212  1.1  christos 
    213  1.1  christos     ctx->srp_ctx.N = NULL;
    214  1.1  christos     ctx->srp_ctx.g = NULL;
    215  1.1  christos     ctx->srp_ctx.s = NULL;
    216  1.1  christos     ctx->srp_ctx.B = NULL;
    217  1.1  christos     ctx->srp_ctx.A = NULL;
    218  1.1  christos     ctx->srp_ctx.a = NULL;
    219  1.1  christos     ctx->srp_ctx.b = NULL;
    220  1.1  christos     ctx->srp_ctx.v = NULL;
    221  1.1  christos     ctx->srp_ctx.login = NULL;
    222  1.1  christos     ctx->srp_ctx.srp_Mask = 0;
    223  1.1  christos     ctx->srp_ctx.info = NULL;
    224  1.1  christos     ctx->srp_ctx.strength = SRP_MINIMAL_N;
    225  1.1  christos 
    226  1.1  christos     return (1);
    227  1.1  christos }
    228  1.1  christos 
    229  1.1  christos /* server side */
    230  1.1  christos int SSL_srp_server_param_with_username(SSL *s, int *ad)
    231  1.1  christos {
    232  1.1  christos     unsigned char b[SSL_MAX_MASTER_KEY_LENGTH];
    233  1.1  christos     int al;
    234  1.1  christos 
    235  1.1  christos     *ad = SSL_AD_UNKNOWN_PSK_IDENTITY;
    236  1.1  christos     if ((s->srp_ctx.TLS_ext_srp_username_callback != NULL) &&
    237  1.1  christos         ((al =
    238  1.1  christos           s->srp_ctx.TLS_ext_srp_username_callback(s, ad,
    239  1.1  christos                                                    s->srp_ctx.SRP_cb_arg)) !=
    240  1.1  christos          SSL_ERROR_NONE))
    241  1.1  christos         return al;
    242  1.1  christos 
    243  1.1  christos     *ad = SSL_AD_INTERNAL_ERROR;
    244  1.1  christos     if ((s->srp_ctx.N == NULL) ||
    245  1.1  christos         (s->srp_ctx.g == NULL) ||
    246  1.1  christos         (s->srp_ctx.s == NULL) || (s->srp_ctx.v == NULL))
    247  1.1  christos         return SSL3_AL_FATAL;
    248  1.1  christos 
    249  1.1  christos     if (RAND_bytes(b, sizeof(b)) <= 0)
    250  1.1  christos         return SSL3_AL_FATAL;
    251  1.1  christos     s->srp_ctx.b = BN_bin2bn(b, sizeof(b), NULL);
    252  1.1  christos     OPENSSL_cleanse(b, sizeof(b));
    253  1.1  christos 
    254  1.1  christos     /* Calculate:  B = (kv + g^b) % N  */
    255  1.1  christos 
    256  1.1  christos     return ((s->srp_ctx.B =
    257  1.1  christos              SRP_Calc_B(s->srp_ctx.b, s->srp_ctx.N, s->srp_ctx.g,
    258  1.1  christos                         s->srp_ctx.v)) !=
    259  1.1  christos             NULL) ? SSL_ERROR_NONE : SSL3_AL_FATAL;
    260  1.1  christos }
    261  1.1  christos 
    262  1.1  christos /*
    263  1.1  christos  * If the server just has the raw password, make up a verifier entry on the
    264  1.1  christos  * fly
    265  1.1  christos  */
    266  1.1  christos int SSL_set_srp_server_param_pw(SSL *s, const char *user, const char *pass,
    267  1.1  christos                                 const char *grp)
    268  1.1  christos {
    269  1.1  christos     SRP_gN *GN = SRP_get_default_gN(grp);
    270  1.1  christos     if (GN == NULL)
    271  1.1  christos         return -1;
    272  1.1  christos     s->srp_ctx.N = BN_dup(GN->N);
    273  1.1  christos     s->srp_ctx.g = BN_dup(GN->g);
    274  1.1  christos     if (s->srp_ctx.v != NULL) {
    275  1.1  christos         BN_clear_free(s->srp_ctx.v);
    276  1.1  christos         s->srp_ctx.v = NULL;
    277  1.1  christos     }
    278  1.1  christos     if (s->srp_ctx.s != NULL) {
    279  1.1  christos         BN_clear_free(s->srp_ctx.s);
    280  1.1  christos         s->srp_ctx.s = NULL;
    281  1.1  christos     }
    282  1.1  christos     if (!SRP_create_verifier_BN
    283  1.1  christos         (user, pass, &s->srp_ctx.s, &s->srp_ctx.v, GN->N, GN->g))
    284  1.1  christos         return -1;
    285  1.1  christos 
    286  1.1  christos     return 1;
    287  1.1  christos }
    288  1.1  christos 
    289  1.1  christos int SSL_set_srp_server_param(SSL *s, const BIGNUM *N, const BIGNUM *g,
    290  1.1  christos                              BIGNUM *sa, BIGNUM *v, char *info)
    291  1.1  christos {
    292  1.1  christos     if (N != NULL) {
    293  1.1  christos         if (s->srp_ctx.N != NULL) {
    294  1.1  christos             if (!BN_copy(s->srp_ctx.N, N)) {
    295  1.1  christos                 BN_free(s->srp_ctx.N);
    296  1.1  christos                 s->srp_ctx.N = NULL;
    297  1.1  christos             }
    298  1.1  christos         } else
    299  1.1  christos             s->srp_ctx.N = BN_dup(N);
    300  1.1  christos     }
    301  1.1  christos     if (g != NULL) {
    302  1.1  christos         if (s->srp_ctx.g != NULL) {
    303  1.1  christos             if (!BN_copy(s->srp_ctx.g, g)) {
    304  1.1  christos                 BN_free(s->srp_ctx.g);
    305  1.1  christos                 s->srp_ctx.g = NULL;
    306  1.1  christos             }
    307  1.1  christos         } else
    308  1.1  christos             s->srp_ctx.g = BN_dup(g);
    309  1.1  christos     }
    310  1.1  christos     if (sa != NULL) {
    311  1.1  christos         if (s->srp_ctx.s != NULL) {
    312  1.1  christos             if (!BN_copy(s->srp_ctx.s, sa)) {
    313  1.1  christos                 BN_free(s->srp_ctx.s);
    314  1.1  christos                 s->srp_ctx.s = NULL;
    315  1.1  christos             }
    316  1.1  christos         } else
    317  1.1  christos             s->srp_ctx.s = BN_dup(sa);
    318  1.1  christos     }
    319  1.1  christos     if (v != NULL) {
    320  1.1  christos         if (s->srp_ctx.v != NULL) {
    321  1.1  christos             if (!BN_copy(s->srp_ctx.v, v)) {
    322  1.1  christos                 BN_free(s->srp_ctx.v);
    323  1.1  christos                 s->srp_ctx.v = NULL;
    324  1.1  christos             }
    325  1.1  christos         } else
    326  1.1  christos             s->srp_ctx.v = BN_dup(v);
    327  1.1  christos     }
    328  1.1  christos     s->srp_ctx.info = info;
    329  1.1  christos 
    330  1.1  christos     if (!(s->srp_ctx.N) ||
    331  1.1  christos         !(s->srp_ctx.g) || !(s->srp_ctx.s) || !(s->srp_ctx.v))
    332  1.1  christos         return -1;
    333  1.1  christos 
    334  1.1  christos     return 1;
    335  1.1  christos }
    336  1.1  christos 
    337  1.1  christos int SRP_generate_server_master_secret(SSL *s, unsigned char *master_key)
    338  1.1  christos {
    339  1.1  christos     BIGNUM *K = NULL, *u = NULL;
    340  1.1  christos     int ret = -1, tmp_len;
    341  1.1  christos     unsigned char *tmp = NULL;
    342  1.1  christos 
    343  1.1  christos     if (!SRP_Verify_A_mod_N(s->srp_ctx.A, s->srp_ctx.N))
    344  1.1  christos         goto err;
    345  1.1  christos     if (!(u = SRP_Calc_u(s->srp_ctx.A, s->srp_ctx.B, s->srp_ctx.N)))
    346  1.1  christos         goto err;
    347  1.1  christos     if (!
    348  1.1  christos         (K =
    349  1.1  christos          SRP_Calc_server_key(s->srp_ctx.A, s->srp_ctx.v, u, s->srp_ctx.b,
    350  1.1  christos                              s->srp_ctx.N)))
    351  1.1  christos         goto err;
    352  1.1  christos 
    353  1.1  christos     tmp_len = BN_num_bytes(K);
    354  1.1  christos     if ((tmp = OPENSSL_malloc(tmp_len)) == NULL)
    355  1.1  christos         goto err;
    356  1.1  christos     BN_bn2bin(K, tmp);
    357  1.1  christos     ret =
    358  1.1  christos         s->method->ssl3_enc->generate_master_secret(s, master_key, tmp,
    359  1.1  christos                                                     tmp_len);
    360  1.1  christos  err:
    361  1.1  christos     if (tmp) {
    362  1.1  christos         OPENSSL_cleanse(tmp, tmp_len);
    363  1.1  christos         OPENSSL_free(tmp);
    364  1.1  christos     }
    365  1.1  christos     BN_clear_free(K);
    366  1.1  christos     BN_clear_free(u);
    367  1.1  christos     return ret;
    368  1.1  christos }
    369  1.1  christos 
    370  1.1  christos /* client side */
    371  1.1  christos int SRP_generate_client_master_secret(SSL *s, unsigned char *master_key)
    372  1.1  christos {
    373  1.1  christos     BIGNUM *x = NULL, *u = NULL, *K = NULL;
    374  1.1  christos     int ret = -1, tmp_len;
    375  1.1  christos     char *passwd = NULL;
    376  1.1  christos     unsigned char *tmp = NULL;
    377  1.1  christos 
    378  1.1  christos     /*
    379  1.1  christos      * Checks if b % n == 0
    380  1.1  christos      */
    381  1.1  christos     if (SRP_Verify_B_mod_N(s->srp_ctx.B, s->srp_ctx.N) == 0)
    382  1.1  christos         goto err;
    383  1.1  christos     if (!(u = SRP_Calc_u(s->srp_ctx.A, s->srp_ctx.B, s->srp_ctx.N)))
    384  1.1  christos         goto err;
    385  1.1  christos     if (s->srp_ctx.SRP_give_srp_client_pwd_callback == NULL)
    386  1.1  christos         goto err;
    387  1.1  christos     if (!
    388  1.1  christos         (passwd =
    389  1.1  christos          s->srp_ctx.SRP_give_srp_client_pwd_callback(s,
    390  1.1  christos                                                      s->srp_ctx.SRP_cb_arg)))
    391  1.1  christos         goto err;
    392  1.1  christos     if (!(x = SRP_Calc_x(s->srp_ctx.s, s->srp_ctx.login, passwd)))
    393  1.1  christos         goto err;
    394  1.1  christos     if (!
    395  1.1  christos         (K =
    396  1.1  christos          SRP_Calc_client_key(s->srp_ctx.N, s->srp_ctx.B, s->srp_ctx.g, x,
    397  1.1  christos                              s->srp_ctx.a, u)))
    398  1.1  christos         goto err;
    399  1.1  christos 
    400  1.1  christos     tmp_len = BN_num_bytes(K);
    401  1.1  christos     if ((tmp = OPENSSL_malloc(tmp_len)) == NULL)
    402  1.1  christos         goto err;
    403  1.1  christos     BN_bn2bin(K, tmp);
    404  1.1  christos     ret =
    405  1.1  christos         s->method->ssl3_enc->generate_master_secret(s, master_key, tmp,
    406  1.1  christos                                                     tmp_len);
    407  1.1  christos  err:
    408  1.1  christos     if (tmp) {
    409  1.1  christos         OPENSSL_cleanse(tmp, tmp_len);
    410  1.1  christos         OPENSSL_free(tmp);
    411  1.1  christos     }
    412  1.1  christos     BN_clear_free(K);
    413  1.1  christos     BN_clear_free(x);
    414  1.1  christos     if (passwd) {
    415  1.1  christos         OPENSSL_cleanse(passwd, strlen(passwd));
    416  1.1  christos         OPENSSL_free(passwd);
    417  1.1  christos     }
    418  1.1  christos     BN_clear_free(u);
    419  1.1  christos     return ret;
    420  1.1  christos }
    421  1.1  christos 
    422  1.1  christos int srp_verify_server_param(SSL *s, int *al)
    423  1.1  christos {
    424  1.1  christos     SRP_CTX *srp = &s->srp_ctx;
    425  1.1  christos     /*
    426  1.1  christos      * Sanity check parameters: we can quickly check B % N == 0 by checking B
    427  1.1  christos      * != 0 since B < N
    428  1.1  christos      */
    429  1.1  christos     if (BN_ucmp(srp->g, srp->N) >= 0 || BN_ucmp(srp->B, srp->N) >= 0
    430  1.1  christos         || BN_is_zero(srp->B)) {
    431  1.1  christos         *al = SSL3_AD_ILLEGAL_PARAMETER;
    432  1.1  christos         return 0;
    433  1.1  christos     }
    434  1.1  christos 
    435  1.1  christos     if (BN_num_bits(srp->N) < srp->strength) {
    436  1.1  christos         *al = TLS1_AD_INSUFFICIENT_SECURITY;
    437  1.1  christos         return 0;
    438  1.1  christos     }
    439  1.1  christos 
    440  1.1  christos     if (srp->SRP_verify_param_callback) {
    441  1.1  christos         if (srp->SRP_verify_param_callback(s, srp->SRP_cb_arg) <= 0) {
    442  1.1  christos             *al = TLS1_AD_INSUFFICIENT_SECURITY;
    443  1.1  christos             return 0;
    444  1.1  christos         }
    445  1.1  christos     } else if (!SRP_check_known_gN_param(srp->g, srp->N)) {
    446  1.1  christos         *al = TLS1_AD_INSUFFICIENT_SECURITY;
    447  1.1  christos         return 0;
    448  1.1  christos     }
    449  1.1  christos 
    450  1.1  christos     return 1;
    451  1.1  christos }
    452  1.1  christos 
    453  1.1  christos int SRP_Calc_A_param(SSL *s)
    454  1.1  christos {
    455  1.1  christos     unsigned char rnd[SSL_MAX_MASTER_KEY_LENGTH];
    456  1.1  christos 
    457  1.1  christos     if (RAND_bytes(rnd, sizeof(rnd)) <= 0)
    458  1.1  christos         return -1;
    459  1.1  christos     s->srp_ctx.a = BN_bin2bn(rnd, sizeof(rnd), s->srp_ctx.a);
    460  1.1  christos     OPENSSL_cleanse(rnd, sizeof(rnd));
    461  1.1  christos 
    462  1.1  christos     if (!
    463  1.1  christos         (s->srp_ctx.A = SRP_Calc_A(s->srp_ctx.a, s->srp_ctx.N, s->srp_ctx.g)))
    464  1.1  christos         return -1;
    465  1.1  christos 
    466  1.1  christos     return 1;
    467  1.1  christos }
    468  1.1  christos 
    469  1.1  christos BIGNUM *SSL_get_srp_g(SSL *s)
    470  1.1  christos {
    471  1.1  christos     if (s->srp_ctx.g != NULL)
    472  1.1  christos         return s->srp_ctx.g;
    473  1.1  christos     return s->ctx->srp_ctx.g;
    474  1.1  christos }
    475  1.1  christos 
    476  1.1  christos BIGNUM *SSL_get_srp_N(SSL *s)
    477  1.1  christos {
    478  1.1  christos     if (s->srp_ctx.N != NULL)
    479  1.1  christos         return s->srp_ctx.N;
    480  1.1  christos     return s->ctx->srp_ctx.N;
    481  1.1  christos }
    482  1.1  christos 
    483  1.1  christos char *SSL_get_srp_username(SSL *s)
    484  1.1  christos {
    485  1.1  christos     if (s->srp_ctx.login != NULL)
    486  1.1  christos         return s->srp_ctx.login;
    487  1.1  christos     return s->ctx->srp_ctx.login;
    488  1.1  christos }
    489  1.1  christos 
    490  1.1  christos char *SSL_get_srp_userinfo(SSL *s)
    491  1.1  christos {
    492  1.1  christos     if (s->srp_ctx.info != NULL)
    493  1.1  christos         return s->srp_ctx.info;
    494  1.1  christos     return s->ctx->srp_ctx.info;
    495  1.1  christos }
    496  1.1  christos 
    497  1.1  christos # define tls1_ctx_ctrl ssl3_ctx_ctrl
    498  1.1  christos # define tls1_ctx_callback_ctrl ssl3_ctx_callback_ctrl
    499  1.1  christos 
    500  1.1  christos int SSL_CTX_set_srp_username(SSL_CTX *ctx, char *name)
    501  1.1  christos {
    502  1.1  christos     return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_USERNAME, 0, name);
    503  1.1  christos }
    504  1.1  christos 
    505  1.1  christos int SSL_CTX_set_srp_password(SSL_CTX *ctx, char *password)
    506  1.1  christos {
    507  1.1  christos     return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD, 0, password);
    508  1.1  christos }
    509  1.1  christos 
    510  1.1  christos int SSL_CTX_set_srp_strength(SSL_CTX *ctx, int strength)
    511  1.1  christos {
    512  1.1  christos     return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH, strength,
    513  1.1  christos                          NULL);
    514  1.1  christos }
    515  1.1  christos 
    516  1.1  christos int SSL_CTX_set_srp_verify_param_callback(SSL_CTX *ctx,
    517  1.1  christos                                           int (*cb) (SSL *, void *))
    518  1.1  christos {
    519  1.1  christos     return tls1_ctx_callback_ctrl(ctx, SSL_CTRL_SET_SRP_VERIFY_PARAM_CB,
    520  1.1  christos                                   (void (*)(void))cb);
    521  1.1  christos }
    522  1.1  christos 
    523  1.1  christos int SSL_CTX_set_srp_cb_arg(SSL_CTX *ctx, void *arg)
    524  1.1  christos {
    525  1.1  christos     return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_SRP_ARG, 0, arg);
    526  1.1  christos }
    527  1.1  christos 
    528  1.1  christos int SSL_CTX_set_srp_username_callback(SSL_CTX *ctx,
    529  1.1  christos                                       int (*cb) (SSL *, int *, void *))
    530  1.1  christos {
    531  1.1  christos     return tls1_ctx_callback_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB,
    532  1.1  christos                                   (void (*)(void))cb);
    533  1.1  christos }
    534  1.1  christos 
    535  1.1  christos int SSL_CTX_set_srp_client_pwd_callback(SSL_CTX *ctx,
    536  1.1  christos                                         char *(*cb) (SSL *, void *))
    537  1.1  christos {
    538  1.1  christos     return tls1_ctx_callback_ctrl(ctx, SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB,
    539  1.1  christos                                   (void (*)(void))cb);
    540  1.1  christos }
    541  1.1  christos 
    542  1.1  christos #endif
    543