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