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