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