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