Centralise loading default apps config file
[openssl.git] / apps / ca.c
1 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2  * All rights reserved.
3  *
4  * This package is an SSL implementation written
5  * by Eric Young (eay@cryptsoft.com).
6  * The implementation was written so as to conform with Netscapes SSL.
7  *
8  * This library is free for commercial and non-commercial use as long as
9  * the following conditions are aheared to.  The following conditions
10  * apply to all code found in this distribution, be it the RC4, RSA,
11  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
12  * included with this distribution is covered by the same copyright terms
13  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14  *
15  * Copyright remains Eric Young's, and as such any Copyright notices in
16  * the code are not to be removed.
17  * If this package is used in a product, Eric Young should be given attribution
18  * as the author of the parts of the library used.
19  * This can be in the form of a textual message at program startup or
20  * in documentation (online or textual) provided with the package.
21  *
22  * Redistribution and use in source and binary forms, with or without
23  * modification, are permitted provided that the following conditions
24  * are met:
25  * 1. Redistributions of source code must retain the copyright
26  *    notice, this list of conditions and the following disclaimer.
27  * 2. Redistributions in binary form must reproduce the above copyright
28  *    notice, this list of conditions and the following disclaimer in the
29  *    documentation and/or other materials provided with the distribution.
30  * 3. All advertising materials mentioning features or use of this software
31  *    must display the following acknowledgement:
32  *    "This product includes cryptographic software written by
33  *     Eric Young (eay@cryptsoft.com)"
34  *    The word 'cryptographic' can be left out if the rouines from the library
35  *    being used are not cryptographic related :-).
36  * 4. If you include any Windows specific code (or a derivative thereof) from
37  *    the apps directory (application code) you must include an acknowledgement:
38  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39  *
40  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50  * SUCH DAMAGE.
51  *
52  * The licence and distribution terms for any publically available version or
53  * derivative of this code cannot be changed.  i.e. this code cannot simply be
54  * copied and put under another distribution licence
55  * [including the GNU Public Licence.]
56  */
57
58 /* The PPKI stuff has been donated by Jeff Barber <jeffb@issl.atl.hp.com> */
59
60 #include <stdio.h>
61 #include <stdlib.h>
62 #include <string.h>
63 #include <ctype.h>
64 #include <sys/types.h>
65 #include <openssl/conf.h>
66 #include <openssl/bio.h>
67 #include <openssl/err.h>
68 #include <openssl/bn.h>
69 #include <openssl/txt_db.h>
70 #include <openssl/evp.h>
71 #include <openssl/x509.h>
72 #include <openssl/x509v3.h>
73 #include <openssl/objects.h>
74 #include <openssl/ocsp.h>
75 #include <openssl/pem.h>
76
77 #ifndef W_OK
78 # ifdef OPENSSL_SYS_VMS
79 #  if defined(__DECC)
80 #   include <unistd.h>
81 #  else
82 #   include <unixlib.h>
83 #  endif
84 # elif !defined(OPENSSL_SYS_VXWORKS) && !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_NETWARE)
85 #  include <sys/file.h>
86 # endif
87 #endif
88
89 #include "apps.h"
90
91 #ifndef W_OK
92 # define F_OK 0
93 # define X_OK 1
94 # define W_OK 2
95 # define R_OK 4
96 #endif
97
98 #undef BSIZE
99 #define BSIZE 256
100
101 #define BASE_SECTION    "ca"
102
103 #define ENV_DEFAULT_CA          "default_ca"
104
105 #define STRING_MASK     "string_mask"
106 #define UTF8_IN                 "utf8"
107
108 #define ENV_DIR                 "dir"
109 #define ENV_CERTS               "certs"
110 #define ENV_CRL_DIR             "crl_dir"
111 #define ENV_CA_DB               "CA_DB"
112 #define ENV_NEW_CERTS_DIR       "new_certs_dir"
113 #define ENV_CERTIFICATE "certificate"
114 #define ENV_SERIAL              "serial"
115 #define ENV_CRLNUMBER           "crlnumber"
116 #define ENV_CRL                 "crl"
117 #define ENV_PRIVATE_KEY         "private_key"
118 #define ENV_RANDFILE            "RANDFILE"
119 #define ENV_DEFAULT_DAYS        "default_days"
120 #define ENV_DEFAULT_STARTDATE   "default_startdate"
121 #define ENV_DEFAULT_ENDDATE     "default_enddate"
122 #define ENV_DEFAULT_CRL_DAYS    "default_crl_days"
123 #define ENV_DEFAULT_CRL_HOURS   "default_crl_hours"
124 #define ENV_DEFAULT_MD          "default_md"
125 #define ENV_DEFAULT_EMAIL_DN    "email_in_dn"
126 #define ENV_PRESERVE            "preserve"
127 #define ENV_POLICY              "policy"
128 #define ENV_EXTENSIONS          "x509_extensions"
129 #define ENV_CRLEXT              "crl_extensions"
130 #define ENV_MSIE_HACK           "msie_hack"
131 #define ENV_NAMEOPT             "name_opt"
132 #define ENV_CERTOPT             "cert_opt"
133 #define ENV_EXTCOPY             "copy_extensions"
134 #define ENV_UNIQUE_SUBJECT      "unique_subject"
135
136 #define ENV_DATABASE            "database"
137
138 /* Additional revocation information types */
139
140 #define REV_NONE                0 /* No addditional information */
141 #define REV_CRL_REASON          1 /* Value is CRL reason code */
142 #define REV_HOLD                2 /* Value is hold instruction */
143 #define REV_KEY_COMPROMISE      3 /* Value is cert key compromise time */
144 #define REV_CA_COMPROMISE       4 /* Value is CA key compromise time */
145
146 static void lookup_fail(const char *name, const char *tag);
147 static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
148                    const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
149                    STACK_OF(CONF_VALUE) *policy, CA_DB *db,
150                    BIGNUM *serial, char *subj, unsigned long chtype,
151                    int multirdn, int email_dn, char *startdate, char *enddate,
152                    long days, int batch, char *ext_sect, CONF *conf,
153                    int verbose, unsigned long certopt, unsigned long nameopt,
154                    int default_op, int ext_copy, int selfsign);
155 static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
156                         const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
157                         STACK_OF(CONF_VALUE) *policy, CA_DB *db,
158                         BIGNUM *serial, char *subj, unsigned long chtype,
159                         int multirdn, int email_dn, char *startdate,
160                         char *enddate, long days, int batch, char *ext_sect,
161                         CONF *conf, int verbose, unsigned long certopt,
162                         unsigned long nameopt, int default_op, int ext_copy,
163                         ENGINE *e);
164 static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey,
165                          X509 *x509, const EVP_MD *dgst,
166                          STACK_OF(OPENSSL_STRING) *sigopts,
167                          STACK_OF(CONF_VALUE) *policy, CA_DB *db,
168                          BIGNUM *serial, char *subj, unsigned long chtype,
169                          int multirdn, int email_dn, char *startdate,
170                          char *enddate, long days, char *ext_sect, CONF *conf,
171                          int verbose, unsigned long certopt,
172                          unsigned long nameopt, int default_op, int ext_copy);
173 static void write_new_certificate(BIO *bp, X509 *x, int output_der,
174                                   int notext);
175 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
176                    const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
177                    STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial,
178                    char *subj, unsigned long chtype, int multirdn,
179                    int email_dn, char *startdate, char *enddate, long days,
180                    int batch, int verbose, X509_REQ *req, char *ext_sect,
181                    CONF *conf, unsigned long certopt, unsigned long nameopt,
182                    int default_op, int ext_copy, int selfsign);
183 static int do_revoke(X509 *x509, CA_DB *db, int ext, char *extval);
184 static int get_certificate_status(const char *ser_status, CA_DB *db);
185 static int do_updatedb(CA_DB *db);
186 static int check_time_format(const char *str);
187 char *make_revocation_str(int rev_type, char *rev_arg);
188 int make_revoked(X509_REVOKED *rev, const char *str);
189 static int old_entry_print(ASN1_OBJECT *obj, ASN1_STRING *str);
190
191 static CONF *conf = NULL;
192 static CONF *extconf = NULL;
193 static char *section = NULL;
194 static int preserve = 0;
195 static int msie_hack = 0;
196
197 typedef enum OPTION_choice {
198     OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
199     OPT_ENGINE, OPT_VERBOSE, OPT_CONFIG, OPT_NAME, OPT_SUBJ, OPT_UTF8,
200     OPT_CREATE_SERIAL, OPT_MULTIVALUE_RDN, OPT_STARTDATE, OPT_ENDDATE,
201     OPT_DAYS, OPT_MD, OPT_POLICY, OPT_KEYFILE, OPT_KEYFORM, OPT_PASSIN,
202     OPT_KEY, OPT_CERT, OPT_SELFSIGN, OPT_IN, OPT_OUT, OPT_OUTDIR,
203     OPT_SIGOPT, OPT_NOTEXT, OPT_BATCH, OPT_PRESERVEDN, OPT_NOEMAILDN,
204     OPT_GENCRL, OPT_MSIE_HACK, OPT_CRLDAYS, OPT_CRLHOURS, OPT_CRLSEC,
205     OPT_INFILES, OPT_SS_CERT, OPT_SPKAC, OPT_REVOKE, OPT_VALID,
206     OPT_EXTENSIONS, OPT_EXTFILE, OPT_STATUS, OPT_UPDATEDB, OPT_CRLEXTS,
207     OPT_CRL_REASON, OPT_CRL_HOLD, OPT_CRL_COMPROMISE,
208     OPT_CRL_CA_COMPROMISE
209 } OPTION_CHOICE;
210
211 OPTIONS ca_options[] = {
212     {"help", OPT_HELP, '-', "Display this summary"},
213     {"verbose", OPT_VERBOSE, '-', "Verbose output during processing"},
214     {"config", OPT_CONFIG, 's', "A config file"},
215     {"name", OPT_NAME, 's', "The particular CA definition to use"},
216     {"subj", OPT_SUBJ, 's', "Use arg instead of request's subject"},
217     {"utf8", OPT_UTF8, '-', "Input characters are UTF8 (default ASCII)"},
218     {"create_serial", OPT_CREATE_SERIAL, '-'},
219     {"multivalue-rdn", OPT_MULTIVALUE_RDN, '-',
220      "Enable support for multivalued RDNs"},
221     {"startdate", OPT_STARTDATE, 's', "Cert notBefore, YYMMDDHHMMSSZ"},
222     {"enddate", OPT_ENDDATE, 's',
223      "YYMMDDHHMMSSZ cert notAfter (overrides -days)"},
224     {"days", OPT_DAYS, 'p', "Number of days to certify the cert for"},
225     {"md", OPT_MD, 's', "md to use; one of md2, md5, sha or sha1"},
226     {"policy", OPT_POLICY, 's', "The CA 'policy' to support"},
227     {"keyfile", OPT_KEYFILE, '<', "Private key file"},
228     {"keyform", OPT_KEYFORM, 'f', "Private key file format (PEM or ENGINE)"},
229     {"passin", OPT_PASSIN, 's'},
230     {"key", OPT_KEY, 's', "Key to decode the private key if it is encrypted"},
231     {"cert", OPT_CERT, '<', "The CA cert"},
232     {"selfsign", OPT_SELFSIGN, '-',
233      "Sign a cert with the key associated with it"},
234     {"in", OPT_IN, '<', "The input PEM encoded cert request(s)"},
235     {"out", OPT_OUT, '>', "Where to put the output file(s)"},
236     {"outdir", OPT_OUTDIR, '/', "Where to put output cert"},
237     {"sigopt", OPT_SIGOPT, 's'},
238     {"notext", OPT_NOTEXT, '-'},
239     {"batch", OPT_BATCH, '-', "Don't ask questions"},
240     {"preserveDN", OPT_PRESERVEDN, '-', "Don't re-order the DN"},
241     {"noemailDN", OPT_NOEMAILDN, '-', "Don't add the EMAIL field to the DN"},
242     {"gencrl", OPT_GENCRL, '-', "Generate a new CRL"},
243     {"msie_hack", OPT_MSIE_HACK, '-',
244      "msie modifications to handle all those universal strings"},
245     {"crldays", OPT_CRLDAYS, 'p', "Days is when the next CRL is due"},
246     {"crlhours", OPT_CRLHOURS, 'p', "Hours is when the next CRL is due"},
247     {"crlsec", OPT_CRLSEC, 'p'},
248     {"infiles", OPT_INFILES, '-', "The last argument, requests to process"},
249     {"ss_cert", OPT_SS_CERT, '<', "File contains a self signed cert to sign"},
250     {"spkac", OPT_SPKAC, '<',
251      "File contains DN and signed public key and challenge"},
252     {"revoke", OPT_REVOKE, '<', "Revoke a cert (given in file)"},
253     {"valid", OPT_VALID, 's'},
254     {"extensions", OPT_EXTENSIONS, 's',
255      "Extension section (override value in config file)"},
256     {"extfile", OPT_EXTFILE, '<',
257      "Configuration file with X509v3 extensions to add"},
258     {"status", OPT_STATUS, 's', "Shows cert status given the serial number"},
259     {"updatedb", OPT_UPDATEDB, '-', "Updates db for expired cert"},
260     {"crlexts", OPT_CRLEXTS, 's',
261      "CRL extension section (override value in config file)"},
262     {"crl_reason", OPT_CRL_REASON, 's'},
263     {"crl_hold", OPT_CRL_HOLD, 's'},
264     {"crl_compromise", OPT_CRL_COMPROMISE, 's'},
265     {"crl_CA_compromise", OPT_CRL_CA_COMPROMISE, 's'},
266 #ifndef OPENSSL_NO_ENGINE
267     {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
268 #endif
269     {NULL}
270 };
271
272 int ca_main(int argc, char **argv)
273 {
274     ENGINE *e = NULL;
275     BIGNUM *crlnumber = NULL, *serial = NULL;
276     EVP_PKEY *pkey = NULL;
277     BIO *in = NULL, *out = NULL, *Sout = NULL, *Cout = NULL;
278     ASN1_INTEGER *tmpser;
279     ASN1_TIME *tmptm;
280     CA_DB *db = NULL;
281     DB_ATTR db_attr;
282     STACK_OF(CONF_VALUE) *attribs = NULL;
283     STACK_OF(OPENSSL_STRING) *sigopts = NULL;
284     STACK_OF(X509) *cert_sk = NULL;
285     X509_CRL *crl = NULL;
286     const EVP_MD *dgst = NULL;
287     char *configfile = default_config_file;
288     char *md = NULL, *policy = NULL, *keyfile = NULL;
289     char *certfile = NULL, *crl_ext = NULL, *crlnumberfile = NULL;
290     char *infile = NULL, *spkac_file = NULL, *ss_cert_file = NULL;
291     char *extensions = NULL, *extfile = NULL, *key = NULL, *passinarg = NULL;
292     char *outdir = NULL, *outfile = NULL, *rev_arg = NULL, *ser_status = NULL;
293     char *serialfile = NULL, *startdate = NULL, *subj = NULL;
294     char *prog, *enddate = NULL, *tmp_email_dn = NULL;
295     char *dbfile = NULL, *f, *randfile = NULL, *tofree = NULL;
296     char buf[3][BSIZE];
297     char *const *pp;
298     const char *p;
299     int create_ser = 0, free_key = 0, total = 0, total_done = 0;
300     int batch = 0, default_op = 1, doupdatedb = 0, ext_copy = EXT_COPY_NONE;
301     int keyformat = FORMAT_PEM, multirdn = 0, notext = 0, output_der = 0;
302     int ret = 1, email_dn = 1, req = 0, verbose = 0, gencrl = 0, dorevoke = 0;
303     int i, j, rev_type = REV_NONE, selfsign = 0;
304     long crldays = 0, crlhours = 0, crlsec = 0, days = 0;
305     unsigned long chtype = MBSTRING_ASC, nameopt = 0, certopt = 0;
306     X509 *x509 = NULL, *x509p = NULL, *x = NULL;
307     X509_REVOKED *r = NULL;
308     OPTION_CHOICE o;
309
310     conf = NULL;
311     section = NULL;
312     preserve = 0;
313     msie_hack = 0;
314
315     prog = opt_init(argc, argv, ca_options);
316     while ((o = opt_next()) != OPT_EOF) {
317         switch (o) {
318             case OPT_EOF:
319             case OPT_ERR:
320 opthelp:
321                 BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
322                 goto end;
323             case OPT_HELP:
324                 opt_help(ca_options);
325                 ret = 0;
326                 goto end;
327             case OPT_IN:
328                 req = 1;
329                 infile = opt_arg();
330                 break;
331             case OPT_OUT:
332                 outfile = opt_arg();
333                 break;
334             case OPT_VERBOSE:
335                 verbose = 1;
336                 break;
337             case OPT_CONFIG:
338                 configfile = opt_arg();
339                 break;
340             case OPT_NAME:
341                 section = opt_arg();
342                 break;
343             case OPT_SUBJ:
344                 subj = opt_arg();
345                 /* preserve=1; */
346                 break;
347             case OPT_UTF8:
348                 chtype = MBSTRING_UTF8;
349                 break;
350         case OPT_CREATE_SERIAL:
351             create_ser = 1;
352             break;
353         case OPT_MULTIVALUE_RDN:
354             multirdn = 1;
355             break;
356         case OPT_STARTDATE:
357             startdate = opt_arg();
358             break;
359         case OPT_ENDDATE:
360             enddate = opt_arg();
361             break;
362         case OPT_DAYS:
363             days = atoi(opt_arg());
364             break;
365         case OPT_MD:
366             md = opt_arg();
367             break;
368         case OPT_POLICY:
369             policy = opt_arg();
370             break;
371         case OPT_KEYFILE:
372             keyfile = opt_arg();
373             break;
374         case OPT_KEYFORM:
375             if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyformat))
376                 goto opthelp;
377             break;
378         case OPT_PASSIN:
379             passinarg = opt_arg();
380             break;
381         case OPT_KEY:
382             key = opt_arg();
383             break;
384         case OPT_CERT:
385             certfile = opt_arg();
386             break;
387         case OPT_SELFSIGN:
388             selfsign = 1;
389             break;
390         case OPT_OUTDIR:
391             outdir = opt_arg();
392             break;
393         case OPT_SIGOPT:
394             if (sigopts == NULL)
395                 sigopts = sk_OPENSSL_STRING_new_null();
396             if (sigopts == NULL
397                 || !sk_OPENSSL_STRING_push(sigopts, opt_arg()))
398                 goto end;
399             break;
400         case OPT_NOTEXT:
401             notext = 1;
402             break;
403         case OPT_BATCH:
404             batch = 1;
405             break;
406         case OPT_PRESERVEDN:
407             preserve = 1;
408             break;
409         case OPT_NOEMAILDN:
410             email_dn = 0;
411             break;
412         case OPT_GENCRL:
413             gencrl = 1;
414             break;
415         case OPT_MSIE_HACK:
416             msie_hack = 1;
417             break;
418         case OPT_CRLDAYS:
419             crldays = atol(opt_arg());
420             break;
421         case OPT_CRLHOURS:
422             crlhours = atol(opt_arg());
423             break;
424         case OPT_CRLSEC:
425             crlsec = atol(opt_arg());
426             break;
427         case OPT_INFILES:
428             req = 1;
429             goto end_of_options;
430         case OPT_SS_CERT:
431             ss_cert_file = opt_arg();
432             req = 1;
433             break;
434         case OPT_SPKAC:
435             spkac_file = opt_arg();
436             req = 1;
437             break;
438         case OPT_REVOKE:
439             infile = opt_arg();
440             dorevoke = 1;
441             break;
442         case OPT_VALID:
443             infile = opt_arg();
444             dorevoke = 2;
445             break;
446         case OPT_EXTENSIONS:
447             extensions = opt_arg();
448             break;
449         case OPT_EXTFILE:
450             extfile = opt_arg();
451             break;
452         case OPT_STATUS:
453             ser_status = opt_arg();
454             break;
455         case OPT_UPDATEDB:
456             doupdatedb = 1;
457             break;
458         case OPT_CRLEXTS:
459             crl_ext = opt_arg();
460             break;
461         case OPT_CRL_REASON:
462             rev_arg = opt_arg();
463             rev_type = REV_CRL_REASON;
464             break;
465         case OPT_CRL_HOLD:
466             rev_arg = opt_arg();
467             rev_type = REV_HOLD;
468             break;
469         case OPT_CRL_COMPROMISE:
470             rev_arg = opt_arg();
471             rev_type = REV_KEY_COMPROMISE;
472             break;
473         case OPT_CRL_CA_COMPROMISE:
474             rev_arg = opt_arg();
475             rev_type = REV_CA_COMPROMISE;
476             break;
477         case OPT_ENGINE:
478             e = setup_engine(opt_arg(), 0);
479             break;
480         }
481     }
482 end_of_options:
483     argc = opt_num_rest();
484     argv = opt_rest();
485
486     BIO_printf(bio_err, "Using configuration from %s\n", configfile);
487     /* We already loaded the default config file */
488     if (configfile != default_config_file) {
489         if ((conf = app_load_config(configfile)) == NULL)
490             goto end;
491         if (!app_load_modules(conf))
492             goto end;
493     }
494
495     /* Lets get the config section we are using */
496     if (section == NULL) {
497         section = NCONF_get_string(conf, BASE_SECTION, ENV_DEFAULT_CA);
498         if (section == NULL) {
499             lookup_fail(BASE_SECTION, ENV_DEFAULT_CA);
500             goto end;
501         }
502     }
503
504     if (conf != NULL) {
505         p = NCONF_get_string(conf, NULL, "oid_file");
506         if (p == NULL)
507             ERR_clear_error();
508         if (p != NULL) {
509             BIO *oid_bio;
510
511             oid_bio = BIO_new_file(p, "r");
512             if (oid_bio == NULL) {
513                 /*-
514                 BIO_printf(bio_err,"problems opening %s for extra oid's\n",p);
515                 ERR_print_errors(bio_err);
516                 */
517                 ERR_clear_error();
518             } else {
519                 OBJ_create_objects(oid_bio);
520                 BIO_free(oid_bio);
521             }
522         }
523         if (!add_oid_section(conf)) {
524             ERR_print_errors(bio_err);
525             goto end;
526         }
527     }
528
529     randfile = NCONF_get_string(conf, BASE_SECTION, "RANDFILE");
530     if (randfile == NULL)
531         ERR_clear_error();
532     app_RAND_load_file(randfile, 0);
533
534     f = NCONF_get_string(conf, section, STRING_MASK);
535     if (!f)
536         ERR_clear_error();
537
538     if (f && !ASN1_STRING_set_default_mask_asc(f)) {
539         BIO_printf(bio_err, "Invalid global string mask setting %s\n", f);
540         goto end;
541     }
542
543     if (chtype != MBSTRING_UTF8) {
544         f = NCONF_get_string(conf, section, UTF8_IN);
545         if (!f)
546             ERR_clear_error();
547         else if (strcmp(f, "yes") == 0)
548             chtype = MBSTRING_UTF8;
549     }
550
551     db_attr.unique_subject = 1;
552     p = NCONF_get_string(conf, section, ENV_UNIQUE_SUBJECT);
553     if (p) {
554         db_attr.unique_subject = parse_yesno(p, 1);
555     } else
556         ERR_clear_error();
557
558         /*****************************************************************/
559     /* report status of cert with serial number given on command line */
560     if (ser_status) {
561         if ((dbfile = NCONF_get_string(conf, section, ENV_DATABASE)) == NULL) {
562             lookup_fail(section, ENV_DATABASE);
563             goto end;
564         }
565         db = load_index(dbfile, &db_attr);
566         if (db == NULL)
567             goto end;
568
569         if (!index_index(db))
570             goto end;
571
572         if (get_certificate_status(ser_status, db) != 1)
573             BIO_printf(bio_err, "Error verifying serial %s!\n", ser_status);
574         goto end;
575     }
576
577         /*****************************************************************/
578     /* we definitely need a private key, so let's get it */
579
580     if ((keyfile == NULL) && ((keyfile = NCONF_get_string(conf,
581                                                           section,
582                                                           ENV_PRIVATE_KEY)) ==
583                               NULL)) {
584         lookup_fail(section, ENV_PRIVATE_KEY);
585         goto end;
586     }
587     if (!key) {
588         free_key = 1;
589         if (!app_passwd(passinarg, NULL, &key, NULL)) {
590             BIO_printf(bio_err, "Error getting password\n");
591             goto end;
592         }
593     }
594     pkey = load_key(keyfile, keyformat, 0, key, e, "CA private key");
595     if (key)
596         OPENSSL_cleanse(key, strlen(key));
597     if (pkey == NULL) {
598         /* load_key() has already printed an appropriate message */
599         goto end;
600     }
601
602         /*****************************************************************/
603     /* we need a certificate */
604     if (!selfsign || spkac_file || ss_cert_file || gencrl) {
605         if ((certfile == NULL)
606             && ((certfile = NCONF_get_string(conf,
607                                              section,
608                                              ENV_CERTIFICATE)) == NULL)) {
609             lookup_fail(section, ENV_CERTIFICATE);
610             goto end;
611         }
612         x509 = load_cert(certfile, FORMAT_PEM, NULL, e, "CA certificate");
613         if (x509 == NULL)
614             goto end;
615
616         if (!X509_check_private_key(x509, pkey)) {
617             BIO_printf(bio_err,
618                        "CA certificate and CA private key do not match\n");
619             goto end;
620         }
621     }
622     if (!selfsign)
623         x509p = x509;
624
625     f = NCONF_get_string(conf, BASE_SECTION, ENV_PRESERVE);
626     if (f == NULL)
627         ERR_clear_error();
628     if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
629         preserve = 1;
630     f = NCONF_get_string(conf, BASE_SECTION, ENV_MSIE_HACK);
631     if (f == NULL)
632         ERR_clear_error();
633     if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
634         msie_hack = 1;
635
636     f = NCONF_get_string(conf, section, ENV_NAMEOPT);
637
638     if (f) {
639         if (!set_name_ex(&nameopt, f)) {
640             BIO_printf(bio_err, "Invalid name options: \"%s\"\n", f);
641             goto end;
642         }
643         default_op = 0;
644     } else {
645         nameopt = XN_FLAG_ONELINE;
646         ERR_clear_error();
647     }
648
649     f = NCONF_get_string(conf, section, ENV_CERTOPT);
650
651     if (f) {
652         if (!set_cert_ex(&certopt, f)) {
653             BIO_printf(bio_err, "Invalid certificate options: \"%s\"\n", f);
654             goto end;
655         }
656         default_op = 0;
657     } else
658         ERR_clear_error();
659
660     f = NCONF_get_string(conf, section, ENV_EXTCOPY);
661
662     if (f) {
663         if (!set_ext_copy(&ext_copy, f)) {
664             BIO_printf(bio_err, "Invalid extension copy option: \"%s\"\n", f);
665             goto end;
666         }
667     } else
668         ERR_clear_error();
669
670         /*****************************************************************/
671     /* lookup where to write new certificates */
672     if ((outdir == NULL) && (req)) {
673
674         if ((outdir = NCONF_get_string(conf, section, ENV_NEW_CERTS_DIR))
675             == NULL) {
676             BIO_printf(bio_err,
677                        "there needs to be defined a directory for new certificate to be placed in\n");
678             goto end;
679         }
680 #ifndef OPENSSL_SYS_VMS
681         /*
682          * outdir is a directory spec, but access() for VMS demands a
683          * filename.  We could use the DEC C routine to convert the
684          * directory syntax to Unixly, and give that to app_isdir,
685          * but for now the fopen will catch the error if it's not a
686          * directory
687          */
688         if (app_isdir(outdir) <= 0) {
689             BIO_printf(bio_err, "%s: %s is not a directory\n", prog, outdir);
690             perror(outdir);
691             goto end;
692         }
693 #endif
694     }
695
696         /*****************************************************************/
697     /* we need to load the database file */
698     if ((dbfile = NCONF_get_string(conf, section, ENV_DATABASE)) == NULL) {
699         lookup_fail(section, ENV_DATABASE);
700         goto end;
701     }
702     db = load_index(dbfile, &db_attr);
703     if (db == NULL)
704         goto end;
705
706     /* Lets check some fields */
707     for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) {
708         pp = sk_OPENSSL_PSTRING_value(db->db->data, i);
709         if ((pp[DB_type][0] != DB_TYPE_REV) && (pp[DB_rev_date][0] != '\0')) {
710             BIO_printf(bio_err,
711                        "entry %d: not revoked yet, but has a revocation date\n",
712                        i + 1);
713             goto end;
714         }
715         if ((pp[DB_type][0] == DB_TYPE_REV) &&
716             !make_revoked(NULL, pp[DB_rev_date])) {
717             BIO_printf(bio_err, " in entry %d\n", i + 1);
718             goto end;
719         }
720         if (!check_time_format((char *)pp[DB_exp_date])) {
721             BIO_printf(bio_err, "entry %d: invalid expiry date\n", i + 1);
722             goto end;
723         }
724         p = pp[DB_serial];
725         j = strlen(p);
726         if (*p == '-') {
727             p++;
728             j--;
729         }
730         if ((j & 1) || (j < 2)) {
731             BIO_printf(bio_err, "entry %d: bad serial number length (%d)\n",
732                        i + 1, j);
733             goto end;
734         }
735         for ( ; *p; p++) {
736             if (!isxdigit(*p)) {
737                 BIO_printf(bio_err,
738                            "entry %d: bad char 0%o '%c' in serial number\n",
739                            i + 1, *p, *p);
740                 goto end;
741             }
742         }
743     }
744     if (verbose) {
745         TXT_DB_write(bio_out, db->db);
746         BIO_printf(bio_err, "%d entries loaded from the database\n",
747                    sk_OPENSSL_PSTRING_num(db->db->data));
748         BIO_printf(bio_err, "generating index\n");
749     }
750
751     if (!index_index(db))
752         goto end;
753
754         /*****************************************************************/
755     /* Update the db file for expired certificates */
756     if (doupdatedb) {
757         if (verbose)
758             BIO_printf(bio_err, "Updating %s ...\n", dbfile);
759
760         i = do_updatedb(db);
761         if (i == -1) {
762             BIO_printf(bio_err, "Malloc failure\n");
763             goto end;
764         } else if (i == 0) {
765             if (verbose)
766                 BIO_printf(bio_err, "No entries found to mark expired\n");
767         } else {
768             if (!save_index(dbfile, "new", db))
769                 goto end;
770
771             if (!rotate_index(dbfile, "new", "old"))
772                 goto end;
773
774             if (verbose)
775                 BIO_printf(bio_err,
776                            "Done. %d entries marked as expired\n", i);
777         }
778     }
779
780     /*****************************************************************/
781     /* Read extensions config file                                   */
782     if (extfile) {
783         if ((extconf = app_load_config(extfile)) == NULL) {
784             ret = 1;
785             goto end;
786         }
787
788         if (verbose)
789             BIO_printf(bio_err, "Successfully loaded extensions file %s\n",
790                        extfile);
791
792         /* We can have sections in the ext file */
793         if (!extensions
794             && !(extensions =
795                  NCONF_get_string(extconf, "default", "extensions")))
796             extensions = "default";
797     }
798
799     /*****************************************************************/
800     if (req || gencrl) {
801         /* FIXME: Is it really always text? */
802         Sout = bio_open_default(outfile, 'w', FORMAT_TEXT);
803         if (Sout == NULL)
804             goto end;
805     }
806
807     if ((md == NULL) && ((md = NCONF_get_string(conf,
808                                                 section,
809                                                 ENV_DEFAULT_MD)) == NULL)) {
810         lookup_fail(section, ENV_DEFAULT_MD);
811         goto end;
812     }
813
814     if (strcmp(md, "default") == 0) {
815         int def_nid;
816         if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) <= 0) {
817             BIO_puts(bio_err, "no default digest\n");
818             goto end;
819         }
820         md = (char *)OBJ_nid2sn(def_nid);
821     }
822
823     if (!opt_md(md, &dgst)) {
824         goto end;
825     }
826
827     if (req) {
828         if ((email_dn == 1) && ((tmp_email_dn = NCONF_get_string(conf,
829                                                                  section,
830                                                                  ENV_DEFAULT_EMAIL_DN))
831                                 != NULL)) {
832             if (strcmp(tmp_email_dn, "no") == 0)
833                 email_dn = 0;
834         }
835         if (verbose)
836             BIO_printf(bio_err, "message digest is %s\n",
837                        OBJ_nid2ln(dgst->type));
838         if ((policy == NULL) && ((policy = NCONF_get_string(conf,
839                                                             section,
840                                                             ENV_POLICY)) ==
841                                  NULL)) {
842             lookup_fail(section, ENV_POLICY);
843             goto end;
844         }
845         if (verbose)
846             BIO_printf(bio_err, "policy is %s\n", policy);
847
848         if ((serialfile = NCONF_get_string(conf, section, ENV_SERIAL))
849             == NULL) {
850             lookup_fail(section, ENV_SERIAL);
851             goto end;
852         }
853
854         if (!extconf) {
855             /*
856              * no '-extfile' option, so we look for extensions in the main
857              * configuration file
858              */
859             if (!extensions) {
860                 extensions = NCONF_get_string(conf, section, ENV_EXTENSIONS);
861                 if (!extensions)
862                     ERR_clear_error();
863             }
864             if (extensions) {
865                 /* Check syntax of file */
866                 X509V3_CTX ctx;
867                 X509V3_set_ctx_test(&ctx);
868                 X509V3_set_nconf(&ctx, conf);
869                 if (!X509V3_EXT_add_nconf(conf, &ctx, extensions, NULL)) {
870                     BIO_printf(bio_err,
871                                "Error Loading extension section %s\n",
872                                extensions);
873                     ret = 1;
874                     goto end;
875                 }
876             }
877         }
878
879         if (startdate == NULL) {
880             startdate = NCONF_get_string(conf, section,
881                                          ENV_DEFAULT_STARTDATE);
882             if (startdate == NULL)
883                 ERR_clear_error();
884         }
885         if (startdate && !ASN1_TIME_set_string(NULL, startdate)) {
886             BIO_printf(bio_err,
887                        "start date is invalid, it should be YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ\n");
888             goto end;
889         }
890         if (startdate == NULL)
891             startdate = "today";
892
893         if (enddate == NULL) {
894             enddate = NCONF_get_string(conf, section, ENV_DEFAULT_ENDDATE);
895             if (enddate == NULL)
896                 ERR_clear_error();
897         }
898         if (enddate && !ASN1_TIME_set_string(NULL, enddate)) {
899             BIO_printf(bio_err,
900                        "end date is invalid, it should be YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ\n");
901             goto end;
902         }
903
904         if (days == 0) {
905             if (!NCONF_get_number(conf, section, ENV_DEFAULT_DAYS, &days))
906                 days = 0;
907         }
908         if (!enddate && (days == 0)) {
909             BIO_printf(bio_err,
910                        "cannot lookup how many days to certify for\n");
911             goto end;
912         }
913
914         if ((serial = load_serial(serialfile, create_ser, NULL)) == NULL) {
915             BIO_printf(bio_err, "error while loading serial number\n");
916             goto end;
917         }
918         if (verbose) {
919             if (BN_is_zero(serial))
920                 BIO_printf(bio_err, "next serial number is 00\n");
921             else {
922                 if ((f = BN_bn2hex(serial)) == NULL)
923                     goto end;
924                 BIO_printf(bio_err, "next serial number is %s\n", f);
925                 OPENSSL_free(f);
926             }
927         }
928
929         if ((attribs = NCONF_get_section(conf, policy)) == NULL) {
930             BIO_printf(bio_err, "unable to find 'section' for %s\n", policy);
931             goto end;
932         }
933
934         if ((cert_sk = sk_X509_new_null()) == NULL) {
935             BIO_printf(bio_err, "Memory allocation failure\n");
936             goto end;
937         }
938         if (spkac_file != NULL) {
939             total++;
940             j = certify_spkac(&x, spkac_file, pkey, x509, dgst, sigopts,
941                               attribs, db, serial, subj, chtype, multirdn,
942                               email_dn, startdate, enddate, days, extensions,
943                               conf, verbose, certopt, nameopt, default_op,
944                               ext_copy);
945             if (j < 0)
946                 goto end;
947             if (j > 0) {
948                 total_done++;
949                 BIO_printf(bio_err, "\n");
950                 if (!BN_add_word(serial, 1))
951                     goto end;
952                 if (!sk_X509_push(cert_sk, x)) {
953                     BIO_printf(bio_err, "Memory allocation failure\n");
954                     goto end;
955                 }
956                 if (outfile) {
957                     output_der = 1;
958                     batch = 1;
959                 }
960             }
961         }
962         if (ss_cert_file != NULL) {
963             total++;
964             j = certify_cert(&x, ss_cert_file, pkey, x509, dgst, sigopts,
965                              attribs,
966                              db, serial, subj, chtype, multirdn, email_dn,
967                              startdate, enddate, days, batch, extensions,
968                              conf, verbose, certopt, nameopt, default_op,
969                              ext_copy, e);
970             if (j < 0)
971                 goto end;
972             if (j > 0) {
973                 total_done++;
974                 BIO_printf(bio_err, "\n");
975                 if (!BN_add_word(serial, 1))
976                     goto end;
977                 if (!sk_X509_push(cert_sk, x)) {
978                     BIO_printf(bio_err, "Memory allocation failure\n");
979                     goto end;
980                 }
981             }
982         }
983         if (infile != NULL) {
984             total++;
985             j = certify(&x, infile, pkey, x509p, dgst, sigopts, attribs, db,
986                         serial, subj, chtype, multirdn, email_dn, startdate,
987                         enddate, days, batch, extensions, conf, verbose,
988                         certopt, nameopt, default_op, ext_copy, selfsign);
989             if (j < 0)
990                 goto end;
991             if (j > 0) {
992                 total_done++;
993                 BIO_printf(bio_err, "\n");
994                 if (!BN_add_word(serial, 1))
995                     goto end;
996                 if (!sk_X509_push(cert_sk, x)) {
997                     BIO_printf(bio_err, "Memory allocation failure\n");
998                     goto end;
999                 }
1000             }
1001         }
1002         for (i = 0; i < argc; i++) {
1003             total++;
1004             j = certify(&x, argv[i], pkey, x509p, dgst, sigopts, attribs, db,
1005                         serial, subj, chtype, multirdn, email_dn, startdate,
1006                         enddate, days, batch, extensions, conf, verbose,
1007                         certopt, nameopt, default_op, ext_copy, selfsign);
1008             if (j < 0)
1009                 goto end;
1010             if (j > 0) {
1011                 total_done++;
1012                 BIO_printf(bio_err, "\n");
1013                 if (!BN_add_word(serial, 1))
1014                     goto end;
1015                 if (!sk_X509_push(cert_sk, x)) {
1016                     BIO_printf(bio_err, "Memory allocation failure\n");
1017                     goto end;
1018                 }
1019             }
1020         }
1021         /*
1022          * we have a stack of newly certified certificates and a data base
1023          * and serial number that need updating
1024          */
1025
1026         if (sk_X509_num(cert_sk) > 0) {
1027             if (!batch) {
1028                 BIO_printf(bio_err,
1029                            "\n%d out of %d certificate requests certified, commit? [y/n]",
1030                            total_done, total);
1031                 (void)BIO_flush(bio_err);
1032                 buf[0][0] = '\0';
1033                 if (!fgets(buf[0], 10, stdin)) {
1034                     BIO_printf(bio_err,
1035                                "CERTIFICATION CANCELED: I/O error\n");
1036                     ret = 0;
1037                     goto end;
1038                 }
1039                 if ((buf[0][0] != 'y') && (buf[0][0] != 'Y')) {
1040                     BIO_printf(bio_err, "CERTIFICATION CANCELED\n");
1041                     ret = 0;
1042                     goto end;
1043                 }
1044             }
1045
1046             BIO_printf(bio_err, "Write out database with %d new entries\n",
1047                        sk_X509_num(cert_sk));
1048
1049             if (!save_serial(serialfile, "new", serial, NULL))
1050                 goto end;
1051
1052             if (!save_index(dbfile, "new", db))
1053                 goto end;
1054         }
1055
1056         if (verbose)
1057             BIO_printf(bio_err, "writing new certificates\n");
1058         for (i = 0; i < sk_X509_num(cert_sk); i++) {
1059             ASN1_INTEGER *serialNumber = X509_get_serialNumber(x);
1060             int k;
1061             char *n;
1062
1063             x = sk_X509_value(cert_sk, i);
1064
1065             j = ASN1_STRING_length(serialNumber);
1066             p = (const char *)ASN1_STRING_data(serialNumber);
1067
1068             if (strlen(outdir) >= (size_t)(j ? BSIZE - j * 2 - 6 : BSIZE - 8)) {
1069                 BIO_printf(bio_err, "certificate file name too long\n");
1070                 goto end;
1071             }
1072
1073             strcpy(buf[2], outdir);
1074
1075 #ifndef OPENSSL_SYS_VMS
1076             BUF_strlcat(buf[2], "/", sizeof(buf[2]));
1077 #endif
1078
1079             n = (char *)&(buf[2][strlen(buf[2])]);
1080             if (j > 0) {
1081                 for (k = 0; k < j; k++) {
1082                     if (n >= &(buf[2][sizeof(buf[2])]))
1083                         break;
1084                     BIO_snprintf(n,
1085                                  &buf[2][0] + sizeof(buf[2]) - n,
1086                                  "%02X", (unsigned char)*(p++));
1087                     n += 2;
1088                 }
1089             } else {
1090                 *(n++) = '0';
1091                 *(n++) = '0';
1092             }
1093             *(n++) = '.';
1094             *(n++) = 'p';
1095             *(n++) = 'e';
1096             *(n++) = 'm';
1097             *n = '\0';
1098             if (verbose)
1099                 BIO_printf(bio_err, "writing %s\n", buf[2]);
1100
1101             Cout = BIO_new_file(buf[2], "w");
1102             if (Cout == NULL) {
1103                 perror(buf[2]);
1104                 goto end;
1105             }
1106             write_new_certificate(Cout, x, 0, notext);
1107             write_new_certificate(Sout, x, output_der, notext);
1108         }
1109
1110         if (sk_X509_num(cert_sk)) {
1111             /* Rename the database and the serial file */
1112             if (!rotate_serial(serialfile, "new", "old"))
1113                 goto end;
1114
1115             if (!rotate_index(dbfile, "new", "old"))
1116                 goto end;
1117
1118             BIO_printf(bio_err, "Data Base Updated\n");
1119         }
1120     }
1121
1122         /*****************************************************************/
1123     if (gencrl) {
1124         int crl_v2 = 0;
1125         if (!crl_ext) {
1126             crl_ext = NCONF_get_string(conf, section, ENV_CRLEXT);
1127             if (!crl_ext)
1128                 ERR_clear_error();
1129         }
1130         if (crl_ext) {
1131             /* Check syntax of file */
1132             X509V3_CTX ctx;
1133             X509V3_set_ctx_test(&ctx);
1134             X509V3_set_nconf(&ctx, conf);
1135             if (!X509V3_EXT_add_nconf(conf, &ctx, crl_ext, NULL)) {
1136                 BIO_printf(bio_err,
1137                            "Error Loading CRL extension section %s\n",
1138                            crl_ext);
1139                 ret = 1;
1140                 goto end;
1141             }
1142         }
1143
1144         if ((crlnumberfile = NCONF_get_string(conf, section, ENV_CRLNUMBER))
1145             != NULL)
1146             if ((crlnumber = load_serial(crlnumberfile, 0, NULL)) == NULL) {
1147                 BIO_printf(bio_err, "error while loading CRL number\n");
1148                 goto end;
1149             }
1150
1151         if (!crldays && !crlhours && !crlsec) {
1152             if (!NCONF_get_number(conf, section,
1153                                   ENV_DEFAULT_CRL_DAYS, &crldays))
1154                 crldays = 0;
1155             if (!NCONF_get_number(conf, section,
1156                                   ENV_DEFAULT_CRL_HOURS, &crlhours))
1157                 crlhours = 0;
1158             ERR_clear_error();
1159         }
1160         if ((crldays == 0) && (crlhours == 0) && (crlsec == 0)) {
1161             BIO_printf(bio_err,
1162                        "cannot lookup how long until the next CRL is issued\n");
1163             goto end;
1164         }
1165
1166         if (verbose)
1167             BIO_printf(bio_err, "making CRL\n");
1168         if ((crl = X509_CRL_new()) == NULL)
1169             goto end;
1170         if (!X509_CRL_set_issuer_name(crl, X509_get_subject_name(x509)))
1171             goto end;
1172
1173         tmptm = ASN1_TIME_new();
1174         if (!tmptm)
1175             goto end;
1176         X509_gmtime_adj(tmptm, 0);
1177         X509_CRL_set_lastUpdate(crl, tmptm);
1178         if (!X509_time_adj_ex(tmptm, crldays, crlhours * 60 * 60 + crlsec,
1179                               NULL)) {
1180             BIO_puts(bio_err, "error setting CRL nextUpdate\n");
1181             goto end;
1182         }
1183         X509_CRL_set_nextUpdate(crl, tmptm);
1184
1185         ASN1_TIME_free(tmptm);
1186
1187         for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) {
1188             pp = sk_OPENSSL_PSTRING_value(db->db->data, i);
1189             if (pp[DB_type][0] == DB_TYPE_REV) {
1190                 if ((r = X509_REVOKED_new()) == NULL)
1191                     goto end;
1192                 j = make_revoked(r, pp[DB_rev_date]);
1193                 if (!j)
1194                     goto end;
1195                 if (j == 2)
1196                     crl_v2 = 1;
1197                 if (!BN_hex2bn(&serial, pp[DB_serial]))
1198                     goto end;
1199                 tmpser = BN_to_ASN1_INTEGER(serial, NULL);
1200                 BN_free(serial);
1201                 serial = NULL;
1202                 if (!tmpser)
1203                     goto end;
1204                 X509_REVOKED_set_serialNumber(r, tmpser);
1205                 ASN1_INTEGER_free(tmpser);
1206                 X509_CRL_add0_revoked(crl, r);
1207             }
1208         }
1209
1210         /*
1211          * sort the data so it will be written in serial number order
1212          */
1213         X509_CRL_sort(crl);
1214
1215         /* we now have a CRL */
1216         if (verbose)
1217             BIO_printf(bio_err, "signing CRL\n");
1218
1219         /* Add any extensions asked for */
1220
1221         if (crl_ext || crlnumberfile != NULL) {
1222             X509V3_CTX crlctx;
1223             X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0);
1224             X509V3_set_nconf(&crlctx, conf);
1225
1226             if (crl_ext)
1227                 if (!X509V3_EXT_CRL_add_nconf(conf, &crlctx, crl_ext, crl))
1228                     goto end;
1229             if (crlnumberfile != NULL) {
1230                 tmpser = BN_to_ASN1_INTEGER(crlnumber, NULL);
1231                 if (!tmpser)
1232                     goto end;
1233                 X509_CRL_add1_ext_i2d(crl, NID_crl_number, tmpser, 0, 0);
1234                 ASN1_INTEGER_free(tmpser);
1235                 crl_v2 = 1;
1236                 if (!BN_add_word(crlnumber, 1))
1237                     goto end;
1238             }
1239         }
1240         if (crl_ext || crl_v2) {
1241             if (!X509_CRL_set_version(crl, 1))
1242                 goto end;       /* version 2 CRL */
1243         }
1244
1245         /* we have a CRL number that need updating */
1246         if (crlnumberfile != NULL)
1247             if (!save_serial(crlnumberfile, "new", crlnumber, NULL))
1248                 goto end;
1249
1250         BN_free(crlnumber);
1251         crlnumber = NULL;
1252
1253         if (!do_X509_CRL_sign(crl, pkey, dgst, sigopts))
1254             goto end;
1255
1256         PEM_write_bio_X509_CRL(Sout, crl);
1257
1258         if (crlnumberfile != NULL) /* Rename the crlnumber file */
1259             if (!rotate_serial(crlnumberfile, "new", "old"))
1260                 goto end;
1261
1262     }
1263         /*****************************************************************/
1264     if (dorevoke) {
1265         if (infile == NULL) {
1266             BIO_printf(bio_err, "no input files\n");
1267             goto end;
1268         } else {
1269             X509 *revcert;
1270             revcert = load_cert(infile, FORMAT_PEM, NULL, e, infile);
1271             if (revcert == NULL)
1272                 goto end;
1273             if (dorevoke == 2)
1274                 rev_type = -1;
1275             j = do_revoke(revcert, db, rev_type, rev_arg);
1276             if (j <= 0)
1277                 goto end;
1278             X509_free(revcert);
1279
1280             if (!save_index(dbfile, "new", db))
1281                 goto end;
1282
1283             if (!rotate_index(dbfile, "new", "old"))
1284                 goto end;
1285
1286             BIO_printf(bio_err, "Data Base Updated\n");
1287         }
1288     }
1289         /*****************************************************************/
1290     ret = 0;
1291  end:
1292     OPENSSL_free(tofree);
1293     BIO_free_all(Cout);
1294     BIO_free_all(Sout);
1295     BIO_free_all(out);
1296     BIO_free_all(in);
1297     sk_X509_pop_free(cert_sk, X509_free);
1298
1299     if (ret)
1300         ERR_print_errors(bio_err);
1301     app_RAND_write_file(randfile);
1302     if (free_key)
1303         OPENSSL_free(key);
1304     BN_free(serial);
1305     BN_free(crlnumber);
1306     free_index(db);
1307     sk_OPENSSL_STRING_free(sigopts);
1308     EVP_PKEY_free(pkey);
1309     X509_free(x509);
1310     X509_CRL_free(crl);
1311     NCONF_free(conf);
1312     NCONF_free(extconf);
1313     OBJ_cleanup();
1314     return (ret);
1315 }
1316
1317 static void lookup_fail(const char *name, const char *tag)
1318 {
1319     BIO_printf(bio_err, "variable lookup failed for %s::%s\n", name, tag);
1320 }
1321
1322 static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1323                    const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
1324                    STACK_OF(CONF_VALUE) *policy, CA_DB *db,
1325                    BIGNUM *serial, char *subj, unsigned long chtype,
1326                    int multirdn, int email_dn, char *startdate, char *enddate,
1327                    long days, int batch, char *ext_sect, CONF *lconf,
1328                    int verbose, unsigned long certopt, unsigned long nameopt,
1329                    int default_op, int ext_copy, int selfsign)
1330 {
1331     X509_REQ *req = NULL;
1332     BIO *in = NULL;
1333     EVP_PKEY *pktmp = NULL;
1334     int ok = -1, i;
1335
1336     in = BIO_new_file(infile, "r");
1337     if (in == NULL) {
1338         ERR_print_errors(bio_err);
1339         goto end;
1340     }
1341     if ((req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL)) == NULL) {
1342         BIO_printf(bio_err, "Error reading certificate request in %s\n",
1343                    infile);
1344         goto end;
1345     }
1346     if (verbose)
1347         X509_REQ_print(bio_err, req);
1348
1349     BIO_printf(bio_err, "Check that the request matches the signature\n");
1350
1351     if (selfsign && !X509_REQ_check_private_key(req, pkey)) {
1352         BIO_printf(bio_err,
1353                    "Certificate request and CA private key do not match\n");
1354         ok = 0;
1355         goto end;
1356     }
1357     if ((pktmp = X509_REQ_get_pubkey(req)) == NULL) {
1358         BIO_printf(bio_err, "error unpacking public key\n");
1359         goto end;
1360     }
1361     i = X509_REQ_verify(req, pktmp);
1362     EVP_PKEY_free(pktmp);
1363     if (i < 0) {
1364         ok = 0;
1365         BIO_printf(bio_err, "Signature verification problems....\n");
1366         ERR_print_errors(bio_err);
1367         goto end;
1368     }
1369     if (i == 0) {
1370         ok = 0;
1371         BIO_printf(bio_err,
1372                    "Signature did not match the certificate request\n");
1373         ERR_print_errors(bio_err);
1374         goto end;
1375     } else
1376         BIO_printf(bio_err, "Signature ok\n");
1377
1378     ok = do_body(xret, pkey, x509, dgst, sigopts, policy, db, serial, subj,
1379                  chtype, multirdn, email_dn, startdate, enddate, days, batch,
1380                  verbose, req, ext_sect, lconf, certopt, nameopt, default_op,
1381                  ext_copy, selfsign);
1382
1383  end:
1384     X509_REQ_free(req);
1385     BIO_free(in);
1386     return (ok);
1387 }
1388
1389 static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1390                         const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
1391                         STACK_OF(CONF_VALUE) *policy, CA_DB *db,
1392                         BIGNUM *serial, char *subj, unsigned long chtype,
1393                         int multirdn, int email_dn, char *startdate,
1394                         char *enddate, long days, int batch, char *ext_sect,
1395                         CONF *lconf, int verbose, unsigned long certopt,
1396                         unsigned long nameopt, int default_op, int ext_copy,
1397                         ENGINE *e)
1398 {
1399     X509 *req = NULL;
1400     X509_REQ *rreq = NULL;
1401     EVP_PKEY *pktmp = NULL;
1402     int ok = -1, i;
1403
1404     if ((req = load_cert(infile, FORMAT_PEM, NULL, e, infile)) == NULL)
1405         goto end;
1406     if (verbose)
1407         X509_print(bio_err, req);
1408
1409     BIO_printf(bio_err, "Check that the request matches the signature\n");
1410
1411     if ((pktmp = X509_get_pubkey(req)) == NULL) {
1412         BIO_printf(bio_err, "error unpacking public key\n");
1413         goto end;
1414     }
1415     i = X509_verify(req, pktmp);
1416     EVP_PKEY_free(pktmp);
1417     if (i < 0) {
1418         ok = 0;
1419         BIO_printf(bio_err, "Signature verification problems....\n");
1420         goto end;
1421     }
1422     if (i == 0) {
1423         ok = 0;
1424         BIO_printf(bio_err, "Signature did not match the certificate\n");
1425         goto end;
1426     } else
1427         BIO_printf(bio_err, "Signature ok\n");
1428
1429     if ((rreq = X509_to_X509_REQ(req, NULL, EVP_md5())) == NULL)
1430         goto end;
1431
1432     ok = do_body(xret, pkey, x509, dgst, sigopts, policy, db, serial, subj,
1433                  chtype, multirdn, email_dn, startdate, enddate, days, batch,
1434                  verbose, rreq, ext_sect, lconf, certopt, nameopt, default_op,
1435                  ext_copy, 0);
1436
1437  end:
1438     X509_REQ_free(rreq);
1439     X509_free(req);
1440     return (ok);
1441 }
1442
1443 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
1444                    const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
1445                    STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial,
1446                    char *subj, unsigned long chtype, int multirdn,
1447                    int email_dn, char *startdate, char *enddate, long days,
1448                    int batch, int verbose, X509_REQ *req, char *ext_sect,
1449                    CONF *lconf, unsigned long certopt, unsigned long nameopt,
1450                    int default_op, int ext_copy, int selfsign)
1451 {
1452     X509_NAME *name = NULL, *CAname = NULL, *subject = NULL, *dn_subject =
1453         NULL;
1454     ASN1_UTCTIME *tm, *tmptm;
1455     ASN1_STRING *str, *str2;
1456     ASN1_OBJECT *obj;
1457     X509 *ret = NULL;
1458     X509_NAME_ENTRY *ne;
1459     X509_NAME_ENTRY *tne, *push;
1460     EVP_PKEY *pktmp;
1461     int ok = -1, i, j, last, nid;
1462     const char *p;
1463     CONF_VALUE *cv;
1464     OPENSSL_STRING row[DB_NUMBER];
1465     OPENSSL_STRING *irow = NULL;
1466     OPENSSL_STRING *rrow = NULL;
1467     char buf[25];
1468
1469     tmptm = ASN1_UTCTIME_new();
1470     if (tmptm == NULL) {
1471         BIO_printf(bio_err, "malloc error\n");
1472         return (0);
1473     }
1474
1475     for (i = 0; i < DB_NUMBER; i++)
1476         row[i] = NULL;
1477
1478     if (subj) {
1479         X509_NAME *n = parse_name(subj, chtype, multirdn);
1480
1481         if (!n) {
1482             ERR_print_errors(bio_err);
1483             goto end;
1484         }
1485         X509_REQ_set_subject_name(req, n);
1486         X509_NAME_free(n);
1487     }
1488
1489     if (default_op)
1490         BIO_printf(bio_err,
1491                    "The Subject's Distinguished Name is as follows\n");
1492
1493     name = X509_REQ_get_subject_name(req);
1494     for (i = 0; i < X509_NAME_entry_count(name); i++) {
1495         ne = X509_NAME_get_entry(name, i);
1496         str = X509_NAME_ENTRY_get_data(ne);
1497         obj = X509_NAME_ENTRY_get_object(ne);
1498
1499         if (msie_hack) {
1500             /* assume all type should be strings */
1501             nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(ne));
1502
1503             if (str->type == V_ASN1_UNIVERSALSTRING)
1504                 ASN1_UNIVERSALSTRING_to_string(str);
1505
1506             if ((str->type == V_ASN1_IA5STRING) &&
1507                 (nid != NID_pkcs9_emailAddress))
1508                 str->type = V_ASN1_T61STRING;
1509
1510             if ((nid == NID_pkcs9_emailAddress) &&
1511                 (str->type == V_ASN1_PRINTABLESTRING))
1512                 str->type = V_ASN1_IA5STRING;
1513         }
1514
1515         /* If no EMAIL is wanted in the subject */
1516         if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) && (!email_dn))
1517             continue;
1518
1519         /* check some things */
1520         if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&
1521             (str->type != V_ASN1_IA5STRING)) {
1522             BIO_printf(bio_err,
1523                        "\nemailAddress type needs to be of type IA5STRING\n");
1524             goto end;
1525         }
1526         if ((str->type != V_ASN1_BMPSTRING)
1527             && (str->type != V_ASN1_UTF8STRING)) {
1528             j = ASN1_PRINTABLE_type(str->data, str->length);
1529             if (((j == V_ASN1_T61STRING) &&
1530                  (str->type != V_ASN1_T61STRING)) ||
1531                 ((j == V_ASN1_IA5STRING) &&
1532                  (str->type == V_ASN1_PRINTABLESTRING))) {
1533                 BIO_printf(bio_err,
1534                            "\nThe string contains characters that are illegal for the ASN.1 type\n");
1535                 goto end;
1536             }
1537         }
1538
1539         if (default_op)
1540             old_entry_print(obj, str);
1541     }
1542
1543     /* Ok, now we check the 'policy' stuff. */
1544     if ((subject = X509_NAME_new()) == NULL) {
1545         BIO_printf(bio_err, "Memory allocation failure\n");
1546         goto end;
1547     }
1548
1549     /* take a copy of the issuer name before we mess with it. */
1550     if (selfsign)
1551         CAname = X509_NAME_dup(name);
1552     else
1553         CAname = X509_NAME_dup(X509_get_subject_name(x509));
1554     if (CAname == NULL)
1555         goto end;
1556     str = str2 = NULL;
1557
1558     for (i = 0; i < sk_CONF_VALUE_num(policy); i++) {
1559         cv = sk_CONF_VALUE_value(policy, i); /* get the object id */
1560         if ((j = OBJ_txt2nid(cv->name)) == NID_undef) {
1561             BIO_printf(bio_err,
1562                        "%s:unknown object type in 'policy' configuration\n",
1563                        cv->name);
1564             goto end;
1565         }
1566         obj = OBJ_nid2obj(j);
1567
1568         last = -1;
1569         for (;;) {
1570             /* lookup the object in the supplied name list */
1571             j = X509_NAME_get_index_by_OBJ(name, obj, last);
1572             if (j < 0) {
1573                 if (last != -1)
1574                     break;
1575                 tne = NULL;
1576             } else {
1577                 tne = X509_NAME_get_entry(name, j);
1578             }
1579             last = j;
1580
1581             /* depending on the 'policy', decide what to do. */
1582             push = NULL;
1583             if (strcmp(cv->value, "optional") == 0) {
1584                 if (tne != NULL)
1585                     push = tne;
1586             } else if (strcmp(cv->value, "supplied") == 0) {
1587                 if (tne == NULL) {
1588                     BIO_printf(bio_err,
1589                                "The %s field needed to be supplied and was missing\n",
1590                                cv->name);
1591                     goto end;
1592                 } else
1593                     push = tne;
1594             } else if (strcmp(cv->value, "match") == 0) {
1595                 int last2;
1596
1597                 if (tne == NULL) {
1598                     BIO_printf(bio_err,
1599                                "The mandatory %s field was missing\n",
1600                                cv->name);
1601                     goto end;
1602                 }
1603
1604                 last2 = -1;
1605
1606  again2:
1607                 j = X509_NAME_get_index_by_OBJ(CAname, obj, last2);
1608                 if ((j < 0) && (last2 == -1)) {
1609                     BIO_printf(bio_err,
1610                                "The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",
1611                                cv->name);
1612                     goto end;
1613                 }
1614                 if (j >= 0) {
1615                     push = X509_NAME_get_entry(CAname, j);
1616                     str = X509_NAME_ENTRY_get_data(tne);
1617                     str2 = X509_NAME_ENTRY_get_data(push);
1618                     last2 = j;
1619                     if (ASN1_STRING_cmp(str, str2) != 0)
1620                         goto again2;
1621                 }
1622                 if (j < 0) {
1623                     BIO_printf(bio_err,
1624                                "The %s field needed to be the same in the\nCA certificate (%s) and the request (%s)\n",
1625                                cv->name,
1626                                ((str2 == NULL) ? "NULL" : (char *)str2->data),
1627                                ((str == NULL) ? "NULL" : (char *)str->data));
1628                     goto end;
1629                 }
1630             } else {
1631                 BIO_printf(bio_err,
1632                            "%s:invalid type in 'policy' configuration\n",
1633                            cv->value);
1634                 goto end;
1635             }
1636
1637             if (push != NULL) {
1638                 if (!X509_NAME_add_entry(subject, push, -1, 0)) {
1639                     X509_NAME_ENTRY_free(push);
1640                     BIO_printf(bio_err, "Memory allocation failure\n");
1641                     goto end;
1642                 }
1643             }
1644             if (j < 0)
1645                 break;
1646         }
1647     }
1648
1649     if (preserve) {
1650         X509_NAME_free(subject);
1651         /* subject=X509_NAME_dup(X509_REQ_get_subject_name(req)); */
1652         subject = X509_NAME_dup(name);
1653         if (subject == NULL)
1654             goto end;
1655     }
1656
1657     if (verbose)
1658         BIO_printf(bio_err,
1659                    "The subject name appears to be ok, checking data base for clashes\n");
1660
1661     /* Build the correct Subject if no e-mail is wanted in the subject */
1662     /*
1663      * and add it later on because of the method extensions are added
1664      * (altName)
1665      */
1666
1667     if (email_dn)
1668         dn_subject = subject;
1669     else {
1670         X509_NAME_ENTRY *tmpne;
1671         /*
1672          * Its best to dup the subject DN and then delete any email addresses
1673          * because this retains its structure.
1674          */
1675         if ((dn_subject = X509_NAME_dup(subject)) == NULL) {
1676             BIO_printf(bio_err, "Memory allocation failure\n");
1677             goto end;
1678         }
1679         while ((i = X509_NAME_get_index_by_NID(dn_subject,
1680                                                NID_pkcs9_emailAddress,
1681                                                -1)) >= 0) {
1682             tmpne = X509_NAME_get_entry(dn_subject, i);
1683             X509_NAME_delete_entry(dn_subject, i);
1684             X509_NAME_ENTRY_free(tmpne);
1685         }
1686     }
1687
1688     if (BN_is_zero(serial))
1689         row[DB_serial] = BUF_strdup("00");
1690     else
1691         row[DB_serial] = BN_bn2hex(serial);
1692     if (row[DB_serial] == NULL) {
1693         BIO_printf(bio_err, "Memory allocation failure\n");
1694         goto end;
1695     }
1696
1697     if (db->attributes.unique_subject) {
1698         OPENSSL_STRING *crow = row;
1699
1700         rrow = TXT_DB_get_by_index(db->db, DB_name, crow);
1701         if (rrow != NULL) {
1702             BIO_printf(bio_err,
1703                        "ERROR:There is already a certificate for %s\n",
1704                        row[DB_name]);
1705         }
1706     }
1707     if (rrow == NULL) {
1708         rrow = TXT_DB_get_by_index(db->db, DB_serial, row);
1709         if (rrow != NULL) {
1710             BIO_printf(bio_err,
1711                        "ERROR:Serial number %s has already been issued,\n",
1712                        row[DB_serial]);
1713             BIO_printf(bio_err,
1714                        "      check the database/serial_file for corruption\n");
1715         }
1716     }
1717
1718     if (rrow != NULL) {
1719         BIO_printf(bio_err, "The matching entry has the following details\n");
1720         if (rrow[DB_type][0] == 'E')
1721             p = "Expired";
1722         else if (rrow[DB_type][0] == 'R')
1723             p = "Revoked";
1724         else if (rrow[DB_type][0] == 'V')
1725             p = "Valid";
1726         else
1727             p = "\ninvalid type, Data base error\n";
1728         BIO_printf(bio_err, "Type          :%s\n", p);;
1729         if (rrow[DB_type][0] == 'R') {
1730             p = rrow[DB_exp_date];
1731             if (p == NULL)
1732                 p = "undef";
1733             BIO_printf(bio_err, "Was revoked on:%s\n", p);
1734         }
1735         p = rrow[DB_exp_date];
1736         if (p == NULL)
1737             p = "undef";
1738         BIO_printf(bio_err, "Expires on    :%s\n", p);
1739         p = rrow[DB_serial];
1740         if (p == NULL)
1741             p = "undef";
1742         BIO_printf(bio_err, "Serial Number :%s\n", p);
1743         p = rrow[DB_file];
1744         if (p == NULL)
1745             p = "undef";
1746         BIO_printf(bio_err, "File name     :%s\n", p);
1747         p = rrow[DB_name];
1748         if (p == NULL)
1749             p = "undef";
1750         BIO_printf(bio_err, "Subject Name  :%s\n", p);
1751         ok = -1;                /* This is now a 'bad' error. */
1752         goto end;
1753     }
1754
1755     /* We are now totally happy, lets make and sign the certificate */
1756     if (verbose)
1757         BIO_printf(bio_err,
1758                    "Everything appears to be ok, creating and signing the certificate\n");
1759
1760     if ((ret = X509_new()) == NULL)
1761         goto end;
1762
1763 #ifdef X509_V3
1764     /* Make it an X509 v3 certificate. */
1765     if (!X509_set_version(ret, 2))
1766         goto end;
1767 #endif
1768
1769     if (BN_to_ASN1_INTEGER(serial, X509_get_serialNumber(ret)) == NULL)
1770         goto end;
1771     if (selfsign) {
1772         if (!X509_set_issuer_name(ret, subject))
1773             goto end;
1774     } else {
1775         if (!X509_set_issuer_name(ret, X509_get_subject_name(x509)))
1776             goto end;
1777     }
1778
1779     if (strcmp(startdate, "today") == 0)
1780         X509_gmtime_adj(X509_get_notBefore(ret), 0);
1781     else
1782         ASN1_TIME_set_string(X509_get_notBefore(ret), startdate);
1783
1784     if (enddate == NULL)
1785         X509_time_adj_ex(X509_get_notAfter(ret), days, 0, NULL);
1786     else {
1787         int tdays;
1788         ASN1_TIME_set_string(X509_get_notAfter(ret), enddate);
1789         ASN1_TIME_diff(&tdays, NULL, NULL, X509_get_notAfter(ret));
1790         days = tdays;
1791     }
1792
1793     if (!X509_set_subject_name(ret, subject))
1794         goto end;
1795
1796     pktmp = X509_REQ_get_pubkey(req);
1797     i = X509_set_pubkey(ret, pktmp);
1798     EVP_PKEY_free(pktmp);
1799     if (!i)
1800         goto end;
1801
1802     /* Lets add the extensions, if there are any */
1803     if (ext_sect) {
1804         X509V3_CTX ctx;
1805         X509_set_version(ret, 2);
1806
1807         /* Initialize the context structure */
1808         if (selfsign)
1809             X509V3_set_ctx(&ctx, ret, ret, req, NULL, 0);
1810         else
1811             X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
1812
1813         if (extconf) {
1814             if (verbose)
1815                 BIO_printf(bio_err, "Extra configuration file found\n");
1816
1817             /* Use the extconf configuration db LHASH */
1818             X509V3_set_nconf(&ctx, extconf);
1819
1820             /* Test the structure (needed?) */
1821             /* X509V3_set_ctx_test(&ctx); */
1822
1823             /* Adds exts contained in the configuration file */
1824             if (!X509V3_EXT_add_nconf(extconf, &ctx, ext_sect, ret)) {
1825                 BIO_printf(bio_err,
1826                            "ERROR: adding extensions in section %s\n",
1827                            ext_sect);
1828                 ERR_print_errors(bio_err);
1829                 goto end;
1830             }
1831             if (verbose)
1832                 BIO_printf(bio_err,
1833                            "Successfully added extensions from file.\n");
1834         } else if (ext_sect) {
1835             /* We found extensions to be set from config file */
1836             X509V3_set_nconf(&ctx, lconf);
1837
1838             if (!X509V3_EXT_add_nconf(lconf, &ctx, ext_sect, ret)) {
1839                 BIO_printf(bio_err,
1840                            "ERROR: adding extensions in section %s\n",
1841                            ext_sect);
1842                 ERR_print_errors(bio_err);
1843                 goto end;
1844             }
1845
1846             if (verbose)
1847                 BIO_printf(bio_err,
1848                            "Successfully added extensions from config\n");
1849         }
1850     }
1851
1852     /* Copy extensions from request (if any) */
1853
1854     if (!copy_extensions(ret, req, ext_copy)) {
1855         BIO_printf(bio_err, "ERROR: adding extensions from request\n");
1856         ERR_print_errors(bio_err);
1857         goto end;
1858     }
1859
1860     /* Set the right value for the noemailDN option */
1861     if (email_dn == 0) {
1862         if (!X509_set_subject_name(ret, dn_subject))
1863             goto end;
1864     }
1865
1866     if (!default_op) {
1867         BIO_printf(bio_err, "Certificate Details:\n");
1868         /*
1869          * Never print signature details because signature not present
1870          */
1871         certopt |= X509_FLAG_NO_SIGDUMP | X509_FLAG_NO_SIGNAME;
1872         X509_print_ex(bio_err, ret, nameopt, certopt);
1873     }
1874
1875     BIO_printf(bio_err, "Certificate is to be certified until ");
1876     ASN1_TIME_print(bio_err, X509_get_notAfter(ret));
1877     if (days)
1878         BIO_printf(bio_err, " (%ld days)", days);
1879     BIO_printf(bio_err, "\n");
1880
1881     if (!batch) {
1882
1883         BIO_printf(bio_err, "Sign the certificate? [y/n]:");
1884         (void)BIO_flush(bio_err);
1885         buf[0] = '\0';
1886         if (!fgets(buf, sizeof(buf) - 1, stdin)) {
1887             BIO_printf(bio_err,
1888                        "CERTIFICATE WILL NOT BE CERTIFIED: I/O error\n");
1889             ok = 0;
1890             goto end;
1891         }
1892         if (!((buf[0] == 'y') || (buf[0] == 'Y'))) {
1893             BIO_printf(bio_err, "CERTIFICATE WILL NOT BE CERTIFIED\n");
1894             ok = 0;
1895             goto end;
1896         }
1897     }
1898
1899     pktmp = X509_get_pubkey(ret);
1900     if (EVP_PKEY_missing_parameters(pktmp) &&
1901         !EVP_PKEY_missing_parameters(pkey))
1902         EVP_PKEY_copy_parameters(pktmp, pkey);
1903     EVP_PKEY_free(pktmp);
1904
1905     if (!do_X509_sign(ret, pkey, dgst, sigopts))
1906         goto end;
1907
1908     /* We now just add it to the database */
1909     row[DB_type] = app_malloc(2, "row db type");
1910
1911     tm = X509_get_notAfter(ret);
1912     row[DB_exp_date] = app_malloc(tm->length + 1, "row expdate");
1913     memcpy(row[DB_exp_date], tm->data, tm->length);
1914     row[DB_exp_date][tm->length] = '\0';
1915
1916     row[DB_rev_date] = NULL;
1917
1918     /* row[DB_serial] done already */
1919     row[DB_file] = app_malloc(8, "row file");
1920     row[DB_name] = X509_NAME_oneline(X509_get_subject_name(ret), NULL, 0);
1921
1922     if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
1923         (row[DB_file] == NULL) || (row[DB_name] == NULL)) {
1924         BIO_printf(bio_err, "Memory allocation failure\n");
1925         goto end;
1926     }
1927     BUF_strlcpy(row[DB_file], "unknown", 8);
1928     row[DB_type][0] = 'V';
1929     row[DB_type][1] = '\0';
1930
1931     irow = app_malloc(sizeof(*irow) * (DB_NUMBER + 1), "row space");
1932     for (i = 0; i < DB_NUMBER; i++) {
1933         irow[i] = row[i];
1934         row[i] = NULL;
1935     }
1936     irow[DB_NUMBER] = NULL;
1937
1938     if (!TXT_DB_insert(db->db, irow)) {
1939         BIO_printf(bio_err, "failed to update database\n");
1940         BIO_printf(bio_err, "TXT_DB error number %ld\n", db->db->error);
1941         goto end;
1942     }
1943     ok = 1;
1944  end:
1945     for (i = 0; i < DB_NUMBER; i++)
1946         OPENSSL_free(row[i]);
1947
1948     X509_NAME_free(CAname);
1949     X509_NAME_free(subject);
1950     if (dn_subject != subject)
1951         X509_NAME_free(dn_subject);
1952     ASN1_UTCTIME_free(tmptm);
1953     if (ok <= 0)
1954         X509_free(ret);
1955     else
1956         *xret = ret;
1957     return (ok);
1958 }
1959
1960 static void write_new_certificate(BIO *bp, X509 *x, int output_der,
1961                                   int notext)
1962 {
1963
1964     if (output_der) {
1965         (void)i2d_X509_bio(bp, x);
1966         return;
1967     }
1968     if (!notext)
1969         X509_print(bp, x);
1970     PEM_write_bio_X509(bp, x);
1971 }
1972
1973 static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey,
1974                          X509 *x509, const EVP_MD *dgst,
1975                          STACK_OF(OPENSSL_STRING) *sigopts,
1976                          STACK_OF(CONF_VALUE) *policy, CA_DB *db,
1977                          BIGNUM *serial, char *subj, unsigned long chtype,
1978                          int multirdn, int email_dn, char *startdate,
1979                          char *enddate, long days, char *ext_sect,
1980                          CONF *lconf, int verbose, unsigned long certopt,
1981                          unsigned long nameopt, int default_op, int ext_copy)
1982 {
1983     STACK_OF(CONF_VALUE) *sk = NULL;
1984     LHASH_OF(CONF_VALUE) *parms = NULL;
1985     X509_REQ *req = NULL;
1986     CONF_VALUE *cv = NULL;
1987     NETSCAPE_SPKI *spki = NULL;
1988     char *type, *buf;
1989     EVP_PKEY *pktmp = NULL;
1990     X509_NAME *n = NULL;
1991     X509_NAME_ENTRY *ne = NULL;
1992     int ok = -1, i, j;
1993     long errline;
1994     int nid;
1995
1996     /*
1997      * Load input file into a hash table.  (This is just an easy
1998      * way to read and parse the file, then put it into a convenient
1999      * STACK format).
2000      */
2001     parms = CONF_load(NULL, infile, &errline);
2002     if (parms == NULL) {
2003         BIO_printf(bio_err, "error on line %ld of %s\n", errline, infile);
2004         ERR_print_errors(bio_err);
2005         goto end;
2006     }
2007
2008     sk = CONF_get_section(parms, "default");
2009     if (sk_CONF_VALUE_num(sk) == 0) {
2010         BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);
2011         CONF_free(parms);
2012         goto end;
2013     }
2014
2015     /*
2016      * Now create a dummy X509 request structure.  We don't actually
2017      * have an X509 request, but we have many of the components
2018      * (a public key, various DN components).  The idea is that we
2019      * put these components into the right X509 request structure
2020      * and we can use the same code as if you had a real X509 request.
2021      */
2022     req = X509_REQ_new();
2023     if (req == NULL) {
2024         ERR_print_errors(bio_err);
2025         goto end;
2026     }
2027
2028     /*
2029      * Build up the subject name set.
2030      */
2031     n = X509_REQ_get_subject_name(req);
2032
2033     for (i = 0;; i++) {
2034         if (sk_CONF_VALUE_num(sk) <= i)
2035             break;
2036
2037         cv = sk_CONF_VALUE_value(sk, i);
2038         type = cv->name;
2039         /*
2040          * Skip past any leading X. X: X, etc to allow for multiple instances
2041          */
2042         for (buf = cv->name; *buf; buf++)
2043             if ((*buf == ':') || (*buf == ',') || (*buf == '.')) {
2044                 buf++;
2045                 if (*buf)
2046                     type = buf;
2047                 break;
2048             }
2049
2050         buf = cv->value;
2051         if ((nid = OBJ_txt2nid(type)) == NID_undef) {
2052             if (strcmp(type, "SPKAC") == 0) {
2053                 spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
2054                 if (spki == NULL) {
2055                     BIO_printf(bio_err,
2056                                "unable to load Netscape SPKAC structure\n");
2057                     ERR_print_errors(bio_err);
2058                     goto end;
2059                 }
2060             }
2061             continue;
2062         }
2063
2064         if (!X509_NAME_add_entry_by_NID(n, nid, chtype,
2065                                         (unsigned char *)buf, -1, -1, 0))
2066             goto end;
2067     }
2068     if (spki == NULL) {
2069         BIO_printf(bio_err, "Netscape SPKAC structure not found in %s\n",
2070                    infile);
2071         goto end;
2072     }
2073
2074     /*
2075      * Now extract the key from the SPKI structure.
2076      */
2077
2078     BIO_printf(bio_err,
2079                "Check that the SPKAC request matches the signature\n");
2080
2081     if ((pktmp = NETSCAPE_SPKI_get_pubkey(spki)) == NULL) {
2082         BIO_printf(bio_err, "error unpacking SPKAC public key\n");
2083         goto end;
2084     }
2085
2086     j = NETSCAPE_SPKI_verify(spki, pktmp);
2087     if (j <= 0) {
2088         BIO_printf(bio_err,
2089                    "signature verification failed on SPKAC public key\n");
2090         goto end;
2091     }
2092     BIO_printf(bio_err, "Signature ok\n");
2093
2094     X509_REQ_set_pubkey(req, pktmp);
2095     EVP_PKEY_free(pktmp);
2096     ok = do_body(xret, pkey, x509, dgst, sigopts, policy, db, serial, subj,
2097                  chtype, multirdn, email_dn, startdate, enddate, days, 1,
2098                  verbose, req, ext_sect, lconf, certopt, nameopt, default_op,
2099                  ext_copy, 0);
2100  end:
2101     X509_REQ_free(req);
2102     CONF_free(parms);
2103     NETSCAPE_SPKI_free(spki);
2104     X509_NAME_ENTRY_free(ne);
2105
2106     return (ok);
2107 }
2108
2109 static int check_time_format(const char *str)
2110 {
2111     return ASN1_TIME_set_string(NULL, str);
2112 }
2113
2114 static int do_revoke(X509 *x509, CA_DB *db, int type, char *value)
2115 {
2116     ASN1_UTCTIME *tm = NULL;
2117     char *row[DB_NUMBER], **rrow, **irow;
2118     char *rev_str = NULL;
2119     BIGNUM *bn = NULL;
2120     int ok = -1, i;
2121
2122     for (i = 0; i < DB_NUMBER; i++)
2123         row[i] = NULL;
2124     row[DB_name] = X509_NAME_oneline(X509_get_subject_name(x509), NULL, 0);
2125     bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509), NULL);
2126     if (!bn)
2127         goto end;
2128     if (BN_is_zero(bn))
2129         row[DB_serial] = BUF_strdup("00");
2130     else
2131         row[DB_serial] = BN_bn2hex(bn);
2132     BN_free(bn);
2133     if ((row[DB_name] == NULL) || (row[DB_serial] == NULL)) {
2134         BIO_printf(bio_err, "Memory allocation failure\n");
2135         goto end;
2136     }
2137     /*
2138      * We have to lookup by serial number because name lookup skips revoked
2139      * certs
2140      */
2141     rrow = TXT_DB_get_by_index(db->db, DB_serial, row);
2142     if (rrow == NULL) {
2143         BIO_printf(bio_err,
2144                    "Adding Entry with serial number %s to DB for %s\n",
2145                    row[DB_serial], row[DB_name]);
2146
2147         /* We now just add it to the database */
2148         row[DB_type] = app_malloc(2, "row type");
2149
2150         tm = X509_get_notAfter(x509);
2151         row[DB_exp_date] = app_malloc(tm->length + 1, "row exp_data");
2152         memcpy(row[DB_exp_date], tm->data, tm->length);
2153         row[DB_exp_date][tm->length] = '\0';
2154
2155         row[DB_rev_date] = NULL;
2156
2157         /* row[DB_serial] done already */
2158         row[DB_file] = app_malloc(8, "row filename");
2159
2160         /* row[DB_name] done already */
2161
2162         BUF_strlcpy(row[DB_file], "unknown", 8);
2163         row[DB_type][0] = 'V';
2164         row[DB_type][1] = '\0';
2165
2166         irow = app_malloc(sizeof(*irow) * (DB_NUMBER + 1), "row ptr");
2167         for (i = 0; i < DB_NUMBER; i++) {
2168             irow[i] = row[i];
2169             row[i] = NULL;
2170         }
2171         irow[DB_NUMBER] = NULL;
2172
2173         if (!TXT_DB_insert(db->db, irow)) {
2174             BIO_printf(bio_err, "failed to update database\n");
2175             BIO_printf(bio_err, "TXT_DB error number %ld\n", db->db->error);
2176             goto end;
2177         }
2178
2179         /* Revoke Certificate */
2180         if (type == -1)
2181             ok = 1;
2182         else
2183             ok = do_revoke(x509, db, type, value);
2184
2185         goto end;
2186
2187     } else if (index_name_cmp_noconst(row, rrow)) {
2188         BIO_printf(bio_err, "ERROR:name does not match %s\n", row[DB_name]);
2189         goto end;
2190     } else if (type == -1) {
2191         BIO_printf(bio_err, "ERROR:Already present, serial number %s\n",
2192                    row[DB_serial]);
2193         goto end;
2194     } else if (rrow[DB_type][0] == 'R') {
2195         BIO_printf(bio_err, "ERROR:Already revoked, serial number %s\n",
2196                    row[DB_serial]);
2197         goto end;
2198     } else {
2199         BIO_printf(bio_err, "Revoking Certificate %s.\n", rrow[DB_serial]);
2200         rev_str = make_revocation_str(type, value);
2201         if (!rev_str) {
2202             BIO_printf(bio_err, "Error in revocation arguments\n");
2203             goto end;
2204         }
2205         rrow[DB_type][0] = 'R';
2206         rrow[DB_type][1] = '\0';
2207         rrow[DB_rev_date] = rev_str;
2208     }
2209     ok = 1;
2210  end:
2211     for (i = 0; i < DB_NUMBER; i++) {
2212         OPENSSL_free(row[i]);
2213     }
2214     return (ok);
2215 }
2216
2217 static int get_certificate_status(const char *serial, CA_DB *db)
2218 {
2219     char *row[DB_NUMBER], **rrow;
2220     int ok = -1, i;
2221
2222     /* Free Resources */
2223     for (i = 0; i < DB_NUMBER; i++)
2224         row[i] = NULL;
2225
2226     /* Malloc needed char spaces */
2227     row[DB_serial] = app_malloc(strlen(serial) + 2, "row serial#");
2228
2229     if (strlen(serial) % 2) {
2230         /*
2231          * Set the first char to 0
2232          */ ;
2233         row[DB_serial][0] = '0';
2234
2235         /* Copy String from serial to row[DB_serial] */
2236         memcpy(row[DB_serial] + 1, serial, strlen(serial));
2237         row[DB_serial][strlen(serial) + 1] = '\0';
2238     } else {
2239         /* Copy String from serial to row[DB_serial] */
2240         memcpy(row[DB_serial], serial, strlen(serial));
2241         row[DB_serial][strlen(serial)] = '\0';
2242     }
2243
2244     /* Make it Upper Case */
2245     for (i = 0; row[DB_serial][i] != '\0'; i++)
2246         row[DB_serial][i] = toupper((unsigned char)row[DB_serial][i]);
2247
2248     ok = 1;
2249
2250     /* Search for the certificate */
2251     rrow = TXT_DB_get_by_index(db->db, DB_serial, row);
2252     if (rrow == NULL) {
2253         BIO_printf(bio_err, "Serial %s not present in db.\n", row[DB_serial]);
2254         ok = -1;
2255         goto end;
2256     } else if (rrow[DB_type][0] == 'V') {
2257         BIO_printf(bio_err, "%s=Valid (%c)\n",
2258                    row[DB_serial], rrow[DB_type][0]);
2259         goto end;
2260     } else if (rrow[DB_type][0] == 'R') {
2261         BIO_printf(bio_err, "%s=Revoked (%c)\n",
2262                    row[DB_serial], rrow[DB_type][0]);
2263         goto end;
2264     } else if (rrow[DB_type][0] == 'E') {
2265         BIO_printf(bio_err, "%s=Expired (%c)\n",
2266                    row[DB_serial], rrow[DB_type][0]);
2267         goto end;
2268     } else if (rrow[DB_type][0] == 'S') {
2269         BIO_printf(bio_err, "%s=Suspended (%c)\n",
2270                    row[DB_serial], rrow[DB_type][0]);
2271         goto end;
2272     } else {
2273         BIO_printf(bio_err, "%s=Unknown (%c).\n",
2274                    row[DB_serial], rrow[DB_type][0]);
2275         ok = -1;
2276     }
2277  end:
2278     for (i = 0; i < DB_NUMBER; i++) {
2279         OPENSSL_free(row[i]);
2280     }
2281     return (ok);
2282 }
2283
2284 static int do_updatedb(CA_DB *db)
2285 {
2286     ASN1_UTCTIME *a_tm = NULL;
2287     int i, cnt = 0;
2288     int db_y2k, a_y2k;          /* flags = 1 if y >= 2000 */
2289     char **rrow, *a_tm_s;
2290
2291     a_tm = ASN1_UTCTIME_new();
2292
2293     /* get actual time and make a string */
2294     a_tm = X509_gmtime_adj(a_tm, 0);
2295     a_tm_s = (char *)OPENSSL_malloc(a_tm->length + 1);
2296
2297     memcpy(a_tm_s, a_tm->data, a_tm->length);
2298     a_tm_s[a_tm->length] = '\0';
2299
2300     if (strncmp(a_tm_s, "49", 2) <= 0)
2301         a_y2k = 1;
2302     else
2303         a_y2k = 0;
2304
2305     for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) {
2306         rrow = sk_OPENSSL_PSTRING_value(db->db->data, i);
2307
2308         if (rrow[DB_type][0] == 'V') {
2309             /* ignore entries that are not valid */
2310             if (strncmp(rrow[DB_exp_date], "49", 2) <= 0)
2311                 db_y2k = 1;
2312             else
2313                 db_y2k = 0;
2314
2315             if (db_y2k == a_y2k) {
2316                 /* all on the same y2k side */
2317                 if (strcmp(rrow[DB_exp_date], a_tm_s) <= 0) {
2318                     rrow[DB_type][0] = 'E';
2319                     rrow[DB_type][1] = '\0';
2320                     cnt++;
2321
2322                     BIO_printf(bio_err, "%s=Expired\n", rrow[DB_serial]);
2323                 }
2324             } else if (db_y2k < a_y2k) {
2325                 rrow[DB_type][0] = 'E';
2326                 rrow[DB_type][1] = '\0';
2327                 cnt++;
2328
2329                 BIO_printf(bio_err, "%s=Expired\n", rrow[DB_serial]);
2330             }
2331
2332         }
2333     }
2334
2335     ASN1_UTCTIME_free(a_tm);
2336     OPENSSL_free(a_tm_s);
2337     return (cnt);
2338 }
2339
2340 static const char *crl_reasons[] = {
2341     /* CRL reason strings */
2342     "unspecified",
2343     "keyCompromise",
2344     "CACompromise",
2345     "affiliationChanged",
2346     "superseded",
2347     "cessationOfOperation",
2348     "certificateHold",
2349     "removeFromCRL",
2350     /* Additional pseudo reasons */
2351     "holdInstruction",
2352     "keyTime",
2353     "CAkeyTime"
2354 };
2355
2356 #define NUM_REASONS OSSL_NELEM(crl_reasons)
2357
2358 /*
2359  * Given revocation information convert to a DB string. The format of the
2360  * string is: revtime[,reason,extra]. Where 'revtime' is the revocation time
2361  * (the current time). 'reason' is the optional CRL reason and 'extra' is any
2362  * additional argument
2363  */
2364
2365 char *make_revocation_str(int rev_type, char *rev_arg)
2366 {
2367     char *other = NULL, *str;
2368     const char *reason = NULL;
2369     ASN1_OBJECT *otmp;
2370     ASN1_UTCTIME *revtm = NULL;
2371     int i;
2372     switch (rev_type) {
2373     case REV_NONE:
2374         break;
2375
2376     case REV_CRL_REASON:
2377         for (i = 0; i < 8; i++) {
2378             if (strcasecmp(rev_arg, crl_reasons[i]) == 0) {
2379                 reason = crl_reasons[i];
2380                 break;
2381             }
2382         }
2383         if (reason == NULL) {
2384             BIO_printf(bio_err, "Unknown CRL reason %s\n", rev_arg);
2385             return NULL;
2386         }
2387         break;
2388
2389     case REV_HOLD:
2390         /* Argument is an OID */
2391
2392         otmp = OBJ_txt2obj(rev_arg, 0);
2393         ASN1_OBJECT_free(otmp);
2394
2395         if (otmp == NULL) {
2396             BIO_printf(bio_err, "Invalid object identifier %s\n", rev_arg);
2397             return NULL;
2398         }
2399
2400         reason = "holdInstruction";
2401         other = rev_arg;
2402         break;
2403
2404     case REV_KEY_COMPROMISE:
2405     case REV_CA_COMPROMISE:
2406
2407         /* Argument is the key compromise time  */
2408         if (!ASN1_GENERALIZEDTIME_set_string(NULL, rev_arg)) {
2409             BIO_printf(bio_err,
2410                        "Invalid time format %s. Need YYYYMMDDHHMMSSZ\n",
2411                        rev_arg);
2412             return NULL;
2413         }
2414         other = rev_arg;
2415         if (rev_type == REV_KEY_COMPROMISE)
2416             reason = "keyTime";
2417         else
2418             reason = "CAkeyTime";
2419
2420         break;
2421
2422     }
2423
2424     revtm = X509_gmtime_adj(NULL, 0);
2425
2426     if (!revtm)
2427         return NULL;
2428
2429     i = revtm->length + 1;
2430
2431     if (reason)
2432         i += strlen(reason) + 1;
2433     if (other)
2434         i += strlen(other) + 1;
2435
2436     str = app_malloc(i, "revocation reason");
2437     BUF_strlcpy(str, (char *)revtm->data, i);
2438     if (reason) {
2439         BUF_strlcat(str, ",", i);
2440         BUF_strlcat(str, reason, i);
2441     }
2442     if (other) {
2443         BUF_strlcat(str, ",", i);
2444         BUF_strlcat(str, other, i);
2445     }
2446     ASN1_UTCTIME_free(revtm);
2447     return str;
2448 }
2449
2450 /*-
2451  * Convert revocation field to X509_REVOKED entry
2452  * return code:
2453  * 0 error
2454  * 1 OK
2455  * 2 OK and some extensions added (i.e. V2 CRL)
2456  */
2457
2458 int make_revoked(X509_REVOKED *rev, const char *str)
2459 {
2460     char *tmp = NULL;
2461     int reason_code = -1;
2462     int i, ret = 0;
2463     ASN1_OBJECT *hold = NULL;
2464     ASN1_GENERALIZEDTIME *comp_time = NULL;
2465     ASN1_ENUMERATED *rtmp = NULL;
2466
2467     ASN1_TIME *revDate = NULL;
2468
2469     i = unpack_revinfo(&revDate, &reason_code, &hold, &comp_time, str);
2470
2471     if (i == 0)
2472         goto end;
2473
2474     if (rev && !X509_REVOKED_set_revocationDate(rev, revDate))
2475         goto end;
2476
2477     if (rev && (reason_code != OCSP_REVOKED_STATUS_NOSTATUS)) {
2478         rtmp = ASN1_ENUMERATED_new();
2479         if (!rtmp || !ASN1_ENUMERATED_set(rtmp, reason_code))
2480             goto end;
2481         if (!X509_REVOKED_add1_ext_i2d(rev, NID_crl_reason, rtmp, 0, 0))
2482             goto end;
2483     }
2484
2485     if (rev && comp_time) {
2486         if (!X509_REVOKED_add1_ext_i2d
2487             (rev, NID_invalidity_date, comp_time, 0, 0))
2488             goto end;
2489     }
2490     if (rev && hold) {
2491         if (!X509_REVOKED_add1_ext_i2d
2492             (rev, NID_hold_instruction_code, hold, 0, 0))
2493             goto end;
2494     }
2495
2496     if (reason_code != OCSP_REVOKED_STATUS_NOSTATUS)
2497         ret = 2;
2498     else
2499         ret = 1;
2500
2501  end:
2502
2503     OPENSSL_free(tmp);
2504     ASN1_OBJECT_free(hold);
2505     ASN1_GENERALIZEDTIME_free(comp_time);
2506     ASN1_ENUMERATED_free(rtmp);
2507     ASN1_TIME_free(revDate);
2508
2509     return ret;
2510 }
2511
2512 static int old_entry_print(ASN1_OBJECT *obj, ASN1_STRING *str)
2513 {
2514     char buf[25], *pbuf, *p;
2515     int j;
2516     j = i2a_ASN1_OBJECT(bio_err, obj);
2517     pbuf = buf;
2518     for (j = 22 - j; j > 0; j--)
2519         *(pbuf++) = ' ';
2520     *(pbuf++) = ':';
2521     *(pbuf++) = '\0';
2522     BIO_puts(bio_err, buf);
2523
2524     if (str->type == V_ASN1_PRINTABLESTRING)
2525         BIO_printf(bio_err, "PRINTABLE:'");
2526     else if (str->type == V_ASN1_T61STRING)
2527         BIO_printf(bio_err, "T61STRING:'");
2528     else if (str->type == V_ASN1_IA5STRING)
2529         BIO_printf(bio_err, "IA5STRING:'");
2530     else if (str->type == V_ASN1_UNIVERSALSTRING)
2531         BIO_printf(bio_err, "UNIVERSALSTRING:'");
2532     else
2533         BIO_printf(bio_err, "ASN.1 %2d:'", str->type);
2534
2535     p = (char *)str->data;
2536     for (j = str->length; j > 0; j--) {
2537         if ((*p >= ' ') && (*p <= '~'))
2538             BIO_printf(bio_err, "%c", *p);
2539         else if (*p & 0x80)
2540             BIO_printf(bio_err, "\\0x%02X", *p);
2541         else if ((unsigned char)*p == 0xf7)
2542             BIO_printf(bio_err, "^?");
2543         else
2544             BIO_printf(bio_err, "^%c", *p + '@');
2545         p++;
2546     }
2547     BIO_printf(bio_err, "'\n");
2548     return 1;
2549 }
2550
2551 int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold,
2552                    ASN1_GENERALIZEDTIME **pinvtm, const char *str)
2553 {
2554     char *tmp;
2555     char *rtime_str, *reason_str = NULL, *arg_str = NULL, *p;
2556     int reason_code = -1;
2557     int ret = 0;
2558     unsigned int i;
2559     ASN1_OBJECT *hold = NULL;
2560     ASN1_GENERALIZEDTIME *comp_time = NULL;
2561
2562     tmp = BUF_strdup(str);
2563     if (!tmp) {
2564         BIO_printf(bio_err, "memory allocation failure\n");
2565         goto end;
2566     }
2567
2568     p = strchr(tmp, ',');
2569
2570     rtime_str = tmp;
2571
2572     if (p) {
2573         *p = '\0';
2574         p++;
2575         reason_str = p;
2576         p = strchr(p, ',');
2577         if (p) {
2578             *p = '\0';
2579             arg_str = p + 1;
2580         }
2581     }
2582
2583     if (prevtm) {
2584         *prevtm = ASN1_UTCTIME_new();
2585         if (!*prevtm) {
2586             BIO_printf(bio_err, "memory allocation failure\n");
2587             goto end;
2588         }
2589         if (!ASN1_UTCTIME_set_string(*prevtm, rtime_str)) {
2590             BIO_printf(bio_err, "invalid revocation date %s\n", rtime_str);
2591             goto end;
2592         }
2593     }
2594     if (reason_str) {
2595         for (i = 0; i < NUM_REASONS; i++) {
2596             if (strcasecmp(reason_str, crl_reasons[i]) == 0) {
2597                 reason_code = i;
2598                 break;
2599             }
2600         }
2601         if (reason_code == OCSP_REVOKED_STATUS_NOSTATUS) {
2602             BIO_printf(bio_err, "invalid reason code %s\n", reason_str);
2603             goto end;
2604         }
2605
2606         if (reason_code == 7)
2607             reason_code = OCSP_REVOKED_STATUS_REMOVEFROMCRL;
2608         else if (reason_code == 8) { /* Hold instruction */
2609             if (!arg_str) {
2610                 BIO_printf(bio_err, "missing hold instruction\n");
2611                 goto end;
2612             }
2613             reason_code = OCSP_REVOKED_STATUS_CERTIFICATEHOLD;
2614             hold = OBJ_txt2obj(arg_str, 0);
2615
2616             if (!hold) {
2617                 BIO_printf(bio_err, "invalid object identifier %s\n",
2618                            arg_str);
2619                 goto end;
2620             }
2621             if (phold)
2622                 *phold = hold;
2623             else
2624                 ASN1_OBJECT_free(hold);
2625         } else if ((reason_code == 9) || (reason_code == 10)) {
2626             if (!arg_str) {
2627                 BIO_printf(bio_err, "missing compromised time\n");
2628                 goto end;
2629             }
2630             comp_time = ASN1_GENERALIZEDTIME_new();
2631             if (!comp_time) {
2632                 BIO_printf(bio_err, "memory allocation failure\n");
2633                 goto end;
2634             }
2635             if (!ASN1_GENERALIZEDTIME_set_string(comp_time, arg_str)) {
2636                 BIO_printf(bio_err, "invalid compromised time %s\n", arg_str);
2637                 goto end;
2638             }
2639             if (reason_code == 9)
2640                 reason_code = OCSP_REVOKED_STATUS_KEYCOMPROMISE;
2641             else
2642                 reason_code = OCSP_REVOKED_STATUS_CACOMPROMISE;
2643         }
2644     }
2645
2646     if (preason)
2647         *preason = reason_code;
2648     if (pinvtm) {
2649         *pinvtm = comp_time;
2650         comp_time = NULL;
2651     }
2652
2653     ret = 1;
2654
2655  end:
2656
2657     OPENSSL_free(tmp);
2658     ASN1_GENERALIZEDTIME_free(comp_time);
2659
2660     return ret;
2661 }