srp.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763
  1. /* apps/srp.c */
  2. /* Written by Peter Sylvester (peter.sylvester@edelweb.fr)
  3. * for the EdelKey project and contributed to the OpenSSL project 2004.
  4. */
  5. /* ====================================================================
  6. * Copyright (c) 2004 The OpenSSL Project. All rights reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. *
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in
  17. * the documentation and/or other materials provided with the
  18. * distribution.
  19. *
  20. * 3. All advertising materials mentioning features or use of this
  21. * software must display the following acknowledgment:
  22. * "This product includes software developed by the OpenSSL Project
  23. * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
  24. *
  25. * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
  26. * endorse or promote products derived from this software without
  27. * prior written permission. For written permission, please contact
  28. * licensing@OpenSSL.org.
  29. *
  30. * 5. Products derived from this software may not be called "OpenSSL"
  31. * nor may "OpenSSL" appear in their names without prior written
  32. * permission of the OpenSSL Project.
  33. *
  34. * 6. Redistributions of any form whatsoever must retain the following
  35. * acknowledgment:
  36. * "This product includes software developed by the OpenSSL Project
  37. * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
  38. *
  39. * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
  40. * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  41. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  42. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
  43. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  44. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  45. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  46. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  47. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  48. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  49. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  50. * OF THE POSSIBILITY OF SUCH DAMAGE.
  51. * ====================================================================
  52. *
  53. * This product includes cryptographic software written by Eric Young
  54. * (eay@cryptsoft.com). This product includes software written by Tim
  55. * Hudson (tjh@cryptsoft.com).
  56. *
  57. */
  58. #include <openssl/opensslconf.h>
  59. #ifndef OPENSSL_NO_SRP
  60. #include <stdio.h>
  61. #include <stdlib.h>
  62. #include <string.h>
  63. #include <openssl/conf.h>
  64. #include <openssl/bio.h>
  65. #include <openssl/err.h>
  66. #include <openssl/txt_db.h>
  67. #include <openssl/buffer.h>
  68. #include <openssl/srp.h>
  69. #include "apps.h"
  70. #undef PROG
  71. #define PROG srp_main
  72. #define BASE_SECTION "srp"
  73. #define CONFIG_FILE "openssl.cnf"
  74. #define ENV_RANDFILE "RANDFILE"
  75. #define ENV_DATABASE "srpvfile"
  76. #define ENV_DEFAULT_SRP "default_srp"
  77. static char *srp_usage[]={
  78. "usage: srp [args] [user] \n",
  79. "\n",
  80. " -verbose Talk alot while doing things\n",
  81. " -config file A config file\n",
  82. " -name arg The particular srp definition to use\n",
  83. " -srpvfile arg The srp verifier file name\n",
  84. " -add add an user and srp verifier\n",
  85. " -modify modify the srp verifier of an existing user\n",
  86. " -delete delete user from verifier file\n",
  87. " -list list user\n",
  88. " -gn arg g and N values to be used for new verifier\n",
  89. " -userinfo arg additional info to be set for user\n",
  90. " -passin arg input file pass phrase source\n",
  91. " -passout arg output file pass phrase source\n",
  92. #ifndef OPENSSL_NO_ENGINE
  93. " -engine e - use engine e, possibly a hardware device.\n",
  94. #endif
  95. NULL
  96. };
  97. #ifdef EFENCE
  98. extern int EF_PROTECT_FREE;
  99. extern int EF_PROTECT_BELOW;
  100. extern int EF_ALIGNMENT;
  101. #endif
  102. static CONF *conf=NULL;
  103. static char *section=NULL;
  104. #define VERBOSE if (verbose)
  105. #define VVERBOSE if (verbose>1)
  106. int MAIN(int, char **);
  107. static int get_index(CA_DB *db, char* id, char type)
  108. {
  109. char ** pp;
  110. int i;
  111. if (id == NULL) return -1;
  112. if (type == DB_SRP_INDEX)
  113. for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++)
  114. {
  115. pp=sk_OPENSSL_PSTRING_value(db->db->data,i);
  116. if (pp[DB_srptype][0] == DB_SRP_INDEX && !strcmp(id,pp[DB_srpid]))
  117. return i;
  118. }
  119. else for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++)
  120. {
  121. pp=sk_OPENSSL_PSTRING_value(db->db->data,i);
  122. if (pp[DB_srptype][0] != DB_SRP_INDEX && !strcmp(id,pp[DB_srpid]))
  123. return i;
  124. }
  125. return -1 ;
  126. }
  127. static void print_entry(CA_DB *db, BIO * bio, int indx, int verbose, char * s)
  128. {
  129. if (indx >= 0 && verbose)
  130. {
  131. int j;
  132. char **pp=sk_OPENSSL_PSTRING_value(db->db->data,indx);
  133. BIO_printf(bio,"%s \"%s\"\n",s,pp[DB_srpid]);
  134. for (j = 0; j < DB_NUMBER; j++)
  135. {
  136. BIO_printf(bio_err," %d = \"%s\"\n",j,pp[j]);
  137. }
  138. }
  139. }
  140. static void print_index(CA_DB *db, BIO * bio, int indexindex, int verbose)
  141. {
  142. print_entry(db,bio,indexindex, verbose, "g N entry") ;
  143. }
  144. static void print_user(CA_DB *db, BIO * bio, int userindex, int verbose)
  145. {
  146. if (verbose > 0)
  147. {
  148. char **pp= sk_OPENSSL_PSTRING_value(db->db->data,userindex);
  149. if (pp[DB_srptype][0] != 'I')
  150. {
  151. print_entry(db,bio,userindex, verbose, "User entry");
  152. print_entry(db,bio,get_index(db, pp[DB_srpgN],'I'),verbose,"g N entry") ;
  153. }
  154. }
  155. }
  156. static int update_index(CA_DB *db, BIO * bio, char ** row)
  157. {
  158. char ** irow;
  159. int i;
  160. if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
  161. {
  162. BIO_printf(bio_err,"Memory allocation failure\n");
  163. return 0;
  164. }
  165. for (i=0; i<DB_NUMBER; i++)
  166. {
  167. irow[i]=row[i];
  168. row[i]=NULL;
  169. }
  170. irow[DB_NUMBER]=NULL;
  171. if (!TXT_DB_insert(db->db,irow))
  172. {
  173. BIO_printf(bio,"failed to update srpvfile\n");
  174. BIO_printf(bio,"TXT_DB error number %ld\n",db->db->error);
  175. OPENSSL_free(irow);
  176. return 0;
  177. }
  178. return 1;
  179. }
  180. static void lookup_fail(const char *name, const char *tag)
  181. {
  182. BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag);
  183. }
  184. static char *srp_verify_user(const char *user, const char *srp_verifier,
  185. char *srp_usersalt, const char *g,
  186. const char * N, const char *passin, BIO *bio,
  187. int verbose)
  188. {
  189. char password[1024];
  190. PW_CB_DATA cb_tmp;
  191. char *verifier = NULL;
  192. char *gNid = NULL;
  193. cb_tmp.prompt_info = user;
  194. cb_tmp.password = passin;
  195. if (password_callback(password, 1024, 0, &cb_tmp) >0)
  196. {
  197. 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);
  198. BIO_printf(bio,"Pass %s\n",password);
  199. OPENSSL_assert(srp_usersalt != NULL);
  200. if (!(gNid=SRP_create_verifier(user, password, &srp_usersalt, &verifier,
  201. N, g)))
  202. {
  203. BIO_printf(bio,"Internal error validating SRP verifier\n");
  204. }
  205. else
  206. {
  207. if (strcmp(verifier, srp_verifier))
  208. gNid = NULL;
  209. OPENSSL_free(verifier);
  210. }
  211. }
  212. return gNid;
  213. }
  214. static char *srp_create_user(char * user, char **srp_verifier,
  215. char **srp_usersalt,char *g, char *N,
  216. char *passout, BIO *bio, int verbose)
  217. {
  218. char password[1024];
  219. PW_CB_DATA cb_tmp;
  220. char *gNid = NULL;
  221. char *salt = NULL;
  222. cb_tmp.prompt_info = user;
  223. cb_tmp.password = passout;
  224. if (password_callback(password,1024,1,&cb_tmp) >0)
  225. {
  226. VERBOSE BIO_printf(bio,"Creating\n user=\"%s\"\n g=\"%s\"\n N=\"%s\"\n",user,g,N);
  227. if (!(gNid =SRP_create_verifier(user, password, &salt, srp_verifier, N, g)))
  228. {
  229. BIO_printf(bio,"Internal error creating SRP verifier\n");
  230. }
  231. else
  232. *srp_usersalt = salt;
  233. VVERBOSE BIO_printf(bio,"gNid=%s salt =\"%s\"\n verifier =\"%s\"\n", gNid,salt, *srp_verifier);
  234. }
  235. return gNid;
  236. }
  237. int MAIN(int argc, char **argv)
  238. {
  239. int add_user = 0;
  240. int list_user= 0;
  241. int delete_user= 0;
  242. int modify_user= 0;
  243. char * user = NULL;
  244. char *passargin = NULL, *passargout = NULL;
  245. char *passin = NULL, *passout = NULL;
  246. char * gN = NULL;
  247. int gNindex = -1;
  248. char ** gNrow = NULL;
  249. int maxgN = -1;
  250. char * userinfo = NULL;
  251. int badops=0;
  252. int ret=1;
  253. int errors=0;
  254. int verbose=0;
  255. int doupdatedb=0;
  256. char *configfile=NULL;
  257. char *dbfile=NULL;
  258. CA_DB *db=NULL;
  259. char **pp ;
  260. int i;
  261. long errorline = -1;
  262. char *randfile=NULL;
  263. #ifndef OPENSSL_NO_ENGINE
  264. char *engine = NULL;
  265. #endif
  266. char *tofree=NULL;
  267. DB_ATTR db_attr;
  268. #ifdef EFENCE
  269. EF_PROTECT_FREE=1;
  270. EF_PROTECT_BELOW=1;
  271. EF_ALIGNMENT=0;
  272. #endif
  273. apps_startup();
  274. conf = NULL;
  275. section = NULL;
  276. if (bio_err == NULL)
  277. if ((bio_err=BIO_new(BIO_s_file())) != NULL)
  278. BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
  279. argc--;
  280. argv++;
  281. while (argc >= 1 && badops == 0)
  282. {
  283. if (strcmp(*argv,"-verbose") == 0)
  284. verbose++;
  285. else if (strcmp(*argv,"-config") == 0)
  286. {
  287. if (--argc < 1) goto bad;
  288. configfile= *(++argv);
  289. }
  290. else if (strcmp(*argv,"-name") == 0)
  291. {
  292. if (--argc < 1) goto bad;
  293. section= *(++argv);
  294. }
  295. else if (strcmp(*argv,"-srpvfile") == 0)
  296. {
  297. if (--argc < 1) goto bad;
  298. dbfile= *(++argv);
  299. }
  300. else if (strcmp(*argv,"-add") == 0)
  301. add_user=1;
  302. else if (strcmp(*argv,"-delete") == 0)
  303. delete_user=1;
  304. else if (strcmp(*argv,"-modify") == 0)
  305. modify_user=1;
  306. else if (strcmp(*argv,"-list") == 0)
  307. list_user=1;
  308. else if (strcmp(*argv,"-gn") == 0)
  309. {
  310. if (--argc < 1) goto bad;
  311. gN= *(++argv);
  312. }
  313. else if (strcmp(*argv,"-userinfo") == 0)
  314. {
  315. if (--argc < 1) goto bad;
  316. userinfo= *(++argv);
  317. }
  318. else if (strcmp(*argv,"-passin") == 0)
  319. {
  320. if (--argc < 1) goto bad;
  321. passargin= *(++argv);
  322. }
  323. else if (strcmp(*argv,"-passout") == 0)
  324. {
  325. if (--argc < 1) goto bad;
  326. passargout= *(++argv);
  327. }
  328. #ifndef OPENSSL_NO_ENGINE
  329. else if (strcmp(*argv,"-engine") == 0)
  330. {
  331. if (--argc < 1) goto bad;
  332. engine= *(++argv);
  333. }
  334. #endif
  335. else if (**argv == '-')
  336. {
  337. bad:
  338. BIO_printf(bio_err,"unknown option %s\n",*argv);
  339. badops=1;
  340. break;
  341. }
  342. else
  343. break;
  344. argc--;
  345. argv++;
  346. }
  347. if (dbfile && configfile)
  348. {
  349. BIO_printf(bio_err,"-dbfile and -configfile cannot be specified together.\n");
  350. badops = 1;
  351. }
  352. if (add_user+delete_user+modify_user+list_user != 1)
  353. {
  354. BIO_printf(bio_err,"Exactly one of the options -add, -delete, -modify -list must be specified.\n");
  355. badops = 1;
  356. }
  357. if (delete_user+modify_user+delete_user== 1 && argc <= 0)
  358. {
  359. BIO_printf(bio_err,"Need at least one user for options -add, -delete, -modify. \n");
  360. badops = 1;
  361. }
  362. if ((passin || passout) && argc != 1 )
  363. {
  364. BIO_printf(bio_err,"-passin, -passout arguments only valid with one user.\n");
  365. badops = 1;
  366. }
  367. if (badops)
  368. {
  369. for (pp=srp_usage; (*pp != NULL); pp++)
  370. BIO_printf(bio_err,"%s",*pp);
  371. BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
  372. BIO_printf(bio_err," load the file (or the files in the directory) into\n");
  373. BIO_printf(bio_err," the random number generator\n");
  374. goto err;
  375. }
  376. ERR_load_crypto_strings();
  377. #ifndef OPENSSL_NO_ENGINE
  378. setup_engine(bio_err, engine, 0);
  379. #endif
  380. if(!app_passwd(bio_err, passargin, passargout, &passin, &passout))
  381. {
  382. BIO_printf(bio_err, "Error getting passwords\n");
  383. goto err;
  384. }
  385. if (!dbfile)
  386. {
  387. /*****************************************************************/
  388. tofree=NULL;
  389. if (configfile == NULL) configfile = getenv("OPENSSL_CONF");
  390. if (configfile == NULL) configfile = getenv("SSLEAY_CONF");
  391. if (configfile == NULL)
  392. {
  393. const char *s=X509_get_default_cert_area();
  394. size_t len;
  395. #ifdef OPENSSL_SYS_VMS
  396. len = strlen(s)+sizeof(CONFIG_FILE);
  397. tofree=OPENSSL_malloc(len);
  398. strcpy(tofree,s);
  399. #else
  400. len = strlen(s)+sizeof(CONFIG_FILE)+1;
  401. tofree=OPENSSL_malloc(len);
  402. BUF_strlcpy(tofree,s,len);
  403. BUF_strlcat(tofree,"/",len);
  404. #endif
  405. BUF_strlcat(tofree,CONFIG_FILE,len);
  406. configfile=tofree;
  407. }
  408. VERBOSE BIO_printf(bio_err,"Using configuration from %s\n",configfile);
  409. conf = NCONF_new(NULL);
  410. if (NCONF_load(conf,configfile,&errorline) <= 0)
  411. {
  412. if (errorline <= 0)
  413. BIO_printf(bio_err,"error loading the config file '%s'\n",
  414. configfile);
  415. else
  416. BIO_printf(bio_err,"error on line %ld of config file '%s'\n"
  417. ,errorline,configfile);
  418. goto err;
  419. }
  420. if(tofree)
  421. {
  422. OPENSSL_free(tofree);
  423. tofree = NULL;
  424. }
  425. if (!load_config(bio_err, conf))
  426. goto err;
  427. /* Lets get the config section we are using */
  428. if (section == NULL)
  429. {
  430. VERBOSE BIO_printf(bio_err,"trying to read " ENV_DEFAULT_SRP " in \" BASE_SECTION \"\n");
  431. section=NCONF_get_string(conf,BASE_SECTION,ENV_DEFAULT_SRP);
  432. if (section == NULL)
  433. {
  434. lookup_fail(BASE_SECTION,ENV_DEFAULT_SRP);
  435. goto err;
  436. }
  437. }
  438. if (randfile == NULL && conf)
  439. randfile = NCONF_get_string(conf, BASE_SECTION, "RANDFILE");
  440. VERBOSE BIO_printf(bio_err,"trying to read " ENV_DATABASE " in section \"%s\"\n",section);
  441. if ((dbfile=NCONF_get_string(conf,section,ENV_DATABASE)) == NULL)
  442. {
  443. lookup_fail(section,ENV_DATABASE);
  444. goto err;
  445. }
  446. }
  447. if (randfile == NULL)
  448. ERR_clear_error();
  449. else
  450. app_RAND_load_file(randfile, bio_err, 0);
  451. VERBOSE BIO_printf(bio_err,"Trying to read SRP verifier file \"%s\"\n",dbfile);
  452. db = load_index(dbfile, &db_attr);
  453. if (db == NULL) goto err;
  454. /* Lets check some fields */
  455. for (i=0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++)
  456. {
  457. pp=sk_OPENSSL_PSTRING_value(db->db->data, i);
  458. if (pp[DB_srptype][0] == DB_SRP_INDEX)
  459. {
  460. maxgN = i;
  461. if (gNindex < 0 && gN != NULL && !strcmp(gN, pp[DB_srpid]))
  462. gNindex = i;
  463. print_index(db, bio_err, i, verbose > 1) ;
  464. }
  465. }
  466. VERBOSE BIO_printf(bio_err,"Database initialised\n");
  467. if (gNindex >= 0)
  468. {
  469. gNrow=sk_OPENSSL_PSTRING_value(db->db->data,gNindex);
  470. print_entry(db,bio_err,gNindex,verbose>1,"Default g and N") ;
  471. }
  472. else if (maxgN > 0 && !SRP_get_default_gN(gN))
  473. {
  474. BIO_printf(bio_err,"No g and N value for index \"%s\"\n",gN);
  475. goto err;
  476. }
  477. else
  478. {
  479. VERBOSE BIO_printf(bio_err,"Database has no g N information.\n");
  480. gNrow = NULL;
  481. }
  482. VVERBOSE BIO_printf(bio_err,"Starting user processing\n");
  483. if (argc > 0)
  484. user = *(argv++) ;
  485. while (list_user || user)
  486. {
  487. int userindex = -1;
  488. if (user)
  489. VVERBOSE BIO_printf(bio_err, "Processing user \"%s\"\n",user);
  490. if ((userindex = get_index(db, user, 'U')) >= 0)
  491. {
  492. print_user(db,bio_err,userindex,(verbose > 0) || list_user) ;
  493. }
  494. if (list_user)
  495. {
  496. if (user == NULL)
  497. {
  498. BIO_printf(bio_err,"List all users\n");
  499. for (i=0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++)
  500. {
  501. print_user(db,bio_err,i,1) ;
  502. }
  503. list_user = 0;
  504. }
  505. else if (userindex < 0)
  506. {
  507. BIO_printf(bio_err, "user \"%s\" does not exist, ignored. t\n",
  508. user);
  509. errors++;
  510. }
  511. }
  512. else if (add_user)
  513. {
  514. if (userindex >= 0)
  515. {
  516. /* reactivation of a new user */
  517. char **row = sk_OPENSSL_PSTRING_value(db->db->data, userindex);
  518. BIO_printf(bio_err,"user \"%s\" reactivated.\n", user);
  519. row[DB_srptype][0] = 'V' ;
  520. doupdatedb = 1;
  521. }
  522. else
  523. {
  524. char *row[DB_NUMBER] ; char * gNid;
  525. row[DB_srpverifier] = NULL;
  526. row[DB_srpsalt] = NULL;
  527. row[DB_srpinfo] = NULL;
  528. 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)))
  529. {
  530. BIO_printf(bio_err,"Cannot create srp verifier for user \"%s\", operation abandoned .\n",user);
  531. errors++ ;
  532. goto err;
  533. }
  534. row[DB_srpid] = BUF_strdup(user);
  535. row[DB_srptype] = BUF_strdup("v");
  536. row[DB_srpgN] = BUF_strdup(gNid);
  537. if (!row[DB_srpid] || !row[DB_srpgN] || !row[DB_srptype] || !row[DB_srpverifier] || !row[DB_srpsalt] ||
  538. (userinfo && (!(row[DB_srpinfo] = BUF_strdup(userinfo)))) ||
  539. !update_index(db, bio_err, row))
  540. {
  541. if (row[DB_srpid]) OPENSSL_free(row[DB_srpid]);
  542. if (row[DB_srpgN]) OPENSSL_free(row[DB_srpgN]);
  543. if (row[DB_srpinfo]) OPENSSL_free(row[DB_srpinfo]);
  544. if (row[DB_srptype]) OPENSSL_free(row[DB_srptype]);
  545. if (row[DB_srpverifier]) OPENSSL_free(row[DB_srpverifier]);
  546. if (row[DB_srpsalt]) OPENSSL_free(row[DB_srpsalt]);
  547. goto err;
  548. }
  549. doupdatedb = 1;
  550. }
  551. }
  552. else if (modify_user)
  553. {
  554. if (userindex<0)
  555. {
  556. BIO_printf(bio_err,"user \"%s\" does not exist, operation ignored.\n",user);
  557. errors++ ;
  558. }
  559. else
  560. {
  561. char **row=sk_OPENSSL_PSTRING_value(db->db->data, userindex);
  562. char type = row[DB_srptype][0] ;
  563. if (type == 'v')
  564. {
  565. BIO_printf(bio_err,"user \"%s\" already updated, operation ignored.\n",user);
  566. errors++ ;
  567. }
  568. else
  569. {
  570. char * gNid ;
  571. if (row[DB_srptype][0] == 'V')
  572. {
  573. int user_gN ;
  574. char ** irow = NULL;
  575. VERBOSE BIO_printf(bio_err,"Verifying password for user \"%s\"\n",user);
  576. if ( (user_gN = get_index(db, row[DB_srpgN],DB_SRP_INDEX)) >= 0)
  577. irow = sk_OPENSSL_PSTRING_value(db->db->data,
  578. userindex);
  579. 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))
  580. {
  581. BIO_printf(bio_err,"Invalid password for user \"%s\", operation abandoned.\n",user);
  582. errors++ ;
  583. goto err;
  584. }
  585. }
  586. VERBOSE BIO_printf(bio_err,"Password for user \"%s\" ok.\n",user);
  587. 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)))
  588. {
  589. BIO_printf(bio_err,
  590. "Cannot create srp verifier for user "
  591. "\"%s\", operation abandonned .\n",
  592. user);
  593. errors++;
  594. goto err;
  595. }
  596. row[DB_srptype][0] = 'v';
  597. row[DB_srpgN] = BUF_strdup(gNid);
  598. if (!row[DB_srpid] || !row[DB_srpgN] || !row[DB_srptype] || !row[DB_srpverifier] || !row[DB_srpsalt] ||
  599. (userinfo && (!(row[DB_srpinfo] = BUF_strdup(userinfo)))))
  600. goto err;
  601. doupdatedb = 1;
  602. }
  603. }
  604. }
  605. else if (delete_user)
  606. {
  607. if (userindex < 0)
  608. {
  609. BIO_printf(bio_err, "user \"%s\" does not exist, operation ignored. t\n", user);
  610. errors++;
  611. }
  612. else
  613. {
  614. char ** xpp = sk_OPENSSL_PSTRING_value(db->db->data,userindex);
  615. BIO_printf(bio_err,"user \"%s\" revoked. t\n",user);
  616. xpp[DB_srptype][0] = 'R' ;
  617. doupdatedb = 1;
  618. }
  619. }
  620. if (--argc > 0)
  621. user = *(argv++) ;
  622. else
  623. {
  624. user = NULL;
  625. list_user = 0;
  626. }
  627. }
  628. VERBOSE BIO_printf(bio_err,"User procession done.\n");
  629. if (doupdatedb)
  630. {
  631. /* Lets check some fields */
  632. for (i=0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++)
  633. {
  634. pp=sk_OPENSSL_PSTRING_value(db->db->data,i);
  635. if (pp[DB_srptype][0] == 'v')
  636. {
  637. pp[DB_srptype][0] = 'V';
  638. print_user(db,bio_err,i,verbose) ;
  639. }
  640. }
  641. VERBOSE BIO_printf(bio_err,"Trying to update srpvfile.\n");
  642. if (!save_index(dbfile,"new",db)) goto err;
  643. VERBOSE BIO_printf(bio_err,"Temporary srpvfile created.\n");
  644. if (!rotate_index(dbfile,"new","old")) goto err;
  645. VERBOSE BIO_printf(bio_err,"srpvfile updated.\n");
  646. }
  647. ret = (errors != 0);
  648. err:
  649. if (errors != 0)
  650. VERBOSE BIO_printf(bio_err,"User errors %d.\n",errors);
  651. VERBOSE BIO_printf(bio_err,"SRP terminating with code %d.\n",ret);
  652. if(tofree)
  653. OPENSSL_free(tofree);
  654. if (ret) ERR_print_errors(bio_err);
  655. if (randfile) app_RAND_write_file(randfile, bio_err);
  656. if (conf) NCONF_free(conf);
  657. if (db) free_index(db);
  658. OBJ_cleanup();
  659. apps_shutdown();
  660. OPENSSL_EXIT(ret);
  661. }
  662. #endif