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