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