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