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