1 /* apps/req.c */ 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 /* 60 * Until the key-gen callbacks are modified to use newer prototypes, we allow 61 * deprecated functions for openssl-internal code 62 */ 63 #ifdef OPENSSL_NO_DEPRECATED 64 # undef OPENSSL_NO_DEPRECATED 65 #endif 66 67 #include <stdio.h> 68 #include <stdlib.h> 69 #include <time.h> 70 #include <string.h> 71 #ifdef OPENSSL_NO_STDIO 72 # define APPS_WIN16 73 #endif 74 #include "apps.h" 75 #include <openssl/bio.h> 76 #include <openssl/evp.h> 77 #include <openssl/conf.h> 78 #include <openssl/err.h> 79 #include <openssl/asn1.h> 80 #include <openssl/x509.h> 81 #include <openssl/x509v3.h> 82 #include <openssl/objects.h> 83 #include <openssl/pem.h> 84 #include <openssl/bn.h> 85 #ifndef OPENSSL_NO_RSA 86 # include <openssl/rsa.h> 87 #endif 88 #ifndef OPENSSL_NO_DSA 89 # include <openssl/dsa.h> 90 #endif 91 92 #define SECTION "req" 93 94 #define BITS "default_bits" 95 #define KEYFILE "default_keyfile" 96 #define PROMPT "prompt" 97 #define DISTINGUISHED_NAME "distinguished_name" 98 #define ATTRIBUTES "attributes" 99 #define V3_EXTENSIONS "x509_extensions" 100 #define REQ_EXTENSIONS "req_extensions" 101 #define STRING_MASK "string_mask" 102 #define UTF8_IN "utf8" 103 104 #define DEFAULT_KEY_LENGTH 2048 105 #define MIN_KEY_LENGTH 512 106 107 #undef PROG 108 #define PROG req_main 109 110 /*- 111 * -inform arg - input format - default PEM (DER or PEM) 112 * -outform arg - output format - default PEM 113 * -in arg - input file - default stdin 114 * -out arg - output file - default stdout 115 * -verify - check request signature 116 * -noout - don't print stuff out. 117 * -text - print out human readable text. 118 * -nodes - no des encryption 119 * -config file - Load configuration file. 120 * -key file - make a request using key in file (or use it for verification). 121 * -keyform arg - key file format. 122 * -rand file(s) - load the file(s) into the PRNG. 123 * -newkey - make a key and a request. 124 * -modulus - print RSA modulus. 125 * -pubkey - output Public Key. 126 * -x509 - output a self signed X509 structure instead. 127 * -asn1-kludge - output new certificate request in a format that some CA's 128 * require. This format is wrong 129 */ 130 131 static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, char *dn, int mutlirdn, 132 int attribs, unsigned long chtype); 133 static int build_subject(X509_REQ *req, char *subj, unsigned long chtype, 134 int multirdn); 135 static int prompt_info(X509_REQ *req, 136 STACK_OF(CONF_VALUE) *dn_sk, char *dn_sect, 137 STACK_OF(CONF_VALUE) *attr_sk, char *attr_sect, 138 int attribs, unsigned long chtype); 139 static int auto_info(X509_REQ *req, STACK_OF(CONF_VALUE) *sk, 140 STACK_OF(CONF_VALUE) *attr, int attribs, 141 unsigned long chtype); 142 static int add_attribute_object(X509_REQ *req, char *text, const char *def, 143 char *value, int nid, int n_min, int n_max, 144 unsigned long chtype); 145 static int add_DN_object(X509_NAME *n, char *text, const char *def, 146 char *value, int nid, int n_min, int n_max, 147 unsigned long chtype, int mval); 148 static int genpkey_cb(EVP_PKEY_CTX *ctx); 149 static int req_check_len(int len, int n_min, int n_max); 150 static int check_end(const char *str, const char *end); 151 static EVP_PKEY_CTX *set_keygen_ctx(BIO *err, const char *gstr, 152 int *pkey_type, long *pkeylen, 153 char **palgnam, ENGINE *keygen_engine); 154 #ifndef MONOLITH 155 static char *default_config_file = NULL; 156 #endif 157 static CONF *req_conf = NULL; 158 static int batch = 0; 159 160 int MAIN(int, char **); 161 162 int MAIN(int argc, char **argv) 163 { 164 ENGINE *e = NULL, *gen_eng = NULL; 165 unsigned long nmflag = 0, reqflag = 0; 166 int ex = 1, x509 = 0, days = 30; 167 X509 *x509ss = NULL; 168 X509_REQ *req = NULL; 169 EVP_PKEY_CTX *genctx = NULL; 170 const char *keyalg = NULL; 171 char *keyalgstr = NULL; 172 STACK_OF(OPENSSL_STRING) *pkeyopts = NULL, *sigopts = NULL; 173 EVP_PKEY *pkey = NULL; 174 int i = 0, badops = 0, newreq = 0, verbose = 0, pkey_type = -1; 175 long newkey = -1; 176 BIO *in = NULL, *out = NULL; 177 int informat, outformat, verify = 0, noout = 0, text = 0, keyform = 178 FORMAT_PEM; 179 int nodes = 0, kludge = 0, newhdr = 0, subject = 0, pubkey = 0; 180 char *infile, *outfile, *prog, *keyfile = NULL, *template = 181 NULL, *keyout = NULL; 182 char *engine = NULL; 183 char *extensions = NULL; 184 char *req_exts = NULL; 185 const EVP_CIPHER *cipher = NULL; 186 ASN1_INTEGER *serial = NULL; 187 int modulus = 0; 188 char *inrand = NULL; 189 char *passargin = NULL, *passargout = NULL; 190 char *passin = NULL, *passout = NULL; 191 char *p; 192 char *subj = NULL; 193 int multirdn = 0; 194 const EVP_MD *md_alg = NULL, *digest = NULL; 195 unsigned long chtype = MBSTRING_ASC; 196 #ifndef MONOLITH 197 char *to_free; 198 long errline; 199 #endif 200 201 req_conf = NULL; 202 #ifndef OPENSSL_NO_DES 203 cipher = EVP_des_ede3_cbc(); 204 #endif 205 apps_startup(); 206 207 if (bio_err == NULL) 208 if ((bio_err = BIO_new(BIO_s_file())) != NULL) 209 BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); 210 211 infile = NULL; 212 outfile = NULL; 213 informat = FORMAT_PEM; 214 outformat = FORMAT_PEM; 215 216 prog = argv[0]; 217 argc--; 218 argv++; 219 while (argc >= 1) { 220 if (strcmp(*argv, "-inform") == 0) { 221 if (--argc < 1) 222 goto bad; 223 informat = str2fmt(*(++argv)); 224 } else if (strcmp(*argv, "-outform") == 0) { 225 if (--argc < 1) 226 goto bad; 227 outformat = str2fmt(*(++argv)); 228 } 229 #ifndef OPENSSL_NO_ENGINE 230 else if (strcmp(*argv, "-engine") == 0) { 231 if (--argc < 1) 232 goto bad; 233 engine = *(++argv); 234 } else if (strcmp(*argv, "-keygen_engine") == 0) { 235 if (--argc < 1) 236 goto bad; 237 gen_eng = ENGINE_by_id(*(++argv)); 238 if (gen_eng == NULL) { 239 BIO_printf(bio_err, "Can't find keygen engine %s\n", *argv); 240 goto end; 241 } 242 } 243 #endif 244 else if (strcmp(*argv, "-key") == 0) { 245 if (--argc < 1) 246 goto bad; 247 keyfile = *(++argv); 248 } else if (strcmp(*argv, "-pubkey") == 0) { 249 pubkey = 1; 250 } else if (strcmp(*argv, "-new") == 0) { 251 newreq = 1; 252 } else if (strcmp(*argv, "-config") == 0) { 253 if (--argc < 1) 254 goto bad; 255 template = *(++argv); 256 } else if (strcmp(*argv, "-keyform") == 0) { 257 if (--argc < 1) 258 goto bad; 259 keyform = str2fmt(*(++argv)); 260 } else if (strcmp(*argv, "-in") == 0) { 261 if (--argc < 1) 262 goto bad; 263 infile = *(++argv); 264 } else if (strcmp(*argv, "-out") == 0) { 265 if (--argc < 1) 266 goto bad; 267 outfile = *(++argv); 268 } else if (strcmp(*argv, "-keyout") == 0) { 269 if (--argc < 1) 270 goto bad; 271 keyout = *(++argv); 272 } else if (strcmp(*argv, "-passin") == 0) { 273 if (--argc < 1) 274 goto bad; 275 passargin = *(++argv); 276 } else if (strcmp(*argv, "-passout") == 0) { 277 if (--argc < 1) 278 goto bad; 279 passargout = *(++argv); 280 } else if (strcmp(*argv, "-rand") == 0) { 281 if (--argc < 1) 282 goto bad; 283 inrand = *(++argv); 284 } else if (strcmp(*argv, "-newkey") == 0) { 285 if (--argc < 1) 286 goto bad; 287 keyalg = *(++argv); 288 newreq = 1; 289 } else if (strcmp(*argv, "-pkeyopt") == 0) { 290 if (--argc < 1) 291 goto bad; 292 if (!pkeyopts) 293 pkeyopts = sk_OPENSSL_STRING_new_null(); 294 if (!pkeyopts || !sk_OPENSSL_STRING_push(pkeyopts, *(++argv))) 295 goto bad; 296 } else if (strcmp(*argv, "-sigopt") == 0) { 297 if (--argc < 1) 298 goto bad; 299 if (!sigopts) 300 sigopts = sk_OPENSSL_STRING_new_null(); 301 if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv))) 302 goto bad; 303 } else if (strcmp(*argv, "-batch") == 0) 304 batch = 1; 305 else if (strcmp(*argv, "-newhdr") == 0) 306 newhdr = 1; 307 else if (strcmp(*argv, "-modulus") == 0) 308 modulus = 1; 309 else if (strcmp(*argv, "-verify") == 0) 310 verify = 1; 311 else if (strcmp(*argv, "-nodes") == 0) 312 nodes = 1; 313 else if (strcmp(*argv, "-noout") == 0) 314 noout = 1; 315 else if (strcmp(*argv, "-verbose") == 0) 316 verbose = 1; 317 else if (strcmp(*argv, "-utf8") == 0) 318 chtype = MBSTRING_UTF8; 319 else if (strcmp(*argv, "-nameopt") == 0) { 320 if (--argc < 1) 321 goto bad; 322 if (!set_name_ex(&nmflag, *(++argv))) 323 goto bad; 324 } else if (strcmp(*argv, "-reqopt") == 0) { 325 if (--argc < 1) 326 goto bad; 327 if (!set_cert_ex(&reqflag, *(++argv))) 328 goto bad; 329 } else if (strcmp(*argv, "-subject") == 0) 330 subject = 1; 331 else if (strcmp(*argv, "-text") == 0) 332 text = 1; 333 else if (strcmp(*argv, "-x509") == 0) { 334 newreq = 1; 335 x509 = 1; 336 } else if (strcmp(*argv, "-asn1-kludge") == 0) 337 kludge = 1; 338 else if (strcmp(*argv, "-no-asn1-kludge") == 0) 339 kludge = 0; 340 else if (strcmp(*argv, "-subj") == 0) { 341 if (--argc < 1) 342 goto bad; 343 subj = *(++argv); 344 } else if (strcmp(*argv, "-multivalue-rdn") == 0) 345 multirdn = 1; 346 else if (strcmp(*argv, "-days") == 0) { 347 if (--argc < 1) 348 goto bad; 349 days = atoi(*(++argv)); 350 if (days == 0) 351 days = 30; 352 } else if (strcmp(*argv, "-set_serial") == 0) { 353 if (--argc < 1) 354 goto bad; 355 serial = s2i_ASN1_INTEGER(NULL, *(++argv)); 356 if (!serial) 357 goto bad; 358 } else if (strcmp(*argv, "-extensions") == 0) { 359 if (--argc < 1) 360 goto bad; 361 extensions = *(++argv); 362 } else if (strcmp(*argv, "-reqexts") == 0) { 363 if (--argc < 1) 364 goto bad; 365 req_exts = *(++argv); 366 } else if ((md_alg = EVP_get_digestbyname(&((*argv)[1]))) != NULL) { 367 /* ok */ 368 digest = md_alg; 369 } else { 370 BIO_printf(bio_err, "unknown option %s\n", *argv); 371 badops = 1; 372 break; 373 } 374 argc--; 375 argv++; 376 } 377 378 if (badops) { 379 bad: 380 BIO_printf(bio_err, "%s [options] <infile >outfile\n", prog); 381 BIO_printf(bio_err, "where options are\n"); 382 BIO_printf(bio_err, " -inform arg input format - DER or PEM\n"); 383 BIO_printf(bio_err, " -outform arg output format - DER or PEM\n"); 384 BIO_printf(bio_err, " -in arg input file\n"); 385 BIO_printf(bio_err, " -out arg output file\n"); 386 BIO_printf(bio_err, " -text text form of request\n"); 387 BIO_printf(bio_err, " -pubkey output public key\n"); 388 BIO_printf(bio_err, " -noout do not output REQ\n"); 389 BIO_printf(bio_err, " -verify verify signature on REQ\n"); 390 BIO_printf(bio_err, " -modulus RSA modulus\n"); 391 BIO_printf(bio_err, " -nodes don't encrypt the output key\n"); 392 #ifndef OPENSSL_NO_ENGINE 393 BIO_printf(bio_err, 394 " -engine e use engine e, possibly a hardware device\n"); 395 #endif 396 BIO_printf(bio_err, " -subject output the request's subject\n"); 397 BIO_printf(bio_err, " -passin private key password source\n"); 398 BIO_printf(bio_err, 399 " -key file use the private key contained in file\n"); 400 BIO_printf(bio_err, " -keyform arg key file format\n"); 401 BIO_printf(bio_err, " -keyout arg file to send the key to\n"); 402 BIO_printf(bio_err, " -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, 403 LIST_SEPARATOR_CHAR); 404 BIO_printf(bio_err, 405 " load the file (or the files in the directory) into\n"); 406 BIO_printf(bio_err, " the random number generator\n"); 407 BIO_printf(bio_err, 408 " -newkey rsa:bits generate a new RSA key of 'bits' in size\n"); 409 BIO_printf(bio_err, 410 " -newkey dsa:file generate a new DSA key, parameters taken from CA in 'file'\n"); 411 #ifndef OPENSSL_NO_ECDSA 412 BIO_printf(bio_err, 413 " -newkey ec:file generate a new EC key, parameters taken from CA in 'file'\n"); 414 #endif 415 BIO_printf(bio_err, 416 " -[digest] Digest to sign with (md5, sha1, md2, mdc2, md4)\n"); 417 BIO_printf(bio_err, " -config file request template file.\n"); 418 BIO_printf(bio_err, 419 " -subj arg set or modify request subject\n"); 420 BIO_printf(bio_err, 421 " -multivalue-rdn enable support for multivalued RDNs\n"); 422 BIO_printf(bio_err, " -new new request.\n"); 423 BIO_printf(bio_err, 424 " -batch do not ask anything during request generation\n"); 425 BIO_printf(bio_err, 426 " -x509 output a x509 structure instead of a cert. req.\n"); 427 BIO_printf(bio_err, 428 " -days number of days a certificate generated by -x509 is valid for.\n"); 429 BIO_printf(bio_err, 430 " -set_serial serial number to use for a certificate generated by -x509.\n"); 431 BIO_printf(bio_err, 432 " -newhdr output \"NEW\" in the header lines\n"); 433 BIO_printf(bio_err, 434 " -asn1-kludge Output the 'request' in a format that is wrong but some CA's\n"); 435 BIO_printf(bio_err, 436 " have been reported as requiring\n"); 437 BIO_printf(bio_err, 438 " -extensions .. specify certificate extension section (override value in config file)\n"); 439 BIO_printf(bio_err, 440 " -reqexts .. specify request extension section (override value in config file)\n"); 441 BIO_printf(bio_err, 442 " -utf8 input characters are UTF8 (default ASCII)\n"); 443 BIO_printf(bio_err, 444 " -nameopt arg - various certificate name options\n"); 445 BIO_printf(bio_err, 446 " -reqopt arg - various request text options\n\n"); 447 goto end; 448 } 449 450 ERR_load_crypto_strings(); 451 if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) { 452 BIO_printf(bio_err, "Error getting passwords\n"); 453 goto end; 454 } 455 #ifndef MONOLITH /* else this has happened in openssl.c 456 * (global `config') */ 457 /* Lets load up our environment a little */ 458 p = getenv("OPENSSL_CONF"); 459 if (p == NULL) 460 p = getenv("SSLEAY_CONF"); 461 if (p == NULL) 462 p = to_free = make_config_name(); 463 default_config_file = p; 464 config = NCONF_new(NULL); 465 i = NCONF_load(config, p, &errline); 466 #endif 467 468 if (template != NULL) { 469 long errline = -1; 470 471 if (verbose) 472 BIO_printf(bio_err, "Using configuration from %s\n", template); 473 req_conf = NCONF_new(NULL); 474 i = NCONF_load(req_conf, template, &errline); 475 if (i == 0) { 476 BIO_printf(bio_err, "error on line %ld of %s\n", errline, 477 template); 478 goto end; 479 } 480 } else { 481 req_conf = config; 482 483 if (req_conf == NULL) { 484 BIO_printf(bio_err, "Unable to load config info from %s\n", 485 default_config_file); 486 if (newreq) 487 goto end; 488 } else if (verbose) 489 BIO_printf(bio_err, "Using configuration from %s\n", 490 default_config_file); 491 } 492 493 if (req_conf != NULL) { 494 if (!load_config(bio_err, req_conf)) 495 goto end; 496 p = NCONF_get_string(req_conf, NULL, "oid_file"); 497 if (p == NULL) 498 ERR_clear_error(); 499 if (p != NULL) { 500 BIO *oid_bio; 501 502 oid_bio = BIO_new_file(p, "r"); 503 if (oid_bio == NULL) { 504 /*- 505 BIO_printf(bio_err,"problems opening %s for extra oid's\n",p); 506 ERR_print_errors(bio_err); 507 */ 508 } else { 509 OBJ_create_objects(oid_bio); 510 BIO_free(oid_bio); 511 } 512 } 513 } 514 if (!add_oid_section(bio_err, req_conf)) 515 goto end; 516 517 if (md_alg == NULL) { 518 p = NCONF_get_string(req_conf, SECTION, "default_md"); 519 if (p == NULL) 520 ERR_clear_error(); 521 if (p != NULL) { 522 if ((md_alg = EVP_get_digestbyname(p)) != NULL) 523 digest = md_alg; 524 } 525 } 526 527 if (!extensions) { 528 extensions = NCONF_get_string(req_conf, SECTION, V3_EXTENSIONS); 529 if (!extensions) 530 ERR_clear_error(); 531 } 532 if (extensions) { 533 /* Check syntax of file */ 534 X509V3_CTX ctx; 535 X509V3_set_ctx_test(&ctx); 536 X509V3_set_nconf(&ctx, req_conf); 537 if (!X509V3_EXT_add_nconf(req_conf, &ctx, extensions, NULL)) { 538 BIO_printf(bio_err, 539 "Error Loading extension section %s\n", extensions); 540 goto end; 541 } 542 } 543 544 if (!passin) { 545 passin = NCONF_get_string(req_conf, SECTION, "input_password"); 546 if (!passin) 547 ERR_clear_error(); 548 } 549 550 if (!passout) { 551 passout = NCONF_get_string(req_conf, SECTION, "output_password"); 552 if (!passout) 553 ERR_clear_error(); 554 } 555 556 p = NCONF_get_string(req_conf, SECTION, STRING_MASK); 557 if (!p) 558 ERR_clear_error(); 559 560 if (p && !ASN1_STRING_set_default_mask_asc(p)) { 561 BIO_printf(bio_err, "Invalid global string mask setting %s\n", p); 562 goto end; 563 } 564 565 if (chtype != MBSTRING_UTF8) { 566 p = NCONF_get_string(req_conf, SECTION, UTF8_IN); 567 if (!p) 568 ERR_clear_error(); 569 else if (!strcmp(p, "yes")) 570 chtype = MBSTRING_UTF8; 571 } 572 573 if (!req_exts) { 574 req_exts = NCONF_get_string(req_conf, SECTION, REQ_EXTENSIONS); 575 if (!req_exts) 576 ERR_clear_error(); 577 } 578 if (req_exts) { 579 /* Check syntax of file */ 580 X509V3_CTX ctx; 581 X509V3_set_ctx_test(&ctx); 582 X509V3_set_nconf(&ctx, req_conf); 583 if (!X509V3_EXT_add_nconf(req_conf, &ctx, req_exts, NULL)) { 584 BIO_printf(bio_err, 585 "Error Loading request extension section %s\n", 586 req_exts); 587 goto end; 588 } 589 } 590 591 in = BIO_new(BIO_s_file()); 592 out = BIO_new(BIO_s_file()); 593 if ((in == NULL) || (out == NULL)) 594 goto end; 595 596 e = setup_engine(bio_err, engine, 0); 597 598 if (keyfile != NULL) { 599 pkey = load_key(bio_err, keyfile, keyform, 0, passin, e, 600 "Private Key"); 601 if (!pkey) { 602 /* 603 * load_key() has already printed an appropriate message 604 */ 605 goto end; 606 } else { 607 char *randfile = NCONF_get_string(req_conf, SECTION, "RANDFILE"); 608 if (randfile == NULL) 609 ERR_clear_error(); 610 app_RAND_load_file(randfile, bio_err, 0); 611 } 612 } 613 614 if (newreq && (pkey == NULL)) { 615 char *randfile = NCONF_get_string(req_conf, SECTION, "RANDFILE"); 616 if (randfile == NULL) 617 ERR_clear_error(); 618 app_RAND_load_file(randfile, bio_err, 0); 619 if (inrand) 620 app_RAND_load_files(inrand); 621 622 if (!NCONF_get_number(req_conf, SECTION, BITS, &newkey)) { 623 newkey = DEFAULT_KEY_LENGTH; 624 } 625 626 if (keyalg) { 627 genctx = set_keygen_ctx(bio_err, keyalg, &pkey_type, &newkey, 628 &keyalgstr, gen_eng); 629 if (!genctx) 630 goto end; 631 } 632 633 if (newkey < MIN_KEY_LENGTH 634 && (pkey_type == EVP_PKEY_RSA || pkey_type == EVP_PKEY_DSA)) { 635 BIO_printf(bio_err, "private key length is too short,\n"); 636 BIO_printf(bio_err, "it needs to be at least %d bits, not %ld\n", 637 MIN_KEY_LENGTH, newkey); 638 goto end; 639 } 640 641 if (!genctx) { 642 genctx = set_keygen_ctx(bio_err, NULL, &pkey_type, &newkey, 643 &keyalgstr, gen_eng); 644 if (!genctx) 645 goto end; 646 } 647 648 if (pkeyopts) { 649 char *genopt; 650 for (i = 0; i < sk_OPENSSL_STRING_num(pkeyopts); i++) { 651 genopt = sk_OPENSSL_STRING_value(pkeyopts, i); 652 if (pkey_ctrl_string(genctx, genopt) <= 0) { 653 BIO_printf(bio_err, "parameter error \"%s\"\n", genopt); 654 ERR_print_errors(bio_err); 655 goto end; 656 } 657 } 658 } 659 660 BIO_printf(bio_err, "Generating a %ld bit %s private key\n", 661 newkey, keyalgstr); 662 663 EVP_PKEY_CTX_set_cb(genctx, genpkey_cb); 664 EVP_PKEY_CTX_set_app_data(genctx, bio_err); 665 666 if (EVP_PKEY_keygen(genctx, &pkey) <= 0) { 667 BIO_puts(bio_err, "Error Generating Key\n"); 668 goto end; 669 } 670 671 EVP_PKEY_CTX_free(genctx); 672 genctx = NULL; 673 674 app_RAND_write_file(randfile, bio_err); 675 676 if (keyout == NULL) { 677 keyout = NCONF_get_string(req_conf, SECTION, KEYFILE); 678 if (keyout == NULL) 679 ERR_clear_error(); 680 } 681 682 if (keyout == NULL) { 683 BIO_printf(bio_err, "writing new private key to stdout\n"); 684 BIO_set_fp(out, stdout, BIO_NOCLOSE); 685 #ifdef OPENSSL_SYS_VMS 686 { 687 BIO *tmpbio = BIO_new(BIO_f_linebuffer()); 688 out = BIO_push(tmpbio, out); 689 } 690 #endif 691 } else { 692 BIO_printf(bio_err, "writing new private key to '%s'\n", keyout); 693 if (BIO_write_filename(out, keyout) <= 0) { 694 perror(keyout); 695 goto end; 696 } 697 } 698 699 p = NCONF_get_string(req_conf, SECTION, "encrypt_rsa_key"); 700 if (p == NULL) { 701 ERR_clear_error(); 702 p = NCONF_get_string(req_conf, SECTION, "encrypt_key"); 703 if (p == NULL) 704 ERR_clear_error(); 705 } 706 if ((p != NULL) && (strcmp(p, "no") == 0)) 707 cipher = NULL; 708 if (nodes) 709 cipher = NULL; 710 711 i = 0; 712 loop: 713 if (!PEM_write_bio_PrivateKey(out, pkey, cipher, 714 NULL, 0, NULL, passout)) { 715 if ((ERR_GET_REASON(ERR_peek_error()) == 716 PEM_R_PROBLEMS_GETTING_PASSWORD) && (i < 3)) { 717 ERR_clear_error(); 718 i++; 719 goto loop; 720 } 721 goto end; 722 } 723 BIO_printf(bio_err, "-----\n"); 724 } 725 726 if (!newreq) { 727 /* 728 * Since we are using a pre-existing certificate request, the kludge 729 * 'format' info should not be changed. 730 */ 731 kludge = -1; 732 if (infile == NULL) 733 BIO_set_fp(in, stdin, BIO_NOCLOSE); 734 else { 735 if (BIO_read_filename(in, infile) <= 0) { 736 perror(infile); 737 goto end; 738 } 739 } 740 741 if (informat == FORMAT_ASN1) 742 req = d2i_X509_REQ_bio(in, NULL); 743 else if (informat == FORMAT_PEM) 744 req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL); 745 else { 746 BIO_printf(bio_err, 747 "bad input format specified for X509 request\n"); 748 goto end; 749 } 750 if (req == NULL) { 751 BIO_printf(bio_err, "unable to load X509 request\n"); 752 goto end; 753 } 754 } 755 756 if (newreq) { 757 if (pkey == NULL) { 758 BIO_printf(bio_err, "you need to specify a private key\n"); 759 goto end; 760 } 761 762 if (req == NULL) { 763 req = X509_REQ_new(); 764 if (req == NULL) { 765 goto end; 766 } 767 768 i = make_REQ(req, pkey, subj, multirdn, !x509, chtype); 769 subj = NULL; /* done processing '-subj' option */ 770 if ((kludge > 0) 771 && !sk_X509_ATTRIBUTE_num(req->req_info->attributes)) { 772 sk_X509_ATTRIBUTE_free(req->req_info->attributes); 773 req->req_info->attributes = NULL; 774 } 775 if (!i) { 776 BIO_printf(bio_err, "problems making Certificate Request\n"); 777 goto end; 778 } 779 } 780 if (x509) { 781 EVP_PKEY *tmppkey; 782 X509V3_CTX ext_ctx; 783 if ((x509ss = X509_new()) == NULL) 784 goto end; 785 786 /* Set version to V3 */ 787 if (extensions && !X509_set_version(x509ss, 2)) 788 goto end; 789 if (serial) { 790 if (!X509_set_serialNumber(x509ss, serial)) 791 goto end; 792 } else { 793 if (!rand_serial(NULL, X509_get_serialNumber(x509ss))) 794 goto end; 795 } 796 797 if (!X509_set_issuer_name(x509ss, X509_REQ_get_subject_name(req))) 798 goto end; 799 if (!X509_gmtime_adj(X509_get_notBefore(x509ss), 0)) 800 goto end; 801 if (!X509_time_adj_ex(X509_get_notAfter(x509ss), days, 0, NULL)) 802 goto end; 803 if (!X509_set_subject_name 804 (x509ss, X509_REQ_get_subject_name(req))) 805 goto end; 806 tmppkey = X509_REQ_get_pubkey(req); 807 if (!tmppkey || !X509_set_pubkey(x509ss, tmppkey)) 808 goto end; 809 EVP_PKEY_free(tmppkey); 810 811 /* Set up V3 context struct */ 812 813 X509V3_set_ctx(&ext_ctx, x509ss, x509ss, NULL, NULL, 0); 814 X509V3_set_nconf(&ext_ctx, req_conf); 815 816 /* Add extensions */ 817 if (extensions && !X509V3_EXT_add_nconf(req_conf, 818 &ext_ctx, extensions, 819 x509ss)) { 820 BIO_printf(bio_err, "Error Loading extension section %s\n", 821 extensions); 822 goto end; 823 } 824 825 i = do_X509_sign(bio_err, x509ss, pkey, digest, sigopts); 826 if (!i) { 827 ERR_print_errors(bio_err); 828 goto end; 829 } 830 } else { 831 X509V3_CTX ext_ctx; 832 833 /* Set up V3 context struct */ 834 835 X509V3_set_ctx(&ext_ctx, NULL, NULL, req, NULL, 0); 836 X509V3_set_nconf(&ext_ctx, req_conf); 837 838 /* Add extensions */ 839 if (req_exts && !X509V3_EXT_REQ_add_nconf(req_conf, 840 &ext_ctx, req_exts, 841 req)) { 842 BIO_printf(bio_err, "Error Loading extension section %s\n", 843 req_exts); 844 goto end; 845 } 846 i = do_X509_REQ_sign(bio_err, req, pkey, digest, sigopts); 847 if (!i) { 848 ERR_print_errors(bio_err); 849 goto end; 850 } 851 } 852 } 853 854 if (subj && x509) { 855 BIO_printf(bio_err, "Cannot modifiy certificate subject\n"); 856 goto end; 857 } 858 859 if (subj && !x509) { 860 if (verbose) { 861 BIO_printf(bio_err, "Modifying Request's Subject\n"); 862 print_name(bio_err, "old subject=", 863 X509_REQ_get_subject_name(req), nmflag); 864 } 865 866 if (build_subject(req, subj, chtype, multirdn) == 0) { 867 BIO_printf(bio_err, "ERROR: cannot modify subject\n"); 868 ex = 1; 869 goto end; 870 } 871 872 req->req_info->enc.modified = 1; 873 874 if (verbose) { 875 print_name(bio_err, "new subject=", 876 X509_REQ_get_subject_name(req), nmflag); 877 } 878 } 879 880 if (verify && !x509) { 881 int tmp = 0; 882 883 if (pkey == NULL) { 884 pkey = X509_REQ_get_pubkey(req); 885 tmp = 1; 886 if (pkey == NULL) 887 goto end; 888 } 889 890 i = X509_REQ_verify(req, pkey); 891 if (tmp) { 892 EVP_PKEY_free(pkey); 893 pkey = NULL; 894 } 895 896 if (i < 0) { 897 goto end; 898 } else if (i == 0) { 899 BIO_printf(bio_err, "verify failure\n"); 900 ERR_print_errors(bio_err); 901 } else /* if (i > 0) */ 902 BIO_printf(bio_err, "verify OK\n"); 903 } 904 905 if (noout && !text && !modulus && !subject && !pubkey) { 906 ex = 0; 907 goto end; 908 } 909 910 if (outfile == NULL) { 911 BIO_set_fp(out, stdout, BIO_NOCLOSE); 912 #ifdef OPENSSL_SYS_VMS 913 { 914 BIO *tmpbio = BIO_new(BIO_f_linebuffer()); 915 out = BIO_push(tmpbio, out); 916 } 917 #endif 918 } else { 919 if ((keyout != NULL) && (strcmp(outfile, keyout) == 0)) 920 i = (int)BIO_append_filename(out, outfile); 921 else 922 i = (int)BIO_write_filename(out, outfile); 923 if (!i) { 924 perror(outfile); 925 goto end; 926 } 927 } 928 929 if (pubkey) { 930 EVP_PKEY *tpubkey; 931 tpubkey = X509_REQ_get_pubkey(req); 932 if (tpubkey == NULL) { 933 BIO_printf(bio_err, "Error getting public key\n"); 934 ERR_print_errors(bio_err); 935 goto end; 936 } 937 PEM_write_bio_PUBKEY(out, tpubkey); 938 EVP_PKEY_free(tpubkey); 939 } 940 941 if (text) { 942 if (x509) 943 X509_print_ex(out, x509ss, nmflag, reqflag); 944 else 945 X509_REQ_print_ex(out, req, nmflag, reqflag); 946 } 947 948 if (subject) { 949 if (x509) 950 print_name(out, "subject=", X509_get_subject_name(x509ss), 951 nmflag); 952 else 953 print_name(out, "subject=", X509_REQ_get_subject_name(req), 954 nmflag); 955 } 956 957 if (modulus) { 958 EVP_PKEY *tpubkey; 959 960 if (x509) 961 tpubkey = X509_get_pubkey(x509ss); 962 else 963 tpubkey = X509_REQ_get_pubkey(req); 964 if (tpubkey == NULL) { 965 fprintf(stdout, "Modulus=unavailable\n"); 966 goto end; 967 } 968 fprintf(stdout, "Modulus="); 969 #ifndef OPENSSL_NO_RSA 970 if (EVP_PKEY_base_id(tpubkey) == EVP_PKEY_RSA) 971 BN_print(out, tpubkey->pkey.rsa->n); 972 else 973 #endif 974 fprintf(stdout, "Wrong Algorithm type"); 975 EVP_PKEY_free(tpubkey); 976 fprintf(stdout, "\n"); 977 } 978 979 if (!noout && !x509) { 980 if (outformat == FORMAT_ASN1) 981 i = i2d_X509_REQ_bio(out, req); 982 else if (outformat == FORMAT_PEM) { 983 if (newhdr) 984 i = PEM_write_bio_X509_REQ_NEW(out, req); 985 else 986 i = PEM_write_bio_X509_REQ(out, req); 987 } else { 988 BIO_printf(bio_err, "bad output format specified for outfile\n"); 989 goto end; 990 } 991 if (!i) { 992 BIO_printf(bio_err, "unable to write X509 request\n"); 993 goto end; 994 } 995 } 996 if (!noout && x509 && (x509ss != NULL)) { 997 if (outformat == FORMAT_ASN1) 998 i = i2d_X509_bio(out, x509ss); 999 else if (outformat == FORMAT_PEM) 1000 i = PEM_write_bio_X509(out, x509ss); 1001 else { 1002 BIO_printf(bio_err, "bad output format specified for outfile\n"); 1003 goto end; 1004 } 1005 if (!i) { 1006 BIO_printf(bio_err, "unable to write X509 certificate\n"); 1007 goto end; 1008 } 1009 } 1010 ex = 0; 1011 end: 1012 #ifndef MONOLITH 1013 if (to_free) 1014 OPENSSL_free(to_free); 1015 #endif 1016 if (ex) { 1017 ERR_print_errors(bio_err); 1018 } 1019 if ((req_conf != NULL) && (req_conf != config)) 1020 NCONF_free(req_conf); 1021 BIO_free(in); 1022 BIO_free_all(out); 1023 EVP_PKEY_free(pkey); 1024 if (genctx) 1025 EVP_PKEY_CTX_free(genctx); 1026 if (pkeyopts) 1027 sk_OPENSSL_STRING_free(pkeyopts); 1028 if (sigopts) 1029 sk_OPENSSL_STRING_free(sigopts); 1030 #ifndef OPENSSL_NO_ENGINE 1031 if (gen_eng) 1032 ENGINE_free(gen_eng); 1033 #endif 1034 if (keyalgstr) 1035 OPENSSL_free(keyalgstr); 1036 X509_REQ_free(req); 1037 X509_free(x509ss); 1038 ASN1_INTEGER_free(serial); 1039 release_engine(e); 1040 if (passargin && passin) 1041 OPENSSL_free(passin); 1042 if (passargout && passout) 1043 OPENSSL_free(passout); 1044 OBJ_cleanup(); 1045 apps_shutdown(); 1046 OPENSSL_EXIT(ex); 1047 } 1048 1049 static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, char *subj, int multirdn, 1050 int attribs, unsigned long chtype) 1051 { 1052 int ret = 0, i; 1053 char no_prompt = 0; 1054 STACK_OF(CONF_VALUE) *dn_sk, *attr_sk = NULL; 1055 char *tmp, *dn_sect, *attr_sect; 1056 1057 tmp = NCONF_get_string(req_conf, SECTION, PROMPT); 1058 if (tmp == NULL) 1059 ERR_clear_error(); 1060 if ((tmp != NULL) && !strcmp(tmp, "no")) 1061 no_prompt = 1; 1062 1063 dn_sect = NCONF_get_string(req_conf, SECTION, DISTINGUISHED_NAME); 1064 if (dn_sect == NULL) { 1065 BIO_printf(bio_err, "unable to find '%s' in config\n", 1066 DISTINGUISHED_NAME); 1067 goto err; 1068 } 1069 dn_sk = NCONF_get_section(req_conf, dn_sect); 1070 if (dn_sk == NULL) { 1071 BIO_printf(bio_err, "unable to get '%s' section\n", dn_sect); 1072 goto err; 1073 } 1074 1075 attr_sect = NCONF_get_string(req_conf, SECTION, ATTRIBUTES); 1076 if (attr_sect == NULL) { 1077 ERR_clear_error(); 1078 attr_sk = NULL; 1079 } else { 1080 attr_sk = NCONF_get_section(req_conf, attr_sect); 1081 if (attr_sk == NULL) { 1082 BIO_printf(bio_err, "unable to get '%s' section\n", attr_sect); 1083 goto err; 1084 } 1085 } 1086 1087 /* setup version number */ 1088 if (!X509_REQ_set_version(req, 0L)) 1089 goto err; /* version 1 */ 1090 1091 if (no_prompt) 1092 i = auto_info(req, dn_sk, attr_sk, attribs, chtype); 1093 else { 1094 if (subj) 1095 i = build_subject(req, subj, chtype, multirdn); 1096 else 1097 i = prompt_info(req, dn_sk, dn_sect, attr_sk, attr_sect, attribs, 1098 chtype); 1099 } 1100 if (!i) 1101 goto err; 1102 1103 if (!X509_REQ_set_pubkey(req, pkey)) 1104 goto err; 1105 1106 ret = 1; 1107 err: 1108 return (ret); 1109 } 1110 1111 /* 1112 * subject is expected to be in the format /type0=value0/type1=value1/type2=... 1113 * where characters may be escaped by \ 1114 */ 1115 static int build_subject(X509_REQ *req, char *subject, unsigned long chtype, 1116 int multirdn) 1117 { 1118 X509_NAME *n; 1119 1120 if (!(n = parse_name(subject, chtype, multirdn))) 1121 return 0; 1122 1123 if (!X509_REQ_set_subject_name(req, n)) { 1124 X509_NAME_free(n); 1125 return 0; 1126 } 1127 X509_NAME_free(n); 1128 return 1; 1129 } 1130 1131 static int prompt_info(X509_REQ *req, 1132 STACK_OF(CONF_VALUE) *dn_sk, char *dn_sect, 1133 STACK_OF(CONF_VALUE) *attr_sk, char *attr_sect, 1134 int attribs, unsigned long chtype) 1135 { 1136 int i; 1137 char *p, *q; 1138 char buf[100]; 1139 int nid, mval; 1140 long n_min, n_max; 1141 char *type, *value; 1142 const char *def; 1143 CONF_VALUE *v; 1144 X509_NAME *subj; 1145 subj = X509_REQ_get_subject_name(req); 1146 1147 if (!batch) { 1148 BIO_printf(bio_err, 1149 "You are about to be asked to enter information that will be incorporated\n"); 1150 BIO_printf(bio_err, "into your certificate request.\n"); 1151 BIO_printf(bio_err, 1152 "What you are about to enter is what is called a Distinguished Name or a DN.\n"); 1153 BIO_printf(bio_err, 1154 "There are quite a few fields but you can leave some blank\n"); 1155 BIO_printf(bio_err, 1156 "For some fields there will be a default value,\n"); 1157 BIO_printf(bio_err, 1158 "If you enter '.', the field will be left blank.\n"); 1159 BIO_printf(bio_err, "-----\n"); 1160 } 1161 1162 if (sk_CONF_VALUE_num(dn_sk)) { 1163 i = -1; 1164 start:for (;;) { 1165 i++; 1166 if (sk_CONF_VALUE_num(dn_sk) <= i) 1167 break; 1168 1169 v = sk_CONF_VALUE_value(dn_sk, i); 1170 p = q = NULL; 1171 type = v->name; 1172 if (!check_end(type, "_min") || !check_end(type, "_max") || 1173 !check_end(type, "_default") || !check_end(type, "_value")) 1174 continue; 1175 /* 1176 * Skip past any leading X. X: X, etc to allow for multiple 1177 * instances 1178 */ 1179 for (p = v->name; *p; p++) 1180 if ((*p == ':') || (*p == ',') || (*p == '.')) { 1181 p++; 1182 if (*p) 1183 type = p; 1184 break; 1185 } 1186 if (*type == '+') { 1187 mval = -1; 1188 type++; 1189 } else 1190 mval = 0; 1191 /* If OBJ not recognised ignore it */ 1192 if ((nid = OBJ_txt2nid(type)) == NID_undef) 1193 goto start; 1194 if (BIO_snprintf(buf, sizeof buf, "%s_default", v->name) 1195 >= (int)sizeof(buf)) { 1196 BIO_printf(bio_err, "Name '%s' too long\n", v->name); 1197 return 0; 1198 } 1199 1200 if ((def = NCONF_get_string(req_conf, dn_sect, buf)) == NULL) { 1201 ERR_clear_error(); 1202 def = ""; 1203 } 1204 1205 BIO_snprintf(buf, sizeof buf, "%s_value", v->name); 1206 if ((value = NCONF_get_string(req_conf, dn_sect, buf)) == NULL) { 1207 ERR_clear_error(); 1208 value = NULL; 1209 } 1210 1211 BIO_snprintf(buf, sizeof buf, "%s_min", v->name); 1212 if (!NCONF_get_number(req_conf, dn_sect, buf, &n_min)) { 1213 ERR_clear_error(); 1214 n_min = -1; 1215 } 1216 1217 BIO_snprintf(buf, sizeof buf, "%s_max", v->name); 1218 if (!NCONF_get_number(req_conf, dn_sect, buf, &n_max)) { 1219 ERR_clear_error(); 1220 n_max = -1; 1221 } 1222 1223 if (!add_DN_object(subj, v->value, def, value, nid, 1224 n_min, n_max, chtype, mval)) 1225 return 0; 1226 } 1227 if (X509_NAME_entry_count(subj) == 0) { 1228 BIO_printf(bio_err, 1229 "error, no objects specified in config file\n"); 1230 return 0; 1231 } 1232 1233 if (attribs) { 1234 if ((attr_sk != NULL) && (sk_CONF_VALUE_num(attr_sk) > 0) 1235 && (!batch)) { 1236 BIO_printf(bio_err, 1237 "\nPlease enter the following 'extra' attributes\n"); 1238 BIO_printf(bio_err, 1239 "to be sent with your certificate request\n"); 1240 } 1241 1242 i = -1; 1243 start2: for (;;) { 1244 i++; 1245 if ((attr_sk == NULL) || (sk_CONF_VALUE_num(attr_sk) <= i)) 1246 break; 1247 1248 v = sk_CONF_VALUE_value(attr_sk, i); 1249 type = v->name; 1250 if ((nid = OBJ_txt2nid(type)) == NID_undef) 1251 goto start2; 1252 1253 if (BIO_snprintf(buf, sizeof buf, "%s_default", type) 1254 >= (int)sizeof(buf)) { 1255 BIO_printf(bio_err, "Name '%s' too long\n", v->name); 1256 return 0; 1257 } 1258 1259 if ((def = NCONF_get_string(req_conf, attr_sect, buf)) 1260 == NULL) { 1261 ERR_clear_error(); 1262 def = ""; 1263 } 1264 1265 BIO_snprintf(buf, sizeof buf, "%s_value", type); 1266 if ((value = NCONF_get_string(req_conf, attr_sect, buf)) 1267 == NULL) { 1268 ERR_clear_error(); 1269 value = NULL; 1270 } 1271 1272 BIO_snprintf(buf, sizeof buf, "%s_min", type); 1273 if (!NCONF_get_number(req_conf, attr_sect, buf, &n_min)) { 1274 ERR_clear_error(); 1275 n_min = -1; 1276 } 1277 1278 BIO_snprintf(buf, sizeof buf, "%s_max", type); 1279 if (!NCONF_get_number(req_conf, attr_sect, buf, &n_max)) { 1280 ERR_clear_error(); 1281 n_max = -1; 1282 } 1283 1284 if (!add_attribute_object(req, 1285 v->value, def, value, nid, n_min, 1286 n_max, chtype)) 1287 return 0; 1288 } 1289 } 1290 } else { 1291 BIO_printf(bio_err, "No template, please set one up.\n"); 1292 return 0; 1293 } 1294 1295 return 1; 1296 1297 } 1298 1299 static int auto_info(X509_REQ *req, STACK_OF(CONF_VALUE) *dn_sk, 1300 STACK_OF(CONF_VALUE) *attr_sk, int attribs, 1301 unsigned long chtype) 1302 { 1303 int i; 1304 char *p, *q; 1305 char *type; 1306 CONF_VALUE *v; 1307 X509_NAME *subj; 1308 1309 subj = X509_REQ_get_subject_name(req); 1310 1311 for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) { 1312 int mval; 1313 v = sk_CONF_VALUE_value(dn_sk, i); 1314 p = q = NULL; 1315 type = v->name; 1316 /* 1317 * Skip past any leading X. X: X, etc to allow for multiple instances 1318 */ 1319 for (p = v->name; *p; p++) 1320 #ifndef CHARSET_EBCDIC 1321 if ((*p == ':') || (*p == ',') || (*p == '.')) { 1322 #else 1323 if ((*p == os_toascii[':']) || (*p == os_toascii[',']) 1324 || (*p == os_toascii['.'])) { 1325 #endif 1326 p++; 1327 if (*p) 1328 type = p; 1329 break; 1330 } 1331 #ifndef CHARSET_EBCDIC 1332 if (*type == '+') { 1333 #else 1334 if (*type == os_toascii['+']) { 1335 #endif 1336 type++; 1337 mval = -1; 1338 } else 1339 mval = 0; 1340 if (!X509_NAME_add_entry_by_txt(subj, type, chtype, 1341 (unsigned char *)v->value, -1, -1, 1342 mval)) 1343 return 0; 1344 1345 } 1346 1347 if (!X509_NAME_entry_count(subj)) { 1348 BIO_printf(bio_err, "error, no objects specified in config file\n"); 1349 return 0; 1350 } 1351 if (attribs) { 1352 for (i = 0; i < sk_CONF_VALUE_num(attr_sk); i++) { 1353 v = sk_CONF_VALUE_value(attr_sk, i); 1354 if (!X509_REQ_add1_attr_by_txt(req, v->name, chtype, 1355 (unsigned char *)v->value, -1)) 1356 return 0; 1357 } 1358 } 1359 return 1; 1360 } 1361 1362 static int add_DN_object(X509_NAME *n, char *text, const char *def, 1363 char *value, int nid, int n_min, int n_max, 1364 unsigned long chtype, int mval) 1365 { 1366 int i, ret = 0; 1367 MS_STATIC char buf[1024]; 1368 start: 1369 if (!batch) 1370 BIO_printf(bio_err, "%s [%s]:", text, def); 1371 (void)BIO_flush(bio_err); 1372 if (value != NULL) { 1373 BUF_strlcpy(buf, value, sizeof buf); 1374 BUF_strlcat(buf, "\n", sizeof buf); 1375 BIO_printf(bio_err, "%s\n", value); 1376 } else { 1377 buf[0] = '\0'; 1378 if (!batch) { 1379 if (!fgets(buf, sizeof buf, stdin)) 1380 return 0; 1381 } else { 1382 buf[0] = '\n'; 1383 buf[1] = '\0'; 1384 } 1385 } 1386 1387 if (buf[0] == '\0') 1388 return (0); 1389 else if (buf[0] == '\n') { 1390 if ((def == NULL) || (def[0] == '\0')) 1391 return (1); 1392 BUF_strlcpy(buf, def, sizeof buf); 1393 BUF_strlcat(buf, "\n", sizeof buf); 1394 } else if ((buf[0] == '.') && (buf[1] == '\n')) 1395 return (1); 1396 1397 i = strlen(buf); 1398 if (buf[i - 1] != '\n') { 1399 BIO_printf(bio_err, "weird input :-(\n"); 1400 return (0); 1401 } 1402 buf[--i] = '\0'; 1403 #ifdef CHARSET_EBCDIC 1404 ebcdic2ascii(buf, buf, i); 1405 #endif 1406 if (!req_check_len(i, n_min, n_max)) { 1407 if (batch || value) 1408 return 0; 1409 goto start; 1410 } 1411 1412 if (!X509_NAME_add_entry_by_NID(n, nid, chtype, 1413 (unsigned char *)buf, -1, -1, mval)) 1414 goto err; 1415 ret = 1; 1416 err: 1417 return (ret); 1418 } 1419 1420 static int add_attribute_object(X509_REQ *req, char *text, const char *def, 1421 char *value, int nid, int n_min, 1422 int n_max, unsigned long chtype) 1423 { 1424 int i; 1425 static char buf[1024]; 1426 1427 start: 1428 if (!batch) 1429 BIO_printf(bio_err, "%s [%s]:", text, def); 1430 (void)BIO_flush(bio_err); 1431 if (value != NULL) { 1432 BUF_strlcpy(buf, value, sizeof buf); 1433 BUF_strlcat(buf, "\n", sizeof buf); 1434 BIO_printf(bio_err, "%s\n", value); 1435 } else { 1436 buf[0] = '\0'; 1437 if (!batch) { 1438 if (!fgets(buf, sizeof buf, stdin)) 1439 return 0; 1440 } else { 1441 buf[0] = '\n'; 1442 buf[1] = '\0'; 1443 } 1444 } 1445 1446 if (buf[0] == '\0') 1447 return (0); 1448 else if (buf[0] == '\n') { 1449 if ((def == NULL) || (def[0] == '\0')) 1450 return (1); 1451 BUF_strlcpy(buf, def, sizeof buf); 1452 BUF_strlcat(buf, "\n", sizeof buf); 1453 } else if ((buf[0] == '.') && (buf[1] == '\n')) 1454 return (1); 1455 1456 i = strlen(buf); 1457 if (buf[i - 1] != '\n') { 1458 BIO_printf(bio_err, "weird input :-(\n"); 1459 return (0); 1460 } 1461 buf[--i] = '\0'; 1462 #ifdef CHARSET_EBCDIC 1463 ebcdic2ascii(buf, buf, i); 1464 #endif 1465 if (!req_check_len(i, n_min, n_max)) { 1466 if (batch || value) 1467 return 0; 1468 goto start; 1469 } 1470 1471 if (!X509_REQ_add1_attr_by_NID(req, nid, chtype, 1472 (unsigned char *)buf, -1)) { 1473 BIO_printf(bio_err, "Error adding attribute\n"); 1474 ERR_print_errors(bio_err); 1475 goto err; 1476 } 1477 1478 return (1); 1479 err: 1480 return (0); 1481 } 1482 1483 static int req_check_len(int len, int n_min, int n_max) 1484 { 1485 if ((n_min > 0) && (len < n_min)) { 1486 BIO_printf(bio_err, 1487 "string is too short, it needs to be at least %d bytes long\n", 1488 n_min); 1489 return (0); 1490 } 1491 if ((n_max >= 0) && (len > n_max)) { 1492 BIO_printf(bio_err, 1493 "string is too long, it needs to be less than %d bytes long\n", 1494 n_max); 1495 return (0); 1496 } 1497 return (1); 1498 } 1499 1500 /* Check if the end of a string matches 'end' */ 1501 static int check_end(const char *str, const char *end) 1502 { 1503 int elen, slen; 1504 const char *tmp; 1505 elen = strlen(end); 1506 slen = strlen(str); 1507 if (elen > slen) 1508 return 1; 1509 tmp = str + slen - elen; 1510 return strcmp(tmp, end); 1511 } 1512 1513 static EVP_PKEY_CTX *set_keygen_ctx(BIO *err, const char *gstr, 1514 int *pkey_type, long *pkeylen, 1515 char **palgnam, ENGINE *keygen_engine) 1516 { 1517 EVP_PKEY_CTX *gctx = NULL; 1518 EVP_PKEY *param = NULL; 1519 long keylen = -1; 1520 BIO *pbio = NULL; 1521 const char *paramfile = NULL; 1522 1523 if (gstr == NULL) { 1524 *pkey_type = EVP_PKEY_RSA; 1525 keylen = *pkeylen; 1526 } else if (gstr[0] >= '0' && gstr[0] <= '9') { 1527 *pkey_type = EVP_PKEY_RSA; 1528 keylen = atol(gstr); 1529 *pkeylen = keylen; 1530 } else if (!strncmp(gstr, "param:", 6)) 1531 paramfile = gstr + 6; 1532 else { 1533 const char *p = strchr(gstr, ':'); 1534 int len; 1535 ENGINE *tmpeng; 1536 const EVP_PKEY_ASN1_METHOD *ameth; 1537 1538 if (p) 1539 len = p - gstr; 1540 else 1541 len = strlen(gstr); 1542 /* 1543 * The lookup of a the string will cover all engines so keep a note 1544 * of the implementation. 1545 */ 1546 1547 ameth = EVP_PKEY_asn1_find_str(&tmpeng, gstr, len); 1548 1549 if (!ameth) { 1550 BIO_printf(err, "Unknown algorithm %.*s\n", len, gstr); 1551 return NULL; 1552 } 1553 1554 EVP_PKEY_asn1_get0_info(NULL, pkey_type, NULL, NULL, NULL, ameth); 1555 #ifndef OPENSSL_NO_ENGINE 1556 if (tmpeng) 1557 ENGINE_finish(tmpeng); 1558 #endif 1559 if (*pkey_type == EVP_PKEY_RSA) { 1560 if (p) { 1561 keylen = atol(p + 1); 1562 *pkeylen = keylen; 1563 } else 1564 keylen = *pkeylen; 1565 } else if (p) 1566 paramfile = p + 1; 1567 } 1568 1569 if (paramfile) { 1570 pbio = BIO_new_file(paramfile, "r"); 1571 if (!pbio) { 1572 BIO_printf(err, "Can't open parameter file %s\n", paramfile); 1573 return NULL; 1574 } 1575 param = PEM_read_bio_Parameters(pbio, NULL); 1576 1577 if (!param) { 1578 X509 *x; 1579 (void)BIO_reset(pbio); 1580 x = PEM_read_bio_X509(pbio, NULL, NULL, NULL); 1581 if (x) { 1582 param = X509_get_pubkey(x); 1583 X509_free(x); 1584 } 1585 } 1586 1587 BIO_free(pbio); 1588 1589 if (!param) { 1590 BIO_printf(err, "Error reading parameter file %s\n", paramfile); 1591 return NULL; 1592 } 1593 if (*pkey_type == -1) 1594 *pkey_type = EVP_PKEY_id(param); 1595 else if (*pkey_type != EVP_PKEY_base_id(param)) { 1596 BIO_printf(err, "Key Type does not match parameters\n"); 1597 EVP_PKEY_free(param); 1598 return NULL; 1599 } 1600 } 1601 1602 if (palgnam) { 1603 const EVP_PKEY_ASN1_METHOD *ameth; 1604 ENGINE *tmpeng; 1605 const char *anam; 1606 ameth = EVP_PKEY_asn1_find(&tmpeng, *pkey_type); 1607 if (!ameth) { 1608 BIO_puts(err, "Internal error: can't find key algorithm\n"); 1609 return NULL; 1610 } 1611 EVP_PKEY_asn1_get0_info(NULL, NULL, NULL, NULL, &anam, ameth); 1612 *palgnam = BUF_strdup(anam); 1613 #ifndef OPENSSL_NO_ENGINE 1614 if (tmpeng) 1615 ENGINE_finish(tmpeng); 1616 #endif 1617 } 1618 1619 if (param) { 1620 gctx = EVP_PKEY_CTX_new(param, keygen_engine); 1621 *pkeylen = EVP_PKEY_bits(param); 1622 EVP_PKEY_free(param); 1623 } else 1624 gctx = EVP_PKEY_CTX_new_id(*pkey_type, keygen_engine); 1625 1626 if (!gctx) { 1627 BIO_puts(err, "Error allocating keygen context\n"); 1628 ERR_print_errors(err); 1629 return NULL; 1630 } 1631 1632 if (EVP_PKEY_keygen_init(gctx) <= 0) { 1633 BIO_puts(err, "Error initializing keygen context\n"); 1634 ERR_print_errors(err); 1635 return NULL; 1636 } 1637 #ifndef OPENSSL_NO_RSA 1638 if ((*pkey_type == EVP_PKEY_RSA) && (keylen != -1)) { 1639 if (EVP_PKEY_CTX_set_rsa_keygen_bits(gctx, keylen) <= 0) { 1640 BIO_puts(err, "Error setting RSA keysize\n"); 1641 ERR_print_errors(err); 1642 EVP_PKEY_CTX_free(gctx); 1643 return NULL; 1644 } 1645 } 1646 #endif 1647 1648 return gctx; 1649 } 1650 1651 static int genpkey_cb(EVP_PKEY_CTX *ctx) 1652 { 1653 char c = '*'; 1654 BIO *b = EVP_PKEY_CTX_get_app_data(ctx); 1655 int p; 1656 p = EVP_PKEY_CTX_get_keygen_info(ctx, 0); 1657 if (p == 0) 1658 c = '.'; 1659 if (p == 1) 1660 c = '+'; 1661 if (p == 2) 1662 c = '*'; 1663 if (p == 3) 1664 c = '\n'; 1665 BIO_write(b, &c, 1); 1666 (void)BIO_flush(b); 1667 #ifdef LINT 1668 p = n; 1669 #endif 1670 return 1; 1671 } 1672 1673 static int do_sign_init(BIO *err, EVP_MD_CTX *ctx, EVP_PKEY *pkey, 1674 const EVP_MD *md, STACK_OF(OPENSSL_STRING) *sigopts) 1675 { 1676 EVP_PKEY_CTX *pkctx = NULL; 1677 int i; 1678 EVP_MD_CTX_init(ctx); 1679 if (!EVP_DigestSignInit(ctx, &pkctx, md, NULL, pkey)) 1680 return 0; 1681 for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) { 1682 char *sigopt = sk_OPENSSL_STRING_value(sigopts, i); 1683 if (pkey_ctrl_string(pkctx, sigopt) <= 0) { 1684 BIO_printf(err, "parameter error \"%s\"\n", sigopt); 1685 ERR_print_errors(bio_err); 1686 return 0; 1687 } 1688 } 1689 return 1; 1690 } 1691 1692 int do_X509_sign(BIO *err, X509 *x, EVP_PKEY *pkey, const EVP_MD *md, 1693 STACK_OF(OPENSSL_STRING) *sigopts) 1694 { 1695 int rv; 1696 EVP_MD_CTX mctx; 1697 EVP_MD_CTX_init(&mctx); 1698 rv = do_sign_init(err, &mctx, pkey, md, sigopts); 1699 if (rv > 0) 1700 rv = X509_sign_ctx(x, &mctx); 1701 EVP_MD_CTX_cleanup(&mctx); 1702 return rv > 0 ? 1 : 0; 1703 } 1704 1705 int do_X509_REQ_sign(BIO *err, X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md, 1706 STACK_OF(OPENSSL_STRING) *sigopts) 1707 { 1708 int rv; 1709 EVP_MD_CTX mctx; 1710 EVP_MD_CTX_init(&mctx); 1711 rv = do_sign_init(err, &mctx, pkey, md, sigopts); 1712 if (rv > 0) 1713 rv = X509_REQ_sign_ctx(x, &mctx); 1714 EVP_MD_CTX_cleanup(&mctx); 1715 return rv > 0 ? 1 : 0; 1716 } 1717 1718 int do_X509_CRL_sign(BIO *err, X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md, 1719 STACK_OF(OPENSSL_STRING) *sigopts) 1720 { 1721 int rv; 1722 EVP_MD_CTX mctx; 1723 EVP_MD_CTX_init(&mctx); 1724 rv = do_sign_init(err, &mctx, pkey, md, sigopts); 1725 if (rv > 0) 1726 rv = X509_CRL_sign_ctx(x, &mctx); 1727 EVP_MD_CTX_cleanup(&mctx); 1728 return rv > 0 ? 1 : 0; 1729 } 1730