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