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