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