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