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