]> git.ipfire.org Git - thirdparty/openssl.git/blob - apps/ca.c
LHASH revamp. make depend.
[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 STRING row[DB_NUMBER];
1682 STRING *irow=NULL;
1683 STRING *rrow=NULL;
1684 char buf[25];
1685
1686 tmptm=ASN1_UTCTIME_new();
1687 if (tmptm == NULL)
1688 {
1689 BIO_printf(bio_err,"malloc error\n");
1690 return(0);
1691 }
1692
1693 for (i=0; i<DB_NUMBER; i++)
1694 row[i]=NULL;
1695
1696 if (subj)
1697 {
1698 X509_NAME *n = parse_name(subj, chtype, multirdn);
1699
1700 if (!n)
1701 {
1702 ERR_print_errors(bio_err);
1703 goto err;
1704 }
1705 X509_REQ_set_subject_name(req,n);
1706 req->req_info->enc.modified = 1;
1707 X509_NAME_free(n);
1708 }
1709
1710 if (default_op)
1711 BIO_printf(bio_err,"The Subject's Distinguished Name is as follows\n");
1712
1713 name=X509_REQ_get_subject_name(req);
1714 for (i=0; i<X509_NAME_entry_count(name); i++)
1715 {
1716 ne= X509_NAME_get_entry(name,i);
1717 str=X509_NAME_ENTRY_get_data(ne);
1718 obj=X509_NAME_ENTRY_get_object(ne);
1719
1720 if (msie_hack)
1721 {
1722 /* assume all type should be strings */
1723 nid=OBJ_obj2nid(ne->object);
1724
1725 if (str->type == V_ASN1_UNIVERSALSTRING)
1726 ASN1_UNIVERSALSTRING_to_string(str);
1727
1728 if ((str->type == V_ASN1_IA5STRING) &&
1729 (nid != NID_pkcs9_emailAddress))
1730 str->type=V_ASN1_T61STRING;
1731
1732 if ((nid == NID_pkcs9_emailAddress) &&
1733 (str->type == V_ASN1_PRINTABLESTRING))
1734 str->type=V_ASN1_IA5STRING;
1735 }
1736
1737 /* If no EMAIL is wanted in the subject */
1738 if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) && (!email_dn))
1739 continue;
1740
1741 /* check some things */
1742 if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&
1743 (str->type != V_ASN1_IA5STRING))
1744 {
1745 BIO_printf(bio_err,"\nemailAddress type needs to be of type IA5STRING\n");
1746 goto err;
1747 }
1748 if ((str->type != V_ASN1_BMPSTRING) && (str->type != V_ASN1_UTF8STRING))
1749 {
1750 j=ASN1_PRINTABLE_type(str->data,str->length);
1751 if ( ((j == V_ASN1_T61STRING) &&
1752 (str->type != V_ASN1_T61STRING)) ||
1753 ((j == V_ASN1_IA5STRING) &&
1754 (str->type == V_ASN1_PRINTABLESTRING)))
1755 {
1756 BIO_printf(bio_err,"\nThe string contains characters that are illegal for the ASN.1 type\n");
1757 goto err;
1758 }
1759 }
1760
1761 if (default_op)
1762 old_entry_print(bio_err, obj, str);
1763 }
1764
1765 /* Ok, now we check the 'policy' stuff. */
1766 if ((subject=X509_NAME_new()) == NULL)
1767 {
1768 BIO_printf(bio_err,"Memory allocation failure\n");
1769 goto err;
1770 }
1771
1772 /* take a copy of the issuer name before we mess with it. */
1773 if (selfsign)
1774 CAname=X509_NAME_dup(name);
1775 else
1776 CAname=X509_NAME_dup(x509->cert_info->subject);
1777 if (CAname == NULL) goto err;
1778 str=str2=NULL;
1779
1780 for (i=0; i<sk_CONF_VALUE_num(policy); i++)
1781 {
1782 cv=sk_CONF_VALUE_value(policy,i); /* get the object id */
1783 if ((j=OBJ_txt2nid(cv->name)) == NID_undef)
1784 {
1785 BIO_printf(bio_err,"%s:unknown object type in 'policy' configuration\n",cv->name);
1786 goto err;
1787 }
1788 obj=OBJ_nid2obj(j);
1789
1790 last= -1;
1791 for (;;)
1792 {
1793 /* lookup the object in the supplied name list */
1794 j=X509_NAME_get_index_by_OBJ(name,obj,last);
1795 if (j < 0)
1796 {
1797 if (last != -1) break;
1798 tne=NULL;
1799 }
1800 else
1801 {
1802 tne=X509_NAME_get_entry(name,j);
1803 }
1804 last=j;
1805
1806 /* depending on the 'policy', decide what to do. */
1807 push=NULL;
1808 if (strcmp(cv->value,"optional") == 0)
1809 {
1810 if (tne != NULL)
1811 push=tne;
1812 }
1813 else if (strcmp(cv->value,"supplied") == 0)
1814 {
1815 if (tne == NULL)
1816 {
1817 BIO_printf(bio_err,"The %s field needed to be supplied and was missing\n",cv->name);
1818 goto err;
1819 }
1820 else
1821 push=tne;
1822 }
1823 else if (strcmp(cv->value,"match") == 0)
1824 {
1825 int last2;
1826
1827 if (tne == NULL)
1828 {
1829 BIO_printf(bio_err,"The mandatory %s field was missing\n",cv->name);
1830 goto err;
1831 }
1832
1833 last2= -1;
1834
1835 again2:
1836 j=X509_NAME_get_index_by_OBJ(CAname,obj,last2);
1837 if ((j < 0) && (last2 == -1))
1838 {
1839 BIO_printf(bio_err,"The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",cv->name);
1840 goto err;
1841 }
1842 if (j >= 0)
1843 {
1844 push=X509_NAME_get_entry(CAname,j);
1845 str=X509_NAME_ENTRY_get_data(tne);
1846 str2=X509_NAME_ENTRY_get_data(push);
1847 last2=j;
1848 if (ASN1_STRING_cmp(str,str2) != 0)
1849 goto again2;
1850 }
1851 if (j < 0)
1852 {
1853 BIO_printf(bio_err,"The %s field needed to be the same in the\nCA certificate (%s) and the request (%s)\n",cv->name,((str2 == NULL)?"NULL":(char *)str2->data),((str == NULL)?"NULL":(char *)str->data));
1854 goto err;
1855 }
1856 }
1857 else
1858 {
1859 BIO_printf(bio_err,"%s:invalid type in 'policy' configuration\n",cv->value);
1860 goto err;
1861 }
1862
1863 if (push != NULL)
1864 {
1865 if (!X509_NAME_add_entry(subject,push, -1, 0))
1866 {
1867 if (push != NULL)
1868 X509_NAME_ENTRY_free(push);
1869 BIO_printf(bio_err,"Memory allocation failure\n");
1870 goto err;
1871 }
1872 }
1873 if (j < 0) break;
1874 }
1875 }
1876
1877 if (preserve)
1878 {
1879 X509_NAME_free(subject);
1880 /* subject=X509_NAME_dup(X509_REQ_get_subject_name(req)); */
1881 subject=X509_NAME_dup(name);
1882 if (subject == NULL) goto err;
1883 }
1884
1885 if (verbose)
1886 BIO_printf(bio_err,"The subject name appears to be ok, checking data base for clashes\n");
1887
1888 /* Build the correct Subject if no e-mail is wanted in the subject */
1889 /* and add it later on because of the method extensions are added (altName) */
1890
1891 if (email_dn)
1892 dn_subject = subject;
1893 else
1894 {
1895 X509_NAME_ENTRY *tmpne;
1896 /* Its best to dup the subject DN and then delete any email
1897 * addresses because this retains its structure.
1898 */
1899 if (!(dn_subject = X509_NAME_dup(subject)))
1900 {
1901 BIO_printf(bio_err,"Memory allocation failure\n");
1902 goto err;
1903 }
1904 while((i = X509_NAME_get_index_by_NID(dn_subject,
1905 NID_pkcs9_emailAddress, -1)) >= 0)
1906 {
1907 tmpne = X509_NAME_get_entry(dn_subject, i);
1908 X509_NAME_delete_entry(dn_subject, i);
1909 X509_NAME_ENTRY_free(tmpne);
1910 }
1911 }
1912
1913 if (BN_is_zero(serial))
1914 row[DB_serial]=BUF_strdup("00");
1915 else
1916 row[DB_serial]=BN_bn2hex(serial);
1917 if (row[DB_serial] == NULL)
1918 {
1919 BIO_printf(bio_err,"Memory allocation failure\n");
1920 goto err;
1921 }
1922
1923 if (db->attributes.unique_subject)
1924 {
1925 STRING *crow=row;
1926
1927 rrow=TXT_DB_get_by_index(db->db,DB_name,crow);
1928 if (rrow != NULL)
1929 {
1930 BIO_printf(bio_err,
1931 "ERROR:There is already a certificate for %s\n",
1932 row[DB_name]);
1933 }
1934 }
1935 if (rrow == NULL)
1936 {
1937 rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
1938 if (rrow != NULL)
1939 {
1940 BIO_printf(bio_err,"ERROR:Serial number %s has already been issued,\n",
1941 row[DB_serial]);
1942 BIO_printf(bio_err," check the database/serial_file for corruption\n");
1943 }
1944 }
1945
1946 if (rrow != NULL)
1947 {
1948 BIO_printf(bio_err,
1949 "The matching entry has the following details\n");
1950 if (rrow[DB_type][0] == 'E')
1951 p="Expired";
1952 else if (rrow[DB_type][0] == 'R')
1953 p="Revoked";
1954 else if (rrow[DB_type][0] == 'V')
1955 p="Valid";
1956 else
1957 p="\ninvalid type, Data base error\n";
1958 BIO_printf(bio_err,"Type :%s\n",p);;
1959 if (rrow[DB_type][0] == 'R')
1960 {
1961 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1962 BIO_printf(bio_err,"Was revoked on:%s\n",p);
1963 }
1964 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1965 BIO_printf(bio_err,"Expires on :%s\n",p);
1966 p=rrow[DB_serial]; if (p == NULL) p="undef";
1967 BIO_printf(bio_err,"Serial Number :%s\n",p);
1968 p=rrow[DB_file]; if (p == NULL) p="undef";
1969 BIO_printf(bio_err,"File name :%s\n",p);
1970 p=rrow[DB_name]; if (p == NULL) p="undef";
1971 BIO_printf(bio_err,"Subject Name :%s\n",p);
1972 ok= -1; /* This is now a 'bad' error. */
1973 goto err;
1974 }
1975
1976 /* We are now totally happy, lets make and sign the certificate */
1977 if (verbose)
1978 BIO_printf(bio_err,"Everything appears to be ok, creating and signing the certificate\n");
1979
1980 if ((ret=X509_new()) == NULL) goto err;
1981 ci=ret->cert_info;
1982
1983 #ifdef X509_V3
1984 /* Make it an X509 v3 certificate. */
1985 if (!X509_set_version(ret,2)) goto err;
1986 #endif
1987
1988 if (BN_to_ASN1_INTEGER(serial,ci->serialNumber) == NULL)
1989 goto err;
1990 if (selfsign)
1991 {
1992 if (!X509_set_issuer_name(ret,subject))
1993 goto err;
1994 }
1995 else
1996 {
1997 if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))
1998 goto err;
1999 }
2000
2001 if (strcmp(startdate,"today") == 0)
2002 X509_gmtime_adj(X509_get_notBefore(ret),0);
2003 else ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate);
2004
2005 if (enddate == NULL)
2006 X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days);
2007 else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate);
2008
2009 if (!X509_set_subject_name(ret,subject)) goto err;
2010
2011 pktmp=X509_REQ_get_pubkey(req);
2012 i = X509_set_pubkey(ret,pktmp);
2013 EVP_PKEY_free(pktmp);
2014 if (!i) goto err;
2015
2016 /* Lets add the extensions, if there are any */
2017 if (ext_sect)
2018 {
2019 X509V3_CTX ctx;
2020 if (ci->version == NULL)
2021 if ((ci->version=ASN1_INTEGER_new()) == NULL)
2022 goto err;
2023 ASN1_INTEGER_set(ci->version,2); /* version 3 certificate */
2024
2025 /* Free the current entries if any, there should not
2026 * be any I believe */
2027 if (ci->extensions != NULL)
2028 sk_X509_EXTENSION_pop_free(ci->extensions,
2029 X509_EXTENSION_free);
2030
2031 ci->extensions = NULL;
2032
2033 /* Initialize the context structure */
2034 if (selfsign)
2035 X509V3_set_ctx(&ctx, ret, ret, req, NULL, 0);
2036 else
2037 X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
2038
2039 if (extconf)
2040 {
2041 if (verbose)
2042 BIO_printf(bio_err, "Extra configuration file found\n");
2043
2044 /* Use the extconf configuration db LHASH */
2045 X509V3_set_nconf(&ctx, extconf);
2046
2047 /* Test the structure (needed?) */
2048 /* X509V3_set_ctx_test(&ctx); */
2049
2050 /* Adds exts contained in the configuration file */
2051 if (!X509V3_EXT_add_nconf(extconf, &ctx, ext_sect,ret))
2052 {
2053 BIO_printf(bio_err,
2054 "ERROR: adding extensions in section %s\n",
2055 ext_sect);
2056 ERR_print_errors(bio_err);
2057 goto err;
2058 }
2059 if (verbose)
2060 BIO_printf(bio_err, "Successfully added extensions from file.\n");
2061 }
2062 else if (ext_sect)
2063 {
2064 /* We found extensions to be set from config file */
2065 X509V3_set_nconf(&ctx, lconf);
2066
2067 if(!X509V3_EXT_add_nconf(lconf, &ctx, ext_sect, ret))
2068 {
2069 BIO_printf(bio_err, "ERROR: adding extensions in section %s\n", ext_sect);
2070 ERR_print_errors(bio_err);
2071 goto err;
2072 }
2073
2074 if (verbose)
2075 BIO_printf(bio_err, "Successfully added extensions from config\n");
2076 }
2077 }
2078
2079 /* Copy extensions from request (if any) */
2080
2081 if (!copy_extensions(ret, req, ext_copy))
2082 {
2083 BIO_printf(bio_err, "ERROR: adding extensions from request\n");
2084 ERR_print_errors(bio_err);
2085 goto err;
2086 }
2087
2088 /* Set the right value for the noemailDN option */
2089 if( email_dn == 0 )
2090 {
2091 if (!X509_set_subject_name(ret,dn_subject)) goto err;
2092 }
2093
2094 if (!default_op)
2095 {
2096 BIO_printf(bio_err, "Certificate Details:\n");
2097 /* Never print signature details because signature not present */
2098 certopt |= X509_FLAG_NO_SIGDUMP | X509_FLAG_NO_SIGNAME;
2099 X509_print_ex(bio_err, ret, nameopt, certopt);
2100 }
2101
2102 BIO_printf(bio_err,"Certificate is to be certified until ");
2103 ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ret));
2104 if (days) BIO_printf(bio_err," (%ld days)",days);
2105 BIO_printf(bio_err, "\n");
2106
2107 if (!batch)
2108 {
2109
2110 BIO_printf(bio_err,"Sign the certificate? [y/n]:");
2111 (void)BIO_flush(bio_err);
2112 buf[0]='\0';
2113 fgets(buf,sizeof(buf)-1,stdin);
2114 if (!((buf[0] == 'y') || (buf[0] == 'Y')))
2115 {
2116 BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED\n");
2117 ok=0;
2118 goto err;
2119 }
2120 }
2121
2122 pktmp=X509_get_pubkey(ret);
2123 if (EVP_PKEY_missing_parameters(pktmp) &&
2124 !EVP_PKEY_missing_parameters(pkey))
2125 EVP_PKEY_copy_parameters(pktmp,pkey);
2126 EVP_PKEY_free(pktmp);
2127
2128 if (!X509_sign(ret,pkey,dgst))
2129 goto err;
2130
2131 /* We now just add it to the database */
2132 row[DB_type]=(char *)OPENSSL_malloc(2);
2133
2134 tm=X509_get_notAfter(ret);
2135 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2136 memcpy(row[DB_exp_date],tm->data,tm->length);
2137 row[DB_exp_date][tm->length]='\0';
2138
2139 row[DB_rev_date]=NULL;
2140
2141 /* row[DB_serial] done already */
2142 row[DB_file]=(char *)OPENSSL_malloc(8);
2143 row[DB_name]=X509_NAME_oneline(X509_get_subject_name(ret),NULL,0);
2144
2145 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2146 (row[DB_file] == NULL) || (row[DB_name] == NULL))
2147 {
2148 BIO_printf(bio_err,"Memory allocation failure\n");
2149 goto err;
2150 }
2151 BUF_strlcpy(row[DB_file],"unknown",8);
2152 row[DB_type][0]='V';
2153 row[DB_type][1]='\0';
2154
2155 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2156 {
2157 BIO_printf(bio_err,"Memory allocation failure\n");
2158 goto err;
2159 }
2160
2161 for (i=0; i<DB_NUMBER; i++)
2162 {
2163 irow[i]=row[i];
2164 row[i]=NULL;
2165 }
2166 irow[DB_NUMBER]=NULL;
2167
2168 if (!TXT_DB_insert(db->db,irow))
2169 {
2170 BIO_printf(bio_err,"failed to update database\n");
2171 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->db->error);
2172 goto err;
2173 }
2174 ok=1;
2175 err:
2176 for (i=0; i<DB_NUMBER; i++)
2177 if (row[i] != NULL) OPENSSL_free(row[i]);
2178
2179 if (CAname != NULL)
2180 X509_NAME_free(CAname);
2181 if (subject != NULL)
2182 X509_NAME_free(subject);
2183 if ((dn_subject != NULL) && !email_dn)
2184 X509_NAME_free(dn_subject);
2185 if (tmptm != NULL)
2186 ASN1_UTCTIME_free(tmptm);
2187 if (ok <= 0)
2188 {
2189 if (ret != NULL) X509_free(ret);
2190 ret=NULL;
2191 }
2192 else
2193 *xret=ret;
2194 return(ok);
2195 }
2196
2197 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext)
2198 {
2199
2200 if (output_der)
2201 {
2202 (void)i2d_X509_bio(bp,x);
2203 return;
2204 }
2205 #if 0
2206 /* ??? Not needed since X509_print prints all this stuff anyway */
2207 f=X509_NAME_oneline(X509_get_issuer_name(x),buf,256);
2208 BIO_printf(bp,"issuer :%s\n",f);
2209
2210 f=X509_NAME_oneline(X509_get_subject_name(x),buf,256);
2211 BIO_printf(bp,"subject:%s\n",f);
2212
2213 BIO_puts(bp,"serial :");
2214 i2a_ASN1_INTEGER(bp,x->cert_info->serialNumber);
2215 BIO_puts(bp,"\n\n");
2216 #endif
2217 if (!notext)X509_print(bp,x);
2218 PEM_write_bio_X509(bp,x);
2219 }
2220
2221 static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
2222 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db,
2223 BIGNUM *serial, char *subj,unsigned long chtype, int multirdn, int email_dn, char *startdate, char *enddate,
2224 long days, char *ext_sect, CONF *lconf, int verbose, unsigned long certopt,
2225 unsigned long nameopt, int default_op, int ext_copy)
2226 {
2227 STACK_OF(CONF_VALUE) *sk=NULL;
2228 LHASH_OF(CONF_VALUE) *parms=NULL;
2229 X509_REQ *req=NULL;
2230 CONF_VALUE *cv=NULL;
2231 NETSCAPE_SPKI *spki = NULL;
2232 X509_REQ_INFO *ri;
2233 char *type,*buf;
2234 EVP_PKEY *pktmp=NULL;
2235 X509_NAME *n=NULL;
2236 X509_NAME_ENTRY *ne=NULL;
2237 int ok= -1,i,j;
2238 long errline;
2239 int nid;
2240
2241 /*
2242 * Load input file into a hash table. (This is just an easy
2243 * way to read and parse the file, then put it into a convenient
2244 * STACK format).
2245 */
2246 parms=CONF_load(NULL,infile,&errline);
2247 if (parms == NULL)
2248 {
2249 BIO_printf(bio_err,"error on line %ld of %s\n",errline,infile);
2250 ERR_print_errors(bio_err);
2251 goto err;
2252 }
2253
2254 sk=CONF_get_section(parms, "default");
2255 if (sk_CONF_VALUE_num(sk) == 0)
2256 {
2257 BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);
2258 CONF_free(parms);
2259 goto err;
2260 }
2261
2262 /*
2263 * Now create a dummy X509 request structure. We don't actually
2264 * have an X509 request, but we have many of the components
2265 * (a public key, various DN components). The idea is that we
2266 * put these components into the right X509 request structure
2267 * and we can use the same code as if you had a real X509 request.
2268 */
2269 req=X509_REQ_new();
2270 if (req == NULL)
2271 {
2272 ERR_print_errors(bio_err);
2273 goto err;
2274 }
2275
2276 /*
2277 * Build up the subject name set.
2278 */
2279 ri=req->req_info;
2280 n = ri->subject;
2281
2282 for (i = 0; ; i++)
2283 {
2284 if (sk_CONF_VALUE_num(sk) <= i) break;
2285
2286 cv=sk_CONF_VALUE_value(sk,i);
2287 type=cv->name;
2288 /* Skip past any leading X. X: X, etc to allow for
2289 * multiple instances
2290 */
2291 for (buf = cv->name; *buf ; buf++)
2292 if ((*buf == ':') || (*buf == ',') || (*buf == '.'))
2293 {
2294 buf++;
2295 if (*buf) type = buf;
2296 break;
2297 }
2298
2299 buf=cv->value;
2300 if ((nid=OBJ_txt2nid(type)) == NID_undef)
2301 {
2302 if (strcmp(type, "SPKAC") == 0)
2303 {
2304 spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
2305 if (spki == NULL)
2306 {
2307 BIO_printf(bio_err,"unable to load Netscape SPKAC structure\n");
2308 ERR_print_errors(bio_err);
2309 goto err;
2310 }
2311 }
2312 continue;
2313 }
2314
2315 /*
2316 if ((nid == NID_pkcs9_emailAddress) && (email_dn == 0))
2317 continue;
2318 */
2319
2320 j=ASN1_PRINTABLE_type((unsigned char *)buf,-1);
2321 if (fix_data(nid, &j) == 0)
2322 {
2323 BIO_printf(bio_err,
2324 "invalid characters in string %s\n",buf);
2325 goto err;
2326 }
2327
2328 if ((ne=X509_NAME_ENTRY_create_by_NID(&ne,nid,j,
2329 (unsigned char *)buf,
2330 strlen(buf))) == NULL)
2331 goto err;
2332
2333 if (!X509_NAME_add_entry(n,ne,-1, 0)) goto err;
2334 }
2335 if (spki == NULL)
2336 {
2337 BIO_printf(bio_err,"Netscape SPKAC structure not found in %s\n",
2338 infile);
2339 goto err;
2340 }
2341
2342 /*
2343 * Now extract the key from the SPKI structure.
2344 */
2345
2346 BIO_printf(bio_err,"Check that the SPKAC request matches the signature\n");
2347
2348 if ((pktmp=NETSCAPE_SPKI_get_pubkey(spki)) == NULL)
2349 {
2350 BIO_printf(bio_err,"error unpacking SPKAC public key\n");
2351 goto err;
2352 }
2353
2354 j = NETSCAPE_SPKI_verify(spki, pktmp);
2355 if (j <= 0)
2356 {
2357 BIO_printf(bio_err,"signature verification failed on SPKAC public key\n");
2358 goto err;
2359 }
2360 BIO_printf(bio_err,"Signature ok\n");
2361
2362 X509_REQ_set_pubkey(req,pktmp);
2363 EVP_PKEY_free(pktmp);
2364 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,chtype,multirdn,email_dn,startdate,enddate,
2365 days,1,verbose,req,ext_sect,lconf, certopt, nameopt, default_op,
2366 ext_copy, 0);
2367 err:
2368 if (req != NULL) X509_REQ_free(req);
2369 if (parms != NULL) CONF_free(parms);
2370 if (spki != NULL) NETSCAPE_SPKI_free(spki);
2371 if (ne != NULL) X509_NAME_ENTRY_free(ne);
2372
2373 return(ok);
2374 }
2375
2376 static int fix_data(int nid, int *type)
2377 {
2378 if (nid == NID_pkcs9_emailAddress)
2379 *type=V_ASN1_IA5STRING;
2380 if ((nid == NID_commonName) && (*type == V_ASN1_IA5STRING))
2381 *type=V_ASN1_T61STRING;
2382 if ((nid == NID_pkcs9_challengePassword) && (*type == V_ASN1_IA5STRING))
2383 *type=V_ASN1_T61STRING;
2384 if ((nid == NID_pkcs9_unstructuredName) && (*type == V_ASN1_T61STRING))
2385 return(0);
2386 if (nid == NID_pkcs9_unstructuredName)
2387 *type=V_ASN1_IA5STRING;
2388 return(1);
2389 }
2390
2391 static int check_time_format(const char *str)
2392 {
2393 ASN1_UTCTIME tm;
2394
2395 tm.data=(unsigned char *)str;
2396 tm.length=strlen(str);
2397 tm.type=V_ASN1_UTCTIME;
2398 return(ASN1_UTCTIME_check(&tm));
2399 }
2400
2401 static int do_revoke(X509 *x509, CA_DB *db, int type, char *value)
2402 {
2403 ASN1_UTCTIME *tm=NULL;
2404 char *row[DB_NUMBER],**rrow,**irow;
2405 char *rev_str = NULL;
2406 BIGNUM *bn = NULL;
2407 int ok=-1,i;
2408
2409 for (i=0; i<DB_NUMBER; i++)
2410 row[i]=NULL;
2411 row[DB_name]=X509_NAME_oneline(X509_get_subject_name(x509),NULL,0);
2412 bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509),NULL);
2413 if (!bn)
2414 goto err;
2415 if (BN_is_zero(bn))
2416 row[DB_serial]=BUF_strdup("00");
2417 else
2418 row[DB_serial]=BN_bn2hex(bn);
2419 BN_free(bn);
2420 if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
2421 {
2422 BIO_printf(bio_err,"Memory allocation failure\n");
2423 goto err;
2424 }
2425 /* We have to lookup by serial number because name lookup
2426 * skips revoked certs
2427 */
2428 rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
2429 if (rrow == NULL)
2430 {
2431 BIO_printf(bio_err,"Adding Entry with serial number %s to DB for %s\n", row[DB_serial], row[DB_name]);
2432
2433 /* We now just add it to the database */
2434 row[DB_type]=(char *)OPENSSL_malloc(2);
2435
2436 tm=X509_get_notAfter(x509);
2437 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2438 memcpy(row[DB_exp_date],tm->data,tm->length);
2439 row[DB_exp_date][tm->length]='\0';
2440
2441 row[DB_rev_date]=NULL;
2442
2443 /* row[DB_serial] done already */
2444 row[DB_file]=(char *)OPENSSL_malloc(8);
2445
2446 /* row[DB_name] done already */
2447
2448 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2449 (row[DB_file] == NULL))
2450 {
2451 BIO_printf(bio_err,"Memory allocation failure\n");
2452 goto err;
2453 }
2454 BUF_strlcpy(row[DB_file],"unknown",8);
2455 row[DB_type][0]='V';
2456 row[DB_type][1]='\0';
2457
2458 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2459 {
2460 BIO_printf(bio_err,"Memory allocation failure\n");
2461 goto err;
2462 }
2463
2464 for (i=0; i<DB_NUMBER; i++)
2465 {
2466 irow[i]=row[i];
2467 row[i]=NULL;
2468 }
2469 irow[DB_NUMBER]=NULL;
2470
2471 if (!TXT_DB_insert(db->db,irow))
2472 {
2473 BIO_printf(bio_err,"failed to update database\n");
2474 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->db->error);
2475 goto err;
2476 }
2477
2478 /* Revoke Certificate */
2479 ok = do_revoke(x509,db, type, value);
2480
2481 goto err;
2482
2483 }
2484 else if (index_name_cmp(row,rrow))
2485 {
2486 BIO_printf(bio_err,"ERROR:name does not match %s\n",
2487 row[DB_name]);
2488 goto err;
2489 }
2490 else if (rrow[DB_type][0]=='R')
2491 {
2492 BIO_printf(bio_err,"ERROR:Already revoked, serial number %s\n",
2493 row[DB_serial]);
2494 goto err;
2495 }
2496 else
2497 {
2498 BIO_printf(bio_err,"Revoking Certificate %s.\n", rrow[DB_serial]);
2499 rev_str = make_revocation_str(type, value);
2500 if (!rev_str)
2501 {
2502 BIO_printf(bio_err, "Error in revocation arguments\n");
2503 goto err;
2504 }
2505 rrow[DB_type][0]='R';
2506 rrow[DB_type][1]='\0';
2507 rrow[DB_rev_date] = rev_str;
2508 }
2509 ok=1;
2510 err:
2511 for (i=0; i<DB_NUMBER; i++)
2512 {
2513 if (row[i] != NULL)
2514 OPENSSL_free(row[i]);
2515 }
2516 return(ok);
2517 }
2518
2519 static int get_certificate_status(const char *serial, CA_DB *db)
2520 {
2521 char *row[DB_NUMBER],**rrow;
2522 int ok=-1,i;
2523
2524 /* Free Resources */
2525 for (i=0; i<DB_NUMBER; i++)
2526 row[i]=NULL;
2527
2528 /* Malloc needed char spaces */
2529 row[DB_serial] = OPENSSL_malloc(strlen(serial) + 2);
2530 if (row[DB_serial] == NULL)
2531 {
2532 BIO_printf(bio_err,"Malloc failure\n");
2533 goto err;
2534 }
2535
2536 if (strlen(serial) % 2)
2537 {
2538 /* Set the first char to 0 */;
2539 row[DB_serial][0]='0';
2540
2541 /* Copy String from serial to row[DB_serial] */
2542 memcpy(row[DB_serial]+1, serial, strlen(serial));
2543 row[DB_serial][strlen(serial)+1]='\0';
2544 }
2545 else
2546 {
2547 /* Copy String from serial to row[DB_serial] */
2548 memcpy(row[DB_serial], serial, strlen(serial));
2549 row[DB_serial][strlen(serial)]='\0';
2550 }
2551
2552 /* Make it Upper Case */
2553 for (i=0; row[DB_serial][i] != '\0'; i++)
2554 row[DB_serial][i] = toupper(row[DB_serial][i]);
2555
2556
2557 ok=1;
2558
2559 /* Search for the certificate */
2560 rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
2561 if (rrow == NULL)
2562 {
2563 BIO_printf(bio_err,"Serial %s not present in db.\n",
2564 row[DB_serial]);
2565 ok=-1;
2566 goto err;
2567 }
2568 else if (rrow[DB_type][0]=='V')
2569 {
2570 BIO_printf(bio_err,"%s=Valid (%c)\n",
2571 row[DB_serial], rrow[DB_type][0]);
2572 goto err;
2573 }
2574 else if (rrow[DB_type][0]=='R')
2575 {
2576 BIO_printf(bio_err,"%s=Revoked (%c)\n",
2577 row[DB_serial], rrow[DB_type][0]);
2578 goto err;
2579 }
2580 else if (rrow[DB_type][0]=='E')
2581 {
2582 BIO_printf(bio_err,"%s=Expired (%c)\n",
2583 row[DB_serial], rrow[DB_type][0]);
2584 goto err;
2585 }
2586 else if (rrow[DB_type][0]=='S')
2587 {
2588 BIO_printf(bio_err,"%s=Suspended (%c)\n",
2589 row[DB_serial], rrow[DB_type][0]);
2590 goto err;
2591 }
2592 else
2593 {
2594 BIO_printf(bio_err,"%s=Unknown (%c).\n",
2595 row[DB_serial], rrow[DB_type][0]);
2596 ok=-1;
2597 }
2598 err:
2599 for (i=0; i<DB_NUMBER; i++)
2600 {
2601 if (row[i] != NULL)
2602 OPENSSL_free(row[i]);
2603 }
2604 return(ok);
2605 }
2606
2607 static int do_updatedb (CA_DB *db)
2608 {
2609 ASN1_UTCTIME *a_tm = NULL;
2610 int i, cnt = 0;
2611 int db_y2k, a_y2k; /* flags = 1 if y >= 2000 */
2612 char **rrow, *a_tm_s;
2613
2614 a_tm = ASN1_UTCTIME_new();
2615
2616 /* get actual time and make a string */
2617 a_tm = X509_gmtime_adj(a_tm, 0);
2618 a_tm_s = (char *) OPENSSL_malloc(a_tm->length+1);
2619 if (a_tm_s == NULL)
2620 {
2621 cnt = -1;
2622 goto err;
2623 }
2624
2625 memcpy(a_tm_s, a_tm->data, a_tm->length);
2626 a_tm_s[a_tm->length] = '\0';
2627
2628 if (strncmp(a_tm_s, "49", 2) <= 0)
2629 a_y2k = 1;
2630 else
2631 a_y2k = 0;
2632
2633 for (i = 0; i < sk_num(db->db->data); i++)
2634 {
2635 rrow = (char **) sk_value(db->db->data, i);
2636
2637 if (rrow[DB_type][0] == 'V')
2638 {
2639 /* ignore entries that are not valid */
2640 if (strncmp(rrow[DB_exp_date], "49", 2) <= 0)
2641 db_y2k = 1;
2642 else
2643 db_y2k = 0;
2644
2645 if (db_y2k == a_y2k)
2646 {
2647 /* all on the same y2k side */
2648 if (strcmp(rrow[DB_exp_date], a_tm_s) <= 0)
2649 {
2650 rrow[DB_type][0] = 'E';
2651 rrow[DB_type][1] = '\0';
2652 cnt++;
2653
2654 BIO_printf(bio_err, "%s=Expired\n",
2655 rrow[DB_serial]);
2656 }
2657 }
2658 else if (db_y2k < a_y2k)
2659 {
2660 rrow[DB_type][0] = 'E';
2661 rrow[DB_type][1] = '\0';
2662 cnt++;
2663
2664 BIO_printf(bio_err, "%s=Expired\n",
2665 rrow[DB_serial]);
2666 }
2667
2668 }
2669 }
2670
2671 err:
2672
2673 ASN1_UTCTIME_free(a_tm);
2674 OPENSSL_free(a_tm_s);
2675
2676 return (cnt);
2677 }
2678
2679 static const char *crl_reasons[] = {
2680 /* CRL reason strings */
2681 "unspecified",
2682 "keyCompromise",
2683 "CACompromise",
2684 "affiliationChanged",
2685 "superseded",
2686 "cessationOfOperation",
2687 "certificateHold",
2688 "removeFromCRL",
2689 /* Additional pseudo reasons */
2690 "holdInstruction",
2691 "keyTime",
2692 "CAkeyTime"
2693 };
2694
2695 #define NUM_REASONS (sizeof(crl_reasons) / sizeof(char *))
2696
2697 /* Given revocation information convert to a DB string.
2698 * The format of the string is:
2699 * revtime[,reason,extra]. Where 'revtime' is the
2700 * revocation time (the current time). 'reason' is the
2701 * optional CRL reason and 'extra' is any additional
2702 * argument
2703 */
2704
2705 char *make_revocation_str(int rev_type, char *rev_arg)
2706 {
2707 char *other = NULL, *str;
2708 const char *reason = NULL;
2709 ASN1_OBJECT *otmp;
2710 ASN1_UTCTIME *revtm = NULL;
2711 int i;
2712 switch (rev_type)
2713 {
2714 case REV_NONE:
2715 break;
2716
2717 case REV_CRL_REASON:
2718 for (i = 0; i < 8; i++)
2719 {
2720 if (!strcasecmp(rev_arg, crl_reasons[i]))
2721 {
2722 reason = crl_reasons[i];
2723 break;
2724 }
2725 }
2726 if (reason == NULL)
2727 {
2728 BIO_printf(bio_err, "Unknown CRL reason %s\n", rev_arg);
2729 return NULL;
2730 }
2731 break;
2732
2733 case REV_HOLD:
2734 /* Argument is an OID */
2735
2736 otmp = OBJ_txt2obj(rev_arg, 0);
2737 ASN1_OBJECT_free(otmp);
2738
2739 if (otmp == NULL)
2740 {
2741 BIO_printf(bio_err, "Invalid object identifier %s\n", rev_arg);
2742 return NULL;
2743 }
2744
2745 reason = "holdInstruction";
2746 other = rev_arg;
2747 break;
2748
2749 case REV_KEY_COMPROMISE:
2750 case REV_CA_COMPROMISE:
2751
2752 /* Argument is the key compromise time */
2753 if (!ASN1_GENERALIZEDTIME_set_string(NULL, rev_arg))
2754 {
2755 BIO_printf(bio_err, "Invalid time format %s. Need YYYYMMDDHHMMSSZ\n", rev_arg);
2756 return NULL;
2757 }
2758 other = rev_arg;
2759 if (rev_type == REV_KEY_COMPROMISE)
2760 reason = "keyTime";
2761 else
2762 reason = "CAkeyTime";
2763
2764 break;
2765
2766 }
2767
2768 revtm = X509_gmtime_adj(NULL, 0);
2769
2770 i = revtm->length + 1;
2771
2772 if (reason) i += strlen(reason) + 1;
2773 if (other) i += strlen(other) + 1;
2774
2775 str = OPENSSL_malloc(i);
2776
2777 if (!str) return NULL;
2778
2779 BUF_strlcpy(str, (char *)revtm->data, i);
2780 if (reason)
2781 {
2782 BUF_strlcat(str, ",", i);
2783 BUF_strlcat(str, reason, i);
2784 }
2785 if (other)
2786 {
2787 BUF_strlcat(str, ",", i);
2788 BUF_strlcat(str, other, i);
2789 }
2790 ASN1_UTCTIME_free(revtm);
2791 return str;
2792 }
2793
2794 /* Convert revocation field to X509_REVOKED entry
2795 * return code:
2796 * 0 error
2797 * 1 OK
2798 * 2 OK and some extensions added (i.e. V2 CRL)
2799 */
2800
2801
2802 int make_revoked(X509_REVOKED *rev, const char *str)
2803 {
2804 char *tmp = NULL;
2805 int reason_code = -1;
2806 int i, ret = 0;
2807 ASN1_OBJECT *hold = NULL;
2808 ASN1_GENERALIZEDTIME *comp_time = NULL;
2809 ASN1_ENUMERATED *rtmp = NULL;
2810
2811 ASN1_TIME *revDate = NULL;
2812
2813 i = unpack_revinfo(&revDate, &reason_code, &hold, &comp_time, str);
2814
2815 if (i == 0)
2816 goto err;
2817
2818 if (rev && !X509_REVOKED_set_revocationDate(rev, revDate))
2819 goto err;
2820
2821 if (rev && (reason_code != OCSP_REVOKED_STATUS_NOSTATUS))
2822 {
2823 rtmp = ASN1_ENUMERATED_new();
2824 if (!rtmp || !ASN1_ENUMERATED_set(rtmp, reason_code))
2825 goto err;
2826 if (!X509_REVOKED_add1_ext_i2d(rev, NID_crl_reason, rtmp, 0, 0))
2827 goto err;
2828 }
2829
2830 if (rev && comp_time)
2831 {
2832 if (!X509_REVOKED_add1_ext_i2d(rev, NID_invalidity_date, comp_time, 0, 0))
2833 goto err;
2834 }
2835 if (rev && hold)
2836 {
2837 if (!X509_REVOKED_add1_ext_i2d(rev, NID_hold_instruction_code, hold, 0, 0))
2838 goto err;
2839 }
2840
2841 if (reason_code != OCSP_REVOKED_STATUS_NOSTATUS)
2842 ret = 2;
2843 else ret = 1;
2844
2845 err:
2846
2847 if (tmp) OPENSSL_free(tmp);
2848 ASN1_OBJECT_free(hold);
2849 ASN1_GENERALIZEDTIME_free(comp_time);
2850 ASN1_ENUMERATED_free(rtmp);
2851 ASN1_TIME_free(revDate);
2852
2853 return ret;
2854 }
2855
2856 int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str)
2857 {
2858 char buf[25],*pbuf, *p;
2859 int j;
2860 j=i2a_ASN1_OBJECT(bp,obj);
2861 pbuf=buf;
2862 for (j=22-j; j>0; j--)
2863 *(pbuf++)=' ';
2864 *(pbuf++)=':';
2865 *(pbuf++)='\0';
2866 BIO_puts(bp,buf);
2867
2868 if (str->type == V_ASN1_PRINTABLESTRING)
2869 BIO_printf(bp,"PRINTABLE:'");
2870 else if (str->type == V_ASN1_T61STRING)
2871 BIO_printf(bp,"T61STRING:'");
2872 else if (str->type == V_ASN1_IA5STRING)
2873 BIO_printf(bp,"IA5STRING:'");
2874 else if (str->type == V_ASN1_UNIVERSALSTRING)
2875 BIO_printf(bp,"UNIVERSALSTRING:'");
2876 else
2877 BIO_printf(bp,"ASN.1 %2d:'",str->type);
2878
2879 p=(char *)str->data;
2880 for (j=str->length; j>0; j--)
2881 {
2882 if ((*p >= ' ') && (*p <= '~'))
2883 BIO_printf(bp,"%c",*p);
2884 else if (*p & 0x80)
2885 BIO_printf(bp,"\\0x%02X",*p);
2886 else if ((unsigned char)*p == 0xf7)
2887 BIO_printf(bp,"^?");
2888 else BIO_printf(bp,"^%c",*p+'@');
2889 p++;
2890 }
2891 BIO_printf(bp,"'\n");
2892 return 1;
2893 }
2894
2895 int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold, ASN1_GENERALIZEDTIME **pinvtm, const char *str)
2896 {
2897 char *tmp = NULL;
2898 char *rtime_str, *reason_str = NULL, *arg_str = NULL, *p;
2899 int reason_code = -1;
2900 int ret = 0;
2901 unsigned int i;
2902 ASN1_OBJECT *hold = NULL;
2903 ASN1_GENERALIZEDTIME *comp_time = NULL;
2904 tmp = BUF_strdup(str);
2905
2906 p = strchr(tmp, ',');
2907
2908 rtime_str = tmp;
2909
2910 if (p)
2911 {
2912 *p = '\0';
2913 p++;
2914 reason_str = p;
2915 p = strchr(p, ',');
2916 if (p)
2917 {
2918 *p = '\0';
2919 arg_str = p + 1;
2920 }
2921 }
2922
2923 if (prevtm)
2924 {
2925 *prevtm = ASN1_UTCTIME_new();
2926 if (!ASN1_UTCTIME_set_string(*prevtm, rtime_str))
2927 {
2928 BIO_printf(bio_err, "invalid revocation date %s\n", rtime_str);
2929 goto err;
2930 }
2931 }
2932 if (reason_str)
2933 {
2934 for (i = 0; i < NUM_REASONS; i++)
2935 {
2936 if(!strcasecmp(reason_str, crl_reasons[i]))
2937 {
2938 reason_code = i;
2939 break;
2940 }
2941 }
2942 if (reason_code == OCSP_REVOKED_STATUS_NOSTATUS)
2943 {
2944 BIO_printf(bio_err, "invalid reason code %s\n", reason_str);
2945 goto err;
2946 }
2947
2948 if (reason_code == 7)
2949 reason_code = OCSP_REVOKED_STATUS_REMOVEFROMCRL;
2950 else if (reason_code == 8) /* Hold instruction */
2951 {
2952 if (!arg_str)
2953 {
2954 BIO_printf(bio_err, "missing hold instruction\n");
2955 goto err;
2956 }
2957 reason_code = OCSP_REVOKED_STATUS_CERTIFICATEHOLD;
2958 hold = OBJ_txt2obj(arg_str, 0);
2959
2960 if (!hold)
2961 {
2962 BIO_printf(bio_err, "invalid object identifier %s\n", arg_str);
2963 goto err;
2964 }
2965 if (phold) *phold = hold;
2966 }
2967 else if ((reason_code == 9) || (reason_code == 10))
2968 {
2969 if (!arg_str)
2970 {
2971 BIO_printf(bio_err, "missing compromised time\n");
2972 goto err;
2973 }
2974 comp_time = ASN1_GENERALIZEDTIME_new();
2975 if (!ASN1_GENERALIZEDTIME_set_string(comp_time, arg_str))
2976 {
2977 BIO_printf(bio_err, "invalid compromised time %s\n", arg_str);
2978 goto err;
2979 }
2980 if (reason_code == 9)
2981 reason_code = OCSP_REVOKED_STATUS_KEYCOMPROMISE;
2982 else
2983 reason_code = OCSP_REVOKED_STATUS_CACOMPROMISE;
2984 }
2985 }
2986
2987 if (preason) *preason = reason_code;
2988 if (pinvtm) *pinvtm = comp_time;
2989 else ASN1_GENERALIZEDTIME_free(comp_time);
2990
2991 ret = 1;
2992
2993 err:
2994
2995 if (tmp) OPENSSL_free(tmp);
2996 if (!phold) ASN1_OBJECT_free(hold);
2997 if (!pinvtm) ASN1_GENERALIZEDTIME_free(comp_time);
2998
2999 return ret;
3000 }