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 else 723 { 724 char *randfile = NCONF_get_string(req_conf,SECTION,"RANDFILE"); 725 if (randfile == NULL) 726 ERR_clear_error(); 727 app_RAND_load_file(randfile, bio_err, 0); 728 } 729 } 730 731 if (newreq && (pkey == NULL)) 732 { 733 #ifndef OPENSSL_NO_RSA 734 BN_GENCB cb; 735 #endif 736 char *randfile = NCONF_get_string(req_conf,SECTION,"RANDFILE"); 737 if (randfile == NULL) 738 ERR_clear_error(); 739 app_RAND_load_file(randfile, bio_err, 0); 740 if (inrand) 741 app_RAND_load_files(inrand); 742 743 if (newkey <= 0) 744 { 745 if (!NCONF_get_number(req_conf,SECTION,BITS, &newkey)) 746 newkey=DEFAULT_KEY_LENGTH; 747 } 748 749 if (newkey < MIN_KEY_LENGTH && (pkey_type == TYPE_RSA || pkey_type == TYPE_DSA)) 750 { 751 BIO_printf(bio_err,"private key length is too short,\n"); 752 BIO_printf(bio_err,"it needs to be at least %d bits, not %ld\n",MIN_KEY_LENGTH,newkey); 753 goto end; 754 } 755 BIO_printf(bio_err,"Generating a %ld bit %s private key\n", 756 newkey,(pkey_type == TYPE_RSA)?"RSA": 757 (pkey_type == TYPE_DSA)?"DSA":"EC"); 758 759 if ((pkey=EVP_PKEY_new()) == NULL) goto end; 760 761 #ifndef OPENSSL_NO_RSA 762 BN_GENCB_set(&cb, req_cb, bio_err); 763 if (pkey_type == TYPE_RSA) 764 { 765 RSA *rsa = RSA_new(); 766 BIGNUM *bn = BN_new(); 767 if(!bn || !rsa || !BN_set_word(bn, 0x10001) || 768 !RSA_generate_key_ex(rsa, newkey, bn, &cb) || 769 !EVP_PKEY_assign_RSA(pkey, rsa)) 770 { 771 if(bn) BN_free(bn); 772 if(rsa) RSA_free(rsa); 773 goto end; 774 } 775 BN_free(bn); 776 } 777 else 778 #endif 779 #ifndef OPENSSL_NO_DSA 780 if (pkey_type == TYPE_DSA) 781 { 782 if (!DSA_generate_key(dsa_params)) goto end; 783 if (!EVP_PKEY_assign_DSA(pkey,dsa_params)) goto end; 784 dsa_params=NULL; 785 } 786 #endif 787 #ifndef OPENSSL_NO_ECDSA 788 if (pkey_type == TYPE_EC) 789 { 790 if (!EC_KEY_generate_key(ec_params)) goto end; 791 if (!EVP_PKEY_assign_EC_KEY(pkey, ec_params)) 792 goto end; 793 ec_params = NULL; 794 } 795 #endif 796 797 app_RAND_write_file(randfile, bio_err); 798 799 if (pkey == NULL) goto end; 800 801 if (keyout == NULL) 802 { 803 keyout=NCONF_get_string(req_conf,SECTION,KEYFILE); 804 if (keyout == NULL) 805 ERR_clear_error(); 806 } 807 808 if (keyout == NULL) 809 { 810 BIO_printf(bio_err,"writing new private key to stdout\n"); 811 BIO_set_fp(out,stdout,BIO_NOCLOSE); 812 #ifdef OPENSSL_SYS_VMS 813 { 814 BIO *tmpbio = BIO_new(BIO_f_linebuffer()); 815 out = BIO_push(tmpbio, out); 816 } 817 #endif 818 } 819 else 820 { 821 BIO_printf(bio_err,"writing new private key to '%s'\n",keyout); 822 if (BIO_write_filename(out,keyout) <= 0) 823 { 824 perror(keyout); 825 goto end; 826 } 827 } 828 829 p=NCONF_get_string(req_conf,SECTION,"encrypt_rsa_key"); 830 if (p == NULL) 831 { 832 ERR_clear_error(); 833 p=NCONF_get_string(req_conf,SECTION,"encrypt_key"); 834 if (p == NULL) 835 ERR_clear_error(); 836 } 837 if ((p != NULL) && (strcmp(p,"no") == 0)) 838 cipher=NULL; 839 if (nodes) cipher=NULL; 840 841 i=0; 842 loop: 843 if (!PEM_write_bio_PrivateKey(out,pkey,cipher, 844 NULL,0,NULL,passout)) 845 { 846 if ((ERR_GET_REASON(ERR_peek_error()) == 847 PEM_R_PROBLEMS_GETTING_PASSWORD) && (i < 3)) 848 { 849 ERR_clear_error(); 850 i++; 851 goto loop; 852 } 853 goto end; 854 } 855 BIO_printf(bio_err,"-----\n"); 856 } 857 858 if (!newreq) 859 { 860 /* Since we are using a pre-existing certificate 861 * request, the kludge 'format' info should not be 862 * changed. */ 863 kludge= -1; 864 if (infile == NULL) 865 BIO_set_fp(in,stdin,BIO_NOCLOSE); 866 else 867 { 868 if (BIO_read_filename(in,infile) <= 0) 869 { 870 perror(infile); 871 goto end; 872 } 873 } 874 875 if (informat == FORMAT_ASN1) 876 req=d2i_X509_REQ_bio(in,NULL); 877 else if (informat == FORMAT_PEM) 878 req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL); 879 else 880 { 881 BIO_printf(bio_err,"bad input format specified for X509 request\n"); 882 goto end; 883 } 884 if (req == NULL) 885 { 886 BIO_printf(bio_err,"unable to load X509 request\n"); 887 goto end; 888 } 889 } 890 891 if (newreq || x509) 892 { 893 if (pkey == NULL) 894 { 895 BIO_printf(bio_err,"you need to specify a private key\n"); 896 goto end; 897 } 898 #ifndef OPENSSL_NO_DSA 899 if (pkey->type == EVP_PKEY_DSA) 900 digest=EVP_dss1(); 901 #endif 902 #ifndef OPENSSL_NO_ECDSA 903 if (pkey->type == EVP_PKEY_EC) 904 digest=EVP_ecdsa(); 905 #endif 906 if (req == NULL) 907 { 908 req=X509_REQ_new(); 909 if (req == NULL) 910 { 911 goto end; 912 } 913 914 i=make_REQ(req,pkey,subj,multirdn,!x509, chtype); 915 subj=NULL; /* done processing '-subj' option */ 916 if ((kludge > 0) && !sk_X509_ATTRIBUTE_num(req->req_info->attributes)) 917 { 918 sk_X509_ATTRIBUTE_free(req->req_info->attributes); 919 req->req_info->attributes = NULL; 920 } 921 if (!i) 922 { 923 BIO_printf(bio_err,"problems making Certificate Request\n"); 924 goto end; 925 } 926 } 927 if (x509) 928 { 929 EVP_PKEY *tmppkey; 930 X509V3_CTX ext_ctx; 931 if ((x509ss=X509_new()) == NULL) goto end; 932 933 /* Set version to V3 */ 934 if(extensions && !X509_set_version(x509ss, 2)) goto end; 935 if (serial) 936 { 937 if (!X509_set_serialNumber(x509ss, serial)) goto end; 938 } 939 else 940 { 941 if (!rand_serial(NULL, 942 X509_get_serialNumber(x509ss))) 943 goto end; 944 } 945 946 if (!X509_set_issuer_name(x509ss, X509_REQ_get_subject_name(req))) goto end; 947 if (!X509_gmtime_adj(X509_get_notBefore(x509ss),0)) goto end; 948 if (!X509_gmtime_adj(X509_get_notAfter(x509ss), (long)60*60*24*days)) goto end; 949 if (!X509_set_subject_name(x509ss, X509_REQ_get_subject_name(req))) goto end; 950 tmppkey = X509_REQ_get_pubkey(req); 951 if (!tmppkey || !X509_set_pubkey(x509ss,tmppkey)) goto end; 952 EVP_PKEY_free(tmppkey); 953 954 /* Set up V3 context struct */ 955 956 X509V3_set_ctx(&ext_ctx, x509ss, x509ss, NULL, NULL, 0); 957 X509V3_set_nconf(&ext_ctx, req_conf); 958 959 /* Add extensions */ 960 if(extensions && !X509V3_EXT_add_nconf(req_conf, 961 &ext_ctx, extensions, x509ss)) 962 { 963 BIO_printf(bio_err, 964 "Error Loading extension section %s\n", 965 extensions); 966 goto end; 967 } 968 969 if (!(i=X509_sign(x509ss,pkey,digest))) 970 goto end; 971 } 972 else 973 { 974 X509V3_CTX ext_ctx; 975 976 /* Set up V3 context struct */ 977 978 X509V3_set_ctx(&ext_ctx, NULL, NULL, req, NULL, 0); 979 X509V3_set_nconf(&ext_ctx, req_conf); 980 981 /* Add extensions */ 982 if(req_exts && !X509V3_EXT_REQ_add_nconf(req_conf, 983 &ext_ctx, req_exts, req)) 984 { 985 BIO_printf(bio_err, 986 "Error Loading extension section %s\n", 987 req_exts); 988 goto end; 989 } 990 if (!(i=X509_REQ_sign(req,pkey,digest))) 991 goto end; 992 } 993 } 994 995 if (subj && x509) 996 { 997 BIO_printf(bio_err, "Cannot modifiy certificate subject\n"); 998 goto end; 999 } 1000 1001 if (subj && !x509) 1002 { 1003 if (verbose) 1004 { 1005 BIO_printf(bio_err, "Modifying Request's Subject\n"); 1006 print_name(bio_err, "old subject=", X509_REQ_get_subject_name(req), nmflag); 1007 } 1008 1009 if (build_subject(req, subj, chtype, multirdn) == 0) 1010 { 1011 BIO_printf(bio_err, "ERROR: cannot modify subject\n"); 1012 ex=1; 1013 goto end; 1014 } 1015 1016 req->req_info->enc.modified = 1; 1017 1018 if (verbose) 1019 { 1020 print_name(bio_err, "new subject=", X509_REQ_get_subject_name(req), nmflag); 1021 } 1022 } 1023 1024 if (verify && !x509) 1025 { 1026 int tmp=0; 1027 1028 if (pkey == NULL) 1029 { 1030 pkey=X509_REQ_get_pubkey(req); 1031 tmp=1; 1032 if (pkey == NULL) goto end; 1033 } 1034 1035 i=X509_REQ_verify(req,pkey); 1036 if (tmp) { 1037 EVP_PKEY_free(pkey); 1038 pkey=NULL; 1039 } 1040 1041 if (i < 0) 1042 { 1043 goto end; 1044 } 1045 else if (i == 0) 1046 { 1047 BIO_printf(bio_err,"verify failure\n"); 1048 ERR_print_errors(bio_err); 1049 } 1050 else /* if (i > 0) */ 1051 BIO_printf(bio_err,"verify OK\n"); 1052 } 1053 1054 if (noout && !text && !modulus && !subject && !pubkey) 1055 { 1056 ex=0; 1057 goto end; 1058 } 1059 1060 if (outfile == NULL) 1061 { 1062 BIO_set_fp(out,stdout,BIO_NOCLOSE); 1063 #ifdef OPENSSL_SYS_VMS 1064 { 1065 BIO *tmpbio = BIO_new(BIO_f_linebuffer()); 1066 out = BIO_push(tmpbio, out); 1067 } 1068 #endif 1069 } 1070 else 1071 { 1072 if ((keyout != NULL) && (strcmp(outfile,keyout) == 0)) 1073 i=(int)BIO_append_filename(out,outfile); 1074 else 1075 i=(int)BIO_write_filename(out,outfile); 1076 if (!i) 1077 { 1078 perror(outfile); 1079 goto end; 1080 } 1081 } 1082 1083 if (pubkey) 1084 { 1085 EVP_PKEY *tpubkey; 1086 tpubkey=X509_REQ_get_pubkey(req); 1087 if (tpubkey == NULL) 1088 { 1089 BIO_printf(bio_err,"Error getting public key\n"); 1090 ERR_print_errors(bio_err); 1091 goto end; 1092 } 1093 PEM_write_bio_PUBKEY(out, tpubkey); 1094 EVP_PKEY_free(tpubkey); 1095 } 1096 1097 if (text) 1098 { 1099 if (x509) 1100 X509_print_ex(out, x509ss, nmflag, reqflag); 1101 else 1102 X509_REQ_print_ex(out, req, nmflag, reqflag); 1103 } 1104 1105 if(subject) 1106 { 1107 if(x509) 1108 print_name(out, "subject=", X509_get_subject_name(x509ss), nmflag); 1109 else 1110 print_name(out, "subject=", X509_REQ_get_subject_name(req), nmflag); 1111 } 1112 1113 if (modulus) 1114 { 1115 EVP_PKEY *tpubkey; 1116 1117 if (x509) 1118 tpubkey=X509_get_pubkey(x509ss); 1119 else 1120 tpubkey=X509_REQ_get_pubkey(req); 1121 if (tpubkey == NULL) 1122 { 1123 fprintf(stdout,"Modulus=unavailable\n"); 1124 goto end; 1125 } 1126 fprintf(stdout,"Modulus="); 1127 #ifndef OPENSSL_NO_RSA 1128 if (tpubkey->type == EVP_PKEY_RSA) 1129 BN_print(out,tpubkey->pkey.rsa->n); 1130 else 1131 #endif 1132 fprintf(stdout,"Wrong Algorithm type"); 1133 EVP_PKEY_free(tpubkey); 1134 fprintf(stdout,"\n"); 1135 } 1136 1137 if (!noout && !x509) 1138 { 1139 if (outformat == FORMAT_ASN1) 1140 i=i2d_X509_REQ_bio(out,req); 1141 else if (outformat == FORMAT_PEM) { 1142 if(newhdr) i=PEM_write_bio_X509_REQ_NEW(out,req); 1143 else i=PEM_write_bio_X509_REQ(out,req); 1144 } else { 1145 BIO_printf(bio_err,"bad output format specified for outfile\n"); 1146 goto end; 1147 } 1148 if (!i) 1149 { 1150 BIO_printf(bio_err,"unable to write X509 request\n"); 1151 goto end; 1152 } 1153 } 1154 if (!noout && x509 && (x509ss != NULL)) 1155 { 1156 if (outformat == FORMAT_ASN1) 1157 i=i2d_X509_bio(out,x509ss); 1158 else if (outformat == FORMAT_PEM) 1159 i=PEM_write_bio_X509(out,x509ss); 1160 else { 1161 BIO_printf(bio_err,"bad output format specified for outfile\n"); 1162 goto end; 1163 } 1164 if (!i) 1165 { 1166 BIO_printf(bio_err,"unable to write X509 certificate\n"); 1167 goto end; 1168 } 1169 } 1170 ex=0; 1171 end: 1172 #ifndef MONOLITH 1173 if(to_free) 1174 OPENSSL_free(to_free); 1175 #endif 1176 if (ex) 1177 { 1178 ERR_print_errors(bio_err); 1179 } 1180 if ((req_conf != NULL) && (req_conf != config)) NCONF_free(req_conf); 1181 BIO_free(in); 1182 BIO_free_all(out); 1183 EVP_PKEY_free(pkey); 1184 X509_REQ_free(req); 1185 X509_free(x509ss); 1186 ASN1_INTEGER_free(serial); 1187 if(passargin && passin) OPENSSL_free(passin); 1188 if(passargout && passout) OPENSSL_free(passout); 1189 OBJ_cleanup(); 1190 #ifndef OPENSSL_NO_DSA 1191 if (dsa_params != NULL) DSA_free(dsa_params); 1192 #endif 1193 #ifndef OPENSSL_NO_ECDSA 1194 if (ec_params != NULL) EC_KEY_free(ec_params); 1195 #endif 1196 apps_shutdown(); 1197 OPENSSL_EXIT(ex); 1198 } 1199 1200 static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, char *subj, int multirdn, 1201 int attribs, unsigned long chtype) 1202 { 1203 int ret=0,i; 1204 char no_prompt = 0; 1205 STACK_OF(CONF_VALUE) *dn_sk, *attr_sk = NULL; 1206 char *tmp, *dn_sect,*attr_sect; 1207 1208 tmp=NCONF_get_string(req_conf,SECTION,PROMPT); 1209 if (tmp == NULL) 1210 ERR_clear_error(); 1211 if((tmp != NULL) && !strcmp(tmp, "no")) no_prompt = 1; 1212 1213 dn_sect=NCONF_get_string(req_conf,SECTION,DISTINGUISHED_NAME); 1214 if (dn_sect == NULL) 1215 { 1216 BIO_printf(bio_err,"unable to find '%s' in config\n", 1217 DISTINGUISHED_NAME); 1218 goto err; 1219 } 1220 dn_sk=NCONF_get_section(req_conf,dn_sect); 1221 if (dn_sk == NULL) 1222 { 1223 BIO_printf(bio_err,"unable to get '%s' section\n",dn_sect); 1224 goto err; 1225 } 1226 1227 attr_sect=NCONF_get_string(req_conf,SECTION,ATTRIBUTES); 1228 if (attr_sect == NULL) 1229 { 1230 ERR_clear_error(); 1231 attr_sk=NULL; 1232 } 1233 else 1234 { 1235 attr_sk=NCONF_get_section(req_conf,attr_sect); 1236 if (attr_sk == NULL) 1237 { 1238 BIO_printf(bio_err,"unable to get '%s' section\n",attr_sect); 1239 goto err; 1240 } 1241 } 1242 1243 /* setup version number */ 1244 if (!X509_REQ_set_version(req,0L)) goto err; /* version 1 */ 1245 1246 if (no_prompt) 1247 i = auto_info(req, dn_sk, attr_sk, attribs, chtype); 1248 else 1249 { 1250 if (subj) 1251 i = build_subject(req, subj, chtype, multirdn); 1252 else 1253 i = prompt_info(req, dn_sk, dn_sect, attr_sk, attr_sect, attribs, chtype); 1254 } 1255 if(!i) goto err; 1256 1257 if (!X509_REQ_set_pubkey(req,pkey)) goto err; 1258 1259 ret=1; 1260 err: 1261 return(ret); 1262 } 1263 1264 /* 1265 * subject is expected to be in the format /type0=value0/type1=value1/type2=... 1266 * where characters may be escaped by \ 1267 */ 1268 static int build_subject(X509_REQ *req, char *subject, unsigned long chtype, int multirdn) 1269 { 1270 X509_NAME *n; 1271 1272 if (!(n = parse_name(subject, chtype, multirdn))) 1273 return 0; 1274 1275 if (!X509_REQ_set_subject_name(req, n)) 1276 { 1277 X509_NAME_free(n); 1278 return 0; 1279 } 1280 X509_NAME_free(n); 1281 return 1; 1282 } 1283 1284 1285 static int prompt_info(X509_REQ *req, 1286 STACK_OF(CONF_VALUE) *dn_sk, char *dn_sect, 1287 STACK_OF(CONF_VALUE) *attr_sk, char *attr_sect, int attribs, 1288 unsigned long chtype) 1289 { 1290 int i; 1291 char *p,*q; 1292 char buf[100]; 1293 int nid, mval; 1294 long n_min,n_max; 1295 char *type, *value; 1296 const char *def; 1297 CONF_VALUE *v; 1298 X509_NAME *subj; 1299 subj = X509_REQ_get_subject_name(req); 1300 1301 if(!batch) 1302 { 1303 BIO_printf(bio_err,"You are about to be asked to enter information that will be incorporated\n"); 1304 BIO_printf(bio_err,"into your certificate request.\n"); 1305 BIO_printf(bio_err,"What you are about to enter is what is called a Distinguished Name or a DN.\n"); 1306 BIO_printf(bio_err,"There are quite a few fields but you can leave some blank\n"); 1307 BIO_printf(bio_err,"For some fields there will be a default value,\n"); 1308 BIO_printf(bio_err,"If you enter '.', the field will be left blank.\n"); 1309 BIO_printf(bio_err,"-----\n"); 1310 } 1311 1312 1313 if (sk_CONF_VALUE_num(dn_sk)) 1314 { 1315 i= -1; 1316 start: for (;;) 1317 { 1318 i++; 1319 if (sk_CONF_VALUE_num(dn_sk) <= i) break; 1320 1321 v=sk_CONF_VALUE_value(dn_sk,i); 1322 p=q=NULL; 1323 type=v->name; 1324 if(!check_end(type,"_min") || !check_end(type,"_max") || 1325 !check_end(type,"_default") || 1326 !check_end(type,"_value")) continue; 1327 /* Skip past any leading X. X: X, etc to allow for 1328 * multiple instances 1329 */ 1330 for(p = v->name; *p ; p++) 1331 if ((*p == ':') || (*p == ',') || 1332 (*p == '.')) { 1333 p++; 1334 if(*p) type = p; 1335 break; 1336 } 1337 if (*type == '+') 1338 { 1339 mval = -1; 1340 type++; 1341 } 1342 else 1343 mval = 0; 1344 /* If OBJ not recognised ignore it */ 1345 if ((nid=OBJ_txt2nid(type)) == NID_undef) goto start; 1346 if (BIO_snprintf(buf,sizeof buf,"%s_default",v->name) 1347 >= (int)sizeof(buf)) 1348 { 1349 BIO_printf(bio_err,"Name '%s' too long\n",v->name); 1350 return 0; 1351 } 1352 1353 if ((def=NCONF_get_string(req_conf,dn_sect,buf)) == NULL) 1354 { 1355 ERR_clear_error(); 1356 def=""; 1357 } 1358 1359 BIO_snprintf(buf,sizeof buf,"%s_value",v->name); 1360 if ((value=NCONF_get_string(req_conf,dn_sect,buf)) == NULL) 1361 { 1362 ERR_clear_error(); 1363 value=NULL; 1364 } 1365 1366 BIO_snprintf(buf,sizeof buf,"%s_min",v->name); 1367 if (!NCONF_get_number(req_conf,dn_sect,buf, &n_min)) 1368 { 1369 ERR_clear_error(); 1370 n_min = -1; 1371 } 1372 1373 BIO_snprintf(buf,sizeof buf,"%s_max",v->name); 1374 if (!NCONF_get_number(req_conf,dn_sect,buf, &n_max)) 1375 { 1376 ERR_clear_error(); 1377 n_max = -1; 1378 } 1379 1380 if (!add_DN_object(subj,v->value,def,value,nid, 1381 n_min,n_max, chtype, mval)) 1382 return 0; 1383 } 1384 if (X509_NAME_entry_count(subj) == 0) 1385 { 1386 BIO_printf(bio_err,"error, no objects specified in config file\n"); 1387 return 0; 1388 } 1389 1390 if (attribs) 1391 { 1392 if ((attr_sk != NULL) && (sk_CONF_VALUE_num(attr_sk) > 0) && (!batch)) 1393 { 1394 BIO_printf(bio_err,"\nPlease enter the following 'extra' attributes\n"); 1395 BIO_printf(bio_err,"to be sent with your certificate request\n"); 1396 } 1397 1398 i= -1; 1399 start2: for (;;) 1400 { 1401 i++; 1402 if ((attr_sk == NULL) || 1403 (sk_CONF_VALUE_num(attr_sk) <= i)) 1404 break; 1405 1406 v=sk_CONF_VALUE_value(attr_sk,i); 1407 type=v->name; 1408 if ((nid=OBJ_txt2nid(type)) == NID_undef) 1409 goto start2; 1410 1411 if (BIO_snprintf(buf,sizeof buf,"%s_default",type) 1412 >= (int)sizeof(buf)) 1413 { 1414 BIO_printf(bio_err,"Name '%s' too long\n",v->name); 1415 return 0; 1416 } 1417 1418 if ((def=NCONF_get_string(req_conf,attr_sect,buf)) 1419 == NULL) 1420 { 1421 ERR_clear_error(); 1422 def=""; 1423 } 1424 1425 1426 BIO_snprintf(buf,sizeof buf,"%s_value",type); 1427 if ((value=NCONF_get_string(req_conf,attr_sect,buf)) 1428 == NULL) 1429 { 1430 ERR_clear_error(); 1431 value=NULL; 1432 } 1433 1434 BIO_snprintf(buf,sizeof buf,"%s_min",type); 1435 if (!NCONF_get_number(req_conf,attr_sect,buf, &n_min)) 1436 { 1437 ERR_clear_error(); 1438 n_min = -1; 1439 } 1440 1441 BIO_snprintf(buf,sizeof buf,"%s_max",type); 1442 if (!NCONF_get_number(req_conf,attr_sect,buf, &n_max)) 1443 { 1444 ERR_clear_error(); 1445 n_max = -1; 1446 } 1447 1448 if (!add_attribute_object(req, 1449 v->value,def,value,nid,n_min,n_max, chtype)) 1450 return 0; 1451 } 1452 } 1453 } 1454 else 1455 { 1456 BIO_printf(bio_err,"No template, please set one up.\n"); 1457 return 0; 1458 } 1459 1460 return 1; 1461 1462 } 1463 1464 static int auto_info(X509_REQ *req, STACK_OF(CONF_VALUE) *dn_sk, 1465 STACK_OF(CONF_VALUE) *attr_sk, int attribs, unsigned long chtype) 1466 { 1467 int i; 1468 char *p,*q; 1469 char *type; 1470 CONF_VALUE *v; 1471 X509_NAME *subj; 1472 1473 subj = X509_REQ_get_subject_name(req); 1474 1475 for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) 1476 { 1477 int mval; 1478 v=sk_CONF_VALUE_value(dn_sk,i); 1479 p=q=NULL; 1480 type=v->name; 1481 /* Skip past any leading X. X: X, etc to allow for 1482 * multiple instances 1483 */ 1484 for(p = v->name; *p ; p++) 1485 #ifndef CHARSET_EBCDIC 1486 if ((*p == ':') || (*p == ',') || (*p == '.')) { 1487 #else 1488 if ((*p == os_toascii[':']) || (*p == os_toascii[',']) || (*p == os_toascii['.'])) { 1489 #endif 1490 p++; 1491 if(*p) type = p; 1492 break; 1493 } 1494 #ifndef CHARSET_EBCDIC 1495 if (*p == '+') 1496 #else 1497 if (*p == os_toascii['+']) 1498 #endif 1499 { 1500 p++; 1501 mval = -1; 1502 } 1503 else 1504 mval = 0; 1505 if (!X509_NAME_add_entry_by_txt(subj,type, chtype, 1506 (unsigned char *) v->value,-1,-1,mval)) return 0; 1507 1508 } 1509 1510 if (!X509_NAME_entry_count(subj)) 1511 { 1512 BIO_printf(bio_err,"error, no objects specified in config file\n"); 1513 return 0; 1514 } 1515 if (attribs) 1516 { 1517 for (i = 0; i < sk_CONF_VALUE_num(attr_sk); i++) 1518 { 1519 v=sk_CONF_VALUE_value(attr_sk,i); 1520 if(!X509_REQ_add1_attr_by_txt(req, v->name, chtype, 1521 (unsigned char *)v->value, -1)) return 0; 1522 } 1523 } 1524 return 1; 1525 } 1526 1527 1528 static int add_DN_object(X509_NAME *n, char *text, const char *def, char *value, 1529 int nid, int n_min, int n_max, unsigned long chtype, int mval) 1530 { 1531 int i,ret=0; 1532 MS_STATIC char buf[1024]; 1533 start: 1534 if (!batch) BIO_printf(bio_err,"%s [%s]:",text,def); 1535 (void)BIO_flush(bio_err); 1536 if(value != NULL) 1537 { 1538 BUF_strlcpy(buf,value,sizeof buf); 1539 BUF_strlcat(buf,"\n",sizeof buf); 1540 BIO_printf(bio_err,"%s\n",value); 1541 } 1542 else 1543 { 1544 buf[0]='\0'; 1545 if (!batch) 1546 { 1547 if (!fgets(buf,sizeof buf,stdin)) 1548 return 0; 1549 } 1550 else 1551 { 1552 buf[0] = '\n'; 1553 buf[1] = '\0'; 1554 } 1555 } 1556 1557 if (buf[0] == '\0') return(0); 1558 else if (buf[0] == '\n') 1559 { 1560 if ((def == NULL) || (def[0] == '\0')) 1561 return(1); 1562 BUF_strlcpy(buf,def,sizeof buf); 1563 BUF_strlcat(buf,"\n",sizeof buf); 1564 } 1565 else if ((buf[0] == '.') && (buf[1] == '\n')) return(1); 1566 1567 i=strlen(buf); 1568 if (buf[i-1] != '\n') 1569 { 1570 BIO_printf(bio_err,"weird input :-(\n"); 1571 return(0); 1572 } 1573 buf[--i]='\0'; 1574 #ifdef CHARSET_EBCDIC 1575 ebcdic2ascii(buf, buf, i); 1576 #endif 1577 if(!req_check_len(i, n_min, n_max)) goto start; 1578 if (!X509_NAME_add_entry_by_NID(n,nid, chtype, 1579 (unsigned char *) buf, -1,-1,mval)) goto err; 1580 ret=1; 1581 err: 1582 return(ret); 1583 } 1584 1585 static int add_attribute_object(X509_REQ *req, char *text, const char *def, 1586 char *value, int nid, int n_min, 1587 int n_max, unsigned long chtype) 1588 { 1589 int i; 1590 static char buf[1024]; 1591 1592 start: 1593 if (!batch) BIO_printf(bio_err,"%s [%s]:",text,def); 1594 (void)BIO_flush(bio_err); 1595 if (value != NULL) 1596 { 1597 BUF_strlcpy(buf,value,sizeof buf); 1598 BUF_strlcat(buf,"\n",sizeof buf); 1599 BIO_printf(bio_err,"%s\n",value); 1600 } 1601 else 1602 { 1603 buf[0]='\0'; 1604 if (!batch) 1605 { 1606 if (!fgets(buf,sizeof buf,stdin)) 1607 return 0; 1608 } 1609 else 1610 { 1611 buf[0] = '\n'; 1612 buf[1] = '\0'; 1613 } 1614 } 1615 1616 if (buf[0] == '\0') return(0); 1617 else if (buf[0] == '\n') 1618 { 1619 if ((def == NULL) || (def[0] == '\0')) 1620 return(1); 1621 BUF_strlcpy(buf,def,sizeof buf); 1622 BUF_strlcat(buf,"\n",sizeof buf); 1623 } 1624 else if ((buf[0] == '.') && (buf[1] == '\n')) return(1); 1625 1626 i=strlen(buf); 1627 if (buf[i-1] != '\n') 1628 { 1629 BIO_printf(bio_err,"weird input :-(\n"); 1630 return(0); 1631 } 1632 buf[--i]='\0'; 1633 #ifdef CHARSET_EBCDIC 1634 ebcdic2ascii(buf, buf, i); 1635 #endif 1636 if(!req_check_len(i, n_min, n_max)) goto start; 1637 1638 if(!X509_REQ_add1_attr_by_NID(req, nid, chtype, 1639 (unsigned char *)buf, -1)) { 1640 BIO_printf(bio_err, "Error adding attribute\n"); 1641 ERR_print_errors(bio_err); 1642 goto err; 1643 } 1644 1645 return(1); 1646 err: 1647 return(0); 1648 } 1649 1650 #ifndef OPENSSL_NO_RSA 1651 static int MS_CALLBACK req_cb(int p, int n, BN_GENCB *cb) 1652 { 1653 char c='*'; 1654 1655 if (p == 0) c='.'; 1656 if (p == 1) c='+'; 1657 if (p == 2) c='*'; 1658 if (p == 3) c='\n'; 1659 BIO_write(cb->arg,&c,1); 1660 (void)BIO_flush(cb->arg); 1661 #ifdef LINT 1662 p=n; 1663 #endif 1664 return 1; 1665 } 1666 #endif 1667 1668 static int req_check_len(int len, int n_min, int n_max) 1669 { 1670 if ((n_min > 0) && (len < n_min)) 1671 { 1672 BIO_printf(bio_err,"string is too short, it needs to be at least %d bytes long\n",n_min); 1673 return(0); 1674 } 1675 if ((n_max >= 0) && (len > n_max)) 1676 { 1677 BIO_printf(bio_err,"string is too long, it needs to be less than %d bytes long\n",n_max); 1678 return(0); 1679 } 1680 return(1); 1681 } 1682 1683 /* Check if the end of a string matches 'end' */ 1684 static int check_end(const char *str, const char *end) 1685 { 1686 int elen, slen; 1687 const char *tmp; 1688 elen = strlen(end); 1689 slen = strlen(str); 1690 if(elen > slen) return 1; 1691 tmp = str + slen - elen; 1692 return strcmp(tmp, end); 1693 } 1694