]> git.ipfire.org Git - thirdparty/openssl.git/blame_incremental - apps/ca.c
make RSA blinding thread-safe
[thirdparty/openssl.git] / apps / ca.c
... / ...
CommitLineData
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#ifndef OPENSSL_NO_ECDSA
1548 if (pkey->type == EVP_PKEY_EC)
1549 dgst=EVP_ecdsa();
1550 else
1551#endif
1552 dgst=EVP_md5();
1553 }
1554
1555 /* Add any extensions asked for */
1556
1557 if (crl_ext)
1558 {
1559 X509V3_CTX crlctx;
1560 X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0);
1561 X509V3_set_nconf(&crlctx, conf);
1562
1563 if (!X509V3_EXT_CRL_add_nconf(conf, &crlctx,
1564 crl_ext, crl)) goto err;
1565 }
1566 if (crl_ext || crl_v2)
1567 {
1568 if (!X509_CRL_set_version(crl, 1))
1569 goto err; /* version 2 CRL */
1570 }
1571
1572 if (!X509_CRL_sign(crl,pkey,dgst)) goto err;
1573
1574 PEM_write_bio_X509_CRL(Sout,crl);
1575 }
1576 /*****************************************************************/
1577 if (dorevoke)
1578 {
1579 if (infile == NULL)
1580 {
1581 BIO_printf(bio_err,"no input files\n");
1582 goto err;
1583 }
1584 else
1585 {
1586 X509 *revcert;
1587 revcert=load_cert(bio_err, infile, FORMAT_PEM,
1588 NULL, e, infile);
1589 if (revcert == NULL)
1590 goto err;
1591 j=do_revoke(revcert,db, rev_type, rev_arg);
1592 if (j <= 0) goto err;
1593 X509_free(revcert);
1594
1595 if(strlen(dbfile) > BSIZE-5)
1596 {
1597 BIO_printf(bio_err,"filename too long\n");
1598 goto err;
1599 }
1600
1601 strcpy(buf[0],dbfile);
1602#ifndef OPENSSL_SYS_VMS
1603 strcat(buf[0],".new");
1604#else
1605 strcat(buf[0],"-new");
1606#endif
1607 if (BIO_write_filename(out,buf[0]) <= 0)
1608 {
1609 perror(dbfile);
1610 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
1611 goto err;
1612 }
1613 j=TXT_DB_write(out,db);
1614 if (j <= 0) goto err;
1615 strncpy(buf[1],dbfile,BSIZE-4);
1616 buf[1][BSIZE-4]='\0';
1617#ifndef OPENSSL_SYS_VMS
1618 strcat(buf[1],".old");
1619#else
1620 strcat(buf[1],"-old");
1621#endif
1622 BIO_free(in);
1623 in = NULL;
1624 BIO_free(out);
1625 out = NULL;
1626 if (rename(dbfile,buf[1]) < 0)
1627 {
1628 BIO_printf(bio_err,"unable to rename %s to %s\n", dbfile, buf[1]);
1629 perror("reason");
1630 goto err;
1631 }
1632 if (rename(buf[0],dbfile) < 0)
1633 {
1634 BIO_printf(bio_err,"unable to rename %s to %s\n", buf[0],dbfile);
1635 perror("reason");
1636 rename(buf[1],dbfile);
1637 goto err;
1638 }
1639 BIO_printf(bio_err,"Data Base Updated\n");
1640 }
1641 }
1642 /*****************************************************************/
1643 ret=0;
1644err:
1645 if(tofree)
1646 OPENSSL_free(tofree);
1647 BIO_free_all(Cout);
1648 BIO_free_all(Sout);
1649 BIO_free_all(out);
1650 BIO_free_all(in);
1651
1652 if (cert_sk)
1653 sk_X509_pop_free(cert_sk,X509_free);
1654
1655 if (ret) ERR_print_errors(bio_err);
1656 app_RAND_write_file(randfile, bio_err);
1657 if (free_key && key)
1658 OPENSSL_free(key);
1659 BN_free(serial);
1660 TXT_DB_free(db);
1661 EVP_PKEY_free(pkey);
1662 X509_free(x509);
1663 X509_CRL_free(crl);
1664 NCONF_free(conf);
1665 OBJ_cleanup();
1666 apps_shutdown();
1667 OPENSSL_EXIT(ret);
1668 }
1669
1670static void lookup_fail(char *name, char *tag)
1671 {
1672 BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag);
1673 }
1674
1675static unsigned long index_serial_hash(const char **a)
1676 {
1677 const char *n;
1678
1679 n=a[DB_serial];
1680 while (*n == '0') n++;
1681 return(lh_strhash(n));
1682 }
1683
1684static int index_serial_cmp(const char **a, const char **b)
1685 {
1686 const char *aa,*bb;
1687
1688 for (aa=a[DB_serial]; *aa == '0'; aa++);
1689 for (bb=b[DB_serial]; *bb == '0'; bb++);
1690 return(strcmp(aa,bb));
1691 }
1692
1693static unsigned long index_name_hash(const char **a)
1694 { return(lh_strhash(a[DB_name])); }
1695
1696static int index_name_qual(char **a)
1697 { return(a[0][0] == 'V'); }
1698
1699static int index_name_cmp(const char **a, const char **b)
1700 { return(strcmp(a[DB_name],
1701 b[DB_name])); }
1702
1703static BIGNUM *load_serial(char *serialfile)
1704 {
1705 BIO *in=NULL;
1706 BIGNUM *ret=NULL;
1707 MS_STATIC char buf[1024];
1708 ASN1_INTEGER *ai=NULL;
1709
1710 if ((in=BIO_new(BIO_s_file())) == NULL)
1711 {
1712 ERR_print_errors(bio_err);
1713 goto err;
1714 }
1715
1716 if (BIO_read_filename(in,serialfile) <= 0)
1717 {
1718 perror(serialfile);
1719 goto err;
1720 }
1721 ai=ASN1_INTEGER_new();
1722 if (ai == NULL) goto err;
1723 if (!a2i_ASN1_INTEGER(in,ai,buf,1024))
1724 {
1725 BIO_printf(bio_err,"unable to load number from %s\n",
1726 serialfile);
1727 goto err;
1728 }
1729 ret=ASN1_INTEGER_to_BN(ai,NULL);
1730 if (ret == NULL)
1731 {
1732 BIO_printf(bio_err,"error converting number from bin to BIGNUM\n");
1733 goto err;
1734 }
1735err:
1736 if (in != NULL) BIO_free(in);
1737 if (ai != NULL) ASN1_INTEGER_free(ai);
1738 return(ret);
1739 }
1740
1741static int save_serial(char *serialfile, BIGNUM *serial)
1742 {
1743 BIO *out;
1744 int ret=0;
1745 ASN1_INTEGER *ai=NULL;
1746
1747 out=BIO_new(BIO_s_file());
1748 if (out == NULL)
1749 {
1750 ERR_print_errors(bio_err);
1751 goto err;
1752 }
1753 if (BIO_write_filename(out,serialfile) <= 0)
1754 {
1755 perror(serialfile);
1756 goto err;
1757 }
1758
1759 if ((ai=BN_to_ASN1_INTEGER(serial,NULL)) == NULL)
1760 {
1761 BIO_printf(bio_err,"error converting serial to ASN.1 format\n");
1762 goto err;
1763 }
1764 i2a_ASN1_INTEGER(out,ai);
1765 BIO_puts(out,"\n");
1766 ret=1;
1767err:
1768 if (out != NULL) BIO_free_all(out);
1769 if (ai != NULL) ASN1_INTEGER_free(ai);
1770 return(ret);
1771 }
1772
1773static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1774 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1775 BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate,
1776 long days, int batch, char *ext_sect, CONF *lconf, int verbose,
1777 unsigned long certopt, unsigned long nameopt, int default_op,
1778 int ext_copy)
1779 {
1780 X509_REQ *req=NULL;
1781 BIO *in=NULL;
1782 EVP_PKEY *pktmp=NULL;
1783 int ok= -1,i;
1784
1785 in=BIO_new(BIO_s_file());
1786
1787 if (BIO_read_filename(in,infile) <= 0)
1788 {
1789 perror(infile);
1790 goto err;
1791 }
1792 if ((req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL)) == NULL)
1793 {
1794 BIO_printf(bio_err,"Error reading certificate request in %s\n",
1795 infile);
1796 goto err;
1797 }
1798 if (verbose)
1799 X509_REQ_print(bio_err,req);
1800
1801 BIO_printf(bio_err,"Check that the request matches the signature\n");
1802
1803 if ((pktmp=X509_REQ_get_pubkey(req)) == NULL)
1804 {
1805 BIO_printf(bio_err,"error unpacking public key\n");
1806 goto err;
1807 }
1808 i=X509_REQ_verify(req,pktmp);
1809 EVP_PKEY_free(pktmp);
1810 if (i < 0)
1811 {
1812 ok=0;
1813 BIO_printf(bio_err,"Signature verification problems....\n");
1814 goto err;
1815 }
1816 if (i == 0)
1817 {
1818 ok=0;
1819 BIO_printf(bio_err,"Signature did not match the certificate request\n");
1820 goto err;
1821 }
1822 else
1823 BIO_printf(bio_err,"Signature ok\n");
1824
1825 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj, email_dn,
1826 startdate,enddate,days,batch,verbose,req,ext_sect,lconf,
1827 certopt, nameopt, default_op, ext_copy);
1828
1829err:
1830 if (req != NULL) X509_REQ_free(req);
1831 if (in != NULL) BIO_free(in);
1832 return(ok);
1833 }
1834
1835static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1836 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1837 BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate,
1838 long days, int batch, char *ext_sect, CONF *lconf, int verbose,
1839 unsigned long certopt, unsigned long nameopt, int default_op,
1840 int ext_copy, ENGINE *e)
1841 {
1842 X509 *req=NULL;
1843 X509_REQ *rreq=NULL;
1844 EVP_PKEY *pktmp=NULL;
1845 int ok= -1,i;
1846
1847 if ((req=load_cert(bio_err, infile, FORMAT_PEM, NULL, e, infile)) == NULL)
1848 goto err;
1849 if (verbose)
1850 X509_print(bio_err,req);
1851
1852 BIO_printf(bio_err,"Check that the request matches the signature\n");
1853
1854 if ((pktmp=X509_get_pubkey(req)) == NULL)
1855 {
1856 BIO_printf(bio_err,"error unpacking public key\n");
1857 goto err;
1858 }
1859 i=X509_verify(req,pktmp);
1860 EVP_PKEY_free(pktmp);
1861 if (i < 0)
1862 {
1863 ok=0;
1864 BIO_printf(bio_err,"Signature verification problems....\n");
1865 goto err;
1866 }
1867 if (i == 0)
1868 {
1869 ok=0;
1870 BIO_printf(bio_err,"Signature did not match the certificate\n");
1871 goto err;
1872 }
1873 else
1874 BIO_printf(bio_err,"Signature ok\n");
1875
1876 if ((rreq=X509_to_X509_REQ(req,NULL,EVP_md5())) == NULL)
1877 goto err;
1878
1879 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,email_dn,startdate,enddate,
1880 days,batch,verbose,rreq,ext_sect,lconf, certopt, nameopt, default_op,
1881 ext_copy);
1882
1883err:
1884 if (rreq != NULL) X509_REQ_free(rreq);
1885 if (req != NULL) X509_free(req);
1886 return(ok);
1887 }
1888
1889static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
1890 STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial, char *subj,
1891 int email_dn, char *startdate, char *enddate, long days, int batch,
1892 int verbose, X509_REQ *req, char *ext_sect, CONF *lconf,
1893 unsigned long certopt, unsigned long nameopt, int default_op,
1894 int ext_copy)
1895 {
1896 X509_NAME *name=NULL,*CAname=NULL,*subject=NULL, *dn_subject=NULL;
1897 ASN1_UTCTIME *tm,*tmptm;
1898 ASN1_STRING *str,*str2;
1899 ASN1_OBJECT *obj;
1900 X509 *ret=NULL;
1901 X509_CINF *ci;
1902 X509_NAME_ENTRY *ne;
1903 X509_NAME_ENTRY *tne,*push;
1904 EVP_PKEY *pktmp;
1905 int ok= -1,i,j,last,nid;
1906 char *p;
1907 CONF_VALUE *cv;
1908 char *row[DB_NUMBER],**rrow,**irow=NULL;
1909 char buf[25];
1910
1911 tmptm=ASN1_UTCTIME_new();
1912 if (tmptm == NULL)
1913 {
1914 BIO_printf(bio_err,"malloc error\n");
1915 return(0);
1916 }
1917
1918 for (i=0; i<DB_NUMBER; i++)
1919 row[i]=NULL;
1920
1921 if (subj)
1922 {
1923 X509_NAME *n = do_subject(subj, MBSTRING_ASC);
1924
1925 if (!n)
1926 {
1927 ERR_print_errors(bio_err);
1928 goto err;
1929 }
1930 X509_REQ_set_subject_name(req,n);
1931 req->req_info->enc.modified = 1;
1932 X509_NAME_free(n);
1933 }
1934
1935 if (default_op)
1936 BIO_printf(bio_err,"The Subject's Distinguished Name is as follows\n");
1937
1938 name=X509_REQ_get_subject_name(req);
1939 for (i=0; i<X509_NAME_entry_count(name); i++)
1940 {
1941 ne= X509_NAME_get_entry(name,i);
1942 str=X509_NAME_ENTRY_get_data(ne);
1943 obj=X509_NAME_ENTRY_get_object(ne);
1944
1945 if (msie_hack)
1946 {
1947 /* assume all type should be strings */
1948 nid=OBJ_obj2nid(ne->object);
1949
1950 if (str->type == V_ASN1_UNIVERSALSTRING)
1951 ASN1_UNIVERSALSTRING_to_string(str);
1952
1953 if ((str->type == V_ASN1_IA5STRING) &&
1954 (nid != NID_pkcs9_emailAddress))
1955 str->type=V_ASN1_T61STRING;
1956
1957 if ((nid == NID_pkcs9_emailAddress) &&
1958 (str->type == V_ASN1_PRINTABLESTRING))
1959 str->type=V_ASN1_IA5STRING;
1960 }
1961
1962 /* If no EMAIL is wanted in the subject */
1963 if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) && (!email_dn))
1964 continue;
1965
1966 /* check some things */
1967 if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&
1968 (str->type != V_ASN1_IA5STRING))
1969 {
1970 BIO_printf(bio_err,"\nemailAddress type needs to be of type IA5STRING\n");
1971 goto err;
1972 }
1973 if ((str->type != V_ASN1_BMPSTRING) && (str->type != V_ASN1_UTF8STRING))
1974 {
1975 j=ASN1_PRINTABLE_type(str->data,str->length);
1976 if ( ((j == V_ASN1_T61STRING) &&
1977 (str->type != V_ASN1_T61STRING)) ||
1978 ((j == V_ASN1_IA5STRING) &&
1979 (str->type == V_ASN1_PRINTABLESTRING)))
1980 {
1981 BIO_printf(bio_err,"\nThe string contains characters that are illegal for the ASN.1 type\n");
1982 goto err;
1983 }
1984 }
1985
1986 if (default_op)
1987 old_entry_print(bio_err, obj, str);
1988 }
1989
1990 /* Ok, now we check the 'policy' stuff. */
1991 if ((subject=X509_NAME_new()) == NULL)
1992 {
1993 BIO_printf(bio_err,"Memory allocation failure\n");
1994 goto err;
1995 }
1996
1997 /* take a copy of the issuer name before we mess with it. */
1998 CAname=X509_NAME_dup(x509->cert_info->subject);
1999 if (CAname == NULL) goto err;
2000 str=str2=NULL;
2001
2002 for (i=0; i<sk_CONF_VALUE_num(policy); i++)
2003 {
2004 cv=sk_CONF_VALUE_value(policy,i); /* get the object id */
2005 if ((j=OBJ_txt2nid(cv->name)) == NID_undef)
2006 {
2007 BIO_printf(bio_err,"%s:unknown object type in 'policy' configuration\n",cv->name);
2008 goto err;
2009 }
2010 obj=OBJ_nid2obj(j);
2011
2012 last= -1;
2013 for (;;)
2014 {
2015 /* lookup the object in the supplied name list */
2016 j=X509_NAME_get_index_by_OBJ(name,obj,last);
2017 if (j < 0)
2018 {
2019 if (last != -1) break;
2020 tne=NULL;
2021 }
2022 else
2023 {
2024 tne=X509_NAME_get_entry(name,j);
2025 }
2026 last=j;
2027
2028 /* depending on the 'policy', decide what to do. */
2029 push=NULL;
2030 if (strcmp(cv->value,"optional") == 0)
2031 {
2032 if (tne != NULL)
2033 push=tne;
2034 }
2035 else if (strcmp(cv->value,"supplied") == 0)
2036 {
2037 if (tne == NULL)
2038 {
2039 BIO_printf(bio_err,"The %s field needed to be supplied and was missing\n",cv->name);
2040 goto err;
2041 }
2042 else
2043 push=tne;
2044 }
2045 else if (strcmp(cv->value,"match") == 0)
2046 {
2047 int last2;
2048
2049 if (tne == NULL)
2050 {
2051 BIO_printf(bio_err,"The mandatory %s field was missing\n",cv->name);
2052 goto err;
2053 }
2054
2055 last2= -1;
2056
2057again2:
2058 j=X509_NAME_get_index_by_OBJ(CAname,obj,last2);
2059 if ((j < 0) && (last2 == -1))
2060 {
2061 BIO_printf(bio_err,"The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",cv->name);
2062 goto err;
2063 }
2064 if (j >= 0)
2065 {
2066 push=X509_NAME_get_entry(CAname,j);
2067 str=X509_NAME_ENTRY_get_data(tne);
2068 str2=X509_NAME_ENTRY_get_data(push);
2069 last2=j;
2070 if (ASN1_STRING_cmp(str,str2) != 0)
2071 goto again2;
2072 }
2073 if (j < 0)
2074 {
2075 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));
2076 goto err;
2077 }
2078 }
2079 else
2080 {
2081 BIO_printf(bio_err,"%s:invalid type in 'policy' configuration\n",cv->value);
2082 goto err;
2083 }
2084
2085 if (push != NULL)
2086 {
2087 if (!X509_NAME_add_entry(subject,push, -1, 0))
2088 {
2089 if (push != NULL)
2090 X509_NAME_ENTRY_free(push);
2091 BIO_printf(bio_err,"Memory allocation failure\n");
2092 goto err;
2093 }
2094 }
2095 if (j < 0) break;
2096 }
2097 }
2098
2099 if (preserve)
2100 {
2101 X509_NAME_free(subject);
2102 /* subject=X509_NAME_dup(X509_REQ_get_subject_name(req)); */
2103 subject=X509_NAME_dup(name);
2104 if (subject == NULL) goto err;
2105 }
2106
2107 if (verbose)
2108 BIO_printf(bio_err,"The subject name appears to be ok, checking data base for clashes\n");
2109
2110 /* Build the correct Subject if no e-mail is wanted in the subject */
2111 /* and add it later on because of the method extensions are added (altName) */
2112
2113 if (email_dn)
2114 dn_subject = subject;
2115 else
2116 {
2117 X509_NAME_ENTRY *tmpne;
2118 /* Its best to dup the subject DN and then delete any email
2119 * addresses because this retains its structure.
2120 */
2121 if (!(dn_subject = X509_NAME_dup(subject)))
2122 {
2123 BIO_printf(bio_err,"Memory allocation failure\n");
2124 goto err;
2125 }
2126 while((i = X509_NAME_get_index_by_NID(dn_subject,
2127 NID_pkcs9_emailAddress, -1)) >= 0)
2128 {
2129 tmpne = X509_NAME_get_entry(dn_subject, i);
2130 X509_NAME_delete_entry(dn_subject, i);
2131 X509_NAME_ENTRY_free(tmpne);
2132 }
2133 }
2134
2135 if (BN_is_zero(serial))
2136 row[DB_serial]=BUF_strdup("00");
2137 else
2138 row[DB_serial]=BN_bn2hex(serial);
2139 if (row[DB_serial] == NULL)
2140 {
2141 BIO_printf(bio_err,"Memory allocation failure\n");
2142 goto err;
2143 }
2144
2145 rrow=TXT_DB_get_by_index(db,DB_name,row);
2146 if (rrow != NULL)
2147 {
2148 BIO_printf(bio_err,"ERROR:There is already a certificate for %s\n",
2149 row[DB_name]);
2150 }
2151 else
2152 {
2153 rrow=TXT_DB_get_by_index(db,DB_serial,row);
2154 if (rrow != NULL)
2155 {
2156 BIO_printf(bio_err,"ERROR:Serial number %s has already been issued,\n",
2157 row[DB_serial]);
2158 BIO_printf(bio_err," check the database/serial_file for corruption\n");
2159 }
2160 }
2161
2162 if (rrow != NULL)
2163 {
2164 BIO_printf(bio_err,
2165 "The matching entry has the following details\n");
2166 if (rrow[DB_type][0] == 'E')
2167 p="Expired";
2168 else if (rrow[DB_type][0] == 'R')
2169 p="Revoked";
2170 else if (rrow[DB_type][0] == 'V')
2171 p="Valid";
2172 else
2173 p="\ninvalid type, Data base error\n";
2174 BIO_printf(bio_err,"Type :%s\n",p);;
2175 if (rrow[DB_type][0] == 'R')
2176 {
2177 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
2178 BIO_printf(bio_err,"Was revoked on:%s\n",p);
2179 }
2180 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
2181 BIO_printf(bio_err,"Expires on :%s\n",p);
2182 p=rrow[DB_serial]; if (p == NULL) p="undef";
2183 BIO_printf(bio_err,"Serial Number :%s\n",p);
2184 p=rrow[DB_file]; if (p == NULL) p="undef";
2185 BIO_printf(bio_err,"File name :%s\n",p);
2186 p=rrow[DB_name]; if (p == NULL) p="undef";
2187 BIO_printf(bio_err,"Subject Name :%s\n",p);
2188 ok= -1; /* This is now a 'bad' error. */
2189 goto err;
2190 }
2191
2192 /* We are now totally happy, lets make and sign the certificate */
2193 if (verbose)
2194 BIO_printf(bio_err,"Everything appears to be ok, creating and signing the certificate\n");
2195
2196 if ((ret=X509_new()) == NULL) goto err;
2197 ci=ret->cert_info;
2198
2199#ifdef X509_V3
2200 /* Make it an X509 v3 certificate. */
2201 if (!X509_set_version(x509,2)) goto err;
2202#endif
2203
2204 if (BN_to_ASN1_INTEGER(serial,ci->serialNumber) == NULL)
2205 goto err;
2206 if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))
2207 goto err;
2208
2209 if (strcmp(startdate,"today") == 0)
2210 X509_gmtime_adj(X509_get_notBefore(ret),0);
2211 else ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate);
2212
2213 if (enddate == NULL)
2214 X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days);
2215 else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate);
2216
2217 if (!X509_set_subject_name(ret,subject)) goto err;
2218
2219 pktmp=X509_REQ_get_pubkey(req);
2220 i = X509_set_pubkey(ret,pktmp);
2221 EVP_PKEY_free(pktmp);
2222 if (!i) goto err;
2223
2224 /* Lets add the extensions, if there are any */
2225 if (ext_sect)
2226 {
2227 X509V3_CTX ctx;
2228 if (ci->version == NULL)
2229 if ((ci->version=ASN1_INTEGER_new()) == NULL)
2230 goto err;
2231 ASN1_INTEGER_set(ci->version,2); /* version 3 certificate */
2232
2233 /* Free the current entries if any, there should not
2234 * be any I believe */
2235 if (ci->extensions != NULL)
2236 sk_X509_EXTENSION_pop_free(ci->extensions,
2237 X509_EXTENSION_free);
2238
2239 ci->extensions = NULL;
2240
2241 /* Initialize the context structure */
2242 X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
2243
2244 if (extconf)
2245 {
2246 if (verbose)
2247 BIO_printf(bio_err, "Extra configuration file found\n");
2248
2249 /* Use the extconf configuration db LHASH */
2250 X509V3_set_nconf(&ctx, extconf);
2251
2252 /* Test the structure (needed?) */
2253 /* X509V3_set_ctx_test(&ctx); */
2254
2255 /* Adds exts contained in the configuration file */
2256 if (!X509V3_EXT_add_nconf(extconf, &ctx, ext_sect,ret))
2257 {
2258 BIO_printf(bio_err,
2259 "ERROR: adding extensions in section %s\n",
2260 ext_sect);
2261 ERR_print_errors(bio_err);
2262 goto err;
2263 }
2264 if (verbose)
2265 BIO_printf(bio_err, "Successfully added extensions from file.\n");
2266 }
2267 else if (ext_sect)
2268 {
2269 /* We found extensions to be set from config file */
2270 X509V3_set_nconf(&ctx, lconf);
2271
2272 if(!X509V3_EXT_add_nconf(lconf, &ctx, ext_sect, ret))
2273 {
2274 BIO_printf(bio_err, "ERROR: adding extensions in section %s\n", ext_sect);
2275 ERR_print_errors(bio_err);
2276 goto err;
2277 }
2278
2279 if (verbose)
2280 BIO_printf(bio_err, "Successfully added extensions from config\n");
2281 }
2282 }
2283
2284 /* Copy extensions from request (if any) */
2285
2286 if (!copy_extensions(ret, req, ext_copy))
2287 {
2288 BIO_printf(bio_err, "ERROR: adding extensions from request\n");
2289 ERR_print_errors(bio_err);
2290 goto err;
2291 }
2292
2293 /* Set the right value for the noemailDN option */
2294 if( email_dn == 0 )
2295 {
2296 if (!X509_set_subject_name(ret,dn_subject)) goto err;
2297 }
2298
2299 if (!default_op)
2300 {
2301 BIO_printf(bio_err, "Certificate Details:\n");
2302 /* Never print signature details because signature not present */
2303 certopt |= X509_FLAG_NO_SIGDUMP | X509_FLAG_NO_SIGNAME;
2304 X509_print_ex(bio_err, ret, nameopt, certopt);
2305 }
2306
2307 BIO_printf(bio_err,"Certificate is to be certified until ");
2308 ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ret));
2309 if (days) BIO_printf(bio_err," (%d days)",days);
2310 BIO_printf(bio_err, "\n");
2311
2312 if (!batch)
2313 {
2314
2315 BIO_printf(bio_err,"Sign the certificate? [y/n]:");
2316 (void)BIO_flush(bio_err);
2317 buf[0]='\0';
2318 fgets(buf,sizeof(buf)-1,stdin);
2319 if (!((buf[0] == 'y') || (buf[0] == 'Y')))
2320 {
2321 BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED\n");
2322 ok=0;
2323 goto err;
2324 }
2325 }
2326
2327
2328#ifndef OPENSSL_NO_DSA
2329 if (pkey->type == EVP_PKEY_DSA) dgst=EVP_dss1();
2330 pktmp=X509_get_pubkey(ret);
2331 if (EVP_PKEY_missing_parameters(pktmp) &&
2332 !EVP_PKEY_missing_parameters(pkey))
2333 EVP_PKEY_copy_parameters(pktmp,pkey);
2334 EVP_PKEY_free(pktmp);
2335#endif
2336#ifndef OPENSSL_NO_ECDSA
2337 if (pkey->type == EVP_PKEY_EC)
2338 dgst = EVP_ecdsa();
2339 pktmp = X509_get_pubkey(ret);
2340 if (EVP_PKEY_missing_parameters(pktmp) &&
2341 !EVP_PKEY_missing_parameters(pkey))
2342 EVP_PKEY_copy_parameters(pktmp, pkey);
2343 EVP_PKEY_free(pktmp);
2344#endif
2345
2346
2347 if (!X509_sign(ret,pkey,dgst))
2348 goto err;
2349
2350 /* We now just add it to the database */
2351 row[DB_type]=(char *)OPENSSL_malloc(2);
2352
2353 tm=X509_get_notAfter(ret);
2354 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2355 memcpy(row[DB_exp_date],tm->data,tm->length);
2356 row[DB_exp_date][tm->length]='\0';
2357
2358 row[DB_rev_date]=NULL;
2359
2360 /* row[DB_serial] done already */
2361 row[DB_file]=(char *)OPENSSL_malloc(8);
2362 row[DB_name]=X509_NAME_oneline(X509_get_subject_name(ret),NULL,0);
2363
2364 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2365 (row[DB_file] == NULL) || (row[DB_name] == NULL))
2366 {
2367 BIO_printf(bio_err,"Memory allocation failure\n");
2368 goto err;
2369 }
2370 strcpy(row[DB_file],"unknown");
2371 row[DB_type][0]='V';
2372 row[DB_type][1]='\0';
2373
2374 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2375 {
2376 BIO_printf(bio_err,"Memory allocation failure\n");
2377 goto err;
2378 }
2379
2380 for (i=0; i<DB_NUMBER; i++)
2381 {
2382 irow[i]=row[i];
2383 row[i]=NULL;
2384 }
2385 irow[DB_NUMBER]=NULL;
2386
2387 if (!TXT_DB_insert(db,irow))
2388 {
2389 BIO_printf(bio_err,"failed to update database\n");
2390 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
2391 goto err;
2392 }
2393 ok=1;
2394err:
2395 for (i=0; i<DB_NUMBER; i++)
2396 if (row[i] != NULL) OPENSSL_free(row[i]);
2397
2398 if (CAname != NULL)
2399 X509_NAME_free(CAname);
2400 if (subject != NULL)
2401 X509_NAME_free(subject);
2402 if ((dn_subject != NULL) && !email_dn)
2403 X509_NAME_free(dn_subject);
2404 if (tmptm != NULL)
2405 ASN1_UTCTIME_free(tmptm);
2406 if (ok <= 0)
2407 {
2408 if (ret != NULL) X509_free(ret);
2409 ret=NULL;
2410 }
2411 else
2412 *xret=ret;
2413 return(ok);
2414 }
2415
2416static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext)
2417 {
2418
2419 if (output_der)
2420 {
2421 (void)i2d_X509_bio(bp,x);
2422 return;
2423 }
2424#if 0
2425 /* ??? Not needed since X509_print prints all this stuff anyway */
2426 f=X509_NAME_oneline(X509_get_issuer_name(x),buf,256);
2427 BIO_printf(bp,"issuer :%s\n",f);
2428
2429 f=X509_NAME_oneline(X509_get_subject_name(x),buf,256);
2430 BIO_printf(bp,"subject:%s\n",f);
2431
2432 BIO_puts(bp,"serial :");
2433 i2a_ASN1_INTEGER(bp,x->cert_info->serialNumber);
2434 BIO_puts(bp,"\n\n");
2435#endif
2436 if (!notext)X509_print(bp,x);
2437 PEM_write_bio_X509(bp,x);
2438 }
2439
2440static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
2441 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
2442 BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate,
2443 long days, char *ext_sect, CONF *lconf, int verbose, unsigned long certopt,
2444 unsigned long nameopt, int default_op, int ext_copy)
2445 {
2446 STACK_OF(CONF_VALUE) *sk=NULL;
2447 LHASH *parms=NULL;
2448 X509_REQ *req=NULL;
2449 CONF_VALUE *cv=NULL;
2450 NETSCAPE_SPKI *spki = NULL;
2451 X509_REQ_INFO *ri;
2452 char *type,*buf;
2453 EVP_PKEY *pktmp=NULL;
2454 X509_NAME *n=NULL;
2455 X509_NAME_ENTRY *ne=NULL;
2456 int ok= -1,i,j;
2457 long errline;
2458 int nid;
2459
2460 /*
2461 * Load input file into a hash table. (This is just an easy
2462 * way to read and parse the file, then put it into a convenient
2463 * STACK format).
2464 */
2465 parms=CONF_load(NULL,infile,&errline);
2466 if (parms == NULL)
2467 {
2468 BIO_printf(bio_err,"error on line %ld of %s\n",errline,infile);
2469 ERR_print_errors(bio_err);
2470 goto err;
2471 }
2472
2473 sk=CONF_get_section(parms, "default");
2474 if (sk_CONF_VALUE_num(sk) == 0)
2475 {
2476 BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);
2477 CONF_free(parms);
2478 goto err;
2479 }
2480
2481 /*
2482 * Now create a dummy X509 request structure. We don't actually
2483 * have an X509 request, but we have many of the components
2484 * (a public key, various DN components). The idea is that we
2485 * put these components into the right X509 request structure
2486 * and we can use the same code as if you had a real X509 request.
2487 */
2488 req=X509_REQ_new();
2489 if (req == NULL)
2490 {
2491 ERR_print_errors(bio_err);
2492 goto err;
2493 }
2494
2495 /*
2496 * Build up the subject name set.
2497 */
2498 ri=req->req_info;
2499 n = ri->subject;
2500
2501 for (i = 0; ; i++)
2502 {
2503 if (sk_CONF_VALUE_num(sk) <= i) break;
2504
2505 cv=sk_CONF_VALUE_value(sk,i);
2506 type=cv->name;
2507 /* Skip past any leading X. X: X, etc to allow for
2508 * multiple instances
2509 */
2510 for (buf = cv->name; *buf ; buf++)
2511 if ((*buf == ':') || (*buf == ',') || (*buf == '.'))
2512 {
2513 buf++;
2514 if (*buf) type = buf;
2515 break;
2516 }
2517
2518 buf=cv->value;
2519 if ((nid=OBJ_txt2nid(type)) == NID_undef)
2520 {
2521 if (strcmp(type, "SPKAC") == 0)
2522 {
2523 spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
2524 if (spki == NULL)
2525 {
2526 BIO_printf(bio_err,"unable to load Netscape SPKAC structure\n");
2527 ERR_print_errors(bio_err);
2528 goto err;
2529 }
2530 }
2531 continue;
2532 }
2533
2534 /*
2535 if ((nid == NID_pkcs9_emailAddress) && (email_dn == 0))
2536 continue;
2537 */
2538
2539 j=ASN1_PRINTABLE_type((unsigned char *)buf,-1);
2540 if (fix_data(nid, &j) == 0)
2541 {
2542 BIO_printf(bio_err,
2543 "invalid characters in string %s\n",buf);
2544 goto err;
2545 }
2546
2547 if ((ne=X509_NAME_ENTRY_create_by_NID(&ne,nid,j,
2548 (unsigned char *)buf,
2549 strlen(buf))) == NULL)
2550 goto err;
2551
2552 if (!X509_NAME_add_entry(n,ne,-1, 0)) goto err;
2553 }
2554 if (spki == NULL)
2555 {
2556 BIO_printf(bio_err,"Netscape SPKAC structure not found in %s\n",
2557 infile);
2558 goto err;
2559 }
2560
2561 /*
2562 * Now extract the key from the SPKI structure.
2563 */
2564
2565 BIO_printf(bio_err,"Check that the SPKAC request matches the signature\n");
2566
2567 if ((pktmp=NETSCAPE_SPKI_get_pubkey(spki)) == NULL)
2568 {
2569 BIO_printf(bio_err,"error unpacking SPKAC public key\n");
2570 goto err;
2571 }
2572
2573 j = NETSCAPE_SPKI_verify(spki, pktmp);
2574 if (j <= 0)
2575 {
2576 BIO_printf(bio_err,"signature verification failed on SPKAC public key\n");
2577 goto err;
2578 }
2579 BIO_printf(bio_err,"Signature ok\n");
2580
2581 X509_REQ_set_pubkey(req,pktmp);
2582 EVP_PKEY_free(pktmp);
2583 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,email_dn,startdate,enddate,
2584 days,1,verbose,req,ext_sect,lconf, certopt, nameopt, default_op,
2585 ext_copy);
2586err:
2587 if (req != NULL) X509_REQ_free(req);
2588 if (parms != NULL) CONF_free(parms);
2589 if (spki != NULL) NETSCAPE_SPKI_free(spki);
2590 if (ne != NULL) X509_NAME_ENTRY_free(ne);
2591
2592 return(ok);
2593 }
2594
2595static int fix_data(int nid, int *type)
2596 {
2597 if (nid == NID_pkcs9_emailAddress)
2598 *type=V_ASN1_IA5STRING;
2599 if ((nid == NID_commonName) && (*type == V_ASN1_IA5STRING))
2600 *type=V_ASN1_T61STRING;
2601 if ((nid == NID_pkcs9_challengePassword) && (*type == V_ASN1_IA5STRING))
2602 *type=V_ASN1_T61STRING;
2603 if ((nid == NID_pkcs9_unstructuredName) && (*type == V_ASN1_T61STRING))
2604 return(0);
2605 if (nid == NID_pkcs9_unstructuredName)
2606 *type=V_ASN1_IA5STRING;
2607 return(1);
2608 }
2609
2610static int check_time_format(char *str)
2611 {
2612 ASN1_UTCTIME tm;
2613
2614 tm.data=(unsigned char *)str;
2615 tm.length=strlen(str);
2616 tm.type=V_ASN1_UTCTIME;
2617 return(ASN1_UTCTIME_check(&tm));
2618 }
2619
2620static int do_revoke(X509 *x509, TXT_DB *db, int type, char *value)
2621 {
2622 ASN1_UTCTIME *tm=NULL;
2623 char *row[DB_NUMBER],**rrow,**irow;
2624 char *rev_str = NULL;
2625 BIGNUM *bn = NULL;
2626 int ok=-1,i;
2627
2628 for (i=0; i<DB_NUMBER; i++)
2629 row[i]=NULL;
2630 row[DB_name]=X509_NAME_oneline(X509_get_subject_name(x509),NULL,0);
2631 bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509),NULL);
2632 if (BN_is_zero(bn))
2633 row[DB_serial]=BUF_strdup("00");
2634 else
2635 row[DB_serial]=BN_bn2hex(bn);
2636 BN_free(bn);
2637 if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
2638 {
2639 BIO_printf(bio_err,"Memory allocation failure\n");
2640 goto err;
2641 }
2642 /* We have to lookup by serial number because name lookup
2643 * skips revoked certs
2644 */
2645 rrow=TXT_DB_get_by_index(db,DB_serial,row);
2646 if (rrow == NULL)
2647 {
2648 BIO_printf(bio_err,"Adding Entry to DB for %s\n", row[DB_name]);
2649
2650 /* We now just add it to the database */
2651 row[DB_type]=(char *)OPENSSL_malloc(2);
2652
2653 tm=X509_get_notAfter(x509);
2654 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2655 memcpy(row[DB_exp_date],tm->data,tm->length);
2656 row[DB_exp_date][tm->length]='\0';
2657
2658 row[DB_rev_date]=NULL;
2659
2660 /* row[DB_serial] done already */
2661 row[DB_file]=(char *)OPENSSL_malloc(8);
2662
2663 /* row[DB_name] done already */
2664
2665 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2666 (row[DB_file] == NULL))
2667 {
2668 BIO_printf(bio_err,"Memory allocation failure\n");
2669 goto err;
2670 }
2671 strcpy(row[DB_file],"unknown");
2672 row[DB_type][0]='V';
2673 row[DB_type][1]='\0';
2674
2675 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2676 {
2677 BIO_printf(bio_err,"Memory allocation failure\n");
2678 goto err;
2679 }
2680
2681 for (i=0; i<DB_NUMBER; i++)
2682 {
2683 irow[i]=row[i];
2684 row[i]=NULL;
2685 }
2686 irow[DB_NUMBER]=NULL;
2687
2688 if (!TXT_DB_insert(db,irow))
2689 {
2690 BIO_printf(bio_err,"failed to update database\n");
2691 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
2692 goto err;
2693 }
2694
2695 /* Revoke Certificate */
2696 ok = do_revoke(x509,db, type, value);
2697
2698 goto err;
2699
2700 }
2701 else if (index_name_cmp((const char **)row,(const char **)rrow))
2702 {
2703 BIO_printf(bio_err,"ERROR:name does not match %s\n",
2704 row[DB_name]);
2705 goto err;
2706 }
2707 else if (rrow[DB_type][0]=='R')
2708 {
2709 BIO_printf(bio_err,"ERROR:Already revoked, serial number %s\n",
2710 row[DB_serial]);
2711 goto err;
2712 }
2713 else
2714 {
2715 BIO_printf(bio_err,"Revoking Certificate %s.\n", rrow[DB_serial]);
2716 rev_str = make_revocation_str(type, value);
2717 if (!rev_str)
2718 {
2719 BIO_printf(bio_err, "Error in revocation arguments\n");
2720 goto err;
2721 }
2722 rrow[DB_type][0]='R';
2723 rrow[DB_type][1]='\0';
2724 rrow[DB_rev_date] = rev_str;
2725 }
2726 ok=1;
2727err:
2728 for (i=0; i<DB_NUMBER; i++)
2729 {
2730 if (row[i] != NULL)
2731 OPENSSL_free(row[i]);
2732 }
2733 return(ok);
2734 }
2735
2736static int get_certificate_status(const char *serial, TXT_DB *db)
2737 {
2738 char *row[DB_NUMBER],**rrow;
2739 int ok=-1,i;
2740
2741 /* Free Resources */
2742 for (i=0; i<DB_NUMBER; i++)
2743 row[i]=NULL;
2744
2745 /* Malloc needed char spaces */
2746 row[DB_serial] = OPENSSL_malloc(strlen(serial) + 2);
2747 if (row[DB_serial] == NULL)
2748 {
2749 BIO_printf(bio_err,"Malloc failure\n");
2750 goto err;
2751 }
2752
2753 if (strlen(serial) % 2)
2754 {
2755 /* Set the first char to 0 */;
2756 row[DB_serial][0]='0';
2757
2758 /* Copy String from serial to row[DB_serial] */
2759 memcpy(row[DB_serial]+1, serial, strlen(serial));
2760 row[DB_serial][strlen(serial)+1]='\0';
2761 }
2762 else
2763 {
2764 /* Copy String from serial to row[DB_serial] */
2765 memcpy(row[DB_serial], serial, strlen(serial));
2766 row[DB_serial][strlen(serial)]='\0';
2767 }
2768
2769 /* Make it Upper Case */
2770 for (i=0; row[DB_serial][i] != '\0'; i++)
2771 row[DB_serial][i] = toupper(row[DB_serial][i]);
2772
2773
2774 ok=1;
2775
2776 /* Search for the certificate */
2777 rrow=TXT_DB_get_by_index(db,DB_serial,row);
2778 if (rrow == NULL)
2779 {
2780 BIO_printf(bio_err,"Serial %s not present in db.\n",
2781 row[DB_serial]);
2782 ok=-1;
2783 goto err;
2784 }
2785 else if (rrow[DB_type][0]=='V')
2786 {
2787 BIO_printf(bio_err,"%s=Valid (%c)\n",
2788 row[DB_serial], rrow[DB_type][0]);
2789 goto err;
2790 }
2791 else if (rrow[DB_type][0]=='R')
2792 {
2793 BIO_printf(bio_err,"%s=Revoked (%c)\n",
2794 row[DB_serial], rrow[DB_type][0]);
2795 goto err;
2796 }
2797 else if (rrow[DB_type][0]=='E')
2798 {
2799 BIO_printf(bio_err,"%s=Expired (%c)\n",
2800 row[DB_serial], rrow[DB_type][0]);
2801 goto err;
2802 }
2803 else if (rrow[DB_type][0]=='S')
2804 {
2805 BIO_printf(bio_err,"%s=Suspended (%c)\n",
2806 row[DB_serial], rrow[DB_type][0]);
2807 goto err;
2808 }
2809 else
2810 {
2811 BIO_printf(bio_err,"%s=Unknown (%c).\n",
2812 row[DB_serial], rrow[DB_type][0]);
2813 ok=-1;
2814 }
2815err:
2816 for (i=0; i<DB_NUMBER; i++)
2817 {
2818 if (row[i] != NULL)
2819 OPENSSL_free(row[i]);
2820 }
2821 return(ok);
2822 }
2823
2824static int do_updatedb (TXT_DB *db)
2825 {
2826 ASN1_UTCTIME *a_tm = NULL;
2827 int i, cnt = 0;
2828 int db_y2k, a_y2k; /* flags = 1 if y >= 2000 */
2829 char **rrow, *a_tm_s;
2830
2831 a_tm = ASN1_UTCTIME_new();
2832
2833 /* get actual time and make a string */
2834 a_tm = X509_gmtime_adj(a_tm, 0);
2835 a_tm_s = (char *) OPENSSL_malloc(a_tm->length+1);
2836 if (a_tm_s == NULL)
2837 {
2838 cnt = -1;
2839 goto err;
2840 }
2841
2842 memcpy(a_tm_s, a_tm->data, a_tm->length);
2843 a_tm_s[a_tm->length] = '\0';
2844
2845 if (strncmp(a_tm_s, "49", 2) <= 0)
2846 a_y2k = 1;
2847 else
2848 a_y2k = 0;
2849
2850 for (i = 0; i < sk_num(db->data); i++)
2851 {
2852 rrow = (char **) sk_value(db->data, i);
2853
2854 if (rrow[DB_type][0] == 'V')
2855 {
2856 /* ignore entries that are not valid */
2857 if (strncmp(rrow[DB_exp_date], "49", 2) <= 0)
2858 db_y2k = 1;
2859 else
2860 db_y2k = 0;
2861
2862 if (db_y2k == a_y2k)
2863 {
2864 /* all on the same y2k side */
2865 if (strcmp(rrow[DB_exp_date], a_tm_s) <= 0)
2866 {
2867 rrow[DB_type][0] = 'E';
2868 rrow[DB_type][1] = '\0';
2869 cnt++;
2870
2871 BIO_printf(bio_err, "%s=Expired\n",
2872 rrow[DB_serial]);
2873 }
2874 }
2875 else if (db_y2k < a_y2k)
2876 {
2877 rrow[DB_type][0] = 'E';
2878 rrow[DB_type][1] = '\0';
2879 cnt++;
2880
2881 BIO_printf(bio_err, "%s=Expired\n",
2882 rrow[DB_serial]);
2883 }
2884
2885 }
2886 }
2887
2888err:
2889
2890 ASN1_UTCTIME_free(a_tm);
2891 OPENSSL_free(a_tm_s);
2892
2893 return (cnt);
2894 }
2895
2896static char *crl_reasons[] = {
2897 /* CRL reason strings */
2898 "unspecified",
2899 "keyCompromise",
2900 "CACompromise",
2901 "affiliationChanged",
2902 "superseded",
2903 "cessationOfOperation",
2904 "certificateHold",
2905 "removeFromCRL",
2906 /* Additional pseudo reasons */
2907 "holdInstruction",
2908 "keyTime",
2909 "CAkeyTime"
2910};
2911
2912#define NUM_REASONS (sizeof(crl_reasons) / sizeof(char *))
2913
2914/* Given revocation information convert to a DB string.
2915 * The format of the string is:
2916 * revtime[,reason,extra]. Where 'revtime' is the
2917 * revocation time (the current time). 'reason' is the
2918 * optional CRL reason and 'extra' is any additional
2919 * argument
2920 */
2921
2922char *make_revocation_str(int rev_type, char *rev_arg)
2923 {
2924 char *reason = NULL, *other = NULL, *str;
2925 ASN1_OBJECT *otmp;
2926 ASN1_UTCTIME *revtm = NULL;
2927 int i;
2928 switch (rev_type)
2929 {
2930 case REV_NONE:
2931 break;
2932
2933 case REV_CRL_REASON:
2934 for (i = 0; i < 8; i++)
2935 {
2936 if (!strcasecmp(rev_arg, crl_reasons[i]))
2937 {
2938 reason = crl_reasons[i];
2939 break;
2940 }
2941 }
2942 if (reason == NULL)
2943 {
2944 BIO_printf(bio_err, "Unknown CRL reason %s\n", rev_arg);
2945 return NULL;
2946 }
2947 break;
2948
2949 case REV_HOLD:
2950 /* Argument is an OID */
2951
2952 otmp = OBJ_txt2obj(rev_arg, 0);
2953 ASN1_OBJECT_free(otmp);
2954
2955 if (otmp == NULL)
2956 {
2957 BIO_printf(bio_err, "Invalid object identifier %s\n", rev_arg);
2958 return NULL;
2959 }
2960
2961 reason = "holdInstruction";
2962 other = rev_arg;
2963 break;
2964
2965 case REV_KEY_COMPROMISE:
2966 case REV_CA_COMPROMISE:
2967
2968 /* Argument is the key compromise time */
2969 if (!ASN1_GENERALIZEDTIME_set_string(NULL, rev_arg))
2970 {
2971 BIO_printf(bio_err, "Invalid time format %s. Need YYYYMMDDHHMMSSZ\n", rev_arg);
2972 return NULL;
2973 }
2974 other = rev_arg;
2975 if (rev_type == REV_KEY_COMPROMISE)
2976 reason = "keyTime";
2977 else
2978 reason = "CAkeyTime";
2979
2980 break;
2981
2982 }
2983
2984 revtm = X509_gmtime_adj(NULL, 0);
2985
2986 i = revtm->length + 1;
2987
2988 if (reason) i += strlen(reason) + 1;
2989 if (other) i += strlen(other) + 1;
2990
2991 str = OPENSSL_malloc(i);
2992
2993 if (!str) return NULL;
2994
2995 strcpy(str, (char *)revtm->data);
2996 if (reason)
2997 {
2998 strcat(str, ",");
2999 strcat(str, reason);
3000 }
3001 if (other)
3002 {
3003 strcat(str, ",");
3004 strcat(str, other);
3005 }
3006 ASN1_UTCTIME_free(revtm);
3007 return str;
3008 }
3009
3010/* Convert revocation field to X509_REVOKED entry
3011 * return code:
3012 * 0 error
3013 * 1 OK
3014 * 2 OK and some extensions added (i.e. V2 CRL)
3015 */
3016
3017
3018int make_revoked(X509_REVOKED *rev, char *str)
3019 {
3020 char *tmp = NULL;
3021 int reason_code = -1;
3022 int i, ret = 0;
3023 ASN1_OBJECT *hold = NULL;
3024 ASN1_GENERALIZEDTIME *comp_time = NULL;
3025 ASN1_ENUMERATED *rtmp = NULL;
3026
3027 ASN1_TIME *revDate = NULL;
3028
3029 i = unpack_revinfo(&revDate, &reason_code, &hold, &comp_time, str);
3030
3031 if (i == 0)
3032 goto err;
3033
3034 if (rev && !X509_REVOKED_set_revocationDate(rev, revDate))
3035 goto err;
3036
3037 if (rev && (reason_code != OCSP_REVOKED_STATUS_NOSTATUS))
3038 {
3039 rtmp = ASN1_ENUMERATED_new();
3040 if (!rtmp || !ASN1_ENUMERATED_set(rtmp, reason_code))
3041 goto err;
3042 if (!X509_REVOKED_add1_ext_i2d(rev, NID_crl_reason, rtmp, 0, 0))
3043 goto err;
3044 }
3045
3046 if (rev && comp_time)
3047 {
3048 if (!X509_REVOKED_add1_ext_i2d(rev, NID_invalidity_date, comp_time, 0, 0))
3049 goto err;
3050 }
3051 if (rev && hold)
3052 {
3053 if (!X509_REVOKED_add1_ext_i2d(rev, NID_hold_instruction_code, hold, 0, 0))
3054 goto err;
3055 }
3056
3057 if (reason_code != OCSP_REVOKED_STATUS_NOSTATUS)
3058 ret = 2;
3059 else ret = 1;
3060
3061 err:
3062
3063 if (tmp) OPENSSL_free(tmp);
3064 ASN1_OBJECT_free(hold);
3065 ASN1_GENERALIZEDTIME_free(comp_time);
3066 ASN1_ENUMERATED_free(rtmp);
3067 ASN1_TIME_free(revDate);
3068
3069 return ret;
3070 }
3071
3072/*
3073 * subject is expected to be in the format /type0=value0/type1=value1/type2=...
3074 * where characters may be escaped by \
3075 */
3076X509_NAME *do_subject(char *subject, long chtype)
3077 {
3078 size_t buflen = strlen(subject)+1; /* to copy the types and values into. due to escaping, the copy can only become shorter */
3079 char *buf = OPENSSL_malloc(buflen);
3080 size_t max_ne = buflen / 2 + 1; /* maximum number of name elements */
3081 char **ne_types = OPENSSL_malloc(max_ne * sizeof (char *));
3082 char **ne_values = OPENSSL_malloc(max_ne * sizeof (char *));
3083
3084 char *sp = subject, *bp = buf;
3085 int i, ne_num = 0;
3086
3087 X509_NAME *n = NULL;
3088 int nid;
3089
3090 if (!buf || !ne_types || !ne_values)
3091 {
3092 BIO_printf(bio_err, "malloc error\n");
3093 goto error;
3094 }
3095
3096 if (*subject != '/')
3097 {
3098 BIO_printf(bio_err, "Subject does not start with '/'.\n");
3099 goto error;
3100 }
3101 sp++; /* skip leading / */
3102
3103 while (*sp)
3104 {
3105 /* collect type */
3106 ne_types[ne_num] = bp;
3107 while (*sp)
3108 {
3109 if (*sp == '\\') /* is there anything to escape in the type...? */
3110 {
3111 if (*++sp)
3112 *bp++ = *sp++;
3113 else
3114 {
3115 BIO_printf(bio_err, "escape character at end of string\n");
3116 goto error;
3117 }
3118 }
3119 else if (*sp == '=')
3120 {
3121 sp++;
3122 *bp++ = '\0';
3123 break;
3124 }
3125 else
3126 *bp++ = *sp++;
3127 }
3128 if (!*sp)
3129 {
3130 BIO_printf(bio_err, "end of string encountered while processing type of subject name element #%d\n", ne_num);
3131 goto error;
3132 }
3133 ne_values[ne_num] = bp;
3134 while (*sp)
3135 {
3136 if (*sp == '\\')
3137 {
3138 if (*++sp)
3139 *bp++ = *sp++;
3140 else
3141 {
3142 BIO_printf(bio_err, "escape character at end of string\n");
3143 goto error;
3144 }
3145 }
3146 else if (*sp == '/')
3147 {
3148 sp++;
3149 break;
3150 }
3151 else
3152 *bp++ = *sp++;
3153 }
3154 *bp++ = '\0';
3155 ne_num++;
3156 }
3157
3158 if (!(n = X509_NAME_new()))
3159 goto error;
3160
3161 for (i = 0; i < ne_num; i++)
3162 {
3163 if ((nid=OBJ_txt2nid(ne_types[i])) == NID_undef)
3164 {
3165 BIO_printf(bio_err, "Subject Attribute %s has no known NID, skipped\n", ne_types[i]);
3166 continue;
3167 }
3168
3169 if (!*ne_values[i])
3170 {
3171 BIO_printf(bio_err, "No value provided for Subject Attribute %s, skipped\n", ne_types[i]);
3172 continue;
3173 }
3174
3175 if (!X509_NAME_add_entry_by_NID(n, nid, chtype, (unsigned char*)ne_values[i], -1,-1,0))
3176 goto error;
3177 }
3178
3179 OPENSSL_free(ne_values);
3180 OPENSSL_free(ne_types);
3181 OPENSSL_free(buf);
3182 return n;
3183
3184error:
3185 X509_NAME_free(n);
3186 if (ne_values)
3187 OPENSSL_free(ne_values);
3188 if (ne_types)
3189 OPENSSL_free(ne_types);
3190 if (buf)
3191 OPENSSL_free(buf);
3192 return NULL;
3193}
3194
3195int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str)
3196 {
3197 char buf[25],*pbuf, *p;
3198 int j;
3199 j=i2a_ASN1_OBJECT(bp,obj);
3200 pbuf=buf;
3201 for (j=22-j; j>0; j--)
3202 *(pbuf++)=' ';
3203 *(pbuf++)=':';
3204 *(pbuf++)='\0';
3205 BIO_puts(bp,buf);
3206
3207 if (str->type == V_ASN1_PRINTABLESTRING)
3208 BIO_printf(bp,"PRINTABLE:'");
3209 else if (str->type == V_ASN1_T61STRING)
3210 BIO_printf(bp,"T61STRING:'");
3211 else if (str->type == V_ASN1_IA5STRING)
3212 BIO_printf(bp,"IA5STRING:'");
3213 else if (str->type == V_ASN1_UNIVERSALSTRING)
3214 BIO_printf(bp,"UNIVERSALSTRING:'");
3215 else
3216 BIO_printf(bp,"ASN.1 %2d:'",str->type);
3217
3218 p=(char *)str->data;
3219 for (j=str->length; j>0; j--)
3220 {
3221 if ((*p >= ' ') && (*p <= '~'))
3222 BIO_printf(bp,"%c",*p);
3223 else if (*p & 0x80)
3224 BIO_printf(bp,"\\0x%02X",*p);
3225 else if ((unsigned char)*p == 0xf7)
3226 BIO_printf(bp,"^?");
3227 else BIO_printf(bp,"^%c",*p+'@');
3228 p++;
3229 }
3230 BIO_printf(bp,"'\n");
3231 return 1;
3232 }
3233
3234int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold, ASN1_GENERALIZEDTIME **pinvtm, char *str)
3235 {
3236 char *tmp = NULL;
3237 char *rtime_str, *reason_str = NULL, *arg_str = NULL, *p;
3238 int reason_code = -1;
3239 int i, ret = 0;
3240 ASN1_OBJECT *hold = NULL;
3241 ASN1_GENERALIZEDTIME *comp_time = NULL;
3242 tmp = BUF_strdup(str);
3243
3244 p = strchr(tmp, ',');
3245
3246 rtime_str = tmp;
3247
3248 if (p)
3249 {
3250 *p = '\0';
3251 p++;
3252 reason_str = p;
3253 p = strchr(p, ',');
3254 if (p)
3255 {
3256 *p = '\0';
3257 arg_str = p + 1;
3258 }
3259 }
3260
3261 if (prevtm)
3262 {
3263 *prevtm = ASN1_UTCTIME_new();
3264 if (!ASN1_UTCTIME_set_string(*prevtm, rtime_str))
3265 {
3266 BIO_printf(bio_err, "invalid revocation date %s\n", rtime_str);
3267 goto err;
3268 }
3269 }
3270 if (reason_str)
3271 {
3272 for (i = 0; i < NUM_REASONS; i++)
3273 {
3274 if(!strcasecmp(reason_str, crl_reasons[i]))
3275 {
3276 reason_code = i;
3277 break;
3278 }
3279 }
3280 if (reason_code == OCSP_REVOKED_STATUS_NOSTATUS)
3281 {
3282 BIO_printf(bio_err, "invalid reason code %s\n", reason_str);
3283 goto err;
3284 }
3285
3286 if (reason_code == 7)
3287 reason_code = OCSP_REVOKED_STATUS_REMOVEFROMCRL;
3288 else if (reason_code == 8) /* Hold instruction */
3289 {
3290 if (!arg_str)
3291 {
3292 BIO_printf(bio_err, "missing hold instruction\n");
3293 goto err;
3294 }
3295 reason_code = OCSP_REVOKED_STATUS_CERTIFICATEHOLD;
3296 hold = OBJ_txt2obj(arg_str, 0);
3297
3298 if (!hold)
3299 {
3300 BIO_printf(bio_err, "invalid object identifier %s\n", arg_str);
3301 goto err;
3302 }
3303 if (phold) *phold = hold;
3304 }
3305 else if ((reason_code == 9) || (reason_code == 10))
3306 {
3307 if (!arg_str)
3308 {
3309 BIO_printf(bio_err, "missing compromised time\n");
3310 goto err;
3311 }
3312 comp_time = ASN1_GENERALIZEDTIME_new();
3313 if (!ASN1_GENERALIZEDTIME_set_string(comp_time, arg_str))
3314 {
3315 BIO_printf(bio_err, "invalid compromised time %s\n", arg_str);
3316 goto err;
3317 }
3318 if (reason_code == 9)
3319 reason_code = OCSP_REVOKED_STATUS_KEYCOMPROMISE;
3320 else
3321 reason_code = OCSP_REVOKED_STATUS_CACOMPROMISE;
3322 }
3323 }
3324
3325 if (preason) *preason = reason_code;
3326 if (pinvtm) *pinvtm = comp_time;
3327 else ASN1_GENERALIZEDTIME_free(comp_time);
3328
3329 ret = 1;
3330
3331 err:
3332
3333 if (tmp) OPENSSL_free(tmp);
3334 if (!phold) ASN1_OBJECT_free(hold);
3335 if (!pinvtm) ASN1_GENERALIZEDTIME_free(comp_time);
3336
3337 return ret;
3338 }
3339
3340int make_serial_index(TXT_DB *db)
3341 {
3342 if (!TXT_DB_create_index(db, DB_serial, NULL,
3343 LHASH_HASH_FN(index_serial_hash),
3344 LHASH_COMP_FN(index_serial_cmp)))
3345 {
3346 BIO_printf(bio_err,
3347 "error creating serial number index:(%ld,%ld,%ld)\n",
3348 db->error,db->arg1,db->arg2);
3349 return 0;
3350 }
3351 return 1;
3352 }