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