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