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