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