diff options
Diffstat (limited to 'app/openssl/apps/srp.c')
| -rw-r--r-- | app/openssl/apps/srp.c | 756 | 
1 files changed, 756 insertions, 0 deletions
diff --git a/app/openssl/apps/srp.c b/app/openssl/apps/srp.c new file mode 100644 index 00000000..9c7ae184 --- /dev/null +++ b/app/openssl/apps/srp.c @@ -0,0 +1,756 @@ +/* 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 = 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 = 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 = 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 = 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]; +        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) +	{ +	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 +	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; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) +		{ +		pp = sk_OPENSSL_PSTRING_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 = sk_OPENSSL_PSTRING_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; i < sk_OPENSSL_PSTRING_num(db->db->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 = sk_OPENSSL_PSTRING_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 = sk_OPENSSL_PSTRING_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_OPENSSL_PSTRING_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 abandoned.\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 **xpp = sk_OPENSSL_PSTRING_value(db->db->data,userindex); +				BIO_printf(bio_err, "user \"%s\" revoked. t\n", user); + +				xpp[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; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) +			{ +			pp = sk_OPENSSL_PSTRING_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 +  | 
