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