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