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