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