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