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