diff -ruN openssl-1.0.0d-orig/Configure openssl-1.0.0d-srp/Configure --- openssl-1.0.0d-orig/Configure 2010-11-30 14:19:26.000000000 -0800 +++ openssl-1.0.0d-srp/Configure 2011-03-14 17:11:18.000000000 -0700 @@ -946,6 +946,12 @@ $disabled{"gost"} = "forced"; } +# SRP requires TLSEXT +if (defined($disabled{"tlsext"})) + { + $disabled{"srp"} = "forced"; + } + if ($target eq "TABLE") { foreach $target (sort keys %table) { print_table_entry($target); diff -ruN openssl-1.0.0d-orig/Makefile.org openssl-1.0.0d-srp/Makefile.org --- openssl-1.0.0d-orig/Makefile.org 2010-01-27 08:06:58.000000000 -0800 +++ openssl-1.0.0d-srp/Makefile.org 2011-03-14 17:11:18.000000000 -0700 @@ -121,7 +121,7 @@ bn ec rsa dsa ecdsa dh ecdh dso engine \ buffer bio stack lhash rand err \ evp asn1 pem x509 x509v3 conf txt_db pkcs7 pkcs12 comp ocsp ui krb5 \ - cms pqueue ts jpake store + cms pqueue ts jpake srp store # keep in mind that the above list is adjusted by ./Configure # according to no-xxx arguments... diff -ruN openssl-1.0.0d-orig/apps/Makefile openssl-1.0.0d-srp/apps/Makefile --- openssl-1.0.0d-orig/apps/Makefile 2010-12-02 10:26:10.000000000 -0800 +++ openssl-1.0.0d-srp/apps/Makefile 2011-03-14 17:11:18.000000000 -0700 @@ -39,7 +39,7 @@ ca crl rsa rsautl dsa dsaparam ec ecparam \ x509 genrsa gendsa genpkey s_server s_client speed \ s_time version pkcs7 cms crl2pkcs7 sess_id ciphers nseq pkcs12 \ - pkcs8 pkey pkeyparam pkeyutl spkac smime rand engine ocsp prime ts + pkcs8 pkey pkeyparam pkeyutl spkac smime rand engine ocsp prime ts srp PROGS= $(PROGRAM).c @@ -56,7 +56,7 @@ x509.o genrsa.o gendsa.o genpkey.o s_server.o s_client.o speed.o \ s_time.o $(A_OBJ) $(S_OBJ) $(RAND_OBJ) version.o sess_id.o \ ciphers.o nseq.o pkcs12.o pkcs8.o pkey.o pkeyparam.o pkeyutl.o \ - spkac.o smime.o cms.o rand.o engine.o ocsp.o prime.o ts.o + spkac.o smime.o cms.o rand.o engine.o ocsp.o prime.o ts.o srp.o E_SRC= verify.c asn1pars.c req.c dgst.c dh.c enc.c passwd.c gendh.c errstr.c ca.c \ pkcs7.c crl2p7.c crl.c \ @@ -64,7 +64,7 @@ x509.c genrsa.c gendsa.c genpkey.c s_server.c s_client.c speed.c \ s_time.c $(A_SRC) $(S_SRC) $(RAND_SRC) version.c sess_id.c \ ciphers.c nseq.c pkcs12.c pkcs8.c pkey.c pkeyparam.c pkeyutl.c \ - spkac.c smime.c cms.c rand.c engine.c ocsp.c prime.c ts.c + spkac.c smime.c cms.c rand.c engine.c ocsp.c prime.c ts.c srp.c SRC=$(E_SRC) diff -ruN openssl-1.0.0d-orig/apps/demoSRP/srp_verifier.txt openssl-1.0.0d-srp/apps/demoSRP/srp_verifier.txt --- openssl-1.0.0d-orig/apps/demoSRP/srp_verifier.txt 1969-12-31 16:00:00.000000000 -0800 +++ openssl-1.0.0d-srp/apps/demoSRP/srp_verifier.txt 2011-03-14 17:11:18.000000000 -0700 @@ -0,0 +1,6 @@ +# This is a file that will be filled by the openssl srp routine. +# You can initialize the file with additional groups, these are +# records starting with a I followed by the g and N values and the id. +# The exact values ... you have to dig this out from the source of srp.c +# or srp_vfy.c +# The last value of an I is used as the default group for new users. diff -ruN openssl-1.0.0d-orig/apps/demoSRP/srp_verifier.txt.attr openssl-1.0.0d-srp/apps/demoSRP/srp_verifier.txt.attr --- openssl-1.0.0d-orig/apps/demoSRP/srp_verifier.txt.attr 1969-12-31 16:00:00.000000000 -0800 +++ openssl-1.0.0d-srp/apps/demoSRP/srp_verifier.txt.attr 2011-03-14 17:11:18.000000000 -0700 @@ -0,0 +1 @@ +unique_subject = yes diff -ruN openssl-1.0.0d-orig/apps/progs.h openssl-1.0.0d-srp/apps/progs.h --- openssl-1.0.0d-orig/apps/progs.h 2009-06-30 08:08:38.000000000 -0700 +++ openssl-1.0.0d-srp/apps/progs.h 2011-03-14 17:11:18.000000000 -0700 @@ -44,6 +44,7 @@ extern int rand_main(int argc,char *argv[]); extern int engine_main(int argc,char *argv[]); extern int ocsp_main(int argc,char *argv[]); +extern int srp_main(int argc,char *argv[]); extern int prime_main(int argc,char *argv[]); extern int ts_main(int argc,char *argv[]); @@ -145,6 +146,9 @@ #ifndef OPENSSL_NO_OCSP {FUNC_TYPE_GENERAL,"ocsp",ocsp_main}, #endif +#ifndef OPENSSL_NO_SRP + {FUNC_TYPE_GENERAL,"srp",srp_main}, +#endif {FUNC_TYPE_GENERAL,"prime",prime_main}, {FUNC_TYPE_GENERAL,"ts",ts_main}, #ifndef OPENSSL_NO_MD2 diff -ruN openssl-1.0.0d-orig/apps/s_client.c openssl-1.0.0d-srp/apps/s_client.c --- openssl-1.0.0d-orig/apps/s_client.c 2009-12-16 12:28:28.000000000 -0800 +++ openssl-1.0.0d-srp/apps/s_client.c 2011-03-14 17:11:18.000000000 -0700 @@ -163,6 +163,9 @@ #include #include #include +#ifndef OPENSSL_NO_SRP +#include +#endif #include "s_apps.h" #include "timeouts.h" @@ -316,6 +319,13 @@ BIO_printf(bio_err," -jpake arg - JPAKE secret to use\n"); # endif #endif +#ifndef OPENSSL_NO_SRP + BIO_printf(bio_err," -srpuser user - SRP authentification for 'user'\n"); + BIO_printf(bio_err," -srppass arg - password for 'user'\n"); + BIO_printf(bio_err," -srp_lateuser - SRP username into second ClientHello message\n"); + BIO_printf(bio_err," -srp_moregroups - Tolerate other than the known g N values.\n"); + BIO_printf(bio_err," -srp_strength int - minimal mength in bits for N (default %d).\n",SRP_MINIMAL_N); +#endif BIO_printf(bio_err," -ssl2 - just use SSLv2\n"); BIO_printf(bio_err," -ssl3 - just use SSLv3\n"); BIO_printf(bio_err," -tls1 - just use TLSv1\n"); @@ -366,6 +376,112 @@ return SSL_TLSEXT_ERR_OK; } + +#ifndef OPENSSL_NO_SRP + +/* This is a context that we pass to all callbacks */ +typedef struct srp_arg_st + { + char *srppassin; + char *srplogin; + int msg; /* copy from c_msg */ + int debug; /* copy from c_debug */ + int amp; /* allow more groups */ + int strength /* minimal size for N */ ; + } SRP_ARG; + +#define SRP_NUMBER_ITERATIONS_FOR_PRIME 64 + +int SRP_Verify_N_and_g(BIGNUM *N, BIGNUM *g) + { + BN_CTX *bn_ctx = BN_CTX_new(); + BIGNUM *p = BN_new(); + BIGNUM *r = BN_new(); + int ret = + g != NULL && N != NULL && bn_ctx != NULL && BN_is_odd(N) && + BN_is_prime(N,SRP_NUMBER_ITERATIONS_FOR_PRIME,NULL,bn_ctx,NULL) && + p != NULL && BN_rshift1(p, N) && + + /* p = (N-1)/2 */ + BN_is_prime(p,SRP_NUMBER_ITERATIONS_FOR_PRIME,NULL,bn_ctx,NULL) && + r != NULL && + + /* verify g^((N-1)/2) == -1 (mod N) */ + BN_mod_exp(r, g, p, N, bn_ctx) && + BN_add_word(r, 1) && + BN_cmp(r, N) == 0; + + if(r) + BN_free(r); + if(p) + BN_free(p); + if(bn_ctx) + BN_CTX_free(bn_ctx); + return ret; + } + +static int MS_CALLBACK ssl_srp_verify_param_cb(SSL *s, void *arg) + { + SRP_ARG *srp_arg = (SRP_ARG *)arg; + BIGNUM *N = NULL, *g = NULL; + if (!(N = SSL_get_srp_N(s)) || !(g = SSL_get_srp_g(s))) + return 0; + if (srp_arg->debug || srp_arg->msg || srp_arg->amp == 1) + { + BIO_printf(bio_err, "SRP parameters:\n"); + BIO_printf(bio_err,"\tN="); BN_print(bio_err,N); + BIO_printf(bio_err,"\n\tg="); BN_print(bio_err,g); + BIO_printf(bio_err,"\n"); + } + + if (SRP_check_known_gN_param(g,N)) + return 1; + + if (srp_arg->amp == 1) + { + if (srp_arg->debug) + BIO_printf(bio_err, "SRP param N and g are not known params, going to check deeper.\n"); + +/* The srp_moregroups must be used with caution, testing primes costs time. + Implementors should rather add the value to the known ones. + The minimal size has already been tested. +*/ + if (BN_num_bits(g) <= BN_BITS && SRP_Verify_N_and_g(N,g)) + return 1; + } + BIO_printf(bio_err, "SRP param N and g rejected.\n"); + return 0; + } + +#define PWD_STRLEN 1024 + +static char * MS_CALLBACK ssl_give_srp_client_pwd_cb(SSL *s, void *arg) + { + SRP_ARG *srp_arg = (SRP_ARG *)arg; + char *pass = (char *)OPENSSL_malloc(PWD_STRLEN+1); + PW_CB_DATA cb_tmp; + int l; + + cb_tmp.password = (char *)srp_arg->srppassin; + cb_tmp.prompt_info = "SRP user"; + if ((l = password_callback(pass, PWD_STRLEN, 0, &cb_tmp))<0) + { + BIO_printf (bio_err, "Can't read Password\n"); + OPENSSL_free(pass); + return NULL; + } + *(pass+l)= '\0'; + + return pass; + } + +static char * MS_CALLBACK missing_srp_username_callback(SSL *s, void *arg) + { + SRP_ARG *srp_arg = (SRP_ARG *)arg; + return BUF_strdup(srp_arg->srplogin); + } + +#endif #endif enum @@ -439,6 +555,11 @@ #ifndef OPENSSL_NO_JPAKE char *jpake_secret = NULL; #endif +#ifndef OPENSSL_NO_SRP + char * srppass = NULL; + int srp_lateuser = 0; + SRP_ARG srp_arg = {NULL,NULL,0,0,0,1024}; +#endif #if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3) meth=SSLv23_client_method(); @@ -588,6 +709,37 @@ } } #endif +#ifndef OPENSSL_NO_SRP + else if (strcmp(*argv,"-srpuser") == 0) + { + if (--argc < 1) goto bad; + srp_arg.srplogin= *(++argv); + meth=TLSv1_client_method(); + } + else if (strcmp(*argv,"-srppass") == 0) + { + if (--argc < 1) goto bad; + srppass= *(++argv); + meth=TLSv1_client_method(); + } + else if (strcmp(*argv,"-srp_strength") == 0) + { + if (--argc < 1) goto bad; + srp_arg.strength=atoi(*(++argv)); + BIO_printf(bio_err,"SRP minimal length for N is %d\n",srp_arg.strength); + meth=TLSv1_client_method(); + } + else if (strcmp(*argv,"-srp_lateuser") == 0) + { + srp_lateuser= 1; + meth=TLSv1_client_method(); + } + else if (strcmp(*argv,"-srp_moregroups") == 0) + { + srp_arg.amp=1; + meth=TLSv1_client_method(); + } +#endif #ifndef OPENSSL_NO_SSL2 else if (strcmp(*argv,"-ssl2") == 0) meth=SSLv2_client_method(); @@ -835,6 +987,14 @@ } } +#ifndef OPENSSL_NO_SRP + if(!app_passwd(bio_err, srppass, NULL, &srp_arg.srppassin, NULL)) + { + BIO_printf(bio_err, "Error getting password\n"); + goto end; + } +#endif + ctx=SSL_CTX_new(meth); if (ctx == NULL) { @@ -914,6 +1074,26 @@ SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb); SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp); } +#ifndef OPENSSL_NO_SRP + if (srp_arg.srplogin) + { + if (srp_lateuser) + SSL_CTX_set_srp_missing_srp_username_callback(ctx,missing_srp_username_callback); + else if (!SSL_CTX_set_srp_username(ctx, srp_arg.srplogin)) + { + BIO_printf(bio_err,"Unable to set SRP username\n"); + goto end; + } + srp_arg.msg = c_msg; + srp_arg.debug = c_debug ; + SSL_CTX_set_srp_cb_arg(ctx,&srp_arg); + SSL_CTX_set_srp_client_pwd_callback(ctx, ssl_give_srp_client_pwd_cb); + SSL_CTX_set_srp_strength(ctx, srp_arg.strength); + if (c_msg || c_debug || srp_arg.amp == 0) + SSL_CTX_set_srp_verify_param_callback(ctx, ssl_srp_verify_param_cb); + } + +#endif #endif con=SSL_new(ctx); diff -ruN openssl-1.0.0d-orig/apps/s_server.c openssl-1.0.0d-srp/apps/s_server.c --- openssl-1.0.0d-orig/apps/s_server.c 2010-06-15 10:25:02.000000000 -0700 +++ openssl-1.0.0d-srp/apps/s_server.c 2011-03-14 17:11:18.000000000 -0700 @@ -186,6 +186,9 @@ #ifndef OPENSSL_NO_RSA #include #endif +#ifndef OPENSSL_NO_SRP +#include +#endif #include "s_apps.h" #include "timeouts.h" @@ -369,6 +372,39 @@ } #endif +#ifndef OPENSSL_NO_SRP +/* This is a context that we pass to callbacks */ +typedef struct srpsrvparm_st + { + int verbose; + char *login; + SRP_VBASE *vb; + } srpsrvparm; + +static int MS_CALLBACK ssl_srp_server_param_cb(SSL *s, int *ad, void *arg) + { + srpsrvparm * p = (srpsrvparm *) arg; + SRP_user_pwd *user; + + p->login = BUF_strdup(SSL_get_srp_username(s)); + BIO_printf(bio_err,"SRP username = \"%s\"\n",p->login); + + user = SRP_VBASE_get_by_user(p->vb,p->login); + if (user == NULL) + { + BIO_printf(bio_err, "User %s doesn't exist\n", p->login); + return SSL3_AL_FATAL; + } + if (SSL_set_srp_server_param(s,user->N,user->g,user->s,user->v, user->info)<0) + { + *ad = SSL_AD_INTERNAL_ERROR; + return SSL3_AL_FATAL; + } + return SSL_ERROR_NONE; + } + +#endif + #ifdef MONOLITH static void s_server_init(void) { @@ -456,6 +492,10 @@ BIO_printf(bio_err," -jpake arg - JPAKE secret to use\n"); # endif #endif +#ifndef OPENSSL_NO_SRP + BIO_printf(bio_err," -srpvfile file - The verifier file for SRP\n"); + BIO_printf(bio_err," -srpuserseed string - A seed string for a default user salt.\n"); +#endif BIO_printf(bio_err," -ssl2 - Just talk SSLv2\n"); BIO_printf(bio_err," -ssl3 - Just talk SSLv3\n"); BIO_printf(bio_err," -tls1 - Just talk TLSv1\n"); @@ -872,12 +912,21 @@ /* by default do not send a PSK identity hint */ static char *psk_identity_hint=NULL; #endif +#ifndef OPENSSL_NO_SRP + char * srpuserseed = NULL; + char * srp_verifier_file = NULL; + srpsrvparm p; +#endif #if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3) meth=SSLv23_server_method(); #elif !defined(OPENSSL_NO_SSL3) meth=SSLv3_server_method(); #elif !defined(OPENSSL_NO_SSL2) meth=SSLv2_server_method(); +#elif !defined(OPENSSL_NO_TLS1) + meth=TLSv1_server_method(); +#else + /* #error no SSL version enabled */ #endif local_argc=argc; @@ -1110,6 +1159,20 @@ } } #endif +#ifndef OPENSSL_NO_SRP + else if (strcmp(*argv,"-srpvfile") == 0) + { + if (--argc < 1) goto bad; + srp_verifier_file= *(++argv); + meth=TLSv1_server_method(); + } + else if (strcmp(*argv,"-srpuserseed") == 0) + { + if (--argc < 1) goto bad; + srpuserseed= *(++argv); + meth=TLSv1_server_method(); + } +#endif else if (strcmp(*argv,"-www") == 0) { www=1; } else if (strcmp(*argv,"-WWW") == 0) @@ -1684,6 +1747,21 @@ } #endif +#ifndef OPENSSL_NO_SRP + if (srp_verifier_file != NULL) + { + p.vb = SRP_VBASE_new(srpuserseed); + if ((ret = SRP_VBASE_init(p.vb, srp_verifier_file)) != SRP_NO_ERROR) + { + BIO_printf(bio_err,"Cannot initialize SRP verifier file \"%s\":ret=%d\n",srp_verifier_file,ret); + goto end; + } + SSL_CTX_set_verify(ctx,SSL_VERIFY_NONE,verify_callback); + SSL_CTX_set_srp_cb_arg(ctx, &p); + SSL_CTX_set_srp_username_callback(ctx, ssl_srp_server_param_cb); + } + else +#endif if (CAfile != NULL) { SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile)); diff -ruN openssl-1.0.0d-orig/apps/srp.c openssl-1.0.0d-srp/apps/srp.c --- openssl-1.0.0d-orig/apps/srp.c 1969-12-31 16:00:00.000000000 -0800 +++ openssl-1.0.0d-srp/apps/srp.c 2011-03-14 17:12:49.000000000 -0700 @@ -0,0 +1,753 @@ +/* apps/srp.c */ +/* Written by Peter Sylvester (peter.sylvester@edelweb.fr) + * for the EdelKey project and contributed to the OpenSSL project 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#include + +#ifndef OPENSSL_NO_SRP +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "apps.h" + +#undef PROG +#define PROG srp_main + +#define BASE_SECTION "srp" +#define CONFIG_FILE "openssl.cnf" + +#define ENV_RANDFILE "RANDFILE" + +#define ENV_DATABASE "srpvfile" +#define ENV_DEFAULT_SRP "default_srp" + +static char *srp_usage[]={ +"usage: srp [args] [user] \n", +"\n", +" -verbose Talk alot while doing things\n", +" -config file A config file\n", +" -name arg The particular srp definition to use\n", +" -srpvfile arg The srp verifier file name\n", +" -add add an user and srp verifier\n", +" -modify modify the srp verifier of an existing user\n", +" -delete delete user from verifier file\n", +" -list list user\n", +" -gn arg g and N values to be used for new verifier\n", +" -userinfo arg additional info to be set for user\n", +" -passin arg input file pass phrase source\n", +" -passout arg output file pass phrase source\n", +#ifndef OPENSSL_NO_ENGINE +" -engine e - use engine e, possibly a hardware device.\n", +#endif +NULL +}; + +#ifdef EFENCE +extern int EF_PROTECT_FREE; +extern int EF_PROTECT_BELOW; +extern int EF_ALIGNMENT; +#endif + +static CONF *conf=NULL; +static char *section=NULL; + +#define VERBOSE if (verbose) +#define VVERBOSE if (verbose>1) + + +int MAIN(int, char **); + +int get_index(CA_DB *db, char* id, char type) + { + char ** pp; + int i; + if (id == NULL) return -1; + if (type == DB_SRP_INDEX) + for (i = 0; i < sk_num(db->db->data); i++) + { + pp=(char **)sk_value(db->db->data,i); + if (pp[DB_srptype][0] == DB_SRP_INDEX && !strcmp(id,pp[DB_srpid])) + return i; + } + else for (i = 0; i < sk_num(db->db->data); i++) + { + pp=(char **)sk_value(db->db->data,i); + + if (pp[DB_srptype][0] != DB_SRP_INDEX && !strcmp(id,pp[DB_srpid])) + return i; + } + + return -1 ; + } + +void print_entry(CA_DB *db, BIO * bio, int index,int verbose, char * s) + { + if (index >= 0 && verbose) + { + int j; + char ** pp=(char **)sk_value(db->db->data,index); + BIO_printf(bio,"%s \"%s\"\n",s,pp[DB_srpid]); + for (j = 0; j < DB_NUMBER; j++) + { + BIO_printf(bio_err," %d = \"%s\"\n",j,pp[j]); + } + } + } + +void print_index(CA_DB *db, BIO * bio, int indexindex,int verbose) + { + print_entry(db,bio,indexindex, verbose, "g N entry") ; + } + +void print_user(CA_DB *db, BIO * bio, int userindex,int verbose) + { + if (verbose > 0) + { + char ** pp= (char **)sk_value(db->db->data,userindex); + + if (pp[DB_srptype][0] != 'I') + { + print_entry(db,bio,userindex, verbose, "User entry"); + print_entry(db,bio,get_index(db, pp[DB_srpgN],'I'),verbose,"g N entry") ; + } + + } + } + +int update_index(CA_DB *db, BIO * bio, char ** row) + { + char ** irow; + int i; + + if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL) + { + BIO_printf(bio_err,"Memory allocation failure\n"); + return 0; + } + + for (i=0; idb,irow)) + { + BIO_printf(bio,"failed to update srpvfile\n"); + BIO_printf(bio,"TXT_DB error number %ld\n",db->db->error); + OPENSSL_free(irow); + return 0; + } + return 1; + } + +static void lookup_fail(char *name, char *tag) + { + BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag); + } + + +char * srp_verify_user(char * user,char * srp_verifier, char * srp_usersalt,char * g, char * N, char * passin, BIO *bio, int verbose) + { + char password[1024]; + PW_CB_DATA cb_tmp; + char *verifier = NULL; + char *gNid = NULL; + cb_tmp.prompt_info = user; + cb_tmp.password = passin; + + if (password_callback(password,1024,0,&cb_tmp) >0) + { + VERBOSE BIO_printf(bio,"Validating\n user=\"%s\"\n srp_verifier=\"%s\"\n srp_usersalt=\"%s\"\n g=\"%s\"\n N=\"%s\"\n",user,srp_verifier,srp_usersalt,g,N); +BIO_printf(bio,"Pass %s\n",password); + + if (!(gNid=SRP_create_verifier(user, password, &srp_usersalt, &verifier, N, g))) + { + BIO_printf(bio,"Internal error validating SRP verifier\n"); + } + else + { + if (strcmp(verifier,srp_verifier)) + gNid = NULL; + OPENSSL_free(verifier); + } + } + return gNid; + } + +char * srp_create_user(char * user,char **srp_verifier, char **srp_usersalt,char *g, char *N, char *passout, BIO *bio, int verbose) + { + char password[1024]; + PW_CB_DATA cb_tmp; + char *gNid = NULL; + char *salt = NULL; + cb_tmp.prompt_info = user; + cb_tmp.password = passout; + + if (password_callback(password,1024,1,&cb_tmp) >0) + { + VERBOSE BIO_printf(bio,"Creating\n user=\"%s\"\n g=\"%s\"\n N=\"%s\"\n",user,g,N); + if (!(gNid =SRP_create_verifier(user, password, &salt, srp_verifier, N, g))) + { + BIO_printf(bio,"Internal error creating SRP verifier\n"); + } + else + *srp_usersalt = salt; + VVERBOSE BIO_printf(bio,"gNid=%s salt =\"%s\"\n verifier =\"%s\"\n", gNid,salt, *srp_verifier); + + } + return gNid; + } + +int MAIN(int argc, char **argv) + { +#ifndef OPENSSL_NO_ENGINE + ENGINE *e = NULL; +#endif + int add_user = 0; + int list_user= 0; + int delete_user= 0; + int modify_user= 0; + char * user = NULL; + + char *passargin = NULL, *passargout = NULL; + char *passin = NULL, *passout = NULL; + char * gN = NULL; + int gNindex = -1; + char ** gNrow = NULL; + int maxgN = -1; + + char * userinfo = NULL; + + int badops=0; + int ret=1; + int errors=0; + int verbose=0; + int doupdatedb=0; + char *configfile=NULL; + char *dbfile=NULL; + CA_DB *db=NULL; + char **pp ; + int i; + long errorline = -1; + char *randfile=NULL; +#ifndef OPENSSL_NO_ENGINE + char *engine = NULL; +#endif + char *tofree=NULL; + DB_ATTR db_attr; + +#ifdef EFENCE +EF_PROTECT_FREE=1; +EF_PROTECT_BELOW=1; +EF_ALIGNMENT=0; +#endif + + apps_startup(); + + conf = NULL; + section = NULL; + + if (bio_err == NULL) + if ((bio_err=BIO_new(BIO_s_file())) != NULL) + BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT); + + argc--; + argv++; + while (argc >= 1 && badops == 0) + { + if (strcmp(*argv,"-verbose") == 0) + verbose++; + else if (strcmp(*argv,"-config") == 0) + { + if (--argc < 1) goto bad; + configfile= *(++argv); + } + else if (strcmp(*argv,"-name") == 0) + { + if (--argc < 1) goto bad; + section= *(++argv); + } + else if (strcmp(*argv,"-srpvfile") == 0) + { + if (--argc < 1) goto bad; + dbfile= *(++argv); + } + else if (strcmp(*argv,"-add") == 0) + add_user=1; + else if (strcmp(*argv,"-delete") == 0) + delete_user=1; + else if (strcmp(*argv,"-modify") == 0) + modify_user=1; + else if (strcmp(*argv,"-list") == 0) + list_user=1; + else if (strcmp(*argv,"-gn") == 0) + { + if (--argc < 1) goto bad; + gN= *(++argv); + } + else if (strcmp(*argv,"-userinfo") == 0) + { + if (--argc < 1) goto bad; + userinfo= *(++argv); + } + else if (strcmp(*argv,"-passin") == 0) + { + if (--argc < 1) goto bad; + passargin= *(++argv); + } + else if (strcmp(*argv,"-passout") == 0) + { + if (--argc < 1) goto bad; + passargout= *(++argv); + } +#ifndef OPENSSL_NO_ENGINE + else if (strcmp(*argv,"-engine") == 0) + { + if (--argc < 1) goto bad; + engine= *(++argv); + } +#endif + + else if (**argv == '-') + { +bad: + BIO_printf(bio_err,"unknown option %s\n",*argv); + badops=1; + break; + } + else + break; + + argc--; + argv++; + } + + if (dbfile && configfile) + { + BIO_printf(bio_err,"-dbfile and -configfile cannot be specified together.\n"); + badops = 1; + } + if (add_user+delete_user+modify_user+list_user != 1) + { + BIO_printf(bio_err,"Exactly one of the options -add, -delete, -modify -list must be specified.\n"); + badops = 1; + } + if (delete_user+modify_user+delete_user== 1 && argc <= 0) + { + BIO_printf(bio_err,"Need at least one user for options -add, -delete, -modify. \n"); + badops = 1; + } + if ((passin || passout) && argc != 1 ) + { + BIO_printf(bio_err,"-passin, -passout arguments only valid with one user.\n"); + badops = 1; + } + + if (badops) + { + for (pp=srp_usage; (*pp != NULL); pp++) + BIO_printf(bio_err,"%s",*pp); + + BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR); + BIO_printf(bio_err," load the file (or the files in the directory) into\n"); + BIO_printf(bio_err," the random number generator\n"); + goto err; + } + + ERR_load_crypto_strings(); + +#ifndef OPENSSL_NO_ENGINE + e = setup_engine(bio_err, engine, 0); +#endif + + if(!app_passwd(bio_err, passargin, passargout, &passin, &passout)) + { + BIO_printf(bio_err, "Error getting passwords\n"); + goto err; + } + + if (!dbfile) + { + + + /*****************************************************************/ + tofree=NULL; + if (configfile == NULL) configfile = getenv("OPENSSL_CONF"); + if (configfile == NULL) configfile = getenv("SSLEAY_CONF"); + if (configfile == NULL) + { + const char *s=X509_get_default_cert_area(); + size_t len; + +#ifdef OPENSSL_SYS_VMS + len = strlen(s)+sizeof(CONFIG_FILE); + tofree=OPENSSL_malloc(len); + strcpy(tofree,s); +#else + len = strlen(s)+sizeof(CONFIG_FILE)+1; + tofree=OPENSSL_malloc(len); + BUF_strlcpy(tofree,s,len); + BUF_strlcat(tofree,"/",len); +#endif + BUF_strlcat(tofree,CONFIG_FILE,len); + configfile=tofree; + } + + VERBOSE BIO_printf(bio_err,"Using configuration from %s\n",configfile); + conf = NCONF_new(NULL); + if (NCONF_load(conf,configfile,&errorline) <= 0) + { + if (errorline <= 0) + BIO_printf(bio_err,"error loading the config file '%s'\n", + configfile); + else + BIO_printf(bio_err,"error on line %ld of config file '%s'\n" + ,errorline,configfile); + goto err; + } + if(tofree) + { + OPENSSL_free(tofree); + tofree = NULL; + } + + if (!load_config(bio_err, conf)) + goto err; + + /* Lets get the config section we are using */ + if (section == NULL) + { + VERBOSE BIO_printf(bio_err,"trying to read " ENV_DEFAULT_SRP " in \" BASE_SECTION \"\n"); + + section=NCONF_get_string(conf,BASE_SECTION,ENV_DEFAULT_SRP); + if (section == NULL) + { + lookup_fail(BASE_SECTION,ENV_DEFAULT_SRP); + goto err; + } + } + + if (randfile == NULL && conf) + randfile = NCONF_get_string(conf, BASE_SECTION, "RANDFILE"); + + + VERBOSE BIO_printf(bio_err,"trying to read " ENV_DATABASE " in section \"%s\"\n",section); + + if ((dbfile=NCONF_get_string(conf,section,ENV_DATABASE)) == NULL) + { + lookup_fail(section,ENV_DATABASE); + goto err; + } + + } + if (randfile == NULL) + ERR_clear_error(); + else + app_RAND_load_file(randfile, bio_err, 0); + + VERBOSE BIO_printf(bio_err,"Trying to read SRP verifier file \"%s\"\n",dbfile); + + db = load_index(dbfile, &db_attr); + if (db == NULL) goto err; + + /* Lets check some fields */ + for (i=0; idb->data); i++) + { + pp=(char **)sk_value(db->db->data,i); + + if (pp[DB_srptype][0] == DB_SRP_INDEX) + { + maxgN = i; + if (gNindex < 0 && gN != NULL && !strcmp(gN,pp[DB_srpid])) + gNindex = i; + + print_index(db,bio_err,i,verbose>1) ; + } + } + + VERBOSE BIO_printf(bio_err,"Database initialised\n"); + + if (gNindex >= 0) + { + gNrow=(char **)sk_value(db->db->data,gNindex); + print_entry(db,bio_err,gNindex,verbose>1,"Default g and N") ; + } + else if (maxgN > 0 && !SRP_get_default_gN(gN)) + { + BIO_printf(bio_err,"No g and N value for index \"%s\"\n",gN); + goto err; + } + else + { + VERBOSE BIO_printf(bio_err,"Database has no g N information.\n"); + gNrow = NULL; + } + + + VVERBOSE BIO_printf(bio_err,"Starting user processing\n"); + + if (argc > 0) + user = *(argv++) ; + + while (list_user || user) + { + int userindex = -1; + if (user) + VVERBOSE BIO_printf(bio_err,"Processing user \"%s\"\n",user); + if ((userindex = get_index(db, user, 'U')) >= 0) + { + print_user(db,bio_err,userindex,(verbose >0) || list_user) ; + } + + if (list_user) + { + if (user == NULL) + { + BIO_printf(bio_err,"List all users\n"); + + for (i=0; idb->data); i++) + { + print_user(db,bio_err,i,1) ; + } + list_user = 0; + } + else if (userindex < 0) + { + BIO_printf(bio_err,"user \"%s\" does not exist, ignored. t\n",user); + errors++; + } + } + else if (add_user) + { + if (userindex>=0) + { + /* reactivation of a new user */ + char ** row= (char **)sk_value(db->db->data,userindex); + BIO_printf(bio_err,"user \"%s\" reactivated.\n",user); + row[DB_srptype][0] = 'V' ; + + doupdatedb = 1; + } + else + { + char *row[DB_NUMBER] ; char * gNid; + row[DB_srpverifier] = NULL; + row[DB_srpsalt] = NULL; + row[DB_srpinfo] = NULL; + if (!(gNid = srp_create_user(user,&(row[DB_srpverifier]), &(row[DB_srpsalt]),gNrow?gNrow[DB_srpsalt]:gN,gNrow?gNrow[DB_srpverifier]:NULL, passout, bio_err,verbose))) + { + BIO_printf(bio_err,"Cannot create srp verifier for user \"%s\", operation abandoned .\n",user); + errors++ ; + goto err; + } + row[DB_srpid] = BUF_strdup(user); + row[DB_srptype] = BUF_strdup("v"); + row[DB_srpgN] = BUF_strdup(gNid); + + if (!row[DB_srpid] || !row[DB_srpgN] || !row[DB_srptype] || !row[DB_srpverifier] || !row[DB_srpsalt] || + (userinfo && (!(row[DB_srpinfo] = BUF_strdup(userinfo)))) || + !update_index(db, bio_err, row)) + { + if (row[DB_srpid]) OPENSSL_free(row[DB_srpid]); + if (row[DB_srpgN]) OPENSSL_free(row[DB_srpgN]); + if (row[DB_srpinfo]) OPENSSL_free(row[DB_srpinfo]); + if (row[DB_srptype]) OPENSSL_free(row[DB_srptype]); + if (row[DB_srpverifier]) OPENSSL_free(row[DB_srpverifier]); + if (row[DB_srpsalt]) OPENSSL_free(row[DB_srpsalt]); + goto err; + } + doupdatedb = 1; + } + } + else if (modify_user) + { + if (userindex<0) + { + BIO_printf(bio_err,"user \"%s\" does not exist, operation ignored.\n",user); + errors++ ; + } + else + { + + char ** row=(char **)sk_value(db->db->data,userindex); + char type = row[DB_srptype][0] ; + if (type == 'v') + { + BIO_printf(bio_err,"user \"%s\" already updated, operation ignored.\n",user); + errors++ ; + } + else + { + char * gNid ; + + if (row[DB_srptype][0] == 'V') + { + int user_gN ; + char ** irow = NULL; + VERBOSE BIO_printf(bio_err,"Verifying password for user \"%s\"\n",user); + if ( (user_gN = get_index(db, row[DB_srpgN],DB_SRP_INDEX)) >= 0) + irow=(char **)sk_value(db->db->data,userindex); + + if (!srp_verify_user(user,row[DB_srpverifier], row[DB_srpsalt],irow?irow[DB_srpsalt]:row[DB_srpgN], irow?irow[DB_srpverifier]:NULL, passin, bio_err,verbose)) + { + BIO_printf(bio_err,"Invalid password for user \"%s\", operation abandoned.\n",user); + errors++ ; + goto err; + } + } + VERBOSE BIO_printf(bio_err,"Password for user \"%s\" ok.\n",user); + + if (!(gNid=srp_create_user(user,&(row[DB_srpverifier]), &(row[DB_srpsalt]),gNrow?gNrow[DB_srpsalt]:NULL, gNrow?gNrow[DB_srpverifier]:NULL, passout, bio_err,verbose))) + { + BIO_printf(bio_err,"Cannot create srp verifier for user \"%s\", operation abandonned .\n", user); + errors++ ; + goto err; + } + + row[DB_srptype][0] = 'v'; + row[DB_srpgN] = BUF_strdup(gNid); + + if (!row[DB_srpid] || !row[DB_srpgN] || !row[DB_srptype] || !row[DB_srpverifier] || !row[DB_srpsalt] || + (userinfo && (!(row[DB_srpinfo] = BUF_strdup(userinfo))))) + goto err; + + doupdatedb = 1; + } + } + } + else if (delete_user) + { + if (userindex<0) + { + BIO_printf(bio_err,"user \"%s\" does not exist, operation ignored. t\n",user); + errors++; + } + else + { + char ** pp= (char **)sk_value(db->db->data,userindex); + BIO_printf(bio_err,"user \"%s\" revoked. t\n",user); + + pp[DB_srptype][0] = 'R' ; + + doupdatedb = 1; + } + } + if (--argc > 0) + user = *(argv++) ; + else + { + user = NULL; + list_user = 0; + } + } + + VERBOSE BIO_printf(bio_err,"User procession done.\n"); + + + if (doupdatedb) + { + /* Lets check some fields */ + for (i=0; idb->data); i++) + { + pp=(char **)sk_value(db->db->data,i); + + if (pp[DB_srptype][0] == 'v') + { + pp[DB_srptype][0] = 'V'; + print_user(db,bio_err,i,verbose) ; + } + } + + VERBOSE BIO_printf(bio_err,"Trying to update srpvfile.\n"); + if (!save_index(dbfile,"new",db)) goto err; + + VERBOSE BIO_printf(bio_err,"Temporary srpvfile created.\n"); + if (!rotate_index(dbfile,"new","old")) goto err; + + VERBOSE BIO_printf(bio_err,"srpvfile updated.\n"); + } + + ret = (errors != 0); +err: + if (errors != 0) + VERBOSE BIO_printf(bio_err,"User errors %d.\n",errors); + + VERBOSE BIO_printf(bio_err,"SRP terminating with code %d.\n",ret); + if(tofree) + OPENSSL_free(tofree); + if (ret) ERR_print_errors(bio_err); + if (randfile) app_RAND_write_file(randfile, bio_err); + if (conf) NCONF_free(conf); + if (db) free_index(db); + + OBJ_cleanup(); + apps_shutdown(); + OPENSSL_EXIT(ret); + } + + + +#endif + diff -ruN openssl-1.0.0d-orig/crypto/srp/Makefile openssl-1.0.0d-srp/crypto/srp/Makefile --- openssl-1.0.0d-orig/crypto/srp/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ openssl-1.0.0d-srp/crypto/srp/Makefile 2011-03-14 17:11:18.000000000 -0700 @@ -0,0 +1,91 @@ +DIR= srp +TOP= ../.. +CC= cc +INCLUDES= -I.. -I$(TOP) -I../../include +CFLAG=-g +INSTALL_PREFIX= +OPENSSLDIR= /usr/local/ssl +INSTALLTOP=/usr/local/ssl +MAKE= make -f Makefile.ssl +MAKEDEPPROG= makedepend +MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG) +MAKEFILE= Makefile.ssl +AR= ar r + +CFLAGS= $(INCLUDES) $(CFLAG) + +GENERAL=Makefile +TEST=srptest.c +APPS= + +LIB=$(TOP)/libcrypto.a +LIBSRC=srp_lib.c srp_vfy.c +LIBOBJ=srp_lib.o srp_vfy.o + +SRC= $(LIBSRC) + +EXHEADER= srp.h +HEADER= $(EXHEADER) + +top: + (cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all) + +all: lib + +lib: $(LIBOBJ) + $(AR) $(LIB) $(LIBOBJ) + $(RANLIB) $(LIB) || echo Never mind. + @touch lib + +links: + @$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER) + @$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST) + @$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS) + +install: + @for i in $(EXHEADER) ; \ + do \ + (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \ + chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \ + done; + +tags: + ctags $(SRC) + +tests: + +srptest: top srptest.c $(LIB) + $(CC) $(CFLAGS) -Wall -Werror -g -o srptest srptest.c $(LIB) + +lint: + lint -DLINT $(INCLUDES) $(SRC)>fluff + +depend: + $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC) + +dclean: + $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new + mv -f Makefile.new $(MAKEFILE) + +clean: + rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +srp_lib.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h +srp_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h +srp_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +srp_lib.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h +srp_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h +srp_lib.o: ../../include/openssl/sha.h ../../include/openssl/srp.h +srp_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +srp_lib.o: ../cryptlib.h srp_grps.h srp_lcl.h srp_lib.c +srp_vfy.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h +srp_vfy.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h +srp_vfy.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +srp_vfy.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h +srp_vfy.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +srp_vfy.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h +srp_vfy.o: ../../include/openssl/sha.h ../../include/openssl/srp.h +srp_vfy.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +srp_vfy.o: ../../include/openssl/txt_db.h ../cryptlib.h srp_lcl.h srp_vfy.c diff -ruN openssl-1.0.0d-orig/crypto/srp/srp.h openssl-1.0.0d-srp/crypto/srp/srp.h --- openssl-1.0.0d-orig/crypto/srp/srp.h 1969-12-31 16:00:00.000000000 -0800 +++ openssl-1.0.0d-srp/crypto/srp/srp.h 2011-03-14 17:11:18.000000000 -0700 @@ -0,0 +1,171 @@ +/* crypto/srp/srp.h */ +/* Written by Christophe Renou (christophe.renou@edelweb.fr) with + * the precious help of Peter Sylvester (peter.sylvester@edelweb.fr) + * for the EdelKey project and contributed to the OpenSSL project 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#ifndef __SRP_H__ +#define __SRP_H__ + +#ifndef OPENSSL_NO_SRP + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +typedef struct SRP_gN_cache_st + { + char *b64_bn; + BIGNUM *bn; + } SRP_gN_cache; + + +DECLARE_STACK_OF(SRP_gN_cache); + +typedef struct SRP_user_pwd_st + { + char *id; + BIGNUM *s; + BIGNUM *v; + BIGNUM *g; + BIGNUM *N; + char *info; + } SRP_user_pwd; + +DECLARE_STACK_OF(SRP_user_pwd); + +typedef struct SRP_VBASE_st + { + STACK_OF(SRP_user_pwd) *users_pwd; + STACK_OF(SRP_gN_cache) *gN_cache; +/* to simulate a user */ + char *seed_key; + BIGNUM *default_g; + BIGNUM *default_N; + } SRP_VBASE; + + +/*Structure interne pour retenir les couples N et g*/ +typedef struct SRP_gN_st + { + char *id; + BIGNUM *g; + BIGNUM *N; + } SRP_gN; + +DECLARE_STACK_OF(SRP_gN); + +SRP_VBASE *SRP_VBASE_new(char *seed_key); +int SRP_VBASE_free(SRP_VBASE *vb); +int SRP_VBASE_init(SRP_VBASE *vb, char * verifier_file); +SRP_user_pwd *SRP_VBASE_get_by_user(SRP_VBASE *vb, char *username); +char * SRP_create_verifier(const char *user, const char *pass, char **salt, char **verifier, char *N, char *g); +int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt, BIGNUM **verifier, BIGNUM *N, BIGNUM *g); + + +#define SRP_NO_ERROR 0 +#define SRP_ERR_VBASE_INCOMPLETE_FILE 1 +#define SRP_ERR_VBASE_BN_LIB 2 +#define SRP_ERR_OPEN_FILE 3 +#define SRP_ERR_MEMORY 4 + +#define DB_srptype 0 +#define DB_srpverifier 1 +#define DB_srpsalt 2 +#define DB_srpid 3 +#define DB_srpgN 4 +#define DB_srpinfo 5 +#undef DB_NUMBER +#define DB_NUMBER 6 + +#define DB_SRP_INDEX 'I' +#define DB_SRP_VALID 'V' +#define DB_SRP_REVOKED 'R' +#define DB_SRP_MODIF 'v' + + +/* see srp.c */ +char * SRP_check_known_gN_param(BIGNUM* g, BIGNUM* N); +SRP_gN *SRP_get_default_gN(const char * id) ; + +/* server side .... */ +BIGNUM *SRP_Calc_server_key(BIGNUM *A, BIGNUM *v, BIGNUM *u, BIGNUM *b, BIGNUM *N); +BIGNUM *SRP_Calc_B(BIGNUM *b, BIGNUM *N, BIGNUM *g, BIGNUM *v); +int SRP_Verify_A_mod_N(BIGNUM *A, BIGNUM *N); +BIGNUM *SRP_Calc_u(BIGNUM *A, BIGNUM *B, BIGNUM *N) ; + + + +/* client side .... */ +BIGNUM *SRP_Calc_x(BIGNUM *s, const char *user, const char *pass); +BIGNUM *SRP_Calc_A(BIGNUM *a, BIGNUM *N, BIGNUM *g); +BIGNUM *SRP_Calc_client_key(BIGNUM *N, BIGNUM *B, BIGNUM *g, BIGNUM *x, BIGNUM *a, BIGNUM *u); +int SRP_Verify_B_mod_N(BIGNUM *B, BIGNUM *N); + +#define SRP_MINIMAL_N 1024 + +#ifdef __cplusplus +} +#endif + +#endif +#endif diff -ruN openssl-1.0.0d-orig/crypto/srp/srp_grps.h openssl-1.0.0d-srp/crypto/srp/srp_grps.h --- openssl-1.0.0d-orig/crypto/srp/srp_grps.h 1969-12-31 16:00:00.000000000 -0800 +++ openssl-1.0.0d-srp/crypto/srp/srp_grps.h 2011-03-14 17:11:18.000000000 -0700 @@ -0,0 +1,517 @@ +/* start of generated data */ + +static BN_ULONG bn_group_1024_value[] = { + bn_pack4(9FC6,1D2F,C0EB,06E3), + bn_pack4(FD51,38FE,8376,435B), + bn_pack4(2FD4,CBF4,976E,AA9A), + bn_pack4(68ED,BC3C,0572,6CC0), + bn_pack4(C529,F566,660E,57EC), + bn_pack4(8255,9B29,7BCF,1885), + bn_pack4(CE8E,F4AD,69B1,5D49), + bn_pack4(5DC7,D7B4,6154,D6B6), + bn_pack4(8E49,5C1D,6089,DAD1), + bn_pack4(E0D5,D8E2,50B9,8BE4), + bn_pack4(383B,4813,D692,C6E0), + bn_pack4(D674,DF74,96EA,81D3), + bn_pack4(9EA2,314C,9C25,6576), + bn_pack4(6072,6187,75FF,3C0B), + bn_pack4(9C33,F80A,FA8F,C5E8), + bn_pack4(EEAF,0AB9,ADB3,8DD6) +}; +static BIGNUM bn_group_1024 = { + bn_group_1024_value, + (sizeof bn_group_1024_value)/sizeof(BN_ULONG), + (sizeof bn_group_1024_value)/sizeof(BN_ULONG), + 0, + BN_FLG_STATIC_DATA +}; + +static BN_ULONG bn_group_1536_value[] = { + bn_pack4(CF76,E3FE,D135,F9BB), + bn_pack4(1518,0F93,499A,234D), + bn_pack4(8CE7,A28C,2442,C6F3), + bn_pack4(5A02,1FFF,5E91,479E), + bn_pack4(7F8A,2FE9,B8B5,292E), + bn_pack4(837C,264A,E3A9,BEB8), + bn_pack4(E442,734A,F7CC,B7AE), + bn_pack4(6577,2E43,7D6C,7F8C), + bn_pack4(DB2F,D53D,24B7,C486), + bn_pack4(6EDF,0195,3934,9627), + bn_pack4(158B,FD3E,2B9C,8CF5), + bn_pack4(764E,3F4B,53DD,9DA1), + bn_pack4(4754,8381,DBC5,B1FC), + bn_pack4(9B60,9E0B,E3BA,B63D), + bn_pack4(8134,B1C8,B979,8914), + bn_pack4(DF02,8A7C,EC67,F0D0), + bn_pack4(80B6,55BB,9A22,E8DC), + bn_pack4(1558,903B,A0D0,F843), + bn_pack4(51C6,A94B,E460,7A29), + bn_pack4(5F4F,5F55,6E27,CBDE), + bn_pack4(BEEE,A961,4B19,CC4D), + bn_pack4(DBA5,1DF4,99AC,4C80), + bn_pack4(B1F1,2A86,17A4,7BBB), + bn_pack4(9DEF,3CAF,B939,277A) +}; +static BIGNUM bn_group_1536 = { + bn_group_1536_value, + (sizeof bn_group_1536_value)/sizeof(BN_ULONG), + (sizeof bn_group_1536_value)/sizeof(BN_ULONG), + 0, + BN_FLG_STATIC_DATA +}; + +static BN_ULONG bn_group_2048_value[] = { + bn_pack4(0FA7,111F,9E4A,FF73), + bn_pack4(9B65,E372,FCD6,8EF2), + bn_pack4(35DE,236D,525F,5475), + bn_pack4(94B5,C803,D89F,7AE4), + bn_pack4(71AE,35F8,E9DB,FBB6), + bn_pack4(2A56,98F3,A8D0,C382), + bn_pack4(9CCC,041C,7BC3,08D8), + bn_pack4(AF87,4E73,03CE,5329), + bn_pack4(6160,2790,04E5,7AE6), + bn_pack4(032C,FBDB,F52F,B378), + bn_pack4(5EA7,7A27,75D2,ECFA), + bn_pack4(5445,23B5,24B0,D57D), + bn_pack4(5B9D,32E6,88F8,7748), + bn_pack4(F1D2,B907,8717,461A), + bn_pack4(76BD,207A,436C,6481), + bn_pack4(CA97,B43A,23FB,8016), + bn_pack4(1D28,1E44,6B14,773B), + bn_pack4(7359,D041,D5C3,3EA7), + bn_pack4(A80D,740A,DBF4,FF74), + bn_pack4(55F9,7993,EC97,5EEA), + bn_pack4(2918,A996,2F0B,93B8), + bn_pack4(661A,05FB,D5FA,AAE8), + bn_pack4(CF60,9517,9A16,3AB3), + bn_pack4(E808,3969,EDB7,67B0), + bn_pack4(CD7F,48A9,DA04,FD50), + bn_pack4(D523,12AB,4B03,310D), + bn_pack4(8193,E075,7767,A13D), + bn_pack4(A373,29CB,B4A0,99ED), + bn_pack4(FC31,9294,3DB5,6050), + bn_pack4(AF72,B665,1987,EE07), + bn_pack4(F166,DE5E,1389,582F), + bn_pack4(AC6B,DB41,324A,9A9B) +}; +static BIGNUM bn_group_2048 = { + bn_group_2048_value, + (sizeof bn_group_2048_value)/sizeof(BN_ULONG), + (sizeof bn_group_2048_value)/sizeof(BN_ULONG), + 0, + BN_FLG_STATIC_DATA +}; + +static BN_ULONG bn_group_3072_value[] = { + bn_pack4(FFFF,FFFF,FFFF,FFFF), + bn_pack4(4B82,D120,A93A,D2CA), + bn_pack4(43DB,5BFC,E0FD,108E), + bn_pack4(08E2,4FA0,74E5,AB31), + bn_pack4(7709,88C0,BAD9,46E2), + bn_pack4(BBE1,1757,7A61,5D6C), + bn_pack4(521F,2B18,177B,200C), + bn_pack4(D876,0273,3EC8,6A64), + bn_pack4(F12F,FA06,D98A,0864), + bn_pack4(CEE3,D226,1AD2,EE6B), + bn_pack4(1E8C,94E0,4A25,619D), + bn_pack4(ABF5,AE8C,DB09,33D7), + bn_pack4(B397,0F85,A6E1,E4C7), + bn_pack4(8AEA,7157,5D06,0C7D), + bn_pack4(ECFB,8504,58DB,EF0A), + bn_pack4(A855,21AB,DF1C,BA64), + bn_pack4(AD33,170D,0450,7A33), + bn_pack4(1572,8E5A,8AAA,C42D), + bn_pack4(15D2,2618,98FA,0510), + bn_pack4(3995,497C,EA95,6AE5), + bn_pack4(DE2B,CBF6,9558,1718), + bn_pack4(B5C5,5DF0,6F4C,52C9), + bn_pack4(9B27,83A2,EC07,A28F), + bn_pack4(E39E,772C,180E,8603), + bn_pack4(3290,5E46,2E36,CE3B), + bn_pack4(F174,6C08,CA18,217C), + bn_pack4(670C,354E,4ABC,9804), + bn_pack4(9ED5,2907,7096,966D), + bn_pack4(1C62,F356,2085,52BB), + bn_pack4(8365,5D23,DCA3,AD96), + bn_pack4(6916,3FA8,FD24,CF5F), + bn_pack4(98DA,4836,1C55,D39A), + bn_pack4(C200,7CB8,A163,BF05), + bn_pack4(4928,6651,ECE4,5B3D), + bn_pack4(AE9F,2411,7C4B,1FE6), + bn_pack4(EE38,6BFB,5A89,9FA5), + bn_pack4(0BFF,5CB6,F406,B7ED), + bn_pack4(F44C,42E9,A637,ED6B), + bn_pack4(E485,B576,625E,7EC6), + bn_pack4(4FE1,356D,6D51,C245), + bn_pack4(302B,0A6D,F25F,1437), + bn_pack4(EF95,19B3,CD3A,431B), + bn_pack4(514A,0879,8E34,04DD), + bn_pack4(020B,BEA6,3B13,9B22), + bn_pack4(2902,4E08,8A67,CC74), + bn_pack4(C4C6,628B,80DC,1CD1), + bn_pack4(C90F,DAA2,2168,C234), + bn_pack4(FFFF,FFFF,FFFF,FFFF) +}; +static BIGNUM bn_group_3072 = { + bn_group_3072_value, + (sizeof bn_group_3072_value)/sizeof(BN_ULONG), + (sizeof bn_group_3072_value)/sizeof(BN_ULONG), + 0, + BN_FLG_STATIC_DATA +}; + +static BN_ULONG bn_group_4096_value[] = { + bn_pack4(FFFF,FFFF,FFFF,FFFF), + bn_pack4(4DF4,35C9,3406,3199), + bn_pack4(86FF,B7DC,90A6,C08F), + bn_pack4(93B4,EA98,8D8F,DDC1), + bn_pack4(D006,9127,D5B0,5AA9), + bn_pack4(B81B,DD76,2170,481C), + bn_pack4(1F61,2970,CEE2,D7AF), + bn_pack4(233B,A186,515B,E7ED), + bn_pack4(99B2,964F,A090,C3A2), + bn_pack4(287C,5947,4E6B,C05D), + bn_pack4(2E8E,FC14,1FBE,CAA6), + bn_pack4(DBBB,C2DB,04DE,8EF9), + bn_pack4(2583,E9CA,2AD4,4CE8), + bn_pack4(1A94,6834,B615,0BDA), + bn_pack4(99C3,2718,6AF4,E23C), + bn_pack4(8871,9A10,BDBA,5B26), + bn_pack4(1A72,3C12,A787,E6D7), + bn_pack4(4B82,D120,A921,0801), + bn_pack4(43DB,5BFC,E0FD,108E), + bn_pack4(08E2,4FA0,74E5,AB31), + bn_pack4(7709,88C0,BAD9,46E2), + bn_pack4(BBE1,1757,7A61,5D6C), + bn_pack4(521F,2B18,177B,200C), + bn_pack4(D876,0273,3EC8,6A64), + bn_pack4(F12F,FA06,D98A,0864), + bn_pack4(CEE3,D226,1AD2,EE6B), + bn_pack4(1E8C,94E0,4A25,619D), + bn_pack4(ABF5,AE8C,DB09,33D7), + bn_pack4(B397,0F85,A6E1,E4C7), + bn_pack4(8AEA,7157,5D06,0C7D), + bn_pack4(ECFB,8504,58DB,EF0A), + bn_pack4(A855,21AB,DF1C,BA64), + bn_pack4(AD33,170D,0450,7A33), + bn_pack4(1572,8E5A,8AAA,C42D), + bn_pack4(15D2,2618,98FA,0510), + bn_pack4(3995,497C,EA95,6AE5), + bn_pack4(DE2B,CBF6,9558,1718), + bn_pack4(B5C5,5DF0,6F4C,52C9), + bn_pack4(9B27,83A2,EC07,A28F), + bn_pack4(E39E,772C,180E,8603), + bn_pack4(3290,5E46,2E36,CE3B), + bn_pack4(F174,6C08,CA18,217C), + bn_pack4(670C,354E,4ABC,9804), + bn_pack4(9ED5,2907,7096,966D), + bn_pack4(1C62,F356,2085,52BB), + bn_pack4(8365,5D23,DCA3,AD96), + bn_pack4(6916,3FA8,FD24,CF5F), + bn_pack4(98DA,4836,1C55,D39A), + bn_pack4(C200,7CB8,A163,BF05), + bn_pack4(4928,6651,ECE4,5B3D), + bn_pack4(AE9F,2411,7C4B,1FE6), + bn_pack4(EE38,6BFB,5A89,9FA5), + bn_pack4(0BFF,5CB6,F406,B7ED), + bn_pack4(F44C,42E9,A637,ED6B), + bn_pack4(E485,B576,625E,7EC6), + bn_pack4(4FE1,356D,6D51,C245), + bn_pack4(302B,0A6D,F25F,1437), + bn_pack4(EF95,19B3,CD3A,431B), + bn_pack4(514A,0879,8E34,04DD), + bn_pack4(020B,BEA6,3B13,9B22), + bn_pack4(2902,4E08,8A67,CC74), + bn_pack4(C4C6,628B,80DC,1CD1), + bn_pack4(C90F,DAA2,2168,C234), + bn_pack4(FFFF,FFFF,FFFF,FFFF) +}; +static BIGNUM bn_group_4096 = { + bn_group_4096_value, + (sizeof bn_group_4096_value)/sizeof(BN_ULONG), + (sizeof bn_group_4096_value)/sizeof(BN_ULONG), + 0, + BN_FLG_STATIC_DATA +}; + +static BN_ULONG bn_group_6144_value[] = { + bn_pack4(FFFF,FFFF,FFFF,FFFF), + bn_pack4(E694,F91E,6DCC,4024), + bn_pack4(12BF,2D5B,0B74,74D6), + bn_pack4(043E,8F66,3F48,60EE), + bn_pack4(387F,E8D7,6E3C,0468), + bn_pack4(DA56,C9EC,2EF2,9632), + bn_pack4(EB19,CCB1,A313,D55C), + bn_pack4(F550,AA3D,8A1F,BFF0), + bn_pack4(06A1,D58B,B7C5,DA76), + bn_pack4(A797,15EE,F29B,E328), + bn_pack4(14CC,5ED2,0F80,37E0), + bn_pack4(CC8F,6D7E,BF48,E1D8), + bn_pack4(4BD4,07B2,2B41,54AA), + bn_pack4(0F1D,45B7,FF58,5AC5), + bn_pack4(23A9,7A7E,36CC,88BE), + bn_pack4(59E7,C97F,BEC7,E8F3), + bn_pack4(B5A8,4031,900B,1C9E), + bn_pack4(D55E,702F,4698,0C82), + bn_pack4(F482,D7CE,6E74,FEF6), + bn_pack4(F032,EA15,D172,1D03), + bn_pack4(5983,CA01,C64B,92EC), + bn_pack4(6FB8,F401,378C,D2BF), + bn_pack4(3320,5151,2BD7,AF42), + bn_pack4(DB7F,1447,E6CC,254B), + bn_pack4(44CE,6CBA,CED4,BB1B), + bn_pack4(DA3E,DBEB,CF9B,14ED), + bn_pack4(1797,27B0,865A,8918), + bn_pack4(B06A,53ED,9027,D831), + bn_pack4(E5DB,382F,4130,01AE), + bn_pack4(F8FF,9406,AD9E,530E), + bn_pack4(C975,1E76,3DBA,37BD), + bn_pack4(C1D4,DCB2,6026,46DE), + bn_pack4(36C3,FAB4,D27C,7026), + bn_pack4(4DF4,35C9,3402,8492), + bn_pack4(86FF,B7DC,90A6,C08F), + bn_pack4(93B4,EA98,8D8F,DDC1), + bn_pack4(D006,9127,D5B0,5AA9), + bn_pack4(B81B,DD76,2170,481C), + bn_pack4(1F61,2970,CEE2,D7AF), + bn_pack4(233B,A186,515B,E7ED), + bn_pack4(99B2,964F,A090,C3A2), + bn_pack4(287C,5947,4E6B,C05D), + bn_pack4(2E8E,FC14,1FBE,CAA6), + bn_pack4(DBBB,C2DB,04DE,8EF9), + bn_pack4(2583,E9CA,2AD4,4CE8), + bn_pack4(1A94,6834,B615,0BDA), + bn_pack4(99C3,2718,6AF4,E23C), + bn_pack4(8871,9A10,BDBA,5B26), + bn_pack4(1A72,3C12,A787,E6D7), + bn_pack4(4B82,D120,A921,0801), + bn_pack4(43DB,5BFC,E0FD,108E), + bn_pack4(08E2,4FA0,74E5,AB31), + bn_pack4(7709,88C0,BAD9,46E2), + bn_pack4(BBE1,1757,7A61,5D6C), + bn_pack4(521F,2B18,177B,200C), + bn_pack4(D876,0273,3EC8,6A64), + bn_pack4(F12F,FA06,D98A,0864), + bn_pack4(CEE3,D226,1AD2,EE6B), + bn_pack4(1E8C,94E0,4A25,619D), + bn_pack4(ABF5,AE8C,DB09,33D7), + bn_pack4(B397,0F85,A6E1,E4C7), + bn_pack4(8AEA,7157,5D06,0C7D), + bn_pack4(ECFB,8504,58DB,EF0A), + bn_pack4(A855,21AB,DF1C,BA64), + bn_pack4(AD33,170D,0450,7A33), + bn_pack4(1572,8E5A,8AAA,C42D), + bn_pack4(15D2,2618,98FA,0510), + bn_pack4(3995,497C,EA95,6AE5), + bn_pack4(DE2B,CBF6,9558,1718), + bn_pack4(B5C5,5DF0,6F4C,52C9), + bn_pack4(9B27,83A2,EC07,A28F), + bn_pack4(E39E,772C,180E,8603), + bn_pack4(3290,5E46,2E36,CE3B), + bn_pack4(F174,6C08,CA18,217C), + bn_pack4(670C,354E,4ABC,9804), + bn_pack4(9ED5,2907,7096,966D), + bn_pack4(1C62,F356,2085,52BB), + bn_pack4(8365,5D23,DCA3,AD96), + bn_pack4(6916,3FA8,FD24,CF5F), + bn_pack4(98DA,4836,1C55,D39A), + bn_pack4(C200,7CB8,A163,BF05), + bn_pack4(4928,6651,ECE4,5B3D), + bn_pack4(AE9F,2411,7C4B,1FE6), + bn_pack4(EE38,6BFB,5A89,9FA5), + bn_pack4(0BFF,5CB6,F406,B7ED), + bn_pack4(F44C,42E9,A637,ED6B), + bn_pack4(E485,B576,625E,7EC6), + bn_pack4(4FE1,356D,6D51,C245), + bn_pack4(302B,0A6D,F25F,1437), + bn_pack4(EF95,19B3,CD3A,431B), + bn_pack4(514A,0879,8E34,04DD), + bn_pack4(020B,BEA6,3B13,9B22), + bn_pack4(2902,4E08,8A67,CC74), + bn_pack4(C4C6,628B,80DC,1CD1), + bn_pack4(C90F,DAA2,2168,C234), + bn_pack4(FFFF,FFFF,FFFF,FFFF) +}; +static BIGNUM bn_group_6144 = { + bn_group_6144_value, + (sizeof bn_group_6144_value)/sizeof(BN_ULONG), + (sizeof bn_group_6144_value)/sizeof(BN_ULONG), + 0, + BN_FLG_STATIC_DATA +}; + +static BN_ULONG bn_group_8192_value[] = { + bn_pack4(FFFF,FFFF,FFFF,FFFF), + bn_pack4(60C9,80DD,98ED,D3DF), + bn_pack4(C81F,56E8,80B9,6E71), + bn_pack4(9E30,50E2,7656,94DF), + bn_pack4(9558,E447,5677,E9AA), + bn_pack4(C919,0DA6,FC02,6E47), + bn_pack4(889A,002E,D5EE,382B), + bn_pack4(4009,438B,481C,6CD7), + bn_pack4(3590,46F4,EB87,9F92), + bn_pack4(FAF3,6BC3,1ECF,A268), + bn_pack4(B1D5,10BD,7EE7,4D73), + bn_pack4(F9AB,4819,5DED,7EA1), + bn_pack4(64F3,1CC5,0846,851D), + bn_pack4(4597,E899,A025,5DC1), + bn_pack4(DF31,0EE0,74AB,6A36), + bn_pack4(6D2A,13F8,3F44,F82D), + bn_pack4(062B,3CF5,B3A2,78A6), + bn_pack4(7968,3303,ED5B,DD3A), + bn_pack4(FA9D,4B7F,A2C0,87E8), + bn_pack4(4BCB,C886,2F83,85DD), + bn_pack4(3473,FC64,6CEA,306B), + bn_pack4(13EB,57A8,1A23,F0C7), + bn_pack4(2222,2E04,A403,7C07), + bn_pack4(E3FD,B8BE,FC84,8AD9), + bn_pack4(238F,16CB,E39D,652D), + bn_pack4(3423,B474,2BF1,C978), + bn_pack4(3AAB,639C,5AE4,F568), + bn_pack4(2576,F693,6BA4,2466), + bn_pack4(741F,A7BF,8AFC,47ED), + bn_pack4(3BC8,32B6,8D9D,D300), + bn_pack4(D8BE,C4D0,73B9,31BA), + bn_pack4(3877,7CB6,A932,DF8C), + bn_pack4(74A3,926F,12FE,E5E4), + bn_pack4(E694,F91E,6DBE,1159), + bn_pack4(12BF,2D5B,0B74,74D6), + bn_pack4(043E,8F66,3F48,60EE), + bn_pack4(387F,E8D7,6E3C,0468), + bn_pack4(DA56,C9EC,2EF2,9632), + bn_pack4(EB19,CCB1,A313,D55C), + bn_pack4(F550,AA3D,8A1F,BFF0), + bn_pack4(06A1,D58B,B7C5,DA76), + bn_pack4(A797,15EE,F29B,E328), + bn_pack4(14CC,5ED2,0F80,37E0), + bn_pack4(CC8F,6D7E,BF48,E1D8), + bn_pack4(4BD4,07B2,2B41,54AA), + bn_pack4(0F1D,45B7,FF58,5AC5), + bn_pack4(23A9,7A7E,36CC,88BE), + bn_pack4(59E7,C97F,BEC7,E8F3), + bn_pack4(B5A8,4031,900B,1C9E), + bn_pack4(D55E,702F,4698,0C82), + bn_pack4(F482,D7CE,6E74,FEF6), + bn_pack4(F032,EA15,D172,1D03), + bn_pack4(5983,CA01,C64B,92EC), + bn_pack4(6FB8,F401,378C,D2BF), + bn_pack4(3320,5151,2BD7,AF42), + bn_pack4(DB7F,1447,E6CC,254B), + bn_pack4(44CE,6CBA,CED4,BB1B), + bn_pack4(DA3E,DBEB,CF9B,14ED), + bn_pack4(1797,27B0,865A,8918), + bn_pack4(B06A,53ED,9027,D831), + bn_pack4(E5DB,382F,4130,01AE), + bn_pack4(F8FF,9406,AD9E,530E), + bn_pack4(C975,1E76,3DBA,37BD), + bn_pack4(C1D4,DCB2,6026,46DE), + bn_pack4(36C3,FAB4,D27C,7026), + bn_pack4(4DF4,35C9,3402,8492), + bn_pack4(86FF,B7DC,90A6,C08F), + bn_pack4(93B4,EA98,8D8F,DDC1), + bn_pack4(D006,9127,D5B0,5AA9), + bn_pack4(B81B,DD76,2170,481C), + bn_pack4(1F61,2970,CEE2,D7AF), + bn_pack4(233B,A186,515B,E7ED), + bn_pack4(99B2,964F,A090,C3A2), + bn_pack4(287C,5947,4E6B,C05D), + bn_pack4(2E8E,FC14,1FBE,CAA6), + bn_pack4(DBBB,C2DB,04DE,8EF9), + bn_pack4(2583,E9CA,2AD4,4CE8), + bn_pack4(1A94,6834,B615,0BDA), + bn_pack4(99C3,2718,6AF4,E23C), + bn_pack4(8871,9A10,BDBA,5B26), + bn_pack4(1A72,3C12,A787,E6D7), + bn_pack4(4B82,D120,A921,0801), + bn_pack4(43DB,5BFC,E0FD,108E), + bn_pack4(08E2,4FA0,74E5,AB31), + bn_pack4(7709,88C0,BAD9,46E2), + bn_pack4(BBE1,1757,7A61,5D6C), + bn_pack4(521F,2B18,177B,200C), + bn_pack4(D876,0273,3EC8,6A64), + bn_pack4(F12F,FA06,D98A,0864), + bn_pack4(CEE3,D226,1AD2,EE6B), + bn_pack4(1E8C,94E0,4A25,619D), + bn_pack4(ABF5,AE8C,DB09,33D7), + bn_pack4(B397,0F85,A6E1,E4C7), + bn_pack4(8AEA,7157,5D06,0C7D), + bn_pack4(ECFB,8504,58DB,EF0A), + bn_pack4(A855,21AB,DF1C,BA64), + bn_pack4(AD33,170D,0450,7A33), + bn_pack4(1572,8E5A,8AAA,C42D), + bn_pack4(15D2,2618,98FA,0510), + bn_pack4(3995,497C,EA95,6AE5), + bn_pack4(DE2B,CBF6,9558,1718), + bn_pack4(B5C5,5DF0,6F4C,52C9), + bn_pack4(9B27,83A2,EC07,A28F), + bn_pack4(E39E,772C,180E,8603), + bn_pack4(3290,5E46,2E36,CE3B), + bn_pack4(F174,6C08,CA18,217C), + bn_pack4(670C,354E,4ABC,9804), + bn_pack4(9ED5,2907,7096,966D), + bn_pack4(1C62,F356,2085,52BB), + bn_pack4(8365,5D23,DCA3,AD96), + bn_pack4(6916,3FA8,FD24,CF5F), + bn_pack4(98DA,4836,1C55,D39A), + bn_pack4(C200,7CB8,A163,BF05), + bn_pack4(4928,6651,ECE4,5B3D), + bn_pack4(AE9F,2411,7C4B,1FE6), + bn_pack4(EE38,6BFB,5A89,9FA5), + bn_pack4(0BFF,5CB6,F406,B7ED), + bn_pack4(F44C,42E9,A637,ED6B), + bn_pack4(E485,B576,625E,7EC6), + bn_pack4(4FE1,356D,6D51,C245), + bn_pack4(302B,0A6D,F25F,1437), + bn_pack4(EF95,19B3,CD3A,431B), + bn_pack4(514A,0879,8E34,04DD), + bn_pack4(020B,BEA6,3B13,9B22), + bn_pack4(2902,4E08,8A67,CC74), + bn_pack4(C4C6,628B,80DC,1CD1), + bn_pack4(C90F,DAA2,2168,C234), + bn_pack4(FFFF,FFFF,FFFF,FFFF) +}; +static BIGNUM bn_group_8192 = { + bn_group_8192_value, + (sizeof bn_group_8192_value)/sizeof(BN_ULONG), + (sizeof bn_group_8192_value)/sizeof(BN_ULONG), + 0, + BN_FLG_STATIC_DATA +}; + +static BN_ULONG bn_generator_19_value[] = {19} ; +static BIGNUM bn_generator_19 = { + bn_generator_19_value, + 1, + 1, + 0, + BN_FLG_STATIC_DATA +}; +static BN_ULONG bn_generator_5_value[] = {5} ; +static BIGNUM bn_generator_5 = { + bn_generator_5_value, + 1, + 1, + 0, + BN_FLG_STATIC_DATA +}; +static BN_ULONG bn_generator_2_value[] = {2} ; +static BIGNUM bn_generator_2 = { + bn_generator_2_value, + 1, + 1, + 0, + BN_FLG_STATIC_DATA +}; + +static SRP_gN knowngN[] = { + {"8192",&bn_generator_19 , &bn_group_8192}, + {"6144",&bn_generator_5 , &bn_group_6144}, + {"4096",&bn_generator_5 , &bn_group_4096}, + {"3072",&bn_generator_5 , &bn_group_3072}, + {"2048",&bn_generator_2 , &bn_group_2048}, + {"1536",&bn_generator_2 , &bn_group_1536}, + {"1024",&bn_generator_2 , &bn_group_1024}, +}; +#define KNOWN_GN_NUMBER sizeof(knowngN) / sizeof(SRP_gN) + +/* end of generated data */ diff -ruN openssl-1.0.0d-orig/crypto/srp/srp_lcl.h openssl-1.0.0d-srp/crypto/srp/srp_lcl.h --- openssl-1.0.0d-orig/crypto/srp/srp_lcl.h 1969-12-31 16:00:00.000000000 -0800 +++ openssl-1.0.0d-srp/crypto/srp/srp_lcl.h 2011-03-14 17:11:18.000000000 -0700 @@ -0,0 +1,83 @@ +/* crypto/srp/srp_lcl.h */ +/* Written by Peter Sylvester (peter.sylvester@edelweb.fr) + * for the EdelKey project and contributed to the OpenSSL project 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#ifndef HEADER_SRP_LCL_H +#define HEADER_SRP_LCL_H + +#include +#include + +#if 0 +#define srp_bn_print(a) {fprintf(stderr, #a "="); BN_print_fp(stderr,a); \ + fprintf(stderr,"\n");} +#else +#define srp_bn_print(a) +#endif + + + +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif + +#endif diff -ruN openssl-1.0.0d-orig/crypto/srp/srp_lib.c openssl-1.0.0d-srp/crypto/srp/srp_lib.c --- openssl-1.0.0d-orig/crypto/srp/srp_lib.c 1969-12-31 16:00:00.000000000 -0800 +++ openssl-1.0.0d-srp/crypto/srp/srp_lib.c 2011-03-14 17:11:18.000000000 -0700 @@ -0,0 +1,357 @@ +/* crypto/srp/srp_lib.c */ +/* Written by Christophe Renou (christophe.renou@edelweb.fr) with + * the precious help of Peter Sylvester (peter.sylvester@edelweb.fr) + * for the EdelKey project and contributed to the OpenSSL project 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#ifndef OPENSSL_NO_SRP +#include "cryptlib.h" +#include "srp_lcl.h" +#include +#include + +#if (BN_BYTES == 8) +#define bn_pack4(a1,a2,a3,a4) 0x##a1##a2##a3##a4##ul +#endif +#if (BN_BYTES == 4) +#define bn_pack4(a1,a2,a3,a4) 0x##a3##a4##ul, 0x##a1##a2##ul +#endif +#if (BN_BYTES == 2) +#define bn_pack4(a1,a2,a3,a4) 0x##a4##u,0x##a3##u,0x##a2##u,0x##a1##u +#endif + + +#include "srp_grps.h" + +static BIGNUM *srp_Calc_k(BIGNUM *N, BIGNUM *g) + { + /* k = SHA1(N | PAD(g)) -- tls-srp draft 8 */ + + unsigned char digest[SHA_DIGEST_LENGTH]; + unsigned char *tmp; + EVP_MD_CTX ctxt; + int longg ; + int longN = BN_num_bytes(N); + + if ((tmp = OPENSSL_malloc(longN)) == NULL) + return NULL; + BN_bn2bin(N,tmp) ; + + EVP_MD_CTX_init(&ctxt); + EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL); + EVP_DigestUpdate(&ctxt, tmp, longN); + + memset(tmp, 0, longN); + longg = BN_bn2bin(g,tmp) ; + /* use the zeros behind to pad on left */ + EVP_DigestUpdate(&ctxt, tmp + longg, longN-longg); + EVP_DigestUpdate(&ctxt, tmp, longg); + OPENSSL_free(tmp); + + EVP_DigestFinal_ex(&ctxt, digest, NULL); + EVP_MD_CTX_cleanup(&ctxt); + return BN_bin2bn(digest, sizeof(digest), NULL); + } + +BIGNUM *SRP_Calc_u(BIGNUM *A, BIGNUM *B, BIGNUM *N) + { + /* k = SHA1(PAD(A) || PAD(B) ) -- tls-srp draft 8 */ + + BIGNUM *u; + unsigned char cu[SHA_DIGEST_LENGTH]; + unsigned char *cAB; + EVP_MD_CTX ctxt; + int longN; + if ((A == NULL) ||(B == NULL) || (N == NULL)) + return NULL; + + longN= BN_num_bytes(N); + + if ((cAB = OPENSSL_malloc(2*longN)) == NULL) + return NULL; + + memset(cAB, 0, longN); + + EVP_MD_CTX_init(&ctxt); + EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL); + EVP_DigestUpdate(&ctxt, cAB + BN_bn2bin(A,cAB+longN), longN); + EVP_DigestUpdate(&ctxt, cAB + BN_bn2bin(B,cAB+longN), longN); + OPENSSL_free(cAB); + EVP_DigestFinal_ex(&ctxt, cu, NULL); + EVP_MD_CTX_cleanup(&ctxt); + + if (!(u = BN_bin2bn(cu, sizeof(cu), NULL))) + return NULL; + if (!BN_is_zero(u)) + return u; + BN_free(u); + return NULL; +} + +BIGNUM *SRP_Calc_server_key(BIGNUM *A, BIGNUM *v, BIGNUM *u, BIGNUM *b, BIGNUM *N) + { + BIGNUM *tmp = NULL, *S = NULL; + BN_CTX *bn_ctx; + + if (u == NULL || A == NULL || v == NULL || b == NULL || N == NULL) + return NULL; + + if ((bn_ctx = BN_CTX_new()) == NULL || + (tmp = BN_new()) == NULL || + (S = BN_new()) == NULL ) + goto err; + + /* S = (A*v**u) ** b */ + + if (!BN_mod_exp(tmp,v,u,N,bn_ctx)) + goto err; + if (!BN_mod_mul(tmp,A,tmp,N,bn_ctx)) + goto err; + if (!BN_mod_exp(S,tmp,b,N,bn_ctx)) + goto err; +err: + BN_CTX_free(bn_ctx); + BN_clear_free(tmp); + return S; + } + +BIGNUM *SRP_Calc_B(BIGNUM *b, BIGNUM *N, BIGNUM *g, BIGNUM *v) + { + BIGNUM *kv = NULL, *gb = NULL; + BIGNUM *B = NULL, *k = NULL; + BN_CTX *bn_ctx; + + if (b == NULL || N == NULL || g == NULL || v == NULL || + (bn_ctx = BN_CTX_new()) == NULL) + return NULL; + + if ( (kv = BN_new()) == NULL || + (gb = BN_new()) == NULL || + (B = BN_new())== NULL) + goto err; + + /* B = g**b + k*v */ + + if (!BN_mod_exp(gb,g,b,N,bn_ctx) || + !(k = srp_Calc_k(N,g)) || + !BN_mod_mul(kv,v,k,N,bn_ctx) || + !BN_mod_add(B,gb,kv,N,bn_ctx)) + { + BN_free(B); + B = NULL; + } +err: + BN_CTX_free(bn_ctx); + BN_clear_free(kv); + BN_clear_free(gb); + BN_free(k); + return B; + } + +BIGNUM *SRP_Calc_x(BIGNUM *s, const char *user, const char *pass) + { + unsigned char dig[SHA_DIGEST_LENGTH]; + EVP_MD_CTX ctxt; + unsigned char *cs; + + if ((s == NULL) || + (user == NULL) || + (pass == NULL)) + return NULL; + + if ((cs = OPENSSL_malloc(BN_num_bytes(s))) == NULL) + return NULL; + + EVP_MD_CTX_init(&ctxt); + EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL); + EVP_DigestUpdate(&ctxt, user, strlen(user)); + EVP_DigestUpdate(&ctxt, ":", 1); + EVP_DigestUpdate(&ctxt, pass, strlen(pass)); + EVP_DigestFinal_ex(&ctxt, dig, NULL); + + EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL); + BN_bn2bin(s,cs); + EVP_DigestUpdate(&ctxt, cs, BN_num_bytes(s)); + OPENSSL_free(cs); + EVP_DigestUpdate(&ctxt, dig, sizeof(dig)); + EVP_DigestFinal_ex(&ctxt, dig, NULL); + EVP_MD_CTX_cleanup(&ctxt); + + return BN_bin2bn(dig, sizeof(dig), NULL); + } + +BIGNUM *SRP_Calc_A(BIGNUM *a, BIGNUM *N, BIGNUM *g) + { + BN_CTX *bn_ctx; + BIGNUM * A = NULL; + + if (a == NULL || N == NULL || g == NULL || + (bn_ctx = BN_CTX_new()) == NULL) + return NULL; + + if ((A = BN_new()) != NULL && + !BN_mod_exp(A,g,a,N,bn_ctx)) + { + BN_free(A); + A = NULL; + } + BN_CTX_free(bn_ctx); + return A; + } + + +BIGNUM *SRP_Calc_client_key(BIGNUM *N, BIGNUM *B, BIGNUM *g, BIGNUM *x, BIGNUM *a, BIGNUM *u) + { + BIGNUM *tmp = NULL, *tmp2 = NULL, *tmp3 = NULL , *k = NULL, *K = NULL; + BN_CTX *bn_ctx; + + if (u == NULL || B == NULL || N == NULL || g == NULL || x == NULL || a == NULL || + (bn_ctx = BN_CTX_new()) == NULL) + return NULL; + + if ((tmp = BN_new()) == NULL || + (tmp2 = BN_new())== NULL || + (tmp3 = BN_new())== NULL || + (K = BN_new()) == NULL) + goto err; + + if (!BN_mod_exp(tmp,g,x,N,bn_ctx)) + goto err; + if (!(k = srp_Calc_k(N,g))) + goto err; + if (!BN_mod_mul(tmp2,tmp,k,N,bn_ctx)) + goto err; + if (!BN_mod_sub(tmp,B,tmp2,N,bn_ctx)) + goto err; + + if (!BN_mod_mul(tmp3,u,x,N,bn_ctx)) + goto err; + if (!BN_mod_add(tmp2,a,tmp3,N,bn_ctx)) + goto err; + if (!BN_mod_exp(K,tmp,tmp2,N,bn_ctx)) + goto err; + +err : + BN_CTX_free(bn_ctx); + BN_clear_free(tmp); + BN_clear_free(tmp2); + BN_clear_free(tmp3); + BN_free(k); + return K; + } + +int SRP_Verify_B_mod_N(BIGNUM *B, BIGNUM *N) + { + BIGNUM *r; + BN_CTX *bn_ctx; + int ret = 0; + + if (B == NULL || N == NULL || + (bn_ctx = BN_CTX_new()) == NULL) + return 0; + + if ((r = BN_new()) == NULL) + goto err; + /* Checks if B % N == 0 */ + if (!BN_nnmod(r,B,N,bn_ctx)) + goto err; + ret = !BN_is_zero(r); +err: + BN_CTX_free(bn_ctx); + BN_free(r); + return ret; + } + +int SRP_Verify_A_mod_N(BIGNUM *A, BIGNUM *N) + { + /* Checks if A % N == 0 */ + return SRP_Verify_B_mod_N(A,N) ; + } + + +/* Check if G and N are kwown parameters. + The values have been generated from the ietf-tls-srp draft version 8 +*/ +char * SRP_check_known_gN_param(BIGNUM* g, BIGNUM* N) + { + int i; + if ((g == NULL) || (N == NULL)) + return 0; + + srp_bn_print(g); + srp_bn_print(N); + + for(i = 0; i < KNOWN_GN_NUMBER; i++) + { + if (BN_cmp(knowngN[i].g,g) == 0 && BN_cmp(knowngN[i].N,N) == 0) + return knowngN[i].id; + } + return NULL; + } + +SRP_gN *SRP_get_default_gN(const char * id) + { + int i; + + if (id == NULL) + return knowngN; + for(i = 0; i < KNOWN_GN_NUMBER; i++) + { + if (strcmp(knowngN[i].id,id)==0) + return knowngN+i; + } + return NULL; + } +#endif diff -ruN openssl-1.0.0d-orig/crypto/srp/srp_vfy.c openssl-1.0.0d-srp/crypto/srp/srp_vfy.c --- openssl-1.0.0d-orig/crypto/srp/srp_vfy.c 1969-12-31 16:00:00.000000000 -0800 +++ openssl-1.0.0d-srp/crypto/srp/srp_vfy.c 2011-03-14 17:13:43.000000000 -0700 @@ -0,0 +1,650 @@ +/* crypto/srp/srp_vfy.c */ +/* Written by Christophe Renou (christophe.renou@edelweb.fr) with + * the precious help of Peter Sylvester (peter.sylvester@edelweb.fr) + * for the EdelKey project and contributed to the OpenSSL project 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#ifndef OPENSSL_NO_SRP +#include "cryptlib.h" +#include "srp_lcl.h" +#include +#include +#include +#include +#include + +#define SRP_RANDOM_SALT_LEN 20 +#define MAX_LEN 2500 + +static char b64table[] = + "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./"; + +/* the following two conversion routines have been inspired by code from Stanford */ + +/* + * Convert a base64 string into raw byte array representation. + */ +static int t_fromb64(char * a, const char * src) + { + char *loc; + int i, j; + int size; + + while(*src && (*src == ' ' || *src == '\t' || *src == '\n')) + ++src; + size = strlen(src); + i = 0; + while(i < size) + { + loc = strchr(b64table, src[i]); + if(loc == (char *) 0) break; + else a[i] = loc - b64table; + ++i; + } + size = i; + i = size - 1; + j = size; + while(1) + { + a[j] = a[i]; + if(--i < 0) break; + a[j] |= (a[i] & 3) << 6; + --j; + a[j] = (unsigned char) ((a[i] & 0x3c) >> 2); + if(--i < 0) break; + a[j] |= (a[i] & 0xf) << 4; + --j; + a[j] = (unsigned char) ((a[i] & 0x30) >> 4); + if(--i < 0) break; + a[j] |= (a[i] << 2); + + a[--j] = 0; + if(--i < 0) break; + } + while(a[j] == 0 && j <= size) ++j; + i = 0; + while (j <= size) a[i++] = a[j++]; + return i; + } + + +/* + * Convert a raw byte string into a null-terminated base64 ASCII string. + */ +static char *t_tob64(char * dst, const char * src, int size) + { + int c, pos = size % 3; + unsigned char b0 = 0, b1 = 0, b2 = 0, notleading = 0; + char *olddst = dst; + + switch(pos) + { + case 1: + b2 = src[0]; + break; + case 2: + b1 = src[0]; + b2 = src[1]; + break; + } + + while(1) + { + c = (b0 & 0xfc) >> 2; + if(notleading || c != 0) + { + *dst++ = b64table[c]; + notleading = 1; + } + c = ((b0 & 3) << 4) | ((b1 & 0xf0) >> 4); + if(notleading || c != 0) + { + *dst++ = b64table[c]; + notleading = 1; + } + c = ((b1 & 0xf) << 2) | ((b2 & 0xc0) >> 6); + if(notleading || c != 0) + { + *dst++ = b64table[c]; + notleading = 1; + } + c = b2 & 0x3f; + if(notleading || c != 0) + { + *dst++ = b64table[c]; + notleading = 1; + } + if(pos >= size) break; + else + { + b0 = src[pos++]; + b1 = src[pos++]; + b2 = src[pos++]; + } + } + + *dst++ = '\0'; + return olddst; + } + +void SRP_user_pwd_free(SRP_user_pwd *user_pwd) + { + if (user_pwd == NULL) + return; + BN_free(user_pwd->s); + BN_clear_free(user_pwd->v); + OPENSSL_free(user_pwd->id); + OPENSSL_free(user_pwd->info); + OPENSSL_free(user_pwd); + } + +SRP_user_pwd * SRP_user_pwd_new() + { + SRP_user_pwd * ret = OPENSSL_malloc(sizeof(SRP_user_pwd)); + if (ret == NULL) + return NULL; + ret->N = NULL; + ret->g = NULL; + ret->s = NULL; + ret->v = NULL; + ret->id = NULL ; + ret->info = NULL; + return ret; + } + +void SRP_user_pwd_set_gN(SRP_user_pwd * vinfo, BIGNUM * g, BIGNUM * N) + { + vinfo->N = N; + vinfo->g = g; + } + +int SRP_user_pwd_set_ids(SRP_user_pwd * vinfo, char * id, char * info) + { + if (id != NULL && NULL == (vinfo->id = BUF_strdup(id))) + return 0; + return (info == NULL || NULL != (vinfo->info = BUF_strdup(info))) ; + } + +int SRP_user_pwd_set_sv(SRP_user_pwd * vinfo, char * s, char * v) + { + char tmp[MAX_LEN]; + int len ; + if (strlen(s) > MAX_LEN || strlen(v) > MAX_LEN) + return 0; + len = t_fromb64(tmp,v); + if (NULL == (vinfo->v = BN_bin2bn(tmp,len,NULL)) ) + return 0; + len = t_fromb64(tmp,s); + return ((vinfo->s = BN_bin2bn(tmp,len,NULL)) != NULL) ; + } + +int SRP_user_pwd_set_sv_BN(SRP_user_pwd * vinfo, BIGNUM * s, BIGNUM * v) + { + vinfo->v = v; + vinfo->s = s; + return (vinfo->s != NULL && vinfo->v != NULL) ; + } + +SRP_VBASE *SRP_VBASE_new(char *seed_key) + { + SRP_VBASE *vb = (SRP_VBASE *) OPENSSL_malloc(sizeof(SRP_VBASE)); + + if (vb == NULL) + return NULL; + if (!(vb->users_pwd = sk_SRP_user_pwd_new_null()) || + !(vb->gN_cache = sk_SRP_gN_cache_new_null())) + { + OPENSSL_free(vb); + return NULL; + } + vb->default_g = NULL; + vb->default_N = NULL; + vb->seed_key = NULL; + if ((seed_key != NULL) && + (vb->seed_key = BUF_strdup(seed_key)) == NULL) + { + sk_SRP_user_pwd_free(vb->users_pwd); + sk_SRP_gN_cache_free(vb->gN_cache); + OPENSSL_free(vb); + return NULL; + } + return vb; + } + + +int SRP_VBASE_free(SRP_VBASE *vb) + { + sk_SRP_user_pwd_pop_free(vb->users_pwd,SRP_user_pwd_free); + sk_SRP_gN_cache_free(vb->gN_cache); + OPENSSL_free(vb->seed_key); + OPENSSL_free(vb); + return 0; + } + + +SRP_gN_cache *SRP_gN_new_init(char *ch) + { + char tmp[MAX_LEN]; + int len; + + SRP_gN_cache *newgN = (SRP_gN_cache *)OPENSSL_malloc(sizeof(SRP_gN_cache)); + if (newgN == NULL) + return NULL; + + if ((newgN->b64_bn = BUF_strdup(ch)) == NULL) + goto err; + + len = t_fromb64(tmp,ch); + if ((newgN->bn = BN_bin2bn(tmp,len,NULL))) + return newgN; + + OPENSSL_free(newgN->b64_bn); +err: + OPENSSL_free(newgN); + return NULL; + } + + +void SRP_gN_free(SRP_gN_cache *gN_cache) + { + if (gN_cache == NULL) + return; + OPENSSL_free(gN_cache->b64_bn); + BN_free(gN_cache->bn); + OPENSSL_free(gN_cache); + } + +SRP_gN *SRP_get_gN_by_id(char *id, STACK_OF(SRP_gN) *gN_tab) + { + int i; + + SRP_gN *gN; + if (gN_tab != NULL) + for(i = 0; i < sk_SRP_gN_num(gN_tab); i++) + { + gN = sk_SRP_gN_value(gN_tab, i); + if (gN && (id == NULL || strcmp(gN->id,id)==0)) + return gN; + } + + return SRP_get_default_gN(id); + } + +BIGNUM *SRP_gN_place_bn(STACK_OF(SRP_gN_cache) *gN_cache, char *ch) + { + int i; + if (gN_cache == NULL) + return NULL; + + /* search if we have already one... */ + for(i = 0; i < sk_SRP_gN_cache_num(gN_cache); i++) + { + SRP_gN_cache *cache = sk_SRP_gN_cache_value(gN_cache, i); + if (strcmp(cache->b64_bn,ch)==0) + return cache->bn; + } + { /* it is the first time that we find it */ + SRP_gN_cache *newgN = SRP_gN_new_init(ch); + if (newgN) + { + if (sk_SRP_gN_cache_insert(gN_cache,newgN,0)>0) + return newgN->bn; + SRP_gN_free(newgN); + } + } + return NULL; + } + +/* this function parses verifier file. Format is: + * string(index):base64(N):base64(g):0 + * string(username):base64(v):base64(salt):int(index) + */ + + +int SRP_VBASE_init(SRP_VBASE *vb, char * verifier_file) + { + int error_code ; + STACK_OF(SRP_gN) *SRP_gN_tab = sk_SRP_gN_new_null(); + char * last_index = NULL; + int i; + char ** pp; + + SRP_gN *gN = NULL; + SRP_user_pwd *user_pwd = NULL ; + + TXT_DB *tmpdb = NULL; + BIO *in = BIO_new(BIO_s_file()); + + error_code = SRP_ERR_OPEN_FILE; + + if (in == NULL || BIO_read_filename(in,verifier_file) <= 0) + goto err; + + error_code = SRP_ERR_VBASE_INCOMPLETE_FILE; + + if ((tmpdb =TXT_DB_read(in,DB_NUMBER)) == NULL) + goto err; + + error_code = SRP_ERR_MEMORY; + + + if (vb->seed_key) + { + last_index = SRP_get_default_gN(NULL)->id; + } + for (i=0; idata); i++) + { + pp=(char **)sk_value(tmpdb->data,i); + if (pp[DB_srptype][0] == DB_SRP_INDEX) + { + /*we add this couple in the internal Stack */ + + if ((gN = (SRP_gN *)OPENSSL_malloc(sizeof(SRP_gN))) == NULL) + goto err; + + if (!(gN->id = BUF_strdup(pp[DB_srpid])) + || !(gN->N = SRP_gN_place_bn(vb->gN_cache,pp[DB_srpverifier])) + || !(gN->g = SRP_gN_place_bn(vb->gN_cache,pp[DB_srpsalt])) + || sk_SRP_gN_insert(SRP_gN_tab,gN,0) == 0) + goto err; + + gN = NULL; + + if (vb->seed_key != NULL) + { + last_index = pp[DB_srpid]; + } + } + else if (pp[DB_srptype][0] == DB_SRP_VALID) + { + /* it is a user .... */ + SRP_gN *gN; + if ((gN = SRP_get_gN_by_id(pp[DB_srpgN],SRP_gN_tab))!=NULL) + { + error_code = SRP_ERR_MEMORY; + if ((user_pwd = SRP_user_pwd_new()) == NULL) + goto err; + + SRP_user_pwd_set_gN(user_pwd,gN->g,gN->N); + if (!SRP_user_pwd_set_ids(user_pwd,pp[DB_srpid],pp[DB_srpinfo])) + goto err; + + error_code = SRP_ERR_VBASE_BN_LIB; + if (!SRP_user_pwd_set_sv(user_pwd,pp[DB_srpsalt],pp[DB_srpverifier])) + goto err; + + if (sk_SRP_user_pwd_insert(vb->users_pwd,user_pwd,0) == 0) + goto err; + user_pwd = NULL; /* abandon responsability */ + } + } + } + + if (last_index != NULL) + { + /* this means that we want to simulate a default user */ + + if (((gN = SRP_get_gN_by_id(last_index,SRP_gN_tab))==NULL)) + { + error_code = SRP_ERR_VBASE_BN_LIB; + goto err; + } + vb->default_g = gN->g ; + vb->default_N = gN->N ; + gN = NULL ; + } + error_code = SRP_NO_ERROR; + + err: + /* there may be still some leaks to fix, if this fails, the application terminates most likely */ + + if (gN != NULL) + { + OPENSSL_free(gN->id); + OPENSSL_free(gN); + } + + SRP_user_pwd_free(user_pwd); + + if (tmpdb) TXT_DB_free(tmpdb); + if (in) BIO_free_all(in); + + sk_SRP_gN_free(SRP_gN_tab); + + return error_code; + + } + + +SRP_user_pwd *SRP_VBASE_get_by_user(SRP_VBASE *vb, char *username) + { + int i; + SRP_user_pwd *user; + unsigned char digv[SHA_DIGEST_LENGTH]; + unsigned char digs[SHA_DIGEST_LENGTH]; + EVP_MD_CTX ctxt; + + if (vb == NULL) + return NULL; + for(i = 0; i < sk_SRP_user_pwd_num(vb->users_pwd); i++) + { + user = sk_SRP_user_pwd_value(vb->users_pwd, i); + if (strcmp(user->id,username)==0) + return user; + } + if ((vb->seed_key == NULL) || + (vb->default_g == NULL) || + (vb->default_N == NULL)) + return NULL; + +/* if the user is unknown we set parameters as well if we have a seed_key */ + + if ((user = SRP_user_pwd_new()) == NULL) + return NULL; + + SRP_user_pwd_set_gN(user,vb->default_g,vb->default_N); + + if (!SRP_user_pwd_set_ids(user,username,NULL)) + goto err; + + RAND_pseudo_bytes(digv, SHA_DIGEST_LENGTH); + EVP_MD_CTX_init(&ctxt); + EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL); + EVP_DigestUpdate(&ctxt, vb->seed_key, strlen(vb->seed_key)); + EVP_DigestUpdate(&ctxt, username, strlen(username)); + EVP_DigestFinal_ex(&ctxt, digs, NULL); + EVP_MD_CTX_cleanup(&ctxt); + if (SRP_user_pwd_set_sv_BN(user, BN_bin2bn(digs,SHA_DIGEST_LENGTH,NULL), BN_bin2bn(digv,SHA_DIGEST_LENGTH, NULL))) + return user; + +err: SRP_user_pwd_free(user); + return NULL; + } + + +/* + create a verifier (*salt,*verifier,g and N are in base64) +*/ +char * SRP_create_verifier(const char *user, const char *pass, char **salt, char **verifier, char *N, char *g) + { + int len; + char * result=NULL; + char *vf; + BIGNUM *N_bn = NULL, *g_bn = NULL, *s = NULL, *v = NULL; + char tmp[MAX_LEN]; + char tmp2[MAX_LEN]; + char * defgNid = NULL; + + if ((user == NULL)|| + (pass == NULL)|| + (salt == NULL)|| + (verifier == NULL)) + goto err; + + if (N) + { + if (!(len = t_fromb64(tmp,N))) goto err; + N_bn = BN_bin2bn(tmp,len,NULL); + if (!(len = t_fromb64(tmp,g))) goto err; + g_bn = BN_bin2bn(tmp,len,NULL); + defgNid = "*"; + } + else + { + SRP_gN * gN = SRP_get_gN_by_id(g, NULL) ; + if (gN == NULL) + goto err; + N_bn = gN->N; + g_bn = gN->g; + defgNid = gN->id; + } + + if (*salt == NULL) + { + RAND_pseudo_bytes(tmp2, SRP_RANDOM_SALT_LEN); + + s = BN_bin2bn(tmp2,SRP_RANDOM_SALT_LEN,NULL); + } + else + { + if (!(len = t_fromb64(tmp2,*salt))) + goto err; + s = BN_bin2bn(tmp2,len,NULL); + } + + + if(!SRP_create_verifier_BN(user, pass, &s, &v, N_bn, g_bn)) goto err; + + BN_bn2bin(v,tmp); + if (((vf = OPENSSL_malloc(BN_num_bytes(v)*2)) == NULL)) + goto err; + t_tob64(vf,tmp,BN_num_bytes(v)); + + *verifier = vf; + if (*salt == NULL) + { + if ((*salt = (char *)OPENSSL_malloc(SRP_RANDOM_SALT_LEN*2)) == NULL) + { + OPENSSL_free(vf); + goto err; + } + t_tob64(*salt,tmp2,SRP_RANDOM_SALT_LEN); + } + + result=defgNid; + +err: + if(N) + { + BN_free(N_bn); + BN_free(g_bn); + } + return result; + } + +/* + create a verifier (*salt,*verifier,g and N are BIGNUMs) +*/ +int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt, BIGNUM **verifier, BIGNUM *N, BIGNUM *g) + { + int result=0; + BIGNUM *x = NULL; + BN_CTX *bn_ctx = BN_CTX_new(); + char tmp2[MAX_LEN]; + + if ((user == NULL)|| + (pass == NULL)|| + (salt == NULL)|| + (verifier == NULL)|| + (N == NULL)|| + (g == NULL)|| + (bn_ctx == NULL)) + goto err; + + srp_bn_print(N); + srp_bn_print(g); + + if (*salt == NULL) + { + RAND_pseudo_bytes(tmp2, SRP_RANDOM_SALT_LEN); + + *salt = BN_bin2bn(tmp2,SRP_RANDOM_SALT_LEN,NULL); + } + + x = SRP_Calc_x(*salt,user,pass); + + *verifier = BN_new(); + if(*verifier == NULL) goto err; + + if (!BN_mod_exp(*verifier,g,x,N,bn_ctx)) + { + BN_clear_free(*verifier); + goto err; + } + + srp_bn_print(*verifier); + + result=1; + +err: + + BN_clear_free(x); + BN_CTX_free(bn_ctx); + return result; + } + + + +#endif diff -ruN openssl-1.0.0d-orig/crypto/srp/srptest.c openssl-1.0.0d-srp/crypto/srp/srptest.c --- openssl-1.0.0d-orig/crypto/srp/srptest.c 1969-12-31 16:00:00.000000000 -0800 +++ openssl-1.0.0d-srp/crypto/srp/srptest.c 2011-03-14 17:11:18.000000000 -0700 @@ -0,0 +1,161 @@ +#include +#ifdef OPENSSL_NO_SRP + +#include + +int main(int argc, char *argv[]) + { + printf("No SRP support\n"); + return(0); + } + +#else + +#include +#include +#include + +static void showbn(const char *name, const BIGNUM *bn) + { + fputs(name, stdout); + fputs(" = ", stdout); + BN_print_fp(stdout, bn); + putc('\n', stdout); + } + +#define RANDOM_SIZE 32 /* use 256 bits on each side */ + +static int run_srp(const char *username, const char *client_pass, const char *server_pass) + { + int ret=-1; + BIGNUM *s = NULL; + BIGNUM *v = NULL; + BIGNUM *a = NULL; + BIGNUM *b = NULL; + BIGNUM *u = NULL; + BIGNUM *x = NULL; + BIGNUM *Apub = NULL; + BIGNUM *Bpub = NULL; + BIGNUM *Kclient = NULL; + BIGNUM *Kserver = NULL; + unsigned char rand_tmp[RANDOM_SIZE]; + SRP_gN *GN = SRP_get_default_gN("1024"); // use builtin 1024-bit params + + if(GN == NULL) + { + fprintf(stderr, "Failed to get SRP parameters\n"); + return -1; + } + /* Set up server's password entry */ + if(!SRP_create_verifier_BN(username, server_pass, &s, &v, GN->N, GN->g)) + { + fprintf(stderr, "Failed to create SRP verifier\n"); + return -1; + } + + showbn("N", GN->N); + showbn("g", GN->g); + showbn("Salt", s); + showbn("Verifier", v); + + /* Server random */ + RAND_pseudo_bytes(rand_tmp, sizeof(rand_tmp)); + b = BN_bin2bn(rand_tmp, sizeof(rand_tmp), NULL); + /* TODO - check b != 0 */ + showbn("b", b); + + /* Server's first message */ + Bpub = SRP_Calc_B(b, GN->N, GN->g, v); + showbn("B", Bpub); + + if(!SRP_Verify_B_mod_N(Bpub, GN->N)) + { + fprintf(stderr, "Invalid B\n"); + return -1; + } + + /* Client random */ + RAND_pseudo_bytes(rand_tmp, sizeof(rand_tmp)); + a = BN_bin2bn(rand_tmp, sizeof(rand_tmp), NULL); + /* TODO - check a != 0 */ + showbn("a", a); + + /* Client's response */ + Apub = SRP_Calc_A(a, GN->N, GN->g); + showbn("A", Apub); + + if(!SRP_Verify_A_mod_N(Apub, GN->N)) + { + fprintf(stderr, "Invalid A\n"); + return -1; + } + + /* Both sides calculate u */ + u = SRP_Calc_u(Apub, Bpub, GN->N); + + /* Client's key */ + x = SRP_Calc_x(s, username, client_pass); + Kclient = SRP_Calc_client_key(GN->N, Bpub, GN->g, x, a, u); + showbn("Client's key", Kclient); + + /* Server's key */ + Kserver = SRP_Calc_server_key(Apub, v, u, b, GN->N); + showbn("Server's key", Kserver); + + if(BN_cmp(Kclient, Kserver) == 0) + { + ret = 0; + } + else + { + fprintf(stderr, "Keys mismatch\n"); + ret = 1; + } + + BN_clear_free(Kclient); + BN_clear_free(Kserver); + BN_clear_free(x); + BN_free(u); + BN_free(Apub); + BN_clear_free(a); + BN_free(Bpub); + BN_clear_free(b); + BN_free(s); + BN_clear_free(v); + + return ret; + } + +int main(int argc, char **argv) + { + BIO *bio_err; + bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); + + CRYPTO_malloc_debug_init(); + CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL); + CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); + + ERR_load_crypto_strings(); + + /* "Negative" test, expect a mismatch */ + if(run_srp("alice", "password1", "password2") == 0) + { + fprintf(stderr, "Mismatched SRP run failed\n"); + return 1; + } + + /* "Positive" test, should pass */ + if(run_srp("alice", "password", "password") != 0) + { + fprintf(stderr, "Plain SRP run failed\n"); + return 1; + } + + CRYPTO_cleanup_all_ex_data(); + ERR_remove_thread_state(NULL); + ERR_free_strings(); + CRYPTO_mem_leaks(bio_err); + + return 0; + } +#endif diff -ruN openssl-1.0.0d-orig/crypto/stack/safestack.h openssl-1.0.0d-srp/crypto/stack/safestack.h --- openssl-1.0.0d-orig/crypto/stack/safestack.h 2011-02-03 04:04:39.000000000 -0800 +++ openssl-1.0.0d-srp/crypto/stack/safestack.h 2011-03-14 17:11:18.000000000 -0700 @@ -1459,6 +1459,66 @@ #define sk_POLICY_MAPPING_sort(st) SKM_sk_sort(POLICY_MAPPING, (st)) #define sk_POLICY_MAPPING_is_sorted(st) SKM_sk_is_sorted(POLICY_MAPPING, (st)) +#define sk_SRP_gN_new(st) SKM_sk_new(SRP_gN, (st)) +#define sk_SRP_gN_new_null() SKM_sk_new_null(SRP_gN) +#define sk_SRP_gN_free(st) SKM_sk_free(SRP_gN, (st)) +#define sk_SRP_gN_num(st) SKM_sk_num(SRP_gN, (st)) +#define sk_SRP_gN_value(st, i) SKM_sk_value(SRP_gN, (st), (i)) +#define sk_SRP_gN_set(st, i, val) SKM_sk_set(SRP_gN, (st), (i), (val)) +#define sk_SRP_gN_zero(st) SKM_sk_zero(SRP_gN, (st)) +#define sk_SRP_gN_push(st, val) SKM_sk_push(SRP_gN, (st), (val)) +#define sk_SRP_gN_unshift(st, val) SKM_sk_unshift(SRP_gN, (st), (val)) +#define sk_SRP_gN_find(st, val) SKM_sk_find(SRP_gN, (st), (val)) +#define sk_SRP_gN_delete(st, i) SKM_sk_delete(SRP_gN, (st), (i)) +#define sk_SRP_gN_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRP_gN, (st), (ptr)) +#define sk_SRP_gN_insert(st, val, i) SKM_sk_insert(SRP_gN, (st), (val), (i)) +#define sk_SRP_gN_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRP_gN, (st), (cmp)) +#define sk_SRP_gN_dup(st) SKM_sk_dup(SRP_gN, st) +#define sk_SRP_gN_pop_free(st, free_func) SKM_sk_pop_free(SRP_gN, (st), (free_func)) +#define sk_SRP_gN_shift(st) SKM_sk_shift(SRP_gN, (st)) +#define sk_SRP_gN_pop(st) SKM_sk_pop(SRP_gN, (st)) +#define sk_SRP_gN_sort(st) SKM_sk_sort(SRP_gN, (st)) + +#define sk_SRP_gN_cache_new(st) SKM_sk_new(SRP_gN_cache, (st)) +#define sk_SRP_gN_cache_new_null() SKM_sk_new_null(SRP_gN_cache) +#define sk_SRP_gN_cache_free(st) SKM_sk_free(SRP_gN_cache, (st)) +#define sk_SRP_gN_cache_num(st) SKM_sk_num(SRP_gN_cache, (st)) +#define sk_SRP_gN_cache_value(st, i) SKM_sk_value(SRP_gN_cache, (st), (i)) +#define sk_SRP_gN_cache_set(st, i, val) SKM_sk_set(SRP_gN_cache, (st), (i), (val)) +#define sk_SRP_gN_cache_zero(st) SKM_sk_zero(SRP_gN_cache, (st)) +#define sk_SRP_gN_cache_push(st, val) SKM_sk_push(SRP_gN_cache, (st), (val)) +#define sk_SRP_gN_cache_unshift(st, val) SKM_sk_unshift(SRP_gN_cache, (st), (val)) +#define sk_SRP_gN_cache_find(st, val) SKM_sk_find(SRP_gN_cache, (st), (val)) +#define sk_SRP_gN_cache_delete(st, i) SKM_sk_delete(SRP_gN_cache, (st), (i)) +#define sk_SRP_gN_cache_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRP_gN_cache, (st), (ptr)) +#define sk_SRP_gN_cache_insert(st, val, i) SKM_sk_insert(SRP_gN_cache, (st), (val), (i)) +#define sk_SRP_gN_cache_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRP_gN_cache, (st), (cmp)) +#define sk_SRP_gN_cache_dup(st) SKM_sk_dup(SRP_gN_cache, st) +#define sk_SRP_gN_cache_pop_free(st, free_func) SKM_sk_pop_free(SRP_gN_cache, (st), (free_func)) +#define sk_SRP_gN_cache_shift(st) SKM_sk_shift(SRP_gN_cache, (st)) +#define sk_SRP_gN_cache_pop(st) SKM_sk_pop(SRP_gN_cache, (st)) +#define sk_SRP_gN_cache_sort(st) SKM_sk_sort(SRP_gN_cache, (st)) + +#define sk_SRP_user_pwd_new(st) SKM_sk_new(SRP_user_pwd, (st)) +#define sk_SRP_user_pwd_new_null() SKM_sk_new_null(SRP_user_pwd) +#define sk_SRP_user_pwd_free(st) SKM_sk_free(SRP_user_pwd, (st)) +#define sk_SRP_user_pwd_num(st) SKM_sk_num(SRP_user_pwd, (st)) +#define sk_SRP_user_pwd_value(st, i) SKM_sk_value(SRP_user_pwd, (st), (i)) +#define sk_SRP_user_pwd_set(st, i, val) SKM_sk_set(SRP_user_pwd, (st), (i), (val)) +#define sk_SRP_user_pwd_zero(st) SKM_sk_zero(SRP_user_pwd, (st)) +#define sk_SRP_user_pwd_push(st, val) SKM_sk_push(SRP_user_pwd, (st), (val)) +#define sk_SRP_user_pwd_unshift(st, val) SKM_sk_unshift(SRP_user_pwd, (st), (val)) +#define sk_SRP_user_pwd_find(st, val) SKM_sk_find(SRP_user_pwd, (st), (val)) +#define sk_SRP_user_pwd_delete(st, i) SKM_sk_delete(SRP_user_pwd, (st), (i)) +#define sk_SRP_user_pwd_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRP_user_pwd, (st), (ptr)) +#define sk_SRP_user_pwd_insert(st, val, i) SKM_sk_insert(SRP_user_pwd, (st), (val), (i)) +#define sk_SRP_user_pwd_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRP_user_pwd, (st), (cmp)) +#define sk_SRP_user_pwd_dup(st) SKM_sk_dup(SRP_user_pwd, st) +#define sk_SRP_user_pwd_pop_free(st, free_func) SKM_sk_pop_free(SRP_user_pwd, (st), (free_func)) +#define sk_SRP_user_pwd_shift(st) SKM_sk_shift(SRP_user_pwd, (st)) +#define sk_SRP_user_pwd_pop(st) SKM_sk_pop(SRP_user_pwd, (st)) +#define sk_SRP_user_pwd_sort(st) SKM_sk_sort(SRP_user_pwd, (st)) + #define sk_SSL_CIPHER_new(cmp) SKM_sk_new(SSL_CIPHER, (cmp)) #define sk_SSL_CIPHER_new_null() SKM_sk_new_null(SSL_CIPHER) #define sk_SSL_CIPHER_free(st) SKM_sk_free(SSL_CIPHER, (st)) diff -ruN openssl-1.0.0d-orig/ssl/Makefile openssl-1.0.0d-srp/ssl/Makefile --- openssl-1.0.0d-orig/ssl/Makefile 2010-12-02 10:26:12.000000000 -0800 +++ openssl-1.0.0d-srp/ssl/Makefile 2011-03-14 17:11:18.000000000 -0700 @@ -30,7 +30,7 @@ ssl_lib.c ssl_err2.c ssl_cert.c ssl_sess.c \ ssl_ciph.c ssl_stat.c ssl_rsa.c \ ssl_asn1.c ssl_txt.c ssl_algs.c \ - bio_ssl.c ssl_err.c kssl.c t1_reneg.c + bio_ssl.c ssl_err.c kssl.c tls_srp.c t1_reneg.c LIBOBJ= \ s2_meth.o s2_srvr.o s2_clnt.o s2_lib.o s2_enc.o s2_pkt.o \ s3_meth.o s3_srvr.o s3_clnt.o s3_lib.o s3_enc.o s3_pkt.o s3_both.o \ @@ -41,7 +41,7 @@ ssl_lib.o ssl_err2.o ssl_cert.o ssl_sess.o \ ssl_ciph.o ssl_stat.o ssl_rsa.o \ ssl_asn1.o ssl_txt.o ssl_algs.o \ - bio_ssl.o ssl_err.o kssl.o t1_reneg.o + bio_ssl.o ssl_err.o kssl.o tls_srp.o t1_reneg.o SRC= $(LIBSRC) diff -ruN openssl-1.0.0d-orig/ssl/s3_clnt.c openssl-1.0.0d-srp/ssl/s3_clnt.c --- openssl-1.0.0d-orig/ssl/s3_clnt.c 2010-12-02 10:24:54.000000000 -0800 +++ openssl-1.0.0d-srp/ssl/s3_clnt.c 2011-03-14 17:11:18.000000000 -0700 @@ -277,6 +277,20 @@ case SSL3_ST_CR_SRVR_HELLO_A: case SSL3_ST_CR_SRVR_HELLO_B: ret=ssl3_get_server_hello(s); +#ifndef OPENSSL_NO_SRP + if ((ret == 0) && (s->s3->warn_alert == SSL_AD_MISSING_SRP_USERNAME)) + { + if (!SRP_have_to_put_srp_username(s)) + { + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_MISSING_SRP_USERNAME); + ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_USER_CANCELLED); + goto end; + } + s->state=SSL3_ST_CW_CLNT_HELLO_A; + if (!ssl_init_wbio_buffer(s,0)) { ret= -1; goto end; } + break; + } +#endif if (ret <= 0) goto end; if (s->hit) @@ -358,6 +372,17 @@ case SSL3_ST_CR_SRVR_DONE_B: ret=ssl3_get_server_done(s); if (ret <= 0) goto end; +#ifndef OPENSSL_NO_SRP + if (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kSRP) + { + if ((ret = SRP_Calc_A_param(s))<=0) + { + SSLerr(SSL_F_SSL3_GET_SERVER_DONE,SSL_R_SRP_A_CALC); + ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_INTERNAL_ERROR); + goto end; + } + } +#endif if (s->s3->tmp.cert_req) s->state=SSL3_ST_CW_CERT_A; else @@ -1282,6 +1307,86 @@ } else #endif /* !OPENSSL_NO_PSK */ +#ifndef OPENSSL_NO_SRP + if (alg_k & SSL_kSRP) + { + n2s(p,i); + param_len=i+2; + if (param_len > n) + { + al=SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SRP_N_LENGTH); + goto f_err; + } + if (!(s->srp_ctx.N=BN_bin2bn(p,i,NULL))) + { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB); + goto err; + } + p+=i; + + n2s(p,i); + param_len+=i+2; + if (param_len > n) + { + al=SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SRP_G_LENGTH); + goto f_err; + } + if (!(s->srp_ctx.g=BN_bin2bn(p,i,NULL))) + { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB); + goto err; + } + p+=i; + + i = (unsigned int)(p[0]); + p++; + param_len+=i+1; + if (param_len > n) + { + al=SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SRP_S_LENGTH); + goto f_err; + } + if (!(s->srp_ctx.s=BN_bin2bn(p,i,NULL))) + { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB); + goto err; + } + p+=i; + + n2s(p,i); + param_len+=i+2; + if (param_len > n) + { + al=SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SRP_B_LENGTH); + goto f_err; + } + if (!(s->srp_ctx.B=BN_bin2bn(p,i,NULL))) + { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB); + goto err; + } + p+=i; + n-=param_len; + +/* We must check if there is a certificate */ +#ifndef OPENSSL_NO_RSA + if (alg_a & SSL_aRSA) + pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509); +#else + if (0) + ; +#endif +#ifndef OPENSSL_NO_DSA + else if (alg_a & SSL_aDSS) + pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_DSA_SIGN].x509); +#endif + } + else +#endif /* !OPENSSL_NO_SRP */ #ifndef OPENSSL_NO_RSA if (alg_k & SSL_kRSA) { @@ -2551,6 +2656,39 @@ EVP_PKEY_free(pub_key); } +#ifndef OPENSSL_NO_SRP + else if (alg_k & SSL_kSRP) + { + if (s->srp_ctx.A != NULL) + { + /* send off the data */ + n=BN_num_bytes(s->srp_ctx.A); + s2n(n,p); + BN_bn2bin(s->srp_ctx.A,p); + n+=2; + } + else + { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR); + goto err; + } + if (s->session->srp_username != NULL) + OPENSSL_free(s->session->srp_username); + s->session->srp_username = BUF_strdup(s->srp_ctx.login); + if (s->session->srp_username == NULL) + { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto err; + } + + if ((s->session->master_key_length = SRP_generate_client_master_secret(s,s->session->master_key))<0) + { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR); + goto err; + } + } +#endif #ifndef OPENSSL_NO_PSK else if (alg_k & SSL_kPSK) { diff -ruN openssl-1.0.0d-orig/ssl/s3_lib.c openssl-1.0.0d-srp/ssl/s3_lib.c --- openssl-1.0.0d-orig/ssl/s3_lib.c 2009-10-16 08:24:19.000000000 -0700 +++ openssl-1.0.0d-srp/ssl/s3_lib.c 2011-03-14 17:11:18.000000000 -0700 @@ -2012,6 +2012,152 @@ }, #endif /* OPENSSL_NO_ECDH */ +#ifndef OPENSSL_NO_SRP + /* Cipher C01A */ + { + 1, + TLS1_TXT_SRP_SHA_WITH_3DES_EDE_CBC_SHA, + TLS1_CK_SRP_SHA_WITH_3DES_EDE_CBC_SHA, + SSL_kSRP, + SSL_aNULL, + SSL_3DES, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 168, + 168, + }, + + /* Cipher C01B */ + { + 1, + TLS1_TXT_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA, + TLS1_CK_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA, + SSL_kSRP, + SSL_aRSA, + SSL_3DES, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 168, + 168, + }, + + /* Cipher C01C */ + { + 1, + TLS1_TXT_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA, + TLS1_CK_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA, + SSL_kSRP, + SSL_aDSS, + SSL_3DES, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 168, + 168, + }, + + /* Cipher C01D */ + { + 1, + TLS1_TXT_SRP_SHA_WITH_AES_128_CBC_SHA, + TLS1_CK_SRP_SHA_WITH_AES_128_CBC_SHA, + SSL_kSRP, + SSL_aNULL, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 128, + 128, + }, + + /* Cipher C01E */ + { + 1, + TLS1_TXT_SRP_SHA_RSA_WITH_AES_128_CBC_SHA, + TLS1_CK_SRP_SHA_RSA_WITH_AES_128_CBC_SHA, + SSL_kSRP, + SSL_aRSA, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 128, + 128, + }, + + /* Cipher C01F */ + { + 1, + TLS1_TXT_SRP_SHA_DSS_WITH_AES_128_CBC_SHA, + TLS1_CK_SRP_SHA_DSS_WITH_AES_128_CBC_SHA, + SSL_kSRP, + SSL_aDSS, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 128, + 128, + }, + + /* Cipher C020 */ + { + 1, + TLS1_TXT_SRP_SHA_WITH_AES_256_CBC_SHA, + TLS1_CK_SRP_SHA_WITH_AES_256_CBC_SHA, + SSL_kSRP, + SSL_aNULL, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 256, + 256, + }, + + /* Cipher C021 */ + { + 1, + TLS1_TXT_SRP_SHA_RSA_WITH_AES_256_CBC_SHA, + TLS1_CK_SRP_SHA_RSA_WITH_AES_256_CBC_SHA, + SSL_kSRP, + SSL_aRSA, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 256, + 256, + }, + + /* Cipher C022 */ + { + 1, + TLS1_TXT_SRP_SHA_DSS_WITH_AES_256_CBC_SHA, + TLS1_CK_SRP_SHA_DSS_WITH_AES_256_CBC_SHA, + SSL_kSRP, + SSL_aDSS, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 256, + 256, + }, +#endif /* OPENSSL_NO_SRP */ + #ifdef TEMP_GOST_TLS /* Cipher FF00 */ { @@ -2128,6 +2274,9 @@ s->s3=s3; +#ifndef OPENSSL_NO_SRP + SSL_SRP_CTX_init(s); +#endif s->method->ssl_clear(s); return(1); err: @@ -2168,6 +2317,9 @@ BIO_free(s->s3->handshake_buffer); } if (s->s3->handshake_dgst) ssl3_free_digest_list(s); +#ifndef OPENSSL_NO_SRP + SSL_SRP_CTX_free(s); +#endif OPENSSL_cleanse(s->s3,sizeof *s->s3); OPENSSL_free(s->s3); s->s3=NULL; @@ -2232,6 +2384,13 @@ s->version=SSL3_VERSION; } +#ifndef OPENSSL_NO_SRP +static char * MS_CALLBACK srp_password_from_info_cb(SSL *s, void *arg) + { + return BUF_strdup(s->srp_ctx.info) ; + } +#endif + long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) { int ret=0; @@ -2709,6 +2868,38 @@ return 1; break; +#ifndef OPENSSL_NO_SRP + case SSL_CTRL_SET_TLS_EXT_SRP_USERNAME: + ctx->srp_ctx.srp_Mask|=SSL_kSRP; + if (ctx->srp_ctx.login != NULL) + OPENSSL_free(ctx->srp_ctx.login); + ctx->srp_ctx.login = NULL; + if (parg == NULL) + break; + if (strlen((char *)parg) > 254) + { + SSLerr(SSL_F_SSL3_CTX_CTRL, SSL_R_INVALID_SRP_USERNAME); + return 0; + } + if ((ctx->srp_ctx.login = BUF_strdup((char *)parg)) == NULL) + { + SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_INTERNAL_ERROR); + return 0; + } + break; + case SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD: + ctx->srp_ctx.SRP_give_srp_client_pwd_callback=srp_password_from_info_cb; + ctx->srp_ctx.info=parg; + break; + case SSL_CTRL_SET_SRP_ARG: + ctx->srp_ctx.srp_Mask|=SSL_kSRP; + ctx->srp_ctx.SRP_cb_arg=parg; + break; + + case SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH: + ctx->srp_ctx.strength=larg; + break; +#endif #endif /* !OPENSSL_NO_TLSEXT */ /* A Thawte special :-) */ @@ -2778,6 +2969,24 @@ HMAC_CTX *, int))fp; break; +#ifndef OPENSSL_NO_SRP + case SSL_CTRL_SET_SRP_VERIFY_PARAM_CB: + ctx->srp_ctx.srp_Mask|=SSL_kSRP; + ctx->srp_ctx.SRP_verify_param_callback=(int (*)(SSL *,void *))fp; + break; + case SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB: + ctx->srp_ctx.srp_Mask|=SSL_kSRP; + ctx->srp_ctx.TLS_ext_srp_username_callback=(int (*)(SSL *,int *,void *))fp; + break; + case SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB: + ctx->srp_ctx.srp_Mask|=SSL_kSRP; + ctx->srp_ctx.SRP_give_srp_client_pwd_callback=(char *(*)(SSL *,void *))fp; + break; + case SSL_CTRL_SET_TLS_EXT_SRP_MISSING_CLIENT_USERNAME_CB: + ctx->srp_ctx.srp_Mask|=SSL_kSRP; + ctx->srp_ctx.SRP_TLS_ext_missing_srp_client_username_callback=(char *(*)(SSL *,void *))fp; + break; +#endif #endif default: return(0); @@ -2878,6 +3087,10 @@ mask_a = cert->mask_a; emask_k = cert->export_mask_k; emask_a = cert->export_mask_a; +#ifndef OPENSSL_NO_SRP + mask_k=cert->mask_k | s->srp_ctx.srp_Mask; + emask_k=cert->export_mask_k | s->srp_ctx.srp_Mask; +#endif #ifdef KSSL_DEBUG /* printf("ssl3_choose_cipher %d alg= %lx\n", i,c->algorithms);*/ diff -ruN openssl-1.0.0d-orig/ssl/s3_pkt.c openssl-1.0.0d-srp/ssl/s3_pkt.c --- openssl-1.0.0d-orig/ssl/s3_pkt.c 2010-03-25 04:22:42.000000000 -0700 +++ openssl-1.0.0d-srp/ssl/s3_pkt.c 2011-03-14 17:11:18.000000000 -0700 @@ -1183,6 +1183,10 @@ SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_NO_RENEGOTIATION); goto f_err; } +#ifdef SSL_AD_MISSING_SRP_USERNAME + if (alert_descr == SSL_AD_MISSING_SRP_USERNAME) + return(0); +#endif } else if (alert_level == 2) /* fatal */ { diff -ruN openssl-1.0.0d-orig/ssl/s3_srvr.c openssl-1.0.0d-srp/ssl/s3_srvr.c --- openssl-1.0.0d-orig/ssl/s3_srvr.c 2010-12-02 10:24:55.000000000 -0800 +++ openssl-1.0.0d-srp/ssl/s3_srvr.c 2011-03-14 17:11:18.000000000 -0700 @@ -179,6 +179,31 @@ return(NULL); } +#ifndef OPENSSL_NO_SRP +int SSL_check_srp_ext_ClientHello(SSL *s,int *ad) + { + int ret = SSL_ERROR_NONE; + + *ad = SSL_AD_UNRECOGNIZED_NAME; + + if ((s->s3->tmp.new_cipher->algorithm_mkey & SSL_kSRP) && + (s->srp_ctx.TLS_ext_srp_username_callback != NULL)) + { + if(s->srp_ctx.login == NULL) + { + /* There isn't any srp login extension !!! */ + ret = SSL3_AL_WARNING; + *ad = SSL_AD_MISSING_SRP_USERNAME; + } + else + { + ret = SSL_srp_server_param_with_username(s,ad); + } + } + return ret; + } +#endif + IMPLEMENT_ssl3_meth_func(SSLv3_server_method, ssl3_accept, ssl_undefined_function, @@ -191,6 +216,10 @@ void (*cb)(const SSL *ssl,int type,int val)=NULL; int ret= -1; int new_state,state,skip=0; +#ifndef OPENSSL_NO_SRP + int srp_no_username =0; + int extension_error,al; +#endif RAND_add(&Time,sizeof(Time),0); ERR_clear_error(); @@ -311,10 +340,34 @@ case SSL3_ST_SR_CLNT_HELLO_A: case SSL3_ST_SR_CLNT_HELLO_B: case SSL3_ST_SR_CLNT_HELLO_C: +#ifndef OPENSSL_NO_SRP + case SSL3_ST_SR_CLNT_HELLO_SRP_USERNAME: +#endif s->shutdown=0; ret=ssl3_get_client_hello(s); if (ret <= 0) goto end; +#ifndef OPENSSL_NO_SRP + extension_error = 0; + if ((al = SSL_check_srp_ext_ClientHello(s,&extension_error)) != SSL_ERROR_NONE) + { + ssl3_send_alert(s,al,extension_error); + if (extension_error == SSL_AD_MISSING_SRP_USERNAME) + { + if (srp_no_username) goto end; + ERR_clear_error(); + srp_no_username = 1; + s->state=SSL3_ST_SR_CLNT_HELLO_SRP_USERNAME; + if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1); + if ((ret=BIO_flush(s->wbio)) <= 0) goto end; + s->init_num=0; + break; + } + ret = -1; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT); + goto end; + } +#endif s->new_session = 2; s->state=SSL3_ST_SW_SRVR_HELLO_A; @@ -345,7 +398,7 @@ case SSL3_ST_SW_CERT_A: case SSL3_ST_SW_CERT_B: /* Check if it is anon DH or anon ECDH, */ - /* normal PSK or KRB5 */ + /* normal PSK or KRB5 or SRP */ if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK) && !(s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5)) @@ -410,6 +463,10 @@ #ifndef OPENSSL_NO_PSK || ((alg_k & SSL_kPSK) && s->ctx->psk_identity_hint) #endif +#ifndef OPENSSL_NO_SRP + /* SRP: send ServerKeyExchange */ + || (alg_k & SSL_kSRP) +#endif || (alg_k & (SSL_kDHr|SSL_kDHd|SSL_kEDH)) || (alg_k & SSL_kEECDH) || ((alg_k & SSL_kRSA) @@ -802,7 +859,11 @@ * If we are SSLv3, we will respond with SSLv3, even if prompted with * TLSv1. */ - if (s->state == SSL3_ST_SR_CLNT_HELLO_A) + if (s->state == SSL3_ST_SR_CLNT_HELLO_A +#ifndef OPENSSL_NO_SRP + || (s->state == SSL3_ST_SR_CLNT_HELLO_SRP_USERNAME) +#endif + ) { s->state=SSL3_ST_SR_CLNT_HELLO_B; } @@ -1667,14 +1728,37 @@ } else #endif /* !OPENSSL_NO_PSK */ +#ifndef OPENSSL_NO_SRP + if (type & SSL_kSRP) + { + if ((s->srp_ctx.N == NULL) || + (s->srp_ctx.g == NULL) || + (s->srp_ctx.s == NULL) || + (s->srp_ctx.B == NULL)) + { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_SRP_PARAM); + goto err; + } + r[0]=s->srp_ctx.N; + r[1]=s->srp_ctx.g; + r[2]=s->srp_ctx.s; + r[3]=s->srp_ctx.B; + } + else +#endif { al=SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE); goto f_err; } - for (i=0; r[i] != NULL; i++) + for (i=0; r[i] != NULL && i<4; i++) { nr[i]=BN_num_bytes(r[i]); +#ifndef OPENSSL_NO_SRP + if ((i == 2) && (type & SSL_kSRP)) + n+=1+nr[i]; + else +#endif n+=2+nr[i]; } @@ -1703,8 +1787,16 @@ d=(unsigned char *)s->init_buf->data; p= &(d[4]); - for (i=0; r[i] != NULL; i++) + for (i=0; r[i] != NULL && i<4; i++) { +#ifndef OPENSSL_NO_SRP + if ((i == 2) && (type & SSL_kSRP)) + { + *p = nr[i]; + p++; + } + else +#endif s2n(nr[i],p); BN_bn2bin(r[i],p); p+=nr[i]; @@ -2580,6 +2672,44 @@ } else #endif +#ifndef OPENSSL_NO_SRP + if (alg_k & SSL_kSRP) + { + int param_len; + + n2s(p,i); + param_len=i+2; + if (param_len > n) + { + al=SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SRP_A_LENGTH); + goto f_err; + } + if (!(s->srp_ctx.A=BN_bin2bn(p,i,NULL))) + { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB); + goto err; + } + if (s->session->srp_username != NULL) + OPENSSL_free(s->session->srp_username); + s->session->srp_username = BUF_strdup(s->srp_ctx.login); + if (s->session->srp_username == NULL) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto err; + } + + if ((s->session->master_key_length = SRP_generate_server_master_secret(s,s->session->master_key))<0) + { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR); + goto err; + } + + p+=i; + } + else +#endif /* OPENSSL_NO_SRP */ if (alg_k & SSL_kGOST) { int ret = 0; @@ -2663,7 +2793,7 @@ return(1); f_err: ssl3_send_alert(s,SSL3_AL_FATAL,al); -#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_ECDH) +#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_ECDH) || #defined(OPENSSL_NO_SRP) err: #endif #ifndef OPENSSL_NO_ECDH diff -ruN openssl-1.0.0d-orig/ssl/ssl.h openssl-1.0.0d-srp/ssl/ssl.h --- openssl-1.0.0d-orig/ssl/ssl.h 2010-01-06 09:37:38.000000000 -0800 +++ openssl-1.0.0d-srp/ssl/ssl.h 2011-03-14 17:11:18.000000000 -0700 @@ -252,6 +252,7 @@ #define SSL_TXT_kEECDH "kEECDH" #define SSL_TXT_kPSK "kPSK" #define SSL_TXT_kGOST "kGOST" +#define SSL_TXT_kSRP "kSRP" #define SSL_TXT_aRSA "aRSA" #define SSL_TXT_aDSS "aDSS" @@ -275,6 +276,7 @@ #define SSL_TXT_ECDSA "ECDSA" #define SSL_TXT_KRB5 "KRB5" #define SSL_TXT_PSK "PSK" +#define SSL_TXT_SRP "SRP" #define SSL_TXT_DES "DES" #define SSL_TXT_3DES "3DES" @@ -436,6 +438,7 @@ * ECPointFormatList [ 7 ] OCTET STRING, -- optional EC point format list from TLS extension * PSK_identity_hint [ 8 ] EXPLICIT OCTET STRING, -- optional PSK identity hint * PSK_identity [ 9 ] EXPLICIT OCTET STRING -- optional PSK identity + * SRP_username [ 11 ] EXPLICIT OCTET STRING -- optional SRP username * } * Look in ssl/ssl_asn1.c for more details * I'm using EXPLICIT tags so I can read the damn things using asn1parse :-). @@ -467,6 +470,9 @@ char *psk_identity_hint; char *psk_identity; #endif +#ifndef OPENSSL_NO_SRP + char *srp_username; +#endif int not_resumable; /* The cert is the certificate used to establish this connection */ @@ -642,7 +648,42 @@ #define SSL_CTX_set_msg_callback_arg(ctx, arg) SSL_CTX_ctrl((ctx), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg)) #define SSL_set_msg_callback_arg(ssl, arg) SSL_ctrl((ssl), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg)) +#ifndef OPENSSL_NO_SRP + +typedef struct srp_ctx_st + { + /* param for all the callbacks */ + void *SRP_cb_arg; + /* set client Hello login callback */ + int (*TLS_ext_srp_username_callback)(SSL *, int *, void *); + /* set SRP N/g param callback for verification */ + int (*SRP_verify_param_callback)(SSL *, void *); + /* set SRP client passwd callback */ + char *(*SRP_give_srp_client_pwd_callback)(SSL *, void *); + /* set SRP client username callback */ + char *(*SRP_TLS_ext_missing_srp_client_username_callback)(SSL *, void *); + + char *login; + BIGNUM *N,*g,*s,*B,*A; + BIGNUM *a,*b,*v; + char *info; + int strength; + + unsigned long srp_Mask; + } SRP_CTX; + +/* see tls_srp.c */ +int SSL_SRP_CTX_init(SSL *s); +int SSL_CTX_SRP_CTX_init(SSL_CTX *ctx); +int SSL_SRP_CTX_free(SSL *ctx); +int SSL_CTX_SRP_CTX_free(SSL_CTX *ctx); +int SSL_srp_server_param_with_username(SSL *s, int *ad); +int SRP_generate_server_master_secret(SSL *s,unsigned char *master_key); +int SRP_Calc_A_param(SSL *s); +int SRP_generate_client_master_secret(SSL *s,unsigned char *master_key); +int SRP_have_to_put_srp_username(SSL *s); +#endif #if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN32) #define SSL_MAX_CERT_LIST_DEFAULT 1024*30 /* 30k max cert list :-) */ @@ -861,6 +902,10 @@ unsigned char *psk, unsigned int max_psk_len); #endif +#ifndef OPENSSL_NO_SRP + SRP_CTX srp_ctx; /* ctx for SRP authentication */ +#endif + #ifndef OPENSSL_NO_BUF_FREELISTS #define SSL_MAX_BUF_FREELIST_LEN_DEFAULT 32 unsigned int freelist_max_len; @@ -1108,6 +1153,10 @@ unsigned char *psk, unsigned int max_psk_len); #endif +#ifndef OPENSSL_NO_SRP + SRP_CTX srp_ctx; /* ctx for SRP authentication */ +#endif + SSL_CTX *ctx; /* set this flag to 1 and a sleep(1) is put into all SSL_read() * and SSL_write() calls, good for nbio debuging :-) */ @@ -1325,6 +1374,8 @@ #define SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE #define SSL_AD_BAD_CERTIFICATE_HASH_VALUE TLS1_AD_BAD_CERTIFICATE_HASH_VALUE #define SSL_AD_UNKNOWN_PSK_IDENTITY TLS1_AD_UNKNOWN_PSK_IDENTITY /* fatal */ +#define SSL_AD_UNKNOWN_SRP_USERNAME TLS1_AD_UNKNOWN_SRP_USERNAME +#define SSL_AD_MISSING_SRP_USERNAME TLS1_AD_MISSING_SRP_USERNAME #define SSL_ERROR_NONE 0 #define SSL_ERROR_SSL 1 @@ -1408,6 +1459,15 @@ #define SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP 71 #define SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB 72 + +#define SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB 75 +#define SSL_CTRL_SET_SRP_VERIFY_PARAM_CB 76 +#define SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB 77 +#define SSL_CTRL_SET_TLS_EXT_SRP_MISSING_CLIENT_USERNAME_CB 78 +#define SSL_CTRL_SET_SRP_ARG 79 +#define SSL_CTRL_SET_TLS_EXT_SRP_USERNAME 80 +#define SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH 81 +#define SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD 82 #endif #define DTLS_CTRL_GET_TIMEOUT 73 @@ -1612,6 +1672,26 @@ int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm); int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm); +#ifndef OPENSSL_NO_SRP +int SSL_CTX_set_srp_username(SSL_CTX *ctx,char *name); +int SSL_CTX_set_srp_password(SSL_CTX *ctx,char *password); +int SSL_CTX_set_srp_strength(SSL_CTX *ctx, int strength); +int SSL_CTX_set_srp_client_pwd_callback(SSL_CTX *ctx, char *(*cb)(SSL *,void *)); +int SSL_CTX_set_srp_verify_param_callback(SSL_CTX *ctx, int (*cb)(SSL *,void *)); +int SSL_CTX_set_srp_username_callback(SSL_CTX *ctx, int (*cb)(SSL *,int *,void *)); +int SSL_CTX_set_srp_missing_srp_username_callback(SSL_CTX *ctx, char *(*cb)(SSL *,void *)); +int SSL_CTX_set_srp_cb_arg(SSL_CTX *ctx, void *arg); + +int SSL_set_srp_server_param(SSL *s,BIGNUM *N,BIGNUM *g,BIGNUM *sa,BIGNUM *v,char *info); +int SSL_set_srp_server_param_pw(SSL *s, const char *user, const char *pass, const char *grp); + +BIGNUM *SSL_get_srp_g(SSL *s); +BIGNUM *SSL_get_srp_N(SSL *s); + +char *SSL_get_srp_username(SSL *s); +char *SSL_get_srp_userinfo(SSL *s); +#endif + void SSL_free(SSL *ssl); int SSL_accept(SSL *ssl); int SSL_connect(SSL *ssl); @@ -1995,6 +2075,7 @@ #define SSL_F_SSL_SET_TRUST 228 #define SSL_F_SSL_SET_WFD 196 #define SSL_F_SSL_SHUTDOWN 224 +#define SSL_F_SSL_SRP_CTX_INIT 293 #define SSL_F_SSL_UNDEFINED_CONST_FUNCTION 243 #define SSL_F_SSL_UNDEFINED_FUNCTION 197 #define SSL_F_SSL_UNDEFINED_VOID_FUNCTION 244 @@ -2053,6 +2134,11 @@ #define SSL_R_BAD_RSA_MODULUS_LENGTH 121 #define SSL_R_BAD_RSA_SIGNATURE 122 #define SSL_R_BAD_SIGNATURE 123 +#define SSL_R_BAD_SRP_A_LENGTH 2096 +#define SSL_R_BAD_SRP_B_LENGTH 2097 +#define SSL_R_BAD_SRP_G_LENGTH 2098 +#define SSL_R_BAD_SRP_N_LENGTH 2099 +#define SSL_R_BAD_SRP_S_LENGTH 2100 #define SSL_R_BAD_SSL_FILETYPE 124 #define SSL_R_BAD_SSL_SESSION_ID_LENGTH 125 #define SSL_R_BAD_STATE 126 @@ -2069,6 +2155,7 @@ #define SSL_R_CIPHER_CODE_WRONG_LENGTH 137 #define SSL_R_CIPHER_OR_HASH_UNAVAILABLE 138 #define SSL_R_CIPHER_TABLE_SRC_ERROR 139 +#define SSL_R_CLIENTHELLO_SRP_TLS_EXT 2101 #define SSL_R_CLIENTHELLO_TLSEXT 226 #define SSL_R_COMPRESSED_LENGTH_TOO_LONG 140 #define SSL_R_COMPRESSION_DISABLED 343 @@ -2105,6 +2192,7 @@ #define SSL_R_INVALID_COMMAND 280 #define SSL_R_INVALID_COMPRESSION_ALGORITHM 341 #define SSL_R_INVALID_PURPOSE 278 +#define SSL_R_INVALID_SRP_USERNAME 2107 #define SSL_R_INVALID_STATUS_RESPONSE 328 #define SSL_R_INVALID_TICKET_KEYS_LENGTH 325 #define SSL_R_INVALID_TRUST 279 @@ -2134,6 +2222,8 @@ #define SSL_R_MISSING_RSA_CERTIFICATE 168 #define SSL_R_MISSING_RSA_ENCRYPTING_CERT 169 #define SSL_R_MISSING_RSA_SIGNING_CERT 170 +#define SSL_R_MISSING_SRP_PARAM 2103 +#define SSL_R_MISSING_SRP_USERNAME 2104 #define SSL_R_MISSING_TMP_DH_KEY 171 #define SSL_R_MISSING_TMP_ECDH_KEY 311 #define SSL_R_MISSING_TMP_RSA_KEY 172 @@ -2206,6 +2296,7 @@ #define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED 277 #define SSL_R_SHORT_READ 219 #define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE 220 +#define SSL_R_SRP_A_CALC 2105 #define SSL_R_SSL23_DOING_SESSION_ID_REUSE 221 #define SSL_R_SSL2_CONNECTION_ID_TOO_LONG 299 #define SSL_R_SSL3_EXT_INVALID_ECPOINTFORMAT 321 diff -ruN openssl-1.0.0d-orig/ssl/ssl3.h openssl-1.0.0d-srp/ssl/ssl3.h --- openssl-1.0.0d-orig/ssl/ssl3.h 2010-01-06 09:37:38.000000000 -0800 +++ openssl-1.0.0d-srp/ssl/ssl3.h 2011-03-14 17:11:18.000000000 -0700 @@ -566,6 +566,8 @@ #define SSL3_ST_SR_CLNT_HELLO_A (0x110|SSL_ST_ACCEPT) #define SSL3_ST_SR_CLNT_HELLO_B (0x111|SSL_ST_ACCEPT) #define SSL3_ST_SR_CLNT_HELLO_C (0x112|SSL_ST_ACCEPT) +/* a new state to remember that we have already receive a ClientHello without srp username extension */ +#define SSL3_ST_SR_CLNT_HELLO_SRP_USERNAME (0x1E2|SSL_ST_ACCEPT) /* write to client */ #define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A (0x113|SSL_ST_ACCEPT) #define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B (0x114|SSL_ST_ACCEPT) diff -ruN openssl-1.0.0d-orig/ssl/ssl_asn1.c openssl-1.0.0d-srp/ssl/ssl_asn1.c --- openssl-1.0.0d-orig/ssl/ssl_asn1.c 2010-06-15 10:25:14.000000000 -0700 +++ openssl-1.0.0d-srp/ssl/ssl_asn1.c 2011-03-14 17:11:18.000000000 -0700 @@ -114,6 +114,9 @@ ASN1_OCTET_STRING psk_identity_hint; ASN1_OCTET_STRING psk_identity; #endif /* OPENSSL_NO_PSK */ +#ifndef OPENSSL_NO_SRP + ASN1_OCTET_STRING srp_username; +#endif /* OPENSSL_NO_SRP */ } SSL_SESSION_ASN1; int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp) @@ -130,6 +133,9 @@ unsigned char cbuf; int v11=0; #endif +#ifndef OPENSSL_NO_SRP + int v12=0; +#endif long l; SSL_SESSION_ASN1 a; M_ASN1_I2D_vars(in); @@ -267,6 +273,14 @@ a.psk_identity.data=(unsigned char *)(in->psk_identity); } #endif /* OPENSSL_NO_PSK */ +#ifndef OPENSSL_NO_SRP + if (in->srp_username) + { + a.srp_username.length=strlen(in->srp_username); + a.srp_username.type=V_ASN1_OCTET_STRING; + a.srp_username.data=(unsigned char *)(in->srp_username); + } +#endif /* OPENSSL_NO_SRP */ M_ASN1_I2D_len(&(a.version), i2d_ASN1_INTEGER); M_ASN1_I2D_len(&(a.ssl_version), i2d_ASN1_INTEGER); @@ -307,6 +321,10 @@ if (in->psk_identity) M_ASN1_I2D_len_EXP_opt(&(a.psk_identity), i2d_ASN1_OCTET_STRING,8,v8); #endif /* OPENSSL_NO_PSK */ +#ifndef OPENSSL_NO_SRP + if (in->srp_username) + M_ASN1_I2D_len_EXP_opt(&(a.srp_username), i2d_ASN1_OCTET_STRING,12,v12); +#endif /* OPENSSL_NO_SRP */ M_ASN1_I2D_seq_total(); @@ -351,6 +369,10 @@ if (in->compress_meth) M_ASN1_I2D_put_EXP_opt(&(a.comp_id), i2d_ASN1_OCTET_STRING,11,v11); #endif +#ifndef OPENSSL_NO_SRP + if (in->srp_username) + M_ASN1_I2D_put_EXP_opt(&(a.srp_username), i2d_ASN1_OCTET_STRING,12,v12); +#endif /* OPENSSL_NO_SRP */ M_ASN1_I2D_finish(); } @@ -588,5 +610,20 @@ } #endif +#ifndef OPENSSL_NO_SRP + os.length=0; + os.data=NULL; + M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,11); + if (os.data) + { + ret->srp_username = BUF_strndup((char *)os.data, os.length); + OPENSSL_free(os.data); + os.data = NULL; + os.length = 0; + } + else + ret->srp_username=NULL; +#endif /* OPENSSL_NO_SRP */ + M_ASN1_D2I_Finish(a,SSL_SESSION_free,SSL_F_D2I_SSL_SESSION); } diff -ruN openssl-1.0.0d-orig/ssl/ssl_ciph.c openssl-1.0.0d-srp/ssl/ssl_ciph.c --- openssl-1.0.0d-orig/ssl/ssl_ciph.c 2010-06-15 10:25:14.000000000 -0700 +++ openssl-1.0.0d-srp/ssl/ssl_ciph.c 2011-03-14 17:11:18.000000000 -0700 @@ -247,6 +247,7 @@ {0,SSL_TXT_ECDH,0, SSL_kECDHr|SSL_kECDHe|SSL_kEECDH,0,0,0,0,0,0,0,0}, {0,SSL_TXT_kPSK,0, SSL_kPSK, 0,0,0,0,0,0,0,0}, + {0,SSL_TXT_kSRP,0, SSL_kSRP, 0,0,0,0,0,0,0,0}, {0,SSL_TXT_kGOST,0, SSL_kGOST,0,0,0,0,0,0,0,0}, /* server authentication aliases */ @@ -273,6 +274,7 @@ {0,SSL_TXT_ADH,0, SSL_kEDH,SSL_aNULL,0,0,0,0,0,0,0}, {0,SSL_TXT_AECDH,0, SSL_kEECDH,SSL_aNULL,0,0,0,0,0,0,0}, {0,SSL_TXT_PSK,0, SSL_kPSK,SSL_aPSK,0,0,0,0,0,0,0}, + {0,SSL_TXT_SRP,0, SSL_kSRP,0,0,0,0,0,0,0,0}, /* symmetric encryption aliases */ @@ -661,6 +663,9 @@ *mkey |= SSL_kPSK; *auth |= SSL_aPSK; #endif +#ifdef OPENSSL_NO_SRP + *mkey |= SSL_kSRP; +#endif /* Check for presence of GOST 34.10 algorithms, and if they * do not present, disable appropriate auth and key exchange */ if (!get_optional_pkey_id("gost94")) { @@ -1511,6 +1516,9 @@ case SSL_kPSK: kx="PSK"; break; + case SSL_kSRP: + kx="SRP"; + break; default: kx="unknown"; } diff -ruN openssl-1.0.0d-orig/ssl/ssl_err.c openssl-1.0.0d-srp/ssl/ssl_err.c --- openssl-1.0.0d-orig/ssl/ssl_err.c 2010-01-06 09:37:38.000000000 -0800 +++ openssl-1.0.0d-srp/ssl/ssl_err.c 2011-03-14 17:11:18.000000000 -0700 @@ -250,6 +250,7 @@ {ERR_FUNC(SSL_F_SSL_SET_TRUST), "SSL_set_trust"}, {ERR_FUNC(SSL_F_SSL_SET_WFD), "SSL_set_wfd"}, {ERR_FUNC(SSL_F_SSL_SHUTDOWN), "SSL_shutdown"}, +{ERR_FUNC(SSL_F_SSL_SRP_CTX_INIT), "SSL_SRP_CTX_INIT"}, {ERR_FUNC(SSL_F_SSL_UNDEFINED_CONST_FUNCTION), "SSL_UNDEFINED_CONST_FUNCTION"}, {ERR_FUNC(SSL_F_SSL_UNDEFINED_FUNCTION), "SSL_UNDEFINED_FUNCTION"}, {ERR_FUNC(SSL_F_SSL_UNDEFINED_VOID_FUNCTION), "SSL_UNDEFINED_VOID_FUNCTION"}, @@ -311,6 +312,11 @@ {ERR_REASON(SSL_R_BAD_RSA_MODULUS_LENGTH),"bad rsa modulus length"}, {ERR_REASON(SSL_R_BAD_RSA_SIGNATURE) ,"bad rsa signature"}, {ERR_REASON(SSL_R_BAD_SIGNATURE) ,"bad signature"}, +{ERR_REASON(SSL_R_BAD_SRP_A_LENGTH) ,"bad srp a length"}, +{ERR_REASON(SSL_R_BAD_SRP_B_LENGTH) ,"bad srp b length"}, +{ERR_REASON(SSL_R_BAD_SRP_G_LENGTH) ,"bad srp g length"}, +{ERR_REASON(SSL_R_BAD_SRP_N_LENGTH) ,"bad srp n length"}, +{ERR_REASON(SSL_R_BAD_SRP_S_LENGTH) ,"bad srp s length"}, {ERR_REASON(SSL_R_BAD_SSL_FILETYPE) ,"bad ssl filetype"}, {ERR_REASON(SSL_R_BAD_SSL_SESSION_ID_LENGTH),"bad ssl session id length"}, {ERR_REASON(SSL_R_BAD_STATE) ,"bad state"}, @@ -327,6 +333,7 @@ {ERR_REASON(SSL_R_CIPHER_CODE_WRONG_LENGTH),"cipher code wrong length"}, {ERR_REASON(SSL_R_CIPHER_OR_HASH_UNAVAILABLE),"cipher or hash unavailable"}, {ERR_REASON(SSL_R_CIPHER_TABLE_SRC_ERROR),"cipher table src error"}, +{ERR_REASON(SSL_R_CLIENTHELLO_SRP_TLS_EXT),"error with the SRP username"}, {ERR_REASON(SSL_R_CLIENTHELLO_TLSEXT) ,"clienthello tlsext"}, {ERR_REASON(SSL_R_COMPRESSED_LENGTH_TOO_LONG),"compressed length too long"}, {ERR_REASON(SSL_R_COMPRESSION_DISABLED) ,"compression disabled"}, @@ -363,6 +370,7 @@ {ERR_REASON(SSL_R_INVALID_COMMAND) ,"invalid command"}, {ERR_REASON(SSL_R_INVALID_COMPRESSION_ALGORITHM),"invalid compression algorithm"}, {ERR_REASON(SSL_R_INVALID_PURPOSE) ,"invalid purpose"}, +{ERR_REASON(SSL_R_INVALID_SRP_USERNAME) ,"invalid srp username"}, {ERR_REASON(SSL_R_INVALID_STATUS_RESPONSE),"invalid status response"}, {ERR_REASON(SSL_R_INVALID_TICKET_KEYS_LENGTH),"invalid ticket keys length"}, {ERR_REASON(SSL_R_INVALID_TRUST) ,"invalid trust"}, @@ -392,6 +400,8 @@ {ERR_REASON(SSL_R_MISSING_RSA_CERTIFICATE),"missing rsa certificate"}, {ERR_REASON(SSL_R_MISSING_RSA_ENCRYPTING_CERT),"missing rsa encrypting cert"}, {ERR_REASON(SSL_R_MISSING_RSA_SIGNING_CERT),"missing rsa signing cert"}, +{ERR_REASON(SSL_R_MISSING_SRP_PARAM) ,"can't find SRP server param"}, +{ERR_REASON(SSL_R_MISSING_SRP_USERNAME) ,"missing srp username"}, {ERR_REASON(SSL_R_MISSING_TMP_DH_KEY) ,"missing tmp dh key"}, {ERR_REASON(SSL_R_MISSING_TMP_ECDH_KEY) ,"missing tmp ecdh key"}, {ERR_REASON(SSL_R_MISSING_TMP_RSA_KEY) ,"missing tmp rsa key"}, @@ -464,6 +474,7 @@ {ERR_REASON(SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED),"session id context uninitialized"}, {ERR_REASON(SSL_R_SHORT_READ) ,"short read"}, {ERR_REASON(SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE),"signature for non signing certificate"}, +{ERR_REASON(SSL_R_SRP_A_CALC) ,"error with the srp params"}, {ERR_REASON(SSL_R_SSL23_DOING_SESSION_ID_REUSE),"ssl23 doing session id reuse"}, {ERR_REASON(SSL_R_SSL2_CONNECTION_ID_TOO_LONG),"ssl2 connection id too long"}, {ERR_REASON(SSL_R_SSL3_EXT_INVALID_ECPOINTFORMAT),"ssl3 ext invalid ecpointformat"}, diff -ruN openssl-1.0.0d-orig/ssl/ssl_lib.c openssl-1.0.0d-srp/ssl/ssl_lib.c --- openssl-1.0.0d-orig/ssl/ssl_lib.c 2010-06-15 10:25:14.000000000 -0700 +++ openssl-1.0.0d-srp/ssl/ssl_lib.c 2011-03-14 17:11:18.000000000 -0700 @@ -1646,6 +1646,9 @@ ret->psk_client_callback=NULL; ret->psk_server_callback=NULL; #endif +#ifndef OPENSSL_NO_SRP + SSL_CTX_SRP_CTX_init(ret); +#endif #ifndef OPENSSL_NO_BUF_FREELISTS ret->freelist_max_len = SSL_MAX_BUF_FREELIST_LEN_DEFAULT; ret->rbuf_freelist = OPENSSL_malloc(sizeof(SSL3_BUF_FREELIST)); @@ -1778,6 +1781,9 @@ if (a->psk_identity_hint) OPENSSL_free(a->psk_identity_hint); #endif +#ifndef OPENSSL_NO_SRP + SSL_CTX_SRP_CTX_free(a); +#endif #ifndef OPENSSL_NO_ENGINE if (a->client_cert_engine) ENGINE_finish(a->client_cert_engine); diff -ruN openssl-1.0.0d-orig/ssl/ssl_locl.h openssl-1.0.0d-srp/ssl/ssl_locl.h --- openssl-1.0.0d-orig/ssl/ssl_locl.h 2009-12-08 03:38:18.000000000 -0800 +++ openssl-1.0.0d-srp/ssl/ssl_locl.h 2011-03-14 17:11:18.000000000 -0700 @@ -289,6 +289,7 @@ #define SSL_kEECDH 0x00000080L /* ephemeral ECDH */ #define SSL_kPSK 0x00000100L /* PSK */ #define SSL_kGOST 0x00000200L /* GOST key exchange */ +#define SSL_kSRP 0x00000400L /* SRP */ /* Bits for algorithm_auth (server authentication) */ #define SSL_aRSA 0x00000001L /* RSA auth */ diff -ruN openssl-1.0.0d-orig/ssl/ssl_sess.c openssl-1.0.0d-srp/ssl/ssl_sess.c --- openssl-1.0.0d-orig/ssl/ssl_sess.c 2010-02-01 08:49:42.000000000 -0800 +++ openssl-1.0.0d-srp/ssl/ssl_sess.c 2011-03-14 17:11:18.000000000 -0700 @@ -218,6 +218,9 @@ ss->psk_identity_hint=NULL; ss->psk_identity=NULL; #endif +#ifndef OPENSSL_NO_SRP + ss->srp_username=NULL; +#endif return(ss); } @@ -729,6 +732,10 @@ if (ss->psk_identity != NULL) OPENSSL_free(ss->psk_identity); #endif +#ifndef OPENSSL_NO_SRP + if (ss->srp_username != NULL) + OPENSSL_free(ss->srp_username); +#endif OPENSSL_cleanse(ss,sizeof(*ss)); OPENSSL_free(ss); } diff -ruN openssl-1.0.0d-orig/ssl/ssl_stat.c openssl-1.0.0d-srp/ssl/ssl_stat.c --- openssl-1.0.0d-orig/ssl/ssl_stat.c 2010-01-16 11:20:38.000000000 -0800 +++ openssl-1.0.0d-srp/ssl/ssl_stat.c 2011-03-14 17:11:18.000000000 -0700 @@ -210,6 +210,9 @@ case SSL3_ST_SR_KEY_EXCH_B: str="SSLv3 read client key exchange B"; break; case SSL3_ST_SR_CERT_VRFY_A: str="SSLv3 read certificate verify A"; break; case SSL3_ST_SR_CERT_VRFY_B: str="SSLv3 read certificate verify B"; break; +#ifndef OPENSSL_NO_SRP +case SSL3_ST_SR_CLNT_HELLO_SRP_USERNAME: str="SSLv3 waiting for a SRP username"; break; +#endif #endif #if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3) @@ -547,6 +550,11 @@ case TLS1_AD_UNKNOWN_PSK_IDENTITY: str="unknown PSK identity"; break; +#ifndef OPENSSL_NO_SRP + case TLS1_AD_MISSING_SRP_USERNAME: + str="no srp username"; + break; +#endif default: str="unknown"; break; } return(str); diff -ruN openssl-1.0.0d-orig/ssl/ssl_txt.c openssl-1.0.0d-srp/ssl/ssl_txt.c --- openssl-1.0.0d-orig/ssl/ssl_txt.c 2009-06-30 15:26:28.000000000 -0700 +++ openssl-1.0.0d-srp/ssl/ssl_txt.c 2011-03-14 17:11:18.000000000 -0700 @@ -187,6 +187,10 @@ if (BIO_puts(bp,"\n PSK identity hint: ") <= 0) goto err; if (BIO_printf(bp, "%s", x->psk_identity_hint ? x->psk_identity_hint : "None") <= 0) goto err; #endif +#ifndef OPENSSL_NO_SRP + if (BIO_puts(bp,"\n SRP username: ") <= 0) goto err; + if (BIO_printf(bp, "%s", x->srp_username ? x->srp_username : "None") <= 0) goto err; +#endif #ifndef OPENSSL_NO_TLSEXT if (x->tlsext_tick_lifetime_hint) { diff -ruN openssl-1.0.0d-orig/ssl/ssltest.c openssl-1.0.0d-srp/ssl/ssltest.c --- openssl-1.0.0d-orig/ssl/ssltest.c 2010-06-15 10:25:15.000000000 -0700 +++ openssl-1.0.0d-srp/ssl/ssltest.c 2011-03-14 17:11:18.000000000 -0700 @@ -181,6 +181,9 @@ #ifndef OPENSSL_NO_DH #include #endif +#ifndef OPENSSL_NO_SRP +#include +#endif #include #define _XOPEN_SOURCE_EXTENDED 1 /* Or gethostname won't be declared properly @@ -246,6 +249,55 @@ unsigned int max_psk_len); #endif +#ifndef OPENSSL_NO_SRP +/* SRP client */ +/* This is a context that we pass to all callbacks */ +typedef struct srp_client_arg_st + { + char *srppassin; + char *srplogin; + } SRP_CLIENT_ARG; + +#define PWD_STRLEN 1024 + +static char * MS_CALLBACK ssl_give_srp_client_pwd_cb(SSL *s, void *arg) + { + SRP_CLIENT_ARG *srp_client_arg = (SRP_CLIENT_ARG *)arg; + return BUF_strdup((char *)srp_client_arg->srppassin); + } + +static char * MS_CALLBACK missing_srp_username_callback(SSL *s, void *arg) + { + SRP_CLIENT_ARG *srp_client_arg = (SRP_CLIENT_ARG *)arg; + return BUF_strdup(srp_client_arg->srplogin); + } + +/* SRP server */ +/* This is a context that we pass to SRP server callbacks */ +typedef struct srp_server_arg_st + { + char *expected_user; + char *pass; + } SRP_SERVER_ARG; + +static int MS_CALLBACK ssl_srp_server_param_cb(SSL *s, int *ad, void *arg) + { + SRP_SERVER_ARG * p = (SRP_SERVER_ARG *) arg; + + if (strcmp(p->expected_user, SSL_get_srp_username(s)) != 0) + { + fprintf(stderr, "User %s doesn't exist\n", SSL_get_srp_username(s)); + return SSL3_AL_FATAL; + } + if (SSL_set_srp_server_param_pw(s,p->expected_user,p->pass,"1024")<0) + { + *ad = SSL_AD_INTERNAL_ERROR; + return SSL3_AL_FATAL; + } + return SSL_ERROR_NONE; + } +#endif + static BIO *bio_err=NULL; static BIO *bio_stdout=NULL; @@ -289,6 +341,10 @@ #ifndef OPENSSL_NO_PSK fprintf(stderr," -psk arg - PSK in hex (without 0x)\n"); #endif +#ifndef OPENSSL_NO_SRP + fprintf(stderr," -srpuser user - SRP username to use\n"); + fprintf(stderr," -srppass arg - password for 'user'\n"); +#endif #ifndef OPENSSL_NO_SSL2 fprintf(stderr," -ssl2 - use SSLv2\n"); #endif @@ -476,6 +532,13 @@ #ifndef OPENSSL_NO_ECDH EC_KEY *ecdh = NULL; #endif +#ifndef OPENSSL_NO_SRP + /* client */ + int srp_lateuser = 0; + SRP_CLIENT_ARG srp_client_arg = {NULL,NULL}; + /* server */ + SRP_SERVER_ARG srp_server_arg = {NULL,NULL}; +#endif int no_dhe = 0; int no_ecdhe = 0; int no_psk = 0; @@ -572,6 +635,20 @@ no_psk=1; #endif } +#ifndef OPENSSL_NO_SRP + else if (strcmp(*argv,"-srpuser") == 0) + { + if (--argc < 1) goto bad; + srp_server_arg.expected_user = srp_client_arg.srplogin= *(++argv); + tls1=1; + } + else if (strcmp(*argv,"-srppass") == 0) + { + if (--argc < 1) goto bad; + srp_server_arg.pass = srp_client_arg.srppassin= *(++argv); + tls1=1; + } +#endif else if (strcmp(*argv,"-ssl2") == 0) ssl2=1; else if (strcmp(*argv,"-tls1") == 0) @@ -940,6 +1017,28 @@ } #endif } +#ifndef OPENSSL_NO_SRP + if (srp_client_arg.srplogin) + { + if (srp_lateuser) + SSL_CTX_set_srp_missing_srp_username_callback(c_ctx,missing_srp_username_callback); + else if (!SSL_CTX_set_srp_username(c_ctx, srp_client_arg.srplogin)) + { + BIO_printf(bio_err,"Unable to set SRP username\n"); + goto end; + } + SSL_CTX_set_srp_cb_arg(c_ctx,&srp_client_arg); + SSL_CTX_set_srp_client_pwd_callback(c_ctx, ssl_give_srp_client_pwd_cb); + /*SSL_CTX_set_srp_strength(c_ctx, srp_client_arg.strength);*/ + } + + if (srp_server_arg.expected_user != NULL) + { + SSL_CTX_set_verify(s_ctx,SSL_VERIFY_NONE,verify_callback); + SSL_CTX_set_srp_cb_arg(s_ctx, &srp_server_arg); + SSL_CTX_set_srp_username_callback(s_ctx, ssl_srp_server_param_cb); + } +#endif c_ssl=SSL_new(c_ctx); s_ssl=SSL_new(s_ctx); diff -ruN openssl-1.0.0d-orig/ssl/t1_enc.c openssl-1.0.0d-srp/ssl/t1_enc.c --- openssl-1.0.0d-orig/ssl/t1_enc.c 2010-06-15 10:25:15.000000000 -0700 +++ openssl-1.0.0d-srp/ssl/t1_enc.c 2011-03-14 17:11:18.000000000 -0700 @@ -1035,6 +1035,9 @@ case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: return(TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE); case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: return(TLS1_AD_BAD_CERTIFICATE_HASH_VALUE); case SSL_AD_UNKNOWN_PSK_IDENTITY:return(TLS1_AD_UNKNOWN_PSK_IDENTITY); +#ifndef OPENSSL_NO_SRP + case SSL_AD_MISSING_SRP_USERNAME:return(TLS1_AD_MISSING_SRP_USERNAME); +#endif #if 0 /* not appropriate for TLS, not used for DTLS */ case DTLS1_AD_MISSING_HANDSHAKE_MESSAGE: return (DTLS1_AD_MISSING_HANDSHAKE_MESSAGE); diff -ruN openssl-1.0.0d-orig/ssl/t1_lib.c openssl-1.0.0d-srp/ssl/t1_lib.c --- openssl-1.0.0d-orig/ssl/t1_lib.c 2011-02-08 09:10:53.000000000 -0800 +++ openssl-1.0.0d-srp/ssl/t1_lib.c 2011-03-14 17:11:18.000000000 -0700 @@ -341,6 +341,30 @@ ret += el; } +#ifndef OPENSSL_NO_SRP +#define MIN(x,y) (((x)<(y))?(x):(y)) + /* we add SRP username the first time only if we have one! */ + if (s->srp_ctx.login != NULL) + {/* Add TLS extension SRP username to the Client Hello message */ + int login_len = MIN(strlen(s->srp_ctx.login) + 1, 255); + long lenmax; + + if ((lenmax = limit - ret - 5) < 0) return NULL; + if (login_len > lenmax) return NULL; + if (login_len > 255) + { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return NULL; + } + s2n(TLSEXT_TYPE_srp,ret); + s2n(login_len+1,ret); + + (*ret++) = (unsigned char) MIN(strlen(s->srp_ctx.login), 254); + memcpy(ret, s->srp_ctx.login, MIN(strlen(s->srp_ctx.login), 254)); + ret+=login_len; + } +#endif + #ifndef OPENSSL_NO_EC if (s->tlsext_ecpointformatlist != NULL && s->version != DTLS1_VERSION) @@ -762,6 +786,19 @@ } } +#ifndef OPENSSL_NO_SRP + else if (type == TLSEXT_TYPE_srp) + { + if (size > 0) + { + len = data[0]; + if ((s->srp_ctx.login = OPENSSL_malloc(len+1)) == NULL) + return -1; + memcpy(s->srp_ctx.login, &data[1], len); + s->srp_ctx.login[len]='\0'; + } + } +#endif #ifndef OPENSSL_NO_EC else if (type == TLSEXT_TYPE_ec_point_formats && diff -ruN openssl-1.0.0d-orig/ssl/tls1.h openssl-1.0.0d-srp/ssl/tls1.h --- openssl-1.0.0d-orig/ssl/tls1.h 2009-11-11 06:51:29.000000000 -0800 +++ openssl-1.0.0d-srp/ssl/tls1.h 2011-03-14 17:11:18.000000000 -0700 @@ -182,6 +182,8 @@ #define TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE 113 #define TLS1_AD_BAD_CERTIFICATE_HASH_VALUE 114 #define TLS1_AD_UNKNOWN_PSK_IDENTITY 115 /* fatal */ +#define TLS1_AD_UNKNOWN_SRP_USERNAME 120 /* fatal */ +#define TLS1_AD_MISSING_SRP_USERNAME 121 /* ExtensionType values from RFC3546 / RFC4366 */ #define TLSEXT_TYPE_server_name 0 @@ -193,6 +195,8 @@ /* ExtensionType values from RFC4492 */ #define TLSEXT_TYPE_elliptic_curves 10 #define TLSEXT_TYPE_ec_point_formats 11 +/* ExtensionType value from RFC5054 */ +#define TLSEXT_TYPE_srp 12 #define TLSEXT_TYPE_session_ticket 35 /* ExtensionType value from draft-rescorla-tls-opaque-prf-input-00.txt */ #if 0 /* will have to be provided externally for now , @@ -376,6 +380,17 @@ #define TLS1_CK_ECDH_anon_WITH_AES_128_CBC_SHA 0x0300C018 #define TLS1_CK_ECDH_anon_WITH_AES_256_CBC_SHA 0x0300C019 +/* SRP ciphersuites from RFC 5054 */ +#define TLS1_CK_SRP_SHA_WITH_3DES_EDE_CBC_SHA 0x0300C01A +#define TLS1_CK_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA 0x0300C01B +#define TLS1_CK_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA 0x0300C01C +#define TLS1_CK_SRP_SHA_WITH_AES_128_CBC_SHA 0x0300C01D +#define TLS1_CK_SRP_SHA_RSA_WITH_AES_128_CBC_SHA 0x0300C01E +#define TLS1_CK_SRP_SHA_DSS_WITH_AES_128_CBC_SHA 0x0300C01F +#define TLS1_CK_SRP_SHA_WITH_AES_256_CBC_SHA 0x0300C020 +#define TLS1_CK_SRP_SHA_RSA_WITH_AES_256_CBC_SHA 0x0300C021 +#define TLS1_CK_SRP_SHA_DSS_WITH_AES_256_CBC_SHA 0x0300C022 + /* XXX * Inconsistency alert: * The OpenSSL names of ciphers with ephemeral DH here include the string @@ -443,6 +458,17 @@ #define TLS1_TXT_PSK_WITH_AES_128_CBC_SHA "PSK-AES128-CBC-SHA" #define TLS1_TXT_PSK_WITH_AES_256_CBC_SHA "PSK-AES256-CBC-SHA" +/* SRP ciphersuite from RFC 5054 */ +#define TLS1_TXT_SRP_SHA_WITH_3DES_EDE_CBC_SHA "SRP-3DES-EDE-CBC-SHA" +#define TLS1_TXT_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA "SRP-RSA-3DES-EDE-CBC-SHA" +#define TLS1_TXT_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA "SRP-DSS-3DES-EDE-CBC-SHA" +#define TLS1_TXT_SRP_SHA_WITH_AES_128_CBC_SHA "SRP-AES-128-CBC-SHA" +#define TLS1_TXT_SRP_SHA_RSA_WITH_AES_128_CBC_SHA "SRP-RSA-AES-128-CBC-SHA" +#define TLS1_TXT_SRP_SHA_DSS_WITH_AES_128_CBC_SHA "SRP-DSS-AES-128-CBC-SHA" +#define TLS1_TXT_SRP_SHA_WITH_AES_256_CBC_SHA "SRP-AES-256-CBC-SHA" +#define TLS1_TXT_SRP_SHA_RSA_WITH_AES_256_CBC_SHA "SRP-RSA-AES-256-CBC-SHA" +#define TLS1_TXT_SRP_SHA_DSS_WITH_AES_256_CBC_SHA "SRP-DSS-AES-256-CBC-SHA" + /* Camellia ciphersuites from RFC4132 */ #define TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA "CAMELLIA128-SHA" #define TLS1_TXT_DH_DSS_WITH_CAMELLIA_128_CBC_SHA "DH-DSS-CAMELLIA128-SHA" diff -ruN openssl-1.0.0d-orig/ssl/tls_srp.c openssl-1.0.0d-srp/ssl/tls_srp.c --- openssl-1.0.0d-orig/ssl/tls_srp.c 1969-12-31 16:00:00.000000000 -0800 +++ openssl-1.0.0d-srp/ssl/tls_srp.c 2011-03-14 17:11:18.000000000 -0700 @@ -0,0 +1,518 @@ +/* ssl/tls_srp.c */ +/* Written by Christophe Renou (christophe.renou@edelweb.fr) with + * the precious help of Peter Sylvester (peter.sylvester@edelweb.fr) + * for the EdelKey project and contributed to the OpenSSL project 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#include "ssl_locl.h" +#ifndef OPENSSL_NO_SRP + +#include +#include +#include + +int SSL_CTX_SRP_CTX_free(struct ssl_ctx_st *ctx) + { + if (ctx == NULL) + return 0; + OPENSSL_free(ctx->srp_ctx.login); + BN_free(ctx->srp_ctx.N); + BN_free(ctx->srp_ctx.g); + BN_free(ctx->srp_ctx.s); + BN_free(ctx->srp_ctx.B); + BN_free(ctx->srp_ctx.A); + BN_free(ctx->srp_ctx.a); + BN_free(ctx->srp_ctx.b); + BN_free(ctx->srp_ctx.v); + ctx->srp_ctx.TLS_ext_srp_username_callback = NULL; + ctx->srp_ctx.SRP_cb_arg = NULL; + ctx->srp_ctx.SRP_verify_param_callback = NULL; + ctx->srp_ctx.SRP_give_srp_client_pwd_callback = NULL; + ctx->srp_ctx.SRP_TLS_ext_missing_srp_client_username_callback = NULL; + ctx->srp_ctx.N = NULL; + ctx->srp_ctx.g = NULL; + ctx->srp_ctx.s = NULL; + ctx->srp_ctx.B = NULL; + ctx->srp_ctx.A = NULL; + ctx->srp_ctx.a = NULL; + ctx->srp_ctx.b = NULL; + ctx->srp_ctx.v = NULL; + ctx->srp_ctx.login = NULL; + ctx->srp_ctx.info = NULL; + ctx->srp_ctx.strength = SRP_MINIMAL_N; + ctx->srp_ctx.srp_Mask = 0; + return (1); + } + +int SSL_SRP_CTX_free(struct ssl_st *s) + { + if (s == NULL) + return 0; + OPENSSL_free(s->srp_ctx.login); + BN_free(s->srp_ctx.N); + BN_free(s->srp_ctx.g); + BN_free(s->srp_ctx.s); + BN_free(s->srp_ctx.B); + BN_free(s->srp_ctx.A); + BN_free(s->srp_ctx.a); + BN_free(s->srp_ctx.b); + BN_free(s->srp_ctx.v); + s->srp_ctx.TLS_ext_srp_username_callback = NULL; + s->srp_ctx.SRP_cb_arg = NULL; + s->srp_ctx.SRP_verify_param_callback = NULL; + s->srp_ctx.SRP_give_srp_client_pwd_callback = NULL; + s->srp_ctx.SRP_TLS_ext_missing_srp_client_username_callback = NULL; + s->srp_ctx.N = NULL; + s->srp_ctx.g = NULL; + s->srp_ctx.s = NULL; + s->srp_ctx.B = NULL; + s->srp_ctx.A = NULL; + s->srp_ctx.a = NULL; + s->srp_ctx.b = NULL; + s->srp_ctx.v = NULL; + s->srp_ctx.login = NULL; + s->srp_ctx.info = NULL; + s->srp_ctx.strength = SRP_MINIMAL_N; + s->srp_ctx.srp_Mask = 0; + return (1); + } + +int SSL_SRP_CTX_init(struct ssl_st *s) + { + SSL_CTX *ctx; + + if ((s == NULL) || ((ctx = s->ctx) == NULL)) + return 0; + s->srp_ctx.SRP_cb_arg = ctx->srp_ctx.SRP_cb_arg; + /* set client Hello login callback */ + s->srp_ctx.TLS_ext_srp_username_callback = ctx->srp_ctx.TLS_ext_srp_username_callback; + /* set SRP N/g param callback for verification */ + s->srp_ctx.SRP_verify_param_callback = ctx->srp_ctx.SRP_verify_param_callback; + /* set SRP client passwd callback */ + s->srp_ctx.SRP_give_srp_client_pwd_callback = ctx->srp_ctx.SRP_give_srp_client_pwd_callback; + s->srp_ctx.SRP_TLS_ext_missing_srp_client_username_callback = ctx->srp_ctx.SRP_TLS_ext_missing_srp_client_username_callback; + + s->srp_ctx.N = NULL; + s->srp_ctx.g = NULL; + s->srp_ctx.s = NULL; + s->srp_ctx.B = NULL; + s->srp_ctx.A = NULL; + s->srp_ctx.a = NULL; + s->srp_ctx.b = NULL; + s->srp_ctx.v = NULL; + s->srp_ctx.login = NULL; + s->srp_ctx.info = ctx->srp_ctx.info; + s->srp_ctx.strength = ctx->srp_ctx.strength; + + if (((ctx->srp_ctx.N != NULL) && + ((s->srp_ctx.N = BN_dup(ctx->srp_ctx.N)) == NULL)) || + ((ctx->srp_ctx.g != NULL) && + ((s->srp_ctx.g = BN_dup(ctx->srp_ctx.g)) == NULL)) || + ((ctx->srp_ctx.s != NULL) && + ((s->srp_ctx.s = BN_dup(ctx->srp_ctx.s)) == NULL)) || + ((ctx->srp_ctx.B != NULL) && + ((s->srp_ctx.B = BN_dup(ctx->srp_ctx.B)) == NULL)) || + ((ctx->srp_ctx.A != NULL) && + ((s->srp_ctx.A = BN_dup(ctx->srp_ctx.A)) == NULL)) || + ((ctx->srp_ctx.a != NULL) && + ((s->srp_ctx.a = BN_dup(ctx->srp_ctx.a)) == NULL)) || + ((ctx->srp_ctx.v != NULL) && + ((s->srp_ctx.v = BN_dup(ctx->srp_ctx.v)) == NULL)) || + ((ctx->srp_ctx.b != NULL) && + ((s->srp_ctx.b = BN_dup(ctx->srp_ctx.b)) == NULL))) + { + SSLerr(SSL_F_SSL_SRP_CTX_INIT,ERR_R_BN_LIB); + goto err; + } + if ((ctx->srp_ctx.login != NULL) && + ((s->srp_ctx.login = BUF_strdup(ctx->srp_ctx.login)) == NULL)) + { + SSLerr(SSL_F_SSL_SRP_CTX_INIT,ERR_R_INTERNAL_ERROR); + goto err; + } + s->srp_ctx.srp_Mask = ctx->srp_ctx.srp_Mask; + + return (1); +err: + OPENSSL_free(s->srp_ctx.login); + BN_free(s->srp_ctx.N); + BN_free(s->srp_ctx.g); + BN_free(s->srp_ctx.s); + BN_free(s->srp_ctx.B); + BN_free(s->srp_ctx.A); + BN_free(s->srp_ctx.a); + BN_free(s->srp_ctx.b); + BN_free(s->srp_ctx.v); + return (0); + } + +int SSL_CTX_SRP_CTX_init(struct ssl_ctx_st *ctx) + { + if (ctx == NULL) + return 0; + + ctx->srp_ctx.SRP_cb_arg = NULL; + /* set client Hello login callback */ + ctx->srp_ctx.TLS_ext_srp_username_callback = NULL; + /* set SRP N/g param callback for verification */ + ctx->srp_ctx.SRP_verify_param_callback = NULL; + /* set SRP client passwd callback */ + ctx->srp_ctx.SRP_give_srp_client_pwd_callback = NULL; + ctx->srp_ctx.SRP_TLS_ext_missing_srp_client_username_callback = NULL; + + ctx->srp_ctx.N = NULL; + ctx->srp_ctx.g = NULL; + ctx->srp_ctx.s = NULL; + ctx->srp_ctx.B = NULL; + ctx->srp_ctx.A = NULL; + ctx->srp_ctx.a = NULL; + ctx->srp_ctx.b = NULL; + ctx->srp_ctx.v = NULL; + ctx->srp_ctx.login = NULL; + ctx->srp_ctx.srp_Mask = 0; + ctx->srp_ctx.info = NULL; + ctx->srp_ctx.strength = SRP_MINIMAL_N; + + return (1); + } + +/* server side */ +int SSL_srp_server_param_with_username(SSL *s, int *ad) + { + unsigned char b[SSL_MAX_MASTER_KEY_LENGTH]; + int al; + + *ad = SSL_AD_UNKNOWN_SRP_USERNAME; + if ((s->srp_ctx.TLS_ext_srp_username_callback !=NULL) && + ((al = s->srp_ctx.TLS_ext_srp_username_callback(s, ad, s->srp_ctx.SRP_cb_arg))!=SSL_ERROR_NONE)) + return al; + + *ad = SSL_AD_INTERNAL_ERROR; + if ((s->srp_ctx.N == NULL) || + (s->srp_ctx.g == NULL) || + (s->srp_ctx.s == NULL) || + (s->srp_ctx.v == NULL)) + return SSL3_AL_FATAL; + + RAND_bytes(b, sizeof(b)); + s->srp_ctx.b = BN_bin2bn(b,sizeof(b),NULL); + OPENSSL_cleanse(b,sizeof(b)); + + /* Calculate: B = (kv + g^b) % N */ + + 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)? + SSL_ERROR_NONE:SSL3_AL_FATAL; + } + +/* If the server just has the raw password, make up a verifier entry on the fly */ +int SSL_set_srp_server_param_pw(SSL *s, const char *user, const char *pass, const char *grp) + { + SRP_gN *GN = SRP_get_default_gN(grp); + if(GN == NULL) return -1; + s->srp_ctx.N = BN_dup(GN->N); + s->srp_ctx.g = BN_dup(GN->g); + if(s->srp_ctx.v != NULL) + { + BN_clear_free(s->srp_ctx.v); + s->srp_ctx.v = NULL; + } + if(s->srp_ctx.s != NULL) + { + BN_clear_free(s->srp_ctx.s); + s->srp_ctx.s = NULL; + } + if(!SRP_create_verifier_BN(user, pass, &s->srp_ctx.s, &s->srp_ctx.v, GN->N, GN->g)) return -1; + + return 1; + } + +int SSL_set_srp_server_param(SSL *s,BIGNUM *N,BIGNUM *g,BIGNUM *sa,BIGNUM *v,char *info) + { + if (N!= NULL) + { + if (s->srp_ctx.N != NULL) + { + if (!BN_copy(s->srp_ctx.N,N)) + { + BN_free(s->srp_ctx.N); + s->srp_ctx.N = NULL; + } + } + else + s->srp_ctx.N = BN_dup(N); + } + if (g!= NULL) + { + if (s->srp_ctx.g != NULL) + { + if (!BN_copy(s->srp_ctx.g,g)) + { + BN_free(s->srp_ctx.g); + s->srp_ctx.g = NULL; + } + } + else + s->srp_ctx.g = BN_dup(g); + } + if (sa!= NULL) + { + if (s->srp_ctx.s != NULL) + { + if (!BN_copy(s->srp_ctx.s,sa)) + { + BN_free(s->srp_ctx.s); + s->srp_ctx.s = NULL; + } + } + else + s->srp_ctx.s = BN_dup(sa); + } + if (v!= NULL) + { + if (s->srp_ctx.v != NULL) + { + if (!BN_copy(s->srp_ctx.v,v)) + { + BN_free(s->srp_ctx.v); + s->srp_ctx.v = NULL; + } + } + else + s->srp_ctx.v = BN_dup(v); + } + s->srp_ctx.info = info; + + if (!(s->srp_ctx.N) || + !(s->srp_ctx.g) || + !(s->srp_ctx.s) || + !(s->srp_ctx.v)) + return -1; + + return 1; + } + +int SRP_generate_server_master_secret(SSL *s,unsigned char *master_key) + { + BIGNUM *K = NULL, *u = NULL; + int ret = -1, tmp_len; + unsigned char *tmp = NULL; + + if (!SRP_Verify_A_mod_N(s->srp_ctx.A,s->srp_ctx.N)) + goto err; + if (!(u = SRP_Calc_u(s->srp_ctx.A,s->srp_ctx.B,s->srp_ctx.N))) + goto err; + if (!(K = SRP_Calc_server_key(s->srp_ctx.A, s->srp_ctx.v, u, s->srp_ctx.b, s->srp_ctx.N))) + goto err; + + tmp_len = BN_num_bytes(K); + if ((tmp = OPENSSL_malloc(tmp_len)) == NULL) + goto err; + BN_bn2bin(K, tmp); + ret = s->method->ssl3_enc->generate_master_secret(s,master_key,tmp,tmp_len); +err: + if (tmp) + { + OPENSSL_cleanse(tmp,tmp_len) ; + OPENSSL_free(tmp); + } + BN_clear_free(K); + BN_clear_free(u); + return ret; + } + +/* client side */ +int SRP_generate_client_master_secret(SSL *s,unsigned char *master_key) + { + BIGNUM *x = NULL, *u = NULL, *K = NULL; + int ret = -1, tmp_len; + char *passwd = NULL; + unsigned char *tmp = NULL; + + /* Checks if b % n == 0 + */ + if (SRP_Verify_B_mod_N(s->srp_ctx.B,s->srp_ctx.N)==0) goto err; + if (!(u = SRP_Calc_u(s->srp_ctx.A,s->srp_ctx.B,s->srp_ctx.N))) goto err; + if (s->srp_ctx.SRP_give_srp_client_pwd_callback == NULL) goto err; + if (!(passwd = s->srp_ctx.SRP_give_srp_client_pwd_callback(s, s->srp_ctx.SRP_cb_arg))) goto err; + if (!(x = SRP_Calc_x(s->srp_ctx.s,s->srp_ctx.login,passwd))) goto err; + 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; + + tmp_len = BN_num_bytes(K); + if ((tmp = OPENSSL_malloc(tmp_len)) == NULL) goto err; + BN_bn2bin(K, tmp); + ret = s->method->ssl3_enc->generate_master_secret(s,master_key,tmp,tmp_len); +err: + if (tmp) + { + OPENSSL_cleanse(tmp,tmp_len) ; + OPENSSL_free(tmp); + } + BN_clear_free(K); + BN_clear_free(x); + if (passwd) + { + OPENSSL_cleanse(passwd,strlen(passwd)) ; + OPENSSL_free(passwd); + } + BN_clear_free(u); + return ret; + } + +int SRP_Calc_A_param(SSL *s) + { + unsigned char rand[SSL_MAX_MASTER_KEY_LENGTH]; + + if (BN_num_bits(s->srp_ctx.N) < s->srp_ctx.strength) + return -1; + + if (s->srp_ctx.SRP_verify_param_callback ==NULL && + !SRP_check_known_gN_param(s->srp_ctx.g,s->srp_ctx.N)) + return -1 ; + + RAND_bytes(rand, sizeof(rand)); + s->srp_ctx.a = BN_bin2bn(rand,sizeof(rand), s->srp_ctx.a); + OPENSSL_cleanse(rand,sizeof(rand)); + + if (!(s->srp_ctx.A = SRP_Calc_A(s->srp_ctx.a,s->srp_ctx.N,s->srp_ctx.g))) + return -1; + + /* We can have a callback to verify SRP param!! */ + if (s->srp_ctx.SRP_verify_param_callback !=NULL) + return s->srp_ctx.SRP_verify_param_callback(s,s->srp_ctx.SRP_cb_arg); + + return 1; + } + +int SRP_have_to_put_srp_username(SSL *s) + { + if (s->srp_ctx.SRP_TLS_ext_missing_srp_client_username_callback == NULL) + return 0; + if ((s->srp_ctx.login = s->srp_ctx.SRP_TLS_ext_missing_srp_client_username_callback(s,s->srp_ctx.SRP_cb_arg)) == NULL) + return 0; + s->srp_ctx.srp_Mask|=SSL_kSRP; + return 1; + } + +BIGNUM *SSL_get_srp_g(SSL *s) + { + if (s->srp_ctx.g != NULL) + return s->srp_ctx.g; + return s->ctx->srp_ctx.g; + } + +BIGNUM *SSL_get_srp_N(SSL *s) + { + if (s->srp_ctx.N != NULL) + return s->srp_ctx.N; + return s->ctx->srp_ctx.N; + } + +char *SSL_get_srp_username(SSL *s) + { + if (s->srp_ctx.login != NULL) + return s->srp_ctx.login; + return s->ctx->srp_ctx.login; + } + +char *SSL_get_srp_userinfo(SSL *s) + { + if (s->srp_ctx.info != NULL) + return s->srp_ctx.info; + return s->ctx->srp_ctx.info; + } + +#define tls1_ctx_ctrl ssl3_ctx_ctrl +#define tls1_ctx_callback_ctrl ssl3_ctx_callback_ctrl + +int SSL_CTX_set_srp_username(SSL_CTX *ctx,char *name) + { + return tls1_ctx_ctrl(ctx,SSL_CTRL_SET_TLS_EXT_SRP_USERNAME,0,name); + } + +int SSL_CTX_set_srp_password(SSL_CTX *ctx,char *password) + { + return tls1_ctx_ctrl(ctx,SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD,0,password); + } + +int SSL_CTX_set_srp_strength(SSL_CTX *ctx, int strength) + { + return tls1_ctx_ctrl(ctx,SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH,strength,NULL); + } + +int SSL_CTX_set_srp_verify_param_callback(SSL_CTX *ctx, int (*cb)(SSL *,void *)) + { + return tls1_ctx_callback_ctrl(ctx,SSL_CTRL_SET_SRP_VERIFY_PARAM_CB,(void (*)())cb); + } + +int SSL_CTX_set_srp_cb_arg(SSL_CTX *ctx, void *arg) + { + return tls1_ctx_ctrl(ctx,SSL_CTRL_SET_SRP_ARG,0,arg); + } + +int SSL_CTX_set_srp_username_callback(SSL_CTX *ctx, int (*cb)(SSL *,int *,void *)) + { + return tls1_ctx_callback_ctrl(ctx,SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB,(void (*)())cb); + } + +int SSL_CTX_set_srp_client_pwd_callback(SSL_CTX *ctx, char *(*cb)(SSL *,void *)) + { + return tls1_ctx_callback_ctrl(ctx,SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB,(void (*)())cb); + } + +int SSL_CTX_set_srp_missing_srp_username_callback(SSL_CTX *ctx, char *(*cb)(SSL *,void *)) + { + return tls1_ctx_callback_ctrl(ctx,SSL_CTRL_SET_TLS_EXT_SRP_MISSING_CLIENT_USERNAME_CB,(void (*)())cb); + } +#endif diff -ruN openssl-1.0.0d-orig/test/Makefile openssl-1.0.0d-srp/test/Makefile --- openssl-1.0.0d-orig/test/Makefile 2010-12-02 10:26:12.000000000 -0800 +++ openssl-1.0.0d-srp/test/Makefile 2011-03-14 17:11:18.000000000 -0700 @@ -61,6 +61,7 @@ EVPTEST= evp_test IGETEST= igetest JPAKETEST= jpaketest +SRPTEST= srptest ASN1TEST= asn1test TESTS= alltests @@ -72,7 +73,7 @@ $(MDC2TEST)$(EXE_EXT) $(RMDTEST)$(EXE_EXT) \ $(RANDTEST)$(EXE_EXT) $(DHTEST)$(EXE_EXT) $(ENGINETEST)$(EXE_EXT) \ $(BFTEST)$(EXE_EXT) $(CASTTEST)$(EXE_EXT) $(SSLTEST)$(EXE_EXT) $(EXPTEST)$(EXE_EXT) $(DSATEST)$(EXE_EXT) $(RSATEST)$(EXE_EXT) \ - $(EVPTEST)$(EXE_EXT) $(IGETEST)$(EXE_EXT) $(JPAKETEST)$(EXE_EXT) \ + $(EVPTEST)$(EXE_EXT) $(IGETEST)$(EXE_EXT) $(JPAKETEST)$(EXE_EXT) $(SRPTEST)$(EXE_EXT) \ $(ASN1TEST)$(EXE_EXT) # $(METHTEST)$(EXE_EXT) @@ -93,7 +94,7 @@ $(DESTEST).c $(SHATEST).c $(SHA1TEST).c $(MDC2TEST).c $(RMDTEST).c \ $(RANDTEST).c $(DHTEST).c $(ENGINETEST).c $(CASTTEST).c \ $(BFTEST).c $(SSLTEST).c $(DSATEST).c $(EXPTEST).c $(RSATEST).c \ - $(EVPTEST).c $(IGETEST).c $(JPAKETEST).c $(ASN1TEST).c + $(EVPTEST).c $(IGETEST).c $(JPAKETEST).c $(SRPTEST).c $(ASN1TEST).c EXHEADER= HEADER= $(EXHEADER) @@ -136,7 +137,7 @@ test_enc test_x509 test_rsa test_crl test_sid \ test_gen test_req test_pkcs7 test_verify test_dh test_dsa \ test_ss test_ca test_engine test_evp test_ssl test_tsa test_ige \ - test_jpake test_cms + test_jpake test_srp test_cms test_evp: ../util/shlib_wrap.sh ./$(EVPTEST) evptests.txt @@ -310,6 +311,10 @@ @echo "CMS consistency test" $(PERL) cms-test.pl +test_srp: $(SRPTEST)$(EXE_EXT) + @echo "Test SRP" + ../util/shlib_wrap.sh ./srptest + lint: lint -DLINT $(INCLUDES) $(SRC)>fluff @@ -446,6 +451,9 @@ $(ASN1TEST)$(EXE_EXT): $(ASN1TEST).o $(DLIBCRYPTO) @target=$(ASN1TEST); $(BUILD_CMD) +$(SRPTEST)$(EXE_EXT): $(SRPTEST).o $(DLIBCRYPTO) + @target=$(SRPTEST); $(BUILD_CMD) + #$(AESTEST).o: $(AESTEST).c # $(CC) -c $(CFLAGS) -DINTERMEDIATE_VALUE_KAT -DTRACE_KAT_MCT $(AESTEST).c diff -ruN openssl-1.0.0d-orig/test/testssl openssl-1.0.0d-srp/test/testssl --- openssl-1.0.0d-orig/test/testssl 2006-03-10 15:06:27.000000000 -0800 +++ openssl-1.0.0d-srp/test/testssl 2011-03-14 17:11:18.000000000 -0700 @@ -148,4 +148,14 @@ echo test tls1 with PSK via BIO pair $ssltest -bio_pair -tls1 -cipher PSK -psk abc123 $extra || exit 1 +if ../util/shlib_wrap.sh ../apps/openssl no-srp; then + echo skipping SRP tests +else + echo test tls1 with SRP + $ssltest -tls1 -cipher SRP -srpuser test -srppass abc123 + + echo test tls1 with SRP via BIO pair + $ssltest -bio_pair -tls1 -cipher SRP -srpuser test -srppass abc123 +fi + exit 0 diff -ruN openssl-1.0.0d-orig/util/libeay.num openssl-1.0.0d-srp/util/libeay.num --- openssl-1.0.0d-orig/util/libeay.num 2010-07-25 09:56:06.000000000 -0700 +++ openssl-1.0.0d-srp/util/libeay.num 2011-03-14 17:11:18.000000000 -0700 @@ -4189,3 +4189,19 @@ CRYPTO_cbc128_decrypt 4561 EXIST::FUNCTION: CRYPTO_cfb128_encrypt 4562 EXIST::FUNCTION: CRYPTO_cfb128_8_encrypt 4563 EXIST::FUNCTION: +SRP_VBASE_get_by_user 4564 EXIST::FUNCTION:SRP +SRP_Calc_server_key 4565 EXIST::FUNCTION:SRP +SRP_create_verifier 4566 EXIST::FUNCTION:SRP +SRP_create_verifier_BN 4567 EXIST::FUNCTION:SRP +SRP_Calc_u 4568 EXIST::FUNCTION:SRP +SRP_VBASE_free 4569 EXIST::FUNCTION:SRP +SRP_Calc_client_key 4570 EXIST::FUNCTION:SRP +SRP_get_default_gN 4571 EXIST::FUNCTION:SRP +SRP_Calc_x 4572 EXIST::FUNCTION:SRP +SRP_Calc_B 4573 EXIST::FUNCTION:SRP +SRP_VBASE_new 4574 EXIST::FUNCTION:SRP +SRP_check_known_gN_param 4575 EXIST::FUNCTION:SRP +SRP_Calc_A 4576 EXIST::FUNCTION:SRP +SRP_Verify_A_mod_N 4577 EXIST::FUNCTION:SRP +SRP_VBASE_init 4578 EXIST::FUNCTION:SRP +SRP_Verify_B_mod_N 4579 EXIST::FUNCTION:SRP diff -ruN openssl-1.0.0d-orig/util/mk1mf.pl openssl-1.0.0d-srp/util/mk1mf.pl --- openssl-1.0.0d-orig/util/mk1mf.pl 2010-12-03 11:31:06.000000000 -0800 +++ openssl-1.0.0d-srp/util/mk1mf.pl 2011-03-14 17:11:18.000000000 -0700 @@ -104,6 +104,7 @@ just-ssl - remove all non-ssl keys/digest no-asm - No x86 asm no-krb5 - No KRB5 + no-srp - No SRP no-ec - No EC no-ecdsa - No ECDSA no-ecdh - No ECDH @@ -261,6 +262,7 @@ $cflags.=" -DOPENSSL_NO_SSL2" if $no_ssl2; $cflags.=" -DOPENSSL_NO_SSL3" if $no_ssl3; $cflags.=" -DOPENSSL_NO_TLSEXT" if $no_tlsext; +$cflags.=" -DOPENSSL_NO_SRP" if $no_srp; $cflags.=" -DOPENSSL_NO_CMS" if $no_cms; $cflags.=" -DOPENSSL_NO_ERR" if $no_err; $cflags.=" -DOPENSSL_NO_KRB5" if $no_krb5; @@ -781,6 +783,8 @@ @a=grep(!/(^sha1)|(_sha1$)|(m_dss1$)/,@a) if $no_sha1; @a=grep(!/_mdc2$/,@a) if $no_mdc2; + @a=grep(!/(srp)/,@a) if $no_srp; + @a=grep(!/^engine$/,@a) if $no_engine; @a=grep(!/^hw$/,@a) if $no_hw; @a=grep(!/(^rsa$)|(^genrsa$)/,@a) if $no_rsa; @@ -1056,6 +1060,7 @@ "no-ssl2" => \$no_ssl2, "no-ssl3" => \$no_ssl3, "no-tlsext" => \$no_tlsext, + "no-srp" => \$no_srp, "no-cms" => \$no_cms, "no-jpake" => \$no_jpake, "no-err" => \$no_err, @@ -1071,7 +1076,7 @@ [\$no_rc2, \$no_idea, \$no_des, \$no_bf, \$no_cast, \$no_md2, \$no_sha, \$no_mdc2, \$no_dsa, \$no_dh, \$no_ssl2, \$no_err, \$no_ripemd, \$no_rc5, - \$no_aes, \$no_camellia, \$no_seed], + \$no_aes, \$no_camellia, \$no_seed, \$no_srp], "rsaref" => 0, "gcc" => \$gcc, "debug" => \$debug, diff -ruN openssl-1.0.0d-orig/util/mkdef.pl openssl-1.0.0d-srp/util/mkdef.pl --- openssl-1.0.0d-orig/util/mkdef.pl 2010-07-25 09:56:06.000000000 -0700 +++ openssl-1.0.0d-srp/util/mkdef.pl 2011-03-14 17:11:18.000000000 -0700 @@ -98,7 +98,7 @@ # RFC3779 "RFC3779", # TLS - "TLSEXT", "PSK", + "TLSEXT", "PSK", "SRP", # CMS "CMS", # CryptoAPI Engine @@ -127,7 +127,7 @@ my $no_ec; my $no_ecdsa; my $no_ecdh; my $no_engine; my $no_hw; my $no_fp_api; my $no_static_engine=1; my $no_gmp; my $no_deprecated; my $no_rfc3779; my $no_psk; my $no_tlsext; my $no_cms; my $no_capieng; -my $no_jpake; my $no_ssl2; +my $no_jpake; my $no_srp; my $no_ssl2; my $zlib; @@ -218,6 +218,7 @@ elsif (/^no-ssl2$/) { $no_ssl2=1; } elsif (/^no-capieng$/) { $no_capieng=1; } elsif (/^no-jpake$/) { $no_jpake=1; } + elsif (/^no-srp$/) { $no_srp=1; } } @@ -317,6 +318,7 @@ $crypto.=" crypto/cms/cms.h"; $crypto.=" crypto/jpake/jpake.h"; $crypto.=" crypto/modes/modes.h"; +$crypto.=" crypto/srp/srp.h"; my $symhacks="crypto/symhacks.h"; @@ -1173,6 +1175,7 @@ if ($keyword eq "SSL2" && $no_ssl2) { return 0; } if ($keyword eq "CAPIENG" && $no_capieng) { return 0; } if ($keyword eq "JPAKE" && $no_jpake) { return 0; } + if ($keyword eq "SRP" && $no_srp) { return 0; } if ($keyword eq "DEPRECATED" && $no_deprecated) { return 0; } # Nothing recognise as true diff -ruN openssl-1.0.0d-orig/util/mkfiles.pl openssl-1.0.0d-srp/util/mkfiles.pl --- openssl-1.0.0d-orig/util/mkfiles.pl 2008-12-23 07:15:44.000000000 -0800 +++ openssl-1.0.0d-srp/util/mkfiles.pl 2011-03-14 17:11:18.000000000 -0700 @@ -62,6 +62,7 @@ "crypto/pqueue", "crypto/whrlpool", "crypto/ts", +"crypto/srp", "ssl", "apps", "engines", diff -ruN openssl-1.0.0d-orig/util/ssleay.num openssl-1.0.0d-srp/util/ssleay.num --- openssl-1.0.0d-orig/util/ssleay.num 2009-07-08 02:13:24.000000000 -0700 +++ openssl-1.0.0d-srp/util/ssleay.num 2011-03-14 17:11:18.000000000 -0700 @@ -259,3 +259,17 @@ SSL_set_session_ticket_ext_cb 308 EXIST::FUNCTION: SSL_set1_param 309 EXIST::FUNCTION: SSL_CTX_set1_param 310 EXIST::FUNCTION: +SSL_CTX_set_srp_client_pwd_callback 311 EXIST::FUNCTION:SRP,TLSEXT +SSL_get_srp_g 312 EXIST::FUNCTION:SRP,TLSEXT +SSL_CTX_set_srp_username_callback 313 EXIST::FUNCTION:SRP,TLSEXT +SSL_get_srp_userinfo 314 EXIST::FUNCTION:SRP,TLSEXT +SSL_set_srp_server_param 315 EXIST::FUNCTION:SRP,TLSEXT +SSL_set_srp_server_param_pw 316 EXIST::FUNCTION:SRP,TLSEXT +SSL_get_srp_N 317 EXIST::FUNCTION:SRP,TLSEXT +SSL_get_srp_username 318 EXIST::FUNCTION:SRP,TLSEXT +SSL_CTX_set_srp_password 319 EXIST::FUNCTION:SRP,TLSEXT +SSL_CTX_set_srp_strength 320 EXIST::FUNCTION:SRP,TLSEXT +SSL_CTX_set_srp_verify_param_callback 321 EXIST::FUNCTION:SRP,TLSEXT +SSL_CTX_set_srp_missing_srp_username_callback 322 EXIST::FUNCTION:SRP,TLSEXT +SSL_CTX_set_srp_cb_arg 323 EXIST::FUNCTION:SRP,TLSEXT +SSL_CTX_set_srp_username 324 EXIST::FUNCTION:SRP,TLSEXT