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