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