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