PR: 2013
[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                 if (!X509_time_adj_ex(tmptm, crldays, crlhours*60*60 + crlsec,
1407                         NULL))
1408                         {
1409                         BIO_puts(bio_err, "error setting CRL nextUpdate\n");
1410                         goto err;
1411                         }
1412                 X509_CRL_set_nextUpdate(crl, tmptm);    
1413
1414                 ASN1_TIME_free(tmptm);
1415
1416                 for (i=0; i<sk_OPENSSL_PSTRING_num(db->db->data); i++)
1417                         {
1418                         pp=sk_OPENSSL_PSTRING_value(db->db->data,i);
1419                         if (pp[DB_type][0] == DB_TYPE_REV)
1420                                 {
1421                                 if ((r=X509_REVOKED_new()) == NULL) goto err;
1422                                 j = make_revoked(r, pp[DB_rev_date]);
1423                                 if (!j) goto err;
1424                                 if (j == 2) crl_v2 = 1;
1425                                 if (!BN_hex2bn(&serial, pp[DB_serial]))
1426                                         goto err;
1427                                 tmpser = BN_to_ASN1_INTEGER(serial, NULL);
1428                                 BN_free(serial);
1429                                 serial = NULL;
1430                                 if (!tmpser)
1431                                         goto err;
1432                                 X509_REVOKED_set_serialNumber(r, tmpser);
1433                                 ASN1_INTEGER_free(tmpser);
1434                                 X509_CRL_add0_revoked(crl,r);
1435                                 }
1436                         }
1437
1438                 /* sort the data so it will be written in serial
1439                  * number order */
1440                 X509_CRL_sort(crl);
1441
1442                 /* we now have a CRL */
1443                 if (verbose) BIO_printf(bio_err,"signing CRL\n");
1444
1445                 /* Add any extensions asked for */
1446
1447                 if (crl_ext || crlnumberfile != NULL)
1448                         {
1449                         X509V3_CTX crlctx;
1450                         X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0);
1451                         X509V3_set_nconf(&crlctx, conf);
1452
1453                         if (crl_ext)
1454                                 if (!X509V3_EXT_CRL_add_nconf(conf, &crlctx,
1455                                         crl_ext, crl)) goto err;
1456                         if (crlnumberfile != NULL)
1457                                 {
1458                                 tmpser = BN_to_ASN1_INTEGER(crlnumber, NULL);
1459                                 if (!tmpser) goto err;
1460                                 X509_CRL_add1_ext_i2d(crl,NID_crl_number,tmpser,0,0);
1461                                 ASN1_INTEGER_free(tmpser);
1462                                 crl_v2 = 1;
1463                                 if (!BN_add_word(crlnumber,1)) goto err;
1464                                 }
1465                         }
1466                 if (crl_ext || crl_v2)
1467                         {
1468                         if (!X509_CRL_set_version(crl, 1))
1469                                 goto err; /* version 2 CRL */
1470                         }
1471
1472                 
1473                 if (crlnumberfile != NULL)      /* we have a CRL number that need updating */
1474                         if (!save_serial(crlnumberfile,"new",crlnumber,NULL)) goto err;
1475
1476                 if (crlnumber)
1477                         {
1478                         BN_free(crlnumber);
1479                         crlnumber = NULL;
1480                         }
1481
1482                 if (!X509_CRL_sign(crl,pkey,dgst)) goto err;
1483
1484                 PEM_write_bio_X509_CRL(Sout,crl);
1485
1486                 if (crlnumberfile != NULL)      /* Rename the crlnumber file */
1487                         if (!rotate_serial(crlnumberfile,"new","old")) goto err;
1488
1489                 }
1490         /*****************************************************************/
1491         if (dorevoke)
1492                 {
1493                 if (infile == NULL) 
1494                         {
1495                         BIO_printf(bio_err,"no input files\n");
1496                         goto err;
1497                         }
1498                 else
1499                         {
1500                         X509 *revcert;
1501                         revcert=load_cert(bio_err, infile, FORMAT_PEM,
1502                                 NULL, e, infile);
1503                         if (revcert == NULL)
1504                                 goto err;
1505                         j=do_revoke(revcert,db, rev_type, rev_arg);
1506                         if (j <= 0) goto err;
1507                         X509_free(revcert);
1508
1509                         if (!save_index(dbfile, "new", db)) goto err;
1510
1511                         if (!rotate_index(dbfile, "new", "old")) goto err;
1512
1513                         BIO_printf(bio_err,"Data Base Updated\n"); 
1514                         }
1515                 }
1516         /*****************************************************************/
1517         ret=0;
1518 err:
1519         if(tofree)
1520                 OPENSSL_free(tofree);
1521         BIO_free_all(Cout);
1522         BIO_free_all(Sout);
1523         BIO_free_all(out);
1524         BIO_free_all(in);
1525
1526         if (cert_sk)
1527                 sk_X509_pop_free(cert_sk,X509_free);
1528
1529         if (ret) ERR_print_errors(bio_err);
1530         app_RAND_write_file(randfile, bio_err);
1531         if (free_key && key)
1532                 OPENSSL_free(key);
1533         BN_free(serial);
1534         BN_free(crlnumber);
1535         free_index(db);
1536         EVP_PKEY_free(pkey);
1537         if (x509) X509_free(x509);
1538         X509_CRL_free(crl);
1539         NCONF_free(conf);
1540         NCONF_free(extconf);
1541         OBJ_cleanup();
1542         apps_shutdown();
1543         OPENSSL_EXIT(ret);
1544         }
1545
1546 static void lookup_fail(const char *name, const char *tag)
1547         {
1548         BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag);
1549         }
1550
1551 static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1552              const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db,
1553              BIGNUM *serial, char *subj,unsigned long chtype, int multirdn, int email_dn, char *startdate, char *enddate,
1554              long days, int batch, char *ext_sect, CONF *lconf, int verbose,
1555              unsigned long certopt, unsigned long nameopt, int default_op,
1556              int ext_copy, int selfsign)
1557         {
1558         X509_REQ *req=NULL;
1559         BIO *in=NULL;
1560         EVP_PKEY *pktmp=NULL;
1561         int ok= -1,i;
1562
1563         in=BIO_new(BIO_s_file());
1564
1565         if (BIO_read_filename(in,infile) <= 0)
1566                 {
1567                 perror(infile);
1568                 goto err;
1569                 }
1570         if ((req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL)) == NULL)
1571                 {
1572                 BIO_printf(bio_err,"Error reading certificate request in %s\n",
1573                         infile);
1574                 goto err;
1575                 }
1576         if (verbose)
1577                 X509_REQ_print(bio_err,req);
1578
1579         BIO_printf(bio_err,"Check that the request matches the signature\n");
1580
1581         if (selfsign && !X509_REQ_check_private_key(req,pkey))
1582                 {
1583                 BIO_printf(bio_err,"Certificate request and CA private key do not match\n");
1584                 ok=0;
1585                 goto err;
1586                 }
1587         if ((pktmp=X509_REQ_get_pubkey(req)) == NULL)
1588                 {
1589                 BIO_printf(bio_err,"error unpacking public key\n");
1590                 goto err;
1591                 }
1592         i=X509_REQ_verify(req,pktmp);
1593         EVP_PKEY_free(pktmp);
1594         if (i < 0)
1595                 {
1596                 ok=0;
1597                 BIO_printf(bio_err,"Signature verification problems....\n");
1598                 goto err;
1599                 }
1600         if (i == 0)
1601                 {
1602                 ok=0;
1603                 BIO_printf(bio_err,"Signature did not match the certificate request\n");
1604                 goto err;
1605                 }
1606         else
1607                 BIO_printf(bio_err,"Signature ok\n");
1608
1609         ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,chtype,multirdn, email_dn,
1610                 startdate,enddate,days,batch,verbose,req,ext_sect,lconf,
1611                 certopt, nameopt, default_op, ext_copy, selfsign);
1612
1613 err:
1614         if (req != NULL) X509_REQ_free(req);
1615         if (in != NULL) BIO_free(in);
1616         return(ok);
1617         }
1618
1619 static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1620              const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db,
1621              BIGNUM *serial, char *subj, unsigned long chtype, int multirdn, int email_dn, char *startdate, char *enddate,
1622              long days, int batch, char *ext_sect, CONF *lconf, int verbose,
1623              unsigned long certopt, unsigned long nameopt, int default_op,
1624              int ext_copy, ENGINE *e)
1625         {
1626         X509 *req=NULL;
1627         X509_REQ *rreq=NULL;
1628         EVP_PKEY *pktmp=NULL;
1629         int ok= -1,i;
1630
1631         if ((req=load_cert(bio_err, infile, FORMAT_PEM, NULL, e, infile)) == NULL)
1632                 goto err;
1633         if (verbose)
1634                 X509_print(bio_err,req);
1635
1636         BIO_printf(bio_err,"Check that the request matches the signature\n");
1637
1638         if ((pktmp=X509_get_pubkey(req)) == NULL)
1639                 {
1640                 BIO_printf(bio_err,"error unpacking public key\n");
1641                 goto err;
1642                 }
1643         i=X509_verify(req,pktmp);
1644         EVP_PKEY_free(pktmp);
1645         if (i < 0)
1646                 {
1647                 ok=0;
1648                 BIO_printf(bio_err,"Signature verification problems....\n");
1649                 goto err;
1650                 }
1651         if (i == 0)
1652                 {
1653                 ok=0;
1654                 BIO_printf(bio_err,"Signature did not match the certificate\n");
1655                 goto err;
1656                 }
1657         else
1658                 BIO_printf(bio_err,"Signature ok\n");
1659
1660         if ((rreq=X509_to_X509_REQ(req,NULL,EVP_md5())) == NULL)
1661                 goto err;
1662
1663         ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,chtype,multirdn,email_dn,startdate,enddate,
1664                 days,batch,verbose,rreq,ext_sect,lconf, certopt, nameopt, default_op,
1665                 ext_copy, 0);
1666
1667 err:
1668         if (rreq != NULL) X509_REQ_free(rreq);
1669         if (req != NULL) X509_free(req);
1670         return(ok);
1671         }
1672
1673 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
1674              STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial, char *subj,
1675              unsigned long chtype, int multirdn,
1676              int email_dn, char *startdate, char *enddate, long days, int batch,
1677              int verbose, X509_REQ *req, char *ext_sect, CONF *lconf,
1678              unsigned long certopt, unsigned long nameopt, int default_op,
1679              int ext_copy, int selfsign)
1680         {
1681         X509_NAME *name=NULL,*CAname=NULL,*subject=NULL, *dn_subject=NULL;
1682         ASN1_UTCTIME *tm,*tmptm;
1683         ASN1_STRING *str,*str2;
1684         ASN1_OBJECT *obj;
1685         X509 *ret=NULL;
1686         X509_CINF *ci;
1687         X509_NAME_ENTRY *ne;
1688         X509_NAME_ENTRY *tne,*push;
1689         EVP_PKEY *pktmp;
1690         int ok= -1,i,j,last,nid;
1691         const char *p;
1692         CONF_VALUE *cv;
1693         OPENSSL_STRING row[DB_NUMBER];
1694         OPENSSL_STRING *irow=NULL;
1695         OPENSSL_STRING *rrow=NULL;
1696         char buf[25];
1697
1698         tmptm=ASN1_UTCTIME_new();
1699         if (tmptm == NULL)
1700                 {
1701                 BIO_printf(bio_err,"malloc error\n");
1702                 return(0);
1703                 }
1704
1705         for (i=0; i<DB_NUMBER; i++)
1706                 row[i]=NULL;
1707
1708         if (subj)
1709                 {
1710                 X509_NAME *n = parse_name(subj, chtype, multirdn);
1711
1712                 if (!n)
1713                         {
1714                         ERR_print_errors(bio_err);
1715                         goto err;
1716                         }
1717                 X509_REQ_set_subject_name(req,n);
1718                 req->req_info->enc.modified = 1;
1719                 X509_NAME_free(n);
1720                 }
1721
1722         if (default_op)
1723                 BIO_printf(bio_err,"The Subject's Distinguished Name is as follows\n");
1724
1725         name=X509_REQ_get_subject_name(req);
1726         for (i=0; i<X509_NAME_entry_count(name); i++)
1727                 {
1728                 ne= X509_NAME_get_entry(name,i);
1729                 str=X509_NAME_ENTRY_get_data(ne);
1730                 obj=X509_NAME_ENTRY_get_object(ne);
1731
1732                 if (msie_hack)
1733                         {
1734                         /* assume all type should be strings */
1735                         nid=OBJ_obj2nid(ne->object);
1736
1737                         if (str->type == V_ASN1_UNIVERSALSTRING)
1738                                 ASN1_UNIVERSALSTRING_to_string(str);
1739
1740                         if ((str->type == V_ASN1_IA5STRING) &&
1741                                 (nid != NID_pkcs9_emailAddress))
1742                                 str->type=V_ASN1_T61STRING;
1743
1744                         if ((nid == NID_pkcs9_emailAddress) &&
1745                                 (str->type == V_ASN1_PRINTABLESTRING))
1746                                 str->type=V_ASN1_IA5STRING;
1747                         }
1748
1749                 /* If no EMAIL is wanted in the subject */
1750                 if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) && (!email_dn))
1751                         continue;
1752
1753                 /* check some things */
1754                 if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&
1755                         (str->type != V_ASN1_IA5STRING))
1756                         {
1757                         BIO_printf(bio_err,"\nemailAddress type needs to be of type IA5STRING\n");
1758                         goto err;
1759                         }
1760                 if ((str->type != V_ASN1_BMPSTRING) && (str->type != V_ASN1_UTF8STRING))
1761                         {
1762                         j=ASN1_PRINTABLE_type(str->data,str->length);
1763                         if (    ((j == V_ASN1_T61STRING) &&
1764                                  (str->type != V_ASN1_T61STRING)) ||
1765                                 ((j == V_ASN1_IA5STRING) &&
1766                                  (str->type == V_ASN1_PRINTABLESTRING)))
1767                                 {
1768                                 BIO_printf(bio_err,"\nThe string contains characters that are illegal for the ASN.1 type\n");
1769                                 goto err;
1770                                 }
1771                         }
1772
1773                 if (default_op)
1774                         old_entry_print(bio_err, obj, str);
1775                 }
1776
1777         /* Ok, now we check the 'policy' stuff. */
1778         if ((subject=X509_NAME_new()) == NULL)
1779                 {
1780                 BIO_printf(bio_err,"Memory allocation failure\n");
1781                 goto err;
1782                 }
1783
1784         /* take a copy of the issuer name before we mess with it. */
1785         if (selfsign)
1786                 CAname=X509_NAME_dup(name);
1787         else
1788                 CAname=X509_NAME_dup(x509->cert_info->subject);
1789         if (CAname == NULL) goto err;
1790         str=str2=NULL;
1791
1792         for (i=0; i<sk_CONF_VALUE_num(policy); i++)
1793                 {
1794                 cv=sk_CONF_VALUE_value(policy,i); /* get the object id */
1795                 if ((j=OBJ_txt2nid(cv->name)) == NID_undef)
1796                         {
1797                         BIO_printf(bio_err,"%s:unknown object type in 'policy' configuration\n",cv->name);
1798                         goto err;
1799                         }
1800                 obj=OBJ_nid2obj(j);
1801
1802                 last= -1;
1803                 for (;;)
1804                         {
1805                         /* lookup the object in the supplied name list */
1806                         j=X509_NAME_get_index_by_OBJ(name,obj,last);
1807                         if (j < 0)
1808                                 {
1809                                 if (last != -1) break;
1810                                 tne=NULL;
1811                                 }
1812                         else
1813                                 {
1814                                 tne=X509_NAME_get_entry(name,j);
1815                                 }
1816                         last=j;
1817
1818                         /* depending on the 'policy', decide what to do. */
1819                         push=NULL;
1820                         if (strcmp(cv->value,"optional") == 0)
1821                                 {
1822                                 if (tne != NULL)
1823                                         push=tne;
1824                                 }
1825                         else if (strcmp(cv->value,"supplied") == 0)
1826                                 {
1827                                 if (tne == NULL)
1828                                         {
1829                                         BIO_printf(bio_err,"The %s field needed to be supplied and was missing\n",cv->name);
1830                                         goto err;
1831                                         }
1832                                 else
1833                                         push=tne;
1834                                 }
1835                         else if (strcmp(cv->value,"match") == 0)
1836                                 {
1837                                 int last2;
1838
1839                                 if (tne == NULL)
1840                                         {
1841                                         BIO_printf(bio_err,"The mandatory %s field was missing\n",cv->name);
1842                                         goto err;
1843                                         }
1844
1845                                 last2= -1;
1846
1847 again2:
1848                                 j=X509_NAME_get_index_by_OBJ(CAname,obj,last2);
1849                                 if ((j < 0) && (last2 == -1))
1850                                         {
1851                                         BIO_printf(bio_err,"The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",cv->name);
1852                                         goto err;
1853                                         }
1854                                 if (j >= 0)
1855                                         {
1856                                         push=X509_NAME_get_entry(CAname,j);
1857                                         str=X509_NAME_ENTRY_get_data(tne);
1858                                         str2=X509_NAME_ENTRY_get_data(push);
1859                                         last2=j;
1860                                         if (ASN1_STRING_cmp(str,str2) != 0)
1861                                                 goto again2;
1862                                         }
1863                                 if (j < 0)
1864                                         {
1865                                         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));
1866                                         goto err;
1867                                         }
1868                                 }
1869                         else
1870                                 {
1871                                 BIO_printf(bio_err,"%s:invalid type in 'policy' configuration\n",cv->value);
1872                                 goto err;
1873                                 }
1874
1875                         if (push != NULL)
1876                                 {
1877                                 if (!X509_NAME_add_entry(subject,push, -1, 0))
1878                                         {
1879                                         if (push != NULL)
1880                                                 X509_NAME_ENTRY_free(push);
1881                                         BIO_printf(bio_err,"Memory allocation failure\n");
1882                                         goto err;
1883                                         }
1884                                 }
1885                         if (j < 0) break;
1886                         }
1887                 }
1888
1889         if (preserve)
1890                 {
1891                 X509_NAME_free(subject);
1892                 /* subject=X509_NAME_dup(X509_REQ_get_subject_name(req)); */
1893                 subject=X509_NAME_dup(name);
1894                 if (subject == NULL) goto err;
1895                 }
1896
1897         if (verbose)
1898                 BIO_printf(bio_err,"The subject name appears to be ok, checking data base for clashes\n");
1899
1900         /* Build the correct Subject if no e-mail is wanted in the subject */
1901         /* and add it later on because of the method extensions are added (altName) */
1902          
1903         if (email_dn)
1904                 dn_subject = subject;
1905         else
1906                 {
1907                 X509_NAME_ENTRY *tmpne;
1908                 /* Its best to dup the subject DN and then delete any email
1909                  * addresses because this retains its structure.
1910                  */
1911                 if (!(dn_subject = X509_NAME_dup(subject)))
1912                         {
1913                         BIO_printf(bio_err,"Memory allocation failure\n");
1914                         goto err;
1915                         }
1916                 while((i = X509_NAME_get_index_by_NID(dn_subject,
1917                                         NID_pkcs9_emailAddress, -1)) >= 0)
1918                         {
1919                         tmpne = X509_NAME_get_entry(dn_subject, i);
1920                         X509_NAME_delete_entry(dn_subject, i);
1921                         X509_NAME_ENTRY_free(tmpne);
1922                         }
1923                 }
1924
1925         if (BN_is_zero(serial))
1926                 row[DB_serial]=BUF_strdup("00");
1927         else
1928                 row[DB_serial]=BN_bn2hex(serial);
1929         if (row[DB_serial] == NULL)
1930                 {
1931                 BIO_printf(bio_err,"Memory allocation failure\n");
1932                 goto err;
1933                 }
1934
1935         if (db->attributes.unique_subject)
1936                 {
1937                 OPENSSL_STRING *crow=row;
1938
1939                 rrow=TXT_DB_get_by_index(db->db,DB_name,crow);
1940                 if (rrow != NULL)
1941                         {
1942                         BIO_printf(bio_err,
1943                                 "ERROR:There is already a certificate for %s\n",
1944                                 row[DB_name]);
1945                         }
1946                 }
1947         if (rrow == NULL)
1948                 {
1949                 rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
1950                 if (rrow != NULL)
1951                         {
1952                         BIO_printf(bio_err,"ERROR:Serial number %s has already been issued,\n",
1953                                 row[DB_serial]);
1954                         BIO_printf(bio_err,"      check the database/serial_file for corruption\n");
1955                         }
1956                 }
1957
1958         if (rrow != NULL)
1959                 {
1960                 BIO_printf(bio_err,
1961                         "The matching entry has the following details\n");
1962                 if (rrow[DB_type][0] == 'E')
1963                         p="Expired";
1964                 else if (rrow[DB_type][0] == 'R')
1965                         p="Revoked";
1966                 else if (rrow[DB_type][0] == 'V')
1967                         p="Valid";
1968                 else
1969                         p="\ninvalid type, Data base error\n";
1970                 BIO_printf(bio_err,"Type          :%s\n",p);;
1971                 if (rrow[DB_type][0] == 'R')
1972                         {
1973                         p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1974                         BIO_printf(bio_err,"Was revoked on:%s\n",p);
1975                         }
1976                 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1977                 BIO_printf(bio_err,"Expires on    :%s\n",p);
1978                 p=rrow[DB_serial]; if (p == NULL) p="undef";
1979                 BIO_printf(bio_err,"Serial Number :%s\n",p);
1980                 p=rrow[DB_file]; if (p == NULL) p="undef";
1981                 BIO_printf(bio_err,"File name     :%s\n",p);
1982                 p=rrow[DB_name]; if (p == NULL) p="undef";
1983                 BIO_printf(bio_err,"Subject Name  :%s\n",p);
1984                 ok= -1; /* This is now a 'bad' error. */
1985                 goto err;
1986                 }
1987
1988         /* We are now totally happy, lets make and sign the certificate */
1989         if (verbose)
1990                 BIO_printf(bio_err,"Everything appears to be ok, creating and signing the certificate\n");
1991
1992         if ((ret=X509_new()) == NULL) goto err;
1993         ci=ret->cert_info;
1994
1995 #ifdef X509_V3
1996         /* Make it an X509 v3 certificate. */
1997         if (!X509_set_version(ret,2)) goto err;
1998 #endif
1999
2000         if (BN_to_ASN1_INTEGER(serial,ci->serialNumber) == NULL)
2001                 goto err;
2002         if (selfsign)
2003                 {
2004                 if (!X509_set_issuer_name(ret,subject))
2005                         goto err;
2006                 }
2007         else
2008                 {
2009                 if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))
2010                         goto err;
2011                 }
2012
2013         if (strcmp(startdate,"today") == 0)
2014                 X509_gmtime_adj(X509_get_notBefore(ret),0);
2015         else ASN1_TIME_set_string(X509_get_notBefore(ret),startdate);
2016
2017         if (enddate == NULL)
2018                 X509_time_adj_ex(X509_get_notAfter(ret),days, 0, NULL);
2019         else ASN1_TIME_set_string(X509_get_notAfter(ret),enddate);
2020
2021         if (!X509_set_subject_name(ret,subject)) goto err;
2022
2023         pktmp=X509_REQ_get_pubkey(req);
2024         i = X509_set_pubkey(ret,pktmp);
2025         EVP_PKEY_free(pktmp);
2026         if (!i) goto err;
2027
2028         /* Lets add the extensions, if there are any */
2029         if (ext_sect)
2030                 {
2031                 X509V3_CTX ctx;
2032                 if (ci->version == NULL)
2033                         if ((ci->version=ASN1_INTEGER_new()) == NULL)
2034                                 goto err;
2035                 ASN1_INTEGER_set(ci->version,2); /* version 3 certificate */
2036
2037                 /* Free the current entries if any, there should not
2038                  * be any I believe */
2039                 if (ci->extensions != NULL)
2040                         sk_X509_EXTENSION_pop_free(ci->extensions,
2041                                                    X509_EXTENSION_free);
2042
2043                 ci->extensions = NULL;
2044
2045                 /* Initialize the context structure */
2046                 if (selfsign)
2047                         X509V3_set_ctx(&ctx, ret, ret, req, NULL, 0);
2048                 else
2049                         X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
2050
2051                 if (extconf)
2052                         {
2053                         if (verbose)
2054                                 BIO_printf(bio_err, "Extra configuration file found\n");
2055  
2056                         /* Use the extconf configuration db LHASH */
2057                         X509V3_set_nconf(&ctx, extconf);
2058  
2059                         /* Test the structure (needed?) */
2060                         /* X509V3_set_ctx_test(&ctx); */
2061
2062                         /* Adds exts contained in the configuration file */
2063                         if (!X509V3_EXT_add_nconf(extconf, &ctx, ext_sect,ret))
2064                                 {
2065                                 BIO_printf(bio_err,
2066                                     "ERROR: adding extensions in section %s\n",
2067                                                                 ext_sect);
2068                                 ERR_print_errors(bio_err);
2069                                 goto err;
2070                                 }
2071                         if (verbose)
2072                                 BIO_printf(bio_err, "Successfully added extensions from file.\n");
2073                         }
2074                 else if (ext_sect)
2075                         {
2076                         /* We found extensions to be set from config file */
2077                         X509V3_set_nconf(&ctx, lconf);
2078
2079                         if(!X509V3_EXT_add_nconf(lconf, &ctx, ext_sect, ret))
2080                                 {
2081                                 BIO_printf(bio_err, "ERROR: adding extensions in section %s\n", ext_sect);
2082                                 ERR_print_errors(bio_err);
2083                                 goto err;
2084                                 }
2085
2086                         if (verbose) 
2087                                 BIO_printf(bio_err, "Successfully added extensions from config\n");
2088                         }
2089                 }
2090
2091         /* Copy extensions from request (if any) */
2092
2093         if (!copy_extensions(ret, req, ext_copy))
2094                 {
2095                 BIO_printf(bio_err, "ERROR: adding extensions from request\n");
2096                 ERR_print_errors(bio_err);
2097                 goto err;
2098                 }
2099
2100         /* Set the right value for the noemailDN option */
2101         if( email_dn == 0 )
2102                 {
2103                 if (!X509_set_subject_name(ret,dn_subject)) goto err;
2104                 }
2105
2106         if (!default_op)
2107                 {
2108                 BIO_printf(bio_err, "Certificate Details:\n");
2109                 /* Never print signature details because signature not present */
2110                 certopt |= X509_FLAG_NO_SIGDUMP | X509_FLAG_NO_SIGNAME;
2111                 X509_print_ex(bio_err, ret, nameopt, certopt); 
2112                 }
2113
2114         BIO_printf(bio_err,"Certificate is to be certified until ");
2115         ASN1_TIME_print(bio_err,X509_get_notAfter(ret));
2116         if (days) BIO_printf(bio_err," (%ld days)",days);
2117         BIO_printf(bio_err, "\n");
2118
2119         if (!batch)
2120                 {
2121
2122                 BIO_printf(bio_err,"Sign the certificate? [y/n]:");
2123                 (void)BIO_flush(bio_err);
2124                 buf[0]='\0';
2125                 fgets(buf,sizeof(buf)-1,stdin);
2126                 if (!((buf[0] == 'y') || (buf[0] == 'Y')))
2127                         {
2128                         BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED\n");
2129                         ok=0;
2130                         goto err;
2131                         }
2132                 }
2133
2134         pktmp=X509_get_pubkey(ret);
2135         if (EVP_PKEY_missing_parameters(pktmp) &&
2136                 !EVP_PKEY_missing_parameters(pkey))
2137                 EVP_PKEY_copy_parameters(pktmp,pkey);
2138         EVP_PKEY_free(pktmp);
2139
2140         if (!X509_sign(ret,pkey,dgst))
2141                 goto err;
2142
2143         /* We now just add it to the database */
2144         row[DB_type]=(char *)OPENSSL_malloc(2);
2145
2146         tm=X509_get_notAfter(ret);
2147         row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2148         memcpy(row[DB_exp_date],tm->data,tm->length);
2149         row[DB_exp_date][tm->length]='\0';
2150
2151         row[DB_rev_date]=NULL;
2152
2153         /* row[DB_serial] done already */
2154         row[DB_file]=(char *)OPENSSL_malloc(8);
2155         row[DB_name]=X509_NAME_oneline(X509_get_subject_name(ret),NULL,0);
2156
2157         if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2158                 (row[DB_file] == NULL) || (row[DB_name] == NULL))
2159                 {
2160                 BIO_printf(bio_err,"Memory allocation failure\n");
2161                 goto err;
2162                 }
2163         BUF_strlcpy(row[DB_file],"unknown",8);
2164         row[DB_type][0]='V';
2165         row[DB_type][1]='\0';
2166
2167         if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2168                 {
2169                 BIO_printf(bio_err,"Memory allocation failure\n");
2170                 goto err;
2171                 }
2172
2173         for (i=0; i<DB_NUMBER; i++)
2174                 {
2175                 irow[i]=row[i];
2176                 row[i]=NULL;
2177                 }
2178         irow[DB_NUMBER]=NULL;
2179
2180         if (!TXT_DB_insert(db->db,irow))
2181                 {
2182                 BIO_printf(bio_err,"failed to update database\n");
2183                 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->db->error);
2184                 goto err;
2185                 }
2186         ok=1;
2187 err:
2188         for (i=0; i<DB_NUMBER; i++)
2189                 if (row[i] != NULL) OPENSSL_free(row[i]);
2190
2191         if (CAname != NULL)
2192                 X509_NAME_free(CAname);
2193         if (subject != NULL)
2194                 X509_NAME_free(subject);
2195         if ((dn_subject != NULL) && !email_dn)
2196                 X509_NAME_free(dn_subject);
2197         if (tmptm != NULL)
2198                 ASN1_UTCTIME_free(tmptm);
2199         if (ok <= 0)
2200                 {
2201                 if (ret != NULL) X509_free(ret);
2202                 ret=NULL;
2203                 }
2204         else
2205                 *xret=ret;
2206         return(ok);
2207         }
2208
2209 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext)
2210         {
2211
2212         if (output_der)
2213                 {
2214                 (void)i2d_X509_bio(bp,x);
2215                 return;
2216                 }
2217 #if 0
2218         /* ??? Not needed since X509_print prints all this stuff anyway */
2219         f=X509_NAME_oneline(X509_get_issuer_name(x),buf,256);
2220         BIO_printf(bp,"issuer :%s\n",f);
2221
2222         f=X509_NAME_oneline(X509_get_subject_name(x),buf,256);
2223         BIO_printf(bp,"subject:%s\n",f);
2224
2225         BIO_puts(bp,"serial :");
2226         i2a_ASN1_INTEGER(bp,x->cert_info->serialNumber);
2227         BIO_puts(bp,"\n\n");
2228 #endif
2229         if (!notext)X509_print(bp,x);
2230         PEM_write_bio_X509(bp,x);
2231         }
2232
2233 static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
2234              const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db,
2235              BIGNUM *serial, char *subj,unsigned long chtype, int multirdn, int email_dn, char *startdate, char *enddate,
2236              long days, char *ext_sect, CONF *lconf, int verbose, unsigned long certopt,
2237              unsigned long nameopt, int default_op, int ext_copy)
2238         {
2239         STACK_OF(CONF_VALUE) *sk=NULL;
2240         LHASH_OF(CONF_VALUE) *parms=NULL;
2241         X509_REQ *req=NULL;
2242         CONF_VALUE *cv=NULL;
2243         NETSCAPE_SPKI *spki = NULL;
2244         X509_REQ_INFO *ri;
2245         char *type,*buf;
2246         EVP_PKEY *pktmp=NULL;
2247         X509_NAME *n=NULL;
2248         X509_NAME_ENTRY *ne=NULL;
2249         int ok= -1,i,j;
2250         long errline;
2251         int nid;
2252
2253         /*
2254          * Load input file into a hash table.  (This is just an easy
2255          * way to read and parse the file, then put it into a convenient
2256          * STACK format).
2257          */
2258         parms=CONF_load(NULL,infile,&errline);
2259         if (parms == NULL)
2260                 {
2261                 BIO_printf(bio_err,"error on line %ld of %s\n",errline,infile);
2262                 ERR_print_errors(bio_err);
2263                 goto err;
2264                 }
2265
2266         sk=CONF_get_section(parms, "default");
2267         if (sk_CONF_VALUE_num(sk) == 0)
2268                 {
2269                 BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);
2270                 CONF_free(parms);
2271                 goto err;
2272                 }
2273
2274         /*
2275          * Now create a dummy X509 request structure.  We don't actually
2276          * have an X509 request, but we have many of the components
2277          * (a public key, various DN components).  The idea is that we
2278          * put these components into the right X509 request structure
2279          * and we can use the same code as if you had a real X509 request.
2280          */
2281         req=X509_REQ_new();
2282         if (req == NULL)
2283                 {
2284                 ERR_print_errors(bio_err);
2285                 goto err;
2286                 }
2287
2288         /*
2289          * Build up the subject name set.
2290          */
2291         ri=req->req_info;
2292         n = ri->subject;
2293
2294         for (i = 0; ; i++)
2295                 {
2296                 if (sk_CONF_VALUE_num(sk) <= i) break;
2297
2298                 cv=sk_CONF_VALUE_value(sk,i);
2299                 type=cv->name;
2300                 /* Skip past any leading X. X: X, etc to allow for
2301                  * multiple instances
2302                  */
2303                 for (buf = cv->name; *buf ; buf++)
2304                         if ((*buf == ':') || (*buf == ',') || (*buf == '.'))
2305                                 {
2306                                 buf++;
2307                                 if (*buf) type = buf;
2308                                 break;
2309                                 }
2310
2311                 buf=cv->value;
2312                 if ((nid=OBJ_txt2nid(type)) == NID_undef)
2313                         {
2314                         if (strcmp(type, "SPKAC") == 0)
2315                                 {
2316                                 spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
2317                                 if (spki == NULL)
2318                                         {
2319                                         BIO_printf(bio_err,"unable to load Netscape SPKAC structure\n");
2320                                         ERR_print_errors(bio_err);
2321                                         goto err;
2322                                         }
2323                                 }
2324                         continue;
2325                         }
2326
2327                 /*
2328                 if ((nid == NID_pkcs9_emailAddress) && (email_dn == 0))
2329                         continue;
2330                 */
2331                 
2332                 j=ASN1_PRINTABLE_type((unsigned char *)buf,-1);
2333                 if (fix_data(nid, &j) == 0)
2334                         {
2335                         BIO_printf(bio_err,
2336                                 "invalid characters in string %s\n",buf);
2337                         goto err;
2338                         }
2339
2340                 if ((ne=X509_NAME_ENTRY_create_by_NID(&ne,nid,j,
2341                         (unsigned char *)buf,
2342                         strlen(buf))) == NULL)
2343                         goto err;
2344
2345                 if (!X509_NAME_add_entry(n,ne,-1, 0)) goto err;
2346                 }
2347         if (spki == NULL)
2348                 {
2349                 BIO_printf(bio_err,"Netscape SPKAC structure not found in %s\n",
2350                         infile);
2351                 goto err;
2352                 }
2353
2354         /*
2355          * Now extract the key from the SPKI structure.
2356          */
2357
2358         BIO_printf(bio_err,"Check that the SPKAC request matches the signature\n");
2359
2360         if ((pktmp=NETSCAPE_SPKI_get_pubkey(spki)) == NULL)
2361                 {
2362                 BIO_printf(bio_err,"error unpacking SPKAC public key\n");
2363                 goto err;
2364                 }
2365
2366         j = NETSCAPE_SPKI_verify(spki, pktmp);
2367         if (j <= 0)
2368                 {
2369                 BIO_printf(bio_err,"signature verification failed on SPKAC public key\n");
2370                 goto err;
2371                 }
2372         BIO_printf(bio_err,"Signature ok\n");
2373
2374         X509_REQ_set_pubkey(req,pktmp);
2375         EVP_PKEY_free(pktmp);
2376         ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,chtype,multirdn,email_dn,startdate,enddate,
2377                    days,1,verbose,req,ext_sect,lconf, certopt, nameopt, default_op,
2378                         ext_copy, 0);
2379 err:
2380         if (req != NULL) X509_REQ_free(req);
2381         if (parms != NULL) CONF_free(parms);
2382         if (spki != NULL) NETSCAPE_SPKI_free(spki);
2383         if (ne != NULL) X509_NAME_ENTRY_free(ne);
2384
2385         return(ok);
2386         }
2387
2388 static int fix_data(int nid, int *type)
2389         {
2390         if (nid == NID_pkcs9_emailAddress)
2391                 *type=V_ASN1_IA5STRING;
2392         if ((nid == NID_commonName) && (*type == V_ASN1_IA5STRING))
2393                 *type=V_ASN1_T61STRING;
2394         if ((nid == NID_pkcs9_challengePassword) && (*type == V_ASN1_IA5STRING))
2395                 *type=V_ASN1_T61STRING;
2396         if ((nid == NID_pkcs9_unstructuredName) && (*type == V_ASN1_T61STRING))
2397                 return(0);
2398         if (nid == NID_pkcs9_unstructuredName)
2399                 *type=V_ASN1_IA5STRING;
2400         return(1);
2401         }
2402
2403 static int check_time_format(const char *str)
2404         {
2405         return ASN1_TIME_set_string(NULL, str);
2406         }
2407
2408 static int do_revoke(X509 *x509, CA_DB *db, int type, char *value)
2409         {
2410         ASN1_UTCTIME *tm=NULL;
2411         char *row[DB_NUMBER],**rrow,**irow;
2412         char *rev_str = NULL;
2413         BIGNUM *bn = NULL;
2414         int ok=-1,i;
2415
2416         for (i=0; i<DB_NUMBER; i++)
2417                 row[i]=NULL;
2418         row[DB_name]=X509_NAME_oneline(X509_get_subject_name(x509),NULL,0);
2419         bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509),NULL);
2420         if (!bn)
2421                 goto err;
2422         if (BN_is_zero(bn))
2423                 row[DB_serial]=BUF_strdup("00");
2424         else
2425                 row[DB_serial]=BN_bn2hex(bn);
2426         BN_free(bn);
2427         if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
2428                 {
2429                 BIO_printf(bio_err,"Memory allocation failure\n");
2430                 goto err;
2431                 }
2432         /* We have to lookup by serial number because name lookup
2433          * skips revoked certs
2434          */
2435         rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
2436         if (rrow == NULL)
2437                 {
2438                 BIO_printf(bio_err,"Adding Entry with serial number %s to DB for %s\n", row[DB_serial], row[DB_name]);
2439
2440                 /* We now just add it to the database */
2441                 row[DB_type]=(char *)OPENSSL_malloc(2);
2442
2443                 tm=X509_get_notAfter(x509);
2444                 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2445                 memcpy(row[DB_exp_date],tm->data,tm->length);
2446                 row[DB_exp_date][tm->length]='\0';
2447
2448                 row[DB_rev_date]=NULL;
2449
2450                 /* row[DB_serial] done already */
2451                 row[DB_file]=(char *)OPENSSL_malloc(8);
2452
2453                 /* row[DB_name] done already */
2454
2455                 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2456                         (row[DB_file] == NULL))
2457                         {
2458                         BIO_printf(bio_err,"Memory allocation failure\n");
2459                         goto err;
2460                         }
2461                 BUF_strlcpy(row[DB_file],"unknown",8);
2462                 row[DB_type][0]='V';
2463                 row[DB_type][1]='\0';
2464
2465                 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2466                         {
2467                         BIO_printf(bio_err,"Memory allocation failure\n");
2468                         goto err;
2469                         }
2470
2471                 for (i=0; i<DB_NUMBER; i++)
2472                         {
2473                         irow[i]=row[i];
2474                         row[i]=NULL;
2475                         }
2476                 irow[DB_NUMBER]=NULL;
2477
2478                 if (!TXT_DB_insert(db->db,irow))
2479                         {
2480                         BIO_printf(bio_err,"failed to update database\n");
2481                         BIO_printf(bio_err,"TXT_DB error number %ld\n",db->db->error);
2482                         goto err;
2483                         }
2484
2485                 /* Revoke Certificate */
2486                 ok = do_revoke(x509,db, type, value);
2487
2488                 goto err;
2489
2490                 }
2491         else if (index_name_cmp_noconst(row, rrow))
2492                 {
2493                 BIO_printf(bio_err,"ERROR:name does not match %s\n",
2494                            row[DB_name]);
2495                 goto err;
2496                 }
2497         else if (rrow[DB_type][0]=='R')
2498                 {
2499                 BIO_printf(bio_err,"ERROR:Already revoked, serial number %s\n",
2500                            row[DB_serial]);
2501                 goto err;
2502                 }
2503         else
2504                 {
2505                 BIO_printf(bio_err,"Revoking Certificate %s.\n", rrow[DB_serial]);
2506                 rev_str = make_revocation_str(type, value);
2507                 if (!rev_str)
2508                         {
2509                         BIO_printf(bio_err, "Error in revocation arguments\n");
2510                         goto err;
2511                         }
2512                 rrow[DB_type][0]='R';
2513                 rrow[DB_type][1]='\0';
2514                 rrow[DB_rev_date] = rev_str;
2515                 }
2516         ok=1;
2517 err:
2518         for (i=0; i<DB_NUMBER; i++)
2519                 {
2520                 if (row[i] != NULL) 
2521                         OPENSSL_free(row[i]);
2522                 }
2523         return(ok);
2524         }
2525
2526 static int get_certificate_status(const char *serial, CA_DB *db)
2527         {
2528         char *row[DB_NUMBER],**rrow;
2529         int ok=-1,i;
2530
2531         /* Free Resources */
2532         for (i=0; i<DB_NUMBER; i++)
2533                 row[i]=NULL;
2534
2535         /* Malloc needed char spaces */
2536         row[DB_serial] = OPENSSL_malloc(strlen(serial) + 2);
2537         if (row[DB_serial] == NULL)
2538                 {
2539                 BIO_printf(bio_err,"Malloc failure\n");
2540                 goto err;
2541                 }
2542
2543         if (strlen(serial) % 2)
2544                 {
2545                 /* Set the first char to 0 */;
2546                 row[DB_serial][0]='0';
2547
2548                 /* Copy String from serial to row[DB_serial] */
2549                 memcpy(row[DB_serial]+1, serial, strlen(serial));
2550                 row[DB_serial][strlen(serial)+1]='\0';
2551                 }
2552         else
2553                 {
2554                 /* Copy String from serial to row[DB_serial] */
2555                 memcpy(row[DB_serial], serial, strlen(serial));
2556                 row[DB_serial][strlen(serial)]='\0';
2557                 }
2558                         
2559         /* Make it Upper Case */
2560         for (i=0; row[DB_serial][i] != '\0'; i++)
2561                 row[DB_serial][i] = toupper(row[DB_serial][i]);
2562         
2563
2564         ok=1;
2565
2566         /* Search for the certificate */
2567         rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
2568         if (rrow == NULL)
2569                 {
2570                 BIO_printf(bio_err,"Serial %s not present in db.\n",
2571                                  row[DB_serial]);
2572                 ok=-1;
2573                 goto err;
2574                 }
2575         else if (rrow[DB_type][0]=='V')
2576                 {
2577                 BIO_printf(bio_err,"%s=Valid (%c)\n",
2578                         row[DB_serial], rrow[DB_type][0]);
2579                 goto err;
2580                 }
2581         else if (rrow[DB_type][0]=='R')
2582                 {
2583                 BIO_printf(bio_err,"%s=Revoked (%c)\n",
2584                         row[DB_serial], rrow[DB_type][0]);
2585                 goto err;
2586                 }
2587         else if (rrow[DB_type][0]=='E')
2588                 {
2589                 BIO_printf(bio_err,"%s=Expired (%c)\n",
2590                         row[DB_serial], rrow[DB_type][0]);
2591                 goto err;
2592                 }
2593         else if (rrow[DB_type][0]=='S')
2594                 {
2595                 BIO_printf(bio_err,"%s=Suspended (%c)\n",
2596                         row[DB_serial], rrow[DB_type][0]);
2597                 goto err;
2598                 }
2599         else
2600                 {
2601                 BIO_printf(bio_err,"%s=Unknown (%c).\n",
2602                         row[DB_serial], rrow[DB_type][0]);
2603                 ok=-1;
2604                 }
2605 err:
2606         for (i=0; i<DB_NUMBER; i++)
2607                 {
2608                 if (row[i] != NULL)
2609                         OPENSSL_free(row[i]);
2610                 }
2611         return(ok);
2612         }
2613
2614 static int do_updatedb (CA_DB *db)
2615         {
2616         ASN1_UTCTIME    *a_tm = NULL;
2617         int i, cnt = 0;
2618         int db_y2k, a_y2k;  /* flags = 1 if y >= 2000 */ 
2619         char **rrow, *a_tm_s;
2620
2621         a_tm = ASN1_UTCTIME_new();
2622
2623         /* get actual time and make a string */
2624         a_tm = X509_gmtime_adj(a_tm, 0);
2625         a_tm_s = (char *) OPENSSL_malloc(a_tm->length+1);
2626         if (a_tm_s == NULL)
2627                 {
2628                 cnt = -1;
2629                 goto err;
2630                 }
2631
2632         memcpy(a_tm_s, a_tm->data, a_tm->length);
2633         a_tm_s[a_tm->length] = '\0';
2634
2635         if (strncmp(a_tm_s, "49", 2) <= 0)
2636                 a_y2k = 1;
2637         else
2638                 a_y2k = 0;
2639
2640         for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++)
2641                 {
2642                 rrow = sk_OPENSSL_PSTRING_value(db->db->data, i);
2643
2644                 if (rrow[DB_type][0] == 'V')
2645                         {
2646                         /* ignore entries that are not valid */
2647                         if (strncmp(rrow[DB_exp_date], "49", 2) <= 0)
2648                                 db_y2k = 1;
2649                         else
2650                                 db_y2k = 0;
2651
2652                         if (db_y2k == a_y2k)
2653                                 {
2654                                 /* all on the same y2k side */
2655                                 if (strcmp(rrow[DB_exp_date], a_tm_s) <= 0)
2656                                         {
2657                                         rrow[DB_type][0]  = 'E';
2658                                         rrow[DB_type][1]  = '\0';
2659                                         cnt++;
2660
2661                                         BIO_printf(bio_err, "%s=Expired\n",
2662                                                         rrow[DB_serial]);
2663                                         }
2664                                 }
2665                         else if (db_y2k < a_y2k)
2666                                 {
2667                                 rrow[DB_type][0]  = 'E';
2668                                 rrow[DB_type][1]  = '\0';
2669                                 cnt++;
2670
2671                                 BIO_printf(bio_err, "%s=Expired\n",
2672                                                         rrow[DB_serial]);
2673                                 }
2674
2675                         }
2676                 }
2677
2678 err:
2679
2680         ASN1_UTCTIME_free(a_tm);
2681         OPENSSL_free(a_tm_s);
2682
2683         return (cnt);
2684         }
2685
2686 static const char *crl_reasons[] = {
2687         /* CRL reason strings */
2688         "unspecified",
2689         "keyCompromise",
2690         "CACompromise",
2691         "affiliationChanged",
2692         "superseded", 
2693         "cessationOfOperation",
2694         "certificateHold",
2695         "removeFromCRL",
2696         /* Additional pseudo reasons */
2697         "holdInstruction",
2698         "keyTime",
2699         "CAkeyTime"
2700 };
2701
2702 #define NUM_REASONS (sizeof(crl_reasons) / sizeof(char *))
2703
2704 /* Given revocation information convert to a DB string.
2705  * The format of the string is:
2706  * revtime[,reason,extra]. Where 'revtime' is the
2707  * revocation time (the current time). 'reason' is the
2708  * optional CRL reason and 'extra' is any additional
2709  * argument
2710  */
2711
2712 char *make_revocation_str(int rev_type, char *rev_arg)
2713         {
2714         char *other = NULL, *str;
2715         const char *reason = NULL;
2716         ASN1_OBJECT *otmp;
2717         ASN1_UTCTIME *revtm = NULL;
2718         int i;
2719         switch (rev_type)
2720                 {
2721         case REV_NONE:
2722                 break;
2723
2724         case REV_CRL_REASON:
2725                 for (i = 0; i < 8; i++)
2726                         {
2727                         if (!strcasecmp(rev_arg, crl_reasons[i]))
2728                                 {
2729                                 reason = crl_reasons[i];
2730                                 break;
2731                                 }
2732                         }
2733                 if (reason == NULL)
2734                         {
2735                         BIO_printf(bio_err, "Unknown CRL reason %s\n", rev_arg);
2736                         return NULL;
2737                         }
2738                 break;
2739
2740         case REV_HOLD:
2741                 /* Argument is an OID */
2742
2743                 otmp = OBJ_txt2obj(rev_arg, 0);
2744                 ASN1_OBJECT_free(otmp);
2745
2746                 if (otmp == NULL)
2747                         {
2748                         BIO_printf(bio_err, "Invalid object identifier %s\n", rev_arg);
2749                         return NULL;
2750                         }
2751
2752                 reason = "holdInstruction";
2753                 other = rev_arg;
2754                 break;
2755                 
2756         case REV_KEY_COMPROMISE:
2757         case REV_CA_COMPROMISE:
2758
2759                 /* Argument is the key compromise time  */
2760                 if (!ASN1_GENERALIZEDTIME_set_string(NULL, rev_arg))
2761                         {       
2762                         BIO_printf(bio_err, "Invalid time format %s. Need YYYYMMDDHHMMSSZ\n", rev_arg);
2763                         return NULL;
2764                         }
2765                 other = rev_arg;
2766                 if (rev_type == REV_KEY_COMPROMISE)
2767                         reason = "keyTime";
2768                 else 
2769                         reason = "CAkeyTime";
2770
2771                 break;
2772
2773                 }
2774
2775         revtm = X509_gmtime_adj(NULL, 0);
2776
2777         i = revtm->length + 1;
2778
2779         if (reason) i += strlen(reason) + 1;
2780         if (other) i += strlen(other) + 1;
2781
2782         str = OPENSSL_malloc(i);
2783
2784         if (!str) return NULL;
2785
2786         BUF_strlcpy(str, (char *)revtm->data, i);
2787         if (reason)
2788                 {
2789                 BUF_strlcat(str, ",", i);
2790                 BUF_strlcat(str, reason, i);
2791                 }
2792         if (other)
2793                 {
2794                 BUF_strlcat(str, ",", i);
2795                 BUF_strlcat(str, other, i);
2796                 }
2797         ASN1_UTCTIME_free(revtm);
2798         return str;
2799         }
2800
2801 /* Convert revocation field to X509_REVOKED entry 
2802  * return code:
2803  * 0 error
2804  * 1 OK
2805  * 2 OK and some extensions added (i.e. V2 CRL)
2806  */
2807
2808
2809 int make_revoked(X509_REVOKED *rev, const char *str)
2810         {
2811         char *tmp = NULL;
2812         int reason_code = -1;
2813         int i, ret = 0;
2814         ASN1_OBJECT *hold = NULL;
2815         ASN1_GENERALIZEDTIME *comp_time = NULL;
2816         ASN1_ENUMERATED *rtmp = NULL;
2817
2818         ASN1_TIME *revDate = NULL;
2819
2820         i = unpack_revinfo(&revDate, &reason_code, &hold, &comp_time, str);
2821
2822         if (i == 0)
2823                 goto err;
2824
2825         if (rev && !X509_REVOKED_set_revocationDate(rev, revDate))
2826                 goto err;
2827
2828         if (rev && (reason_code != OCSP_REVOKED_STATUS_NOSTATUS))
2829                 {
2830                 rtmp = ASN1_ENUMERATED_new();
2831                 if (!rtmp || !ASN1_ENUMERATED_set(rtmp, reason_code))
2832                         goto err;
2833                 if (!X509_REVOKED_add1_ext_i2d(rev, NID_crl_reason, rtmp, 0, 0))
2834                         goto err;
2835                 }
2836
2837         if (rev && comp_time)
2838                 {
2839                 if (!X509_REVOKED_add1_ext_i2d(rev, NID_invalidity_date, comp_time, 0, 0))
2840                         goto err;
2841                 }
2842         if (rev && hold)
2843                 {
2844                 if (!X509_REVOKED_add1_ext_i2d(rev, NID_hold_instruction_code, hold, 0, 0))
2845                         goto err;
2846                 }
2847
2848         if (reason_code != OCSP_REVOKED_STATUS_NOSTATUS)
2849                 ret = 2;
2850         else ret = 1;
2851
2852         err:
2853
2854         if (tmp) OPENSSL_free(tmp);
2855         ASN1_OBJECT_free(hold);
2856         ASN1_GENERALIZEDTIME_free(comp_time);
2857         ASN1_ENUMERATED_free(rtmp);
2858         ASN1_TIME_free(revDate);
2859
2860         return ret;
2861         }
2862
2863 int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str)
2864         {
2865         char buf[25],*pbuf, *p;
2866         int j;
2867         j=i2a_ASN1_OBJECT(bp,obj);
2868         pbuf=buf;
2869         for (j=22-j; j>0; j--)
2870                 *(pbuf++)=' ';
2871         *(pbuf++)=':';
2872         *(pbuf++)='\0';
2873         BIO_puts(bp,buf);
2874
2875         if (str->type == V_ASN1_PRINTABLESTRING)
2876                 BIO_printf(bp,"PRINTABLE:'");
2877         else if (str->type == V_ASN1_T61STRING)
2878                 BIO_printf(bp,"T61STRING:'");
2879         else if (str->type == V_ASN1_IA5STRING)
2880                 BIO_printf(bp,"IA5STRING:'");
2881         else if (str->type == V_ASN1_UNIVERSALSTRING)
2882                 BIO_printf(bp,"UNIVERSALSTRING:'");
2883         else
2884                 BIO_printf(bp,"ASN.1 %2d:'",str->type);
2885                         
2886         p=(char *)str->data;
2887         for (j=str->length; j>0; j--)
2888                 {
2889                 if ((*p >= ' ') && (*p <= '~'))
2890                         BIO_printf(bp,"%c",*p);
2891                 else if (*p & 0x80)
2892                         BIO_printf(bp,"\\0x%02X",*p);
2893                 else if ((unsigned char)*p == 0xf7)
2894                         BIO_printf(bp,"^?");
2895                 else    BIO_printf(bp,"^%c",*p+'@');
2896                 p++;
2897                 }
2898         BIO_printf(bp,"'\n");
2899         return 1;
2900         }
2901
2902 int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold, ASN1_GENERALIZEDTIME **pinvtm, const char *str)
2903         {
2904         char *tmp = NULL;
2905         char *rtime_str, *reason_str = NULL, *arg_str = NULL, *p;
2906         int reason_code = -1;
2907         int ret = 0;
2908         unsigned int i;
2909         ASN1_OBJECT *hold = NULL;
2910         ASN1_GENERALIZEDTIME *comp_time = NULL;
2911         tmp = BUF_strdup(str);
2912
2913         p = strchr(tmp, ',');
2914
2915         rtime_str = tmp;
2916
2917         if (p)
2918                 {
2919                 *p = '\0';
2920                 p++;
2921                 reason_str = p;
2922                 p = strchr(p, ',');
2923                 if (p)
2924                         {
2925                         *p = '\0';
2926                         arg_str = p + 1;
2927                         }
2928                 }
2929
2930         if (prevtm)
2931                 {
2932                 *prevtm = ASN1_UTCTIME_new();
2933                 if (!ASN1_UTCTIME_set_string(*prevtm, rtime_str))
2934                         {
2935                         BIO_printf(bio_err, "invalid revocation date %s\n", rtime_str);
2936                         goto err;
2937                         }
2938                 }
2939         if (reason_str)
2940                 {
2941                 for (i = 0; i < NUM_REASONS; i++)
2942                         {
2943                         if(!strcasecmp(reason_str, crl_reasons[i]))
2944                                 {
2945                                 reason_code = i;
2946                                 break;
2947                                 }
2948                         }
2949                 if (reason_code == OCSP_REVOKED_STATUS_NOSTATUS)
2950                         {
2951                         BIO_printf(bio_err, "invalid reason code %s\n", reason_str);
2952                         goto err;
2953                         }
2954
2955                 if (reason_code == 7)
2956                         reason_code = OCSP_REVOKED_STATUS_REMOVEFROMCRL;
2957                 else if (reason_code == 8)              /* Hold instruction */
2958                         {
2959                         if (!arg_str)
2960                                 {       
2961                                 BIO_printf(bio_err, "missing hold instruction\n");
2962                                 goto err;
2963                                 }
2964                         reason_code = OCSP_REVOKED_STATUS_CERTIFICATEHOLD;
2965                         hold = OBJ_txt2obj(arg_str, 0);
2966
2967                         if (!hold)
2968                                 {
2969                                 BIO_printf(bio_err, "invalid object identifier %s\n", arg_str);
2970                                 goto err;
2971                                 }
2972                         if (phold) *phold = hold;
2973                         }
2974                 else if ((reason_code == 9) || (reason_code == 10))
2975                         {
2976                         if (!arg_str)
2977                                 {       
2978                                 BIO_printf(bio_err, "missing compromised time\n");
2979                                 goto err;
2980                                 }
2981                         comp_time = ASN1_GENERALIZEDTIME_new();
2982                         if (!ASN1_GENERALIZEDTIME_set_string(comp_time, arg_str))
2983                                 {       
2984                                 BIO_printf(bio_err, "invalid compromised time %s\n", arg_str);
2985                                 goto err;
2986                                 }
2987                         if (reason_code == 9)
2988                                 reason_code = OCSP_REVOKED_STATUS_KEYCOMPROMISE;
2989                         else
2990                                 reason_code = OCSP_REVOKED_STATUS_CACOMPROMISE;
2991                         }
2992                 }
2993
2994         if (preason) *preason = reason_code;
2995         if (pinvtm) *pinvtm = comp_time;
2996         else ASN1_GENERALIZEDTIME_free(comp_time);
2997
2998         ret = 1;
2999
3000         err:
3001
3002         if (tmp) OPENSSL_free(tmp);
3003         if (!phold) ASN1_OBJECT_free(hold);
3004         if (!pinvtm) ASN1_GENERALIZEDTIME_free(comp_time);
3005
3006         return ret;
3007         }