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