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