diff options
46 files changed, 4571 insertions, 17 deletions
@@ -4,6 +4,9 @@ Changes between 1.0.0d and 1.0.1 [xx XXX xxxx] + *) Add SRP support. + [Tom Wu <tjw@cs.stanford.edu> and Ben Laurie] + *) Add functions to copy EVP_PKEY_METHOD and retrieve flags and id. [Steve Henson] @@ -946,6 +946,12 @@ if (defined($disabled{"ec"}) || defined($disabled{"dsa"}) $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 --git a/Makefile.org b/Makefile.org index fb0af7ecc2..c8869d14df 100644 --- a/Makefile.org +++ b/Makefile.org @@ -121,7 +121,7 @@ SDIRS= \ 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 --git a/apps/Makefile b/apps/Makefile index fa32d2d7e7..61c80da0fb 100644 --- a/apps/Makefile +++ b/apps/Makefile @@ -39,7 +39,7 @@ E_EXE= verify asn1pars req dgst dh dhparam enc passwd gendh errstr \ 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 @@ E_OBJ= verify.o asn1pars.o req.o dgst.o dh.o dhparam.o enc.o passwd.o gendh.o er 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 @@ E_SRC= verify.c asn1pars.c req.c dgst.c dh.c enc.c passwd.c gendh.c errstr.c ca. 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 --git a/apps/demoSRP/srp_verifier.txt b/apps/demoSRP/srp_verifier.txt new file mode 100644 index 0000000000..ccae629247 --- /dev/null +++ b/apps/demoSRP/srp_verifier.txt @@ -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 --git a/apps/demoSRP/srp_verifier.txt.attr b/apps/demoSRP/srp_verifier.txt.attr new file mode 100644 index 0000000000..8f7e63a347 --- /dev/null +++ b/apps/demoSRP/srp_verifier.txt.attr @@ -0,0 +1 @@ +unique_subject = yes diff --git a/apps/progs.h b/apps/progs.h index 79e479a337..e91b884a9c 100644 --- a/apps/progs.h +++ b/apps/progs.h @@ -44,6 +44,7 @@ extern int smime_main(int argc,char *argv[]); 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 @@ FUNCTION functions[] = { #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 --git a/apps/s_client.c b/apps/s_client.c index 484d009987..81c7e85fdb 100644 --- a/apps/s_client.c +++ b/apps/s_client.c @@ -163,6 +163,9 @@ typedef unsigned int u_int; #include <openssl/rand.h> #include <openssl/ocsp.h> #include <openssl/bn.h> +#ifndef OPENSSL_NO_SRP +#include <openssl/srp.h> +#endif #include "s_apps.h" #include "timeouts.h" @@ -316,6 +319,13 @@ static void sc_usage(void) 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_1 - just use TLSv1.1\n"); @@ -367,6 +377,112 @@ static int MS_CALLBACK ssl_servername_cb(SSL *s, int *ad, void *arg) 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 + +static 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_ex(N, SRP_NUMBER_ITERATIONS_FOR_PRIME, bn_ctx, NULL) && + p != NULL && BN_rshift1(p, N) && + + /* p = (N-1)/2 */ + BN_is_prime_ex(p, SRP_NUMBER_ITERATIONS_FOR_PRIME, 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 @@ -440,6 +556,11 @@ int MAIN(int argc, char **argv) #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(); @@ -589,6 +710,37 @@ int MAIN(int argc, char **argv) } } #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(); @@ -840,6 +992,14 @@ bad: } } +#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) { @@ -919,6 +1079,26 @@ bad: 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 --git a/apps/s_server.c b/apps/s_server.c index 9e2f4830b0..a1934e893d 100644 --- a/apps/s_server.c +++ b/apps/s_server.c @@ -186,6 +186,9 @@ typedef unsigned int u_int; #ifndef OPENSSL_NO_RSA #include <openssl/rsa.h> #endif +#ifndef OPENSSL_NO_SRP +#include <openssl/srp.h> +#endif #include "s_apps.h" #include "timeouts.h" @@ -369,6 +372,40 @@ static unsigned int psk_server_cb(SSL *ssl, const char *identity, } #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 +493,10 @@ static void sv_usage(void) 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_1 - Just talk TLSv1_1\n"); @@ -874,12 +915,21 @@ int MAIN(int argc, char *argv[]) /* 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; @@ -1112,6 +1162,20 @@ int MAIN(int argc, char *argv[]) } } #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) @@ -1690,6 +1754,23 @@ bad: } #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 --git a/apps/srp.c b/apps/srp.c new file mode 100644 index 0000000000..4b969ec6dd --- /dev/null +++ b/apps/srp.c @@ -0,0 +1,759 @@ +/* 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 <openssl/opensslconf.h> + +#ifndef OPENSSL_NO_SRP +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <openssl/conf.h> +#include <openssl/bio.h> +#include <openssl/err.h> +#include <openssl/txt_db.h> +#include <openssl/buffer.h> +#include <openssl/srp.h> + +#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 **); + +static 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_OPENSSL_PSTRING_num(db->db->data); i++) + { + pp = (char **)sk_OPENSSL_PSTRING_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_OPENSSL_PSTRING_num(db->db->data); i++) + { + pp = (char **)sk_OPENSSL_PSTRING_value(db->db->data, i); + + if (pp[DB_srptype][0] != DB_SRP_INDEX && !strcmp(id,pp[DB_srpid])) + return i; + } + + return -1 ; + } + +static void print_entry(CA_DB *db, BIO *bio, int indx, int verbose, char *s) + { + if (indx >= 0 && verbose) + { + int j; + char **pp = (char **)sk_OPENSSL_PSTRING_value(db->db->data, indx); + 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]); + } + } + } + +static void print_index(CA_DB *db, BIO *bio, int indexindex, int verbose) + { + print_entry(db, bio, indexindex, verbose, "g N entry") ; + } + +static void print_user(CA_DB *db, BIO *bio, int userindex, int verbose) + { + if (verbose > 0) + { + char **pp = (char **)sk_OPENSSL_PSTRING_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"); + } + + } + } + +static 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; i<DB_NUMBER; i++) + { + irow[i]=row[i]; + row[i]=NULL; + } + irow[DB_NUMBER]=NULL; + + if (!TXT_DB_insert(db->db,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(const char *name, char *tag) + { + BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag); + } + + +static char *srp_verify_user(const char *user, const char *srp_verifier, + char *srp_usersalt, const char *g, const char *N, + const 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; + } + +static 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]; + |