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