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