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