req.c revision 279264
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 (!NCONF_get_number(req_conf,SECTION,BITS, &newkey))
648			{
649			newkey=DEFAULT_KEY_LENGTH;
650			}
651
652		if (keyalg)
653			{
654			genctx = set_keygen_ctx(bio_err, keyalg, &pkey_type, &newkey,
655							&keyalgstr, gen_eng);
656			if (!genctx)
657				goto end;
658			}
659
660		if (newkey < MIN_KEY_LENGTH && (pkey_type == EVP_PKEY_RSA || pkey_type == EVP_PKEY_DSA))
661			{
662			BIO_printf(bio_err,"private key length is too short,\n");
663			BIO_printf(bio_err,"it needs to be at least %d bits, not %ld\n",MIN_KEY_LENGTH,newkey);
664			goto end;
665			}
666
667		if (!genctx)
668			{
669			genctx = set_keygen_ctx(bio_err, NULL, &pkey_type, &newkey,
670							&keyalgstr, gen_eng);
671			if (!genctx)
672				goto end;
673			}
674
675		if (pkeyopts)
676			{
677			char *genopt;
678			for (i = 0; i < sk_OPENSSL_STRING_num(pkeyopts); i++)
679				{
680				genopt = sk_OPENSSL_STRING_value(pkeyopts, i);
681				if (pkey_ctrl_string(genctx, genopt) <= 0)
682					{
683					BIO_printf(bio_err,
684						"parameter error \"%s\"\n",
685						genopt);
686					ERR_print_errors(bio_err);
687					goto end;
688					}
689				}
690			}
691
692		BIO_printf(bio_err,"Generating a %ld bit %s private key\n",
693				newkey, keyalgstr);
694
695		EVP_PKEY_CTX_set_cb(genctx, genpkey_cb);
696		EVP_PKEY_CTX_set_app_data(genctx, bio_err);
697
698		if (EVP_PKEY_keygen(genctx, &pkey) <= 0)
699			{
700			BIO_puts(bio_err, "Error Generating Key\n");
701			goto end;
702			}
703
704		EVP_PKEY_CTX_free(genctx);
705		genctx = NULL;
706
707		app_RAND_write_file(randfile, bio_err);
708
709		if (keyout == NULL)
710			{
711			keyout=NCONF_get_string(req_conf,SECTION,KEYFILE);
712			if (keyout == NULL)
713				ERR_clear_error();
714			}
715
716		if (keyout == NULL)
717			{
718			BIO_printf(bio_err,"writing new private key to stdout\n");
719			BIO_set_fp(out,stdout,BIO_NOCLOSE);
720#ifdef OPENSSL_SYS_VMS
721			{
722			BIO *tmpbio = BIO_new(BIO_f_linebuffer());
723			out = BIO_push(tmpbio, out);
724			}
725#endif
726			}
727		else
728			{
729			BIO_printf(bio_err,"writing new private key to '%s'\n",keyout);
730			if (BIO_write_filename(out,keyout) <= 0)
731				{
732				perror(keyout);
733				goto end;
734				}
735			}
736
737		p=NCONF_get_string(req_conf,SECTION,"encrypt_rsa_key");
738		if (p == NULL)
739			{
740			ERR_clear_error();
741			p=NCONF_get_string(req_conf,SECTION,"encrypt_key");
742			if (p == NULL)
743				ERR_clear_error();
744			}
745		if ((p != NULL) && (strcmp(p,"no") == 0))
746			cipher=NULL;
747		if (nodes) cipher=NULL;
748
749		i=0;
750loop:
751		if (!PEM_write_bio_PrivateKey(out,pkey,cipher,
752			NULL,0,NULL,passout))
753			{
754			if ((ERR_GET_REASON(ERR_peek_error()) ==
755				PEM_R_PROBLEMS_GETTING_PASSWORD) && (i < 3))
756				{
757				ERR_clear_error();
758				i++;
759				goto loop;
760				}
761			goto end;
762			}
763		BIO_printf(bio_err,"-----\n");
764		}
765
766	if (!newreq)
767		{
768		/* Since we are using a pre-existing certificate
769		 * request, the kludge 'format' info should not be
770		 * changed. */
771		kludge= -1;
772		if (infile == NULL)
773			BIO_set_fp(in,stdin,BIO_NOCLOSE);
774		else
775			{
776			if (BIO_read_filename(in,infile) <= 0)
777				{
778				perror(infile);
779				goto end;
780				}
781			}
782
783		if	(informat == FORMAT_ASN1)
784			req=d2i_X509_REQ_bio(in,NULL);
785		else if (informat == FORMAT_PEM)
786			req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL);
787		else
788			{
789			BIO_printf(bio_err,"bad input format specified for X509 request\n");
790			goto end;
791			}
792		if (req == NULL)
793			{
794			BIO_printf(bio_err,"unable to load X509 request\n");
795			goto end;
796			}
797		}
798
799	if (newreq || x509)
800		{
801		if (pkey == NULL)
802			{
803			BIO_printf(bio_err,"you need to specify a private key\n");
804			goto end;
805			}
806
807		if (req == NULL)
808			{
809			req=X509_REQ_new();
810			if (req == NULL)
811				{
812				goto end;
813				}
814
815			i=make_REQ(req,pkey,subj,multirdn,!x509, chtype);
816			subj=NULL; /* done processing '-subj' option */
817			if ((kludge > 0) && !sk_X509_ATTRIBUTE_num(req->req_info->attributes))
818				{
819				sk_X509_ATTRIBUTE_free(req->req_info->attributes);
820				req->req_info->attributes = NULL;
821				}
822			if (!i)
823				{
824				BIO_printf(bio_err,"problems making Certificate Request\n");
825				goto end;
826				}
827			}
828		if (x509)
829			{
830			EVP_PKEY *tmppkey;
831			X509V3_CTX ext_ctx;
832			if ((x509ss=X509_new()) == NULL) goto end;
833
834			/* Set version to V3 */
835			if(extensions && !X509_set_version(x509ss, 2)) goto end;
836			if (serial)
837				{
838				if (!X509_set_serialNumber(x509ss, serial)) goto end;
839				}
840			else
841				{
842				if (!rand_serial(NULL,
843					X509_get_serialNumber(x509ss)))
844						goto end;
845				}
846
847			if (!X509_set_issuer_name(x509ss, X509_REQ_get_subject_name(req))) goto end;
848			if (!X509_gmtime_adj(X509_get_notBefore(x509ss),0)) goto end;
849			if (!X509_time_adj_ex(X509_get_notAfter(x509ss), days, 0, NULL)) goto end;
850			if (!X509_set_subject_name(x509ss, X509_REQ_get_subject_name(req))) goto end;
851			tmppkey = X509_REQ_get_pubkey(req);
852			if (!tmppkey || !X509_set_pubkey(x509ss,tmppkey)) goto end;
853			EVP_PKEY_free(tmppkey);
854
855			/* Set up V3 context struct */
856
857			X509V3_set_ctx(&ext_ctx, x509ss, x509ss, NULL, NULL, 0);
858			X509V3_set_nconf(&ext_ctx, req_conf);
859
860			/* Add extensions */
861			if(extensions && !X509V3_EXT_add_nconf(req_conf,
862				 	&ext_ctx, extensions, x509ss))
863				{
864				BIO_printf(bio_err,
865					"Error Loading extension section %s\n",
866					extensions);
867				goto end;
868				}
869
870			i=do_X509_sign(bio_err, x509ss, pkey, digest, sigopts);
871			if (!i)
872				{
873				ERR_print_errors(bio_err);
874				goto end;
875				}
876			}
877		else
878			{
879			X509V3_CTX ext_ctx;
880
881			/* Set up V3 context struct */
882
883			X509V3_set_ctx(&ext_ctx, NULL, NULL, req, NULL, 0);
884			X509V3_set_nconf(&ext_ctx, req_conf);
885
886			/* Add extensions */
887			if(req_exts && !X509V3_EXT_REQ_add_nconf(req_conf,
888				 	&ext_ctx, req_exts, req))
889				{
890				BIO_printf(bio_err,
891					"Error Loading extension section %s\n",
892					req_exts);
893				goto end;
894				}
895			i=do_X509_REQ_sign(bio_err, req, pkey, digest, sigopts);
896			if (!i)
897				{
898				ERR_print_errors(bio_err);
899				goto end;
900				}
901			}
902		}
903
904	if (subj && x509)
905		{
906		BIO_printf(bio_err, "Cannot modifiy certificate subject\n");
907		goto end;
908		}
909
910	if (subj && !x509)
911		{
912		if (verbose)
913			{
914			BIO_printf(bio_err, "Modifying Request's Subject\n");
915			print_name(bio_err, "old subject=", X509_REQ_get_subject_name(req), nmflag);
916			}
917
918		if (build_subject(req, subj, chtype, multirdn) == 0)
919			{
920			BIO_printf(bio_err, "ERROR: cannot modify subject\n");
921			ex=1;
922			goto end;
923			}
924
925		req->req_info->enc.modified = 1;
926
927		if (verbose)
928			{
929			print_name(bio_err, "new subject=", X509_REQ_get_subject_name(req), nmflag);
930			}
931		}
932
933	if (verify && !x509)
934		{
935		int tmp=0;
936
937		if (pkey == NULL)
938			{
939			pkey=X509_REQ_get_pubkey(req);
940			tmp=1;
941			if (pkey == NULL) goto end;
942			}
943
944		i=X509_REQ_verify(req,pkey);
945		if (tmp) {
946			EVP_PKEY_free(pkey);
947			pkey=NULL;
948		}
949
950		if (i < 0)
951			{
952			goto end;
953			}
954		else if (i == 0)
955			{
956			BIO_printf(bio_err,"verify failure\n");
957			ERR_print_errors(bio_err);
958			}
959		else /* if (i > 0) */
960			BIO_printf(bio_err,"verify OK\n");
961		}
962
963	if (noout && !text && !modulus && !subject && !pubkey)
964		{
965		ex=0;
966		goto end;
967		}
968
969	if (outfile == NULL)
970		{
971		BIO_set_fp(out,stdout,BIO_NOCLOSE);
972#ifdef OPENSSL_SYS_VMS
973		{
974		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
975		out = BIO_push(tmpbio, out);
976		}
977#endif
978		}
979	else
980		{
981		if ((keyout != NULL) && (strcmp(outfile,keyout) == 0))
982			i=(int)BIO_append_filename(out,outfile);
983		else
984			i=(int)BIO_write_filename(out,outfile);
985		if (!i)
986			{
987			perror(outfile);
988			goto end;
989			}
990		}
991
992	if (pubkey)
993		{
994		EVP_PKEY *tpubkey;
995		tpubkey=X509_REQ_get_pubkey(req);
996		if (tpubkey == NULL)
997			{
998			BIO_printf(bio_err,"Error getting public key\n");
999			ERR_print_errors(bio_err);
1000			goto end;
1001			}
1002		PEM_write_bio_PUBKEY(out, tpubkey);
1003		EVP_PKEY_free(tpubkey);
1004		}
1005
1006	if (text)
1007		{
1008		if (x509)
1009			X509_print_ex(out, x509ss, nmflag, reqflag);
1010		else
1011			X509_REQ_print_ex(out, req, nmflag, reqflag);
1012		}
1013
1014	if(subject)
1015		{
1016		if(x509)
1017			print_name(out, "subject=", X509_get_subject_name(x509ss), nmflag);
1018		else
1019			print_name(out, "subject=", X509_REQ_get_subject_name(req), nmflag);
1020		}
1021
1022	if (modulus)
1023		{
1024		EVP_PKEY *tpubkey;
1025
1026		if (x509)
1027			tpubkey=X509_get_pubkey(x509ss);
1028		else
1029			tpubkey=X509_REQ_get_pubkey(req);
1030		if (tpubkey == NULL)
1031			{
1032			fprintf(stdout,"Modulus=unavailable\n");
1033			goto end;
1034			}
1035		fprintf(stdout,"Modulus=");
1036#ifndef OPENSSL_NO_RSA
1037		if (EVP_PKEY_base_id(tpubkey) == EVP_PKEY_RSA)
1038			BN_print(out,tpubkey->pkey.rsa->n);
1039		else
1040#endif
1041			fprintf(stdout,"Wrong Algorithm type");
1042		EVP_PKEY_free(tpubkey);
1043		fprintf(stdout,"\n");
1044		}
1045
1046	if (!noout && !x509)
1047		{
1048		if 	(outformat == FORMAT_ASN1)
1049			i=i2d_X509_REQ_bio(out,req);
1050		else if (outformat == FORMAT_PEM) {
1051			if(newhdr) i=PEM_write_bio_X509_REQ_NEW(out,req);
1052			else i=PEM_write_bio_X509_REQ(out,req);
1053		} else {
1054			BIO_printf(bio_err,"bad output format specified for outfile\n");
1055			goto end;
1056			}
1057		if (!i)
1058			{
1059			BIO_printf(bio_err,"unable to write X509 request\n");
1060			goto end;
1061			}
1062		}
1063	if (!noout && x509 && (x509ss != NULL))
1064		{
1065		if 	(outformat == FORMAT_ASN1)
1066			i=i2d_X509_bio(out,x509ss);
1067		else if (outformat == FORMAT_PEM)
1068			i=PEM_write_bio_X509(out,x509ss);
1069		else	{
1070			BIO_printf(bio_err,"bad output format specified for outfile\n");
1071			goto end;
1072			}
1073		if (!i)
1074			{
1075			BIO_printf(bio_err,"unable to write X509 certificate\n");
1076			goto end;
1077			}
1078		}
1079	ex=0;
1080end:
1081#ifndef MONOLITH
1082	if(to_free)
1083		OPENSSL_free(to_free);
1084#endif
1085	if (ex)
1086		{
1087		ERR_print_errors(bio_err);
1088		}
1089	if ((req_conf != NULL) && (req_conf != config)) NCONF_free(req_conf);
1090	BIO_free(in);
1091	BIO_free_all(out);
1092	EVP_PKEY_free(pkey);
1093	if (genctx)
1094		EVP_PKEY_CTX_free(genctx);
1095	if (pkeyopts)
1096		sk_OPENSSL_STRING_free(pkeyopts);
1097	if (sigopts)
1098		sk_OPENSSL_STRING_free(sigopts);
1099#ifndef OPENSSL_NO_ENGINE
1100	if (gen_eng)
1101		ENGINE_free(gen_eng);
1102#endif
1103	if (keyalgstr)
1104		OPENSSL_free(keyalgstr);
1105	X509_REQ_free(req);
1106	X509_free(x509ss);
1107	ASN1_INTEGER_free(serial);
1108	if(passargin && passin) OPENSSL_free(passin);
1109	if(passargout && passout) OPENSSL_free(passout);
1110	OBJ_cleanup();
1111	apps_shutdown();
1112	OPENSSL_EXIT(ex);
1113	}
1114
1115static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, char *subj, int multirdn,
1116			int attribs, unsigned long chtype)
1117	{
1118	int ret=0,i;
1119	char no_prompt = 0;
1120	STACK_OF(CONF_VALUE) *dn_sk, *attr_sk = NULL;
1121	char *tmp, *dn_sect,*attr_sect;
1122
1123	tmp=NCONF_get_string(req_conf,SECTION,PROMPT);
1124	if (tmp == NULL)
1125		ERR_clear_error();
1126	if((tmp != NULL) && !strcmp(tmp, "no")) no_prompt = 1;
1127
1128	dn_sect=NCONF_get_string(req_conf,SECTION,DISTINGUISHED_NAME);
1129	if (dn_sect == NULL)
1130		{
1131		BIO_printf(bio_err,"unable to find '%s' in config\n",
1132			DISTINGUISHED_NAME);
1133		goto err;
1134		}
1135	dn_sk=NCONF_get_section(req_conf,dn_sect);
1136	if (dn_sk == NULL)
1137		{
1138		BIO_printf(bio_err,"unable to get '%s' section\n",dn_sect);
1139		goto err;
1140		}
1141
1142	attr_sect=NCONF_get_string(req_conf,SECTION,ATTRIBUTES);
1143	if (attr_sect == NULL)
1144		{
1145		ERR_clear_error();
1146		attr_sk=NULL;
1147		}
1148	else
1149		{
1150		attr_sk=NCONF_get_section(req_conf,attr_sect);
1151		if (attr_sk == NULL)
1152			{
1153			BIO_printf(bio_err,"unable to get '%s' section\n",attr_sect);
1154			goto err;
1155			}
1156		}
1157
1158	/* setup version number */
1159	if (!X509_REQ_set_version(req,0L)) goto err; /* version 1 */
1160
1161	if (no_prompt)
1162		i = auto_info(req, dn_sk, attr_sk, attribs, chtype);
1163	else
1164		{
1165		if (subj)
1166			i = build_subject(req, subj, chtype, multirdn);
1167		else
1168			i = prompt_info(req, dn_sk, dn_sect, attr_sk, attr_sect, attribs, chtype);
1169		}
1170	if(!i) goto err;
1171
1172	if (!X509_REQ_set_pubkey(req,pkey)) goto err;
1173
1174	ret=1;
1175err:
1176	return(ret);
1177	}
1178
1179/*
1180 * subject is expected to be in the format /type0=value0/type1=value1/type2=...
1181 * where characters may be escaped by \
1182 */
1183static int build_subject(X509_REQ *req, char *subject, unsigned long chtype, int multirdn)
1184	{
1185	X509_NAME *n;
1186
1187	if (!(n = parse_name(subject, chtype, multirdn)))
1188		return 0;
1189
1190	if (!X509_REQ_set_subject_name(req, n))
1191		{
1192		X509_NAME_free(n);
1193		return 0;
1194		}
1195	X509_NAME_free(n);
1196	return 1;
1197}
1198
1199
1200static int prompt_info(X509_REQ *req,
1201		STACK_OF(CONF_VALUE) *dn_sk, char *dn_sect,
1202		STACK_OF(CONF_VALUE) *attr_sk, char *attr_sect, int attribs,
1203		unsigned long chtype)
1204	{
1205	int i;
1206	char *p,*q;
1207	char buf[100];
1208	int nid, mval;
1209	long n_min,n_max;
1210	char *type, *value;
1211	const char *def;
1212	CONF_VALUE *v;
1213	X509_NAME *subj;
1214	subj = X509_REQ_get_subject_name(req);
1215
1216	if(!batch)
1217		{
1218		BIO_printf(bio_err,"You are about to be asked to enter information that will be incorporated\n");
1219		BIO_printf(bio_err,"into your certificate request.\n");
1220		BIO_printf(bio_err,"What you are about to enter is what is called a Distinguished Name or a DN.\n");
1221		BIO_printf(bio_err,"There are quite a few fields but you can leave some blank\n");
1222		BIO_printf(bio_err,"For some fields there will be a default value,\n");
1223		BIO_printf(bio_err,"If you enter '.', the field will be left blank.\n");
1224		BIO_printf(bio_err,"-----\n");
1225		}
1226
1227
1228	if (sk_CONF_VALUE_num(dn_sk))
1229		{
1230		i= -1;
1231start:		for (;;)
1232			{
1233			i++;
1234			if (sk_CONF_VALUE_num(dn_sk) <= i) break;
1235
1236			v=sk_CONF_VALUE_value(dn_sk,i);
1237			p=q=NULL;
1238			type=v->name;
1239			if(!check_end(type,"_min") || !check_end(type,"_max") ||
1240				!check_end(type,"_default") ||
1241					 !check_end(type,"_value")) continue;
1242			/* Skip past any leading X. X: X, etc to allow for
1243			 * multiple instances
1244			 */
1245			for(p = v->name; *p ; p++)
1246				if ((*p == ':') || (*p == ',') ||
1247							 (*p == '.')) {
1248					p++;
1249					if(*p) type = p;
1250					break;
1251				}
1252			if (*type == '+')
1253				{
1254				mval = -1;
1255				type++;
1256				}
1257			else
1258				mval = 0;
1259			/* If OBJ not recognised ignore it */
1260			if ((nid=OBJ_txt2nid(type)) == NID_undef) goto start;
1261			if (BIO_snprintf(buf,sizeof buf,"%s_default",v->name)
1262				>= (int)sizeof(buf))
1263			   {
1264			   BIO_printf(bio_err,"Name '%s' too long\n",v->name);
1265			   return 0;
1266			   }
1267
1268			if ((def=NCONF_get_string(req_conf,dn_sect,buf)) == NULL)
1269				{
1270				ERR_clear_error();
1271				def="";
1272				}
1273
1274			BIO_snprintf(buf,sizeof buf,"%s_value",v->name);
1275			if ((value=NCONF_get_string(req_conf,dn_sect,buf)) == NULL)
1276				{
1277				ERR_clear_error();
1278				value=NULL;
1279				}
1280
1281			BIO_snprintf(buf,sizeof buf,"%s_min",v->name);
1282			if (!NCONF_get_number(req_conf,dn_sect,buf, &n_min))
1283				{
1284				ERR_clear_error();
1285				n_min = -1;
1286				}
1287
1288			BIO_snprintf(buf,sizeof buf,"%s_max",v->name);
1289			if (!NCONF_get_number(req_conf,dn_sect,buf, &n_max))
1290				{
1291				ERR_clear_error();
1292				n_max = -1;
1293				}
1294
1295			if (!add_DN_object(subj,v->value,def,value,nid,
1296				n_min,n_max, chtype, mval))
1297				return 0;
1298			}
1299		if (X509_NAME_entry_count(subj) == 0)
1300			{
1301			BIO_printf(bio_err,"error, no objects specified in config file\n");
1302			return 0;
1303			}
1304
1305		if (attribs)
1306			{
1307			if ((attr_sk != NULL) && (sk_CONF_VALUE_num(attr_sk) > 0) && (!batch))
1308				{
1309				BIO_printf(bio_err,"\nPlease enter the following 'extra' attributes\n");
1310				BIO_printf(bio_err,"to be sent with your certificate request\n");
1311				}
1312
1313			i= -1;
1314start2:			for (;;)
1315				{
1316				i++;
1317				if ((attr_sk == NULL) ||
1318					    (sk_CONF_VALUE_num(attr_sk) <= i))
1319					break;
1320
1321				v=sk_CONF_VALUE_value(attr_sk,i);
1322				type=v->name;
1323				if ((nid=OBJ_txt2nid(type)) == NID_undef)
1324					goto start2;
1325
1326				if (BIO_snprintf(buf,sizeof buf,"%s_default",type)
1327					>= (int)sizeof(buf))
1328				   {
1329				   BIO_printf(bio_err,"Name '%s' too long\n",v->name);
1330				   return 0;
1331				   }
1332
1333				if ((def=NCONF_get_string(req_conf,attr_sect,buf))
1334					== NULL)
1335					{
1336					ERR_clear_error();
1337					def="";
1338					}
1339
1340
1341				BIO_snprintf(buf,sizeof buf,"%s_value",type);
1342				if ((value=NCONF_get_string(req_conf,attr_sect,buf))
1343					== NULL)
1344					{
1345					ERR_clear_error();
1346					value=NULL;
1347					}
1348
1349				BIO_snprintf(buf,sizeof buf,"%s_min",type);
1350				if (!NCONF_get_number(req_conf,attr_sect,buf, &n_min))
1351					{
1352					ERR_clear_error();
1353					n_min = -1;
1354					}
1355
1356				BIO_snprintf(buf,sizeof buf,"%s_max",type);
1357				if (!NCONF_get_number(req_conf,attr_sect,buf, &n_max))
1358					{
1359					ERR_clear_error();
1360					n_max = -1;
1361					}
1362
1363				if (!add_attribute_object(req,
1364					v->value,def,value,nid,n_min,n_max, chtype))
1365					return 0;
1366				}
1367			}
1368		}
1369	else
1370		{
1371		BIO_printf(bio_err,"No template, please set one up.\n");
1372		return 0;
1373		}
1374
1375	return 1;
1376
1377	}
1378
1379static int auto_info(X509_REQ *req, STACK_OF(CONF_VALUE) *dn_sk,
1380			STACK_OF(CONF_VALUE) *attr_sk, int attribs, unsigned long chtype)
1381	{
1382	int i;
1383	char *p,*q;
1384	char *type;
1385	CONF_VALUE *v;
1386	X509_NAME *subj;
1387
1388	subj = X509_REQ_get_subject_name(req);
1389
1390	for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++)
1391		{
1392		int mval;
1393		v=sk_CONF_VALUE_value(dn_sk,i);
1394		p=q=NULL;
1395		type=v->name;
1396		/* Skip past any leading X. X: X, etc to allow for
1397		 * multiple instances
1398		 */
1399		for(p = v->name; *p ; p++)
1400#ifndef CHARSET_EBCDIC
1401			if ((*p == ':') || (*p == ',') || (*p == '.')) {
1402#else
1403			if ((*p == os_toascii[':']) || (*p == os_toascii[',']) || (*p == os_toascii['.'])) {
1404#endif
1405				p++;
1406				if(*p) type = p;
1407				break;
1408			}
1409#ifndef CHARSET_EBCDIC
1410		if (*p == '+')
1411#else
1412		if (*p == os_toascii['+'])
1413#endif
1414			{
1415			p++;
1416			mval = -1;
1417			}
1418		else
1419			mval = 0;
1420		if (!X509_NAME_add_entry_by_txt(subj,type, chtype,
1421				(unsigned char *) v->value,-1,-1,mval)) return 0;
1422
1423		}
1424
1425		if (!X509_NAME_entry_count(subj))
1426			{
1427			BIO_printf(bio_err,"error, no objects specified in config file\n");
1428			return 0;
1429			}
1430		if (attribs)
1431			{
1432			for (i = 0; i < sk_CONF_VALUE_num(attr_sk); i++)
1433				{
1434				v=sk_CONF_VALUE_value(attr_sk,i);
1435				if(!X509_REQ_add1_attr_by_txt(req, v->name, chtype,
1436					(unsigned char *)v->value, -1)) return 0;
1437				}
1438			}
1439	return 1;
1440	}
1441
1442
1443static int add_DN_object(X509_NAME *n, char *text, const char *def, char *value,
1444	     int nid, int n_min, int n_max, unsigned long chtype, int mval)
1445	{
1446	int i,ret=0;
1447	MS_STATIC char buf[1024];
1448start:
1449	if (!batch) BIO_printf(bio_err,"%s [%s]:",text,def);
1450	(void)BIO_flush(bio_err);
1451	if(value != NULL)
1452		{
1453		BUF_strlcpy(buf,value,sizeof buf);
1454		BUF_strlcat(buf,"\n",sizeof buf);
1455		BIO_printf(bio_err,"%s\n",value);
1456		}
1457	else
1458		{
1459		buf[0]='\0';
1460		if (!batch)
1461			{
1462			if (!fgets(buf,sizeof buf,stdin))
1463				return 0;
1464			}
1465		else
1466			{
1467			buf[0] = '\n';
1468			buf[1] = '\0';
1469			}
1470		}
1471
1472	if (buf[0] == '\0') return(0);
1473	else if (buf[0] == '\n')
1474		{
1475		if ((def == NULL) || (def[0] == '\0'))
1476			return(1);
1477		BUF_strlcpy(buf,def,sizeof buf);
1478		BUF_strlcat(buf,"\n",sizeof buf);
1479		}
1480	else if ((buf[0] == '.') && (buf[1] == '\n')) return(1);
1481
1482	i=strlen(buf);
1483	if (buf[i-1] != '\n')
1484		{
1485		BIO_printf(bio_err,"weird input :-(\n");
1486		return(0);
1487		}
1488	buf[--i]='\0';
1489#ifdef CHARSET_EBCDIC
1490	ebcdic2ascii(buf, buf, i);
1491#endif
1492	if(!req_check_len(i, n_min, n_max))
1493		{
1494		if (batch || value)
1495			return 0;
1496		goto start;
1497		}
1498
1499	if (!X509_NAME_add_entry_by_NID(n,nid, chtype,
1500				(unsigned char *) buf, -1,-1,mval)) goto err;
1501	ret=1;
1502err:
1503	return(ret);
1504	}
1505
1506static int add_attribute_object(X509_REQ *req, char *text, const char *def,
1507				char *value, int nid, int n_min,
1508				int n_max, unsigned long chtype)
1509	{
1510	int i;
1511	static char buf[1024];
1512
1513start:
1514	if (!batch) BIO_printf(bio_err,"%s [%s]:",text,def);
1515	(void)BIO_flush(bio_err);
1516	if (value != NULL)
1517		{
1518		BUF_strlcpy(buf,value,sizeof buf);
1519		BUF_strlcat(buf,"\n",sizeof buf);
1520		BIO_printf(bio_err,"%s\n",value);
1521		}
1522	else
1523		{
1524		buf[0]='\0';
1525		if (!batch)
1526			{
1527			if (!fgets(buf,sizeof buf,stdin))
1528				return 0;
1529			}
1530		else
1531			{
1532			buf[0] = '\n';
1533			buf[1] = '\0';
1534			}
1535		}
1536
1537	if (buf[0] == '\0') return(0);
1538	else if (buf[0] == '\n')
1539		{
1540		if ((def == NULL) || (def[0] == '\0'))
1541			return(1);
1542		BUF_strlcpy(buf,def,sizeof buf);
1543		BUF_strlcat(buf,"\n",sizeof buf);
1544		}
1545	else if ((buf[0] == '.') && (buf[1] == '\n')) return(1);
1546
1547	i=strlen(buf);
1548	if (buf[i-1] != '\n')
1549		{
1550		BIO_printf(bio_err,"weird input :-(\n");
1551		return(0);
1552		}
1553	buf[--i]='\0';
1554#ifdef CHARSET_EBCDIC
1555	ebcdic2ascii(buf, buf, i);
1556#endif
1557	if(!req_check_len(i, n_min, n_max))
1558		{
1559		if (batch || value)
1560			return 0;
1561		goto start;
1562		}
1563
1564	if(!X509_REQ_add1_attr_by_NID(req, nid, chtype,
1565					(unsigned char *)buf, -1)) {
1566		BIO_printf(bio_err, "Error adding attribute\n");
1567		ERR_print_errors(bio_err);
1568		goto err;
1569	}
1570
1571	return(1);
1572err:
1573	return(0);
1574	}
1575
1576static int req_check_len(int len, int n_min, int n_max)
1577	{
1578	if ((n_min > 0) && (len < n_min))
1579		{
1580		BIO_printf(bio_err,"string is too short, it needs to be at least %d bytes long\n",n_min);
1581		return(0);
1582		}
1583	if ((n_max >= 0) && (len > n_max))
1584		{
1585		BIO_printf(bio_err,"string is too long, it needs to be less than  %d bytes long\n",n_max);
1586		return(0);
1587		}
1588	return(1);
1589	}
1590
1591/* Check if the end of a string matches 'end' */
1592static int check_end(const char *str, const char *end)
1593{
1594	int elen, slen;
1595	const char *tmp;
1596	elen = strlen(end);
1597	slen = strlen(str);
1598	if(elen > slen) return 1;
1599	tmp = str + slen - elen;
1600	return strcmp(tmp, end);
1601}
1602
1603static EVP_PKEY_CTX *set_keygen_ctx(BIO *err, const char *gstr, int *pkey_type,
1604					long *pkeylen, char **palgnam,
1605					ENGINE *keygen_engine)
1606	{
1607	EVP_PKEY_CTX *gctx = NULL;
1608	EVP_PKEY *param = NULL;
1609	long keylen = -1;
1610	BIO *pbio = NULL;
1611	const char *paramfile = NULL;
1612
1613	if (gstr == NULL)
1614		{
1615		*pkey_type = EVP_PKEY_RSA;
1616		keylen = *pkeylen;
1617		}
1618	else if (gstr[0] >= '0' && gstr[0] <= '9')
1619		{
1620		*pkey_type = EVP_PKEY_RSA;
1621		keylen = atol(gstr);
1622		*pkeylen = keylen;
1623		}
1624	else if (!strncmp(gstr, "param:", 6))
1625		paramfile = gstr + 6;
1626	else
1627		{
1628		const char *p = strchr(gstr, ':');
1629		int len;
1630		ENGINE *tmpeng;
1631		const EVP_PKEY_ASN1_METHOD *ameth;
1632
1633		if (p)
1634			len = p - gstr;
1635		else
1636			len = strlen(gstr);
1637		/* The lookup of a the string will cover all engines so
1638		 * keep a note of the implementation.
1639		 */
1640
1641		ameth = EVP_PKEY_asn1_find_str(&tmpeng, gstr, len);
1642
1643		if (!ameth)
1644			{
1645			BIO_printf(err, "Unknown algorithm %.*s\n", len, gstr);
1646			return NULL;
1647			}
1648
1649		EVP_PKEY_asn1_get0_info(NULL, pkey_type, NULL, NULL, NULL,
1650									ameth);
1651#ifndef OPENSSL_NO_ENGINE
1652		if (tmpeng)
1653			ENGINE_finish(tmpeng);
1654#endif
1655		if (*pkey_type == EVP_PKEY_RSA)
1656			{
1657			if (p)
1658				{
1659				keylen = atol(p + 1);
1660				*pkeylen = keylen;
1661				}
1662			else
1663				keylen = *pkeylen;
1664			}
1665		else if (p)
1666			paramfile = p + 1;
1667		}
1668
1669	if (paramfile)
1670		{
1671		pbio = BIO_new_file(paramfile, "r");
1672		if (!pbio)
1673			{
1674			BIO_printf(err, "Can't open parameter file %s\n",
1675					paramfile);
1676			return NULL;
1677			}
1678		param = PEM_read_bio_Parameters(pbio, NULL);
1679
1680		if (!param)
1681			{
1682			X509 *x;
1683			(void)BIO_reset(pbio);
1684			x = PEM_read_bio_X509(pbio, NULL, NULL, NULL);
1685			if (x)
1686				{
1687				param = X509_get_pubkey(x);
1688				X509_free(x);
1689				}
1690			}
1691
1692		BIO_free(pbio);
1693
1694		if (!param)
1695			{
1696			BIO_printf(err, "Error reading parameter file %s\n",
1697					paramfile);
1698			return NULL;
1699			}
1700		if (*pkey_type == -1)
1701			*pkey_type = EVP_PKEY_id(param);
1702		else if (*pkey_type != EVP_PKEY_base_id(param))
1703			{
1704			BIO_printf(err, "Key Type does not match parameters\n");
1705			EVP_PKEY_free(param);
1706			return NULL;
1707			}
1708		}
1709
1710	if (palgnam)
1711		{
1712		const EVP_PKEY_ASN1_METHOD *ameth;
1713		ENGINE *tmpeng;
1714		const char *anam;
1715		ameth = EVP_PKEY_asn1_find(&tmpeng, *pkey_type);
1716		if (!ameth)
1717			{
1718			BIO_puts(err, "Internal error: can't find key algorithm\n");
1719			return NULL;
1720			}
1721		EVP_PKEY_asn1_get0_info(NULL, NULL, NULL, NULL, &anam, ameth);
1722		*palgnam = BUF_strdup(anam);
1723#ifndef OPENSSL_NO_ENGINE
1724		if (tmpeng)
1725			ENGINE_finish(tmpeng);
1726#endif
1727		}
1728
1729	if (param)
1730		{
1731		gctx = EVP_PKEY_CTX_new(param, keygen_engine);
1732		*pkeylen = EVP_PKEY_bits(param);
1733		EVP_PKEY_free(param);
1734		}
1735	else
1736		gctx = EVP_PKEY_CTX_new_id(*pkey_type, keygen_engine);
1737
1738	if (!gctx)
1739		{
1740		BIO_puts(err, "Error allocating keygen context\n");
1741		ERR_print_errors(err);
1742		return NULL;
1743		}
1744
1745	if (EVP_PKEY_keygen_init(gctx) <= 0)
1746		{
1747		BIO_puts(err, "Error initializing keygen context\n");
1748		ERR_print_errors(err);
1749		return NULL;
1750		}
1751#ifndef OPENSSL_NO_RSA
1752	if ((*pkey_type == EVP_PKEY_RSA) && (keylen != -1))
1753		{
1754		if (EVP_PKEY_CTX_set_rsa_keygen_bits(gctx, keylen) <= 0)
1755			{
1756			BIO_puts(err, "Error setting RSA keysize\n");
1757			ERR_print_errors(err);
1758			EVP_PKEY_CTX_free(gctx);
1759			return NULL;
1760			}
1761		}
1762#endif
1763
1764	return gctx;
1765	}
1766
1767static int genpkey_cb(EVP_PKEY_CTX *ctx)
1768	{
1769	char c='*';
1770	BIO *b = EVP_PKEY_CTX_get_app_data(ctx);
1771	int p;
1772	p = EVP_PKEY_CTX_get_keygen_info(ctx, 0);
1773	if (p == 0) c='.';
1774	if (p == 1) c='+';
1775	if (p == 2) c='*';
1776	if (p == 3) c='\n';
1777	BIO_write(b,&c,1);
1778	(void)BIO_flush(b);
1779#ifdef LINT
1780	p=n;
1781#endif
1782	return 1;
1783	}
1784
1785static int do_sign_init(BIO *err, EVP_MD_CTX *ctx, EVP_PKEY *pkey,
1786			const EVP_MD *md, STACK_OF(OPENSSL_STRING) *sigopts)
1787	{
1788	EVP_PKEY_CTX *pkctx = NULL;
1789	int i;
1790	EVP_MD_CTX_init(ctx);
1791	if (!EVP_DigestSignInit(ctx, &pkctx, md, NULL, pkey))
1792		return 0;
1793	for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++)
1794		{
1795		char *sigopt = sk_OPENSSL_STRING_value(sigopts, i);
1796		if (pkey_ctrl_string(pkctx, sigopt) <= 0)
1797			{
1798			BIO_printf(err, "parameter error \"%s\"\n", sigopt);
1799			ERR_print_errors(bio_err);
1800			return 0;
1801			}
1802		}
1803	return 1;
1804	}
1805
1806int do_X509_sign(BIO *err, X509 *x, EVP_PKEY *pkey, const EVP_MD *md,
1807			STACK_OF(OPENSSL_STRING) *sigopts)
1808	{
1809	int rv;
1810	EVP_MD_CTX mctx;
1811	EVP_MD_CTX_init(&mctx);
1812	rv = do_sign_init(err, &mctx, pkey, md, sigopts);
1813	if (rv > 0)
1814		rv = X509_sign_ctx(x, &mctx);
1815	EVP_MD_CTX_cleanup(&mctx);
1816	return rv > 0 ? 1 : 0;
1817	}
1818
1819
1820int do_X509_REQ_sign(BIO *err, X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md,
1821			STACK_OF(OPENSSL_STRING) *sigopts)
1822	{
1823	int rv;
1824	EVP_MD_CTX mctx;
1825	EVP_MD_CTX_init(&mctx);
1826	rv = do_sign_init(err, &mctx, pkey, md, sigopts);
1827	if (rv > 0)
1828		rv = X509_REQ_sign_ctx(x, &mctx);
1829	EVP_MD_CTX_cleanup(&mctx);
1830	return rv > 0 ? 1 : 0;
1831	}
1832
1833
1834
1835int do_X509_CRL_sign(BIO *err, X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md,
1836			STACK_OF(OPENSSL_STRING) *sigopts)
1837	{
1838	int rv;
1839	EVP_MD_CTX mctx;
1840	EVP_MD_CTX_init(&mctx);
1841	rv = do_sign_init(err, &mctx, pkey, md, sigopts);
1842	if (rv > 0)
1843		rv = X509_CRL_sign_ctx(x, &mctx);
1844	EVP_MD_CTX_cleanup(&mctx);
1845	return rv > 0 ? 1 : 0;
1846	}
1847
1848
1849