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