1238384Sjkim/* apps/srp.c */ 2296341Sdelphij/* 3296341Sdelphij * Written by Peter Sylvester (peter.sylvester@edelweb.fr) for the EdelKey 4296341Sdelphij * project and contributed to the OpenSSL project 2004. 5238384Sjkim */ 6238384Sjkim/* ==================================================================== 7238384Sjkim * Copyright (c) 2004 The OpenSSL Project. All rights reserved. 8238384Sjkim * 9238384Sjkim * Redistribution and use in source and binary forms, with or without 10238384Sjkim * modification, are permitted provided that the following conditions 11238384Sjkim * are met: 12238384Sjkim * 13238384Sjkim * 1. Redistributions of source code must retain the above copyright 14296341Sdelphij * notice, this list of conditions and the following disclaimer. 15238384Sjkim * 16238384Sjkim * 2. Redistributions in binary form must reproduce the above copyright 17238384Sjkim * notice, this list of conditions and the following disclaimer in 18238384Sjkim * the documentation and/or other materials provided with the 19238384Sjkim * distribution. 20238384Sjkim * 21238384Sjkim * 3. All advertising materials mentioning features or use of this 22238384Sjkim * software must display the following acknowledgment: 23238384Sjkim * "This product includes software developed by the OpenSSL Project 24238384Sjkim * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 25238384Sjkim * 26238384Sjkim * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 27238384Sjkim * endorse or promote products derived from this software without 28238384Sjkim * prior written permission. For written permission, please contact 29238384Sjkim * licensing@OpenSSL.org. 30238384Sjkim * 31238384Sjkim * 5. Products derived from this software may not be called "OpenSSL" 32238384Sjkim * nor may "OpenSSL" appear in their names without prior written 33238384Sjkim * permission of the OpenSSL Project. 34238384Sjkim * 35238384Sjkim * 6. Redistributions of any form whatsoever must retain the following 36238384Sjkim * acknowledgment: 37238384Sjkim * "This product includes software developed by the OpenSSL Project 38238384Sjkim * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 39238384Sjkim * 40238384Sjkim * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 41238384Sjkim * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42238384Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 43238384Sjkim * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 44238384Sjkim * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45238384Sjkim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 46238384Sjkim * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 47238384Sjkim * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48238384Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 49238384Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50238384Sjkim * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 51238384Sjkim * OF THE POSSIBILITY OF SUCH DAMAGE. 52238384Sjkim * ==================================================================== 53238384Sjkim * 54238384Sjkim * This product includes cryptographic software written by Eric Young 55238384Sjkim * (eay@cryptsoft.com). This product includes software written by Tim 56238384Sjkim * Hudson (tjh@cryptsoft.com). 57238384Sjkim * 58238384Sjkim */ 59238384Sjkim#include <openssl/opensslconf.h> 60238384Sjkim 61238384Sjkim#ifndef OPENSSL_NO_SRP 62296341Sdelphij# include <stdio.h> 63296341Sdelphij# include <stdlib.h> 64296341Sdelphij# include <string.h> 65296341Sdelphij# include <openssl/conf.h> 66296341Sdelphij# include <openssl/bio.h> 67296341Sdelphij# include <openssl/err.h> 68296341Sdelphij# include <openssl/txt_db.h> 69296341Sdelphij# include <openssl/buffer.h> 70296341Sdelphij# include <openssl/srp.h> 71238384Sjkim 72296341Sdelphij# include "apps.h" 73238384Sjkim 74296341Sdelphij# undef PROG 75296341Sdelphij# define PROG srp_main 76238384Sjkim 77296341Sdelphij# define BASE_SECTION "srp" 78296341Sdelphij# define CONFIG_FILE "openssl.cnf" 79238384Sjkim 80296341Sdelphij# define ENV_RANDFILE "RANDFILE" 81238384Sjkim 82296341Sdelphij# define ENV_DATABASE "srpvfile" 83296341Sdelphij# define ENV_DEFAULT_SRP "default_srp" 84238384Sjkim 85296341Sdelphijstatic char *srp_usage[] = { 86296341Sdelphij "usage: srp [args] [user] \n", 87296341Sdelphij "\n", 88296341Sdelphij " -verbose Talk alot while doing things\n", 89296341Sdelphij " -config file A config file\n", 90296341Sdelphij " -name arg The particular srp definition to use\n", 91296341Sdelphij " -srpvfile arg The srp verifier file name\n", 92296341Sdelphij " -add add an user and srp verifier\n", 93296341Sdelphij " -modify modify the srp verifier of an existing user\n", 94296341Sdelphij " -delete delete user from verifier file\n", 95296341Sdelphij " -list list user\n", 96296341Sdelphij " -gn arg g and N values to be used for new verifier\n", 97296341Sdelphij " -userinfo arg additional info to be set for user\n", 98296341Sdelphij " -passin arg input file pass phrase source\n", 99296341Sdelphij " -passout arg output file pass phrase source\n", 100296341Sdelphij# ifndef OPENSSL_NO_ENGINE 101296341Sdelphij " -engine e - use engine e, possibly a hardware device.\n", 102296341Sdelphij# endif 103296341Sdelphij NULL 104238384Sjkim}; 105238384Sjkim 106296341Sdelphij# ifdef EFENCE 107238384Sjkimextern int EF_PROTECT_FREE; 108238384Sjkimextern int EF_PROTECT_BELOW; 109238384Sjkimextern int EF_ALIGNMENT; 110296341Sdelphij# endif 111238384Sjkim 112296341Sdelphijstatic CONF *conf = NULL; 113296341Sdelphijstatic char *section = NULL; 114238384Sjkim 115296341Sdelphij# define VERBOSE if (verbose) 116296341Sdelphij# define VVERBOSE if (verbose>1) 117238384Sjkim 118238384Sjkimint MAIN(int, char **); 119238384Sjkim 120296341Sdelphijstatic int get_index(CA_DB *db, char *id, char type) 121296341Sdelphij{ 122296341Sdelphij char **pp; 123296341Sdelphij int i; 124296341Sdelphij if (id == NULL) 125296341Sdelphij return -1; 126296341Sdelphij if (type == DB_SRP_INDEX) 127296341Sdelphij for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) { 128296341Sdelphij pp = sk_OPENSSL_PSTRING_value(db->db->data, i); 129296341Sdelphij if (pp[DB_srptype][0] == DB_SRP_INDEX 130296341Sdelphij && !strcmp(id, pp[DB_srpid])) 131296341Sdelphij return i; 132296341Sdelphij } else 133296341Sdelphij for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) { 134296341Sdelphij pp = sk_OPENSSL_PSTRING_value(db->db->data, i); 135238384Sjkim 136296341Sdelphij if (pp[DB_srptype][0] != DB_SRP_INDEX 137296341Sdelphij && !strcmp(id, pp[DB_srpid])) 138296341Sdelphij return i; 139296341Sdelphij } 140238384Sjkim 141296341Sdelphij return -1; 142296341Sdelphij} 143238384Sjkim 144238384Sjkimstatic void print_entry(CA_DB *db, BIO *bio, int indx, int verbose, char *s) 145296341Sdelphij{ 146296341Sdelphij if (indx >= 0 && verbose) { 147296341Sdelphij int j; 148296341Sdelphij char **pp = sk_OPENSSL_PSTRING_value(db->db->data, indx); 149296341Sdelphij BIO_printf(bio, "%s \"%s\"\n", s, pp[DB_srpid]); 150296341Sdelphij for (j = 0; j < DB_NUMBER; j++) { 151296341Sdelphij BIO_printf(bio_err, " %d = \"%s\"\n", j, pp[j]); 152296341Sdelphij } 153296341Sdelphij } 154296341Sdelphij} 155238384Sjkim 156238384Sjkimstatic void print_index(CA_DB *db, BIO *bio, int indexindex, int verbose) 157296341Sdelphij{ 158296341Sdelphij print_entry(db, bio, indexindex, verbose, "g N entry"); 159296341Sdelphij} 160238384Sjkim 161238384Sjkimstatic void print_user(CA_DB *db, BIO *bio, int userindex, int verbose) 162296341Sdelphij{ 163296341Sdelphij if (verbose > 0) { 164296341Sdelphij char **pp = sk_OPENSSL_PSTRING_value(db->db->data, userindex); 165238384Sjkim 166296341Sdelphij if (pp[DB_srptype][0] != 'I') { 167296341Sdelphij print_entry(db, bio, userindex, verbose, "User entry"); 168296341Sdelphij print_entry(db, bio, get_index(db, pp[DB_srpgN], 'I'), verbose, 169296341Sdelphij "g N entry"); 170296341Sdelphij } 171238384Sjkim 172296341Sdelphij } 173296341Sdelphij} 174238384Sjkim 175238384Sjkimstatic int update_index(CA_DB *db, BIO *bio, char **row) 176296341Sdelphij{ 177296341Sdelphij char **irow; 178296341Sdelphij int i; 179238384Sjkim 180296341Sdelphij if ((irow = 181296341Sdelphij (char **)OPENSSL_malloc(sizeof(char *) * (DB_NUMBER + 1))) == NULL) { 182296341Sdelphij BIO_printf(bio_err, "Memory allocation failure\n"); 183296341Sdelphij return 0; 184296341Sdelphij } 185238384Sjkim 186296341Sdelphij for (i = 0; i < DB_NUMBER; i++) { 187296341Sdelphij irow[i] = row[i]; 188296341Sdelphij row[i] = NULL; 189296341Sdelphij } 190296341Sdelphij irow[DB_NUMBER] = NULL; 191238384Sjkim 192296341Sdelphij if (!TXT_DB_insert(db->db, irow)) { 193296341Sdelphij BIO_printf(bio, "failed to update srpvfile\n"); 194296341Sdelphij BIO_printf(bio, "TXT_DB error number %ld\n", db->db->error); 195296341Sdelphij OPENSSL_free(irow); 196296341Sdelphij return 0; 197296341Sdelphij } 198296341Sdelphij return 1; 199296341Sdelphij} 200238384Sjkim 201238384Sjkimstatic void lookup_fail(const char *name, char *tag) 202296341Sdelphij{ 203296341Sdelphij BIO_printf(bio_err, "variable lookup failed for %s::%s\n", name, tag); 204296341Sdelphij} 205238384Sjkim 206238384Sjkimstatic char *srp_verify_user(const char *user, const char *srp_verifier, 207296341Sdelphij char *srp_usersalt, const char *g, const char *N, 208296341Sdelphij const char *passin, BIO *bio, int verbose) 209296341Sdelphij{ 210296341Sdelphij char password[1024]; 211296341Sdelphij PW_CB_DATA cb_tmp; 212296341Sdelphij char *verifier = NULL; 213296341Sdelphij char *gNid = NULL; 214238384Sjkim 215296341Sdelphij cb_tmp.prompt_info = user; 216296341Sdelphij cb_tmp.password = passin; 217238384Sjkim 218296341Sdelphij if (password_callback(password, 1024, 0, &cb_tmp) > 0) { 219296341Sdelphij VERBOSE BIO_printf(bio, 220296341Sdelphij "Validating\n user=\"%s\"\n srp_verifier=\"%s\"\n srp_usersalt=\"%s\"\n g=\"%s\"\n N=\"%s\"\n", 221296341Sdelphij user, srp_verifier, srp_usersalt, g, N); 222296341Sdelphij BIO_printf(bio, "Pass %s\n", password); 223238384Sjkim 224296341Sdelphij if (! 225296341Sdelphij (gNid = 226296341Sdelphij SRP_create_verifier(user, password, &srp_usersalt, &verifier, N, 227296341Sdelphij g))) { 228296341Sdelphij BIO_printf(bio, "Internal error validating SRP verifier\n"); 229296341Sdelphij } else { 230296341Sdelphij if (strcmp(verifier, srp_verifier)) 231296341Sdelphij gNid = NULL; 232296341Sdelphij OPENSSL_free(verifier); 233296341Sdelphij } 234296341Sdelphij } 235296341Sdelphij return gNid; 236296341Sdelphij} 237238384Sjkim 238238384Sjkimstatic char *srp_create_user(char *user, char **srp_verifier, 239296341Sdelphij char **srp_usersalt, char *g, char *N, 240296341Sdelphij char *passout, BIO *bio, int verbose) 241296341Sdelphij{ 242296341Sdelphij char password[1024]; 243296341Sdelphij PW_CB_DATA cb_tmp; 244296341Sdelphij char *gNid = NULL; 245296341Sdelphij char *salt = NULL; 246296341Sdelphij cb_tmp.prompt_info = user; 247296341Sdelphij cb_tmp.password = passout; 248238384Sjkim 249296341Sdelphij if (password_callback(password, 1024, 1, &cb_tmp) > 0) { 250296341Sdelphij VERBOSE BIO_printf(bio, 251296341Sdelphij "Creating\n user=\"%s\"\n g=\"%s\"\n N=\"%s\"\n", 252296341Sdelphij user, g, N); 253296341Sdelphij if (! 254296341Sdelphij (gNid = 255296341Sdelphij SRP_create_verifier(user, password, &salt, srp_verifier, N, 256296341Sdelphij g))) { 257296341Sdelphij BIO_printf(bio, "Internal error creating SRP verifier\n"); 258296341Sdelphij } else 259296341Sdelphij *srp_usersalt = salt; 260296341Sdelphij VVERBOSE BIO_printf(bio, "gNid=%s salt =\"%s\"\n verifier =\"%s\"\n", 261296341Sdelphij gNid, salt, *srp_verifier); 262238384Sjkim 263296341Sdelphij } 264296341Sdelphij return gNid; 265296341Sdelphij} 266238384Sjkim 267238384Sjkimint MAIN(int argc, char **argv) 268296341Sdelphij{ 269296341Sdelphij int add_user = 0; 270296341Sdelphij int list_user = 0; 271296341Sdelphij int delete_user = 0; 272296341Sdelphij int modify_user = 0; 273296341Sdelphij char *user = NULL; 274238384Sjkim 275296341Sdelphij char *passargin = NULL, *passargout = NULL; 276296341Sdelphij char *passin = NULL, *passout = NULL; 277296341Sdelphij char *gN = NULL; 278296341Sdelphij int gNindex = -1; 279296341Sdelphij char **gNrow = NULL; 280296341Sdelphij int maxgN = -1; 281238384Sjkim 282296341Sdelphij char *userinfo = NULL; 283238384Sjkim 284296341Sdelphij int badops = 0; 285296341Sdelphij int ret = 1; 286296341Sdelphij int errors = 0; 287296341Sdelphij int verbose = 0; 288296341Sdelphij int doupdatedb = 0; 289296341Sdelphij char *configfile = NULL; 290296341Sdelphij char *dbfile = NULL; 291296341Sdelphij CA_DB *db = NULL; 292296341Sdelphij char **pp; 293296341Sdelphij int i; 294296341Sdelphij long errorline = -1; 295296341Sdelphij char *randfile = NULL; 296296341Sdelphij# ifndef OPENSSL_NO_ENGINE 297296341Sdelphij char *engine = NULL; 298296341Sdelphij# endif 299296341Sdelphij char *tofree = NULL; 300296341Sdelphij DB_ATTR db_attr; 301238384Sjkim 302296341Sdelphij# ifdef EFENCE 303296341Sdelphij EF_PROTECT_FREE = 1; 304296341Sdelphij EF_PROTECT_BELOW = 1; 305296341Sdelphij EF_ALIGNMENT = 0; 306296341Sdelphij# endif 307238384Sjkim 308296341Sdelphij apps_startup(); 309238384Sjkim 310296341Sdelphij conf = NULL; 311296341Sdelphij section = NULL; 312238384Sjkim 313296341Sdelphij if (bio_err == NULL) 314296341Sdelphij if ((bio_err = BIO_new(BIO_s_file())) != NULL) 315296341Sdelphij BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); 316238384Sjkim 317296341Sdelphij argc--; 318296341Sdelphij argv++; 319296341Sdelphij while (argc >= 1 && badops == 0) { 320296341Sdelphij if (strcmp(*argv, "-verbose") == 0) 321296341Sdelphij verbose++; 322296341Sdelphij else if (strcmp(*argv, "-config") == 0) { 323296341Sdelphij if (--argc < 1) 324296341Sdelphij goto bad; 325296341Sdelphij configfile = *(++argv); 326296341Sdelphij } else if (strcmp(*argv, "-name") == 0) { 327296341Sdelphij if (--argc < 1) 328296341Sdelphij goto bad; 329296341Sdelphij section = *(++argv); 330296341Sdelphij } else if (strcmp(*argv, "-srpvfile") == 0) { 331296341Sdelphij if (--argc < 1) 332296341Sdelphij goto bad; 333296341Sdelphij dbfile = *(++argv); 334296341Sdelphij } else if (strcmp(*argv, "-add") == 0) 335296341Sdelphij add_user = 1; 336296341Sdelphij else if (strcmp(*argv, "-delete") == 0) 337296341Sdelphij delete_user = 1; 338296341Sdelphij else if (strcmp(*argv, "-modify") == 0) 339296341Sdelphij modify_user = 1; 340296341Sdelphij else if (strcmp(*argv, "-list") == 0) 341296341Sdelphij list_user = 1; 342296341Sdelphij else if (strcmp(*argv, "-gn") == 0) { 343296341Sdelphij if (--argc < 1) 344296341Sdelphij goto bad; 345296341Sdelphij gN = *(++argv); 346296341Sdelphij } else if (strcmp(*argv, "-userinfo") == 0) { 347296341Sdelphij if (--argc < 1) 348296341Sdelphij goto bad; 349296341Sdelphij userinfo = *(++argv); 350296341Sdelphij } else if (strcmp(*argv, "-passin") == 0) { 351296341Sdelphij if (--argc < 1) 352296341Sdelphij goto bad; 353296341Sdelphij passargin = *(++argv); 354296341Sdelphij } else if (strcmp(*argv, "-passout") == 0) { 355296341Sdelphij if (--argc < 1) 356296341Sdelphij goto bad; 357296341Sdelphij passargout = *(++argv); 358296341Sdelphij } 359296341Sdelphij# ifndef OPENSSL_NO_ENGINE 360296341Sdelphij else if (strcmp(*argv, "-engine") == 0) { 361296341Sdelphij if (--argc < 1) 362296341Sdelphij goto bad; 363296341Sdelphij engine = *(++argv); 364296341Sdelphij } 365296341Sdelphij# endif 366238384Sjkim 367296341Sdelphij else if (**argv == '-') { 368296341Sdelphij bad: 369296341Sdelphij BIO_printf(bio_err, "unknown option %s\n", *argv); 370296341Sdelphij badops = 1; 371296341Sdelphij break; 372296341Sdelphij } else 373296341Sdelphij break; 374238384Sjkim 375296341Sdelphij argc--; 376296341Sdelphij argv++; 377296341Sdelphij } 378238384Sjkim 379296341Sdelphij if (dbfile && configfile) { 380296341Sdelphij BIO_printf(bio_err, 381296341Sdelphij "-dbfile and -configfile cannot be specified together.\n"); 382296341Sdelphij badops = 1; 383296341Sdelphij } 384296341Sdelphij if (add_user + delete_user + modify_user + list_user != 1) { 385296341Sdelphij BIO_printf(bio_err, 386296341Sdelphij "Exactly one of the options -add, -delete, -modify -list must be specified.\n"); 387296341Sdelphij badops = 1; 388296341Sdelphij } 389296341Sdelphij if (delete_user + modify_user + delete_user == 1 && argc <= 0) { 390296341Sdelphij BIO_printf(bio_err, 391296341Sdelphij "Need at least one user for options -add, -delete, -modify. \n"); 392296341Sdelphij badops = 1; 393296341Sdelphij } 394296341Sdelphij if ((passin || passout) && argc != 1) { 395296341Sdelphij BIO_printf(bio_err, 396296341Sdelphij "-passin, -passout arguments only valid with one user.\n"); 397296341Sdelphij badops = 1; 398296341Sdelphij } 399238384Sjkim 400296341Sdelphij if (badops) { 401296341Sdelphij for (pp = srp_usage; (*pp != NULL); pp++) 402296341Sdelphij BIO_printf(bio_err, "%s", *pp); 403238384Sjkim 404296341Sdelphij BIO_printf(bio_err, " -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, 405296341Sdelphij LIST_SEPARATOR_CHAR); 406296341Sdelphij BIO_printf(bio_err, 407296341Sdelphij " load the file (or the files in the directory) into\n"); 408296341Sdelphij BIO_printf(bio_err, " the random number generator\n"); 409296341Sdelphij goto err; 410296341Sdelphij } 411238384Sjkim 412296341Sdelphij ERR_load_crypto_strings(); 413238384Sjkim 414296341Sdelphij# ifndef OPENSSL_NO_ENGINE 415296341Sdelphij setup_engine(bio_err, engine, 0); 416296341Sdelphij# endif 417238384Sjkim 418296341Sdelphij if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) { 419296341Sdelphij BIO_printf(bio_err, "Error getting passwords\n"); 420296341Sdelphij goto err; 421296341Sdelphij } 422238384Sjkim 423296341Sdelphij if (!dbfile) { 424238384Sjkim 425296341Sdelphij /*****************************************************************/ 426296341Sdelphij tofree = NULL; 427296341Sdelphij if (configfile == NULL) 428296341Sdelphij configfile = getenv("OPENSSL_CONF"); 429296341Sdelphij if (configfile == NULL) 430296341Sdelphij configfile = getenv("SSLEAY_CONF"); 431296341Sdelphij if (configfile == NULL) { 432296341Sdelphij const char *s = X509_get_default_cert_area(); 433296341Sdelphij size_t len; 434238384Sjkim 435296341Sdelphij# ifdef OPENSSL_SYS_VMS 436296341Sdelphij len = strlen(s) + sizeof(CONFIG_FILE); 437296341Sdelphij tofree = OPENSSL_malloc(len); 438296341Sdelphij if (!tofree) { 439296341Sdelphij BIO_printf(bio_err, "Out of memory\n"); 440296341Sdelphij goto err; 441296341Sdelphij } 442296341Sdelphij strcpy(tofree, s); 443296341Sdelphij# else 444296341Sdelphij len = strlen(s) + sizeof(CONFIG_FILE) + 1; 445296341Sdelphij tofree = OPENSSL_malloc(len); 446296341Sdelphij if (!tofree) { 447296341Sdelphij BIO_printf(bio_err, "Out of memory\n"); 448296341Sdelphij goto err; 449296341Sdelphij } 450296341Sdelphij BUF_strlcpy(tofree, s, len); 451296341Sdelphij BUF_strlcat(tofree, "/", len); 452296341Sdelphij# endif 453296341Sdelphij BUF_strlcat(tofree, CONFIG_FILE, len); 454296341Sdelphij configfile = tofree; 455296341Sdelphij } 456238384Sjkim 457296341Sdelphij VERBOSE BIO_printf(bio_err, "Using configuration from %s\n", 458296341Sdelphij configfile); 459296341Sdelphij conf = NCONF_new(NULL); 460296341Sdelphij if (NCONF_load(conf, configfile, &errorline) <= 0) { 461296341Sdelphij if (errorline <= 0) 462296341Sdelphij BIO_printf(bio_err, "error loading the config file '%s'\n", 463296341Sdelphij configfile); 464296341Sdelphij else 465296341Sdelphij BIO_printf(bio_err, "error on line %ld of config file '%s'\n", 466296341Sdelphij errorline, configfile); 467296341Sdelphij goto err; 468296341Sdelphij } 469296341Sdelphij if (tofree) { 470296341Sdelphij OPENSSL_free(tofree); 471296341Sdelphij tofree = NULL; 472296341Sdelphij } 473238384Sjkim 474296341Sdelphij if (!load_config(bio_err, conf)) 475296341Sdelphij goto err; 476238384Sjkim 477296341Sdelphij /* Lets get the config section we are using */ 478296341Sdelphij if (section == NULL) { 479296341Sdelphij VERBOSE BIO_printf(bio_err, 480296341Sdelphij "trying to read " ENV_DEFAULT_SRP 481296341Sdelphij " in \" BASE_SECTION \"\n"); 482238384Sjkim 483296341Sdelphij section = NCONF_get_string(conf, BASE_SECTION, ENV_DEFAULT_SRP); 484296341Sdelphij if (section == NULL) { 485296341Sdelphij lookup_fail(BASE_SECTION, ENV_DEFAULT_SRP); 486296341Sdelphij goto err; 487296341Sdelphij } 488296341Sdelphij } 489238384Sjkim 490296341Sdelphij if (randfile == NULL && conf) 491296341Sdelphij randfile = NCONF_get_string(conf, BASE_SECTION, "RANDFILE"); 492238384Sjkim 493296341Sdelphij VERBOSE BIO_printf(bio_err, 494296341Sdelphij "trying to read " ENV_DATABASE 495296341Sdelphij " in section \"%s\"\n", section); 496238384Sjkim 497296341Sdelphij if ((dbfile = NCONF_get_string(conf, section, ENV_DATABASE)) == NULL) { 498296341Sdelphij lookup_fail(section, ENV_DATABASE); 499296341Sdelphij goto err; 500296341Sdelphij } 501238384Sjkim 502296341Sdelphij } 503296341Sdelphij if (randfile == NULL) 504296341Sdelphij ERR_clear_error(); 505296341Sdelphij else 506296341Sdelphij app_RAND_load_file(randfile, bio_err, 0); 507238384Sjkim 508296341Sdelphij VERBOSE BIO_printf(bio_err, "Trying to read SRP verifier file \"%s\"\n", 509296341Sdelphij dbfile); 510238384Sjkim 511296341Sdelphij db = load_index(dbfile, &db_attr); 512296341Sdelphij if (db == NULL) 513296341Sdelphij goto err; 514238384Sjkim 515296341Sdelphij /* Lets check some fields */ 516296341Sdelphij for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) { 517296341Sdelphij pp = sk_OPENSSL_PSTRING_value(db->db->data, i); 518238384Sjkim 519296341Sdelphij if (pp[DB_srptype][0] == DB_SRP_INDEX) { 520296341Sdelphij maxgN = i; 521296341Sdelphij if (gNindex < 0 && gN != NULL && !strcmp(gN, pp[DB_srpid])) 522296341Sdelphij gNindex = i; 523238384Sjkim 524296341Sdelphij print_index(db, bio_err, i, verbose > 1); 525296341Sdelphij } 526296341Sdelphij } 527238384Sjkim 528296341Sdelphij VERBOSE BIO_printf(bio_err, "Database initialised\n"); 529238384Sjkim 530296341Sdelphij if (gNindex >= 0) { 531296341Sdelphij gNrow = sk_OPENSSL_PSTRING_value(db->db->data, gNindex); 532296341Sdelphij print_entry(db, bio_err, gNindex, verbose > 1, "Default g and N"); 533296341Sdelphij } else if (maxgN > 0 && !SRP_get_default_gN(gN)) { 534296341Sdelphij BIO_printf(bio_err, "No g and N value for index \"%s\"\n", gN); 535296341Sdelphij goto err; 536296341Sdelphij } else { 537296341Sdelphij VERBOSE BIO_printf(bio_err, "Database has no g N information.\n"); 538296341Sdelphij gNrow = NULL; 539296341Sdelphij } 540238384Sjkim 541296341Sdelphij VVERBOSE BIO_printf(bio_err, "Starting user processing\n"); 542238384Sjkim 543296341Sdelphij if (argc > 0) 544296341Sdelphij user = *(argv++); 545238384Sjkim 546296341Sdelphij while (list_user || user) { 547296341Sdelphij int userindex = -1; 548296341Sdelphij if (user) 549296341Sdelphij VVERBOSE BIO_printf(bio_err, "Processing user \"%s\"\n", user); 550296341Sdelphij if ((userindex = get_index(db, user, 'U')) >= 0) { 551296341Sdelphij print_user(db, bio_err, userindex, (verbose > 0) || list_user); 552296341Sdelphij } 553238384Sjkim 554296341Sdelphij if (list_user) { 555296341Sdelphij if (user == NULL) { 556296341Sdelphij BIO_printf(bio_err, "List all users\n"); 557238384Sjkim 558296341Sdelphij for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) { 559296341Sdelphij print_user(db, bio_err, i, 1); 560296341Sdelphij } 561296341Sdelphij list_user = 0; 562296341Sdelphij } else if (userindex < 0) { 563296341Sdelphij BIO_printf(bio_err, 564296341Sdelphij "user \"%s\" does not exist, ignored. t\n", user); 565296341Sdelphij errors++; 566296341Sdelphij } 567296341Sdelphij } else if (add_user) { 568296341Sdelphij if (userindex >= 0) { 569296341Sdelphij /* reactivation of a new user */ 570296341Sdelphij char **row = 571296341Sdelphij sk_OPENSSL_PSTRING_value(db->db->data, userindex); 572296341Sdelphij BIO_printf(bio_err, "user \"%s\" reactivated.\n", user); 573296341Sdelphij row[DB_srptype][0] = 'V'; 574238384Sjkim 575296341Sdelphij doupdatedb = 1; 576296341Sdelphij } else { 577296341Sdelphij char *row[DB_NUMBER]; 578296341Sdelphij char *gNid; 579296341Sdelphij row[DB_srpverifier] = NULL; 580296341Sdelphij row[DB_srpsalt] = NULL; 581296341Sdelphij row[DB_srpinfo] = NULL; 582296341Sdelphij if (! 583296341Sdelphij (gNid = 584296341Sdelphij srp_create_user(user, &(row[DB_srpverifier]), 585296341Sdelphij &(row[DB_srpsalt]), 586296341Sdelphij gNrow ? gNrow[DB_srpsalt] : gN, 587296341Sdelphij gNrow ? gNrow[DB_srpverifier] : NULL, 588296341Sdelphij passout, bio_err, verbose))) { 589296341Sdelphij BIO_printf(bio_err, 590296341Sdelphij "Cannot create srp verifier for user \"%s\", operation abandoned .\n", 591296341Sdelphij user); 592296341Sdelphij errors++; 593296341Sdelphij goto err; 594296341Sdelphij } 595296341Sdelphij row[DB_srpid] = BUF_strdup(user); 596296341Sdelphij row[DB_srptype] = BUF_strdup("v"); 597296341Sdelphij row[DB_srpgN] = BUF_strdup(gNid); 598238384Sjkim 599296341Sdelphij if (!row[DB_srpid] || !row[DB_srpgN] || !row[DB_srptype] 600296341Sdelphij || !row[DB_srpverifier] || !row[DB_srpsalt] || (userinfo 601296341Sdelphij && 602296341Sdelphij (!(row 603296341Sdelphij [DB_srpinfo] 604296341Sdelphij = 605296341Sdelphij BUF_strdup 606296341Sdelphij (userinfo)))) 607296341Sdelphij || !update_index(db, bio_err, row)) { 608296341Sdelphij if (row[DB_srpid]) 609296341Sdelphij OPENSSL_free(row[DB_srpid]); 610296341Sdelphij if (row[DB_srpgN]) 611296341Sdelphij OPENSSL_free(row[DB_srpgN]); 612296341Sdelphij if (row[DB_srpinfo]) 613296341Sdelphij OPENSSL_free(row[DB_srpinfo]); 614296341Sdelphij if (row[DB_srptype]) 615296341Sdelphij OPENSSL_free(row[DB_srptype]); 616296341Sdelphij if (row[DB_srpverifier]) 617296341Sdelphij OPENSSL_free(row[DB_srpverifier]); 618296341Sdelphij if (row[DB_srpsalt]) 619296341Sdelphij OPENSSL_free(row[DB_srpsalt]); 620296341Sdelphij goto err; 621296341Sdelphij } 622296341Sdelphij doupdatedb = 1; 623296341Sdelphij } 624296341Sdelphij } else if (modify_user) { 625296341Sdelphij if (userindex < 0) { 626296341Sdelphij BIO_printf(bio_err, 627296341Sdelphij "user \"%s\" does not exist, operation ignored.\n", 628296341Sdelphij user); 629296341Sdelphij errors++; 630296341Sdelphij } else { 631238384Sjkim 632296341Sdelphij char **row = 633296341Sdelphij sk_OPENSSL_PSTRING_value(db->db->data, userindex); 634296341Sdelphij char type = row[DB_srptype][0]; 635296341Sdelphij if (type == 'v') { 636296341Sdelphij BIO_printf(bio_err, 637296341Sdelphij "user \"%s\" already updated, operation ignored.\n", 638296341Sdelphij user); 639296341Sdelphij errors++; 640296341Sdelphij } else { 641296341Sdelphij char *gNid; 642238384Sjkim 643296341Sdelphij if (row[DB_srptype][0] == 'V') { 644296341Sdelphij int user_gN; 645296341Sdelphij char **irow = NULL; 646296341Sdelphij VERBOSE BIO_printf(bio_err, 647296341Sdelphij "Verifying password for user \"%s\"\n", 648296341Sdelphij user); 649296341Sdelphij if ((user_gN = 650296341Sdelphij get_index(db, row[DB_srpgN], DB_SRP_INDEX)) >= 0) 651296341Sdelphij irow = 652296341Sdelphij (char **)sk_OPENSSL_PSTRING_value(db-> 653296341Sdelphij db->data, 654296341Sdelphij userindex); 655238384Sjkim 656296341Sdelphij if (!srp_verify_user 657296341Sdelphij (user, row[DB_srpverifier], row[DB_srpsalt], 658296341Sdelphij irow ? irow[DB_srpsalt] : row[DB_srpgN], 659296341Sdelphij irow ? irow[DB_srpverifier] : NULL, passin, 660296341Sdelphij bio_err, verbose)) { 661296341Sdelphij BIO_printf(bio_err, 662296341Sdelphij "Invalid password for user \"%s\", operation abandoned.\n", 663296341Sdelphij user); 664296341Sdelphij errors++; 665296341Sdelphij goto err; 666296341Sdelphij } 667296341Sdelphij } 668296341Sdelphij VERBOSE BIO_printf(bio_err, 669296341Sdelphij "Password for user \"%s\" ok.\n", 670296341Sdelphij user); 671238384Sjkim 672296341Sdelphij if (! 673296341Sdelphij (gNid = 674296341Sdelphij srp_create_user(user, &(row[DB_srpverifier]), 675296341Sdelphij &(row[DB_srpsalt]), 676296341Sdelphij gNrow ? gNrow[DB_srpsalt] : NULL, 677296341Sdelphij gNrow ? gNrow[DB_srpverifier] : NULL, 678296341Sdelphij passout, bio_err, verbose))) { 679296341Sdelphij BIO_printf(bio_err, 680296341Sdelphij "Cannot create srp verifier for user \"%s\", operation abandoned.\n", 681296341Sdelphij user); 682296341Sdelphij errors++; 683296341Sdelphij goto err; 684296341Sdelphij } 685238384Sjkim 686296341Sdelphij row[DB_srptype][0] = 'v'; 687296341Sdelphij row[DB_srpgN] = BUF_strdup(gNid); 688238384Sjkim 689296341Sdelphij if (!row[DB_srpid] || !row[DB_srpgN] || !row[DB_srptype] 690296341Sdelphij || !row[DB_srpverifier] || !row[DB_srpsalt] 691296341Sdelphij || (userinfo 692296341Sdelphij && (!(row[DB_srpinfo] = BUF_strdup(userinfo))))) 693296341Sdelphij goto err; 694238384Sjkim 695296341Sdelphij doupdatedb = 1; 696296341Sdelphij } 697296341Sdelphij } 698296341Sdelphij } else if (delete_user) { 699296341Sdelphij if (userindex < 0) { 700296341Sdelphij BIO_printf(bio_err, 701296341Sdelphij "user \"%s\" does not exist, operation ignored. t\n", 702296341Sdelphij user); 703296341Sdelphij errors++; 704296341Sdelphij } else { 705296341Sdelphij char **xpp = 706296341Sdelphij sk_OPENSSL_PSTRING_value(db->db->data, userindex); 707296341Sdelphij BIO_printf(bio_err, "user \"%s\" revoked. t\n", user); 708238384Sjkim 709296341Sdelphij xpp[DB_srptype][0] = 'R'; 710238384Sjkim 711296341Sdelphij doupdatedb = 1; 712296341Sdelphij } 713296341Sdelphij } 714296341Sdelphij if (--argc > 0) 715296341Sdelphij user = *(argv++); 716296341Sdelphij else { 717296341Sdelphij user = NULL; 718296341Sdelphij list_user = 0; 719296341Sdelphij } 720296341Sdelphij } 721238384Sjkim 722296341Sdelphij VERBOSE BIO_printf(bio_err, "User procession done.\n"); 723238384Sjkim 724296341Sdelphij if (doupdatedb) { 725296341Sdelphij /* Lets check some fields */ 726296341Sdelphij for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) { 727296341Sdelphij pp = sk_OPENSSL_PSTRING_value(db->db->data, i); 728238384Sjkim 729296341Sdelphij if (pp[DB_srptype][0] == 'v') { 730296341Sdelphij pp[DB_srptype][0] = 'V'; 731296341Sdelphij print_user(db, bio_err, i, verbose); 732296341Sdelphij } 733296341Sdelphij } 734238384Sjkim 735296341Sdelphij VERBOSE BIO_printf(bio_err, "Trying to update srpvfile.\n"); 736296341Sdelphij if (!save_index(dbfile, "new", db)) 737296341Sdelphij goto err; 738238384Sjkim 739296341Sdelphij VERBOSE BIO_printf(bio_err, "Temporary srpvfile created.\n"); 740296341Sdelphij if (!rotate_index(dbfile, "new", "old")) 741296341Sdelphij goto err; 742296341Sdelphij 743296341Sdelphij VERBOSE BIO_printf(bio_err, "srpvfile updated.\n"); 744296341Sdelphij } 745296341Sdelphij 746296341Sdelphij ret = (errors != 0); 747296341Sdelphij err: 748296341Sdelphij if (errors != 0) 749296341Sdelphij VERBOSE BIO_printf(bio_err, "User errors %d.\n", errors); 750296341Sdelphij 751296341Sdelphij VERBOSE BIO_printf(bio_err, "SRP terminating with code %d.\n", ret); 752296341Sdelphij if (tofree) 753296341Sdelphij OPENSSL_free(tofree); 754296341Sdelphij if (ret) 755296341Sdelphij ERR_print_errors(bio_err); 756296341Sdelphij if (randfile) 757296341Sdelphij app_RAND_write_file(randfile, bio_err); 758296341Sdelphij if (conf) 759296341Sdelphij NCONF_free(conf); 760296341Sdelphij if (db) 761296341Sdelphij free_index(db); 762296341Sdelphij 763296341Sdelphij OBJ_cleanup(); 764296341Sdelphij apps_shutdown(); 765296341Sdelphij OPENSSL_EXIT(ret); 766296341Sdelphij} 767296341Sdelphij 768238384Sjkim#endif 769