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