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