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