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