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