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