]> git.ipfire.org Git - thirdparty/openssl.git/blob - apps/ca.c
Move add_oid_section to apps.c, so it can be shared by several
[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 <sys/types.h>
65 #include <sys/stat.h>
66 #include "apps.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/pem.h>
77
78 #ifndef W_OK
79 # ifdef VMS
80 # if defined(__DECC)
81 # include <unistd.h>
82 # else
83 # include <unixlib.h>
84 # endif
85 # else
86 # include <sys/file.h>
87 # endif
88 #endif
89
90 #ifndef W_OK
91 # define F_OK 0
92 # define X_OK 1
93 # define W_OK 2
94 # define R_OK 4
95 #endif
96
97 #undef PROG
98 #define PROG ca_main
99
100 #define BASE_SECTION "ca"
101 #define CONFIG_FILE "openssl.cnf"
102
103 #define ENV_DEFAULT_CA "default_ca"
104
105 #define ENV_DIR "dir"
106 #define ENV_CERTS "certs"
107 #define ENV_CRL_DIR "crl_dir"
108 #define ENV_CA_DB "CA_DB"
109 #define ENV_NEW_CERTS_DIR "new_certs_dir"
110 #define ENV_CERTIFICATE "certificate"
111 #define ENV_SERIAL "serial"
112 #define ENV_CRL "crl"
113 #define ENV_PRIVATE_KEY "private_key"
114 #define ENV_RANDFILE "RANDFILE"
115 #define ENV_DEFAULT_DAYS "default_days"
116 #define ENV_DEFAULT_STARTDATE "default_startdate"
117 #define ENV_DEFAULT_ENDDATE "default_enddate"
118 #define ENV_DEFAULT_CRL_DAYS "default_crl_days"
119 #define ENV_DEFAULT_CRL_HOURS "default_crl_hours"
120 #define ENV_DEFAULT_MD "default_md"
121 #define ENV_PRESERVE "preserve"
122 #define ENV_POLICY "policy"
123 #define ENV_EXTENSIONS "x509_extensions"
124 #define ENV_CRLEXT "crl_extensions"
125 #define ENV_MSIE_HACK "msie_hack"
126
127 #define ENV_DATABASE "database"
128
129 #define DB_type 0
130 #define DB_exp_date 1
131 #define DB_rev_date 2
132 #define DB_serial 3 /* index - unique */
133 #define DB_file 4
134 #define DB_name 5 /* index - unique for active */
135 #define DB_NUMBER 6
136
137 #define DB_TYPE_REV 'R'
138 #define DB_TYPE_EXP 'E'
139 #define DB_TYPE_VAL 'V'
140
141 static char *ca_usage[]={
142 "usage: ca args\n",
143 "\n",
144 " -verbose - Talk alot while doing things\n",
145 " -config file - A config file\n",
146 " -name arg - The particular CA definition to use\n",
147 " -gencrl - Generate a new CRL\n",
148 " -crldays days - Days is when the next CRL is due\n",
149 " -crlhours hours - Hours is when the next CRL is due\n",
150 " -startdate YYMMDDHHMMSSZ - certificate validity notBefore\n",
151 " -enddate YYMMDDHHMMSSZ - certificate validity notAfter (overrides -days)\n",
152 " -days arg - number of days to certify the certificate for\n",
153 " -md arg - md to use, one of md2, md5, sha or sha1\n",
154 " -policy arg - The CA 'policy' to support\n",
155 " -keyfile arg - PEM private key file\n",
156 " -key arg - key to decode the private key if it is encrypted\n",
157 " -cert file - The CA certificate\n",
158 " -in file - The input PEM encoded certificate request(s)\n",
159 " -out file - Where to put the output file(s)\n",
160 " -outdir dir - Where to put output certificates\n",
161 " -infiles .... - The last argument, requests to process\n",
162 " -spkac file - File contains DN and signed public key and challenge\n",
163 " -ss_cert file - File contains a self signed cert to sign\n",
164 " -preserveDN - Don't re-order the DN\n",
165 " -batch - Don't ask questions\n",
166 " -msie_hack - msie modifications to handle all those universal strings\n",
167 " -revoke file - Revoke a certificate (given in file)\n",
168 " -extensions .. - Extension section (override value in config file)\n",
169 " -crlexts .. - CRL extension section (override value in config file)\n",
170 NULL
171 };
172
173 #ifdef EFENCE
174 extern int EF_PROTECT_FREE;
175 extern int EF_PROTECT_BELOW;
176 extern int EF_ALIGNMENT;
177 #endif
178
179 static void lookup_fail(char *name,char *tag);
180 static unsigned long index_serial_hash(char **a);
181 static int index_serial_cmp(char **a, char **b);
182 static unsigned long index_name_hash(char **a);
183 static int index_name_qual(char **a);
184 static int index_name_cmp(char **a,char **b);
185 static BIGNUM *load_serial(char *serialfile);
186 static int save_serial(char *serialfile, BIGNUM *serial);
187 static int certify(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
188 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,TXT_DB *db,
189 BIGNUM *serial, char *startdate,char *enddate, int days,
190 int batch, char *ext_sect, LHASH *conf,int verbose);
191 static int certify_cert(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
192 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
193 TXT_DB *db, BIGNUM *serial,char *startdate,
194 char *enddate, int days, int batch, char *ext_sect,
195 LHASH *conf,int verbose);
196 static int certify_spkac(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
197 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
198 TXT_DB *db, BIGNUM *serial,char *startdate,
199 char *enddate, int days, char *ext_sect,LHASH *conf,
200 int verbose);
201 static int fix_data(int nid, int *type);
202 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext);
203 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
204 STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial,
205 char *startdate, char *enddate, int days, int batch, int verbose,
206 X509_REQ *req, char *ext_sect, LHASH *conf);
207 static int do_revoke(X509 *x509, TXT_DB *db);
208 static int check_time_format(char *str);
209 static LHASH *conf=NULL;
210 static char *section=NULL;
211
212 static int preserve=0;
213 static int msie_hack=0;
214
215 int MAIN(int, char **);
216
217 int MAIN(int argc, char **argv)
218 {
219 char *key=NULL;
220 int total=0;
221 int total_done=0;
222 int badops=0;
223 int ret=1;
224 int req=0;
225 int verbose=0;
226 int gencrl=0;
227 int dorevoke=0;
228 long crldays=0;
229 long crlhours=0;
230 long errorline= -1;
231 char *configfile=NULL;
232 char *md=NULL;
233 char *policy=NULL;
234 char *keyfile=NULL;
235 char *certfile=NULL;
236 char *infile=NULL;
237 char *spkac_file=NULL;
238 char *ss_cert_file=NULL;
239 EVP_PKEY *pkey=NULL;
240 int output_der = 0;
241 char *outfile=NULL;
242 char *outdir=NULL;
243 char *serialfile=NULL;
244 char *extensions=NULL;
245 char *crl_ext=NULL;
246 BIGNUM *serial=NULL;
247 char *startdate=NULL;
248 char *enddate=NULL;
249 int days=0;
250 int batch=0;
251 int notext=0;
252 X509 *x509=NULL;
253 X509 *x=NULL;
254 BIO *in=NULL,*out=NULL,*Sout=NULL,*Cout=NULL;
255 char *dbfile=NULL;
256 TXT_DB *db=NULL;
257 X509_CRL *crl=NULL;
258 X509_CRL_INFO *ci=NULL;
259 X509_REVOKED *r=NULL;
260 char **pp,*p,*f;
261 int i,j;
262 long l;
263 const EVP_MD *dgst=NULL;
264 STACK_OF(CONF_VALUE) *attribs=NULL;
265 STACK_OF(X509) *cert_sk=NULL;
266 BIO *hex=NULL;
267 #undef BSIZE
268 #define BSIZE 256
269 MS_STATIC char buf[3][BSIZE];
270 char *randfile=NULL;
271
272 #ifdef EFENCE
273 EF_PROTECT_FREE=1;
274 EF_PROTECT_BELOW=1;
275 EF_ALIGNMENT=0;
276 #endif
277
278 apps_startup();
279
280 conf = NULL;
281 key = NULL;
282 section = NULL;
283
284 preserve=0;
285 msie_hack=0;
286 if (bio_err == NULL)
287 if ((bio_err=BIO_new(BIO_s_file())) != NULL)
288 BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
289
290 argc--;
291 argv++;
292 while (argc >= 1)
293 {
294 if (strcmp(*argv,"-verbose") == 0)
295 verbose=1;
296 else if (strcmp(*argv,"-config") == 0)
297 {
298 if (--argc < 1) goto bad;
299 configfile= *(++argv);
300 }
301 else if (strcmp(*argv,"-name") == 0)
302 {
303 if (--argc < 1) goto bad;
304 section= *(++argv);
305 }
306 else if (strcmp(*argv,"-startdate") == 0)
307 {
308 if (--argc < 1) goto bad;
309 startdate= *(++argv);
310 }
311 else if (strcmp(*argv,"-enddate") == 0)
312 {
313 if (--argc < 1) goto bad;
314 enddate= *(++argv);
315 }
316 else if (strcmp(*argv,"-days") == 0)
317 {
318 if (--argc < 1) goto bad;
319 days=atoi(*(++argv));
320 }
321 else if (strcmp(*argv,"-md") == 0)
322 {
323 if (--argc < 1) goto bad;
324 md= *(++argv);
325 }
326 else if (strcmp(*argv,"-policy") == 0)
327 {
328 if (--argc < 1) goto bad;
329 policy= *(++argv);
330 }
331 else if (strcmp(*argv,"-keyfile") == 0)
332 {
333 if (--argc < 1) goto bad;
334 keyfile= *(++argv);
335 }
336 else if (strcmp(*argv,"-key") == 0)
337 {
338 if (--argc < 1) goto bad;
339 key= *(++argv);
340 }
341 else if (strcmp(*argv,"-cert") == 0)
342 {
343 if (--argc < 1) goto bad;
344 certfile= *(++argv);
345 }
346 else if (strcmp(*argv,"-in") == 0)
347 {
348 if (--argc < 1) goto bad;
349 infile= *(++argv);
350 req=1;
351 }
352 else if (strcmp(*argv,"-out") == 0)
353 {
354 if (--argc < 1) goto bad;
355 outfile= *(++argv);
356 }
357 else if (strcmp(*argv,"-outdir") == 0)
358 {
359 if (--argc < 1) goto bad;
360 outdir= *(++argv);
361 }
362 else if (strcmp(*argv,"-notext") == 0)
363 notext=1;
364 else if (strcmp(*argv,"-batch") == 0)
365 batch=1;
366 else if (strcmp(*argv,"-preserveDN") == 0)
367 preserve=1;
368 else if (strcmp(*argv,"-gencrl") == 0)
369 gencrl=1;
370 else if (strcmp(*argv,"-msie_hack") == 0)
371 msie_hack=1;
372 else if (strcmp(*argv,"-crldays") == 0)
373 {
374 if (--argc < 1) goto bad;
375 crldays= atol(*(++argv));
376 }
377 else if (strcmp(*argv,"-crlhours") == 0)
378 {
379 if (--argc < 1) goto bad;
380 crlhours= atol(*(++argv));
381 }
382 else if (strcmp(*argv,"-infiles") == 0)
383 {
384 argc--;
385 argv++;
386 req=1;
387 break;
388 }
389 else if (strcmp(*argv, "-ss_cert") == 0)
390 {
391 if (--argc < 1) goto bad;
392 ss_cert_file = *(++argv);
393 req=1;
394 }
395 else if (strcmp(*argv, "-spkac") == 0)
396 {
397 if (--argc < 1) goto bad;
398 spkac_file = *(++argv);
399 req=1;
400 }
401 else if (strcmp(*argv,"-revoke") == 0)
402 {
403 if (--argc < 1) goto bad;
404 infile= *(++argv);
405 dorevoke=1;
406 }
407 else if (strcmp(*argv,"-extensions") == 0)
408 {
409 if (--argc < 1) goto bad;
410 extensions= *(++argv);
411 }
412 else if (strcmp(*argv,"-crlexts") == 0)
413 {
414 if (--argc < 1) goto bad;
415 crl_ext= *(++argv);
416 }
417 else
418 {
419 bad:
420 BIO_printf(bio_err,"unknown option %s\n",*argv);
421 badops=1;
422 break;
423 }
424 argc--;
425 argv++;
426 }
427
428 if (badops)
429 {
430 for (pp=ca_usage; (*pp != NULL); pp++)
431 BIO_printf(bio_err,*pp);
432 goto err;
433 }
434
435 ERR_load_crypto_strings();
436
437 /*****************************************************************/
438 if (configfile == NULL) configfile = getenv("OPENSSL_CONF");
439 if (configfile == NULL) configfile = getenv("SSLEAY_CONF");
440 if (configfile == NULL)
441 {
442 /* We will just use 'buf[0]' as a temporary buffer. */
443 #ifdef VMS
444 strncpy(buf[0],X509_get_default_cert_area(),
445 sizeof(buf[0])-1-sizeof(CONFIG_FILE));
446 #else
447 strncpy(buf[0],X509_get_default_cert_area(),
448 sizeof(buf[0])-2-sizeof(CONFIG_FILE));
449 strcat(buf[0],"/");
450 #endif
451 strcat(buf[0],CONFIG_FILE);
452 configfile=buf[0];
453 }
454
455 BIO_printf(bio_err,"Using configuration from %s\n",configfile);
456 if ((conf=CONF_load(NULL,configfile,&errorline)) == NULL)
457 {
458 if (errorline <= 0)
459 BIO_printf(bio_err,"error loading the config file '%s'\n",
460 configfile);
461 else
462 BIO_printf(bio_err,"error on line %ld of config file '%s'\n"
463 ,errorline,configfile);
464 goto err;
465 }
466
467 /* Lets get the config section we are using */
468 if (section == NULL)
469 {
470 section=CONF_get_string(conf,BASE_SECTION,ENV_DEFAULT_CA);
471 if (section == NULL)
472 {
473 lookup_fail(BASE_SECTION,ENV_DEFAULT_CA);
474 goto err;
475 }
476 }
477
478 if (conf != NULL)
479 {
480 p=CONF_get_string(conf,NULL,"oid_file");
481 if (p != NULL)
482 {
483 BIO *oid_bio;
484
485 oid_bio=BIO_new_file(p,"r");
486 if (oid_bio == NULL)
487 {
488 /*
489 BIO_printf(bio_err,"problems opening %s for extra oid's\n",p);
490 ERR_print_errors(bio_err);
491 */
492 ERR_clear_error();
493 }
494 else
495 {
496 OBJ_create_objects(oid_bio);
497 BIO_free(oid_bio);
498 }
499 }
500 if(!add_oid_section(bio_err,conf))
501 {
502 ERR_print_errors(bio_err);
503 goto err;
504 }
505 }
506
507 randfile = CONF_get_string(conf, BASE_SECTION, "RANDFILE");
508 app_RAND_load_file(randfile, bio_err, 0);
509
510 in=BIO_new(BIO_s_file());
511 out=BIO_new(BIO_s_file());
512 Sout=BIO_new(BIO_s_file());
513 Cout=BIO_new(BIO_s_file());
514 if ((in == NULL) || (out == NULL) || (Sout == NULL) || (Cout == NULL))
515 {
516 ERR_print_errors(bio_err);
517 goto err;
518 }
519
520 /*****************************************************************/
521 /* we definitely need an public key, so lets get it */
522
523 if ((keyfile == NULL) && ((keyfile=CONF_get_string(conf,
524 section,ENV_PRIVATE_KEY)) == NULL))
525 {
526 lookup_fail(section,ENV_PRIVATE_KEY);
527 goto err;
528 }
529 if (BIO_read_filename(in,keyfile) <= 0)
530 {
531 perror(keyfile);
532 BIO_printf(bio_err,"trying to load CA private key\n");
533 goto err;
534 }
535 pkey=PEM_read_bio_PrivateKey(in,NULL,NULL,key);
536 if(key) memset(key,0,strlen(key));
537 if (pkey == NULL)
538 {
539 BIO_printf(bio_err,"unable to load CA private key\n");
540 goto err;
541 }
542
543 /*****************************************************************/
544 /* we need a certificate */
545 if ((certfile == NULL) && ((certfile=CONF_get_string(conf,
546 section,ENV_CERTIFICATE)) == NULL))
547 {
548 lookup_fail(section,ENV_CERTIFICATE);
549 goto err;
550 }
551 if (BIO_read_filename(in,certfile) <= 0)
552 {
553 perror(certfile);
554 BIO_printf(bio_err,"trying to load CA certificate\n");
555 goto err;
556 }
557 x509=PEM_read_bio_X509(in,NULL,NULL,NULL);
558 if (x509 == NULL)
559 {
560 BIO_printf(bio_err,"unable to load CA certificate\n");
561 goto err;
562 }
563
564 if (!X509_check_private_key(x509,pkey))
565 {
566 BIO_printf(bio_err,"CA certificate and CA private key do not match\n");
567 goto err;
568 }
569
570 f=CONF_get_string(conf,BASE_SECTION,ENV_PRESERVE);
571 if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
572 preserve=1;
573 f=CONF_get_string(conf,BASE_SECTION,ENV_MSIE_HACK);
574 if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
575 msie_hack=1;
576
577 /*****************************************************************/
578 /* lookup where to write new certificates */
579 if ((outdir == NULL) && (req))
580 {
581 struct stat sb;
582
583 if ((outdir=CONF_get_string(conf,section,ENV_NEW_CERTS_DIR))
584 == NULL)
585 {
586 BIO_printf(bio_err,"there needs to be defined a directory for new certificate to be placed in\n");
587 goto err;
588 }
589 #ifndef VMS /* outdir is a directory spec, but access() for VMS demands a
590 filename. In any case, stat(), below, will catch the problem
591 if outdir is not a directory spec, and the fopen() or open()
592 will catch an error if there is no write access.
593
594 Presumably, this problem could also be solved by using the DEC
595 C routines to convert the directory syntax to Unixly, and give
596 that to access(). However, time's too short to do that just
597 now.
598 */
599 if (access(outdir,R_OK|W_OK|X_OK) != 0)
600 {
601 BIO_printf(bio_err,"I am unable to access the %s directory\n",outdir);
602 perror(outdir);
603 goto err;
604 }
605
606 if (stat(outdir,&sb) != 0)
607 {
608 BIO_printf(bio_err,"unable to stat(%s)\n",outdir);
609 perror(outdir);
610 goto err;
611 }
612 #ifdef S_IFDIR
613 if (!(sb.st_mode & S_IFDIR))
614 {
615 BIO_printf(bio_err,"%s need to be a directory\n",outdir);
616 perror(outdir);
617 goto err;
618 }
619 #endif
620 #endif
621 }
622
623 /*****************************************************************/
624 /* we need to load the database file */
625 if ((dbfile=CONF_get_string(conf,section,ENV_DATABASE)) == NULL)
626 {
627 lookup_fail(section,ENV_DATABASE);
628 goto err;
629 }
630 if (BIO_read_filename(in,dbfile) <= 0)
631 {
632 perror(dbfile);
633 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
634 goto err;
635 }
636 db=TXT_DB_read(in,DB_NUMBER);
637 if (db == NULL) goto err;
638
639 /* Lets check some fields */
640 for (i=0; i<sk_num(db->data); i++)
641 {
642 pp=(char **)sk_value(db->data,i);
643 if ((pp[DB_type][0] != DB_TYPE_REV) &&
644 (pp[DB_rev_date][0] != '\0'))
645 {
646 BIO_printf(bio_err,"entry %d: not revoked yet, but has a revocation date\n",i+1);
647 goto err;
648 }
649 if ((pp[DB_type][0] == DB_TYPE_REV) &&
650 !check_time_format(pp[DB_rev_date]))
651 {
652 BIO_printf(bio_err,"entry %d: invalid revocation date\n",
653 i+1);
654 goto err;
655 }
656 if (!check_time_format(pp[DB_exp_date]))
657 {
658 BIO_printf(bio_err,"entry %d: invalid expiry date\n",i+1);
659 goto err;
660 }
661 p=pp[DB_serial];
662 j=strlen(p);
663 if ((j&1) || (j < 2))
664 {
665 BIO_printf(bio_err,"entry %d: bad serial number length (%d)\n",i+1,j);
666 goto err;
667 }
668 while (*p)
669 {
670 if (!( ((*p >= '0') && (*p <= '9')) ||
671 ((*p >= 'A') && (*p <= 'F')) ||
672 ((*p >= 'a') && (*p <= 'f'))) )
673 {
674 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);
675 goto err;
676 }
677 p++;
678 }
679 }
680 if (verbose)
681 {
682 BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT); /* cannot fail */
683 TXT_DB_write(out,db);
684 BIO_printf(bio_err,"%d entries loaded from the database\n",
685 db->data->num);
686 BIO_printf(bio_err,"generating index\n");
687 }
688
689 if (!TXT_DB_create_index(db,DB_serial,NULL,index_serial_hash,
690 index_serial_cmp))
691 {
692 BIO_printf(bio_err,"error creating serial number index:(%ld,%ld,%ld)\n",db->error,db->arg1,db->arg2);
693 goto err;
694 }
695
696 if (!TXT_DB_create_index(db,DB_name,index_name_qual,index_name_hash,
697 index_name_cmp))
698 {
699 BIO_printf(bio_err,"error creating name index:(%ld,%ld,%ld)\n",
700 db->error,db->arg1,db->arg2);
701 goto err;
702 }
703
704 /*****************************************************************/
705 if (req || gencrl)
706 {
707 if (outfile != NULL)
708 {
709
710 if (BIO_write_filename(Sout,outfile) <= 0)
711 {
712 perror(outfile);
713 goto err;
714 }
715 }
716 else
717 BIO_set_fp(Sout,stdout,BIO_NOCLOSE|BIO_FP_TEXT);
718 }
719
720 if (req)
721 {
722 if ((md == NULL) && ((md=CONF_get_string(conf,
723 section,ENV_DEFAULT_MD)) == NULL))
724 {
725 lookup_fail(section,ENV_DEFAULT_MD);
726 goto err;
727 }
728 if ((dgst=EVP_get_digestbyname(md)) == NULL)
729 {
730 BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
731 goto err;
732 }
733 if (verbose)
734 BIO_printf(bio_err,"message digest is %s\n",
735 OBJ_nid2ln(dgst->type));
736 if ((policy == NULL) && ((policy=CONF_get_string(conf,
737 section,ENV_POLICY)) == NULL))
738 {
739 lookup_fail(section,ENV_POLICY);
740 goto err;
741 }
742 if (verbose)
743 BIO_printf(bio_err,"policy is %s\n",policy);
744
745 if ((serialfile=CONF_get_string(conf,section,ENV_SERIAL))
746 == NULL)
747 {
748 lookup_fail(section,ENV_SERIAL);
749 goto err;
750 }
751 if(!extensions)
752 extensions=CONF_get_string(conf,section,ENV_EXTENSIONS);
753 if(extensions) {
754 /* Check syntax of file */
755 X509V3_CTX ctx;
756 X509V3_set_ctx_test(&ctx);
757 X509V3_set_conf_lhash(&ctx, conf);
758 if(!X509V3_EXT_add_conf(conf, &ctx, extensions, NULL)) {
759 BIO_printf(bio_err,
760 "Error Loading extension section %s\n",
761 extensions);
762 ret = 1;
763 goto err;
764 }
765 }
766
767 if (startdate == NULL)
768 {
769 startdate=CONF_get_string(conf,section,
770 ENV_DEFAULT_STARTDATE);
771 }
772 if (startdate && !ASN1_UTCTIME_set_string(NULL,startdate))
773 {
774 BIO_printf(bio_err,"start date is invalid, it should be YYMMDDHHMMSSZ\n");
775 goto err;
776 }
777 if (startdate == NULL) startdate="today";
778
779 if (enddate == NULL)
780 {
781 enddate=CONF_get_string(conf,section,
782 ENV_DEFAULT_ENDDATE);
783 }
784 if (enddate && !ASN1_UTCTIME_set_string(NULL,enddate))
785 {
786 BIO_printf(bio_err,"end date is invalid, it should be YYMMDDHHMMSSZ\n");
787 goto err;
788 }
789
790 if (days == 0)
791 {
792 days=(int)CONF_get_number(conf,section,
793 ENV_DEFAULT_DAYS);
794 }
795 if (!enddate && (days == 0))
796 {
797 BIO_printf(bio_err,"cannot lookup how many days to certify for\n");
798 goto err;
799 }
800
801 if ((serial=load_serial(serialfile)) == NULL)
802 {
803 BIO_printf(bio_err,"error while loading serial number\n");
804 goto err;
805 }
806 if (verbose)
807 {
808 if ((f=BN_bn2hex(serial)) == NULL) goto err;
809 BIO_printf(bio_err,"next serial number is %s\n",f);
810 OPENSSL_free(f);
811 }
812
813 if ((attribs=CONF_get_section(conf,policy)) == NULL)
814 {
815 BIO_printf(bio_err,"unable to find 'section' for %s\n",policy);
816 goto err;
817 }
818
819 if ((cert_sk=sk_X509_new_null()) == NULL)
820 {
821 BIO_printf(bio_err,"Memory allocation failure\n");
822 goto err;
823 }
824 if (spkac_file != NULL)
825 {
826 total++;
827 j=certify_spkac(&x,spkac_file,pkey,x509,dgst,attribs,db,
828 serial,startdate,enddate, days,extensions,conf,
829 verbose);
830 if (j < 0) goto err;
831 if (j > 0)
832 {
833 total_done++;
834 BIO_printf(bio_err,"\n");
835 if (!BN_add_word(serial,1)) goto err;
836 if (!sk_X509_push(cert_sk,x))
837 {
838 BIO_printf(bio_err,"Memory allocation failure\n");
839 goto err;
840 }
841 if (outfile)
842 {
843 output_der = 1;
844 batch = 1;
845 }
846 }
847 }
848 if (ss_cert_file != NULL)
849 {
850 total++;
851 j=certify_cert(&x,ss_cert_file,pkey,x509,dgst,attribs,
852 db,serial,startdate,enddate,days,batch,
853 extensions,conf,verbose);
854 if (j < 0) goto err;
855 if (j > 0)
856 {
857 total_done++;
858 BIO_printf(bio_err,"\n");
859 if (!BN_add_word(serial,1)) goto err;
860 if (!sk_X509_push(cert_sk,x))
861 {
862 BIO_printf(bio_err,"Memory allocation failure\n");
863 goto err;
864 }
865 }
866 }
867 if (infile != NULL)
868 {
869 total++;
870 j=certify(&x,infile,pkey,x509,dgst,attribs,db,
871 serial,startdate,enddate,days,batch,
872 extensions,conf,verbose);
873 if (j < 0) goto err;
874 if (j > 0)
875 {
876 total_done++;
877 BIO_printf(bio_err,"\n");
878 if (!BN_add_word(serial,1)) goto err;
879 if (!sk_X509_push(cert_sk,x))
880 {
881 BIO_printf(bio_err,"Memory allocation failure\n");
882 goto err;
883 }
884 }
885 }
886 for (i=0; i<argc; i++)
887 {
888 total++;
889 j=certify(&x,argv[i],pkey,x509,dgst,attribs,db,
890 serial,startdate,enddate,days,batch,
891 extensions,conf,verbose);
892 if (j < 0) goto err;
893 if (j > 0)
894 {
895 total_done++;
896 BIO_printf(bio_err,"\n");
897 if (!BN_add_word(serial,1)) goto err;
898 if (!sk_X509_push(cert_sk,x))
899 {
900 BIO_printf(bio_err,"Memory allocation failure\n");
901 goto err;
902 }
903 }
904 }
905 /* we have a stack of newly certified certificates
906 * and a data base and serial number that need
907 * updating */
908
909 if (sk_X509_num(cert_sk) > 0)
910 {
911 if (!batch)
912 {
913 BIO_printf(bio_err,"\n%d out of %d certificate requests certified, commit? [y/n]",total_done,total);
914 (void)BIO_flush(bio_err);
915 buf[0][0]='\0';
916 fgets(buf[0],10,stdin);
917 if ((buf[0][0] != 'y') && (buf[0][0] != 'Y'))
918 {
919 BIO_printf(bio_err,"CERTIFICATION CANCELED\n");
920 ret=0;
921 goto err;
922 }
923 }
924
925 BIO_printf(bio_err,"Write out database with %d new entries\n",sk_X509_num(cert_sk));
926
927 strncpy(buf[0],serialfile,BSIZE-4);
928
929 #ifdef VMS
930 strcat(buf[0],"-new");
931 #else
932 strcat(buf[0],".new");
933 #endif
934
935 if (!save_serial(buf[0],serial)) goto err;
936
937 strncpy(buf[1],dbfile,BSIZE-4);
938
939 #ifdef VMS
940 strcat(buf[1],"-new");
941 #else
942 strcat(buf[1],".new");
943 #endif
944
945 if (BIO_write_filename(out,buf[1]) <= 0)
946 {
947 perror(dbfile);
948 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
949 goto err;
950 }
951 l=TXT_DB_write(out,db);
952 if (l <= 0) goto err;
953 }
954
955 if (verbose)
956 BIO_printf(bio_err,"writing new certificates\n");
957 for (i=0; i<sk_X509_num(cert_sk); i++)
958 {
959 int k;
960 unsigned char *n;
961
962 x=sk_X509_value(cert_sk,i);
963
964 j=x->cert_info->serialNumber->length;
965 p=(char *)x->cert_info->serialNumber->data;
966
967 strncpy(buf[2],outdir,BSIZE-(j*2)-6);
968
969 #ifndef VMS
970 strcat(buf[2],"/");
971 #endif
972
973 n=(unsigned char *)&(buf[2][strlen(buf[2])]);
974 if (j > 0)
975 {
976 for (k=0; k<j; k++)
977 {
978 sprintf((char *)n,"%02X",(unsigned char)*(p++));
979 n+=2;
980 }
981 }
982 else
983 {
984 *(n++)='0';
985 *(n++)='0';
986 }
987 *(n++)='.'; *(n++)='p'; *(n++)='e'; *(n++)='m';
988 *n='\0';
989 if (verbose)
990 BIO_printf(bio_err,"writing %s\n",buf[2]);
991
992 if (BIO_write_filename(Cout,buf[2]) <= 0)
993 {
994 perror(buf[2]);
995 goto err;
996 }
997 write_new_certificate(Cout,x, 0, notext);
998 write_new_certificate(Sout,x, output_der, notext);
999 }
1000
1001 if (sk_X509_num(cert_sk))
1002 {
1003 /* Rename the database and the serial file */
1004 strncpy(buf[2],serialfile,BSIZE-4);
1005
1006 #ifdef VMS
1007 strcat(buf[2],"-old");
1008 #else
1009 strcat(buf[2],".old");
1010 #endif
1011
1012 BIO_free(in);
1013 BIO_free(out);
1014 in=NULL;
1015 out=NULL;
1016 if (rename(serialfile,buf[2]) < 0)
1017 {
1018 BIO_printf(bio_err,"unable to rename %s to %s\n",
1019 serialfile,buf[2]);
1020 perror("reason");
1021 goto err;
1022 }
1023 if (rename(buf[0],serialfile) < 0)
1024 {
1025 BIO_printf(bio_err,"unable to rename %s to %s\n",
1026 buf[0],serialfile);
1027 perror("reason");
1028 rename(buf[2],serialfile);
1029 goto err;
1030 }
1031
1032 strncpy(buf[2],dbfile,BSIZE-4);
1033
1034 #ifdef VMS
1035 strcat(buf[2],"-old");
1036 #else
1037 strcat(buf[2],".old");
1038 #endif
1039
1040 if (rename(dbfile,buf[2]) < 0)
1041 {
1042 BIO_printf(bio_err,"unable to rename %s to %s\n",
1043 dbfile,buf[2]);
1044 perror("reason");
1045 goto err;
1046 }
1047 if (rename(buf[1],dbfile) < 0)
1048 {
1049 BIO_printf(bio_err,"unable to rename %s to %s\n",
1050 buf[1],dbfile);
1051 perror("reason");
1052 rename(buf[2],dbfile);
1053 goto err;
1054 }
1055 BIO_printf(bio_err,"Data Base Updated\n");
1056 }
1057 }
1058
1059 /*****************************************************************/
1060 if (gencrl)
1061 {
1062 if(!crl_ext) crl_ext=CONF_get_string(conf,section,ENV_CRLEXT);
1063 if(crl_ext) {
1064 /* Check syntax of file */
1065 X509V3_CTX ctx;
1066 X509V3_set_ctx_test(&ctx);
1067 X509V3_set_conf_lhash(&ctx, conf);
1068 if(!X509V3_EXT_add_conf(conf, &ctx, crl_ext, NULL)) {
1069 BIO_printf(bio_err,
1070 "Error Loading CRL extension section %s\n",
1071 crl_ext);
1072 ret = 1;
1073 goto err;
1074 }
1075 }
1076 if ((hex=BIO_new(BIO_s_mem())) == NULL) goto err;
1077
1078 if (!crldays && !crlhours)
1079 {
1080 crldays=CONF_get_number(conf,section,
1081 ENV_DEFAULT_CRL_DAYS);
1082 crlhours=CONF_get_number(conf,section,
1083 ENV_DEFAULT_CRL_HOURS);
1084 }
1085 if ((crldays == 0) && (crlhours == 0))
1086 {
1087 BIO_printf(bio_err,"cannot lookup how long until the next CRL is issuer\n");
1088 goto err;
1089 }
1090
1091 if (verbose) BIO_printf(bio_err,"making CRL\n");
1092 if ((crl=X509_CRL_new()) == NULL) goto err;
1093 ci=crl->crl;
1094 X509_NAME_free(ci->issuer);
1095 ci->issuer=X509_NAME_dup(x509->cert_info->subject);
1096 if (ci->issuer == NULL) goto err;
1097
1098 X509_gmtime_adj(ci->lastUpdate,0);
1099 if (ci->nextUpdate == NULL)
1100 ci->nextUpdate=ASN1_UTCTIME_new();
1101 X509_gmtime_adj(ci->nextUpdate,(crldays*24+crlhours)*60*60);
1102
1103 for (i=0; i<sk_num(db->data); i++)
1104 {
1105 pp=(char **)sk_value(db->data,i);
1106 if (pp[DB_type][0] == DB_TYPE_REV)
1107 {
1108 if ((r=X509_REVOKED_new()) == NULL) goto err;
1109 ASN1_STRING_set((ASN1_STRING *)
1110 r->revocationDate,
1111 (unsigned char *)pp[DB_rev_date],
1112 strlen(pp[DB_rev_date]));
1113 /* strcpy(r->revocationDate,pp[DB_rev_date]);*/
1114
1115 (void)BIO_reset(hex);
1116 if (!BIO_puts(hex,pp[DB_serial]))
1117 goto err;
1118 if (!a2i_ASN1_INTEGER(hex,r->serialNumber,
1119 buf[0],BSIZE)) goto err;
1120
1121 sk_X509_REVOKED_push(ci->revoked,r);
1122 }
1123 }
1124 /* sort the data so it will be written in serial
1125 * number order */
1126 sk_X509_REVOKED_sort(ci->revoked);
1127 for (i=0; i<sk_X509_REVOKED_num(ci->revoked); i++)
1128 {
1129 r=sk_X509_REVOKED_value(ci->revoked,i);
1130 r->sequence=i;
1131 }
1132
1133 /* we now have a CRL */
1134 if (verbose) BIO_printf(bio_err,"signing CRL\n");
1135 if (md != NULL)
1136 {
1137 if ((dgst=EVP_get_digestbyname(md)) == NULL)
1138 {
1139 BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
1140 goto err;
1141 }
1142 }
1143 else
1144 {
1145 #ifndef NO_DSA
1146 if (pkey->type == EVP_PKEY_DSA)
1147 dgst=EVP_dss1();
1148 else
1149 #endif
1150 dgst=EVP_md5();
1151 }
1152
1153 /* Add any extensions asked for */
1154
1155 if(crl_ext) {
1156 X509V3_CTX crlctx;
1157 if (ci->version == NULL)
1158 if ((ci->version=ASN1_INTEGER_new()) == NULL) goto err;
1159 ASN1_INTEGER_set(ci->version,1); /* version 2 CRL */
1160 X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0);
1161 X509V3_set_conf_lhash(&crlctx, conf);
1162
1163 if(!X509V3_EXT_CRL_add_conf(conf, &crlctx,
1164 crl_ext, crl)) goto err;
1165 }
1166
1167 if (!X509_CRL_sign(crl,pkey,dgst)) goto err;
1168
1169 PEM_write_bio_X509_CRL(Sout,crl);
1170 }
1171 /*****************************************************************/
1172 if (dorevoke)
1173 {
1174 if (infile == NULL)
1175 {
1176 BIO_printf(bio_err,"no input files\n");
1177 goto err;
1178 }
1179 else
1180 {
1181 X509 *revcert;
1182 if (BIO_read_filename(in,infile) <= 0)
1183 {
1184 perror(infile);
1185 BIO_printf(bio_err,"error trying to load '%s' certificate\n",infile);
1186 goto err;
1187 }
1188 revcert=PEM_read_bio_X509(in,NULL,NULL,NULL);
1189 if (revcert == NULL)
1190 {
1191 BIO_printf(bio_err,"unable to load '%s' certificate\n",infile);
1192 goto err;
1193 }
1194 j=do_revoke(revcert,db);
1195 if (j <= 0) goto err;
1196 X509_free(revcert);
1197
1198 strncpy(buf[0],dbfile,BSIZE-4);
1199 strcat(buf[0],".new");
1200 if (BIO_write_filename(out,buf[0]) <= 0)
1201 {
1202 perror(dbfile);
1203 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
1204 goto err;
1205 }
1206 j=TXT_DB_write(out,db);
1207 if (j <= 0) goto err;
1208 strncpy(buf[1],dbfile,BSIZE-4);
1209 strcat(buf[1],".old");
1210 if (rename(dbfile,buf[1]) < 0)
1211 {
1212 BIO_printf(bio_err,"unable to rename %s to %s\n", dbfile, buf[1]);
1213 perror("reason");
1214 goto err;
1215 }
1216 if (rename(buf[0],dbfile) < 0)
1217 {
1218 BIO_printf(bio_err,"unable to rename %s to %s\n", buf[0],dbfile);
1219 perror("reason");
1220 rename(buf[1],dbfile);
1221 goto err;
1222 }
1223 BIO_printf(bio_err,"Data Base Updated\n");
1224 }
1225 }
1226 /*****************************************************************/
1227 ret=0;
1228 err:
1229 BIO_free(hex);
1230 BIO_free(Cout);
1231 BIO_free(Sout);
1232 BIO_free(out);
1233 BIO_free(in);
1234
1235 sk_X509_pop_free(cert_sk,X509_free);
1236
1237 if (ret) ERR_print_errors(bio_err);
1238 app_RAND_write_file(randfile, bio_err);
1239 BN_free(serial);
1240 TXT_DB_free(db);
1241 EVP_PKEY_free(pkey);
1242 X509_free(x509);
1243 X509_CRL_free(crl);
1244 CONF_free(conf);
1245 OBJ_cleanup();
1246 EXIT(ret);
1247 }
1248
1249 static void lookup_fail(char *name, char *tag)
1250 {
1251 BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag);
1252 }
1253
1254 static unsigned long index_serial_hash(char **a)
1255 {
1256 char *n;
1257
1258 n=a[DB_serial];
1259 while (*n == '0') n++;
1260 return(lh_strhash(n));
1261 }
1262
1263 static int index_serial_cmp(char **a, char **b)
1264 {
1265 char *aa,*bb;
1266
1267 for (aa=a[DB_serial]; *aa == '0'; aa++);
1268 for (bb=b[DB_serial]; *bb == '0'; bb++);
1269 return(strcmp(aa,bb));
1270 }
1271
1272 static unsigned long index_name_hash(char **a)
1273 { return(lh_strhash(a[DB_name])); }
1274
1275 static int index_name_qual(char **a)
1276 { return(a[0][0] == 'V'); }
1277
1278 static int index_name_cmp(char **a, char **b)
1279 { return(strcmp(a[DB_name],
1280 b[DB_name])); }
1281
1282 static BIGNUM *load_serial(char *serialfile)
1283 {
1284 BIO *in=NULL;
1285 BIGNUM *ret=NULL;
1286 MS_STATIC char buf[1024];
1287 ASN1_INTEGER *ai=NULL;
1288
1289 if ((in=BIO_new(BIO_s_file())) == NULL)
1290 {
1291 ERR_print_errors(bio_err);
1292 goto err;
1293 }
1294
1295 if (BIO_read_filename(in,serialfile) <= 0)
1296 {
1297 perror(serialfile);
1298 goto err;
1299 }
1300 ai=ASN1_INTEGER_new();
1301 if (ai == NULL) goto err;
1302 if (!a2i_ASN1_INTEGER(in,ai,buf,1024))
1303 {
1304 BIO_printf(bio_err,"unable to load number from %s\n",
1305 serialfile);
1306 goto err;
1307 }
1308 ret=ASN1_INTEGER_to_BN(ai,NULL);
1309 if (ret == NULL)
1310 {
1311 BIO_printf(bio_err,"error converting number from bin to BIGNUM");
1312 goto err;
1313 }
1314 err:
1315 if (in != NULL) BIO_free(in);
1316 if (ai != NULL) ASN1_INTEGER_free(ai);
1317 return(ret);
1318 }
1319
1320 static int save_serial(char *serialfile, BIGNUM *serial)
1321 {
1322 BIO *out;
1323 int ret=0;
1324 ASN1_INTEGER *ai=NULL;
1325
1326 out=BIO_new(BIO_s_file());
1327 if (out == NULL)
1328 {
1329 ERR_print_errors(bio_err);
1330 goto err;
1331 }
1332 if (BIO_write_filename(out,serialfile) <= 0)
1333 {
1334 perror(serialfile);
1335 goto err;
1336 }
1337
1338 if ((ai=BN_to_ASN1_INTEGER(serial,NULL)) == NULL)
1339 {
1340 BIO_printf(bio_err,"error converting serial to ASN.1 format\n");
1341 goto err;
1342 }
1343 i2a_ASN1_INTEGER(out,ai);
1344 BIO_puts(out,"\n");
1345 ret=1;
1346 err:
1347 if (out != NULL) BIO_free(out);
1348 if (ai != NULL) ASN1_INTEGER_free(ai);
1349 return(ret);
1350 }
1351
1352 static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1353 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1354 BIGNUM *serial, char *startdate, char *enddate, int days,
1355 int batch, char *ext_sect, LHASH *lconf, int verbose)
1356 {
1357 X509_REQ *req=NULL;
1358 BIO *in=NULL;
1359 EVP_PKEY *pktmp=NULL;
1360 int ok= -1,i;
1361
1362 in=BIO_new(BIO_s_file());
1363
1364 if (BIO_read_filename(in,infile) <= 0)
1365 {
1366 perror(infile);
1367 goto err;
1368 }
1369 if ((req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL)) == NULL)
1370 {
1371 BIO_printf(bio_err,"Error reading certificate request in %s\n",
1372 infile);
1373 goto err;
1374 }
1375 if (verbose)
1376 X509_REQ_print(bio_err,req);
1377
1378 BIO_printf(bio_err,"Check that the request matches the signature\n");
1379
1380 if ((pktmp=X509_REQ_get_pubkey(req)) == NULL)
1381 {
1382 BIO_printf(bio_err,"error unpacking public key\n");
1383 goto err;
1384 }
1385 i=X509_REQ_verify(req,pktmp);
1386 EVP_PKEY_free(pktmp);
1387 if (i < 0)
1388 {
1389 ok=0;
1390 BIO_printf(bio_err,"Signature verification problems....\n");
1391 goto err;
1392 }
1393 if (i == 0)
1394 {
1395 ok=0;
1396 BIO_printf(bio_err,"Signature did not match the certificate request\n");
1397 goto err;
1398 }
1399 else
1400 BIO_printf(bio_err,"Signature ok\n");
1401
1402 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate, enddate,
1403 days,batch,verbose,req,ext_sect,lconf);
1404
1405 err:
1406 if (req != NULL) X509_REQ_free(req);
1407 if (in != NULL) BIO_free(in);
1408 return(ok);
1409 }
1410
1411 static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1412 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1413 BIGNUM *serial, char *startdate, char *enddate, int days,
1414 int batch, char *ext_sect, LHASH *lconf, int verbose)
1415 {
1416 X509 *req=NULL;
1417 X509_REQ *rreq=NULL;
1418 BIO *in=NULL;
1419 EVP_PKEY *pktmp=NULL;
1420 int ok= -1,i;
1421
1422 in=BIO_new(BIO_s_file());
1423
1424 if (BIO_read_filename(in,infile) <= 0)
1425 {
1426 perror(infile);
1427 goto err;
1428 }
1429 if ((req=PEM_read_bio_X509(in,NULL,NULL,NULL)) == NULL)
1430 {
1431 BIO_printf(bio_err,"Error reading self signed certificate in %s\n",infile);
1432 goto err;
1433 }
1434 if (verbose)
1435 X509_print(bio_err,req);
1436
1437 BIO_printf(bio_err,"Check that the request matches the signature\n");
1438
1439 if ((pktmp=X509_get_pubkey(req)) == NULL)
1440 {
1441 BIO_printf(bio_err,"error unpacking public key\n");
1442 goto err;
1443 }
1444 i=X509_verify(req,pktmp);
1445 EVP_PKEY_free(pktmp);
1446 if (i < 0)
1447 {
1448 ok=0;
1449 BIO_printf(bio_err,"Signature verification problems....\n");
1450 goto err;
1451 }
1452 if (i == 0)
1453 {
1454 ok=0;
1455 BIO_printf(bio_err,"Signature did not match the certificate\n");
1456 goto err;
1457 }
1458 else
1459 BIO_printf(bio_err,"Signature ok\n");
1460
1461 if ((rreq=X509_to_X509_REQ(req,NULL,EVP_md5())) == NULL)
1462 goto err;
1463
1464 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate,enddate,days,
1465 batch,verbose,rreq,ext_sect,lconf);
1466
1467 err:
1468 if (rreq != NULL) X509_REQ_free(rreq);
1469 if (req != NULL) X509_free(req);
1470 if (in != NULL) BIO_free(in);
1471 return(ok);
1472 }
1473
1474 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
1475 STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial,
1476 char *startdate, char *enddate, int days, int batch, int verbose,
1477 X509_REQ *req, char *ext_sect, LHASH *lconf)
1478 {
1479 X509_NAME *name=NULL,*CAname=NULL,*subject=NULL;
1480 ASN1_UTCTIME *tm,*tmptm;
1481 ASN1_STRING *str,*str2;
1482 ASN1_OBJECT *obj;
1483 X509 *ret=NULL;
1484 X509_CINF *ci;
1485 X509_NAME_ENTRY *ne;
1486 X509_NAME_ENTRY *tne,*push;
1487 EVP_PKEY *pktmp;
1488 int ok= -1,i,j,last,nid;
1489 char *p;
1490 CONF_VALUE *cv;
1491 char *row[DB_NUMBER],**rrow,**irow=NULL;
1492 char buf[25],*pbuf;
1493
1494 tmptm=ASN1_UTCTIME_new();
1495 if (tmptm == NULL)
1496 {
1497 BIO_printf(bio_err,"malloc error\n");
1498 return(0);
1499 }
1500
1501 for (i=0; i<DB_NUMBER; i++)
1502 row[i]=NULL;
1503
1504 BIO_printf(bio_err,"The Subjects Distinguished Name is as follows\n");
1505 name=X509_REQ_get_subject_name(req);
1506 for (i=0; i<X509_NAME_entry_count(name); i++)
1507 {
1508 ne=(X509_NAME_ENTRY *)X509_NAME_get_entry(name,i);
1509 obj=X509_NAME_ENTRY_get_object(ne);
1510 j=i2a_ASN1_OBJECT(bio_err,obj);
1511 str=X509_NAME_ENTRY_get_data(ne);
1512 pbuf=buf;
1513 for (j=22-j; j>0; j--)
1514 *(pbuf++)=' ';
1515 *(pbuf++)=':';
1516 *(pbuf++)='\0';
1517 BIO_puts(bio_err,buf);
1518
1519 if (msie_hack)
1520 {
1521 /* assume all type should be strings */
1522 nid=OBJ_obj2nid(ne->object);
1523
1524 if (str->type == V_ASN1_UNIVERSALSTRING)
1525 ASN1_UNIVERSALSTRING_to_string(str);
1526
1527 if ((str->type == V_ASN1_IA5STRING) &&
1528 (nid != NID_pkcs9_emailAddress))
1529 str->type=V_ASN1_T61STRING;
1530
1531 if ((nid == NID_pkcs9_emailAddress) &&
1532 (str->type == V_ASN1_PRINTABLESTRING))
1533 str->type=V_ASN1_IA5STRING;
1534 }
1535
1536 if (str->type == V_ASN1_PRINTABLESTRING)
1537 BIO_printf(bio_err,"PRINTABLE:'");
1538 else if (str->type == V_ASN1_T61STRING)
1539 BIO_printf(bio_err,"T61STRING:'");
1540 else if (str->type == V_ASN1_IA5STRING)
1541 BIO_printf(bio_err,"IA5STRING:'");
1542 else if (str->type == V_ASN1_UNIVERSALSTRING)
1543 BIO_printf(bio_err,"UNIVERSALSTRING:'");
1544 else
1545 BIO_printf(bio_err,"ASN.1 %2d:'",str->type);
1546
1547 /* check some things */
1548 if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&
1549 (str->type != V_ASN1_IA5STRING))
1550 {
1551 BIO_printf(bio_err,"\nemailAddress type needs to be of type IA5STRING\n");
1552 goto err;
1553 }
1554 j=ASN1_PRINTABLE_type(str->data,str->length);
1555 if ( ((j == V_ASN1_T61STRING) &&
1556 (str->type != V_ASN1_T61STRING)) ||
1557 ((j == V_ASN1_IA5STRING) &&
1558 (str->type == V_ASN1_PRINTABLESTRING)))
1559 {
1560 BIO_printf(bio_err,"\nThe string contains characters that are illegal for the ASN.1 type\n");
1561 goto err;
1562 }
1563
1564 p=(char *)str->data;
1565 for (j=str->length; j>0; j--)
1566 {
1567 if ((*p >= ' ') && (*p <= '~'))
1568 BIO_printf(bio_err,"%c",*p);
1569 else if (*p & 0x80)
1570 BIO_printf(bio_err,"\\0x%02X",*p);
1571 else if ((unsigned char)*p == 0xf7)
1572 BIO_printf(bio_err,"^?");
1573 else BIO_printf(bio_err,"^%c",*p+'@');
1574 p++;
1575 }
1576 BIO_printf(bio_err,"'\n");
1577 }
1578
1579 /* Ok, now we check the 'policy' stuff. */
1580 if ((subject=X509_NAME_new()) == NULL)
1581 {
1582 BIO_printf(bio_err,"Memory allocation failure\n");
1583 goto err;
1584 }
1585
1586 /* take a copy of the issuer name before we mess with it. */
1587 CAname=X509_NAME_dup(x509->cert_info->subject);
1588 if (CAname == NULL) goto err;
1589 str=str2=NULL;
1590
1591 for (i=0; i<sk_CONF_VALUE_num(policy); i++)
1592 {
1593 cv=sk_CONF_VALUE_value(policy,i); /* get the object id */
1594 if ((j=OBJ_txt2nid(cv->name)) == NID_undef)
1595 {
1596 BIO_printf(bio_err,"%s:unknown object type in 'policy' configuration\n",cv->name);
1597 goto err;
1598 }
1599 obj=OBJ_nid2obj(j);
1600
1601 last= -1;
1602 for (;;)
1603 {
1604 /* lookup the object in the supplied name list */
1605 j=X509_NAME_get_index_by_OBJ(name,obj,last);
1606 if (j < 0)
1607 {
1608 if (last != -1) break;
1609 tne=NULL;
1610 }
1611 else
1612 {
1613 tne=X509_NAME_get_entry(name,j);
1614 }
1615 last=j;
1616
1617 /* depending on the 'policy', decide what to do. */
1618 push=NULL;
1619 if (strcmp(cv->value,"optional") == 0)
1620 {
1621 if (tne != NULL)
1622 push=tne;
1623 }
1624 else if (strcmp(cv->value,"supplied") == 0)
1625 {
1626 if (tne == NULL)
1627 {
1628 BIO_printf(bio_err,"The %s field needed to be supplied and was missing\n",cv->name);
1629 goto err;
1630 }
1631 else
1632 push=tne;
1633 }
1634 else if (strcmp(cv->value,"match") == 0)
1635 {
1636 int last2;
1637
1638 if (tne == NULL)
1639 {
1640 BIO_printf(bio_err,"The mandatory %s field was missing\n",cv->name);
1641 goto err;
1642 }
1643
1644 last2= -1;
1645
1646 again2:
1647 j=X509_NAME_get_index_by_OBJ(CAname,obj,last2);
1648 if ((j < 0) && (last2 == -1))
1649 {
1650 BIO_printf(bio_err,"The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",cv->name);
1651 goto err;
1652 }
1653 if (j >= 0)
1654 {
1655 push=X509_NAME_get_entry(CAname,j);
1656 str=X509_NAME_ENTRY_get_data(tne);
1657 str2=X509_NAME_ENTRY_get_data(push);
1658 last2=j;
1659 if (ASN1_STRING_cmp(str,str2) != 0)
1660 goto again2;
1661 }
1662 if (j < 0)
1663 {
1664 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));
1665 goto err;
1666 }
1667 }
1668 else
1669 {
1670 BIO_printf(bio_err,"%s:invalid type in 'policy' configuration\n",cv->value);
1671 goto err;
1672 }
1673
1674 if (push != NULL)
1675 {
1676 if (!X509_NAME_add_entry(subject,push, -1, 0))
1677 {
1678 if (push != NULL)
1679 X509_NAME_ENTRY_free(push);
1680 BIO_printf(bio_err,"Memory allocation failure\n");
1681 goto err;
1682 }
1683 }
1684 if (j < 0) break;
1685 }
1686 }
1687
1688 if (preserve)
1689 {
1690 X509_NAME_free(subject);
1691 subject=X509_NAME_dup(X509_REQ_get_subject_name(req));
1692 if (subject == NULL) goto err;
1693 }
1694
1695 if (verbose)
1696 BIO_printf(bio_err,"The subject name appears to be ok, checking data base for clashes\n");
1697
1698 row[DB_name]=X509_NAME_oneline(subject,NULL,0);
1699 row[DB_serial]=BN_bn2hex(serial);
1700 if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
1701 {
1702 BIO_printf(bio_err,"Memory allocation failure\n");
1703 goto err;
1704 }
1705
1706 rrow=TXT_DB_get_by_index(db,DB_name,row);
1707 if (rrow != NULL)
1708 {
1709 BIO_printf(bio_err,"ERROR:There is already a certificate for %s\n",
1710 row[DB_name]);
1711 }
1712 else
1713 {
1714 rrow=TXT_DB_get_by_index(db,DB_serial,row);
1715 if (rrow != NULL)
1716 {
1717 BIO_printf(bio_err,"ERROR:Serial number %s has already been issued,\n",
1718 row[DB_serial]);
1719 BIO_printf(bio_err," check the database/serial_file for corruption\n");
1720 }
1721 }
1722
1723 if (rrow != NULL)
1724 {
1725 BIO_printf(bio_err,
1726 "The matching entry has the following details\n");
1727 if (rrow[DB_type][0] == 'E')
1728 p="Expired";
1729 else if (rrow[DB_type][0] == 'R')
1730 p="Revoked";
1731 else if (rrow[DB_type][0] == 'V')
1732 p="Valid";
1733 else
1734 p="\ninvalid type, Data base error\n";
1735 BIO_printf(bio_err,"Type :%s\n",p);;
1736 if (rrow[DB_type][0] == 'R')
1737 {
1738 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1739 BIO_printf(bio_err,"Was revoked on:%s\n",p);
1740 }
1741 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1742 BIO_printf(bio_err,"Expires on :%s\n",p);
1743 p=rrow[DB_serial]; if (p == NULL) p="undef";
1744 BIO_printf(bio_err,"Serial Number :%s\n",p);
1745 p=rrow[DB_file]; if (p == NULL) p="undef";
1746 BIO_printf(bio_err,"File name :%s\n",p);
1747 p=rrow[DB_name]; if (p == NULL) p="undef";
1748 BIO_printf(bio_err,"Subject Name :%s\n",p);
1749 ok= -1; /* This is now a 'bad' error. */
1750 goto err;
1751 }
1752
1753 /* We are now totally happy, lets make and sign the certificate */
1754 if (verbose)
1755 BIO_printf(bio_err,"Everything appears to be ok, creating and signing the certificate\n");
1756
1757 if ((ret=X509_new()) == NULL) goto err;
1758 ci=ret->cert_info;
1759
1760 #ifdef X509_V3
1761 /* Make it an X509 v3 certificate. */
1762 if (!X509_set_version(x509,2)) goto err;
1763 #endif
1764
1765 if (BN_to_ASN1_INTEGER(serial,ci->serialNumber) == NULL)
1766 goto err;
1767 if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))
1768 goto err;
1769
1770 BIO_printf(bio_err,"Certificate is to be certified until ");
1771 if (strcmp(startdate,"today") == 0)
1772 X509_gmtime_adj(X509_get_notBefore(ret),0);
1773 else ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate);
1774
1775 if (enddate == NULL)
1776 X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days);
1777 else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate);
1778
1779 ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ret));
1780 if(days) BIO_printf(bio_err," (%d days)",days);
1781 BIO_printf(bio_err, "\n");
1782
1783 if (!X509_set_subject_name(ret,subject)) goto err;
1784
1785 pktmp=X509_REQ_get_pubkey(req);
1786 i = X509_set_pubkey(ret,pktmp);
1787 EVP_PKEY_free(pktmp);
1788 if (!i) goto err;
1789
1790 /* Lets add the extensions, if there are any */
1791 if (ext_sect)
1792 {
1793 X509V3_CTX ctx;
1794 if (ci->version == NULL)
1795 if ((ci->version=ASN1_INTEGER_new()) == NULL)
1796 goto err;
1797 ASN1_INTEGER_set(ci->version,2); /* version 3 certificate */
1798
1799 /* Free the current entries if any, there should not
1800 * be any I believe */
1801 if (ci->extensions != NULL)
1802 sk_X509_EXTENSION_pop_free(ci->extensions,
1803 X509_EXTENSION_free);
1804
1805 ci->extensions = NULL;
1806
1807 X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
1808 X509V3_set_conf_lhash(&ctx, lconf);
1809
1810 if(!X509V3_EXT_add_conf(lconf, &ctx, ext_sect, ret)) goto err;
1811
1812 }
1813
1814
1815 if (!batch)
1816 {
1817 BIO_printf(bio_err,"Sign the certificate? [y/n]:");
1818 (void)BIO_flush(bio_err);
1819 buf[0]='\0';
1820 fgets(buf,sizeof(buf)-1,stdin);
1821 if (!((buf[0] == 'y') || (buf[0] == 'Y')))
1822 {
1823 BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED\n");
1824 ok=0;
1825 goto err;
1826 }
1827 }
1828
1829
1830 #ifndef NO_DSA
1831 if (pkey->type == EVP_PKEY_DSA) dgst=EVP_dss1();
1832 pktmp=X509_get_pubkey(ret);
1833 if (EVP_PKEY_missing_parameters(pktmp) &&
1834 !EVP_PKEY_missing_parameters(pkey))
1835 EVP_PKEY_copy_parameters(pktmp,pkey);
1836 EVP_PKEY_free(pktmp);
1837 #endif
1838
1839 if (!X509_sign(ret,pkey,dgst))
1840 goto err;
1841
1842 /* We now just add it to the database */
1843 row[DB_type]=(char *)OPENSSL_malloc(2);
1844
1845 tm=X509_get_notAfter(ret);
1846 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
1847 memcpy(row[DB_exp_date],tm->data,tm->length);
1848 row[DB_exp_date][tm->length]='\0';
1849
1850 row[DB_rev_date]=NULL;
1851
1852 /* row[DB_serial] done already */
1853 row[DB_file]=(char *)OPENSSL_malloc(8);
1854 /* row[DB_name] done already */
1855
1856 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
1857 (row[DB_file] == NULL))
1858 {
1859 BIO_printf(bio_err,"Memory allocation failure\n");
1860 goto err;
1861 }
1862 strcpy(row[DB_file],"unknown");
1863 row[DB_type][0]='V';
1864 row[DB_type][1]='\0';
1865
1866 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
1867 {
1868 BIO_printf(bio_err,"Memory allocation failure\n");
1869 goto err;
1870 }
1871
1872 for (i=0; i<DB_NUMBER; i++)
1873 {
1874 irow[i]=row[i];
1875 row[i]=NULL;
1876 }
1877 irow[DB_NUMBER]=NULL;
1878
1879 if (!TXT_DB_insert(db,irow))
1880 {
1881 BIO_printf(bio_err,"failed to update database\n");
1882 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
1883 goto err;
1884 }
1885 ok=1;
1886 err:
1887 for (i=0; i<DB_NUMBER; i++)
1888 if (row[i] != NULL) OPENSSL_free(row[i]);
1889
1890 if (CAname != NULL)
1891 X509_NAME_free(CAname);
1892 if (subject != NULL)
1893 X509_NAME_free(subject);
1894 if (tmptm != NULL)
1895 ASN1_UTCTIME_free(tmptm);
1896 if (ok <= 0)
1897 {
1898 if (ret != NULL) X509_free(ret);
1899 ret=NULL;
1900 }
1901 else
1902 *xret=ret;
1903 return(ok);
1904 }
1905
1906 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext)
1907 {
1908
1909 if (output_der)
1910 {
1911 (void)i2d_X509_bio(bp,x);
1912 return;
1913 }
1914 #if 0
1915 /* ??? Not needed since X509_print prints all this stuff anyway */
1916 f=X509_NAME_oneline(X509_get_issuer_name(x),buf,256);
1917 BIO_printf(bp,"issuer :%s\n",f);
1918
1919 f=X509_NAME_oneline(X509_get_subject_name(x),buf,256);
1920 BIO_printf(bp,"subject:%s\n",f);
1921
1922 BIO_puts(bp,"serial :");
1923 i2a_ASN1_INTEGER(bp,x->cert_info->serialNumber);
1924 BIO_puts(bp,"\n\n");
1925 #endif
1926 if(!notext)X509_print(bp,x);
1927 PEM_write_bio_X509(bp,x);
1928 }
1929
1930 static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1931 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1932 BIGNUM *serial, char *startdate, char *enddate, int days,
1933 char *ext_sect, LHASH *lconf, int verbose)
1934 {
1935 STACK_OF(CONF_VALUE) *sk=NULL;
1936 LHASH *parms=NULL;
1937 X509_REQ *req=NULL;
1938 CONF_VALUE *cv=NULL;
1939 NETSCAPE_SPKI *spki = NULL;
1940 X509_REQ_INFO *ri;
1941 char *type,*buf;
1942 EVP_PKEY *pktmp=NULL;
1943 X509_NAME *n=NULL;
1944 X509_NAME_ENTRY *ne=NULL;
1945 int ok= -1,i,j;
1946 long errline;
1947 int nid;
1948
1949 /*
1950 * Load input file into a hash table. (This is just an easy
1951 * way to read and parse the file, then put it into a convenient
1952 * STACK format).
1953 */
1954 parms=CONF_load(NULL,infile,&errline);
1955 if (parms == NULL)
1956 {
1957 BIO_printf(bio_err,"error on line %ld of %s\n",errline,infile);
1958 ERR_print_errors(bio_err);
1959 goto err;
1960 }
1961
1962 sk=CONF_get_section(parms, "default");
1963 if (sk_CONF_VALUE_num(sk) == 0)
1964 {
1965 BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);
1966 CONF_free(parms);
1967 goto err;
1968 }
1969
1970 /*
1971 * Now create a dummy X509 request structure. We don't actually
1972 * have an X509 request, but we have many of the components
1973 * (a public key, various DN components). The idea is that we
1974 * put these components into the right X509 request structure
1975 * and we can use the same code as if you had a real X509 request.
1976 */
1977 req=X509_REQ_new();
1978 if (req == NULL)
1979 {
1980 ERR_print_errors(bio_err);
1981 goto err;
1982 }
1983
1984 /*
1985 * Build up the subject name set.
1986 */
1987 ri=req->req_info;
1988 n = ri->subject;
1989
1990 for (i = 0; ; i++)
1991 {
1992 if (sk_CONF_VALUE_num(sk) <= i) break;
1993
1994 cv=sk_CONF_VALUE_value(sk,i);
1995 type=cv->name;
1996 /* Skip past any leading X. X: X, etc to allow for
1997 * multiple instances
1998 */
1999 for(buf = cv->name; *buf ; buf++)
2000 if ((*buf == ':') || (*buf == ',') || (*buf == '.')) {
2001 buf++;
2002 if(*buf) type = buf;
2003 break;
2004 }
2005
2006 buf=cv->value;
2007 if ((nid=OBJ_txt2nid(type)) == NID_undef)
2008 {
2009 if (strcmp(type, "SPKAC") == 0)
2010 {
2011 spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
2012 if (spki == NULL)
2013 {
2014 BIO_printf(bio_err,"unable to load Netscape SPKAC structure\n");
2015 ERR_print_errors(bio_err);
2016 goto err;
2017 }
2018 }
2019 continue;
2020 }
2021
2022 j=ASN1_PRINTABLE_type((unsigned char *)buf,-1);
2023 if (fix_data(nid, &j) == 0)
2024 {
2025 BIO_printf(bio_err,
2026 "invalid characters in string %s\n",buf);
2027 goto err;
2028 }
2029
2030 if ((ne=X509_NAME_ENTRY_create_by_NID(&ne,nid,j,
2031 (unsigned char *)buf,
2032 strlen(buf))) == NULL)
2033 goto err;
2034
2035 if (!X509_NAME_add_entry(n,ne,-1, 0)) goto err;
2036 }
2037 if (spki == NULL)
2038 {
2039 BIO_printf(bio_err,"Netscape SPKAC structure not found in %s\n",
2040 infile);
2041 goto err;
2042 }
2043
2044 /*
2045 * Now extract the key from the SPKI structure.
2046 */
2047
2048 BIO_printf(bio_err,"Check that the SPKAC request matches the signature\n");
2049
2050 if ((pktmp=NETSCAPE_SPKI_get_pubkey(spki)) == NULL)
2051 {
2052 BIO_printf(bio_err,"error unpacking SPKAC public key\n");
2053 goto err;
2054 }
2055
2056 j = NETSCAPE_SPKI_verify(spki, pktmp);
2057 if (j <= 0)
2058 {
2059 BIO_printf(bio_err,"signature verification failed on SPKAC public key\n");
2060 goto err;
2061 }
2062 BIO_printf(bio_err,"Signature ok\n");
2063
2064 X509_REQ_set_pubkey(req,pktmp);
2065 EVP_PKEY_free(pktmp);
2066 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate,enddate,
2067 days,1,verbose,req,ext_sect,lconf);
2068 err:
2069 if (req != NULL) X509_REQ_free(req);
2070 if (parms != NULL) CONF_free(parms);
2071 if (spki != NULL) NETSCAPE_SPKI_free(spki);
2072 if (ne != NULL) X509_NAME_ENTRY_free(ne);
2073
2074 return(ok);
2075 }
2076
2077 static int fix_data(int nid, int *type)
2078 {
2079 if (nid == NID_pkcs9_emailAddress)
2080 *type=V_ASN1_IA5STRING;
2081 if ((nid == NID_commonName) && (*type == V_ASN1_IA5STRING))
2082 *type=V_ASN1_T61STRING;
2083 if ((nid == NID_pkcs9_challengePassword) && (*type == V_ASN1_IA5STRING))
2084 *type=V_ASN1_T61STRING;
2085 if ((nid == NID_pkcs9_unstructuredName) && (*type == V_ASN1_T61STRING))
2086 return(0);
2087 if (nid == NID_pkcs9_unstructuredName)
2088 *type=V_ASN1_IA5STRING;
2089 return(1);
2090 }
2091
2092 static int check_time_format(char *str)
2093 {
2094 ASN1_UTCTIME tm;
2095
2096 tm.data=(unsigned char *)str;
2097 tm.length=strlen(str);
2098 tm.type=V_ASN1_UTCTIME;
2099 return(ASN1_UTCTIME_check(&tm));
2100 }
2101
2102 static int do_revoke(X509 *x509, TXT_DB *db)
2103 {
2104 ASN1_UTCTIME *tm=NULL, *revtm=NULL;
2105 char *row[DB_NUMBER],**rrow,**irow;
2106 BIGNUM *bn = NULL;
2107 int ok=-1,i;
2108
2109 for (i=0; i<DB_NUMBER; i++)
2110 row[i]=NULL;
2111 row[DB_name]=X509_NAME_oneline(X509_get_subject_name(x509),NULL,0);
2112 bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509),NULL);
2113 row[DB_serial]=BN_bn2hex(bn);
2114 BN_free(bn);
2115 if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
2116 {
2117 BIO_printf(bio_err,"Memory allocation failure\n");
2118 goto err;
2119 }
2120 /* We have to lookup by serial number because name lookup
2121 * skips revoked certs
2122 */
2123 rrow=TXT_DB_get_by_index(db,DB_serial,row);
2124 if (rrow == NULL)
2125 {
2126 BIO_printf(bio_err,"Adding Entry to DB for %s\n", row[DB_name]);
2127
2128 /* We now just add it to the database */
2129 row[DB_type]=(char *)OPENSSL_malloc(2);
2130
2131 tm=X509_get_notAfter(x509);
2132 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2133 memcpy(row[DB_exp_date],tm->data,tm->length);
2134 row[DB_exp_date][tm->length]='\0';
2135
2136 row[DB_rev_date]=NULL;
2137
2138 /* row[DB_serial] done already */
2139 row[DB_file]=(char *)OPENSSL_malloc(8);
2140
2141 /* row[DB_name] done already */
2142
2143 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2144 (row[DB_file] == NULL))
2145 {
2146 BIO_printf(bio_err,"Memory allocation failure\n");
2147 goto err;
2148 }
2149 strcpy(row[DB_file],"unknown");
2150 row[DB_type][0]='V';
2151 row[DB_type][1]='\0';
2152
2153 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2154 {
2155 BIO_printf(bio_err,"Memory allocation failure\n");
2156 goto err;
2157 }
2158
2159 for (i=0; i<DB_NUMBER; i++)
2160 {
2161 irow[i]=row[i];
2162 row[i]=NULL;
2163 }
2164 irow[DB_NUMBER]=NULL;
2165
2166 if (!TXT_DB_insert(db,irow))
2167 {
2168 BIO_printf(bio_err,"failed to update database\n");
2169 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
2170 goto err;
2171 }
2172
2173 /* Revoke Certificate */
2174 ok = do_revoke(x509,db);
2175
2176 goto err;
2177
2178 }
2179 else if (index_name_cmp(row,rrow))
2180 {
2181 BIO_printf(bio_err,"ERROR:name does not match %s\n",
2182 row[DB_name]);
2183 goto err;
2184 }
2185 else if (rrow[DB_type][0]=='R')
2186 {
2187 BIO_printf(bio_err,"ERROR:Already revoked, serial number %s\n",
2188 row[DB_serial]);
2189 goto err;
2190 }
2191 else
2192 {
2193 BIO_printf(bio_err,"Revoking Certificate %s.\n", rrow[DB_serial]);
2194 revtm = ASN1_UTCTIME_new();
2195 revtm=X509_gmtime_adj(revtm,0);
2196 rrow[DB_type][0]='R';
2197 rrow[DB_type][1]='\0';
2198 rrow[DB_rev_date]=(char *)OPENSSL_malloc(revtm->length+1);
2199 memcpy(rrow[DB_rev_date],revtm->data,revtm->length);
2200 rrow[DB_rev_date][revtm->length]='\0';
2201 ASN1_UTCTIME_free(revtm);
2202 }
2203 ok=1;
2204 err:
2205 for (i=0; i<DB_NUMBER; i++)
2206 {
2207 if (row[i] != NULL)
2208 OPENSSL_free(row[i]);
2209 }
2210 return(ok);
2211 }
2212