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