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