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