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