1 /* $OpenBSD: req.c,v 1.19 2020/08/09 16:38:24 jsing Exp $ */ 2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3 * All rights reserved. 4 * 5 * This package is an SSL implementation written 6 * by Eric Young (eay@cryptsoft.com). 7 * The implementation was written so as to conform with Netscapes SSL. 8 * 9 * This library is free for commercial and non-commercial use as long as 10 * the following conditions are aheared to. The following conditions 11 * apply to all code found in this distribution, be it the RC4, RSA, 12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13 * included with this distribution is covered by the same copyright terms 14 * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15 * 16 * Copyright remains Eric Young's, and as such any Copyright notices in 17 * the code are not to be removed. 18 * If this package is used in a product, Eric Young should be given attribution 19 * as the author of the parts of the library used. 20 * This can be in the form of a textual message at program startup or 21 * in documentation (online or textual) provided with the package. 22 * 23 * Redistribution and use in source and binary forms, with or without 24 * modification, are permitted provided that the following conditions 25 * are met: 26 * 1. Redistributions of source code must retain the copyright 27 * notice, this list of conditions and the following disclaimer. 28 * 2. Redistributions in binary form must reproduce the above copyright 29 * notice, this list of conditions and the following disclaimer in the 30 * documentation and/or other materials provided with the distribution. 31 * 3. All advertising materials mentioning features or use of this software 32 * must display the following acknowledgement: 33 * "This product includes cryptographic software written by 34 * Eric Young (eay@cryptsoft.com)" 35 * The word 'cryptographic' can be left out if the rouines from the library 36 * being used are not cryptographic related :-). 37 * 4. If you include any Windows specific code (or a derivative thereof) from 38 * the apps directory (application code) you must include an acknowledgement: 39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40 * 41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51 * SUCH DAMAGE. 52 * 53 * The licence and distribution terms for any publically available version or 54 * derivative of this code cannot be changed. i.e. this code cannot simply be 55 * copied and put under another distribution licence 56 * [including the GNU Public Licence.] 57 */ 58 59 /* Until the key-gen callbacks are modified to use newer prototypes, we allow 60 * deprecated functions for openssl-internal code */ 61 #ifdef OPENSSL_NO_DEPRECATED 62 #undef OPENSSL_NO_DEPRECATED 63 #endif 64 65 #include <ctype.h> 66 #include <limits.h> 67 #include <stdio.h> 68 #include <stdlib.h> 69 #include <string.h> 70 #include <time.h> 71 72 #include "apps.h" 73 74 #include <openssl/asn1.h> 75 #include <openssl/bio.h> 76 #include <openssl/bn.h> 77 #include <openssl/conf.h> 78 #include <openssl/err.h> 79 #include <openssl/evp.h> 80 #include <openssl/objects.h> 81 #include <openssl/pem.h> 82 #include <openssl/x509.h> 83 #include <openssl/x509v3.h> 84 85 #include <openssl/dsa.h> 86 87 #include <openssl/rsa.h> 88 89 #define SECTION "req" 90 91 #define BITS "default_bits" 92 #define KEYFILE "default_keyfile" 93 #define PROMPT "prompt" 94 #define DISTINGUISHED_NAME "distinguished_name" 95 #define ATTRIBUTES "attributes" 96 #define V3_EXTENSIONS "x509_extensions" 97 #define REQ_EXTENSIONS "req_extensions" 98 #define STRING_MASK "string_mask" 99 #define UTF8_IN "utf8" 100 101 #define DEFAULT_KEY_LENGTH 2048 102 #define MIN_KEY_LENGTH 384 103 104 static int make_REQ(X509_REQ * req, EVP_PKEY * pkey, char *dn, int multirdn, 105 int attribs, unsigned long chtype); 106 static int build_subject(X509_REQ * req, char *subj, unsigned long chtype, 107 int multirdn); 108 static int prompt_info(X509_REQ * req, 109 STACK_OF(CONF_VALUE) * dn_sk, char *dn_sect, 110 STACK_OF(CONF_VALUE) * attr_sk, char *attr_sect, int attribs, 111 unsigned long chtype); 112 static int auto_info(X509_REQ * req, STACK_OF(CONF_VALUE) * sk, 113 STACK_OF(CONF_VALUE) * attr, int attribs, 114 unsigned long chtype); 115 static int add_attribute_object(X509_REQ * req, char *text, const char *def, 116 char *value, int nid, int n_min, 117 int n_max, unsigned long chtype); 118 static int add_DN_object(X509_NAME * n, char *text, const char *def, char *value, 119 int nid, int n_min, int n_max, unsigned long chtype, int mval); 120 static int genpkey_cb(EVP_PKEY_CTX * ctx); 121 static int req_check_len(int len, int n_min, int n_max); 122 static int check_end(const char *str, const char *end); 123 static EVP_PKEY_CTX *set_keygen_ctx(BIO * err, const char *gstr, int *pkey_type, 124 long *pkeylen, char **palgnam); 125 static unsigned long ext_name_hash(const OPENSSL_STRING *a); 126 static int ext_name_cmp(const OPENSSL_STRING *a, const OPENSSL_STRING *b); 127 static void exts_cleanup(OPENSSL_STRING *x); 128 static int duplicated(LHASH_OF(OPENSSL_STRING) *addexts, char *kv); 129 static CONF *req_conf = NULL; 130 static CONF *addext_conf = NULL; 131 132 struct { 133 LHASH_OF(OPENSSL_STRING) *addexts; 134 BIO *addext_bio; 135 int batch; 136 unsigned long chtype; 137 int days; 138 const EVP_MD *digest; 139 char *extensions; 140 char *infile; 141 int informat; 142 char *keyalg; 143 char *keyfile; 144 int keyform; 145 char *keyout; 146 int kludge; 147 int modulus; 148 int multirdn; 149 int newhdr; 150 long newkey; 151 int newreq; 152 unsigned long nmflag; 153 int nodes; 154 int noout; 155 char *outfile; 156 int outformat; 157 char *passargin; 158 char *passargout; 159 STACK_OF(OPENSSL_STRING) *pkeyopts; 160 int pubkey; 161 char *req_exts; 162 unsigned long reqflag; 163 ASN1_INTEGER *serial; 164 STACK_OF(OPENSSL_STRING) *sigopts; 165 char *subj; 166 int subject; 167 char *template; 168 int text; 169 int verbose; 170 int verify; 171 int x509; 172 } req_config; 173 174 static int 175 req_opt_addext(char *arg) 176 { 177 int i; 178 179 if (req_config.addexts == NULL) { 180 req_config.addexts = (LHASH_OF(OPENSSL_STRING) *)lh_new( 181 (LHASH_HASH_FN_TYPE)ext_name_hash, 182 (LHASH_COMP_FN_TYPE)ext_name_cmp); 183 req_config.addext_bio = BIO_new(BIO_s_mem()); 184 if (req_config.addexts == NULL || 185 req_config.addext_bio == NULL) 186 return (1); 187 } 188 i = duplicated(req_config.addexts, arg); 189 if (i == 1) 190 return (1); 191 if (i < 0 || BIO_printf(req_config.addext_bio, "%s\n", arg) < 0) 192 return (1); 193 194 return (0); 195 } 196 197 static int 198 req_opt_days(char *arg) 199 { 200 const char *errstr; 201 202 req_config.days = strtonum(arg, 1, INT_MAX, &errstr); 203 if (errstr != NULL) { 204 BIO_printf(bio_err, "bad -days %s, using 0: %s\n", 205 arg, errstr); 206 req_config.days = 30; 207 } 208 return (0); 209 } 210 211 static int 212 req_opt_digest(int argc, char **argv, int *argsused) 213 { 214 char *name = argv[0]; 215 216 if (*name++ != '-') 217 return (1); 218 219 if ((req_config.digest = EVP_get_digestbyname(name)) == NULL) 220 return (1); 221 222 *argsused = 1; 223 return (0); 224 } 225 226 static int 227 req_opt_newkey(char *arg) 228 { 229 req_config.keyalg = arg; 230 req_config.newreq = 1; 231 return (0); 232 } 233 234 static int 235 req_opt_nameopt(char *arg) 236 { 237 if (!set_name_ex(&req_config.nmflag, arg)) 238 return (1); 239 return (0); 240 } 241 242 static int 243 req_opt_pkeyopt(char *arg) 244 { 245 if (req_config.pkeyopts == NULL) 246 req_config.pkeyopts = sk_OPENSSL_STRING_new_null(); 247 if (req_config.pkeyopts == NULL) 248 return (1); 249 if (!sk_OPENSSL_STRING_push(req_config.pkeyopts, arg)) 250 return (1); 251 return (0); 252 } 253 254 static int 255 req_opt_reqopt(char *arg) 256 { 257 if (!set_cert_ex(&req_config.reqflag, arg)) 258 return (1); 259 return (0); 260 } 261 262 static int 263 req_opt_set_serial(char *arg) 264 { 265 req_config.serial = s2i_ASN1_INTEGER(NULL, arg); 266 if (req_config.serial == NULL) 267 return (1); 268 return (0); 269 } 270 271 static int 272 req_opt_sigopt(char *arg) 273 { 274 if (req_config.sigopts == NULL) 275 req_config.sigopts = sk_OPENSSL_STRING_new_null(); 276 if (req_config.sigopts == NULL) 277 return (1); 278 if (!sk_OPENSSL_STRING_push(req_config.sigopts, arg)) 279 return (1); 280 return (0); 281 } 282 283 static int 284 req_opt_utf8(void) 285 { 286 req_config.chtype = MBSTRING_UTF8; 287 return (0); 288 } 289 290 static const struct option req_options[] = { 291 { 292 .name = "addext", 293 .argname = "key=value", 294 .desc = "Additional certificate extension (may be repeated)", 295 .type = OPTION_ARG_FUNC, 296 .opt.argfunc = req_opt_addext, 297 }, 298 { 299 .name = "asn1-kludge", 300 .type = OPTION_VALUE, 301 .opt.value = &req_config.kludge, 302 .value = 1, 303 }, 304 { 305 .name = "batch", 306 .desc = "Operate in batch mode", 307 .type = OPTION_FLAG, 308 .opt.flag = &req_config.batch, 309 }, 310 { 311 .name = "config", 312 .argname = "file", 313 .desc = "Configuration file to use as request template", 314 .type = OPTION_ARG, 315 .opt.arg = &req_config.template, 316 }, 317 { 318 .name = "days", 319 .argname = "number", 320 .desc = "Number of days generated certificate is valid for", 321 .type = OPTION_ARG_FUNC, 322 .opt.argfunc = req_opt_days, 323 }, 324 { 325 .name = "extensions", 326 .argname = "section", 327 .desc = "Config section to use for certificate extensions", 328 .type = OPTION_ARG, 329 .opt.arg = &req_config.extensions, 330 }, 331 { 332 .name = "in", 333 .argname = "file", 334 .desc = "Input file (default stdin)", 335 .type = OPTION_ARG, 336 .opt.arg = &req_config.infile, 337 }, 338 { 339 .name = "inform", 340 .argname = "format", 341 .desc = "Input format (DER or PEM (default))", 342 .type = OPTION_ARG_FORMAT, 343 .opt.value = &req_config.informat, 344 }, 345 { 346 .name = "key", 347 .argname = "file", 348 .desc = "Private key file", 349 .type = OPTION_ARG, 350 .opt.arg = &req_config.keyfile, 351 }, 352 { 353 .name = "keyform", 354 .argname = "format", 355 .desc = "Private key format (DER or PEM (default))", 356 .type = OPTION_ARG_FORMAT, 357 .opt.value = &req_config.keyform, 358 }, 359 { 360 .name = "keyout", 361 .argname = "file", 362 .desc = "Private key output file", 363 .type = OPTION_ARG, 364 .opt.arg = &req_config.keyout, 365 }, 366 { 367 .name = "modulus", 368 .desc = "Print RSA modulus", 369 .type = OPTION_FLAG, 370 .opt.flag = &req_config.modulus, 371 }, 372 { 373 .name = "multivalue-rdn", 374 .desc = "Enable support for multivalued RDNs", 375 .type = OPTION_FLAG, 376 .opt.flag = &req_config.multirdn, 377 }, 378 { 379 .name = "nameopt", 380 .argname = "arg", 381 .desc = "Certificate name options", 382 .type = OPTION_ARG_FUNC, 383 .opt.argfunc = req_opt_nameopt, 384 }, 385 { 386 .name = "new", 387 .desc = "New request", 388 .type = OPTION_FLAG, 389 .opt.flag = &req_config.newreq, 390 }, 391 { 392 .name = "newhdr", 393 .desc = "Include 'NEW' in header lines", 394 .type = OPTION_FLAG, 395 .opt.flag = &req_config.newhdr, 396 }, 397 { 398 .name = "newkey", 399 .argname = "param", 400 .desc = "Generate a new key using given parameters", 401 .type = OPTION_ARG_FUNC, 402 .opt.argfunc = req_opt_newkey, 403 }, 404 { 405 .name = "no-asn1-kludge", 406 .type = OPTION_VALUE, 407 .opt.value = &req_config.kludge, 408 .value = 0, 409 }, 410 { 411 .name = "nodes", 412 .desc = "Do not encrypt output private key", 413 .type = OPTION_FLAG, 414 .opt.flag = &req_config.nodes, 415 }, 416 { 417 .name = "noout", 418 .desc = "Do not output request", 419 .type = OPTION_FLAG, 420 .opt.flag = &req_config.noout, 421 }, 422 { 423 .name = "out", 424 .argname = "file", 425 .desc = "Output file (default stdout)", 426 .type = OPTION_ARG, 427 .opt.arg = &req_config.outfile, 428 }, 429 { 430 .name = "outform", 431 .argname = "format", 432 .desc = "Output format (DER or PEM (default))", 433 .type = OPTION_ARG_FORMAT, 434 .opt.value = &req_config.outformat, 435 }, 436 { 437 .name = "passin", 438 .argname = "source", 439 .desc = "Private key input password source", 440 .type = OPTION_ARG, 441 .opt.arg = &req_config.passargin, 442 }, 443 { 444 .name = "passout", 445 .argname = "source", 446 .desc = "Private key output password source", 447 .type = OPTION_ARG, 448 .opt.arg = &req_config.passargout, 449 }, 450 { 451 .name = "pkeyopt", 452 .argname = "opt:val", 453 .desc = "Set the public key algorithm option opt to val", 454 .type = OPTION_ARG_FUNC, 455 .opt.argfunc = req_opt_pkeyopt, 456 }, 457 { 458 .name = "pubkey", 459 .desc = "Output the public key", 460 .type = OPTION_FLAG, 461 .opt.flag = &req_config.pubkey, 462 }, 463 { 464 .name = "reqexts", 465 .argname = "section", 466 .desc = "Config section to use for request extensions", 467 .type = OPTION_ARG, 468 .opt.arg = &req_config.req_exts, 469 }, 470 { 471 .name = "reqopt", 472 .argname = "option", 473 .desc = "Request text options", 474 .type = OPTION_ARG_FUNC, 475 .opt.argfunc = req_opt_reqopt, 476 }, 477 { 478 .name = "set_serial", 479 .argname = "serial", 480 .desc = "Serial number to use for generated certificate", 481 .type = OPTION_ARG_FUNC, 482 .opt.argfunc = req_opt_set_serial, 483 }, 484 { 485 .name = "sigopt", 486 .argname = "name:val", 487 .desc = "Signature options", 488 .type = OPTION_ARG_FUNC, 489 .opt.argfunc = req_opt_sigopt, 490 }, 491 { 492 .name = "subj", 493 .argname = "name", 494 .desc = "Set or modify the request subject", 495 .type = OPTION_ARG, 496 .opt.arg = &req_config.subj, 497 }, 498 { 499 .name = "subject", 500 .desc = "Output the subject of the request", 501 .type = OPTION_FLAG, 502 .opt.flag = &req_config.subject, 503 }, 504 { 505 .name = "text", 506 .desc = "Print request in text form", 507 .type = OPTION_FLAG, 508 .opt.flag = &req_config.text, 509 }, 510 { 511 .name = "utf8", 512 .desc = "Input characters are in UTF-8 (default ASCII)", 513 .type = OPTION_FUNC, 514 .opt.func = req_opt_utf8, 515 }, 516 { 517 .name = "verbose", 518 .desc = "Verbose", 519 .type = OPTION_FLAG, 520 .opt.flag = &req_config.verbose, 521 }, 522 { 523 .name = "verify", 524 .desc = "Verify signature on request", 525 .type = OPTION_FLAG, 526 .opt.flag = &req_config.verify, 527 }, 528 { 529 .name = "x509", 530 .desc = "Output an X.509 structure instead of a certificate request", 531 .type = OPTION_FLAG, 532 .opt.flag = &req_config.x509, 533 }, 534 { 535 .name = NULL, 536 .desc = "", 537 .type = OPTION_ARGV_FUNC, 538 .opt.argvfunc = req_opt_digest, 539 }, 540 { NULL }, 541 }; 542 543 static void 544 req_usage(void) 545 { 546 fprintf(stderr, 547 "usage: req [-addext ext] [-asn1-kludge] [-batch] [-config file]\n" 548 " [-days n] [-extensions section] [-in file]\n" 549 " [-inform der | pem] [-key keyfile] [-keyform der | pem]\n" 550 " [-keyout file] [-md4 | -md5 | -sha1] [-modulus]\n" 551 " [-multivalue-rdn] [-nameopt option] [-new] [-newhdr]\n" 552 " [-newkey arg] [-no-asn1-kludge] [-nodes] [-noout]\n" 553 " [-out file] [-outform der | pem] [-passin arg]\n" 554 " [-passout arg] [-pkeyopt opt:value] [-pubkey]\n" 555 " [-reqexts section] [-reqopt option] [-set_serial n]\n" 556 " [-sigopt nm:v] [-subj arg] [-subject] [-text] [-utf8]\n" 557 " [-verbose] [-verify] [-x509]\n\n"); 558 559 options_usage(req_options); 560 fprintf(stderr, "\n"); 561 } 562 563 int 564 req_main(int argc, char **argv) 565 { 566 int ex = 1; 567 X509 *x509ss = NULL; 568 X509_REQ *req = NULL; 569 EVP_PKEY_CTX *genctx = NULL; 570 char *keyalgstr = NULL; 571 const EVP_CIPHER *cipher = NULL; 572 EVP_PKEY *pkey = NULL; 573 int i = 0, pkey_type = -1; 574 BIO *in = NULL, *out = NULL; 575 char *passin = NULL, *passout = NULL; 576 const EVP_MD *md_alg = NULL; 577 char *p; 578 579 if (single_execution) { 580 if (pledge("stdio cpath wpath rpath tty", NULL) == -1) { 581 perror("pledge"); 582 exit(1); 583 } 584 } 585 586 memset(&req_config, 0, sizeof(req_config)); 587 588 req_config.chtype = MBSTRING_ASC; 589 req_config.days = 30; 590 req_config.digest = EVP_sha256(); 591 req_config.newkey = -1; 592 req_config.informat = FORMAT_PEM; 593 req_config.keyform = FORMAT_PEM; 594 req_config.outformat = FORMAT_PEM; 595 596 if (options_parse(argc, argv, req_options, NULL, NULL) != 0) { 597 req_usage(); 598 return (1); 599 } 600 601 req_conf = NULL; 602 cipher = EVP_aes_256_cbc(); 603 604 if (!app_passwd(bio_err, req_config.passargin, req_config.passargout, &passin, &passout)) { 605 BIO_printf(bio_err, "Error getting passwords\n"); 606 goto end; 607 } 608 if (req_config.template != NULL) { 609 long errline = -1; 610 611 if (req_config.verbose) 612 BIO_printf(bio_err, "Using configuration from %s\n", req_config.template); 613 if ((req_conf = NCONF_new(NULL)) == NULL) 614 goto end; 615 if(!NCONF_load(req_conf, req_config.template, &errline)) { 616 BIO_printf(bio_err, "error on line %ld of %s\n", errline, req_config.template); 617 goto end; 618 } 619 } else { 620 req_conf = config; 621 622 if (req_conf == NULL) { 623 BIO_printf(bio_err, "Unable to load config info from %s\n", default_config_file); 624 if (req_config.newreq) 625 goto end; 626 } else if (req_config.verbose) 627 BIO_printf(bio_err, "Using configuration from %s\n", 628 default_config_file); 629 } 630 631 if (req_config.addext_bio != NULL) { 632 long errline = -1; 633 if (req_config.verbose) 634 BIO_printf(bio_err, 635 "Using additional configuration from command line\n"); 636 if ((addext_conf = NCONF_new(NULL)) == NULL) 637 goto end; 638 if (!NCONF_load_bio(addext_conf, req_config.addext_bio, &errline)) { 639 BIO_printf(bio_err, 640 "req: Error on line %ld of config input\n", 641 errline); 642 goto end; 643 } 644 } 645 646 if (req_conf != NULL) { 647 if (!load_config(bio_err, req_conf)) 648 goto end; 649 p = NCONF_get_string(req_conf, NULL, "oid_file"); 650 if (p == NULL) 651 ERR_clear_error(); 652 if (p != NULL) { 653 BIO *oid_bio; 654 655 oid_bio = BIO_new_file(p, "r"); 656 if (oid_bio == NULL) { 657 /* 658 BIO_printf(bio_err,"problems opening %s for extra oid's\n",p); 659 ERR_print_errors(bio_err); 660 */ 661 } else { 662 OBJ_create_objects(oid_bio); 663 BIO_free(oid_bio); 664 } 665 } 666 } 667 if (!add_oid_section(bio_err, req_conf)) 668 goto end; 669 670 if (md_alg == NULL) { 671 p = NCONF_get_string(req_conf, SECTION, "default_md"); 672 if (p == NULL) 673 ERR_clear_error(); 674 if (p != NULL) { 675 if ((md_alg = EVP_get_digestbyname(p)) != NULL) 676 req_config.digest = md_alg; 677 } 678 } 679 if (!req_config.extensions) { 680 req_config.extensions = NCONF_get_string(req_conf, SECTION, V3_EXTENSIONS); 681 if (!req_config.extensions) 682 ERR_clear_error(); 683 } 684 if (req_config.extensions) { 685 /* Check syntax of file */ 686 X509V3_CTX ctx; 687 X509V3_set_ctx_test(&ctx); 688 X509V3_set_nconf(&ctx, req_conf); 689 if (!X509V3_EXT_add_nconf(req_conf, &ctx, req_config.extensions, NULL)) { 690 BIO_printf(bio_err, 691 "Error Loading extension section %s\n", req_config.extensions); 692 goto end; 693 } 694 } 695 if (addext_conf != NULL) { 696 /* Check syntax of command line extensions */ 697 X509V3_CTX ctx; 698 X509V3_set_ctx_test(&ctx); 699 X509V3_set_nconf(&ctx, addext_conf); 700 if (!X509V3_EXT_add_nconf(addext_conf, &ctx, "default", NULL)) { 701 BIO_printf(bio_err, 702 "Error Loading command line extensions\n"); 703 goto end; 704 } 705 } 706 if (!passin) { 707 passin = NCONF_get_string(req_conf, SECTION, "input_password"); 708 if (!passin) 709 ERR_clear_error(); 710 } 711 if (!passout) { 712 passout = NCONF_get_string(req_conf, SECTION, "output_password"); 713 if (!passout) 714 ERR_clear_error(); 715 } 716 p = NCONF_get_string(req_conf, SECTION, STRING_MASK); 717 if (!p) 718 ERR_clear_error(); 719 720 if (p && !ASN1_STRING_set_default_mask_asc(p)) { 721 BIO_printf(bio_err, "Invalid global string mask setting %s\n", p); 722 goto end; 723 } 724 if (req_config.chtype != MBSTRING_UTF8) { 725 p = NCONF_get_string(req_conf, SECTION, UTF8_IN); 726 if (!p) 727 ERR_clear_error(); 728 else if (!strcmp(p, "yes")) 729 req_config.chtype = MBSTRING_UTF8; 730 } 731 if (!req_config.req_exts) { 732 req_config.req_exts = NCONF_get_string(req_conf, SECTION, REQ_EXTENSIONS); 733 if (!req_config.req_exts) 734 ERR_clear_error(); 735 } 736 if (req_config.req_exts) { 737 /* Check syntax of file */ 738 X509V3_CTX ctx; 739 X509V3_set_ctx_test(&ctx); 740 X509V3_set_nconf(&ctx, req_conf); 741 if (!X509V3_EXT_add_nconf(req_conf, &ctx, req_config.req_exts, NULL)) { 742 BIO_printf(bio_err, 743 "Error Loading request extension section %s\n", 744 req_config.req_exts); 745 goto end; 746 } 747 } 748 in = BIO_new(BIO_s_file()); 749 out = BIO_new(BIO_s_file()); 750 if ((in == NULL) || (out == NULL)) 751 goto end; 752 753 if (req_config.keyfile != NULL) { 754 pkey = load_key(bio_err, req_config.keyfile, req_config.keyform, 0, passin, 755 "Private Key"); 756 if (!pkey) { 757 /* 758 * load_key() has already printed an appropriate 759 * message 760 */ 761 goto end; 762 } 763 } 764 if (req_config.newreq && (pkey == NULL)) { 765 if (!NCONF_get_number(req_conf, SECTION, BITS, &req_config.newkey)) { 766 req_config.newkey = DEFAULT_KEY_LENGTH; 767 } 768 if (req_config.keyalg) { 769 genctx = set_keygen_ctx(bio_err, req_config.keyalg, &pkey_type, &req_config.newkey, 770 &keyalgstr); 771 if (!genctx) 772 goto end; 773 } 774 if (req_config.newkey < MIN_KEY_LENGTH && (pkey_type == EVP_PKEY_RSA || pkey_type == EVP_PKEY_DSA)) { 775 BIO_printf(bio_err, "private key length is too short,\n"); 776 BIO_printf(bio_err, "it needs to be at least %d bits, not %ld\n", MIN_KEY_LENGTH, req_config.newkey); 777 goto end; 778 } 779 if (!genctx) { 780 genctx = set_keygen_ctx(bio_err, NULL, &pkey_type, &req_config.newkey, 781 &keyalgstr); 782 if (!genctx) 783 goto end; 784 } 785 if (req_config.pkeyopts) { 786 char *genopt; 787 for (i = 0; i < sk_OPENSSL_STRING_num(req_config.pkeyopts); i++) { 788 genopt = sk_OPENSSL_STRING_value(req_config.pkeyopts, i); 789 if (pkey_ctrl_string(genctx, genopt) <= 0) { 790 BIO_printf(bio_err, 791 "parameter error \"%s\"\n", 792 genopt); 793 ERR_print_errors(bio_err); 794 goto end; 795 } 796 } 797 } 798 BIO_printf(bio_err, "Generating a %ld bit %s private key\n", 799 req_config.newkey, keyalgstr); 800 801 EVP_PKEY_CTX_set_cb(genctx, genpkey_cb); 802 EVP_PKEY_CTX_set_app_data(genctx, bio_err); 803 804 if (EVP_PKEY_keygen(genctx, &pkey) <= 0) { 805 BIO_puts(bio_err, "Error Generating Key\n"); 806 goto end; 807 } 808 EVP_PKEY_CTX_free(genctx); 809 genctx = NULL; 810 811 if (req_config.keyout == NULL) { 812 req_config.keyout = NCONF_get_string(req_conf, SECTION, KEYFILE); 813 if (req_config.keyout == NULL) 814 ERR_clear_error(); 815 } 816 if (req_config.keyout == NULL) { 817 BIO_printf(bio_err, "writing new private key to stdout\n"); 818 BIO_set_fp(out, stdout, BIO_NOCLOSE); 819 } else { 820 BIO_printf(bio_err, "writing new private key to '%s'\n", req_config.keyout); 821 if (BIO_write_filename(out, req_config.keyout) <= 0) { 822 perror(req_config.keyout); 823 goto end; 824 } 825 } 826 827 p = NCONF_get_string(req_conf, SECTION, "encrypt_rsa_key"); 828 if (p == NULL) { 829 ERR_clear_error(); 830 p = NCONF_get_string(req_conf, SECTION, "encrypt_key"); 831 if (p == NULL) 832 ERR_clear_error(); 833 } 834 if ((p != NULL) && (strcmp(p, "no") == 0)) 835 cipher = NULL; 836 if (req_config.nodes) 837 cipher = NULL; 838 839 i = 0; 840 loop: 841 if (!PEM_write_bio_PrivateKey(out, pkey, cipher, 842 NULL, 0, NULL, passout)) { 843 if ((ERR_GET_REASON(ERR_peek_error()) == 844 PEM_R_PROBLEMS_GETTING_PASSWORD) && (i < 3)) { 845 ERR_clear_error(); 846 i++; 847 goto loop; 848 } 849 goto end; 850 } 851 BIO_printf(bio_err, "-----\n"); 852 } 853 if (!req_config.newreq) { 854 /* 855 * Since we are using a pre-existing certificate request, the 856 * kludge 'format' info should not be changed. 857 */ 858 req_config.kludge = -1; 859 if (req_config.infile == NULL) 860 BIO_set_fp(in, stdin, BIO_NOCLOSE); 861 else { 862 if (BIO_read_filename(in, req_config.infile) <= 0) { 863 perror(req_config.infile); 864 goto end; 865 } 866 } 867 868 if (req_config.informat == FORMAT_ASN1) 869 req = d2i_X509_REQ_bio(in, NULL); 870 else if (req_config.informat == FORMAT_PEM) 871 req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL); 872 else { 873 BIO_printf(bio_err, "bad input format specified for X509 request\n"); 874 goto end; 875 } 876 if (req == NULL) { 877 BIO_printf(bio_err, "unable to load X509 request\n"); 878 goto end; 879 } 880 } 881 if (req_config.newreq || req_config.x509) { 882 if (pkey == NULL) { 883 BIO_printf(bio_err, "you need to specify a private key\n"); 884 goto end; 885 } 886 if (req == NULL) { 887 req = X509_REQ_new(); 888 if (req == NULL) { 889 goto end; 890 } 891 i = make_REQ(req, pkey, req_config.subj, req_config.multirdn, !req_config.x509, req_config.chtype); 892 req_config.subj = NULL; /* done processing '-subj' option */ 893 if ((req_config.kludge > 0) && !sk_X509_ATTRIBUTE_num(req->req_info->attributes)) { 894 sk_X509_ATTRIBUTE_free(req->req_info->attributes); 895 req->req_info->attributes = NULL; 896 } 897 if (!i) { 898 BIO_printf(bio_err, "problems making Certificate Request\n"); 899 goto end; 900 } 901 } 902 if (req_config.x509) { 903 EVP_PKEY *tmppkey; 904 X509V3_CTX ext_ctx; 905 if ((x509ss = X509_new()) == NULL) 906 goto end; 907 908 /* Set version to V3 */ 909 if ((req_config.extensions != NULL || addext_conf != NULL) && 910 !X509_set_version(x509ss, 2)) 911 goto end; 912 if (req_config.serial) { 913 if (!X509_set_serialNumber(x509ss, req_config.serial)) 914 goto end; 915 } else { 916 if (!rand_serial(NULL, 917 X509_get_serialNumber(x509ss))) 918 goto end; 919 } 920 921 if (!X509_set_issuer_name(x509ss, X509_REQ_get_subject_name(req))) 922 goto end; 923 if (!X509_gmtime_adj(X509_get_notBefore(x509ss), 0)) 924 goto end; 925 if (!X509_time_adj_ex(X509_get_notAfter(x509ss), req_config.days, 0, NULL)) 926 goto end; 927 if (!X509_set_subject_name(x509ss, X509_REQ_get_subject_name(req))) 928 goto end; 929 tmppkey = X509_REQ_get_pubkey(req); 930 if (!tmppkey || !X509_set_pubkey(x509ss, tmppkey)) 931 goto end; 932 EVP_PKEY_free(tmppkey); 933 934 /* Set up V3 context struct */ 935 936 X509V3_set_ctx(&ext_ctx, x509ss, x509ss, NULL, NULL, 0); 937 X509V3_set_nconf(&ext_ctx, req_conf); 938 939 /* Add extensions */ 940 if (req_config.extensions && !X509V3_EXT_add_nconf(req_conf, 941 &ext_ctx, req_config.extensions, x509ss)) { 942 BIO_printf(bio_err, 943 "Error Loading extension section %s\n", 944 req_config.extensions); 945 goto end; 946 } 947 if (addext_conf != NULL && 948 !X509V3_EXT_add_nconf(addext_conf, &ext_ctx, 949 "default", x509ss)) { 950 BIO_printf(bio_err, 951 "Error Loading command line extensions\n"); 952 goto end; 953 } 954 i = do_X509_sign(bio_err, x509ss, pkey, req_config.digest, req_config.sigopts); 955 if (!i) { 956 ERR_print_errors(bio_err); 957 goto end; 958 } 959 } else { 960 X509V3_CTX ext_ctx; 961 962 /* Set up V3 context struct */ 963 964 X509V3_set_ctx(&ext_ctx, NULL, NULL, req, NULL, 0); 965 X509V3_set_nconf(&ext_ctx, req_conf); 966 967 /* Add extensions */ 968 if (req_config.req_exts && !X509V3_EXT_REQ_add_nconf(req_conf, 969 &ext_ctx, req_config.req_exts, req)) { 970 BIO_printf(bio_err, 971 "Error Loading extension section %s\n", 972 req_config.req_exts); 973 goto end; 974 } 975 if (addext_conf != NULL && 976 !X509V3_EXT_REQ_add_nconf(addext_conf, &ext_ctx, 977 "default", req)) { 978 BIO_printf(bio_err, 979 "Error Loading command line extensions\n"); 980 goto end; 981 } 982 i = do_X509_REQ_sign(bio_err, req, pkey, req_config.digest, req_config.sigopts); 983 if (!i) { 984 ERR_print_errors(bio_err); 985 goto end; 986 } 987 } 988 } 989 if (req_config.subj && req_config.x509) { 990 BIO_printf(bio_err, "Cannot modify certificate subject\n"); 991 goto end; 992 } 993 if (req_config.subj && !req_config.x509) { 994 if (req_config.verbose) { 995 BIO_printf(bio_err, "Modifying Request's Subject\n"); 996 print_name(bio_err, "old subject=", X509_REQ_get_subject_name(req), req_config.nmflag); 997 } 998 if (build_subject(req, req_config.subj, req_config.chtype, req_config.multirdn) == 0) { 999 BIO_printf(bio_err, "ERROR: cannot modify subject\n"); 1000 ex = 1; 1001 goto end; 1002 } 1003 req->req_info->enc.modified = 1; 1004 1005 if (req_config.verbose) { 1006 print_name(bio_err, "new subject=", X509_REQ_get_subject_name(req), req_config.nmflag); 1007 } 1008 } 1009 if (req_config.verify && !req_config.x509) { 1010 int tmp = 0; 1011 1012 if (pkey == NULL) { 1013 pkey = X509_REQ_get_pubkey(req); 1014 tmp = 1; 1015 if (pkey == NULL) 1016 goto end; 1017 } 1018 i = X509_REQ_verify(req, pkey); 1019 if (tmp) { 1020 EVP_PKEY_free(pkey); 1021 pkey = NULL; 1022 } 1023 if (i < 0) { 1024 goto end; 1025 } else if (i == 0) { 1026 BIO_printf(bio_err, "verify failure\n"); 1027 ERR_print_errors(bio_err); 1028 } else /* if (i > 0) */ 1029 BIO_printf(bio_err, "verify OK\n"); 1030 } 1031 if (req_config.noout && !req_config.text && !req_config.modulus && !req_config.subject && !req_config.pubkey) { 1032 ex = 0; 1033 goto end; 1034 } 1035 if (req_config.outfile == NULL) { 1036 BIO_set_fp(out, stdout, BIO_NOCLOSE); 1037 } else { 1038 if ((req_config.keyout != NULL) && (strcmp(req_config.outfile, req_config.keyout) == 0)) 1039 i = (int) BIO_append_filename(out, req_config.outfile); 1040 else 1041 i = (int) BIO_write_filename(out, req_config.outfile); 1042 if (!i) { 1043 perror(req_config.outfile); 1044 goto end; 1045 } 1046 } 1047 1048 if (req_config.pubkey) { 1049 EVP_PKEY *tpubkey; 1050 tpubkey = X509_REQ_get_pubkey(req); 1051 if (tpubkey == NULL) { 1052 BIO_printf(bio_err, "Error getting public key\n"); 1053 ERR_print_errors(bio_err); 1054 goto end; 1055 } 1056 PEM_write_bio_PUBKEY(out, tpubkey); 1057 EVP_PKEY_free(tpubkey); 1058 } 1059 if (req_config.text) { 1060 if (req_config.x509) 1061 X509_print_ex(out, x509ss, req_config.nmflag, req_config.reqflag); 1062 else 1063 X509_REQ_print_ex(out, req, req_config.nmflag, req_config.reqflag); 1064 } 1065 if (req_config.subject) { 1066 if (req_config.x509) 1067 print_name(out, "subject=", X509_get_subject_name(x509ss), req_config.nmflag); 1068 else 1069 print_name(out, "subject=", X509_REQ_get_subject_name(req), req_config.nmflag); 1070 } 1071 if (req_config.modulus) { 1072 EVP_PKEY *tpubkey; 1073 1074 if (req_config.x509) 1075 tpubkey = X509_get_pubkey(x509ss); 1076 else 1077 tpubkey = X509_REQ_get_pubkey(req); 1078 if (tpubkey == NULL) { 1079 fprintf(stdout, "Modulus=unavailable\n"); 1080 goto end; 1081 } 1082 fprintf(stdout, "Modulus="); 1083 if (EVP_PKEY_base_id(tpubkey) == EVP_PKEY_RSA) 1084 BN_print(out, tpubkey->pkey.rsa->n); 1085 else 1086 fprintf(stdout, "Wrong Algorithm type"); 1087 EVP_PKEY_free(tpubkey); 1088 fprintf(stdout, "\n"); 1089 } 1090 if (!req_config.noout && !req_config.x509) { 1091 if (req_config.outformat == FORMAT_ASN1) 1092 i = i2d_X509_REQ_bio(out, req); 1093 else if (req_config.outformat == FORMAT_PEM) { 1094 if (req_config.newhdr) 1095 i = PEM_write_bio_X509_REQ_NEW(out, req); 1096 else 1097 i = PEM_write_bio_X509_REQ(out, req); 1098 } else { 1099 BIO_printf(bio_err, "bad output format specified for outfile\n"); 1100 goto end; 1101 } 1102 if (!i) { 1103 BIO_printf(bio_err, "unable to write X509 request\n"); 1104 goto end; 1105 } 1106 } 1107 if (!req_config.noout && req_config.x509 && (x509ss != NULL)) { 1108 if (req_config.outformat == FORMAT_ASN1) 1109 i = i2d_X509_bio(out, x509ss); 1110 else if (req_config.outformat == FORMAT_PEM) 1111 i = PEM_write_bio_X509(out, x509ss); 1112 else { 1113 BIO_printf(bio_err, "bad output format specified for outfile\n"); 1114 goto end; 1115 } 1116 if (!i) { 1117 BIO_printf(bio_err, "unable to write X509 certificate\n"); 1118 goto end; 1119 } 1120 } 1121 ex = 0; 1122 end: 1123 if (ex) { 1124 ERR_print_errors(bio_err); 1125 } 1126 if ((req_conf != NULL) && (req_conf != config)) 1127 NCONF_free(req_conf); 1128 NCONF_free(addext_conf); 1129 BIO_free(req_config.addext_bio); 1130 BIO_free(in); 1131 BIO_free_all(out); 1132 EVP_PKEY_free(pkey); 1133 if (genctx) 1134 EVP_PKEY_CTX_free(genctx); 1135 if (req_config.pkeyopts) 1136 sk_OPENSSL_STRING_free(req_config.pkeyopts); 1137 if (req_config.sigopts) 1138 sk_OPENSSL_STRING_free(req_config.sigopts); 1139 lh_OPENSSL_STRING_doall(req_config.addexts, (LHASH_DOALL_FN_TYPE)exts_cleanup); 1140 lh_OPENSSL_STRING_free(req_config.addexts); 1141 free(keyalgstr); 1142 X509_REQ_free(req); 1143 X509_free(x509ss); 1144 ASN1_INTEGER_free(req_config.serial); 1145 if (req_config.passargin && passin) 1146 free(passin); 1147 if (req_config.passargout && passout) 1148 free(passout); 1149 OBJ_cleanup(); 1150 1151 return (ex); 1152 } 1153 1154 static int 1155 make_REQ(X509_REQ * req, EVP_PKEY * pkey, char *subj, int multirdn, 1156 int attribs, unsigned long chtype) 1157 { 1158 int ret = 0, i; 1159 char no_prompt = 0; 1160 STACK_OF(CONF_VALUE) * dn_sk, *attr_sk = NULL; 1161 char *tmp, *dn_sect, *attr_sect; 1162 1163 tmp = NCONF_get_string(req_conf, SECTION, PROMPT); 1164 if (tmp == NULL) 1165 ERR_clear_error(); 1166 if ((tmp != NULL) && !strcmp(tmp, "no")) 1167 no_prompt = 1; 1168 1169 dn_sect = NCONF_get_string(req_conf, SECTION, DISTINGUISHED_NAME); 1170 if (dn_sect == NULL) { 1171 BIO_printf(bio_err, "unable to find '%s' in config\n", 1172 DISTINGUISHED_NAME); 1173 goto err; 1174 } 1175 dn_sk = NCONF_get_section(req_conf, dn_sect); 1176 if (dn_sk == NULL) { 1177 BIO_printf(bio_err, "unable to get '%s' section\n", dn_sect); 1178 goto err; 1179 } 1180 attr_sect = NCONF_get_string(req_conf, SECTION, ATTRIBUTES); 1181 if (attr_sect == NULL) { 1182 ERR_clear_error(); 1183 attr_sk = NULL; 1184 } else { 1185 attr_sk = NCONF_get_section(req_conf, attr_sect); 1186 if (attr_sk == NULL) { 1187 BIO_printf(bio_err, "unable to get '%s' section\n", attr_sect); 1188 goto err; 1189 } 1190 } 1191 1192 /* setup version number */ 1193 if (!X509_REQ_set_version(req, 0L)) 1194 goto err; /* version 1 */ 1195 1196 if (no_prompt) 1197 i = auto_info(req, dn_sk, attr_sk, attribs, chtype); 1198 else { 1199 if (subj) 1200 i = build_subject(req, subj, chtype, multirdn); 1201 else 1202 i = prompt_info(req, dn_sk, dn_sect, attr_sk, attr_sect, attribs, chtype); 1203 } 1204 if (!i) 1205 goto err; 1206 1207 if (!X509_REQ_set_pubkey(req, pkey)) 1208 goto err; 1209 1210 ret = 1; 1211 err: 1212 return (ret); 1213 } 1214 1215 /* 1216 * subject is expected to be in the format /type0=value0/type1=value1/type2=... 1217 * where characters may be escaped by \ 1218 */ 1219 static int 1220 build_subject(X509_REQ * req, char *subject, unsigned long chtype, int multirdn) 1221 { 1222 X509_NAME *n; 1223 1224 if (!(n = parse_name(subject, chtype, multirdn))) 1225 return 0; 1226 1227 if (!X509_REQ_set_subject_name(req, n)) { 1228 X509_NAME_free(n); 1229 return 0; 1230 } 1231 X509_NAME_free(n); 1232 return 1; 1233 } 1234 1235 1236 static int 1237 prompt_info(X509_REQ * req, 1238 STACK_OF(CONF_VALUE) * dn_sk, char *dn_sect, 1239 STACK_OF(CONF_VALUE) * attr_sk, char *attr_sect, int attribs, 1240 unsigned long chtype) 1241 { 1242 int i; 1243 char *p, *q; 1244 char buf[100]; 1245 int nid, mval; 1246 long n_min, n_max; 1247 char *type, *value; 1248 const char *def; 1249 CONF_VALUE *v; 1250 X509_NAME *subj; 1251 subj = X509_REQ_get_subject_name(req); 1252 1253 if (!req_config.batch) { 1254 BIO_printf(bio_err, "You are about to be asked to enter information that will be incorporated\n"); 1255 BIO_printf(bio_err, "into your certificate request.\n"); 1256 BIO_printf(bio_err, "What you are about to enter is what is called a Distinguished Name or a DN.\n"); 1257 BIO_printf(bio_err, "There are quite a few fields but you can leave some blank\n"); 1258 BIO_printf(bio_err, "For some fields there will be a default value,\n"); 1259 BIO_printf(bio_err, "If you enter '.', the field will be left blank.\n"); 1260 BIO_printf(bio_err, "-----\n"); 1261 } 1262 if (sk_CONF_VALUE_num(dn_sk)) { 1263 i = -1; 1264 start: for (;;) { 1265 int ret; 1266 i++; 1267 if (sk_CONF_VALUE_num(dn_sk) <= i) 1268 break; 1269 1270 v = sk_CONF_VALUE_value(dn_sk, i); 1271 p = q = NULL; 1272 type = v->name; 1273 if (!check_end(type, "_min") || !check_end(type, "_max") || 1274 !check_end(type, "_default") || 1275 !check_end(type, "_value")) 1276 continue; 1277 /* 1278 * Skip past any leading X. X: X, etc to allow for 1279 * multiple instances 1280 */ 1281 for (p = v->name; *p; p++) 1282 if ((*p == ':') || (*p == ',') || 1283 (*p == '.')) { 1284 p++; 1285 if (*p) 1286 type = p; 1287 break; 1288 } 1289 if (*type == '+') { 1290 mval = -1; 1291 type++; 1292 } else 1293 mval = 0; 1294 /* If OBJ not recognised ignore it */ 1295 if ((nid = OBJ_txt2nid(type)) == NID_undef) 1296 goto start; 1297 ret = snprintf(buf, sizeof buf, "%s_default", v->name); 1298 if (ret < 0 || ret >= sizeof(buf)) { 1299 BIO_printf(bio_err, "Name '%s' too long for default\n", 1300 v->name); 1301 return 0; 1302 } 1303 if ((def = NCONF_get_string(req_conf, dn_sect, buf)) == NULL) { 1304 ERR_clear_error(); 1305 def = ""; 1306 } 1307 ret = snprintf(buf, sizeof buf, "%s_value", v->name); 1308 if (ret < 0 || ret >= sizeof(buf)) { 1309 BIO_printf(bio_err, "Name '%s' too long for value\n", 1310 v->name); 1311 return 0; 1312 } 1313 if ((value = NCONF_get_string(req_conf, dn_sect, buf)) == NULL) { 1314 ERR_clear_error(); 1315 value = NULL; 1316 } 1317 ret = snprintf(buf, sizeof buf, "%s_min", v->name); 1318 if (ret < 0 || ret >= sizeof(buf)) { 1319 BIO_printf(bio_err, "Name '%s' too long for min\n", 1320 v->name); 1321 return 0; 1322 } 1323 if (!NCONF_get_number(req_conf, dn_sect, buf, &n_min)) { 1324 ERR_clear_error(); 1325 n_min = -1; 1326 } 1327 ret = snprintf(buf, sizeof buf, "%s_max", v->name); 1328 if (ret < 0 || ret >= sizeof(buf)) { 1329 BIO_printf(bio_err, "Name '%s' too long for max\n", 1330 v->name); 1331 return 0; 1332 } 1333 if (!NCONF_get_number(req_conf, dn_sect, buf, &n_max)) { 1334 ERR_clear_error(); 1335 n_max = -1; 1336 } 1337 if (!add_DN_object(subj, v->value, def, value, nid, 1338 n_min, n_max, chtype, mval)) 1339 return 0; 1340 } 1341 if (X509_NAME_entry_count(subj) == 0) { 1342 BIO_printf(bio_err, "error, no objects specified in config file\n"); 1343 return 0; 1344 } 1345 if (attribs) { 1346 if ((attr_sk != NULL) && (sk_CONF_VALUE_num(attr_sk) > 0) && 1347 (!req_config.batch)) { 1348 BIO_printf(bio_err, 1349 "\nPlease enter the following 'extra' attributes\n"); 1350 BIO_printf(bio_err, 1351 "to be sent with your certificate request\n"); 1352 } 1353 i = -1; 1354 start2: for (;;) { 1355 int ret; 1356 i++; 1357 if ((attr_sk == NULL) || 1358 (sk_CONF_VALUE_num(attr_sk) <= i)) 1359 break; 1360 1361 v = sk_CONF_VALUE_value(attr_sk, i); 1362 type = v->name; 1363 if ((nid = OBJ_txt2nid(type)) == NID_undef) 1364 goto start2; 1365 ret = snprintf(buf, sizeof buf, "%s_default", type); 1366 if (ret < 0 || ret >= sizeof(buf)) { 1367 BIO_printf(bio_err, "Name '%s' too long for default\n", 1368 v->name); 1369 return 0; 1370 } 1371 if ((def = NCONF_get_string(req_conf, attr_sect, buf)) 1372 == NULL) { 1373 ERR_clear_error(); 1374 def = ""; 1375 } 1376 ret = snprintf(buf, sizeof buf, "%s_value", type); 1377 if (ret < 0 || ret >= sizeof(buf)) { 1378 BIO_printf(bio_err, "Name '%s' too long for value\n", 1379 v->name); 1380 return 0; 1381 } 1382 if ((value = NCONF_get_string(req_conf, attr_sect, buf)) 1383 == NULL) { 1384 ERR_clear_error(); 1385 value = NULL; 1386 } 1387 ret = snprintf(buf, sizeof buf, "%s_min", type); 1388 if (ret < 0 || ret >= sizeof(buf)) { 1389 BIO_printf(bio_err, "Name '%s' too long for min\n", 1390 v->name); 1391 return 0; 1392 } 1393 if (!NCONF_get_number(req_conf, attr_sect, buf, &n_min)) { 1394 ERR_clear_error(); 1395 n_min = -1; 1396 } 1397 ret = snprintf(buf, sizeof buf, "%s_max", type); 1398 if (ret < 0 || ret >= sizeof(buf)) { 1399 BIO_printf(bio_err, "Name '%s' too long for max\n", 1400 v->name); 1401 return 0; 1402 } 1403 if (!NCONF_get_number(req_conf, attr_sect, buf, &n_max)) { 1404 ERR_clear_error(); 1405 n_max = -1; 1406 } 1407 if (!add_attribute_object(req, 1408 v->value, def, value, nid, n_min, n_max, chtype)) 1409 return 0; 1410 } 1411 } 1412 } else { 1413 BIO_printf(bio_err, "No template, please set one up.\n"); 1414 return 0; 1415 } 1416 1417 return 1; 1418 1419 } 1420 1421 static int 1422 auto_info(X509_REQ * req, STACK_OF(CONF_VALUE) * dn_sk, 1423 STACK_OF(CONF_VALUE) * attr_sk, int attribs, unsigned long chtype) 1424 { 1425 int i; 1426 char *p, *q; 1427 char *type; 1428 CONF_VALUE *v; 1429 X509_NAME *subj; 1430 1431 subj = X509_REQ_get_subject_name(req); 1432 1433 for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) { 1434 int mval; 1435 v = sk_CONF_VALUE_value(dn_sk, i); 1436 p = q = NULL; 1437 type = v->name; 1438 /* 1439 * Skip past any leading X. X: X, etc to allow for multiple 1440 * instances 1441 */ 1442 for (p = v->name; *p; p++) 1443 if ((*p == ':') || (*p == ',') || (*p == '.')) { 1444 p++; 1445 if (*p) 1446 type = p; 1447 break; 1448 } 1449 if (*p == '+') { 1450 p++; 1451 mval = -1; 1452 } else 1453 mval = 0; 1454 if (!X509_NAME_add_entry_by_txt(subj, type, chtype, 1455 (unsigned char *) v->value, -1, -1, mval)) 1456 return 0; 1457 1458 } 1459 1460 if (!X509_NAME_entry_count(subj)) { 1461 BIO_printf(bio_err, "error, no objects specified in config file\n"); 1462 return 0; 1463 } 1464 if (attribs) { 1465 for (i = 0; i < sk_CONF_VALUE_num(attr_sk); i++) { 1466 v = sk_CONF_VALUE_value(attr_sk, i); 1467 if (!X509_REQ_add1_attr_by_txt(req, v->name, chtype, 1468 (unsigned char *) v->value, -1)) 1469 return 0; 1470 } 1471 } 1472 return 1; 1473 } 1474 1475 1476 static int 1477 add_DN_object(X509_NAME * n, char *text, const char *def, char *value, 1478 int nid, int n_min, int n_max, unsigned long chtype, int mval) 1479 { 1480 int i, ret = 0; 1481 char buf[1024]; 1482 start: 1483 if (!req_config.batch) 1484 BIO_printf(bio_err, "%s [%s]:", text, def); 1485 (void) BIO_flush(bio_err); 1486 if (value != NULL) { 1487 strlcpy(buf, value, sizeof buf); 1488 strlcat(buf, "\n", sizeof buf); 1489 BIO_printf(bio_err, "%s\n", value); 1490 } else { 1491 buf[0] = '\0'; 1492 if (!req_config.batch) { 1493 if (!fgets(buf, sizeof buf, stdin)) 1494 return 0; 1495 } else { 1496 buf[0] = '\n'; 1497 buf[1] = '\0'; 1498 } 1499 } 1500 1501 if (buf[0] == '\0') 1502 return (0); 1503 else if (buf[0] == '\n') { 1504 if ((def == NULL) || (def[0] == '\0')) 1505 return (1); 1506 strlcpy(buf, def, sizeof buf); 1507 strlcat(buf, "\n", sizeof buf); 1508 } else if ((buf[0] == '.') && (buf[1] == '\n')) 1509 return (1); 1510 1511 i = strlen(buf); 1512 if (buf[i - 1] != '\n') { 1513 BIO_printf(bio_err, "weird input :-(\n"); 1514 return (0); 1515 } 1516 buf[--i] = '\0'; 1517 if (!req_check_len(i, n_min, n_max)) 1518 goto start; 1519 if (!X509_NAME_add_entry_by_NID(n, nid, chtype, 1520 (unsigned char *) buf, -1, -1, mval)) 1521 goto err; 1522 ret = 1; 1523 err: 1524 return (ret); 1525 } 1526 1527 static int 1528 add_attribute_object(X509_REQ * req, char *text, const char *def, 1529 char *value, int nid, int n_min, 1530 int n_max, unsigned long chtype) 1531 { 1532 int i; 1533 static char buf[1024]; 1534 1535 start: 1536 if (!req_config.batch) 1537 BIO_printf(bio_err, "%s [%s]:", text, def); 1538 (void) BIO_flush(bio_err); 1539 if (value != NULL) { 1540 strlcpy(buf, value, sizeof buf); 1541 strlcat(buf, "\n", sizeof buf); 1542 BIO_printf(bio_err, "%s\n", value); 1543 } else { 1544 buf[0] = '\0'; 1545 if (!req_config.batch) { 1546 if (!fgets(buf, sizeof buf, stdin)) 1547 return 0; 1548 } else { 1549 buf[0] = '\n'; 1550 buf[1] = '\0'; 1551 } 1552 } 1553 1554 if (buf[0] == '\0') 1555 return (0); 1556 else if (buf[0] == '\n') { 1557 if ((def == NULL) || (def[0] == '\0')) 1558 return (1); 1559 strlcpy(buf, def, sizeof buf); 1560 strlcat(buf, "\n", sizeof buf); 1561 } else if ((buf[0] == '.') && (buf[1] == '\n')) 1562 return (1); 1563 1564 i = strlen(buf); 1565 if (buf[i - 1] != '\n') { 1566 BIO_printf(bio_err, "weird input :-(\n"); 1567 return (0); 1568 } 1569 buf[--i] = '\0'; 1570 if (!req_check_len(i, n_min, n_max)) 1571 goto start; 1572 1573 if (!X509_REQ_add1_attr_by_NID(req, nid, chtype, 1574 (unsigned char *) buf, -1)) { 1575 BIO_printf(bio_err, "Error adding attribute\n"); 1576 ERR_print_errors(bio_err); 1577 goto err; 1578 } 1579 return (1); 1580 err: 1581 return (0); 1582 } 1583 1584 static int 1585 req_check_len(int len, int n_min, int n_max) 1586 { 1587 if ((n_min > 0) && (len < n_min)) { 1588 BIO_printf(bio_err, "string is too short, it needs to be at least %d bytes long\n", n_min); 1589 return (0); 1590 } 1591 if ((n_max >= 0) && (len > n_max)) { 1592 BIO_printf(bio_err, "string is too long, it needs to be less than %d bytes long\n", n_max); 1593 return (0); 1594 } 1595 return (1); 1596 } 1597 1598 /* Check if the end of a string matches 'end' */ 1599 static int 1600 check_end(const char *str, const char *end) 1601 { 1602 int elen, slen; 1603 const char *tmp; 1604 elen = strlen(end); 1605 slen = strlen(str); 1606 if (elen > slen) 1607 return 1; 1608 tmp = str + slen - elen; 1609 return strcmp(tmp, end); 1610 } 1611 1612 static EVP_PKEY_CTX * 1613 set_keygen_ctx(BIO * err, const char *gstr, int *pkey_type, 1614 long *pkeylen, char **palgnam) 1615 { 1616 EVP_PKEY_CTX *gctx = NULL; 1617 EVP_PKEY *param = NULL; 1618 long keylen = -1; 1619 BIO *pbio = NULL; 1620 const char *paramfile = NULL; 1621 const char *errstr; 1622 1623 if (gstr == NULL) { 1624 *pkey_type = EVP_PKEY_RSA; 1625 keylen = *pkeylen; 1626 } else if (gstr[0] >= '0' && gstr[0] <= '9') { 1627 *pkey_type = EVP_PKEY_RSA; 1628 keylen = strtonum(gstr, 0, LONG_MAX, &errstr); 1629 if (errstr) { 1630 BIO_printf(err, "bad algorithm %s: %s\n", gstr, errstr); 1631 return NULL; 1632 } 1633 *pkeylen = keylen; 1634 } else if (!strncmp(gstr, "param:", 6)) 1635 paramfile = gstr + 6; 1636 else { 1637 const char *p = strchr(gstr, ':'); 1638 int len; 1639 const EVP_PKEY_ASN1_METHOD *ameth; 1640 1641 if (p) 1642 len = p - gstr; 1643 else 1644 len = strlen(gstr); 1645 1646 ameth = EVP_PKEY_asn1_find_str(NULL, gstr, len); 1647 1648 if (!ameth) { 1649 BIO_printf(err, "Unknown algorithm %.*s\n", len, gstr); 1650 return NULL; 1651 } 1652 EVP_PKEY_asn1_get0_info(NULL, pkey_type, NULL, NULL, NULL, 1653 ameth); 1654 if (*pkey_type == EVP_PKEY_RSA) { 1655 if (p) { 1656 keylen = strtonum(p + 1, 0, LONG_MAX, &errstr); 1657 if (errstr) { 1658 BIO_printf(err, "bad algorithm %s: %s\n", 1659 p + 1, errstr); 1660 return NULL; 1661 } 1662 *pkeylen = keylen; 1663 } else 1664 keylen = *pkeylen; 1665 } else if (p) 1666 paramfile = p + 1; 1667 } 1668 1669 if (paramfile) { 1670 pbio = BIO_new_file(paramfile, "r"); 1671 if (!pbio) { 1672 BIO_printf(err, "Can't open parameter file %s\n", 1673 paramfile); 1674 return NULL; 1675 } 1676 param = PEM_read_bio_Parameters(pbio, NULL); 1677 1678 if (!param) { 1679 X509 *x; 1680 (void) BIO_reset(pbio); 1681 x = PEM_read_bio_X509(pbio, NULL, NULL, NULL); 1682 if (x) { 1683 param = X509_get_pubkey(x); 1684 X509_free(x); 1685 } 1686 } 1687 BIO_free(pbio); 1688 1689 if (!param) { 1690 BIO_printf(err, "Error reading parameter file %s\n", 1691 paramfile); 1692 return NULL; 1693 } 1694 if (*pkey_type == -1) 1695 *pkey_type = EVP_PKEY_id(param); 1696 else if (*pkey_type != EVP_PKEY_base_id(param)) { 1697 BIO_printf(err, "Key Type does not match parameters\n"); 1698 EVP_PKEY_free(param); 1699 return NULL; 1700 } 1701 } 1702 if (palgnam) { 1703 const EVP_PKEY_ASN1_METHOD *ameth; 1704 const char *anam; 1705 ameth = EVP_PKEY_asn1_find(NULL, *pkey_type); 1706 if (!ameth) { 1707 BIO_puts(err, "Internal error: can't find key algorithm\n"); 1708 return NULL; 1709 } 1710 EVP_PKEY_asn1_get0_info(NULL, NULL, NULL, NULL, &anam, ameth); 1711 *palgnam = strdup(anam); 1712 } 1713 if (param) { 1714 gctx = EVP_PKEY_CTX_new(param, NULL); 1715 *pkeylen = EVP_PKEY_bits(param); 1716 EVP_PKEY_free(param); 1717 } else 1718 gctx = EVP_PKEY_CTX_new_id(*pkey_type, NULL); 1719 1720 if (!gctx) { 1721 BIO_puts(err, "Error allocating keygen context\n"); 1722 ERR_print_errors(err); 1723 return NULL; 1724 } 1725 if (EVP_PKEY_keygen_init(gctx) <= 0) { 1726 BIO_puts(err, "Error initializing keygen context\n"); 1727 ERR_print_errors(err); 1728 return NULL; 1729 } 1730 if ((*pkey_type == EVP_PKEY_RSA) && (keylen != -1)) { 1731 if (EVP_PKEY_CTX_set_rsa_keygen_bits(gctx, keylen) <= 0) { 1732 BIO_puts(err, "Error setting RSA keysize\n"); 1733 ERR_print_errors(err); 1734 EVP_PKEY_CTX_free(gctx); 1735 return NULL; 1736 } 1737 } 1738 1739 return gctx; 1740 } 1741 1742 static int 1743 genpkey_cb(EVP_PKEY_CTX * ctx) 1744 { 1745 char c = '*'; 1746 BIO *b = EVP_PKEY_CTX_get_app_data(ctx); 1747 int p; 1748 p = EVP_PKEY_CTX_get_keygen_info(ctx, 0); 1749 if (p == 0) 1750 c = '.'; 1751 if (p == 1) 1752 c = '+'; 1753 if (p == 2) 1754 c = '*'; 1755 if (p == 3) 1756 c = '\n'; 1757 BIO_write(b, &c, 1); 1758 (void) BIO_flush(b); 1759 return 1; 1760 } 1761 1762 static int 1763 do_sign_init(BIO * err, EVP_MD_CTX * ctx, EVP_PKEY * pkey, 1764 const EVP_MD * md, STACK_OF(OPENSSL_STRING) * sigopts) 1765 { 1766 EVP_PKEY_CTX *pkctx = NULL; 1767 int i; 1768 EVP_MD_CTX_init(ctx); 1769 if (!EVP_DigestSignInit(ctx, &pkctx, md, NULL, pkey)) 1770 return 0; 1771 for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) { 1772 char *sigopt = sk_OPENSSL_STRING_value(sigopts, i); 1773 if (pkey_ctrl_string(pkctx, sigopt) <= 0) { 1774 BIO_printf(err, "parameter error \"%s\"\n", sigopt); 1775 ERR_print_errors(bio_err); 1776 return 0; 1777 } 1778 } 1779 return 1; 1780 } 1781 1782 int 1783 do_X509_sign(BIO * err, X509 * x, EVP_PKEY * pkey, const EVP_MD * md, 1784 STACK_OF(OPENSSL_STRING) * sigopts) 1785 { 1786 int rv; 1787 EVP_MD_CTX mctx; 1788 EVP_MD_CTX_init(&mctx); 1789 rv = do_sign_init(err, &mctx, pkey, md, sigopts); 1790 if (rv > 0) 1791 rv = X509_sign_ctx(x, &mctx); 1792 EVP_MD_CTX_cleanup(&mctx); 1793 return rv > 0 ? 1 : 0; 1794 } 1795 1796 1797 int 1798 do_X509_REQ_sign(BIO * err, X509_REQ * x, EVP_PKEY * pkey, const EVP_MD * md, 1799 STACK_OF(OPENSSL_STRING) * sigopts) 1800 { 1801 int rv; 1802 EVP_MD_CTX mctx; 1803 EVP_MD_CTX_init(&mctx); 1804 rv = do_sign_init(err, &mctx, pkey, md, sigopts); 1805 if (rv > 0) 1806 rv = X509_REQ_sign_ctx(x, &mctx); 1807 EVP_MD_CTX_cleanup(&mctx); 1808 return rv > 0 ? 1 : 0; 1809 } 1810 1811 1812 1813 int 1814 do_X509_CRL_sign(BIO * err, X509_CRL * x, EVP_PKEY * pkey, const EVP_MD * md, 1815 STACK_OF(OPENSSL_STRING) * sigopts) 1816 { 1817 int rv; 1818 EVP_MD_CTX mctx; 1819 EVP_MD_CTX_init(&mctx); 1820 rv = do_sign_init(err, &mctx, pkey, md, sigopts); 1821 if (rv > 0) 1822 rv = X509_CRL_sign_ctx(x, &mctx); 1823 EVP_MD_CTX_cleanup(&mctx); 1824 return rv > 0 ? 1 : 0; 1825 } 1826 1827 static unsigned long 1828 ext_name_hash(const OPENSSL_STRING *a) 1829 { 1830 return lh_strhash((const char *)a); 1831 } 1832 1833 static int 1834 ext_name_cmp(const OPENSSL_STRING *a, const OPENSSL_STRING *b) 1835 { 1836 return strcmp((const char *)a, (const char *)b); 1837 } 1838 1839 static void 1840 exts_cleanup(OPENSSL_STRING *x) 1841 { 1842 free((char *)x); 1843 } 1844 1845 /* 1846 * Is the |kv| key already duplicated ? This is remarkably tricky to get right. 1847 * Return 0 if unique, -1 on runtime error; 1 if found or a syntax error. 1848 */ 1849 static int 1850 duplicated(LHASH_OF(OPENSSL_STRING) *addexts, char *kv) 1851 { 1852 char *p; 1853 size_t off; 1854 1855 /* Check syntax. */ 1856 /* Skip leading whitespace, make a copy. */ 1857 while (*kv && isspace(*kv)) 1858 if (*++kv == '\0') 1859 return 1; 1860 if ((p = strchr(kv, '=')) == NULL) 1861 return 1; 1862 off = p - kv; 1863 if ((kv = strdup(kv)) == NULL) 1864 return -1; 1865 1866 /* Skip trailing space before the equal sign. */ 1867 for (p = kv + off; p > kv; --p) 1868 if (!isspace(p[-1])) 1869 break; 1870 if (p == kv) { 1871 free(kv); 1872 return 1; 1873 } 1874 *p = '\0'; 1875 1876 /* See if "key" is there by attempting to add it. */ 1877 if ((p = (char *)lh_OPENSSL_STRING_insert(addexts, (OPENSSL_STRING*)kv)) 1878 != NULL || lh_OPENSSL_STRING_error(addexts)) { 1879 free(p != NULL ? p : kv); 1880 return -1; 1881 } 1882 1883 return 0; 1884 } 1885