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