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