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