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