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