PR: 1997
[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 #ifndef _WIN32
856                 if (access(outdir,R_OK|W_OK|X_OK) != 0)
857 #else
858                 if (_access(outdir,R_OK|W_OK|X_OK) != 0)
859 #endif
860                         {
861                         BIO_printf(bio_err,"I am unable to access the %s directory\n",outdir);
862                         perror(outdir);
863                         goto err;
864                         }
865
866                 if (app_isdir(outdir)<=0)
867                         {
868                         BIO_printf(bio_err,"%s need to be a directory\n",outdir);
869                         perror(outdir);
870                         goto err;
871                         }
872 #endif
873                 }
874
875         /*****************************************************************/
876         /* we need to load the database file */
877         if ((dbfile=NCONF_get_string(conf,section,ENV_DATABASE)) == NULL)
878                 {
879                 lookup_fail(section,ENV_DATABASE);
880                 goto err;
881                 }
882         db = load_index(dbfile, &db_attr);
883         if (db == NULL) goto err;
884
885         /* Lets check some fields */
886         for (i=0; i<sk_OPENSSL_PSTRING_num(db->db->data); i++)
887                 {
888                 pp=sk_OPENSSL_PSTRING_value(db->db->data,i);
889                 if ((pp[DB_type][0] != DB_TYPE_REV) &&
890                         (pp[DB_rev_date][0] != '\0'))
891                         {
892                         BIO_printf(bio_err,"entry %d: not revoked yet, but has a revocation date\n",i+1);
893                         goto err;
894                         }
895                 if ((pp[DB_type][0] == DB_TYPE_REV) &&
896                         !make_revoked(NULL, pp[DB_rev_date]))
897                         {
898                         BIO_printf(bio_err," in entry %d\n", i+1);
899                         goto err;
900                         }
901                 if (!check_time_format((char *)pp[DB_exp_date]))
902                         {
903                         BIO_printf(bio_err,"entry %d: invalid expiry date\n",i+1);
904                         goto err;
905                         }
906                 p=pp[DB_serial];
907                 j=strlen(p);
908                 if (*p == '-')
909                         {
910                         p++;
911                         j--;
912                         }
913                 if ((j&1) || (j < 2))
914                         {
915                         BIO_printf(bio_err,"entry %d: bad serial number length (%d)\n",i+1,j);
916                         goto err;
917                         }
918                 while (*p)
919                         {
920                         if (!(  ((*p >= '0') && (*p <= '9')) ||
921                                 ((*p >= 'A') && (*p <= 'F')) ||
922                                 ((*p >= 'a') && (*p <= 'f')))  )
923                                 {
924                                 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);
925                                 goto err;
926                                 }
927                         p++;
928                         }
929                 }
930         if (verbose)
931                 {
932                 BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT); /* cannot fail */
933 #ifdef OPENSSL_SYS_VMS
934                 {
935                 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
936                 out = BIO_push(tmpbio, out);
937                 }
938 #endif
939                 TXT_DB_write(out,db->db);
940                 BIO_printf(bio_err,"%d entries loaded from the database\n",
941                            sk_OPENSSL_PSTRING_num(db->db->data));
942                 BIO_printf(bio_err,"generating index\n");
943                 }
944         
945         if (!index_index(db)) goto err;
946
947         /*****************************************************************/
948         /* Update the db file for expired certificates */
949         if (doupdatedb)
950                 {
951                 if (verbose)
952                         BIO_printf(bio_err, "Updating %s ...\n",
953                                                         dbfile);
954
955                 i = do_updatedb(db);
956                 if (i == -1)
957                         {
958                         BIO_printf(bio_err,"Malloc failure\n");
959                         goto err;
960                         }
961                 else if (i == 0)
962                         {
963                         if (verbose) BIO_printf(bio_err,
964                                         "No entries found to mark expired\n"); 
965                         }
966                 else
967                         {
968                         if (!save_index(dbfile,"new",db)) goto err;
969                                 
970                         if (!rotate_index(dbfile,"new","old")) goto err;
971                                 
972                         if (verbose) BIO_printf(bio_err,
973                                 "Done. %d entries marked as expired\n",i); 
974                         }
975                 }
976
977         /*****************************************************************/
978         /* Read extentions config file                                   */
979         if (extfile)
980                 {
981                 extconf = NCONF_new(NULL);
982                 if (NCONF_load(extconf,extfile,&errorline) <= 0)
983                         {
984                         if (errorline <= 0)
985                                 BIO_printf(bio_err, "ERROR: loading the config file '%s'\n",
986                                         extfile);
987                         else
988                                 BIO_printf(bio_err, "ERROR: on line %ld of config file '%s'\n",
989                                         errorline,extfile);
990                         ret = 1;
991                         goto err;
992                         }
993
994                 if (verbose)
995                         BIO_printf(bio_err, "Successfully loaded extensions file %s\n", extfile);
996
997                 /* We can have sections in the ext file */
998                 if (!extensions && !(extensions = NCONF_get_string(extconf, "default", "extensions")))
999                         extensions = "default";
1000                 }
1001
1002         /*****************************************************************/
1003         if (req || gencrl)
1004                 {
1005                 if (outfile != NULL)
1006                         {
1007                         if (BIO_write_filename(Sout,outfile) <= 0)
1008                                 {
1009                                 perror(outfile);
1010                                 goto err;
1011                                 }
1012                         }
1013                 else
1014                         {
1015                         BIO_set_fp(Sout,stdout,BIO_NOCLOSE|BIO_FP_TEXT);
1016 #ifdef OPENSSL_SYS_VMS
1017                         {
1018                         BIO *tmpbio = BIO_new(BIO_f_linebuffer());
1019                         Sout = BIO_push(tmpbio, Sout);
1020                         }
1021 #endif
1022                         }
1023                 }
1024
1025         if ((md == NULL) && ((md=NCONF_get_string(conf,
1026                 section,ENV_DEFAULT_MD)) == NULL))
1027                 {
1028                 lookup_fail(section,ENV_DEFAULT_MD);
1029                 goto err;
1030                 }
1031
1032         if (!strcmp(md, "default"))
1033                 {
1034                 int def_nid;
1035                 if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) <= 0)
1036                         {
1037                         BIO_puts(bio_err,"no default digest\n");
1038                         goto err;
1039                         }
1040                 md = (char *)OBJ_nid2sn(def_nid);
1041                 }
1042
1043         if ((dgst=EVP_get_digestbyname(md)) == NULL)
1044                 {
1045                 BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
1046                 goto err;
1047                 }
1048
1049         if (req)
1050                 {
1051                 if ((email_dn == 1) && ((tmp_email_dn=NCONF_get_string(conf,
1052                         section,ENV_DEFAULT_EMAIL_DN)) != NULL ))
1053                         {
1054                         if(strcmp(tmp_email_dn,"no") == 0)
1055                                 email_dn=0;
1056                         }
1057                 if (verbose)
1058                         BIO_printf(bio_err,"message digest is %s\n",
1059                                 OBJ_nid2ln(dgst->type));
1060                 if ((policy == NULL) && ((policy=NCONF_get_string(conf,
1061                         section,ENV_POLICY)) == NULL))
1062                         {
1063                         lookup_fail(section,ENV_POLICY);
1064                         goto err;
1065                         }
1066                 if (verbose)
1067                         BIO_printf(bio_err,"policy is %s\n",policy);
1068
1069                 if ((serialfile=NCONF_get_string(conf,section,ENV_SERIAL))
1070                         == NULL)
1071                         {
1072                         lookup_fail(section,ENV_SERIAL);
1073                         goto err;
1074                         }
1075
1076                 if (!extconf)
1077                         {
1078                         /* no '-extfile' option, so we look for extensions
1079                          * in the main configuration file */
1080                         if (!extensions)
1081                                 {
1082                                 extensions=NCONF_get_string(conf,section,
1083                                                                 ENV_EXTENSIONS);
1084                                 if (!extensions)
1085                                         ERR_clear_error();
1086                                 }
1087                         if (extensions)
1088                                 {
1089                                 /* Check syntax of file */
1090                                 X509V3_CTX ctx;
1091                                 X509V3_set_ctx_test(&ctx);
1092                                 X509V3_set_nconf(&ctx, conf);
1093                                 if (!X509V3_EXT_add_nconf(conf, &ctx, extensions,
1094                                                                 NULL))
1095                                         {
1096                                         BIO_printf(bio_err,
1097                                         "Error Loading extension section %s\n",
1098                                                                  extensions);
1099                                         ret = 1;
1100                                         goto err;
1101                                         }
1102                                 }
1103                         }
1104
1105                 if (startdate == NULL)
1106                         {
1107                         startdate=NCONF_get_string(conf,section,
1108                                 ENV_DEFAULT_STARTDATE);
1109                         if (startdate == NULL)
1110                                 ERR_clear_error();
1111                         }
1112                 if (startdate && !ASN1_TIME_set_string(NULL, startdate))
1113                         {
1114                         BIO_printf(bio_err,"start date is invalid, it should be YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ\n");
1115                         goto err;
1116                         }
1117                 if (startdate == NULL) startdate="today";
1118
1119                 if (enddate == NULL)
1120                         {
1121                         enddate=NCONF_get_string(conf,section,
1122                                 ENV_DEFAULT_ENDDATE);
1123                         if (enddate == NULL)
1124                                 ERR_clear_error();
1125                         }
1126                 if (enddate && !ASN1_TIME_set_string(NULL, enddate))
1127                         {
1128                         BIO_printf(bio_err,"end date is invalid, it should be YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ\n");
1129                         goto err;
1130                         }
1131
1132                 if (days == 0)
1133                         {
1134                         if(!NCONF_get_number(conf,section, ENV_DEFAULT_DAYS, &days))
1135                                 days = 0;
1136                         }
1137                 if (!enddate && (days == 0))
1138                         {
1139                         BIO_printf(bio_err,"cannot lookup how many days to certify for\n");
1140                         goto err;
1141                         }
1142
1143                 if ((serial=load_serial(serialfile, create_ser, NULL)) == NULL)
1144                         {
1145                         BIO_printf(bio_err,"error while loading serial number\n");
1146                         goto err;
1147                         }
1148                 if (verbose)
1149                         {
1150                         if (BN_is_zero(serial))
1151                                 BIO_printf(bio_err,"next serial number is 00\n");
1152                         else
1153                                 {
1154                                 if ((f=BN_bn2hex(serial)) == NULL) goto err;
1155                                 BIO_printf(bio_err,"next serial number is %s\n",f);
1156                                 OPENSSL_free(f);
1157                                 }
1158                         }
1159
1160                 if ((attribs=NCONF_get_section(conf,policy)) == NULL)
1161                         {
1162                         BIO_printf(bio_err,"unable to find 'section' for %s\n",policy);
1163                         goto err;
1164                         }
1165
1166                 if ((cert_sk=sk_X509_new_null()) == NULL)
1167                         {
1168                         BIO_printf(bio_err,"Memory allocation failure\n");
1169                         goto err;
1170                         }
1171                 if (spkac_file != NULL)
1172                         {
1173                         total++;
1174                         j=certify_spkac(&x,spkac_file,pkey,x509,dgst,attribs,db,
1175                                 serial,subj,chtype,multirdn,email_dn,startdate,enddate,days,extensions,
1176                                 conf,verbose,certopt,nameopt,default_op,ext_copy);
1177                         if (j < 0) goto err;
1178                         if (j > 0)
1179                                 {
1180                                 total_done++;
1181                                 BIO_printf(bio_err,"\n");
1182                                 if (!BN_add_word(serial,1)) goto err;
1183                                 if (!sk_X509_push(cert_sk,x))
1184                                         {
1185                                         BIO_printf(bio_err,"Memory allocation failure\n");
1186                                         goto err;
1187                                         }
1188                                 if (outfile)
1189                                         {
1190                                         output_der = 1;
1191                                         batch = 1;
1192                                         }
1193                                 }
1194                         }
1195                 if (ss_cert_file != NULL)
1196                         {
1197                         total++;
1198                         j=certify_cert(&x,ss_cert_file,pkey,x509,dgst,attribs,
1199                                 db,serial,subj,chtype,multirdn,email_dn,startdate,enddate,days,batch,
1200                                 extensions,conf,verbose, certopt, nameopt,
1201                                 default_op, ext_copy, e);
1202                         if (j < 0) goto err;
1203                         if (j > 0)
1204                                 {
1205                                 total_done++;
1206                                 BIO_printf(bio_err,"\n");
1207                                 if (!BN_add_word(serial,1)) goto err;
1208                                 if (!sk_X509_push(cert_sk,x))
1209                                         {
1210                                         BIO_printf(bio_err,"Memory allocation failure\n");
1211                                         goto err;
1212                                         }
1213                                 }
1214                         }
1215                 if (infile != NULL)
1216                         {
1217                         total++;
1218                         j=certify(&x,infile,pkey,x509p,dgst,attribs,db,
1219                                 serial,subj,chtype,multirdn,email_dn,startdate,enddate,days,batch,
1220                                 extensions,conf,verbose, certopt, nameopt,
1221                                 default_op, ext_copy, selfsign);
1222                         if (j < 0) goto err;
1223                         if (j > 0)
1224                                 {
1225                                 total_done++;
1226                                 BIO_printf(bio_err,"\n");
1227                                 if (!BN_add_word(serial,1)) goto err;
1228                                 if (!sk_X509_push(cert_sk,x))
1229                                         {
1230                                         BIO_printf(bio_err,"Memory allocation failure\n");
1231                                         goto err;
1232                                         }
1233                                 }
1234                         }
1235                 for (i=0; i<argc; i++)
1236                         {
1237                         total++;
1238                         j=certify(&x,argv[i],pkey,x509p,dgst,attribs,db,
1239                                 serial,subj,chtype,multirdn,email_dn,startdate,enddate,days,batch,
1240                                 extensions,conf,verbose, certopt, nameopt,
1241                                 default_op, ext_copy, selfsign);
1242                         if (j < 0) goto err;
1243                         if (j > 0)
1244                                 {
1245                                 total_done++;
1246                                 BIO_printf(bio_err,"\n");
1247                                 if (!BN_add_word(serial,1)) goto err;
1248                                 if (!sk_X509_push(cert_sk,x))
1249                                         {
1250                                         BIO_printf(bio_err,"Memory allocation failure\n");
1251                                         goto err;
1252                                         }
1253                                 }
1254                         }       
1255                 /* we have a stack of newly certified certificates
1256                  * and a data base and serial number that need
1257                  * updating */
1258
1259                 if (sk_X509_num(cert_sk) > 0)
1260                         {
1261                         if (!batch)
1262                                 {
1263                                 BIO_printf(bio_err,"\n%d out of %d certificate requests certified, commit? [y/n]",total_done,total);
1264                                 (void)BIO_flush(bio_err);
1265                                 buf[0][0]='\0';
1266                                 fgets(buf[0],10,stdin);
1267                                 if ((buf[0][0] != 'y') && (buf[0][0] != 'Y'))
1268                                         {
1269                                         BIO_printf(bio_err,"CERTIFICATION CANCELED\n"); 
1270                                         ret=0;
1271                                         goto err;
1272                                         }
1273                                 }
1274
1275                         BIO_printf(bio_err,"Write out database with %d new entries\n",sk_X509_num(cert_sk));
1276
1277                         if (!save_serial(serialfile,"new",serial,NULL)) goto err;
1278
1279                         if (!save_index(dbfile, "new", db)) goto err;
1280                         }
1281         
1282                 if (verbose)
1283                         BIO_printf(bio_err,"writing new certificates\n");
1284                 for (i=0; i<sk_X509_num(cert_sk); i++)
1285                         {
1286                         int k;
1287                         char *n;
1288
1289                         x=sk_X509_value(cert_sk,i);
1290
1291                         j=x->cert_info->serialNumber->length;
1292                         p=(const char *)x->cert_info->serialNumber->data;
1293                         
1294                         if(strlen(outdir) >= (size_t)(j ? BSIZE-j*2-6 : BSIZE-8))
1295                                 {
1296                                 BIO_printf(bio_err,"certificate file name too long\n");
1297                                 goto err;
1298                                 }
1299
1300                         strcpy(buf[2],outdir);
1301
1302 #ifndef OPENSSL_SYS_VMS
1303                         BUF_strlcat(buf[2],"/",sizeof(buf[2]));
1304 #endif
1305
1306                         n=(char *)&(buf[2][strlen(buf[2])]);
1307                         if (j > 0)
1308                                 {
1309                                 for (k=0; k<j; k++)
1310                                         {
1311                                         if (n >= &(buf[2][sizeof(buf[2])]))
1312                                                 break;
1313                                         BIO_snprintf(n,
1314                                                      &buf[2][0] + sizeof(buf[2]) - n,
1315                                                      "%02X",(unsigned char)*(p++));
1316                                         n+=2;
1317                                         }
1318                                 }
1319                         else
1320                                 {
1321                                 *(n++)='0';
1322                                 *(n++)='0';
1323                                 }
1324                         *(n++)='.'; *(n++)='p'; *(n++)='e'; *(n++)='m';
1325                         *n='\0';
1326                         if (verbose)
1327                                 BIO_printf(bio_err,"writing %s\n",buf[2]);
1328
1329                         if (BIO_write_filename(Cout,buf[2]) <= 0)
1330                                 {
1331                                 perror(buf[2]);
1332                                 goto err;
1333                                 }
1334                         write_new_certificate(Cout,x, 0, notext);
1335                         write_new_certificate(Sout,x, output_der, notext);
1336                         }
1337
1338                 if (sk_X509_num(cert_sk))
1339                         {
1340                         /* Rename the database and the serial file */
1341                         if (!rotate_serial(serialfile,"new","old")) goto err;
1342
1343                         if (!rotate_index(dbfile,"new","old")) goto err;
1344
1345                         BIO_printf(bio_err,"Data Base Updated\n");
1346                         }
1347                 }
1348         
1349         /*****************************************************************/
1350         if (gencrl)
1351                 {
1352                 int crl_v2 = 0;
1353                 if (!crl_ext)
1354                         {
1355                         crl_ext=NCONF_get_string(conf,section,ENV_CRLEXT);
1356                         if (!crl_ext)
1357                                 ERR_clear_error();
1358                         }
1359                 if (crl_ext)
1360                         {
1361                         /* Check syntax of file */
1362                         X509V3_CTX ctx;
1363                         X509V3_set_ctx_test(&ctx);
1364                         X509V3_set_nconf(&ctx, conf);
1365                         if (!X509V3_EXT_add_nconf(conf, &ctx, crl_ext, NULL))
1366                                 {
1367                                 BIO_printf(bio_err,
1368                                  "Error Loading CRL extension section %s\n",
1369                                                                  crl_ext);
1370                                 ret = 1;
1371                                 goto err;
1372                                 }
1373                         }
1374
1375                 if ((crlnumberfile=NCONF_get_string(conf,section,ENV_CRLNUMBER))
1376                         != NULL)
1377                         if ((crlnumber=load_serial(crlnumberfile,0,NULL)) == NULL)
1378                                 {
1379                                 BIO_printf(bio_err,"error while loading CRL number\n");
1380                                 goto err;
1381                                 }
1382
1383                 if (!crldays && !crlhours && !crlsec)
1384                         {
1385                         if (!NCONF_get_number(conf,section,
1386                                 ENV_DEFAULT_CRL_DAYS, &crldays))
1387                                 crldays = 0;
1388                         if (!NCONF_get_number(conf,section,
1389                                 ENV_DEFAULT_CRL_HOURS, &crlhours))
1390                                 crlhours = 0;
1391                         }
1392                 if ((crldays == 0) && (crlhours == 0) && (crlsec == 0))
1393                         {
1394                         BIO_printf(bio_err,"cannot lookup how long until the next CRL is issued\n");
1395                         goto err;
1396                         }
1397
1398                 if (verbose) BIO_printf(bio_err,"making CRL\n");
1399                 if ((crl=X509_CRL_new()) == NULL) goto err;
1400                 if (!X509_CRL_set_issuer_name(crl, X509_get_subject_name(x509))) goto err;
1401
1402                 tmptm = ASN1_TIME_new();
1403                 if (!tmptm) goto err;
1404                 X509_gmtime_adj(tmptm,0);
1405                 X509_CRL_set_lastUpdate(crl, tmptm);    
1406                 X509_time_adj_ex(tmptm, crldays, crlhours*60*60 + crlsec, NULL);
1407                 X509_CRL_set_nextUpdate(crl, tmptm);    
1408
1409                 ASN1_TIME_free(tmptm);
1410
1411                 for (i=0; i<sk_OPENSSL_PSTRING_num(db->db->data); i++)
1412                         {
1413                         pp=sk_OPENSSL_PSTRING_value(db->db->data,i);
1414                         if (pp[DB_type][0] == DB_TYPE_REV)
1415                                 {
1416                                 if ((r=X509_REVOKED_new()) == NULL) goto err;
1417                                 j = make_revoked(r, pp[DB_rev_date]);
1418                                 if (!j) goto err;
1419                                 if (j == 2) crl_v2 = 1;
1420                                 if (!BN_hex2bn(&serial, pp[DB_serial]))
1421                                         goto err;
1422                                 tmpser = BN_to_ASN1_INTEGER(serial, NULL);
1423                                 BN_free(serial);
1424                                 serial = NULL;
1425                                 if (!tmpser)
1426                                         goto err;
1427                                 X509_REVOKED_set_serialNumber(r, tmpser);
1428                                 ASN1_INTEGER_free(tmpser);
1429                                 X509_CRL_add0_revoked(crl,r);
1430                                 }
1431                         }
1432
1433                 /* sort the data so it will be written in serial
1434                  * number order */
1435                 X509_CRL_sort(crl);
1436
1437                 /* we now have a CRL */
1438                 if (verbose) BIO_printf(bio_err,"signing CRL\n");
1439
1440                 /* Add any extensions asked for */
1441
1442                 if (crl_ext || crlnumberfile != NULL)
1443                         {
1444                         X509V3_CTX crlctx;
1445                         X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0);
1446                         X509V3_set_nconf(&crlctx, conf);
1447
1448                         if (crl_ext)
1449                                 if (!X509V3_EXT_CRL_add_nconf(conf, &crlctx,
1450                                         crl_ext, crl)) goto err;
1451                         if (crlnumberfile != NULL)
1452                                 {
1453                                 tmpser = BN_to_ASN1_INTEGER(crlnumber, NULL);
1454                                 if (!tmpser) goto err;
1455                                 X509_CRL_add1_ext_i2d(crl,NID_crl_number,tmpser,0,0);
1456                                 ASN1_INTEGER_free(tmpser);
1457                                 crl_v2 = 1;
1458                                 if (!BN_add_word(crlnumber,1)) goto err;
1459                                 }
1460                         }
1461                 if (crl_ext || crl_v2)
1462                         {
1463                         if (!X509_CRL_set_version(crl, 1))
1464                                 goto err; /* version 2 CRL */
1465                         }
1466
1467                 
1468                 if (crlnumberfile != NULL)      /* we have a CRL number that need updating */
1469                         if (!save_serial(crlnumberfile,"new",crlnumber,NULL)) goto err;
1470
1471                 if (crlnumber)
1472                         {
1473                         BN_free(crlnumber);
1474                         crlnumber = NULL;
1475                         }
1476
1477                 if (!X509_CRL_sign(crl,pkey,dgst)) goto err;
1478
1479                 PEM_write_bio_X509_CRL(Sout,crl);
1480
1481                 if (crlnumberfile != NULL)      /* Rename the crlnumber file */
1482                         if (!rotate_serial(crlnumberfile,"new","old")) goto err;
1483
1484                 }
1485         /*****************************************************************/
1486         if (dorevoke)
1487                 {
1488                 if (infile == NULL) 
1489                         {
1490                         BIO_printf(bio_err,"no input files\n");
1491                         goto err;
1492                         }
1493                 else
1494                         {
1495                         X509 *revcert;
1496                         revcert=load_cert(bio_err, infile, FORMAT_PEM,
1497                                 NULL, e, infile);
1498                         if (revcert == NULL)
1499                                 goto err;
1500                         j=do_revoke(revcert,db, rev_type, rev_arg);
1501                         if (j <= 0) goto err;
1502                         X509_free(revcert);
1503
1504                         if (!save_index(dbfile, "new", db)) goto err;
1505
1506                         if (!rotate_index(dbfile, "new", "old")) goto err;
1507
1508                         BIO_printf(bio_err,"Data Base Updated\n"); 
1509                         }
1510                 }
1511         /*****************************************************************/
1512         ret=0;
1513 err:
1514         if(tofree)
1515                 OPENSSL_free(tofree);
1516         BIO_free_all(Cout);
1517         BIO_free_all(Sout);
1518         BIO_free_all(out);
1519         BIO_free_all(in);
1520
1521         if (cert_sk)
1522                 sk_X509_pop_free(cert_sk,X509_free);
1523
1524         if (ret) ERR_print_errors(bio_err);
1525         app_RAND_write_file(randfile, bio_err);
1526         if (free_key && key)
1527                 OPENSSL_free(key);
1528         BN_free(serial);
1529         BN_free(crlnumber);
1530         free_index(db);
1531         EVP_PKEY_free(pkey);
1532         if (x509) X509_free(x509);
1533         X509_CRL_free(crl);
1534         NCONF_free(conf);
1535         NCONF_free(extconf);
1536         OBJ_cleanup();
1537         apps_shutdown();
1538         OPENSSL_EXIT(ret);
1539         }
1540
1541 static void lookup_fail(const char *name, const char *tag)
1542         {
1543         BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag);
1544         }
1545
1546 static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1547              const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db,
1548              BIGNUM *serial, char *subj,unsigned long chtype, int multirdn, int email_dn, char *startdate, char *enddate,
1549              long days, int batch, char *ext_sect, CONF *lconf, int verbose,
1550              unsigned long certopt, unsigned long nameopt, int default_op,
1551              int ext_copy, int selfsign)
1552         {
1553         X509_REQ *req=NULL;
1554         BIO *in=NULL;
1555         EVP_PKEY *pktmp=NULL;
1556         int ok= -1,i;
1557
1558         in=BIO_new(BIO_s_file());
1559
1560         if (BIO_read_filename(in,infile) <= 0)
1561                 {
1562                 perror(infile);
1563                 goto err;
1564                 }
1565         if ((req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL)) == NULL)
1566                 {
1567                 BIO_printf(bio_err,"Error reading certificate request in %s\n",
1568                         infile);
1569                 goto err;
1570                 }
1571         if (verbose)
1572                 X509_REQ_print(bio_err,req);
1573
1574         BIO_printf(bio_err,"Check that the request matches the signature\n");
1575
1576         if (selfsign && !X509_REQ_check_private_key(req,pkey))
1577                 {
1578                 BIO_printf(bio_err,"Certificate request and CA private key do not match\n");
1579                 ok=0;
1580                 goto err;
1581                 }
1582         if ((pktmp=X509_REQ_get_pubkey(req)) == NULL)
1583                 {
1584                 BIO_printf(bio_err,"error unpacking public key\n");
1585                 goto err;
1586                 }
1587         i=X509_REQ_verify(req,pktmp);
1588         EVP_PKEY_free(pktmp);
1589         if (i < 0)
1590                 {
1591                 ok=0;
1592                 BIO_printf(bio_err,"Signature verification problems....\n");
1593                 goto err;
1594                 }
1595         if (i == 0)
1596                 {
1597                 ok=0;
1598                 BIO_printf(bio_err,"Signature did not match the certificate request\n");
1599                 goto err;
1600                 }
1601         else
1602                 BIO_printf(bio_err,"Signature ok\n");
1603
1604         ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,chtype,multirdn, email_dn,
1605                 startdate,enddate,days,batch,verbose,req,ext_sect,lconf,
1606                 certopt, nameopt, default_op, ext_copy, selfsign);
1607
1608 err:
1609         if (req != NULL) X509_REQ_free(req);
1610         if (in != NULL) BIO_free(in);
1611         return(ok);
1612         }
1613
1614 static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1615              const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db,
1616              BIGNUM *serial, char *subj, unsigned long chtype, int multirdn, int email_dn, char *startdate, char *enddate,
1617              long days, int batch, char *ext_sect, CONF *lconf, int verbose,
1618              unsigned long certopt, unsigned long nameopt, int default_op,
1619              int ext_copy, ENGINE *e)
1620         {
1621         X509 *req=NULL;
1622         X509_REQ *rreq=NULL;
1623         EVP_PKEY *pktmp=NULL;
1624         int ok= -1,i;
1625
1626         if ((req=load_cert(bio_err, infile, FORMAT_PEM, NULL, e, infile)) == NULL)
1627                 goto err;
1628         if (verbose)
1629                 X509_print(bio_err,req);
1630
1631         BIO_printf(bio_err,"Check that the request matches the signature\n");
1632
1633         if ((pktmp=X509_get_pubkey(req)) == NULL)
1634                 {
1635                 BIO_printf(bio_err,"error unpacking public key\n");
1636                 goto err;
1637                 }
1638         i=X509_verify(req,pktmp);
1639         EVP_PKEY_free(pktmp);
1640         if (i < 0)
1641                 {
1642                 ok=0;
1643                 BIO_printf(bio_err,"Signature verification problems....\n");
1644                 goto err;
1645                 }
1646         if (i == 0)
1647                 {
1648                 ok=0;
1649                 BIO_printf(bio_err,"Signature did not match the certificate\n");
1650                 goto err;
1651                 }
1652         else
1653                 BIO_printf(bio_err,"Signature ok\n");
1654
1655         if ((rreq=X509_to_X509_REQ(req,NULL,EVP_md5())) == NULL)
1656                 goto err;
1657
1658         ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,chtype,multirdn,email_dn,startdate,enddate,
1659                 days,batch,verbose,rreq,ext_sect,lconf, certopt, nameopt, default_op,
1660                 ext_copy, 0);
1661
1662 err:
1663         if (rreq != NULL) X509_REQ_free(rreq);
1664         if (req != NULL) X509_free(req);
1665         return(ok);
1666         }
1667
1668 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
1669              STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial, char *subj,
1670              unsigned long chtype, int multirdn,
1671              int email_dn, char *startdate, char *enddate, long days, int batch,
1672              int verbose, X509_REQ *req, char *ext_sect, CONF *lconf,
1673              unsigned long certopt, unsigned long nameopt, int default_op,
1674              int ext_copy, int selfsign)
1675         {
1676         X509_NAME *name=NULL,*CAname=NULL,*subject=NULL, *dn_subject=NULL;
1677         ASN1_UTCTIME *tm,*tmptm;
1678         ASN1_STRING *str,*str2;
1679         ASN1_OBJECT *obj;
1680         X509 *ret=NULL;
1681         X509_CINF *ci;
1682         X509_NAME_ENTRY *ne;
1683         X509_NAME_ENTRY *tne,*push;
1684         EVP_PKEY *pktmp;
1685         int ok= -1,i,j,last,nid;
1686         const char *p;
1687         CONF_VALUE *cv;
1688         OPENSSL_STRING row[DB_NUMBER];
1689         OPENSSL_STRING *irow=NULL;
1690         OPENSSL_STRING *rrow=NULL;
1691         char buf[25];
1692
1693         tmptm=ASN1_UTCTIME_new();
1694         if (tmptm == NULL)
1695                 {
1696                 BIO_printf(bio_err,"malloc error\n");
1697                 return(0);
1698                 }
1699
1700         for (i=0; i<DB_NUMBER; i++)
1701                 row[i]=NULL;
1702
1703         if (subj)
1704                 {
1705                 X509_NAME *n = parse_name(subj, chtype, multirdn);
1706
1707                 if (!n)
1708                         {
1709                         ERR_print_errors(bio_err);
1710                         goto err;
1711                         }
1712                 X509_REQ_set_subject_name(req,n);
1713                 req->req_info->enc.modified = 1;
1714                 X509_NAME_free(n);
1715                 }
1716
1717         if (default_op)
1718                 BIO_printf(bio_err,"The Subject's Distinguished Name is as follows\n");
1719
1720         name=X509_REQ_get_subject_name(req);
1721         for (i=0; i<X509_NAME_entry_count(name); i++)
1722                 {
1723                 ne= X509_NAME_get_entry(name,i);
1724                 str=X509_NAME_ENTRY_get_data(ne);
1725                 obj=X509_NAME_ENTRY_get_object(ne);
1726
1727                 if (msie_hack)
1728                         {
1729                         /* assume all type should be strings */
1730                         nid=OBJ_obj2nid(ne->object);
1731
1732                         if (str->type == V_ASN1_UNIVERSALSTRING)
1733                                 ASN1_UNIVERSALSTRING_to_string(str);
1734
1735                         if ((str->type == V_ASN1_IA5STRING) &&
1736                                 (nid != NID_pkcs9_emailAddress))
1737                                 str->type=V_ASN1_T61STRING;
1738
1739                         if ((nid == NID_pkcs9_emailAddress) &&
1740                                 (str->type == V_ASN1_PRINTABLESTRING))
1741                                 str->type=V_ASN1_IA5STRING;
1742                         }
1743
1744                 /* If no EMAIL is wanted in the subject */
1745                 if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) && (!email_dn))
1746                         continue;
1747
1748                 /* check some things */
1749                 if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&
1750                         (str->type != V_ASN1_IA5STRING))
1751                         {
1752                         BIO_printf(bio_err,"\nemailAddress type needs to be of type IA5STRING\n");
1753                         goto err;
1754                         }
1755                 if ((str->type != V_ASN1_BMPSTRING) && (str->type != V_ASN1_UTF8STRING))
1756                         {
1757                         j=ASN1_PRINTABLE_type(str->data,str->length);
1758                         if (    ((j == V_ASN1_T61STRING) &&
1759                                  (str->type != V_ASN1_T61STRING)) ||
1760                                 ((j == V_ASN1_IA5STRING) &&
1761                                  (str->type == V_ASN1_PRINTABLESTRING)))
1762                                 {
1763                                 BIO_printf(bio_err,"\nThe string contains characters that are illegal for the ASN.1 type\n");
1764                                 goto err;
1765                                 }
1766                         }
1767
1768                 if (default_op)
1769                         old_entry_print(bio_err, obj, str);
1770                 }
1771
1772         /* Ok, now we check the 'policy' stuff. */
1773         if ((subject=X509_NAME_new()) == NULL)
1774                 {
1775                 BIO_printf(bio_err,"Memory allocation failure\n");
1776                 goto err;
1777                 }
1778
1779         /* take a copy of the issuer name before we mess with it. */
1780         if (selfsign)
1781                 CAname=X509_NAME_dup(name);
1782         else
1783                 CAname=X509_NAME_dup(x509->cert_info->subject);
1784         if (CAname == NULL) goto err;
1785         str=str2=NULL;
1786
1787         for (i=0; i<sk_CONF_VALUE_num(policy); i++)
1788                 {
1789                 cv=sk_CONF_VALUE_value(policy,i); /* get the object id */
1790                 if ((j=OBJ_txt2nid(cv->name)) == NID_undef)
1791                         {
1792                         BIO_printf(bio_err,"%s:unknown object type in 'policy' configuration\n",cv->name);
1793                         goto err;
1794                         }
1795                 obj=OBJ_nid2obj(j);
1796
1797                 last= -1;
1798                 for (;;)
1799                         {
1800                         /* lookup the object in the supplied name list */
1801                         j=X509_NAME_get_index_by_OBJ(name,obj,last);
1802                         if (j < 0)
1803                                 {
1804                                 if (last != -1) break;
1805                                 tne=NULL;
1806                                 }
1807                         else
1808                                 {
1809                                 tne=X509_NAME_get_entry(name,j);
1810                                 }
1811                         last=j;
1812
1813                         /* depending on the 'policy', decide what to do. */
1814                         push=NULL;
1815                         if (strcmp(cv->value,"optional") == 0)
1816                                 {
1817                                 if (tne != NULL)
1818                                         push=tne;
1819                                 }
1820                         else if (strcmp(cv->value,"supplied") == 0)
1821                                 {
1822                                 if (tne == NULL)
1823                                         {
1824                                         BIO_printf(bio_err,"The %s field needed to be supplied and was missing\n",cv->name);
1825                                         goto err;
1826                                         }
1827                                 else
1828                                         push=tne;
1829                                 }
1830                         else if (strcmp(cv->value,"match") == 0)
1831                                 {
1832                                 int last2;
1833
1834                                 if (tne == NULL)
1835                                         {
1836                                         BIO_printf(bio_err,"The mandatory %s field was missing\n",cv->name);
1837                                         goto err;
1838                                         }
1839
1840                                 last2= -1;
1841
1842 again2:
1843                                 j=X509_NAME_get_index_by_OBJ(CAname,obj,last2);
1844                                 if ((j < 0) && (last2 == -1))
1845                                         {
1846                                         BIO_printf(bio_err,"The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",cv->name);
1847                                         goto err;
1848                                         }
1849                                 if (j >= 0)
1850                                         {
1851                                         push=X509_NAME_get_entry(CAname,j);
1852                                         str=X509_NAME_ENTRY_get_data(tne);
1853                                         str2=X509_NAME_ENTRY_get_data(push);
1854                                         last2=j;
1855                                         if (ASN1_STRING_cmp(str,str2) != 0)
1856                                                 goto again2;
1857                                         }
1858                                 if (j < 0)
1859                                         {
1860                                         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));
1861                                         goto err;
1862                                         }
1863                                 }
1864                         else
1865                                 {
1866                                 BIO_printf(bio_err,"%s:invalid type in 'policy' configuration\n",cv->value);
1867                                 goto err;
1868                                 }
1869
1870                         if (push != NULL)
1871                                 {
1872                                 if (!X509_NAME_add_entry(subject,push, -1, 0))
1873                                         {
1874                                         if (push != NULL)
1875                                                 X509_NAME_ENTRY_free(push);
1876                                         BIO_printf(bio_err,"Memory allocation failure\n");
1877                                         goto err;
1878                                         }
1879                                 }
1880                         if (j < 0) break;
1881                         }
1882                 }
1883
1884         if (preserve)
1885                 {
1886                 X509_NAME_free(subject);
1887                 /* subject=X509_NAME_dup(X509_REQ_get_subject_name(req)); */
1888                 subject=X509_NAME_dup(name);
1889                 if (subject == NULL) goto err;
1890                 }
1891
1892         if (verbose)
1893                 BIO_printf(bio_err,"The subject name appears to be ok, checking data base for clashes\n");
1894
1895         /* Build the correct Subject if no e-mail is wanted in the subject */
1896         /* and add it later on because of the method extensions are added (altName) */
1897          
1898         if (email_dn)
1899                 dn_subject = subject;
1900         else
1901                 {
1902                 X509_NAME_ENTRY *tmpne;
1903                 /* Its best to dup the subject DN and then delete any email
1904                  * addresses because this retains its structure.
1905                  */
1906                 if (!(dn_subject = X509_NAME_dup(subject)))
1907                         {
1908                         BIO_printf(bio_err,"Memory allocation failure\n");
1909                         goto err;
1910                         }
1911                 while((i = X509_NAME_get_index_by_NID(dn_subject,
1912                                         NID_pkcs9_emailAddress, -1)) >= 0)
1913                         {
1914                         tmpne = X509_NAME_get_entry(dn_subject, i);
1915                         X509_NAME_delete_entry(dn_subject, i);
1916                         X509_NAME_ENTRY_free(tmpne);
1917                         }
1918                 }
1919
1920         if (BN_is_zero(serial))
1921                 row[DB_serial]=BUF_strdup("00");
1922         else
1923                 row[DB_serial]=BN_bn2hex(serial);
1924         if (row[DB_serial] == NULL)
1925                 {
1926                 BIO_printf(bio_err,"Memory allocation failure\n");
1927                 goto err;
1928                 }
1929
1930         if (db->attributes.unique_subject)
1931                 {
1932                 OPENSSL_STRING *crow=row;
1933
1934                 rrow=TXT_DB_get_by_index(db->db,DB_name,crow);
1935                 if (rrow != NULL)
1936                         {
1937                         BIO_printf(bio_err,
1938                                 "ERROR:There is already a certificate for %s\n",
1939                                 row[DB_name]);
1940                         }
1941                 }
1942         if (rrow == NULL)
1943                 {
1944                 rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
1945                 if (rrow != NULL)
1946                         {
1947                         BIO_printf(bio_err,"ERROR:Serial number %s has already been issued,\n",
1948                                 row[DB_serial]);
1949                         BIO_printf(bio_err,"      check the database/serial_file for corruption\n");
1950                         }
1951                 }
1952
1953         if (rrow != NULL)
1954                 {
1955                 BIO_printf(bio_err,
1956                         "The matching entry has the following details\n");
1957                 if (rrow[DB_type][0] == 'E')
1958                         p="Expired";
1959                 else if (rrow[DB_type][0] == 'R')
1960                         p="Revoked";
1961                 else if (rrow[DB_type][0] == 'V')
1962                         p="Valid";
1963                 else
1964                         p="\ninvalid type, Data base error\n";
1965                 BIO_printf(bio_err,"Type          :%s\n",p);;
1966                 if (rrow[DB_type][0] == 'R')
1967                         {
1968                         p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1969                         BIO_printf(bio_err,"Was revoked on:%s\n",p);
1970                         }
1971                 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1972                 BIO_printf(bio_err,"Expires on    :%s\n",p);
1973                 p=rrow[DB_serial]; if (p == NULL) p="undef";
1974                 BIO_printf(bio_err,"Serial Number :%s\n",p);
1975                 p=rrow[DB_file]; if (p == NULL) p="undef";
1976                 BIO_printf(bio_err,"File name     :%s\n",p);
1977                 p=rrow[DB_name]; if (p == NULL) p="undef";
1978                 BIO_printf(bio_err,"Subject Name  :%s\n",p);
1979                 ok= -1; /* This is now a 'bad' error. */
1980                 goto err;
1981                 }
1982
1983         /* We are now totally happy, lets make and sign the certificate */
1984         if (verbose)
1985                 BIO_printf(bio_err,"Everything appears to be ok, creating and signing the certificate\n");
1986
1987         if ((ret=X509_new()) == NULL) goto err;
1988         ci=ret->cert_info;
1989
1990 #ifdef X509_V3
1991         /* Make it an X509 v3 certificate. */
1992         if (!X509_set_version(ret,2)) goto err;
1993 #endif
1994
1995         if (BN_to_ASN1_INTEGER(serial,ci->serialNumber) == NULL)
1996                 goto err;
1997         if (selfsign)
1998                 {
1999                 if (!X509_set_issuer_name(ret,subject))
2000                         goto err;
2001                 }
2002         else
2003                 {
2004                 if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))
2005                         goto err;
2006                 }
2007
2008         if (strcmp(startdate,"today") == 0)
2009                 X509_gmtime_adj(X509_get_notBefore(ret),0);
2010         else ASN1_TIME_set_string(X509_get_notBefore(ret),startdate);
2011
2012         if (enddate == NULL)
2013                 X509_time_adj_ex(X509_get_notAfter(ret),days, 0, NULL);
2014         else ASN1_TIME_set_string(X509_get_notAfter(ret),enddate);
2015
2016         if (!X509_set_subject_name(ret,subject)) goto err;
2017
2018         pktmp=X509_REQ_get_pubkey(req);
2019         i = X509_set_pubkey(ret,pktmp);
2020         EVP_PKEY_free(pktmp);
2021         if (!i) goto err;
2022
2023         /* Lets add the extensions, if there are any */
2024         if (ext_sect)
2025                 {
2026                 X509V3_CTX ctx;
2027                 if (ci->version == NULL)
2028                         if ((ci->version=ASN1_INTEGER_new()) == NULL)
2029                                 goto err;
2030                 ASN1_INTEGER_set(ci->version,2); /* version 3 certificate */
2031
2032                 /* Free the current entries if any, there should not
2033                  * be any I believe */
2034                 if (ci->extensions != NULL)
2035                         sk_X509_EXTENSION_pop_free(ci->extensions,
2036                                                    X509_EXTENSION_free);
2037
2038                 ci->extensions = NULL;
2039
2040                 /* Initialize the context structure */
2041                 if (selfsign)
2042                         X509V3_set_ctx(&ctx, ret, ret, req, NULL, 0);
2043                 else
2044                         X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
2045
2046                 if (extconf)
2047                         {
2048                         if (verbose)
2049                                 BIO_printf(bio_err, "Extra configuration file found\n");
2050  
2051                         /* Use the extconf configuration db LHASH */
2052                         X509V3_set_nconf(&ctx, extconf);
2053  
2054                         /* Test the structure (needed?) */
2055                         /* X509V3_set_ctx_test(&ctx); */
2056
2057                         /* Adds exts contained in the configuration file */
2058                         if (!X509V3_EXT_add_nconf(extconf, &ctx, ext_sect,ret))
2059                                 {
2060                                 BIO_printf(bio_err,
2061                                     "ERROR: adding extensions in section %s\n",
2062                                                                 ext_sect);
2063                                 ERR_print_errors(bio_err);
2064                                 goto err;
2065                                 }
2066                         if (verbose)
2067                                 BIO_printf(bio_err, "Successfully added extensions from file.\n");
2068                         }
2069                 else if (ext_sect)
2070                         {
2071                         /* We found extensions to be set from config file */
2072                         X509V3_set_nconf(&ctx, lconf);
2073
2074                         if(!X509V3_EXT_add_nconf(lconf, &ctx, ext_sect, ret))
2075                                 {
2076                                 BIO_printf(bio_err, "ERROR: adding extensions in section %s\n", ext_sect);
2077                                 ERR_print_errors(bio_err);
2078                                 goto err;
2079                                 }
2080
2081                         if (verbose) 
2082                                 BIO_printf(bio_err, "Successfully added extensions from config\n");
2083                         }
2084                 }
2085
2086         /* Copy extensions from request (if any) */
2087
2088         if (!copy_extensions(ret, req, ext_copy))
2089                 {
2090                 BIO_printf(bio_err, "ERROR: adding extensions from request\n");
2091                 ERR_print_errors(bio_err);
2092                 goto err;
2093                 }
2094
2095         /* Set the right value for the noemailDN option */
2096         if( email_dn == 0 )
2097                 {
2098                 if (!X509_set_subject_name(ret,dn_subject)) goto err;
2099                 }
2100
2101         if (!default_op)
2102                 {
2103                 BIO_printf(bio_err, "Certificate Details:\n");
2104                 /* Never print signature details because signature not present */
2105                 certopt |= X509_FLAG_NO_SIGDUMP | X509_FLAG_NO_SIGNAME;
2106                 X509_print_ex(bio_err, ret, nameopt, certopt); 
2107                 }
2108
2109         BIO_printf(bio_err,"Certificate is to be certified until ");
2110         ASN1_TIME_print(bio_err,X509_get_notAfter(ret));
2111         if (days) BIO_printf(bio_err," (%ld days)",days);
2112         BIO_printf(bio_err, "\n");
2113
2114         if (!batch)
2115                 {
2116
2117                 BIO_printf(bio_err,"Sign the certificate? [y/n]:");
2118                 (void)BIO_flush(bio_err);
2119                 buf[0]='\0';
2120                 fgets(buf,sizeof(buf)-1,stdin);
2121                 if (!((buf[0] == 'y') || (buf[0] == 'Y')))
2122                         {
2123                         BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED\n");
2124                         ok=0;
2125                         goto err;
2126                         }
2127                 }
2128
2129         pktmp=X509_get_pubkey(ret);
2130         if (EVP_PKEY_missing_parameters(pktmp) &&
2131                 !EVP_PKEY_missing_parameters(pkey))
2132                 EVP_PKEY_copy_parameters(pktmp,pkey);
2133         EVP_PKEY_free(pktmp);
2134
2135         if (!X509_sign(ret,pkey,dgst))
2136                 goto err;
2137
2138         /* We now just add it to the database */
2139         row[DB_type]=(char *)OPENSSL_malloc(2);
2140
2141         tm=X509_get_notAfter(ret);
2142         row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2143         memcpy(row[DB_exp_date],tm->data,tm->length);
2144         row[DB_exp_date][tm->length]='\0';
2145
2146         row[DB_rev_date]=NULL;
2147
2148         /* row[DB_serial] done already */
2149         row[DB_file]=(char *)OPENSSL_malloc(8);
2150         row[DB_name]=X509_NAME_oneline(X509_get_subject_name(ret),NULL,0);
2151
2152         if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2153                 (row[DB_file] == NULL) || (row[DB_name] == NULL))
2154                 {
2155                 BIO_printf(bio_err,"Memory allocation failure\n");
2156                 goto err;
2157                 }
2158         BUF_strlcpy(row[DB_file],"unknown",8);
2159         row[DB_type][0]='V';
2160         row[DB_type][1]='\0';
2161
2162         if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2163                 {
2164                 BIO_printf(bio_err,"Memory allocation failure\n");
2165                 goto err;
2166                 }
2167
2168         for (i=0; i<DB_NUMBER; i++)
2169                 {
2170                 irow[i]=row[i];
2171                 row[i]=NULL;
2172                 }
2173         irow[DB_NUMBER]=NULL;
2174
2175         if (!TXT_DB_insert(db->db,irow))
2176                 {
2177                 BIO_printf(bio_err,"failed to update database\n");
2178                 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->db->error);
2179                 goto err;
2180                 }
2181         ok=1;
2182 err:
2183         for (i=0; i<DB_NUMBER; i++)
2184                 if (row[i] != NULL) OPENSSL_free(row[i]);
2185
2186         if (CAname != NULL)
2187                 X509_NAME_free(CAname);
2188         if (subject != NULL)
2189                 X509_NAME_free(subject);
2190         if ((dn_subject != NULL) && !email_dn)
2191                 X509_NAME_free(dn_subject);
2192         if (tmptm != NULL)
2193                 ASN1_UTCTIME_free(tmptm);
2194         if (ok <= 0)
2195                 {
2196                 if (ret != NULL) X509_free(ret);
2197                 ret=NULL;
2198                 }
2199         else
2200                 *xret=ret;
2201         return(ok);
2202         }
2203
2204 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext)
2205         {
2206
2207         if (output_der)
2208                 {
2209                 (void)i2d_X509_bio(bp,x);
2210                 return;
2211                 }
2212 #if 0
2213         /* ??? Not needed since X509_print prints all this stuff anyway */
2214         f=X509_NAME_oneline(X509_get_issuer_name(x),buf,256);
2215         BIO_printf(bp,"issuer :%s\n",f);
2216
2217         f=X509_NAME_oneline(X509_get_subject_name(x),buf,256);
2218         BIO_printf(bp,"subject:%s\n",f);
2219
2220         BIO_puts(bp,"serial :");
2221         i2a_ASN1_INTEGER(bp,x->cert_info->serialNumber);
2222         BIO_puts(bp,"\n\n");
2223 #endif
2224         if (!notext)X509_print(bp,x);
2225         PEM_write_bio_X509(bp,x);
2226         }
2227
2228 static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
2229              const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db,
2230              BIGNUM *serial, char *subj,unsigned long chtype, int multirdn, int email_dn, char *startdate, char *enddate,
2231              long days, char *ext_sect, CONF *lconf, int verbose, unsigned long certopt,
2232              unsigned long nameopt, int default_op, int ext_copy)
2233         {
2234         STACK_OF(CONF_VALUE) *sk=NULL;
2235         LHASH_OF(CONF_VALUE) *parms=NULL;
2236         X509_REQ *req=NULL;
2237         CONF_VALUE *cv=NULL;
2238         NETSCAPE_SPKI *spki = NULL;
2239         X509_REQ_INFO *ri;
2240         char *type,*buf;
2241         EVP_PKEY *pktmp=NULL;
2242         X509_NAME *n=NULL;
2243         X509_NAME_ENTRY *ne=NULL;
2244         int ok= -1,i,j;
2245         long errline;
2246         int nid;
2247
2248         /*
2249          * Load input file into a hash table.  (This is just an easy
2250          * way to read and parse the file, then put it into a convenient
2251          * STACK format).
2252          */
2253         parms=CONF_load(NULL,infile,&errline);
2254         if (parms == NULL)
2255                 {
2256                 BIO_printf(bio_err,"error on line %ld of %s\n",errline,infile);
2257                 ERR_print_errors(bio_err);
2258                 goto err;
2259                 }
2260
2261         sk=CONF_get_section(parms, "default");
2262         if (sk_CONF_VALUE_num(sk) == 0)
2263                 {
2264                 BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);
2265                 CONF_free(parms);
2266                 goto err;
2267                 }
2268
2269         /*
2270          * Now create a dummy X509 request structure.  We don't actually
2271          * have an X509 request, but we have many of the components
2272          * (a public key, various DN components).  The idea is that we
2273          * put these components into the right X509 request structure
2274          * and we can use the same code as if you had a real X509 request.
2275          */
2276         req=X509_REQ_new();
2277         if (req == NULL)
2278                 {
2279                 ERR_print_errors(bio_err);
2280                 goto err;
2281                 }
2282
2283         /*
2284          * Build up the subject name set.
2285          */
2286         ri=req->req_info;
2287         n = ri->subject;
2288
2289         for (i = 0; ; i++)
2290                 {
2291                 if (sk_CONF_VALUE_num(sk) <= i) break;
2292
2293                 cv=sk_CONF_VALUE_value(sk,i);
2294                 type=cv->name;
2295                 /* Skip past any leading X. X: X, etc to allow for
2296                  * multiple instances
2297                  */
2298                 for (buf = cv->name; *buf ; buf++)
2299                         if ((*buf == ':') || (*buf == ',') || (*buf == '.'))
2300                                 {
2301                                 buf++;
2302                                 if (*buf) type = buf;
2303                                 break;
2304                                 }
2305
2306                 buf=cv->value;
2307                 if ((nid=OBJ_txt2nid(type)) == NID_undef)
2308                         {
2309                         if (strcmp(type, "SPKAC") == 0)
2310                                 {
2311                                 spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
2312                                 if (spki == NULL)
2313                                         {
2314                                         BIO_printf(bio_err,"unable to load Netscape SPKAC structure\n");
2315                                         ERR_print_errors(bio_err);
2316                                         goto err;
2317                                         }
2318                                 }
2319                         continue;
2320                         }
2321
2322                 /*
2323                 if ((nid == NID_pkcs9_emailAddress) && (email_dn == 0))
2324                         continue;
2325                 */
2326                 
2327                 j=ASN1_PRINTABLE_type((unsigned char *)buf,-1);
2328                 if (fix_data(nid, &j) == 0)
2329                         {
2330                         BIO_printf(bio_err,
2331                                 "invalid characters in string %s\n",buf);
2332                         goto err;
2333                         }
2334
2335                 if ((ne=X509_NAME_ENTRY_create_by_NID(&ne,nid,j,
2336                         (unsigned char *)buf,
2337                         strlen(buf))) == NULL)
2338                         goto err;
2339
2340                 if (!X509_NAME_add_entry(n,ne,-1, 0)) goto err;
2341                 }
2342         if (spki == NULL)
2343                 {
2344                 BIO_printf(bio_err,"Netscape SPKAC structure not found in %s\n",
2345                         infile);
2346                 goto err;
2347                 }
2348
2349         /*
2350          * Now extract the key from the SPKI structure.
2351          */
2352
2353         BIO_printf(bio_err,"Check that the SPKAC request matches the signature\n");
2354
2355         if ((pktmp=NETSCAPE_SPKI_get_pubkey(spki)) == NULL)
2356                 {
2357                 BIO_printf(bio_err,"error unpacking SPKAC public key\n");
2358                 goto err;
2359                 }
2360
2361         j = NETSCAPE_SPKI_verify(spki, pktmp);
2362         if (j <= 0)
2363                 {
2364                 BIO_printf(bio_err,"signature verification failed on SPKAC public key\n");
2365                 goto err;
2366                 }
2367         BIO_printf(bio_err,"Signature ok\n");
2368
2369         X509_REQ_set_pubkey(req,pktmp);
2370         EVP_PKEY_free(pktmp);
2371         ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,chtype,multirdn,email_dn,startdate,enddate,
2372                    days,1,verbose,req,ext_sect,lconf, certopt, nameopt, default_op,
2373                         ext_copy, 0);
2374 err:
2375         if (req != NULL) X509_REQ_free(req);
2376         if (parms != NULL) CONF_free(parms);
2377         if (spki != NULL) NETSCAPE_SPKI_free(spki);
2378         if (ne != NULL) X509_NAME_ENTRY_free(ne);
2379
2380         return(ok);
2381         }
2382
2383 static int fix_data(int nid, int *type)
2384         {
2385         if (nid == NID_pkcs9_emailAddress)
2386                 *type=V_ASN1_IA5STRING;
2387         if ((nid == NID_commonName) && (*type == V_ASN1_IA5STRING))
2388                 *type=V_ASN1_T61STRING;
2389         if ((nid == NID_pkcs9_challengePassword) && (*type == V_ASN1_IA5STRING))
2390                 *type=V_ASN1_T61STRING;
2391         if ((nid == NID_pkcs9_unstructuredName) && (*type == V_ASN1_T61STRING))
2392                 return(0);
2393         if (nid == NID_pkcs9_unstructuredName)
2394                 *type=V_ASN1_IA5STRING;
2395         return(1);
2396         }
2397
2398 static int check_time_format(const char *str)
2399         {
2400         return ASN1_TIME_set_string(NULL, str);
2401         }
2402
2403 static int do_revoke(X509 *x509, CA_DB *db, int type, char *value)
2404         {
2405         ASN1_UTCTIME *tm=NULL;
2406         char *row[DB_NUMBER],**rrow,**irow;
2407         char *rev_str = NULL;
2408         BIGNUM *bn = NULL;
2409         int ok=-1,i;
2410
2411         for (i=0; i<DB_NUMBER; i++)
2412                 row[i]=NULL;
2413         row[DB_name]=X509_NAME_oneline(X509_get_subject_name(x509),NULL,0);
2414         bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509),NULL);
2415         if (!bn)
2416                 goto err;
2417         if (BN_is_zero(bn))
2418                 row[DB_serial]=BUF_strdup("00");
2419         else
2420                 row[DB_serial]=BN_bn2hex(bn);
2421         BN_free(bn);
2422         if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
2423                 {
2424                 BIO_printf(bio_err,"Memory allocation failure\n");
2425                 goto err;
2426                 }
2427         /* We have to lookup by serial number because name lookup
2428          * skips revoked certs
2429          */
2430         rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
2431         if (rrow == NULL)
2432                 {
2433                 BIO_printf(bio_err,"Adding Entry with serial number %s to DB for %s\n", row[DB_serial], row[DB_name]);
2434
2435                 /* We now just add it to the database */
2436                 row[DB_type]=(char *)OPENSSL_malloc(2);
2437
2438                 tm=X509_get_notAfter(x509);
2439                 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2440                 memcpy(row[DB_exp_date],tm->data,tm->length);
2441                 row[DB_exp_date][tm->length]='\0';
2442
2443                 row[DB_rev_date]=NULL;
2444
2445                 /* row[DB_serial] done already */
2446                 row[DB_file]=(char *)OPENSSL_malloc(8);
2447
2448                 /* row[DB_name] done already */
2449
2450                 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2451                         (row[DB_file] == NULL))
2452                         {
2453                         BIO_printf(bio_err,"Memory allocation failure\n");
2454                         goto err;
2455                         }
2456                 BUF_strlcpy(row[DB_file],"unknown",8);
2457                 row[DB_type][0]='V';
2458                 row[DB_type][1]='\0';
2459
2460                 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2461                         {
2462                         BIO_printf(bio_err,"Memory allocation failure\n");
2463                         goto err;
2464                         }
2465
2466                 for (i=0; i<DB_NUMBER; i++)
2467                         {
2468                         irow[i]=row[i];
2469                         row[i]=NULL;
2470                         }
2471                 irow[DB_NUMBER]=NULL;
2472
2473                 if (!TXT_DB_insert(db->db,irow))
2474                         {
2475                         BIO_printf(bio_err,"failed to update database\n");
2476                         BIO_printf(bio_err,"TXT_DB error number %ld\n",db->db->error);
2477                         goto err;
2478                         }
2479
2480                 /* Revoke Certificate */
2481                 ok = do_revoke(x509,db, type, value);
2482
2483                 goto err;
2484
2485                 }
2486         else if (index_name_cmp_noconst(row, rrow))
2487                 {
2488                 BIO_printf(bio_err,"ERROR:name does not match %s\n",
2489                            row[DB_name]);
2490                 goto err;
2491                 }
2492         else if (rrow[DB_type][0]=='R')
2493                 {
2494                 BIO_printf(bio_err,"ERROR:Already revoked, serial number %s\n",
2495                            row[DB_serial]);
2496                 goto err;
2497                 }
2498         else
2499                 {
2500                 BIO_printf(bio_err,"Revoking Certificate %s.\n", rrow[DB_serial]);
2501                 rev_str = make_revocation_str(type, value);
2502                 if (!rev_str)
2503                         {
2504                         BIO_printf(bio_err, "Error in revocation arguments\n");
2505                         goto err;
2506                         }
2507                 rrow[DB_type][0]='R';
2508                 rrow[DB_type][1]='\0';
2509                 rrow[DB_rev_date] = rev_str;
2510                 }
2511         ok=1;
2512 err:
2513         for (i=0; i<DB_NUMBER; i++)
2514                 {
2515                 if (row[i] != NULL) 
2516                         OPENSSL_free(row[i]);
2517                 }
2518         return(ok);
2519         }
2520
2521 static int get_certificate_status(const char *serial, CA_DB *db)
2522         {
2523         char *row[DB_NUMBER],**rrow;
2524         int ok=-1,i;
2525
2526         /* Free Resources */
2527         for (i=0; i<DB_NUMBER; i++)
2528                 row[i]=NULL;
2529
2530         /* Malloc needed char spaces */
2531         row[DB_serial] = OPENSSL_malloc(strlen(serial) + 2);
2532         if (row[DB_serial] == NULL)
2533                 {
2534                 BIO_printf(bio_err,"Malloc failure\n");
2535                 goto err;
2536                 }
2537
2538         if (strlen(serial) % 2)
2539                 {
2540                 /* Set the first char to 0 */;
2541                 row[DB_serial][0]='0';
2542
2543                 /* Copy String from serial to row[DB_serial] */
2544                 memcpy(row[DB_serial]+1, serial, strlen(serial));
2545                 row[DB_serial][strlen(serial)+1]='\0';
2546                 }
2547         else
2548                 {
2549                 /* Copy String from serial to row[DB_serial] */
2550                 memcpy(row[DB_serial], serial, strlen(serial));
2551                 row[DB_serial][strlen(serial)]='\0';
2552                 }
2553                         
2554         /* Make it Upper Case */
2555         for (i=0; row[DB_serial][i] != '\0'; i++)
2556                 row[DB_serial][i] = toupper(row[DB_serial][i]);
2557         
2558
2559         ok=1;
2560
2561         /* Search for the certificate */
2562         rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
2563         if (rrow == NULL)
2564                 {
2565                 BIO_printf(bio_err,"Serial %s not present in db.\n",
2566                                  row[DB_serial]);
2567                 ok=-1;
2568                 goto err;
2569                 }
2570         else if (rrow[DB_type][0]=='V')
2571                 {
2572                 BIO_printf(bio_err,"%s=Valid (%c)\n",
2573                         row[DB_serial], rrow[DB_type][0]);
2574                 goto err;
2575                 }
2576         else if (rrow[DB_type][0]=='R')
2577                 {
2578                 BIO_printf(bio_err,"%s=Revoked (%c)\n",
2579                         row[DB_serial], rrow[DB_type][0]);
2580                 goto err;
2581                 }
2582         else if (rrow[DB_type][0]=='E')
2583                 {
2584                 BIO_printf(bio_err,"%s=Expired (%c)\n",
2585                         row[DB_serial], rrow[DB_type][0]);
2586                 goto err;
2587                 }
2588         else if (rrow[DB_type][0]=='S')
2589                 {
2590                 BIO_printf(bio_err,"%s=Suspended (%c)\n",
2591                         row[DB_serial], rrow[DB_type][0]);
2592                 goto err;
2593                 }
2594         else
2595                 {
2596                 BIO_printf(bio_err,"%s=Unknown (%c).\n",
2597                         row[DB_serial], rrow[DB_type][0]);
2598                 ok=-1;
2599                 }
2600 err:
2601         for (i=0; i<DB_NUMBER; i++)
2602                 {
2603                 if (row[i] != NULL)
2604                         OPENSSL_free(row[i]);
2605                 }
2606         return(ok);
2607         }
2608
2609 static int do_updatedb (CA_DB *db)
2610         {
2611         ASN1_UTCTIME    *a_tm = NULL;
2612         int i, cnt = 0;
2613         int db_y2k, a_y2k;  /* flags = 1 if y >= 2000 */ 
2614         char **rrow, *a_tm_s;
2615
2616         a_tm = ASN1_UTCTIME_new();
2617
2618         /* get actual time and make a string */
2619         a_tm = X509_gmtime_adj(a_tm, 0);
2620         a_tm_s = (char *) OPENSSL_malloc(a_tm->length+1);
2621         if (a_tm_s == NULL)
2622                 {
2623                 cnt = -1;
2624                 goto err;
2625                 }
2626
2627         memcpy(a_tm_s, a_tm->data, a_tm->length);
2628         a_tm_s[a_tm->length] = '\0';
2629
2630         if (strncmp(a_tm_s, "49", 2) <= 0)
2631                 a_y2k = 1;
2632         else
2633                 a_y2k = 0;
2634
2635         for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++)
2636                 {
2637                 rrow = sk_OPENSSL_PSTRING_value(db->db->data, i);
2638
2639                 if (rrow[DB_type][0] == 'V')
2640                         {
2641                         /* ignore entries that are not valid */
2642                         if (strncmp(rrow[DB_exp_date], "49", 2) <= 0)
2643                                 db_y2k = 1;
2644                         else
2645                                 db_y2k = 0;
2646
2647                         if (db_y2k == a_y2k)
2648                                 {
2649                                 /* all on the same y2k side */
2650                                 if (strcmp(rrow[DB_exp_date], a_tm_s) <= 0)
2651                                         {
2652                                         rrow[DB_type][0]  = 'E';
2653                                         rrow[DB_type][1]  = '\0';
2654                                         cnt++;
2655
2656                                         BIO_printf(bio_err, "%s=Expired\n",
2657                                                         rrow[DB_serial]);
2658                                         }
2659                                 }
2660                         else if (db_y2k < a_y2k)
2661                                 {
2662                                 rrow[DB_type][0]  = 'E';
2663                                 rrow[DB_type][1]  = '\0';
2664                                 cnt++;
2665
2666                                 BIO_printf(bio_err, "%s=Expired\n",
2667                                                         rrow[DB_serial]);
2668                                 }
2669
2670                         }
2671                 }
2672
2673 err:
2674
2675         ASN1_UTCTIME_free(a_tm);
2676         OPENSSL_free(a_tm_s);
2677
2678         return (cnt);
2679         }
2680
2681 static const char *crl_reasons[] = {
2682         /* CRL reason strings */
2683         "unspecified",
2684         "keyCompromise",
2685         "CACompromise",
2686         "affiliationChanged",
2687         "superseded", 
2688         "cessationOfOperation",
2689         "certificateHold",
2690         "removeFromCRL",
2691         /* Additional pseudo reasons */
2692         "holdInstruction",
2693         "keyTime",
2694         "CAkeyTime"
2695 };
2696
2697 #define NUM_REASONS (sizeof(crl_reasons) / sizeof(char *))
2698
2699 /* Given revocation information convert to a DB string.
2700  * The format of the string is:
2701  * revtime[,reason,extra]. Where 'revtime' is the
2702  * revocation time (the current time). 'reason' is the
2703  * optional CRL reason and 'extra' is any additional
2704  * argument
2705  */
2706
2707 char *make_revocation_str(int rev_type, char *rev_arg)
2708         {
2709         char *other = NULL, *str;
2710         const char *reason = NULL;
2711         ASN1_OBJECT *otmp;
2712         ASN1_UTCTIME *revtm = NULL;
2713         int i;
2714         switch (rev_type)
2715                 {
2716         case REV_NONE:
2717                 break;
2718
2719         case REV_CRL_REASON:
2720                 for (i = 0; i < 8; i++)
2721                         {
2722                         if (!strcasecmp(rev_arg, crl_reasons[i]))
2723                                 {
2724                                 reason = crl_reasons[i];
2725                                 break;
2726                                 }
2727                         }
2728                 if (reason == NULL)
2729                         {
2730                         BIO_printf(bio_err, "Unknown CRL reason %s\n", rev_arg);
2731                         return NULL;
2732                         }
2733                 break;
2734
2735         case REV_HOLD:
2736                 /* Argument is an OID */
2737
2738                 otmp = OBJ_txt2obj(rev_arg, 0);
2739                 ASN1_OBJECT_free(otmp);
2740
2741                 if (otmp == NULL)
2742                         {
2743                         BIO_printf(bio_err, "Invalid object identifier %s\n", rev_arg);
2744                         return NULL;
2745                         }
2746
2747                 reason = "holdInstruction";
2748                 other = rev_arg;
2749                 break;
2750                 
2751         case REV_KEY_COMPROMISE:
2752         case REV_CA_COMPROMISE:
2753
2754                 /* Argument is the key compromise time  */
2755                 if (!ASN1_GENERALIZEDTIME_set_string(NULL, rev_arg))
2756                         {       
2757                         BIO_printf(bio_err, "Invalid time format %s. Need YYYYMMDDHHMMSSZ\n", rev_arg);
2758                         return NULL;
2759                         }
2760                 other = rev_arg;
2761                 if (rev_type == REV_KEY_COMPROMISE)
2762                         reason = "keyTime";
2763                 else 
2764                         reason = "CAkeyTime";
2765
2766                 break;
2767
2768                 }
2769
2770         revtm = X509_gmtime_adj(NULL, 0);
2771
2772         i = revtm->length + 1;
2773
2774         if (reason) i += strlen(reason) + 1;
2775         if (other) i += strlen(other) + 1;
2776
2777         str = OPENSSL_malloc(i);
2778
2779         if (!str) return NULL;
2780
2781         BUF_strlcpy(str, (char *)revtm->data, i);
2782         if (reason)
2783                 {
2784                 BUF_strlcat(str, ",", i);
2785                 BUF_strlcat(str, reason, i);
2786                 }
2787         if (other)
2788                 {
2789                 BUF_strlcat(str, ",", i);
2790                 BUF_strlcat(str, other, i);
2791                 }
2792         ASN1_UTCTIME_free(revtm);
2793         return str;
2794         }
2795
2796 /* Convert revocation field to X509_REVOKED entry 
2797  * return code:
2798  * 0 error
2799  * 1 OK
2800  * 2 OK and some extensions added (i.e. V2 CRL)
2801  */
2802
2803
2804 int make_revoked(X509_REVOKED *rev, const char *str)
2805         {
2806         char *tmp = NULL;
2807         int reason_code = -1;
2808         int i, ret = 0;
2809         ASN1_OBJECT *hold = NULL;
2810         ASN1_GENERALIZEDTIME *comp_time = NULL;
2811         ASN1_ENUMERATED *rtmp = NULL;
2812
2813         ASN1_TIME *revDate = NULL;
2814
2815         i = unpack_revinfo(&revDate, &reason_code, &hold, &comp_time, str);
2816
2817         if (i == 0)
2818                 goto err;
2819
2820         if (rev && !X509_REVOKED_set_revocationDate(rev, revDate))
2821                 goto err;
2822
2823         if (rev && (reason_code != OCSP_REVOKED_STATUS_NOSTATUS))
2824                 {
2825                 rtmp = ASN1_ENUMERATED_new();
2826                 if (!rtmp || !ASN1_ENUMERATED_set(rtmp, reason_code))
2827                         goto err;
2828                 if (!X509_REVOKED_add1_ext_i2d(rev, NID_crl_reason, rtmp, 0, 0))
2829                         goto err;
2830                 }
2831
2832         if (rev && comp_time)
2833                 {
2834                 if (!X509_REVOKED_add1_ext_i2d(rev, NID_invalidity_date, comp_time, 0, 0))
2835                         goto err;
2836                 }
2837         if (rev && hold)
2838                 {
2839                 if (!X509_REVOKED_add1_ext_i2d(rev, NID_hold_instruction_code, hold, 0, 0))
2840                         goto err;
2841                 }
2842
2843         if (reason_code != OCSP_REVOKED_STATUS_NOSTATUS)
2844                 ret = 2;
2845         else ret = 1;
2846
2847         err:
2848
2849         if (tmp) OPENSSL_free(tmp);
2850         ASN1_OBJECT_free(hold);
2851         ASN1_GENERALIZEDTIME_free(comp_time);
2852         ASN1_ENUMERATED_free(rtmp);
2853         ASN1_TIME_free(revDate);
2854
2855         return ret;
2856         }
2857
2858 int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str)
2859         {
2860         char buf[25],*pbuf, *p;
2861         int j;
2862         j=i2a_ASN1_OBJECT(bp,obj);
2863         pbuf=buf;
2864         for (j=22-j; j>0; j--)
2865                 *(pbuf++)=' ';
2866         *(pbuf++)=':';
2867         *(pbuf++)='\0';
2868         BIO_puts(bp,buf);
2869
2870         if (str->type == V_ASN1_PRINTABLESTRING)
2871                 BIO_printf(bp,"PRINTABLE:'");
2872         else if (str->type == V_ASN1_T61STRING)
2873                 BIO_printf(bp,"T61STRING:'");
2874         else if (str->type == V_ASN1_IA5STRING)
2875                 BIO_printf(bp,"IA5STRING:'");
2876         else if (str->type == V_ASN1_UNIVERSALSTRING)
2877                 BIO_printf(bp,"UNIVERSALSTRING:'");
2878         else
2879                 BIO_printf(bp,"ASN.1 %2d:'",str->type);
2880                         
2881         p=(char *)str->data;
2882         for (j=str->length; j>0; j--)
2883                 {
2884                 if ((*p >= ' ') && (*p <= '~'))
2885                         BIO_printf(bp,"%c",*p);
2886                 else if (*p & 0x80)
2887                         BIO_printf(bp,"\\0x%02X",*p);
2888                 else if ((unsigned char)*p == 0xf7)
2889                         BIO_printf(bp,"^?");
2890                 else    BIO_printf(bp,"^%c",*p+'@');
2891                 p++;
2892                 }
2893         BIO_printf(bp,"'\n");
2894         return 1;
2895         }
2896
2897 int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold, ASN1_GENERALIZEDTIME **pinvtm, const char *str)
2898         {
2899         char *tmp = NULL;
2900         char *rtime_str, *reason_str = NULL, *arg_str = NULL, *p;
2901         int reason_code = -1;
2902         int ret = 0;
2903         unsigned int i;
2904         ASN1_OBJECT *hold = NULL;
2905         ASN1_GENERALIZEDTIME *comp_time = NULL;
2906         tmp = BUF_strdup(str);
2907
2908         p = strchr(tmp, ',');
2909
2910         rtime_str = tmp;
2911
2912         if (p)
2913                 {
2914                 *p = '\0';
2915                 p++;
2916                 reason_str = p;
2917                 p = strchr(p, ',');
2918                 if (p)
2919                         {
2920                         *p = '\0';
2921                         arg_str = p + 1;
2922                         }
2923                 }
2924
2925         if (prevtm)
2926                 {
2927                 *prevtm = ASN1_UTCTIME_new();
2928                 if (!ASN1_UTCTIME_set_string(*prevtm, rtime_str))
2929                         {
2930                         BIO_printf(bio_err, "invalid revocation date %s\n", rtime_str);
2931                         goto err;
2932                         }
2933                 }
2934         if (reason_str)
2935                 {
2936                 for (i = 0; i < NUM_REASONS; i++)
2937                         {
2938                         if(!strcasecmp(reason_str, crl_reasons[i]))
2939                                 {
2940                                 reason_code = i;
2941                                 break;
2942                                 }
2943                         }
2944                 if (reason_code == OCSP_REVOKED_STATUS_NOSTATUS)
2945                         {
2946                         BIO_printf(bio_err, "invalid reason code %s\n", reason_str);
2947                         goto err;
2948                         }
2949
2950                 if (reason_code == 7)
2951                         reason_code = OCSP_REVOKED_STATUS_REMOVEFROMCRL;
2952                 else if (reason_code == 8)              /* Hold instruction */
2953                         {
2954                         if (!arg_str)
2955                                 {       
2956                                 BIO_printf(bio_err, "missing hold instruction\n");
2957                                 goto err;
2958                                 }
2959                         reason_code = OCSP_REVOKED_STATUS_CERTIFICATEHOLD;
2960                         hold = OBJ_txt2obj(arg_str, 0);
2961
2962                         if (!hold)
2963                                 {
2964                                 BIO_printf(bio_err, "invalid object identifier %s\n", arg_str);
2965                                 goto err;
2966                                 }
2967                         if (phold) *phold = hold;
2968                         }
2969                 else if ((reason_code == 9) || (reason_code == 10))
2970                         {
2971                         if (!arg_str)
2972                                 {       
2973                                 BIO_printf(bio_err, "missing compromised time\n");
2974                                 goto err;
2975                                 }
2976                         comp_time = ASN1_GENERALIZEDTIME_new();
2977                         if (!ASN1_GENERALIZEDTIME_set_string(comp_time, arg_str))
2978                                 {       
2979                                 BIO_printf(bio_err, "invalid compromised time %s\n", arg_str);
2980                                 goto err;
2981                                 }
2982                         if (reason_code == 9)
2983                                 reason_code = OCSP_REVOKED_STATUS_KEYCOMPROMISE;
2984                         else
2985                                 reason_code = OCSP_REVOKED_STATUS_CACOMPROMISE;
2986                         }
2987                 }
2988
2989         if (preason) *preason = reason_code;
2990         if (pinvtm) *pinvtm = comp_time;
2991         else ASN1_GENERALIZEDTIME_free(comp_time);
2992
2993         ret = 1;
2994
2995         err:
2996
2997         if (tmp) OPENSSL_free(tmp);
2998         if (!phold) ASN1_OBJECT_free(hold);
2999         if (!pinvtm) ASN1_GENERALIZEDTIME_free(comp_time);
3000
3001         return ret;
3002         }