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