xref: /freebsd/crypto/openssl/apps/srp.c (revision 6cf8931a2f9fa26b2d9bdba6f1915f655e6bf25f)
11f13597dSJung-uk Kim /* apps/srp.c */
26f9291ceSJung-uk Kim /*
36f9291ceSJung-uk Kim  * Written by Peter Sylvester (peter.sylvester@edelweb.fr) for the EdelKey
46f9291ceSJung-uk Kim  * project and contributed to the OpenSSL project 2004.
51f13597dSJung-uk Kim  */
61f13597dSJung-uk Kim /* ====================================================================
71f13597dSJung-uk Kim  * Copyright (c) 2004 The OpenSSL Project.  All rights reserved.
81f13597dSJung-uk Kim  *
91f13597dSJung-uk Kim  * Redistribution and use in source and binary forms, with or without
101f13597dSJung-uk Kim  * modification, are permitted provided that the following conditions
111f13597dSJung-uk Kim  * are met:
121f13597dSJung-uk Kim  *
131f13597dSJung-uk Kim  * 1. Redistributions of source code must retain the above copyright
141f13597dSJung-uk Kim  *    notice, this list of conditions and the following disclaimer.
151f13597dSJung-uk Kim  *
161f13597dSJung-uk Kim  * 2. Redistributions in binary form must reproduce the above copyright
171f13597dSJung-uk Kim  *    notice, this list of conditions and the following disclaimer in
181f13597dSJung-uk Kim  *    the documentation and/or other materials provided with the
191f13597dSJung-uk Kim  *    distribution.
201f13597dSJung-uk Kim  *
211f13597dSJung-uk Kim  * 3. All advertising materials mentioning features or use of this
221f13597dSJung-uk Kim  *    software must display the following acknowledgment:
231f13597dSJung-uk Kim  *    "This product includes software developed by the OpenSSL Project
241f13597dSJung-uk Kim  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
251f13597dSJung-uk Kim  *
261f13597dSJung-uk Kim  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
271f13597dSJung-uk Kim  *    endorse or promote products derived from this software without
281f13597dSJung-uk Kim  *    prior written permission. For written permission, please contact
291f13597dSJung-uk Kim  *    licensing@OpenSSL.org.
301f13597dSJung-uk Kim  *
311f13597dSJung-uk Kim  * 5. Products derived from this software may not be called "OpenSSL"
321f13597dSJung-uk Kim  *    nor may "OpenSSL" appear in their names without prior written
331f13597dSJung-uk Kim  *    permission of the OpenSSL Project.
341f13597dSJung-uk Kim  *
351f13597dSJung-uk Kim  * 6. Redistributions of any form whatsoever must retain the following
361f13597dSJung-uk Kim  *    acknowledgment:
371f13597dSJung-uk Kim  *    "This product includes software developed by the OpenSSL Project
381f13597dSJung-uk Kim  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
391f13597dSJung-uk Kim  *
401f13597dSJung-uk Kim  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
411f13597dSJung-uk Kim  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
421f13597dSJung-uk Kim  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
431f13597dSJung-uk Kim  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
441f13597dSJung-uk Kim  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
451f13597dSJung-uk Kim  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
461f13597dSJung-uk Kim  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
471f13597dSJung-uk Kim  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
481f13597dSJung-uk Kim  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
491f13597dSJung-uk Kim  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
501f13597dSJung-uk Kim  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
511f13597dSJung-uk Kim  * OF THE POSSIBILITY OF SUCH DAMAGE.
521f13597dSJung-uk Kim  * ====================================================================
531f13597dSJung-uk Kim  *
541f13597dSJung-uk Kim  * This product includes cryptographic software written by Eric Young
551f13597dSJung-uk Kim  * (eay@cryptsoft.com).  This product includes software written by Tim
561f13597dSJung-uk Kim  * Hudson (tjh@cryptsoft.com).
571f13597dSJung-uk Kim  *
581f13597dSJung-uk Kim  */
591f13597dSJung-uk Kim #include <openssl/opensslconf.h>
601f13597dSJung-uk Kim 
611f13597dSJung-uk Kim #ifndef OPENSSL_NO_SRP
621f13597dSJung-uk Kim # include <stdio.h>
631f13597dSJung-uk Kim # include <stdlib.h>
641f13597dSJung-uk Kim # include <string.h>
651f13597dSJung-uk Kim # include <openssl/conf.h>
661f13597dSJung-uk Kim # include <openssl/bio.h>
671f13597dSJung-uk Kim # include <openssl/err.h>
681f13597dSJung-uk Kim # include <openssl/txt_db.h>
691f13597dSJung-uk Kim # include <openssl/buffer.h>
701f13597dSJung-uk Kim # include <openssl/srp.h>
711f13597dSJung-uk Kim 
721f13597dSJung-uk Kim # include "apps.h"
731f13597dSJung-uk Kim 
741f13597dSJung-uk Kim # undef PROG
751f13597dSJung-uk Kim # define PROG srp_main
761f13597dSJung-uk Kim 
771f13597dSJung-uk Kim # define BASE_SECTION    "srp"
781f13597dSJung-uk Kim # define CONFIG_FILE "openssl.cnf"
791f13597dSJung-uk Kim 
801f13597dSJung-uk Kim # define ENV_RANDFILE            "RANDFILE"
811f13597dSJung-uk Kim 
821f13597dSJung-uk Kim # define ENV_DATABASE            "srpvfile"
831f13597dSJung-uk Kim # define ENV_DEFAULT_SRP         "default_srp"
841f13597dSJung-uk Kim 
851f13597dSJung-uk Kim static char *srp_usage[] = {
861f13597dSJung-uk Kim     "usage: srp [args] [user] \n",
871f13597dSJung-uk Kim     "\n",
881f13597dSJung-uk Kim     " -verbose        Talk alot while doing things\n",
891f13597dSJung-uk Kim     " -config file    A config file\n",
901f13597dSJung-uk Kim     " -name arg       The particular srp definition to use\n",
911f13597dSJung-uk Kim     " -srpvfile arg   The srp verifier file name\n",
921f13597dSJung-uk Kim     " -add            add an user and srp verifier\n",
931f13597dSJung-uk Kim     " -modify         modify the srp verifier of an existing user\n",
941f13597dSJung-uk Kim     " -delete         delete user from verifier file\n",
951f13597dSJung-uk Kim     " -list           list user\n",
961f13597dSJung-uk Kim     " -gn arg         g and N values to be used for new verifier\n",
971f13597dSJung-uk Kim     " -userinfo arg   additional info to be set for user\n",
981f13597dSJung-uk Kim     " -passin arg     input file pass phrase source\n",
991f13597dSJung-uk Kim     " -passout arg    output file pass phrase source\n",
1001f13597dSJung-uk Kim # ifndef OPENSSL_NO_ENGINE
1011f13597dSJung-uk Kim     " -engine e         - use engine e, possibly a hardware device.\n",
1021f13597dSJung-uk Kim # endif
1031f13597dSJung-uk Kim     NULL
1041f13597dSJung-uk Kim };
1051f13597dSJung-uk Kim 
1061f13597dSJung-uk Kim # ifdef EFENCE
1071f13597dSJung-uk Kim extern int EF_PROTECT_FREE;
1081f13597dSJung-uk Kim extern int EF_PROTECT_BELOW;
1091f13597dSJung-uk Kim extern int EF_ALIGNMENT;
1101f13597dSJung-uk Kim # endif
1111f13597dSJung-uk Kim 
1121f13597dSJung-uk Kim static CONF *conf = NULL;
1131f13597dSJung-uk Kim static char *section = NULL;
1141f13597dSJung-uk Kim 
1151f13597dSJung-uk Kim # define VERBOSE if (verbose)
1161f13597dSJung-uk Kim # define VVERBOSE if (verbose>1)
1171f13597dSJung-uk Kim 
1181f13597dSJung-uk Kim int MAIN(int, char **);
1191f13597dSJung-uk Kim 
1201f13597dSJung-uk Kim static int get_index(CA_DB *db, char *id, char type)
1211f13597dSJung-uk Kim {
1221f13597dSJung-uk Kim     char **pp;
1231f13597dSJung-uk Kim     int i;
1246f9291ceSJung-uk Kim     if (id == NULL)
1256f9291ceSJung-uk Kim         return -1;
1261f13597dSJung-uk Kim     if (type == DB_SRP_INDEX)
1276f9291ceSJung-uk Kim         for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) {
12809286989SJung-uk Kim             pp = sk_OPENSSL_PSTRING_value(db->db->data, i);
1296f9291ceSJung-uk Kim             if (pp[DB_srptype][0] == DB_SRP_INDEX
1306f9291ceSJung-uk Kim                 && !strcmp(id, pp[DB_srpid]))
1311f13597dSJung-uk Kim                 return i;
1326f9291ceSJung-uk Kim     } else
1336f9291ceSJung-uk Kim         for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) {
13409286989SJung-uk Kim             pp = sk_OPENSSL_PSTRING_value(db->db->data, i);
1351f13597dSJung-uk Kim 
1366f9291ceSJung-uk Kim             if (pp[DB_srptype][0] != DB_SRP_INDEX
1376f9291ceSJung-uk Kim                 && !strcmp(id, pp[DB_srpid]))
1381f13597dSJung-uk Kim                 return i;
1391f13597dSJung-uk Kim         }
1401f13597dSJung-uk Kim 
1411f13597dSJung-uk Kim     return -1;
1421f13597dSJung-uk Kim }
1431f13597dSJung-uk Kim 
1441f13597dSJung-uk Kim static void print_entry(CA_DB *db, BIO *bio, int indx, int verbose, char *s)
1451f13597dSJung-uk Kim {
1466f9291ceSJung-uk Kim     if (indx >= 0 && verbose) {
1471f13597dSJung-uk Kim         int j;
14809286989SJung-uk Kim         char **pp = sk_OPENSSL_PSTRING_value(db->db->data, indx);
1491f13597dSJung-uk Kim         BIO_printf(bio, "%s \"%s\"\n", s, pp[DB_srpid]);
1506f9291ceSJung-uk Kim         for (j = 0; j < DB_NUMBER; j++) {
1511f13597dSJung-uk Kim             BIO_printf(bio_err, "  %d = \"%s\"\n", j, pp[j]);
1521f13597dSJung-uk Kim         }
1531f13597dSJung-uk Kim     }
1541f13597dSJung-uk Kim }
1551f13597dSJung-uk Kim 
1561f13597dSJung-uk Kim static void print_index(CA_DB *db, BIO *bio, int indexindex, int verbose)
1571f13597dSJung-uk Kim {
1581f13597dSJung-uk Kim     print_entry(db, bio, indexindex, verbose, "g N entry");
1591f13597dSJung-uk Kim }
1601f13597dSJung-uk Kim 
1611f13597dSJung-uk Kim static void print_user(CA_DB *db, BIO *bio, int userindex, int verbose)
1621f13597dSJung-uk Kim {
1636f9291ceSJung-uk Kim     if (verbose > 0) {
16409286989SJung-uk Kim         char **pp = sk_OPENSSL_PSTRING_value(db->db->data, userindex);
1651f13597dSJung-uk Kim 
1666f9291ceSJung-uk Kim         if (pp[DB_srptype][0] != 'I') {
1671f13597dSJung-uk Kim             print_entry(db, bio, userindex, verbose, "User entry");
1686f9291ceSJung-uk Kim             print_entry(db, bio, get_index(db, pp[DB_srpgN], 'I'), verbose,
1696f9291ceSJung-uk Kim                         "g N entry");
1701f13597dSJung-uk Kim         }
1711f13597dSJung-uk Kim 
1721f13597dSJung-uk Kim     }
1731f13597dSJung-uk Kim }
1741f13597dSJung-uk Kim 
1751f13597dSJung-uk Kim static int update_index(CA_DB *db, BIO *bio, char **row)
1761f13597dSJung-uk Kim {
1771f13597dSJung-uk Kim     char **irow;
1781f13597dSJung-uk Kim     int i;
1791f13597dSJung-uk Kim 
1806f9291ceSJung-uk Kim     if ((irow =
1816f9291ceSJung-uk Kim          (char **)OPENSSL_malloc(sizeof(char *) * (DB_NUMBER + 1))) == NULL) {
1821f13597dSJung-uk Kim         BIO_printf(bio_err, "Memory allocation failure\n");
1831f13597dSJung-uk Kim         return 0;
1841f13597dSJung-uk Kim     }
1851f13597dSJung-uk Kim 
1866f9291ceSJung-uk Kim     for (i = 0; i < DB_NUMBER; i++) {
1871f13597dSJung-uk Kim         irow[i] = row[i];
1881f13597dSJung-uk Kim         row[i] = NULL;
1891f13597dSJung-uk Kim     }
1901f13597dSJung-uk Kim     irow[DB_NUMBER] = NULL;
1911f13597dSJung-uk Kim 
1926f9291ceSJung-uk Kim     if (!TXT_DB_insert(db->db, irow)) {
1931f13597dSJung-uk Kim         BIO_printf(bio, "failed to update srpvfile\n");
1941f13597dSJung-uk Kim         BIO_printf(bio, "TXT_DB error number %ld\n", db->db->error);
1951f13597dSJung-uk Kim         OPENSSL_free(irow);
1961f13597dSJung-uk Kim         return 0;
1971f13597dSJung-uk Kim     }
1981f13597dSJung-uk Kim     return 1;
1991f13597dSJung-uk Kim }
2001f13597dSJung-uk Kim 
2011f13597dSJung-uk Kim static void lookup_fail(const char *name, char *tag)
2021f13597dSJung-uk Kim {
2031f13597dSJung-uk Kim     BIO_printf(bio_err, "variable lookup failed for %s::%s\n", name, tag);
2041f13597dSJung-uk Kim }
2051f13597dSJung-uk Kim 
2061f13597dSJung-uk Kim static char *srp_verify_user(const char *user, const char *srp_verifier,
2071f13597dSJung-uk Kim                              char *srp_usersalt, const char *g, const char *N,
2081f13597dSJung-uk Kim                              const char *passin, BIO *bio, int verbose)
2091f13597dSJung-uk Kim {
2101f13597dSJung-uk Kim     char password[1024];
2111f13597dSJung-uk Kim     PW_CB_DATA cb_tmp;
2121f13597dSJung-uk Kim     char *verifier = NULL;
2131f13597dSJung-uk Kim     char *gNid = NULL;
2141f13597dSJung-uk Kim 
2151f13597dSJung-uk Kim     cb_tmp.prompt_info = user;
2161f13597dSJung-uk Kim     cb_tmp.password = passin;
2171f13597dSJung-uk Kim 
2186f9291ceSJung-uk Kim     if (password_callback(password, 1024, 0, &cb_tmp) > 0) {
2196f9291ceSJung-uk Kim         VERBOSE BIO_printf(bio,
2206f9291ceSJung-uk Kim                            "Validating\n   user=\"%s\"\n srp_verifier=\"%s\"\n srp_usersalt=\"%s\"\n g=\"%s\"\n N=\"%s\"\n",
2216f9291ceSJung-uk Kim                            user, srp_verifier, srp_usersalt, g, N);
2221f13597dSJung-uk Kim         BIO_printf(bio, "Pass %s\n", password);
2231f13597dSJung-uk Kim 
2246f9291ceSJung-uk Kim         if (!
2256f9291ceSJung-uk Kim             (gNid =
2266f9291ceSJung-uk Kim              SRP_create_verifier(user, password, &srp_usersalt, &verifier, N,
2276f9291ceSJung-uk Kim                                  g))) {
2281f13597dSJung-uk Kim             BIO_printf(bio, "Internal error validating SRP verifier\n");
2296f9291ceSJung-uk Kim         } else {
2301f13597dSJung-uk Kim             if (strcmp(verifier, srp_verifier))
2311f13597dSJung-uk Kim                 gNid = NULL;
2321f13597dSJung-uk Kim             OPENSSL_free(verifier);
2331f13597dSJung-uk Kim         }
2341f13597dSJung-uk Kim     }
2351f13597dSJung-uk Kim     return gNid;
2361f13597dSJung-uk Kim }
2371f13597dSJung-uk Kim 
2381f13597dSJung-uk Kim static char *srp_create_user(char *user, char **srp_verifier,
2391f13597dSJung-uk Kim                              char **srp_usersalt, char *g, char *N,
2401f13597dSJung-uk Kim                              char *passout, BIO *bio, int verbose)
2411f13597dSJung-uk Kim {
2421f13597dSJung-uk Kim     char password[1024];
2431f13597dSJung-uk Kim     PW_CB_DATA cb_tmp;
2441f13597dSJung-uk Kim     char *gNid = NULL;
2451f13597dSJung-uk Kim     char *salt = NULL;
2461f13597dSJung-uk Kim     cb_tmp.prompt_info = user;
2471f13597dSJung-uk Kim     cb_tmp.password = passout;
2481f13597dSJung-uk Kim 
2496f9291ceSJung-uk Kim     if (password_callback(password, 1024, 1, &cb_tmp) > 0) {
2506f9291ceSJung-uk Kim         VERBOSE BIO_printf(bio,
2516f9291ceSJung-uk Kim                            "Creating\n user=\"%s\"\n g=\"%s\"\n N=\"%s\"\n",
2526f9291ceSJung-uk Kim                            user, g, N);
2536f9291ceSJung-uk Kim         if (!
2546f9291ceSJung-uk Kim             (gNid =
2556f9291ceSJung-uk Kim              SRP_create_verifier(user, password, &salt, srp_verifier, N,
2566f9291ceSJung-uk Kim                                  g))) {
2571f13597dSJung-uk Kim             BIO_printf(bio, "Internal error creating SRP verifier\n");
2586f9291ceSJung-uk Kim         } else
2591f13597dSJung-uk Kim             *srp_usersalt = salt;
2606f9291ceSJung-uk Kim         VVERBOSE BIO_printf(bio, "gNid=%s salt =\"%s\"\n verifier =\"%s\"\n",
2616f9291ceSJung-uk Kim                             gNid, salt, *srp_verifier);
2621f13597dSJung-uk Kim 
2631f13597dSJung-uk Kim     }
2641f13597dSJung-uk Kim     return gNid;
2651f13597dSJung-uk Kim }
2661f13597dSJung-uk Kim 
2671f13597dSJung-uk Kim int MAIN(int argc, char **argv)
2681f13597dSJung-uk Kim {
2691f13597dSJung-uk Kim     int add_user = 0;
2701f13597dSJung-uk Kim     int list_user = 0;
2711f13597dSJung-uk Kim     int delete_user = 0;
2721f13597dSJung-uk Kim     int modify_user = 0;
2731f13597dSJung-uk Kim     char *user = NULL;
2741f13597dSJung-uk Kim 
2751f13597dSJung-uk Kim     char *passargin = NULL, *passargout = NULL;
2761f13597dSJung-uk Kim     char *passin = NULL, *passout = NULL;
2771f13597dSJung-uk Kim     char *gN = NULL;
2781f13597dSJung-uk Kim     int gNindex = -1;
2791f13597dSJung-uk Kim     char **gNrow = NULL;
2801f13597dSJung-uk Kim     int maxgN = -1;
2811f13597dSJung-uk Kim 
2821f13597dSJung-uk Kim     char *userinfo = NULL;
2831f13597dSJung-uk Kim 
2841f13597dSJung-uk Kim     int badops = 0;
2851f13597dSJung-uk Kim     int ret = 1;
2861f13597dSJung-uk Kim     int errors = 0;
2871f13597dSJung-uk Kim     int verbose = 0;
2881f13597dSJung-uk Kim     int doupdatedb = 0;
2891f13597dSJung-uk Kim     char *configfile = NULL;
2901f13597dSJung-uk Kim     char *dbfile = NULL;
2911f13597dSJung-uk Kim     CA_DB *db = NULL;
2921f13597dSJung-uk Kim     char **pp;
2931f13597dSJung-uk Kim     int i;
2941f13597dSJung-uk Kim     long errorline = -1;
2951f13597dSJung-uk Kim     char *randfile = NULL;
296*6cf8931aSJung-uk Kim     ENGINE *e = NULL;
2971f13597dSJung-uk Kim     char *engine = NULL;
2981f13597dSJung-uk Kim     char *tofree = NULL;
2991f13597dSJung-uk Kim     DB_ATTR db_attr;
3001f13597dSJung-uk Kim 
3011f13597dSJung-uk Kim # ifdef EFENCE
3021f13597dSJung-uk Kim     EF_PROTECT_FREE = 1;
3031f13597dSJung-uk Kim     EF_PROTECT_BELOW = 1;
3041f13597dSJung-uk Kim     EF_ALIGNMENT = 0;
3051f13597dSJung-uk Kim # endif
3061f13597dSJung-uk Kim 
3071f13597dSJung-uk Kim     apps_startup();
3081f13597dSJung-uk Kim 
3091f13597dSJung-uk Kim     conf = NULL;
3101f13597dSJung-uk Kim     section = NULL;
3111f13597dSJung-uk Kim 
3121f13597dSJung-uk Kim     if (bio_err == NULL)
3131f13597dSJung-uk Kim         if ((bio_err = BIO_new(BIO_s_file())) != NULL)
3141f13597dSJung-uk Kim             BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT);
3151f13597dSJung-uk Kim 
3161f13597dSJung-uk Kim     argc--;
3171f13597dSJung-uk Kim     argv++;
3186f9291ceSJung-uk Kim     while (argc >= 1 && badops == 0) {
3191f13597dSJung-uk Kim         if (strcmp(*argv, "-verbose") == 0)
3201f13597dSJung-uk Kim             verbose++;
3216f9291ceSJung-uk Kim         else if (strcmp(*argv, "-config") == 0) {
3226f9291ceSJung-uk Kim             if (--argc < 1)
3236f9291ceSJung-uk Kim                 goto bad;
3241f13597dSJung-uk Kim             configfile = *(++argv);
3256f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-name") == 0) {
3266f9291ceSJung-uk Kim             if (--argc < 1)
3276f9291ceSJung-uk Kim                 goto bad;
3281f13597dSJung-uk Kim             section = *(++argv);
3296f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-srpvfile") == 0) {
3306f9291ceSJung-uk Kim             if (--argc < 1)
3316f9291ceSJung-uk Kim                 goto bad;
3321f13597dSJung-uk Kim             dbfile = *(++argv);
3336f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-add") == 0)
3341f13597dSJung-uk Kim             add_user = 1;
3351f13597dSJung-uk Kim         else if (strcmp(*argv, "-delete") == 0)
3361f13597dSJung-uk Kim             delete_user = 1;
3371f13597dSJung-uk Kim         else if (strcmp(*argv, "-modify") == 0)
3381f13597dSJung-uk Kim             modify_user = 1;
3391f13597dSJung-uk Kim         else if (strcmp(*argv, "-list") == 0)
3401f13597dSJung-uk Kim             list_user = 1;
3416f9291ceSJung-uk Kim         else if (strcmp(*argv, "-gn") == 0) {
3426f9291ceSJung-uk Kim             if (--argc < 1)
3436f9291ceSJung-uk Kim                 goto bad;
3441f13597dSJung-uk Kim             gN = *(++argv);
3456f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-userinfo") == 0) {
3466f9291ceSJung-uk Kim             if (--argc < 1)
3476f9291ceSJung-uk Kim                 goto bad;
3481f13597dSJung-uk Kim             userinfo = *(++argv);
3496f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-passin") == 0) {
3506f9291ceSJung-uk Kim             if (--argc < 1)
3516f9291ceSJung-uk Kim                 goto bad;
3521f13597dSJung-uk Kim             passargin = *(++argv);
3536f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-passout") == 0) {
3546f9291ceSJung-uk Kim             if (--argc < 1)
3556f9291ceSJung-uk Kim                 goto bad;
3561f13597dSJung-uk Kim             passargout = *(++argv);
3571f13597dSJung-uk Kim         }
3581f13597dSJung-uk Kim # ifndef OPENSSL_NO_ENGINE
3596f9291ceSJung-uk Kim         else if (strcmp(*argv, "-engine") == 0) {
3606f9291ceSJung-uk Kim             if (--argc < 1)
3616f9291ceSJung-uk Kim                 goto bad;
3621f13597dSJung-uk Kim             engine = *(++argv);
3631f13597dSJung-uk Kim         }
3641f13597dSJung-uk Kim # endif
3651f13597dSJung-uk Kim 
3666f9291ceSJung-uk Kim         else if (**argv == '-') {
3671f13597dSJung-uk Kim  bad:
3681f13597dSJung-uk Kim             BIO_printf(bio_err, "unknown option %s\n", *argv);
3691f13597dSJung-uk Kim             badops = 1;
3701f13597dSJung-uk Kim             break;
3716f9291ceSJung-uk Kim         } else
3721f13597dSJung-uk Kim             break;
3731f13597dSJung-uk Kim 
3741f13597dSJung-uk Kim         argc--;
3751f13597dSJung-uk Kim         argv++;
3761f13597dSJung-uk Kim     }
3771f13597dSJung-uk Kim 
3786f9291ceSJung-uk Kim     if (dbfile && configfile) {
3796f9291ceSJung-uk Kim         BIO_printf(bio_err,
3806f9291ceSJung-uk Kim                    "-dbfile and -configfile cannot be specified together.\n");
3811f13597dSJung-uk Kim         badops = 1;
3821f13597dSJung-uk Kim     }
3836f9291ceSJung-uk Kim     if (add_user + delete_user + modify_user + list_user != 1) {
3846f9291ceSJung-uk Kim         BIO_printf(bio_err,
3856f9291ceSJung-uk Kim                    "Exactly one of the options -add, -delete, -modify -list must be specified.\n");
3861f13597dSJung-uk Kim         badops = 1;
3871f13597dSJung-uk Kim     }
3886f9291ceSJung-uk Kim     if (delete_user + modify_user + delete_user == 1 && argc <= 0) {
3896f9291ceSJung-uk Kim         BIO_printf(bio_err,
3906f9291ceSJung-uk Kim                    "Need at least one user for options -add, -delete, -modify. \n");
3911f13597dSJung-uk Kim         badops = 1;
3921f13597dSJung-uk Kim     }
3936f9291ceSJung-uk Kim     if ((passin || passout) && argc != 1) {
3946f9291ceSJung-uk Kim         BIO_printf(bio_err,
3956f9291ceSJung-uk Kim                    "-passin, -passout arguments only valid with one user.\n");
3961f13597dSJung-uk Kim         badops = 1;
3971f13597dSJung-uk Kim     }
3981f13597dSJung-uk Kim 
3996f9291ceSJung-uk Kim     if (badops) {
4001f13597dSJung-uk Kim         for (pp = srp_usage; (*pp != NULL); pp++)
4011f13597dSJung-uk Kim             BIO_printf(bio_err, "%s", *pp);
4021f13597dSJung-uk Kim 
4036f9291ceSJung-uk Kim         BIO_printf(bio_err, " -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR,
4046f9291ceSJung-uk Kim                    LIST_SEPARATOR_CHAR);
4056f9291ceSJung-uk Kim         BIO_printf(bio_err,
4066f9291ceSJung-uk Kim                    "                 load the file (or the files in the directory) into\n");
4071f13597dSJung-uk Kim         BIO_printf(bio_err, "                 the random number generator\n");
4081f13597dSJung-uk Kim         goto err;
4091f13597dSJung-uk Kim     }
4101f13597dSJung-uk Kim 
4111f13597dSJung-uk Kim     ERR_load_crypto_strings();
4121f13597dSJung-uk Kim 
413*6cf8931aSJung-uk Kim     e = setup_engine(bio_err, engine, 0);
4141f13597dSJung-uk Kim 
4156f9291ceSJung-uk Kim     if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) {
4161f13597dSJung-uk Kim         BIO_printf(bio_err, "Error getting passwords\n");
4171f13597dSJung-uk Kim         goto err;
4181f13597dSJung-uk Kim     }
4191f13597dSJung-uk Kim 
4206f9291ceSJung-uk Kim     if (!dbfile) {
4211f13597dSJung-uk Kim 
4221f13597dSJung-uk Kim         /*****************************************************************/
4231f13597dSJung-uk Kim         tofree = NULL;
4241f13597dSJung-uk Kim         if (configfile == NULL)
4256f9291ceSJung-uk Kim             configfile = getenv("OPENSSL_CONF");
4266f9291ceSJung-uk Kim         if (configfile == NULL)
4276f9291ceSJung-uk Kim             configfile = getenv("SSLEAY_CONF");
4286f9291ceSJung-uk Kim         if (configfile == NULL) {
4291f13597dSJung-uk Kim             const char *s = X509_get_default_cert_area();
4301f13597dSJung-uk Kim             size_t len;
4311f13597dSJung-uk Kim 
4321f13597dSJung-uk Kim # ifdef OPENSSL_SYS_VMS
4331f13597dSJung-uk Kim             len = strlen(s) + sizeof(CONFIG_FILE);
4341f13597dSJung-uk Kim             tofree = OPENSSL_malloc(len);
4356f9291ceSJung-uk Kim             if (!tofree) {
4366f9291ceSJung-uk Kim                 BIO_printf(bio_err, "Out of memory\n");
4376f9291ceSJung-uk Kim                 goto err;
4386f9291ceSJung-uk Kim             }
4391f13597dSJung-uk Kim             strcpy(tofree, s);
4401f13597dSJung-uk Kim # else
4411f13597dSJung-uk Kim             len = strlen(s) + sizeof(CONFIG_FILE) + 1;
4421f13597dSJung-uk Kim             tofree = OPENSSL_malloc(len);
4436f9291ceSJung-uk Kim             if (!tofree) {
4446f9291ceSJung-uk Kim                 BIO_printf(bio_err, "Out of memory\n");
4456f9291ceSJung-uk Kim                 goto err;
4466f9291ceSJung-uk Kim             }
4471f13597dSJung-uk Kim             BUF_strlcpy(tofree, s, len);
4481f13597dSJung-uk Kim             BUF_strlcat(tofree, "/", len);
4491f13597dSJung-uk Kim # endif
4501f13597dSJung-uk Kim             BUF_strlcat(tofree, CONFIG_FILE, len);
4511f13597dSJung-uk Kim             configfile = tofree;
4521f13597dSJung-uk Kim         }
4531f13597dSJung-uk Kim 
4546f9291ceSJung-uk Kim         VERBOSE BIO_printf(bio_err, "Using configuration from %s\n",
4556f9291ceSJung-uk Kim                            configfile);
4561f13597dSJung-uk Kim         conf = NCONF_new(NULL);
4576f9291ceSJung-uk Kim         if (NCONF_load(conf, configfile, &errorline) <= 0) {
4581f13597dSJung-uk Kim             if (errorline <= 0)
4591f13597dSJung-uk Kim                 BIO_printf(bio_err, "error loading the config file '%s'\n",
4601f13597dSJung-uk Kim                            configfile);
4611f13597dSJung-uk Kim             else
4626f9291ceSJung-uk Kim                 BIO_printf(bio_err, "error on line %ld of config file '%s'\n",
4636f9291ceSJung-uk Kim                            errorline, configfile);
4641f13597dSJung-uk Kim             goto err;
4651f13597dSJung-uk Kim         }
4666f9291ceSJung-uk Kim         if (tofree) {
4671f13597dSJung-uk Kim             OPENSSL_free(tofree);
4681f13597dSJung-uk Kim             tofree = NULL;
4691f13597dSJung-uk Kim         }
4701f13597dSJung-uk Kim 
4711f13597dSJung-uk Kim         if (!load_config(bio_err, conf))
4721f13597dSJung-uk Kim             goto err;
4731f13597dSJung-uk Kim 
4741f13597dSJung-uk Kim         /* Lets get the config section we are using */
4756f9291ceSJung-uk Kim         if (section == NULL) {
4766f9291ceSJung-uk Kim             VERBOSE BIO_printf(bio_err,
4776f9291ceSJung-uk Kim                                "trying to read " ENV_DEFAULT_SRP
4786f9291ceSJung-uk Kim                                " in \" BASE_SECTION \"\n");
4791f13597dSJung-uk Kim 
4801f13597dSJung-uk Kim             section = NCONF_get_string(conf, BASE_SECTION, ENV_DEFAULT_SRP);
4816f9291ceSJung-uk Kim             if (section == NULL) {
4821f13597dSJung-uk Kim                 lookup_fail(BASE_SECTION, ENV_DEFAULT_SRP);
4831f13597dSJung-uk Kim                 goto err;
4841f13597dSJung-uk Kim             }
4851f13597dSJung-uk Kim         }
4861f13597dSJung-uk Kim 
4871f13597dSJung-uk Kim         if (randfile == NULL && conf)
4881f13597dSJung-uk Kim             randfile = NCONF_get_string(conf, BASE_SECTION, "RANDFILE");
4891f13597dSJung-uk Kim 
4906f9291ceSJung-uk Kim         VERBOSE BIO_printf(bio_err,
4916f9291ceSJung-uk Kim                            "trying to read " ENV_DATABASE
4926f9291ceSJung-uk Kim                            " in section \"%s\"\n", section);
4931f13597dSJung-uk Kim 
4946f9291ceSJung-uk Kim         if ((dbfile = NCONF_get_string(conf, section, ENV_DATABASE)) == NULL) {
4951f13597dSJung-uk Kim             lookup_fail(section, ENV_DATABASE);
4961f13597dSJung-uk Kim             goto err;
4971f13597dSJung-uk Kim         }
4981f13597dSJung-uk Kim 
4991f13597dSJung-uk Kim     }
5001f13597dSJung-uk Kim     if (randfile == NULL)
5011f13597dSJung-uk Kim         ERR_clear_error();
5021f13597dSJung-uk Kim     else
5031f13597dSJung-uk Kim         app_RAND_load_file(randfile, bio_err, 0);
5041f13597dSJung-uk Kim 
5056f9291ceSJung-uk Kim     VERBOSE BIO_printf(bio_err, "Trying to read SRP verifier file \"%s\"\n",
5066f9291ceSJung-uk Kim                        dbfile);
5071f13597dSJung-uk Kim 
5081f13597dSJung-uk Kim     db = load_index(dbfile, &db_attr);
5096f9291ceSJung-uk Kim     if (db == NULL)
5106f9291ceSJung-uk Kim         goto err;
5111f13597dSJung-uk Kim 
5121f13597dSJung-uk Kim     /* Lets check some fields */
5136f9291ceSJung-uk Kim     for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) {
51409286989SJung-uk Kim         pp = sk_OPENSSL_PSTRING_value(db->db->data, i);
5151f13597dSJung-uk Kim 
5166f9291ceSJung-uk Kim         if (pp[DB_srptype][0] == DB_SRP_INDEX) {
5171f13597dSJung-uk Kim             maxgN = i;
5181f13597dSJung-uk Kim             if (gNindex < 0 && gN != NULL && !strcmp(gN, pp[DB_srpid]))
5191f13597dSJung-uk Kim                 gNindex = i;
5201f13597dSJung-uk Kim 
5211f13597dSJung-uk Kim             print_index(db, bio_err, i, verbose > 1);
5221f13597dSJung-uk Kim         }
5231f13597dSJung-uk Kim     }
5241f13597dSJung-uk Kim 
5251f13597dSJung-uk Kim     VERBOSE BIO_printf(bio_err, "Database initialised\n");
5261f13597dSJung-uk Kim 
5276f9291ceSJung-uk Kim     if (gNindex >= 0) {
52809286989SJung-uk Kim         gNrow = sk_OPENSSL_PSTRING_value(db->db->data, gNindex);
5291f13597dSJung-uk Kim         print_entry(db, bio_err, gNindex, verbose > 1, "Default g and N");
5306f9291ceSJung-uk Kim     } else if (maxgN > 0 && !SRP_get_default_gN(gN)) {
5311f13597dSJung-uk Kim         BIO_printf(bio_err, "No g and N value for index \"%s\"\n", gN);
5321f13597dSJung-uk Kim         goto err;
5336f9291ceSJung-uk Kim     } else {
5341f13597dSJung-uk Kim         VERBOSE BIO_printf(bio_err, "Database has no g N information.\n");
5351f13597dSJung-uk Kim         gNrow = NULL;
5361f13597dSJung-uk Kim     }
5371f13597dSJung-uk Kim 
5381f13597dSJung-uk Kim     VVERBOSE BIO_printf(bio_err, "Starting user processing\n");
5391f13597dSJung-uk Kim 
5401f13597dSJung-uk Kim     if (argc > 0)
5411f13597dSJung-uk Kim         user = *(argv++);
5421f13597dSJung-uk Kim 
5436f9291ceSJung-uk Kim     while (list_user || user) {
5441f13597dSJung-uk Kim         int userindex = -1;
5451f13597dSJung-uk Kim         if (user)
5461f13597dSJung-uk Kim             VVERBOSE BIO_printf(bio_err, "Processing user \"%s\"\n", user);
5476f9291ceSJung-uk Kim         if ((userindex = get_index(db, user, 'U')) >= 0) {
5481f13597dSJung-uk Kim             print_user(db, bio_err, userindex, (verbose > 0) || list_user);
5491f13597dSJung-uk Kim         }
5501f13597dSJung-uk Kim 
5516f9291ceSJung-uk Kim         if (list_user) {
5526f9291ceSJung-uk Kim             if (user == NULL) {
5531f13597dSJung-uk Kim                 BIO_printf(bio_err, "List all users\n");
5541f13597dSJung-uk Kim 
5556f9291ceSJung-uk Kim                 for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) {
5561f13597dSJung-uk Kim                     print_user(db, bio_err, i, 1);
5571f13597dSJung-uk Kim                 }
5581f13597dSJung-uk Kim                 list_user = 0;
5596f9291ceSJung-uk Kim             } else if (userindex < 0) {
5606f9291ceSJung-uk Kim                 BIO_printf(bio_err,
5616f9291ceSJung-uk Kim                            "user \"%s\" does not exist, ignored. t\n", user);
5621f13597dSJung-uk Kim                 errors++;
5631f13597dSJung-uk Kim             }
5646f9291ceSJung-uk Kim         } else if (add_user) {
5656f9291ceSJung-uk Kim             if (userindex >= 0) {
5661f13597dSJung-uk Kim                 /* reactivation of a new user */
5676f9291ceSJung-uk Kim                 char **row =
5686f9291ceSJung-uk Kim                     sk_OPENSSL_PSTRING_value(db->db->data, userindex);
5691f13597dSJung-uk Kim                 BIO_printf(bio_err, "user \"%s\" reactivated.\n", user);
5701f13597dSJung-uk Kim                 row[DB_srptype][0] = 'V';
5711f13597dSJung-uk Kim 
5721f13597dSJung-uk Kim                 doupdatedb = 1;
5736f9291ceSJung-uk Kim             } else {
5746f9291ceSJung-uk Kim                 char *row[DB_NUMBER];
5756f9291ceSJung-uk Kim                 char *gNid;
5761f13597dSJung-uk Kim                 row[DB_srpverifier] = NULL;
5771f13597dSJung-uk Kim                 row[DB_srpsalt] = NULL;
5781f13597dSJung-uk Kim                 row[DB_srpinfo] = NULL;
5796f9291ceSJung-uk Kim                 if (!
5806f9291ceSJung-uk Kim                     (gNid =
5816f9291ceSJung-uk Kim                      srp_create_user(user, &(row[DB_srpverifier]),
5826f9291ceSJung-uk Kim                                      &(row[DB_srpsalt]),
5836f9291ceSJung-uk Kim                                      gNrow ? gNrow[DB_srpsalt] : gN,
5846f9291ceSJung-uk Kim                                      gNrow ? gNrow[DB_srpverifier] : NULL,
5856f9291ceSJung-uk Kim                                      passout, bio_err, verbose))) {
5866f9291ceSJung-uk Kim                     BIO_printf(bio_err,
5876f9291ceSJung-uk Kim                                "Cannot create srp verifier for user \"%s\", operation abandoned .\n",
5886f9291ceSJung-uk Kim                                user);
5891f13597dSJung-uk Kim                     errors++;
5901f13597dSJung-uk Kim                     goto err;
5911f13597dSJung-uk Kim                 }
5921f13597dSJung-uk Kim                 row[DB_srpid] = BUF_strdup(user);
5931f13597dSJung-uk Kim                 row[DB_srptype] = BUF_strdup("v");
5941f13597dSJung-uk Kim                 row[DB_srpgN] = BUF_strdup(gNid);
5951f13597dSJung-uk Kim 
5966f9291ceSJung-uk Kim                 if (!row[DB_srpid] || !row[DB_srpgN] || !row[DB_srptype]
5976f9291ceSJung-uk Kim                     || !row[DB_srpverifier] || !row[DB_srpsalt] || (userinfo
5986f9291ceSJung-uk Kim                                                                     &&
5996f9291ceSJung-uk Kim                                                                     (!(row
6006f9291ceSJung-uk Kim                                                                        [DB_srpinfo]
6016f9291ceSJung-uk Kim                                                                        =
6026f9291ceSJung-uk Kim                                                                        BUF_strdup
6036f9291ceSJung-uk Kim                                                                        (userinfo))))
6046f9291ceSJung-uk Kim                     || !update_index(db, bio_err, row)) {
6056f9291ceSJung-uk Kim                     if (row[DB_srpid])
6066f9291ceSJung-uk Kim                         OPENSSL_free(row[DB_srpid]);
6076f9291ceSJung-uk Kim                     if (row[DB_srpgN])
6086f9291ceSJung-uk Kim                         OPENSSL_free(row[DB_srpgN]);
6096f9291ceSJung-uk Kim                     if (row[DB_srpinfo])
6106f9291ceSJung-uk Kim                         OPENSSL_free(row[DB_srpinfo]);
6116f9291ceSJung-uk Kim                     if (row[DB_srptype])
6126f9291ceSJung-uk Kim                         OPENSSL_free(row[DB_srptype]);
6136f9291ceSJung-uk Kim                     if (row[DB_srpverifier])
6146f9291ceSJung-uk Kim                         OPENSSL_free(row[DB_srpverifier]);
6156f9291ceSJung-uk Kim                     if (row[DB_srpsalt])
6166f9291ceSJung-uk Kim                         OPENSSL_free(row[DB_srpsalt]);
6171f13597dSJung-uk Kim                     goto err;
6181f13597dSJung-uk Kim                 }
6191f13597dSJung-uk Kim                 doupdatedb = 1;
6201f13597dSJung-uk Kim             }
6216f9291ceSJung-uk Kim         } else if (modify_user) {
6226f9291ceSJung-uk Kim             if (userindex < 0) {
6236f9291ceSJung-uk Kim                 BIO_printf(bio_err,
6246f9291ceSJung-uk Kim                            "user \"%s\" does not exist, operation ignored.\n",
6256f9291ceSJung-uk Kim                            user);
6261f13597dSJung-uk Kim                 errors++;
6276f9291ceSJung-uk Kim             } else {
6281f13597dSJung-uk Kim 
6296f9291ceSJung-uk Kim                 char **row =
6306f9291ceSJung-uk Kim                     sk_OPENSSL_PSTRING_value(db->db->data, userindex);
6311f13597dSJung-uk Kim                 char type = row[DB_srptype][0];
6326f9291ceSJung-uk Kim                 if (type == 'v') {
6336f9291ceSJung-uk Kim                     BIO_printf(bio_err,
6346f9291ceSJung-uk Kim                                "user \"%s\" already updated, operation ignored.\n",
6356f9291ceSJung-uk Kim                                user);
6361f13597dSJung-uk Kim                     errors++;
6376f9291ceSJung-uk Kim                 } else {
6381f13597dSJung-uk Kim                     char *gNid;
6391f13597dSJung-uk Kim 
6406f9291ceSJung-uk Kim                     if (row[DB_srptype][0] == 'V') {
6411f13597dSJung-uk Kim                         int user_gN;
6421f13597dSJung-uk Kim                         char **irow = NULL;
6436f9291ceSJung-uk Kim                         VERBOSE BIO_printf(bio_err,
6446f9291ceSJung-uk Kim                                            "Verifying password for user \"%s\"\n",
6456f9291ceSJung-uk Kim                                            user);
6466f9291ceSJung-uk Kim                         if ((user_gN =
6476f9291ceSJung-uk Kim                              get_index(db, row[DB_srpgN], DB_SRP_INDEX)) >= 0)
6486f9291ceSJung-uk Kim                             irow =
6496f9291ceSJung-uk Kim                                 (char **)sk_OPENSSL_PSTRING_value(db->
6506f9291ceSJung-uk Kim                                                                   db->data,
6516f9291ceSJung-uk Kim                                                                   userindex);
6521f13597dSJung-uk Kim 
6536f9291ceSJung-uk Kim                         if (!srp_verify_user
6546f9291ceSJung-uk Kim                             (user, row[DB_srpverifier], row[DB_srpsalt],
6556f9291ceSJung-uk Kim                              irow ? irow[DB_srpsalt] : row[DB_srpgN],
6566f9291ceSJung-uk Kim                              irow ? irow[DB_srpverifier] : NULL, passin,
6576f9291ceSJung-uk Kim                              bio_err, verbose)) {
6586f9291ceSJung-uk Kim                             BIO_printf(bio_err,
6596f9291ceSJung-uk Kim                                        "Invalid password for user \"%s\", operation abandoned.\n",
6606f9291ceSJung-uk Kim                                        user);
6611f13597dSJung-uk Kim                             errors++;
6621f13597dSJung-uk Kim                             goto err;
6631f13597dSJung-uk Kim                         }
6641f13597dSJung-uk Kim                     }
6656f9291ceSJung-uk Kim                     VERBOSE BIO_printf(bio_err,
6666f9291ceSJung-uk Kim                                        "Password for user \"%s\" ok.\n",
6676f9291ceSJung-uk Kim                                        user);
6681f13597dSJung-uk Kim 
6696f9291ceSJung-uk Kim                     if (!
6706f9291ceSJung-uk Kim                         (gNid =
6716f9291ceSJung-uk Kim                          srp_create_user(user, &(row[DB_srpverifier]),
6726f9291ceSJung-uk Kim                                          &(row[DB_srpsalt]),
6736f9291ceSJung-uk Kim                                          gNrow ? gNrow[DB_srpsalt] : NULL,
6746f9291ceSJung-uk Kim                                          gNrow ? gNrow[DB_srpverifier] : NULL,
6756f9291ceSJung-uk Kim                                          passout, bio_err, verbose))) {
6766f9291ceSJung-uk Kim                         BIO_printf(bio_err,
6776f9291ceSJung-uk Kim                                    "Cannot create srp verifier for user \"%s\", operation abandoned.\n",
6786f9291ceSJung-uk Kim                                    user);
6791f13597dSJung-uk Kim                         errors++;
6801f13597dSJung-uk Kim                         goto err;
6811f13597dSJung-uk Kim                     }
6821f13597dSJung-uk Kim 
6831f13597dSJung-uk Kim                     row[DB_srptype][0] = 'v';
6841f13597dSJung-uk Kim                     row[DB_srpgN] = BUF_strdup(gNid);
6851f13597dSJung-uk Kim 
6866f9291ceSJung-uk Kim                     if (!row[DB_srpid] || !row[DB_srpgN] || !row[DB_srptype]
6876f9291ceSJung-uk Kim                         || !row[DB_srpverifier] || !row[DB_srpsalt]
6886f9291ceSJung-uk Kim                         || (userinfo
6896f9291ceSJung-uk Kim                             && (!(row[DB_srpinfo] = BUF_strdup(userinfo)))))
6901f13597dSJung-uk Kim                         goto err;
6911f13597dSJung-uk Kim 
6921f13597dSJung-uk Kim                     doupdatedb = 1;
6931f13597dSJung-uk Kim                 }
6941f13597dSJung-uk Kim             }
6956f9291ceSJung-uk Kim         } else if (delete_user) {
6966f9291ceSJung-uk Kim             if (userindex < 0) {
6976f9291ceSJung-uk Kim                 BIO_printf(bio_err,
6986f9291ceSJung-uk Kim                            "user \"%s\" does not exist, operation ignored. t\n",
6996f9291ceSJung-uk Kim                            user);
7001f13597dSJung-uk Kim                 errors++;
7016f9291ceSJung-uk Kim             } else {
7026f9291ceSJung-uk Kim                 char **xpp =
7036f9291ceSJung-uk Kim                     sk_OPENSSL_PSTRING_value(db->db->data, userindex);
7041f13597dSJung-uk Kim                 BIO_printf(bio_err, "user \"%s\" revoked. t\n", user);
7051f13597dSJung-uk Kim 
7061f13597dSJung-uk Kim                 xpp[DB_srptype][0] = 'R';
7071f13597dSJung-uk Kim 
7081f13597dSJung-uk Kim                 doupdatedb = 1;
7091f13597dSJung-uk Kim             }
7101f13597dSJung-uk Kim         }
7111f13597dSJung-uk Kim         if (--argc > 0)
7121f13597dSJung-uk Kim             user = *(argv++);
7136f9291ceSJung-uk Kim         else {
7141f13597dSJung-uk Kim             user = NULL;
7151f13597dSJung-uk Kim             list_user = 0;
7161f13597dSJung-uk Kim         }
7171f13597dSJung-uk Kim     }
7181f13597dSJung-uk Kim 
7191f13597dSJung-uk Kim     VERBOSE BIO_printf(bio_err, "User procession done.\n");
7201f13597dSJung-uk Kim 
7216f9291ceSJung-uk Kim     if (doupdatedb) {
7221f13597dSJung-uk Kim         /* Lets check some fields */
7236f9291ceSJung-uk Kim         for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) {
72409286989SJung-uk Kim             pp = sk_OPENSSL_PSTRING_value(db->db->data, i);
7251f13597dSJung-uk Kim 
7266f9291ceSJung-uk Kim             if (pp[DB_srptype][0] == 'v') {
7271f13597dSJung-uk Kim                 pp[DB_srptype][0] = 'V';
7281f13597dSJung-uk Kim                 print_user(db, bio_err, i, verbose);
7291f13597dSJung-uk Kim             }
7301f13597dSJung-uk Kim         }
7311f13597dSJung-uk Kim 
7321f13597dSJung-uk Kim         VERBOSE BIO_printf(bio_err, "Trying to update srpvfile.\n");
7336f9291ceSJung-uk Kim         if (!save_index(dbfile, "new", db))
7346f9291ceSJung-uk Kim             goto err;
7351f13597dSJung-uk Kim 
7361f13597dSJung-uk Kim         VERBOSE BIO_printf(bio_err, "Temporary srpvfile created.\n");
7376f9291ceSJung-uk Kim         if (!rotate_index(dbfile, "new", "old"))
7386f9291ceSJung-uk Kim             goto err;
7391f13597dSJung-uk Kim 
7401f13597dSJung-uk Kim         VERBOSE BIO_printf(bio_err, "srpvfile updated.\n");
7411f13597dSJung-uk Kim     }
7421f13597dSJung-uk Kim 
7431f13597dSJung-uk Kim     ret = (errors != 0);
7441f13597dSJung-uk Kim  err:
7451f13597dSJung-uk Kim     if (errors != 0)
7461f13597dSJung-uk Kim         VERBOSE BIO_printf(bio_err, "User errors %d.\n", errors);
7471f13597dSJung-uk Kim 
7481f13597dSJung-uk Kim     VERBOSE BIO_printf(bio_err, "SRP terminating with code %d.\n", ret);
7491f13597dSJung-uk Kim     if (tofree)
7501f13597dSJung-uk Kim         OPENSSL_free(tofree);
7516f9291ceSJung-uk Kim     if (ret)
7526f9291ceSJung-uk Kim         ERR_print_errors(bio_err);
7536f9291ceSJung-uk Kim     if (randfile)
7546f9291ceSJung-uk Kim         app_RAND_write_file(randfile, bio_err);
7556f9291ceSJung-uk Kim     if (conf)
7566f9291ceSJung-uk Kim         NCONF_free(conf);
7576f9291ceSJung-uk Kim     if (db)
7586f9291ceSJung-uk Kim         free_index(db);
7591f13597dSJung-uk Kim 
760*6cf8931aSJung-uk Kim     release_engine(e);
7611f13597dSJung-uk Kim     OBJ_cleanup();
7621f13597dSJung-uk Kim     apps_shutdown();
7631f13597dSJung-uk Kim     OPENSSL_EXIT(ret);
7641f13597dSJung-uk Kim }
7651f13597dSJung-uk Kim 
766aeb5019cSJung-uk Kim #else
767aeb5019cSJung-uk Kim static void *dummy = &dummy;
7681f13597dSJung-uk Kim #endif
769