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