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