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