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