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