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_ISDIR 843 if (!S_ISDIR(sb.st_mode)) 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 if (db) 1507 free_index(db); 1508 EVP_PKEY_free(pkey); 1509 X509_free(x509); 1510 X509_CRL_free(crl); 1511 NCONF_free(conf); 1512 OBJ_cleanup(); 1513 apps_shutdown(); 1514 OPENSSL_EXIT(ret); 1515 } 1516 1517 static void lookup_fail(char *name, char *tag) 1518 { 1519 BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag); 1520 } 1521 1522 static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, 1523 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db, 1524 BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate, 1525 long days, int batch, char *ext_sect, CONF *lconf, int verbose, 1526 unsigned long certopt, unsigned long nameopt, int default_op, 1527 int ext_copy) 1528 { 1529 X509_REQ *req=NULL; 1530 BIO *in=NULL; 1531 EVP_PKEY *pktmp=NULL; 1532 int ok= -1,i; 1533 1534 in=BIO_new(BIO_s_file()); 1535 1536 if (BIO_read_filename(in,infile) <= 0) 1537 { 1538 perror(infile); 1539 goto err; 1540 } 1541 if ((req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL)) == NULL) 1542 { 1543 BIO_printf(bio_err,"Error reading certificate request in %s\n", 1544 infile); 1545 goto err; 1546 } 1547 if (verbose) 1548 X509_REQ_print(bio_err,req); 1549 1550 BIO_printf(bio_err,"Check that the request matches the signature\n"); 1551 1552 if ((pktmp=X509_REQ_get_pubkey(req)) == NULL) 1553 { 1554 BIO_printf(bio_err,"error unpacking public key\n"); 1555 goto err; 1556 } 1557 i=X509_REQ_verify(req,pktmp); 1558 EVP_PKEY_free(pktmp); 1559 if (i < 0) 1560 { 1561 ok=0; 1562 BIO_printf(bio_err,"Signature verification problems....\n"); 1563 goto err; 1564 } 1565 if (i == 0) 1566 { 1567 ok=0; 1568 BIO_printf(bio_err,"Signature did not match the certificate request\n"); 1569 goto err; 1570 } 1571 else 1572 BIO_printf(bio_err,"Signature ok\n"); 1573 1574 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj, email_dn, 1575 startdate,enddate,days,batch,verbose,req,ext_sect,lconf, 1576 certopt, nameopt, default_op, ext_copy); 1577 1578 err: 1579 if (req != NULL) X509_REQ_free(req); 1580 if (in != NULL) BIO_free(in); 1581 return(ok); 1582 } 1583 1584 static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, 1585 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db, 1586 BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate, 1587 long days, int batch, char *ext_sect, CONF *lconf, int verbose, 1588 unsigned long certopt, unsigned long nameopt, int default_op, 1589 int ext_copy, ENGINE *e) 1590 { 1591 X509 *req=NULL; 1592 X509_REQ *rreq=NULL; 1593 EVP_PKEY *pktmp=NULL; 1594 int ok= -1,i; 1595 1596 if ((req=load_cert(bio_err, infile, FORMAT_PEM, NULL, e, infile)) == NULL) 1597 goto err; 1598 if (verbose) 1599 X509_print(bio_err,req); 1600 1601 BIO_printf(bio_err,"Check that the request matches the signature\n"); 1602 1603 if ((pktmp=X509_get_pubkey(req)) == NULL) 1604 { 1605 BIO_printf(bio_err,"error unpacking public key\n"); 1606 goto err; 1607 } 1608 i=X509_verify(req,pktmp); 1609 EVP_PKEY_free(pktmp); 1610 if (i < 0) 1611 { 1612 ok=0; 1613 BIO_printf(bio_err,"Signature verification problems....\n"); 1614 goto err; 1615 } 1616 if (i == 0) 1617 { 1618 ok=0; 1619 BIO_printf(bio_err,"Signature did not match the certificate\n"); 1620 goto err; 1621 } 1622 else 1623 BIO_printf(bio_err,"Signature ok\n"); 1624 1625 if ((rreq=X509_to_X509_REQ(req,NULL,EVP_md5())) == NULL) 1626 goto err; 1627 1628 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,email_dn,startdate,enddate, 1629 days,batch,verbose,rreq,ext_sect,lconf, certopt, nameopt, default_op, 1630 ext_copy); 1631 1632 err: 1633 if (rreq != NULL) X509_REQ_free(rreq); 1634 if (req != NULL) X509_free(req); 1635 return(ok); 1636 } 1637 1638 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst, 1639 STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial, char *subj, 1640 int email_dn, char *startdate, char *enddate, long days, int batch, 1641 int verbose, X509_REQ *req, char *ext_sect, CONF *lconf, 1642 unsigned long certopt, unsigned long nameopt, int default_op, 1643 int ext_copy) 1644 { 1645 X509_NAME *name=NULL,*CAname=NULL,*subject=NULL, *dn_subject=NULL; 1646 ASN1_UTCTIME *tm,*tmptm; 1647 ASN1_STRING *str,*str2; 1648 ASN1_OBJECT *obj; 1649 X509 *ret=NULL; 1650 X509_CINF *ci; 1651 X509_NAME_ENTRY *ne; 1652 X509_NAME_ENTRY *tne,*push; 1653 EVP_PKEY *pktmp; 1654 int ok= -1,i,j,last,nid; 1655 char *p; 1656 CONF_VALUE *cv; 1657 char *row[DB_NUMBER],**rrow=NULL,**irow=NULL; 1658 char buf[25]; 1659 1660 tmptm=ASN1_UTCTIME_new(); 1661 if (tmptm == NULL) 1662 { 1663 BIO_printf(bio_err,"malloc error\n"); 1664 return(0); 1665 } 1666 1667 for (i=0; i<DB_NUMBER; i++) 1668 row[i]=NULL; 1669 1670 if (subj) 1671 { 1672 X509_NAME *n = do_subject(subj, MBSTRING_ASC); 1673 1674 if (!n) 1675 { 1676 ERR_print_errors(bio_err); 1677 goto err; 1678 } 1679 X509_REQ_set_subject_name(req,n); 1680 req->req_info->enc.modified = 1; 1681 X509_NAME_free(n); 1682 } 1683 1684 if (default_op) 1685 BIO_printf(bio_err,"The Subject's Distinguished Name is as follows\n"); 1686 1687 name=X509_REQ_get_subject_name(req); 1688 for (i=0; i<X509_NAME_entry_count(name); i++) 1689 { 1690 ne= X509_NAME_get_entry(name,i); 1691 str=X509_NAME_ENTRY_get_data(ne); 1692 obj=X509_NAME_ENTRY_get_object(ne); 1693 1694 if (msie_hack) 1695 { 1696 /* assume all type should be strings */ 1697 nid=OBJ_obj2nid(ne->object); 1698 1699 if (str->type == V_ASN1_UNIVERSALSTRING) 1700 ASN1_UNIVERSALSTRING_to_string(str); 1701 1702 if ((str->type == V_ASN1_IA5STRING) && 1703 (nid != NID_pkcs9_emailAddress)) 1704 str->type=V_ASN1_T61STRING; 1705 1706 if ((nid == NID_pkcs9_emailAddress) && 1707 (str->type == V_ASN1_PRINTABLESTRING)) 1708 str->type=V_ASN1_IA5STRING; 1709 } 1710 1711 /* If no EMAIL is wanted in the subject */ 1712 if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) && (!email_dn)) 1713 continue; 1714 1715 /* check some things */ 1716 if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) && 1717 (str->type != V_ASN1_IA5STRING)) 1718 { 1719 BIO_printf(bio_err,"\nemailAddress type needs to be of type IA5STRING\n"); 1720 goto err; 1721 } 1722 if ((str->type != V_ASN1_BMPSTRING) && (str->type != V_ASN1_UTF8STRING)) 1723 { 1724 j=ASN1_PRINTABLE_type(str->data,str->length); 1725 if ( ((j == V_ASN1_T61STRING) && 1726 (str->type != V_ASN1_T61STRING)) || 1727 ((j == V_ASN1_IA5STRING) && 1728 (str->type == V_ASN1_PRINTABLESTRING))) 1729 { 1730 BIO_printf(bio_err,"\nThe string contains characters that are illegal for the ASN.1 type\n"); 1731 goto err; 1732 } 1733 } 1734 1735 if (default_op) 1736 old_entry_print(bio_err, obj, str); 1737 } 1738 1739 /* Ok, now we check the 'policy' stuff. */ 1740 if ((subject=X509_NAME_new()) == NULL) 1741 { 1742 BIO_printf(bio_err,"Memory allocation failure\n"); 1743 goto err; 1744 } 1745 1746 /* take a copy of the issuer name before we mess with it. */ 1747 CAname=X509_NAME_dup(x509->cert_info->subject); 1748 if (CAname == NULL) goto err; 1749 str=str2=NULL; 1750 1751 for (i=0; i<sk_CONF_VALUE_num(policy); i++) 1752 { 1753 cv=sk_CONF_VALUE_value(policy,i); /* get the object id */ 1754 if ((j=OBJ_txt2nid(cv->name)) == NID_undef) 1755 { 1756 BIO_printf(bio_err,"%s:unknown object type in 'policy' configuration\n",cv->name); 1757 goto err; 1758 } 1759 obj=OBJ_nid2obj(j); 1760 1761 last= -1; 1762 for (;;) 1763 { 1764 /* lookup the object in the supplied name list */ 1765 j=X509_NAME_get_index_by_OBJ(name,obj,last); 1766 if (j < 0) 1767 { 1768 if (last != -1) break; 1769 tne=NULL; 1770 } 1771 else 1772 { 1773 tne=X509_NAME_get_entry(name,j); 1774 } 1775 last=j; 1776 1777 /* depending on the 'policy', decide what to do. */ 1778 push=NULL; 1779 if (strcmp(cv->value,"optional") == 0) 1780 { 1781 if (tne != NULL) 1782 push=tne; 1783 } 1784 else if (strcmp(cv->value,"supplied") == 0) 1785 { 1786 if (tne == NULL) 1787 { 1788 BIO_printf(bio_err,"The %s field needed to be supplied and was missing\n",cv->name); 1789 goto err; 1790 } 1791 else 1792 push=tne; 1793 } 1794 else if (strcmp(cv->value,"match") == 0) 1795 { 1796 int last2; 1797 1798 if (tne == NULL) 1799 { 1800 BIO_printf(bio_err,"The mandatory %s field was missing\n",cv->name); 1801 goto err; 1802 } 1803 1804 last2= -1; 1805 1806 again2: 1807 j=X509_NAME_get_index_by_OBJ(CAname,obj,last2); 1808 if ((j < 0) && (last2 == -1)) 1809 { 1810 BIO_printf(bio_err,"The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",cv->name); 1811 goto err; 1812 } 1813 if (j >= 0) 1814 { 1815 push=X509_NAME_get_entry(CAname,j); 1816 str=X509_NAME_ENTRY_get_data(tne); 1817 str2=X509_NAME_ENTRY_get_data(push); 1818 last2=j; 1819 if (ASN1_STRING_cmp(str,str2) != 0) 1820 goto again2; 1821 } 1822 if (j < 0) 1823 { 1824 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)); 1825 goto err; 1826 } 1827 } 1828 else 1829 { 1830 BIO_printf(bio_err,"%s:invalid type in 'policy' configuration\n",cv->value); 1831 goto err; 1832 } 1833 1834 if (push != NULL) 1835 { 1836 if (!X509_NAME_add_entry(subject,push, -1, 0)) 1837 { 1838 if (push != NULL) 1839 X509_NAME_ENTRY_free(push); 1840 BIO_printf(bio_err,"Memory allocation failure\n"); 1841 goto err; 1842 } 1843 } 1844 if (j < 0) break; 1845 } 1846 } 1847 1848 if (preserve) 1849 { 1850 X509_NAME_free(subject); 1851 /* subject=X509_NAME_dup(X509_REQ_get_subject_name(req)); */ 1852 subject=X509_NAME_dup(name); 1853 if (subject == NULL) goto err; 1854 } 1855 1856 if (verbose) 1857 BIO_printf(bio_err,"The subject name appears to be ok, checking data base for clashes\n"); 1858 1859 /* Build the correct Subject if no e-mail is wanted in the subject */ 1860 /* and add it later on because of the method extensions are added (altName) */ 1861 1862 if (email_dn) 1863 dn_subject = subject; 1864 else 1865 { 1866 X509_NAME_ENTRY *tmpne; 1867 /* Its best to dup the subject DN and then delete any email 1868 * addresses because this retains its structure. 1869 */ 1870 if (!(dn_subject = X509_NAME_dup(subject))) 1871 { 1872 BIO_printf(bio_err,"Memory allocation failure\n"); 1873 goto err; 1874 } 1875 while((i = X509_NAME_get_index_by_NID(dn_subject, 1876 NID_pkcs9_emailAddress, -1)) >= 0) 1877 { 1878 tmpne = X509_NAME_get_entry(dn_subject, i); 1879 X509_NAME_delete_entry(dn_subject, i); 1880 X509_NAME_ENTRY_free(tmpne); 1881 } 1882 } 1883 1884 if (BN_is_zero(serial)) 1885 row[DB_serial]=BUF_strdup("00"); 1886 else 1887 row[DB_serial]=BN_bn2hex(serial); 1888 if (row[DB_serial] == NULL) 1889 { 1890 BIO_printf(bio_err,"Memory allocation failure\n"); 1891 goto err; 1892 } 1893 1894 if (db->attributes.unique_subject) 1895 { 1896 rrow=TXT_DB_get_by_index(db->db,DB_name,row); 1897 if (rrow != NULL) 1898 { 1899 BIO_printf(bio_err, 1900 "ERROR:There is already a certificate for %s\n", 1901 row[DB_name]); 1902 } 1903 } 1904 if (rrow == NULL) 1905 { 1906 rrow=TXT_DB_get_by_index(db->db,DB_serial,row); 1907 if (rrow != NULL) 1908 { 1909 BIO_printf(bio_err,"ERROR:Serial number %s has already been issued,\n", 1910 row[DB_serial]); 1911 BIO_printf(bio_err," check the database/serial_file for corruption\n"); 1912 } 1913 } 1914 1915 if (rrow != NULL) 1916 { 1917 BIO_printf(bio_err, 1918 "The matching entry has the following details\n"); 1919 if (rrow[DB_type][0] == 'E') 1920 p="Expired"; 1921 else if (rrow[DB_type][0] == 'R') 1922 p="Revoked"; 1923 else if (rrow[DB_type][0] == 'V') 1924 p="Valid"; 1925 else 1926 p="\ninvalid type, Data base error\n"; 1927 BIO_printf(bio_err,"Type :%s\n",p);; 1928 if (rrow[DB_type][0] == 'R') 1929 { 1930 p=rrow[DB_exp_date]; if (p == NULL) p="undef"; 1931 BIO_printf(bio_err,"Was revoked on:%s\n",p); 1932 } 1933 p=rrow[DB_exp_date]; if (p == NULL) p="undef"; 1934 BIO_printf(bio_err,"Expires on :%s\n",p); 1935 p=rrow[DB_serial]; if (p == NULL) p="undef"; 1936 BIO_printf(bio_err,"Serial Number :%s\n",p); 1937 p=rrow[DB_file]; if (p == NULL) p="undef"; 1938 BIO_printf(bio_err,"File name :%s\n",p); 1939 p=rrow[DB_name]; if (p == NULL) p="undef"; 1940 BIO_printf(bio_err,"Subject Name :%s\n",p); 1941 ok= -1; /* This is now a 'bad' error. */ 1942 goto err; 1943 } 1944 1945 /* We are now totally happy, lets make and sign the certificate */ 1946 if (verbose) 1947 BIO_printf(bio_err,"Everything appears to be ok, creating and signing the certificate\n"); 1948 1949 if ((ret=X509_new()) == NULL) goto err; 1950 ci=ret->cert_info; 1951 1952 #ifdef X509_V3 1953 /* Make it an X509 v3 certificate. */ 1954 if (!X509_set_version(ret,2)) goto err; 1955 #endif 1956 1957 if (BN_to_ASN1_INTEGER(serial,ci->serialNumber) == NULL) 1958 goto err; 1959 if (!X509_set_issuer_name(ret,X509_get_subject_name(x509))) 1960 goto err; 1961 1962 if (strcmp(startdate,"today") == 0) 1963 X509_gmtime_adj(X509_get_notBefore(ret),0); 1964 else ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate); 1965 1966 if (enddate == NULL) 1967 X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days); 1968 else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate); 1969 1970 if (!X509_set_subject_name(ret,subject)) goto err; 1971 1972 pktmp=X509_REQ_get_pubkey(req); 1973 i = X509_set_pubkey(ret,pktmp); 1974 EVP_PKEY_free(pktmp); 1975 if (!i) goto err; 1976 1977 /* Lets add the extensions, if there are any */ 1978 if (ext_sect) 1979 { 1980 X509V3_CTX ctx; 1981 if (ci->version == NULL) 1982 if ((ci->version=ASN1_INTEGER_new()) == NULL) 1983 goto err; 1984 ASN1_INTEGER_set(ci->version,2); /* version 3 certificate */ 1985 1986 /* Free the current entries if any, there should not 1987 * be any I believe */ 1988 if (ci->extensions != NULL) 1989 sk_X509_EXTENSION_pop_free(ci->extensions, 1990 X509_EXTENSION_free); 1991 1992 ci->extensions = NULL; 1993 1994 /* Initialize the context structure */ 1995 X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0); 1996 1997 if (extconf) 1998 { 1999 if (verbose) 2000 BIO_printf(bio_err, "Extra configuration file found\n"); 2001 2002 /* Use the extconf configuration db LHASH */ 2003 X509V3_set_nconf(&ctx, extconf); 2004 2005 /* Test the structure (needed?) */ 2006 /* X509V3_set_ctx_test(&ctx); */ 2007 2008 /* Adds exts contained in the configuration file */ 2009 if (!X509V3_EXT_add_nconf(extconf, &ctx, ext_sect,ret)) 2010 { 2011 BIO_printf(bio_err, 2012 "ERROR: adding extensions in section %s\n", 2013 ext_sect); 2014 ERR_print_errors(bio_err); 2015 goto err; 2016 } 2017 if (verbose) 2018 BIO_printf(bio_err, "Successfully added extensions from file.\n"); 2019 } 2020 else if (ext_sect) 2021 { 2022 /* We found extensions to be set from config file */ 2023 X509V3_set_nconf(&ctx, lconf); 2024 2025 if(!X509V3_EXT_add_nconf(lconf, &ctx, ext_sect, ret)) 2026 { 2027 BIO_printf(bio_err, "ERROR: adding extensions in section %s\n", ext_sect); 2028 ERR_print_errors(bio_err); 2029 goto err; 2030 } 2031 2032 if (verbose) 2033 BIO_printf(bio_err, "Successfully added extensions from config\n"); 2034 } 2035 } 2036 2037 /* Copy extensions from request (if any) */ 2038 2039 if (!copy_extensions(ret, req, ext_copy)) 2040 { 2041 BIO_printf(bio_err, "ERROR: adding extensions from request\n"); 2042 ERR_print_errors(bio_err); 2043 goto err; 2044 } 2045 2046 /* Set the right value for the noemailDN option */ 2047 if( email_dn == 0 ) 2048 { 2049 if (!X509_set_subject_name(ret,dn_subject)) goto err; 2050 } 2051 2052 if (!default_op) 2053 { 2054 BIO_printf(bio_err, "Certificate Details:\n"); 2055 /* Never print signature details because signature not present */ 2056 certopt |= X509_FLAG_NO_SIGDUMP | X509_FLAG_NO_SIGNAME; 2057 X509_print_ex(bio_err, ret, nameopt, certopt); 2058 } 2059 2060 BIO_printf(bio_err,"Certificate is to be certified until "); 2061 ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ret)); 2062 if (days) BIO_printf(bio_err," (%d days)",days); 2063 BIO_printf(bio_err, "\n"); 2064 2065 if (!batch) 2066 { 2067 2068 BIO_printf(bio_err,"Sign the certificate? [y/n]:"); 2069 (void)BIO_flush(bio_err); 2070 buf[0]='\0'; 2071 fgets(buf,sizeof(buf)-1,stdin); 2072 if (!((buf[0] == 'y') || (buf[0] == 'Y'))) 2073 { 2074 BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED\n"); 2075 ok=0; 2076 goto err; 2077 } 2078 } 2079 2080 2081 #ifndef OPENSSL_NO_DSA 2082 if (pkey->type == EVP_PKEY_DSA) dgst=EVP_dss1(); 2083 pktmp=X509_get_pubkey(ret); 2084 if (EVP_PKEY_missing_parameters(pktmp) && 2085 !EVP_PKEY_missing_parameters(pkey)) 2086 EVP_PKEY_copy_parameters(pktmp,pkey); 2087 EVP_PKEY_free(pktmp); 2088 #endif 2089 2090 if (!X509_sign(ret,pkey,dgst)) 2091 goto err; 2092 2093 /* We now just add it to the database */ 2094 row[DB_type]=(char *)OPENSSL_malloc(2); 2095 2096 tm=X509_get_notAfter(ret); 2097 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1); 2098 memcpy(row[DB_exp_date],tm->data,tm->length); 2099 row[DB_exp_date][tm->length]='\0'; 2100 2101 row[DB_rev_date]=NULL; 2102 2103 /* row[DB_serial] done already */ 2104 row[DB_file]=(char *)OPENSSL_malloc(8); 2105 row[DB_name]=X509_NAME_oneline(X509_get_subject_name(ret),NULL,0); 2106 2107 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) || 2108 (row[DB_file] == NULL) || (row[DB_name] == NULL)) 2109 { 2110 BIO_printf(bio_err,"Memory allocation failure\n"); 2111 goto err; 2112 } 2113 BUF_strlcpy(row[DB_file],"unknown",8); 2114 row[DB_type][0]='V'; 2115 row[DB_type][1]='\0'; 2116 2117 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL) 2118 { 2119 BIO_printf(bio_err,"Memory allocation failure\n"); 2120 goto err; 2121 } 2122 2123 for (i=0; i<DB_NUMBER; i++) 2124 { 2125 irow[i]=row[i]; 2126 row[i]=NULL; 2127 } 2128 irow[DB_NUMBER]=NULL; 2129 2130 if (!TXT_DB_insert(db->db,irow)) 2131 { 2132 BIO_printf(bio_err,"failed to update database\n"); 2133 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->db->error); 2134 goto err; 2135 } 2136 ok=1; 2137 err: 2138 for (i=0; i<DB_NUMBER; i++) 2139 if (row[i] != NULL) OPENSSL_free(row[i]); 2140 2141 if (CAname != NULL) 2142 X509_NAME_free(CAname); 2143 if (subject != NULL) 2144 X509_NAME_free(subject); 2145 if ((dn_subject != NULL) && !email_dn) 2146 X509_NAME_free(dn_subject); 2147 if (tmptm != NULL) 2148 ASN1_UTCTIME_free(tmptm); 2149 if (ok <= 0) 2150 { 2151 if (ret != NULL) X509_free(ret); 2152 ret=NULL; 2153 } 2154 else 2155 *xret=ret; 2156 return(ok); 2157 } 2158 2159 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext) 2160 { 2161 2162 if (output_der) 2163 { 2164 (void)i2d_X509_bio(bp,x); 2165 return; 2166 } 2167 #if 0 2168 /* ??? Not needed since X509_print prints all this stuff anyway */ 2169 f=X509_NAME_oneline(X509_get_issuer_name(x),buf,256); 2170 BIO_printf(bp,"issuer :%s\n",f); 2171 2172 f=X509_NAME_oneline(X509_get_subject_name(x),buf,256); 2173 BIO_printf(bp,"subject:%s\n",f); 2174 2175 BIO_puts(bp,"serial :"); 2176 i2a_ASN1_INTEGER(bp,x->cert_info->serialNumber); 2177 BIO_puts(bp,"\n\n"); 2178 #endif 2179 if (!notext)X509_print(bp,x); 2180 PEM_write_bio_X509(bp,x); 2181 } 2182 2183 static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, 2184 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db, 2185 BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate, 2186 long days, char *ext_sect, CONF *lconf, int verbose, unsigned long certopt, 2187 unsigned long nameopt, int default_op, int ext_copy) 2188 { 2189 STACK_OF(CONF_VALUE) *sk=NULL; 2190 LHASH *parms=NULL; 2191 X509_REQ *req=NULL; 2192 CONF_VALUE *cv=NULL; 2193 NETSCAPE_SPKI *spki = NULL; 2194 X509_REQ_INFO *ri; 2195 char *type,*buf; 2196 EVP_PKEY *pktmp=NULL; 2197 X509_NAME *n=NULL; 2198 X509_NAME_ENTRY *ne=NULL; 2199 int ok= -1,i,j; 2200 long errline; 2201 int nid; 2202 2203 /* 2204 * Load input file into a hash table. (This is just an easy 2205 * way to read and parse the file, then put it into a convenient 2206 * STACK format). 2207 */ 2208 parms=CONF_load(NULL,infile,&errline); 2209 if (parms == NULL) 2210 { 2211 BIO_printf(bio_err,"error on line %ld of %s\n",errline,infile); 2212 ERR_print_errors(bio_err); 2213 goto err; 2214 } 2215 2216 sk=CONF_get_section(parms, "default"); 2217 if (sk_CONF_VALUE_num(sk) == 0) 2218 { 2219 BIO_printf(bio_err, "no name/value pairs found in %s\n", infile); 2220 CONF_free(parms); 2221 goto err; 2222 } 2223 2224 /* 2225 * Now create a dummy X509 request structure. We don't actually 2226 * have an X509 request, but we have many of the components 2227 * (a public key, various DN components). The idea is that we 2228 * put these components into the right X509 request structure 2229 * and we can use the same code as if you had a real X509 request. 2230 */ 2231 req=X509_REQ_new(); 2232 if (req == NULL) 2233 { 2234 ERR_print_errors(bio_err); 2235 goto err; 2236 } 2237 2238 /* 2239 * Build up the subject name set. 2240 */ 2241 ri=req->req_info; 2242 n = ri->subject; 2243 2244 for (i = 0; ; i++) 2245 { 2246 if (sk_CONF_VALUE_num(sk) <= i) break; 2247 2248 cv=sk_CONF_VALUE_value(sk,i); 2249 type=cv->name; 2250 /* Skip past any leading X. X: X, etc to allow for 2251 * multiple instances 2252 */ 2253 for (buf = cv->name; *buf ; buf++) 2254 if ((*buf == ':') || (*buf == ',') || (*buf == '.')) 2255 { 2256 buf++; 2257 if (*buf) type = buf; 2258 break; 2259 } 2260 2261 buf=cv->value; 2262 if ((nid=OBJ_txt2nid(type)) == NID_undef) 2263 { 2264 if (strcmp(type, "SPKAC") == 0) 2265 { 2266 spki = NETSCAPE_SPKI_b64_decode(cv->value, -1); 2267 if (spki == NULL) 2268 { 2269 BIO_printf(bio_err,"unable to load Netscape SPKAC structure\n"); 2270 ERR_print_errors(bio_err); 2271 goto err; 2272 } 2273 } 2274 continue; 2275 } 2276 2277 /* 2278 if ((nid == NID_pkcs9_emailAddress) && (email_dn == 0)) 2279 continue; 2280 */ 2281 2282 j=ASN1_PRINTABLE_type((unsigned char *)buf,-1); 2283 if (fix_data(nid, &j) == 0) 2284 { 2285 BIO_printf(bio_err, 2286 "invalid characters in string %s\n",buf); 2287 goto err; 2288 } 2289 2290 if ((ne=X509_NAME_ENTRY_create_by_NID(&ne,nid,j, 2291 (unsigned char *)buf, 2292 strlen(buf))) == NULL) 2293 goto err; 2294 2295 if (!X509_NAME_add_entry(n,ne,-1, 0)) goto err; 2296 } 2297 if (spki == NULL) 2298 { 2299 BIO_printf(bio_err,"Netscape SPKAC structure not found in %s\n", 2300 infile); 2301 goto err; 2302 } 2303 2304 /* 2305 * Now extract the key from the SPKI structure. 2306 */ 2307 2308 BIO_printf(bio_err,"Check that the SPKAC request matches the signature\n"); 2309 2310 if ((pktmp=NETSCAPE_SPKI_get_pubkey(spki)) == NULL) 2311 { 2312 BIO_printf(bio_err,"error unpacking SPKAC public key\n"); 2313 goto err; 2314 } 2315 2316 j = NETSCAPE_SPKI_verify(spki, pktmp); 2317 if (j <= 0) 2318 { 2319 BIO_printf(bio_err,"signature verification failed on SPKAC public key\n"); 2320 goto err; 2321 } 2322 BIO_printf(bio_err,"Signature ok\n"); 2323 2324 X509_REQ_set_pubkey(req,pktmp); 2325 EVP_PKEY_free(pktmp); 2326 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,email_dn,startdate,enddate, 2327 days,1,verbose,req,ext_sect,lconf, certopt, nameopt, default_op, 2328 ext_copy); 2329 err: 2330 if (req != NULL) X509_REQ_free(req); 2331 if (parms != NULL) CONF_free(parms); 2332 if (spki != NULL) NETSCAPE_SPKI_free(spki); 2333 if (ne != NULL) X509_NAME_ENTRY_free(ne); 2334 2335 return(ok); 2336 } 2337 2338 static int fix_data(int nid, int *type) 2339 { 2340 if (nid == NID_pkcs9_emailAddress) 2341 *type=V_ASN1_IA5STRING; 2342 if ((nid == NID_commonName) && (*type == V_ASN1_IA5STRING)) 2343 *type=V_ASN1_T61STRING; 2344 if ((nid == NID_pkcs9_challengePassword) && (*type == V_ASN1_IA5STRING)) 2345 *type=V_ASN1_T61STRING; 2346 if ((nid == NID_pkcs9_unstructuredName) && (*type == V_ASN1_T61STRING)) 2347 return(0); 2348 if (nid == NID_pkcs9_unstructuredName) 2349 *type=V_ASN1_IA5STRING; 2350 return(1); 2351 } 2352 2353 static int check_time_format(char *str) 2354 { 2355 ASN1_UTCTIME tm; 2356 2357 tm.data=(unsigned char *)str; 2358 tm.length=strlen(str); 2359 tm.type=V_ASN1_UTCTIME; 2360 return(ASN1_UTCTIME_check(&tm)); 2361 } 2362 2363 static int do_revoke(X509 *x509, CA_DB *db, int type, char *value) 2364 { 2365 ASN1_UTCTIME *tm=NULL; 2366 char *row[DB_NUMBER],**rrow,**irow; 2367 char *rev_str = NULL; 2368 BIGNUM *bn = NULL; 2369 int ok=-1,i; 2370 2371 for (i=0; i<DB_NUMBER; i++) 2372 row[i]=NULL; 2373 row[DB_name]=X509_NAME_oneline(X509_get_subject_name(x509),NULL,0); 2374 bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509),NULL); 2375 if (BN_is_zero(bn)) 2376 row[DB_serial]=BUF_strdup("00"); 2377 else 2378 row[DB_serial]=BN_bn2hex(bn); 2379 BN_free(bn); 2380 if ((row[DB_name] == NULL) || (row[DB_serial] == NULL)) 2381 { 2382 BIO_printf(bio_err,"Memory allocation failure\n"); 2383 goto err; 2384 } 2385 /* We have to lookup by serial number because name lookup 2386 * skips revoked certs 2387 */ 2388 rrow=TXT_DB_get_by_index(db->db,DB_serial,row); 2389 if (rrow == NULL) 2390 { 2391 BIO_printf(bio_err,"Adding Entry with serial number %s to DB for %s\n", row[DB_serial], row[DB_name]); 2392 2393 /* We now just add it to the database */ 2394 row[DB_type]=(char *)OPENSSL_malloc(2); 2395 2396 tm=X509_get_notAfter(x509); 2397 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1); 2398 memcpy(row[DB_exp_date],tm->data,tm->length); 2399 row[DB_exp_date][tm->length]='\0'; 2400 2401 row[DB_rev_date]=NULL; 2402 2403 /* row[DB_serial] done already */ 2404 row[DB_file]=(char *)OPENSSL_malloc(8); 2405 2406 /* row[DB_name] done already */ 2407 2408 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) || 2409 (row[DB_file] == NULL)) 2410 { 2411 BIO_printf(bio_err,"Memory allocation failure\n"); 2412 goto err; 2413 } 2414 BUF_strlcpy(row[DB_file],"unknown",8); 2415 row[DB_type][0]='V'; 2416 row[DB_type][1]='\0'; 2417 2418 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL) 2419 { 2420 BIO_printf(bio_err,"Memory allocation failure\n"); 2421 goto err; 2422 } 2423 2424 for (i=0; i<DB_NUMBER; i++) 2425 { 2426 irow[i]=row[i]; 2427 row[i]=NULL; 2428 } 2429 irow[DB_NUMBER]=NULL; 2430 2431 if (!TXT_DB_insert(db->db,irow)) 2432 { 2433 BIO_printf(bio_err,"failed to update database\n"); 2434 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->db->error); 2435 goto err; 2436 } 2437 2438 /* Revoke Certificate */ 2439 ok = do_revoke(x509,db, type, value); 2440 2441 goto err; 2442 2443 } 2444 else if (index_name_cmp((const char **)row,(const char **)rrow)) 2445 { 2446 BIO_printf(bio_err,"ERROR:name does not match %s\n", 2447 row[DB_name]); 2448 goto err; 2449 } 2450 else if (rrow[DB_type][0]=='R') 2451 { 2452 BIO_printf(bio_err,"ERROR:Already revoked, serial number %s\n", 2453 row[DB_serial]); 2454 goto err; 2455 } 2456 else 2457 { 2458 BIO_printf(bio_err,"Revoking Certificate %s.\n", rrow[DB_serial]); 2459 rev_str = make_revocation_str(type, value); 2460 if (!rev_str) 2461 { 2462 BIO_printf(bio_err, "Error in revocation arguments\n"); 2463 goto err; 2464 } 2465 rrow[DB_type][0]='R'; 2466 rrow[DB_type][1]='\0'; 2467 rrow[DB_rev_date] = rev_str; 2468 } 2469 ok=1; 2470 err: 2471 for (i=0; i<DB_NUMBER; i++) 2472 { 2473 if (row[i] != NULL) 2474 OPENSSL_free(row[i]); 2475 } 2476 return(ok); 2477 } 2478 2479 static int get_certificate_status(const char *serial, CA_DB *db) 2480 { 2481 char *row[DB_NUMBER],**rrow; 2482 int ok=-1,i; 2483 2484 /* Free Resources */ 2485 for (i=0; i<DB_NUMBER; i++) 2486 row[i]=NULL; 2487 2488 /* Malloc needed char spaces */ 2489 row[DB_serial] = OPENSSL_malloc(strlen(serial) + 2); 2490 if (row[DB_serial] == NULL) 2491 { 2492 BIO_printf(bio_err,"Malloc failure\n"); 2493 goto err; 2494 } 2495 2496 if (strlen(serial) % 2) 2497 { 2498 /* Set the first char to 0 */; 2499 row[DB_serial][0]='0'; 2500 2501 /* Copy String from serial to row[DB_serial] */ 2502 memcpy(row[DB_serial]+1, serial, strlen(serial)); 2503 row[DB_serial][strlen(serial)+1]='\0'; 2504 } 2505 else 2506 { 2507 /* Copy String from serial to row[DB_serial] */ 2508 memcpy(row[DB_serial], serial, strlen(serial)); 2509 row[DB_serial][strlen(serial)]='\0'; 2510 } 2511 2512 /* Make it Upper Case */ 2513 for (i=0; row[DB_serial][i] != '\0'; i++) 2514 row[DB_serial][i] = toupper(row[DB_serial][i]); 2515 2516 2517 ok=1; 2518 2519 /* Search for the certificate */ 2520 rrow=TXT_DB_get_by_index(db->db,DB_serial,row); 2521 if (rrow == NULL) 2522 { 2523 BIO_printf(bio_err,"Serial %s not present in db.\n", 2524 row[DB_serial]); 2525 ok=-1; 2526 goto err; 2527 } 2528 else if (rrow[DB_type][0]=='V') 2529 { 2530 BIO_printf(bio_err,"%s=Valid (%c)\n", 2531 row[DB_serial], rrow[DB_type][0]); 2532 goto err; 2533 } 2534 else if (rrow[DB_type][0]=='R') 2535 { 2536 BIO_printf(bio_err,"%s=Revoked (%c)\n", 2537 row[DB_serial], rrow[DB_type][0]); 2538 goto err; 2539 } 2540 else if (rrow[DB_type][0]=='E') 2541 { 2542 BIO_printf(bio_err,"%s=Expired (%c)\n", 2543 row[DB_serial], rrow[DB_type][0]); 2544 goto err; 2545 } 2546 else if (rrow[DB_type][0]=='S') 2547 { 2548 BIO_printf(bio_err,"%s=Suspended (%c)\n", 2549 row[DB_serial], rrow[DB_type][0]); 2550 goto err; 2551 } 2552 else 2553 { 2554 BIO_printf(bio_err,"%s=Unknown (%c).\n", 2555 row[DB_serial], rrow[DB_type][0]); 2556 ok=-1; 2557 } 2558 err: 2559 for (i=0; i<DB_NUMBER; i++) 2560 { 2561 if (row[i] != NULL) 2562 OPENSSL_free(row[i]); 2563 } 2564 return(ok); 2565 } 2566 2567 static int do_updatedb (CA_DB *db) 2568 { 2569 ASN1_UTCTIME *a_tm = NULL; 2570 int i, cnt = 0; 2571 int db_y2k, a_y2k; /* flags = 1 if y >= 2000 */ 2572 char **rrow, *a_tm_s; 2573 2574 a_tm = ASN1_UTCTIME_new(); 2575 2576 /* get actual time and make a string */ 2577 a_tm = X509_gmtime_adj(a_tm, 0); 2578 a_tm_s = (char *) OPENSSL_malloc(a_tm->length+1); 2579 if (a_tm_s == NULL) 2580 { 2581 cnt = -1; 2582 goto err; 2583 } 2584 2585 memcpy(a_tm_s, a_tm->data, a_tm->length); 2586 a_tm_s[a_tm->length] = '\0'; 2587 2588 if (strncmp(a_tm_s, "49", 2) <= 0) 2589 a_y2k = 1; 2590 else 2591 a_y2k = 0; 2592 2593 for (i = 0; i < sk_num(db->db->data); i++) 2594 { 2595 rrow = (char **) sk_value(db->db->data, i); 2596 2597 if (rrow[DB_type][0] == 'V') 2598 { 2599 /* ignore entries that are not valid */ 2600 if (strncmp(rrow[DB_exp_date], "49", 2) <= 0) 2601 db_y2k = 1; 2602 else 2603 db_y2k = 0; 2604 2605 if (db_y2k == a_y2k) 2606 { 2607 /* all on the same y2k side */ 2608 if (strcmp(rrow[DB_exp_date], a_tm_s) <= 0) 2609 { 2610 rrow[DB_type][0] = 'E'; 2611 rrow[DB_type][1] = '\0'; 2612 cnt++; 2613 2614 BIO_printf(bio_err, "%s=Expired\n", 2615 rrow[DB_serial]); 2616 } 2617 } 2618 else if (db_y2k < a_y2k) 2619 { 2620 rrow[DB_type][0] = 'E'; 2621 rrow[DB_type][1] = '\0'; 2622 cnt++; 2623 2624 BIO_printf(bio_err, "%s=Expired\n", 2625 rrow[DB_serial]); 2626 } 2627 2628 } 2629 } 2630 2631 err: 2632 2633 ASN1_UTCTIME_free(a_tm); 2634 OPENSSL_free(a_tm_s); 2635 2636 return (cnt); 2637 } 2638 2639 static char *crl_reasons[] = { 2640 /* CRL reason strings */ 2641 "unspecified", 2642 "keyCompromise", 2643 "CACompromise", 2644 "affiliationChanged", 2645 "superseded", 2646 "cessationOfOperation", 2647 "certificateHold", 2648 "removeFromCRL", 2649 /* Additional pseudo reasons */ 2650 "holdInstruction", 2651 "keyTime", 2652 "CAkeyTime" 2653 }; 2654 2655 #define NUM_REASONS (sizeof(crl_reasons) / sizeof(char *)) 2656 2657 /* Given revocation information convert to a DB string. 2658 * The format of the string is: 2659 * revtime[,reason,extra]. Where 'revtime' is the 2660 * revocation time (the current time). 'reason' is the 2661 * optional CRL reason and 'extra' is any additional 2662 * argument 2663 */ 2664 2665 char *make_revocation_str(int rev_type, char *rev_arg) 2666 { 2667 char *reason = NULL, *other = NULL, *str; 2668 ASN1_OBJECT *otmp; 2669 ASN1_UTCTIME *revtm = NULL; 2670 int i; 2671 switch (rev_type) 2672 { 2673 case REV_NONE: 2674 break; 2675 2676 case REV_CRL_REASON: 2677 for (i = 0; i < 8; i++) 2678 { 2679 if (!strcasecmp(rev_arg, crl_reasons[i])) 2680 { 2681 reason = crl_reasons[i]; 2682 break; 2683 } 2684 } 2685 if (reason == NULL) 2686 { 2687 BIO_printf(bio_err, "Unknown CRL reason %s\n", rev_arg); 2688 return NULL; 2689 } 2690 break; 2691 2692 case REV_HOLD: 2693 /* Argument is an OID */ 2694 2695 otmp = OBJ_txt2obj(rev_arg, 0); 2696 ASN1_OBJECT_free(otmp); 2697 2698 if (otmp == NULL) 2699 { 2700 BIO_printf(bio_err, "Invalid object identifier %s\n", rev_arg); 2701 return NULL; 2702 } 2703 2704 reason = "holdInstruction"; 2705 other = rev_arg; 2706 break; 2707 2708 case REV_KEY_COMPROMISE: 2709 case REV_CA_COMPROMISE: 2710 2711 /* Argument is the key compromise time */ 2712 if (!ASN1_GENERALIZEDTIME_set_string(NULL, rev_arg)) 2713 { 2714 BIO_printf(bio_err, "Invalid time format %s. Need YYYYMMDDHHMMSSZ\n", rev_arg); 2715 return NULL; 2716 } 2717 other = rev_arg; 2718 if (rev_type == REV_KEY_COMPROMISE) 2719 reason = "keyTime"; 2720 else 2721 reason = "CAkeyTime"; 2722 2723 break; 2724 2725 } 2726 2727 revtm = X509_gmtime_adj(NULL, 0); 2728 2729 i = revtm->length + 1; 2730 2731 if (reason) i += strlen(reason) + 1; 2732 if (other) i += strlen(other) + 1; 2733 2734 str = OPENSSL_malloc(i); 2735 2736 if (!str) return NULL; 2737 2738 BUF_strlcpy(str, (char *)revtm->data, i); 2739 if (reason) 2740 { 2741 BUF_strlcat(str, ",", i); 2742 BUF_strlcat(str, reason, i); 2743 } 2744 if (other) 2745 { 2746 BUF_strlcat(str, ",", i); 2747 BUF_strlcat(str, other, i); 2748 } 2749 ASN1_UTCTIME_free(revtm); 2750 return str; 2751 } 2752 2753 /* Convert revocation field to X509_REVOKED entry 2754 * return code: 2755 * 0 error 2756 * 1 OK 2757 * 2 OK and some extensions added (i.e. V2 CRL) 2758 */ 2759 2760 2761 int make_revoked(X509_REVOKED *rev, char *str) 2762 { 2763 char *tmp = NULL; 2764 int reason_code = -1; 2765 int i, ret = 0; 2766 ASN1_OBJECT *hold = NULL; 2767 ASN1_GENERALIZEDTIME *comp_time = NULL; 2768 ASN1_ENUMERATED *rtmp = NULL; 2769 2770 ASN1_TIME *revDate = NULL; 2771 2772 i = unpack_revinfo(&revDate, &reason_code, &hold, &comp_time, str); 2773 2774 if (i == 0) 2775 goto err; 2776 2777 if (rev && !X509_REVOKED_set_revocationDate(rev, revDate)) 2778 goto err; 2779 2780 if (rev && (reason_code != OCSP_REVOKED_STATUS_NOSTATUS)) 2781 { 2782 rtmp = ASN1_ENUMERATED_new(); 2783 if (!rtmp || !ASN1_ENUMERATED_set(rtmp, reason_code)) 2784 goto err; 2785 if (!X509_REVOKED_add1_ext_i2d(rev, NID_crl_reason, rtmp, 0, 0)) 2786 goto err; 2787 } 2788 2789 if (rev && comp_time) 2790 { 2791 if (!X509_REVOKED_add1_ext_i2d(rev, NID_invalidity_date, comp_time, 0, 0)) 2792 goto err; 2793 } 2794 if (rev && hold) 2795 { 2796 if (!X509_REVOKED_add1_ext_i2d(rev, NID_hold_instruction_code, hold, 0, 0)) 2797 goto err; 2798 } 2799 2800 if (reason_code != OCSP_REVOKED_STATUS_NOSTATUS) 2801 ret = 2; 2802 else ret = 1; 2803 2804 err: 2805 2806 if (tmp) OPENSSL_free(tmp); 2807 ASN1_OBJECT_free(hold); 2808 ASN1_GENERALIZEDTIME_free(comp_time); 2809 ASN1_ENUMERATED_free(rtmp); 2810 ASN1_TIME_free(revDate); 2811 2812 return ret; 2813 } 2814 2815 /* 2816 * subject is expected to be in the format /type0=value0/type1=value1/type2=... 2817 * where characters may be escaped by \ 2818 */ 2819 X509_NAME *do_subject(char *subject, long chtype) 2820 { 2821 size_t buflen = strlen(subject)+1; /* to copy the types and values into. due to escaping, the copy can only become shorter */ 2822 char *buf = OPENSSL_malloc(buflen); 2823 size_t max_ne = buflen / 2 + 1; /* maximum number of name elements */ 2824 char **ne_types = OPENSSL_malloc(max_ne * sizeof (char *)); 2825 char **ne_values = OPENSSL_malloc(max_ne * sizeof (char *)); 2826 2827 char *sp = subject, *bp = buf; 2828 int i, ne_num = 0; 2829 2830 X509_NAME *n = NULL; 2831 int nid; 2832 2833 if (!buf || !ne_types || !ne_values) 2834 { 2835 BIO_printf(bio_err, "malloc error\n"); 2836 goto error; 2837 } 2838 2839 if (*subject != '/') 2840 { 2841 BIO_printf(bio_err, "Subject does not start with '/'.\n"); 2842 goto error; 2843 } 2844 sp++; /* skip leading / */ 2845 2846 while (*sp) 2847 { 2848 /* collect type */ 2849 ne_types[ne_num] = bp; 2850 while (*sp) 2851 { 2852 if (*sp == '\\') /* is there anything to escape in the type...? */ 2853 { 2854 if (*++sp) 2855 *bp++ = *sp++; 2856 else 2857 { 2858 BIO_printf(bio_err, "escape character at end of string\n"); 2859 goto error; 2860 } 2861 } 2862 else if (*sp == '=') 2863 { 2864 sp++; 2865 *bp++ = '\0'; 2866 break; 2867 } 2868 else 2869 *bp++ = *sp++; 2870 } 2871 if (!*sp) 2872 { 2873 BIO_printf(bio_err, "end of string encountered while processing type of subject name element #%d\n", ne_num); 2874 goto error; 2875 } 2876 ne_values[ne_num] = bp; 2877 while (*sp) 2878 { 2879 if (*sp == '\\') 2880 { 2881 if (*++sp) 2882 *bp++ = *sp++; 2883 else 2884 { 2885 BIO_printf(bio_err, "escape character at end of string\n"); 2886 goto error; 2887 } 2888 } 2889 else if (*sp == '/') 2890 { 2891 sp++; 2892 break; 2893 } 2894 else 2895 *bp++ = *sp++; 2896 } 2897 *bp++ = '\0'; 2898 ne_num++; 2899 } 2900 2901 if (!(n = X509_NAME_new())) 2902 goto error; 2903 2904 for (i = 0; i < ne_num; i++) 2905 { 2906 if ((nid=OBJ_txt2nid(ne_types[i])) == NID_undef) 2907 { 2908 BIO_printf(bio_err, "Subject Attribute %s has no known NID, skipped\n", ne_types[i]); 2909 continue; 2910 } 2911 2912 if (!*ne_values[i]) 2913 { 2914 BIO_printf(bio_err, "No value provided for Subject Attribute %s, skipped\n", ne_types[i]); 2915 continue; 2916 } 2917 2918 if (!X509_NAME_add_entry_by_NID(n, nid, chtype, (unsigned char*)ne_values[i], -1,-1,0)) 2919 goto error; 2920 } 2921 2922 OPENSSL_free(ne_values); 2923 OPENSSL_free(ne_types); 2924 OPENSSL_free(buf); 2925 return n; 2926 2927 error: 2928 X509_NAME_free(n); 2929 if (ne_values) 2930 OPENSSL_free(ne_values); 2931 if (ne_types) 2932 OPENSSL_free(ne_types); 2933 if (buf) 2934 OPENSSL_free(buf); 2935 return NULL; 2936 } 2937 2938 int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str) 2939 { 2940 char buf[25],*pbuf, *p; 2941 int j; 2942 j=i2a_ASN1_OBJECT(bp,obj); 2943 pbuf=buf; 2944 for (j=22-j; j>0; j--) 2945 *(pbuf++)=' '; 2946 *(pbuf++)=':'; 2947 *(pbuf++)='\0'; 2948 BIO_puts(bp,buf); 2949 2950 if (str->type == V_ASN1_PRINTABLESTRING) 2951 BIO_printf(bp,"PRINTABLE:'"); 2952 else if (str->type == V_ASN1_T61STRING) 2953 BIO_printf(bp,"T61STRING:'"); 2954 else if (str->type == V_ASN1_IA5STRING) 2955 BIO_printf(bp,"IA5STRING:'"); 2956 else if (str->type == V_ASN1_UNIVERSALSTRING) 2957 BIO_printf(bp,"UNIVERSALSTRING:'"); 2958 else 2959 BIO_printf(bp,"ASN.1 %2d:'",str->type); 2960 2961 p=(char *)str->data; 2962 for (j=str->length; j>0; j--) 2963 { 2964 if ((*p >= ' ') && (*p <= '~')) 2965 BIO_printf(bp,"%c",*p); 2966 else if (*p & 0x80) 2967 BIO_printf(bp,"\\0x%02X",*p); 2968 else if ((unsigned char)*p == 0xf7) 2969 BIO_printf(bp,"^?"); 2970 else BIO_printf(bp,"^%c",*p+'@'); 2971 p++; 2972 } 2973 BIO_printf(bp,"'\n"); 2974 return 1; 2975 } 2976 2977 int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold, ASN1_GENERALIZEDTIME **pinvtm, char *str) 2978 { 2979 char *tmp = NULL; 2980 char *rtime_str, *reason_str = NULL, *arg_str = NULL, *p; 2981 int reason_code = -1; 2982 int i, ret = 0; 2983 ASN1_OBJECT *hold = NULL; 2984 ASN1_GENERALIZEDTIME *comp_time = NULL; 2985 tmp = BUF_strdup(str); 2986 2987 p = strchr(tmp, ','); 2988 2989 rtime_str = tmp; 2990 2991 if (p) 2992 { 2993 *p = '\0'; 2994 p++; 2995 reason_str = p; 2996 p = strchr(p, ','); 2997 if (p) 2998 { 2999 *p = '\0'; 3000 arg_str = p + 1; 3001 } 3002 } 3003 3004 if (prevtm) 3005 { 3006 *prevtm = ASN1_UTCTIME_new(); 3007 if (!ASN1_UTCTIME_set_string(*prevtm, rtime_str)) 3008 { 3009 BIO_printf(bio_err, "invalid revocation date %s\n", rtime_str); 3010 goto err; 3011 } 3012 } 3013 if (reason_str) 3014 { 3015 for (i = 0; i < NUM_REASONS; i++) 3016 { 3017 if(!strcasecmp(reason_str, crl_reasons[i])) 3018 { 3019 reason_code = i; 3020 break; 3021 } 3022 } 3023 if (reason_code == OCSP_REVOKED_STATUS_NOSTATUS) 3024 { 3025 BIO_printf(bio_err, "invalid reason code %s\n", reason_str); 3026 goto err; 3027 } 3028 3029 if (reason_code == 7) 3030 reason_code = OCSP_REVOKED_STATUS_REMOVEFROMCRL; 3031 else if (reason_code == 8) /* Hold instruction */ 3032 { 3033 if (!arg_str) 3034 { 3035 BIO_printf(bio_err, "missing hold instruction\n"); 3036 goto err; 3037 } 3038 reason_code = OCSP_REVOKED_STATUS_CERTIFICATEHOLD; 3039 hold = OBJ_txt2obj(arg_str, 0); 3040 3041 if (!hold) 3042 { 3043 BIO_printf(bio_err, "invalid object identifier %s\n", arg_str); 3044 goto err; 3045 } 3046 if (phold) *phold = hold; 3047 } 3048 else if ((reason_code == 9) || (reason_code == 10)) 3049 { 3050 if (!arg_str) 3051 { 3052 BIO_printf(bio_err, "missing compromised time\n"); 3053 goto err; 3054 } 3055 comp_time = ASN1_GENERALIZEDTIME_new(); 3056 if (!ASN1_GENERALIZEDTIME_set_string(comp_time, arg_str)) 3057 { 3058 BIO_printf(bio_err, "invalid compromised time %s\n", arg_str); 3059 goto err; 3060 } 3061 if (reason_code == 9) 3062 reason_code = OCSP_REVOKED_STATUS_KEYCOMPROMISE; 3063 else 3064 reason_code = OCSP_REVOKED_STATUS_CACOMPROMISE; 3065 } 3066 } 3067 3068 if (preason) *preason = reason_code; 3069 if (pinvtm) *pinvtm = comp_time; 3070 else ASN1_GENERALIZEDTIME_free(comp_time); 3071 3072 ret = 1; 3073 3074 err: 3075 3076 if (tmp) OPENSSL_free(tmp); 3077 if (!phold) ASN1_OBJECT_free(hold); 3078 if (!pinvtm) ASN1_GENERALIZEDTIME_free(comp_time); 3079 3080 return ret; 3081 } 3082