xref: /openbsd-src/usr.bin/openssl/apps.c (revision e5157e49389faebcb42b7237d55fbf096d9c2523)
1 /* $OpenBSD: apps.c,v 1.12 2014/11/07 14:16:48 jsing Exp $ */
2 /*
3  * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
18  * All rights reserved.
19  *
20  * This package is an SSL implementation written
21  * by Eric Young (eay@cryptsoft.com).
22  * The implementation was written so as to conform with Netscapes SSL.
23  *
24  * This library is free for commercial and non-commercial use as long as
25  * the following conditions are aheared to.  The following conditions
26  * apply to all code found in this distribution, be it the RC4, RSA,
27  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
28  * included with this distribution is covered by the same copyright terms
29  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
30  *
31  * Copyright remains Eric Young's, and as such any Copyright notices in
32  * the code are not to be removed.
33  * If this package is used in a product, Eric Young should be given attribution
34  * as the author of the parts of the library used.
35  * This can be in the form of a textual message at program startup or
36  * in documentation (online or textual) provided with the package.
37  *
38  * Redistribution and use in source and binary forms, with or without
39  * modification, are permitted provided that the following conditions
40  * are met:
41  * 1. Redistributions of source code must retain the copyright
42  *    notice, this list of conditions and the following disclaimer.
43  * 2. Redistributions in binary form must reproduce the above copyright
44  *    notice, this list of conditions and the following disclaimer in the
45  *    documentation and/or other materials provided with the distribution.
46  * 3. All advertising materials mentioning features or use of this software
47  *    must display the following acknowledgement:
48  *    "This product includes cryptographic software written by
49  *     Eric Young (eay@cryptsoft.com)"
50  *    The word 'cryptographic' can be left out if the rouines from the library
51  *    being used are not cryptographic related :-).
52  * 4. If you include any Windows specific code (or a derivative thereof) from
53  *    the apps directory (application code) you must include an acknowledgement:
54  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
55  *
56  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
57  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
58  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
59  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
60  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
61  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
62  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
63  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
64  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
65  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
66  * SUCH DAMAGE.
67  *
68  * The licence and distribution terms for any publically available version or
69  * derivative of this code cannot be changed.  i.e. this code cannot simply be
70  * copied and put under another distribution licence
71  * [including the GNU Public Licence.]
72  */
73 /* ====================================================================
74  * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
75  *
76  * Redistribution and use in source and binary forms, with or without
77  * modification, are permitted provided that the following conditions
78  * are met:
79  *
80  * 1. Redistributions of source code must retain the above copyright
81  *    notice, this list of conditions and the following disclaimer.
82  *
83  * 2. Redistributions in binary form must reproduce the above copyright
84  *    notice, this list of conditions and the following disclaimer in
85  *    the documentation and/or other materials provided with the
86  *    distribution.
87  *
88  * 3. All advertising materials mentioning features or use of this
89  *    software must display the following acknowledgment:
90  *    "This product includes software developed by the OpenSSL Project
91  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
92  *
93  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
94  *    endorse or promote products derived from this software without
95  *    prior written permission. For written permission, please contact
96  *    openssl-core@openssl.org.
97  *
98  * 5. Products derived from this software may not be called "OpenSSL"
99  *    nor may "OpenSSL" appear in their names without prior written
100  *    permission of the OpenSSL Project.
101  *
102  * 6. Redistributions of any form whatsoever must retain the following
103  *    acknowledgment:
104  *    "This product includes software developed by the OpenSSL Project
105  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
106  *
107  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
108  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
109  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
110  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
111  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
112  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
113  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
114  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
115  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
116  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
117  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
118  * OF THE POSSIBILITY OF SUCH DAMAGE.
119  * ====================================================================
120  *
121  * This product includes cryptographic software written by Eric Young
122  * (eay@cryptsoft.com).  This product includes software written by Tim
123  * Hudson (tjh@cryptsoft.com).
124  *
125  */
126 
127 #include <sys/types.h>
128 #include <sys/stat.h>
129 #include <sys/times.h>
130 
131 #include <ctype.h>
132 #include <errno.h>
133 #include <stdio.h>
134 #include <stdlib.h>
135 #include <limits.h>
136 #include <string.h>
137 #include <strings.h>
138 #include <unistd.h>
139 
140 #include "apps.h"
141 
142 #include <openssl/bn.h>
143 #include <openssl/err.h>
144 #include <openssl/pem.h>
145 #include <openssl/pkcs12.h>
146 #include <openssl/safestack.h>
147 #include <openssl/ui.h>
148 #include <openssl/x509.h>
149 #include <openssl/x509v3.h>
150 
151 #ifndef OPENSSL_NO_ENGINE
152 #include <openssl/engine.h>
153 #endif
154 
155 #include <openssl/rsa.h>
156 
157 typedef struct {
158 	const char *name;
159 	unsigned long flag;
160 	unsigned long mask;
161 } NAME_EX_TBL;
162 
163 static UI_METHOD *ui_method = NULL;
164 
165 static int set_table_opts(unsigned long *flags, const char *arg,
166     const NAME_EX_TBL *in_tbl);
167 static int set_multi_opts(unsigned long *flags, const char *arg,
168     const NAME_EX_TBL *in_tbl);
169 
170 #if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
171 /* Looks like this stuff is worth moving into separate function */
172 static EVP_PKEY *load_netscape_key(BIO *err, BIO *key, const char *file,
173     const char *key_descrip, int format);
174 #endif
175 
176 int
177 str2fmt(char *s)
178 {
179 	if (s == NULL)
180 		return FORMAT_UNDEF;
181 	if ((*s == 'D') || (*s == 'd'))
182 		return (FORMAT_ASN1);
183 	else if ((*s == 'T') || (*s == 't'))
184 		return (FORMAT_TEXT);
185 	else if ((*s == 'N') || (*s == 'n'))
186 		return (FORMAT_NETSCAPE);
187 	else if ((*s == 'S') || (*s == 's'))
188 		return (FORMAT_SMIME);
189 	else if ((*s == 'M') || (*s == 'm'))
190 		return (FORMAT_MSBLOB);
191 	else if ((*s == '1') ||
192 	    (strcmp(s, "PKCS12") == 0) || (strcmp(s, "pkcs12") == 0) ||
193 	    (strcmp(s, "P12") == 0) || (strcmp(s, "p12") == 0))
194 		return (FORMAT_PKCS12);
195 	else if ((*s == 'E') || (*s == 'e'))
196 		return (FORMAT_ENGINE);
197 	else if ((*s == 'P') || (*s == 'p')) {
198 		if (s[1] == 'V' || s[1] == 'v')
199 			return FORMAT_PVK;
200 		else
201 			return (FORMAT_PEM);
202 	} else
203 		return (FORMAT_UNDEF);
204 }
205 
206 void
207 program_name(char *in, char *out, int size)
208 {
209 	char *p;
210 
211 	p = strrchr(in, '/');
212 	if (p != NULL)
213 		p++;
214 	else
215 		p = in;
216 	strlcpy(out, p, size);
217 }
218 
219 int
220 chopup_args(ARGS *arg, char *buf, int *argc, char **argv[])
221 {
222 	int num, i;
223 	char *p;
224 
225 	*argc = 0;
226 	*argv = NULL;
227 
228 	i = 0;
229 	if (arg->count == 0) {
230 		arg->count = 20;
231 		arg->data = reallocarray(NULL, arg->count, sizeof(char *));
232 	}
233 	for (i = 0; i < arg->count; i++)
234 		arg->data[i] = NULL;
235 
236 	num = 0;
237 	p = buf;
238 	for (;;) {
239 		/* first scan over white space */
240 		if (!*p)
241 			break;
242 		while (*p && ((*p == ' ') || (*p == '\t') || (*p == '\n')))
243 			p++;
244 		if (!*p)
245 			break;
246 
247 		/* The start of something good :-) */
248 		if (num >= arg->count) {
249 			char **tmp_p;
250 			int tlen = arg->count + 20;
251 			tmp_p = reallocarray(arg->data, tlen, sizeof(char *));
252 			if (tmp_p == NULL)
253 				return 0;
254 			arg->data = tmp_p;
255 			arg->count = tlen;
256 			/* initialize newly allocated data */
257 			for (i = num; i < arg->count; i++)
258 				arg->data[i] = NULL;
259 		}
260 		arg->data[num++] = p;
261 
262 		/* now look for the end of this */
263 		if ((*p == '\'') || (*p == '\"')) {	/* scan for closing
264 							 * quote */
265 			i = *(p++);
266 			arg->data[num - 1]++;	/* jump over quote */
267 			while (*p && (*p != i))
268 				p++;
269 			*p = '\0';
270 		} else {
271 			while (*p && ((*p != ' ') &&
272 			    (*p != '\t') && (*p != '\n')))
273 				p++;
274 
275 			if (*p == '\0')
276 				p--;
277 			else
278 				*p = '\0';
279 		}
280 		p++;
281 	}
282 	*argc = num;
283 	*argv = arg->data;
284 	return (1);
285 }
286 
287 int
288 dump_cert_text(BIO *out, X509 *x)
289 {
290 	char *p;
291 
292 	p = X509_NAME_oneline(X509_get_subject_name(x), NULL, 0);
293 	BIO_puts(out, "subject=");
294 	BIO_puts(out, p);
295 	free(p);
296 
297 	p = X509_NAME_oneline(X509_get_issuer_name(x), NULL, 0);
298 	BIO_puts(out, "\nissuer=");
299 	BIO_puts(out, p);
300 	BIO_puts(out, "\n");
301 	free(p);
302 
303 	return 0;
304 }
305 
306 static int
307 ui_open(UI *ui)
308 {
309 	return UI_method_get_opener(UI_OpenSSL()) (ui);
310 }
311 
312 static int
313 ui_read(UI *ui, UI_STRING *uis)
314 {
315 	if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD &&
316 	    UI_get0_user_data(ui)) {
317 		switch (UI_get_string_type(uis)) {
318 		case UIT_PROMPT:
319 		case UIT_VERIFY:
320 			{
321 				const char *password =
322 				    ((PW_CB_DATA *)UI_get0_user_data(ui))->password;
323 				if (password && password[0] != '\0') {
324 					UI_set_result(ui, uis, password);
325 					return 1;
326 				}
327 			}
328 			break;
329 		default:
330 			break;
331 		}
332 	}
333 	return UI_method_get_reader(UI_OpenSSL()) (ui, uis);
334 }
335 
336 static int
337 ui_write(UI *ui, UI_STRING *uis)
338 {
339 	if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD &&
340 	    UI_get0_user_data(ui)) {
341 		switch (UI_get_string_type(uis)) {
342 		case UIT_PROMPT:
343 		case UIT_VERIFY:
344 			{
345 				const char *password =
346 				    ((PW_CB_DATA *)UI_get0_user_data(ui))->password;
347 				if (password && password[0] != '\0')
348 					return 1;
349 			}
350 			break;
351 		default:
352 			break;
353 		}
354 	}
355 	return UI_method_get_writer(UI_OpenSSL()) (ui, uis);
356 }
357 
358 static int
359 ui_close(UI *ui)
360 {
361 	return UI_method_get_closer(UI_OpenSSL()) (ui);
362 }
363 
364 int
365 setup_ui_method(void)
366 {
367 	ui_method = UI_create_method("OpenSSL application user interface");
368 	UI_method_set_opener(ui_method, ui_open);
369 	UI_method_set_reader(ui_method, ui_read);
370 	UI_method_set_writer(ui_method, ui_write);
371 	UI_method_set_closer(ui_method, ui_close);
372 	return 0;
373 }
374 
375 void
376 destroy_ui_method(void)
377 {
378 	if (ui_method) {
379 		UI_destroy_method(ui_method);
380 		ui_method = NULL;
381 	}
382 }
383 
384 int
385 password_callback(char *buf, int bufsiz, int verify, void *arg)
386 {
387 	PW_CB_DATA *cb_tmp = arg;
388 	UI *ui = NULL;
389 	int res = 0;
390 	const char *prompt_info = NULL;
391 	const char *password = NULL;
392 	PW_CB_DATA *cb_data = (PW_CB_DATA *) cb_tmp;
393 
394 	if (cb_data) {
395 		if (cb_data->password)
396 			password = cb_data->password;
397 		if (cb_data->prompt_info)
398 			prompt_info = cb_data->prompt_info;
399 	}
400 	if (password) {
401 		res = strlen(password);
402 		if (res > bufsiz)
403 			res = bufsiz;
404 		memcpy(buf, password, res);
405 		return res;
406 	}
407 	ui = UI_new_method(ui_method);
408 	if (ui) {
409 		int ok = 0;
410 		char *buff = NULL;
411 		int ui_flags = 0;
412 		char *prompt = NULL;
413 
414 		prompt = UI_construct_prompt(ui, "pass phrase", prompt_info);
415 
416 		ui_flags |= UI_INPUT_FLAG_DEFAULT_PWD;
417 		UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0);
418 
419 		if (ok >= 0)
420 			ok = UI_add_input_string(ui, prompt, ui_flags, buf,
421 			    PW_MIN_LENGTH, bufsiz - 1);
422 		if (ok >= 0 && verify) {
423 			buff = malloc(bufsiz);
424 			ok = UI_add_verify_string(ui, prompt, ui_flags, buff,
425 			    PW_MIN_LENGTH, bufsiz - 1, buf);
426 		}
427 		if (ok >= 0)
428 			do {
429 				ok = UI_process(ui);
430 			} while (ok < 0 &&
431 			    UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0));
432 
433 		if (buff) {
434 			OPENSSL_cleanse(buff, (unsigned int) bufsiz);
435 			free(buff);
436 		}
437 		if (ok >= 0)
438 			res = strlen(buf);
439 		if (ok == -1) {
440 			BIO_printf(bio_err, "User interface error\n");
441 			ERR_print_errors(bio_err);
442 			OPENSSL_cleanse(buf, (unsigned int) bufsiz);
443 			res = 0;
444 		}
445 		if (ok == -2) {
446 			BIO_printf(bio_err, "aborted!\n");
447 			OPENSSL_cleanse(buf, (unsigned int) bufsiz);
448 			res = 0;
449 		}
450 		UI_free(ui);
451 		free(prompt);
452 	}
453 	return res;
454 }
455 
456 static char *app_get_pass(BIO *err, char *arg, int keepbio);
457 
458 int
459 app_passwd(BIO *err, char *arg1, char *arg2, char **pass1, char **pass2)
460 {
461 	int same;
462 
463 	if (!arg2 || !arg1 || strcmp(arg1, arg2))
464 		same = 0;
465 	else
466 		same = 1;
467 	if (arg1) {
468 		*pass1 = app_get_pass(err, arg1, same);
469 		if (!*pass1)
470 			return 0;
471 	} else if (pass1)
472 		*pass1 = NULL;
473 	if (arg2) {
474 		*pass2 = app_get_pass(err, arg2, same ? 2 : 0);
475 		if (!*pass2)
476 			return 0;
477 	} else if (pass2)
478 		*pass2 = NULL;
479 	return 1;
480 }
481 
482 static char *
483 app_get_pass(BIO *err, char *arg, int keepbio)
484 {
485 	char *tmp, tpass[APP_PASS_LEN];
486 	static BIO *pwdbio = NULL;
487 	const char *errstr = NULL;
488 	int i;
489 
490 	if (!strncmp(arg, "pass:", 5))
491 		return strdup(arg + 5);
492 	if (!strncmp(arg, "env:", 4)) {
493 		tmp = getenv(arg + 4);
494 		if (!tmp) {
495 			BIO_printf(err, "Can't read environment variable %s\n",
496 			    arg + 4);
497 			return NULL;
498 		}
499 		return strdup(tmp);
500 	}
501 	if (!keepbio || !pwdbio) {
502 		if (!strncmp(arg, "file:", 5)) {
503 			pwdbio = BIO_new_file(arg + 5, "r");
504 			if (!pwdbio) {
505 				BIO_printf(err, "Can't open file %s\n",
506 				    arg + 5);
507 				return NULL;
508 			}
509 		} else if (!strncmp(arg, "fd:", 3)) {
510 			BIO *btmp;
511 			i = strtonum(arg + 3, 0, INT_MAX, &errstr);
512 			if (errstr) {
513 				BIO_printf(err,
514 				    "Invalid file descriptor %s: %s\n",
515 				    arg, errstr);
516 				return NULL;
517 			}
518 			pwdbio = BIO_new_fd(i, BIO_NOCLOSE);
519 			if (!pwdbio) {
520 				BIO_printf(err,
521 				    "Can't access file descriptor %s\n",
522 				    arg + 3);
523 				return NULL;
524 			}
525 			/*
526 			 * Can't do BIO_gets on an fd BIO so add a buffering
527 			 * BIO
528 			 */
529 			btmp = BIO_new(BIO_f_buffer());
530 			pwdbio = BIO_push(btmp, pwdbio);
531 		} else if (!strcmp(arg, "stdin")) {
532 			pwdbio = BIO_new_fp(stdin, BIO_NOCLOSE);
533 			if (!pwdbio) {
534 				BIO_printf(err, "Can't open BIO for stdin\n");
535 				return NULL;
536 			}
537 		} else {
538 			BIO_printf(err, "Invalid password argument \"%s\"\n",
539 			    arg);
540 			return NULL;
541 		}
542 	}
543 	i = BIO_gets(pwdbio, tpass, APP_PASS_LEN);
544 	if (keepbio != 1) {
545 		BIO_free_all(pwdbio);
546 		pwdbio = NULL;
547 	}
548 	if (i <= 0) {
549 		BIO_printf(err, "Error reading password from BIO\n");
550 		return NULL;
551 	}
552 	tmp = strchr(tpass, '\n');
553 	if (tmp)
554 		*tmp = 0;
555 	return strdup(tpass);
556 }
557 
558 int
559 add_oid_section(BIO *err, CONF *conf)
560 {
561 	char *p;
562 	STACK_OF(CONF_VALUE) *sktmp;
563 	CONF_VALUE *cnf;
564 	int i;
565 
566 	if (!(p = NCONF_get_string(conf, NULL, "oid_section"))) {
567 		ERR_clear_error();
568 		return 1;
569 	}
570 	if (!(sktmp = NCONF_get_section(conf, p))) {
571 		BIO_printf(err, "problem loading oid section %s\n", p);
572 		return 0;
573 	}
574 	for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) {
575 		cnf = sk_CONF_VALUE_value(sktmp, i);
576 		if (OBJ_create(cnf->value, cnf->name, cnf->name) == NID_undef) {
577 			BIO_printf(err, "problem creating object %s=%s\n",
578 			    cnf->name, cnf->value);
579 			return 0;
580 		}
581 	}
582 	return 1;
583 }
584 
585 static int
586 load_pkcs12(BIO *err, BIO *in, const char *desc, pem_password_cb *pem_cb,
587     void *cb_data, EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca)
588 {
589 	const char *pass;
590 	char tpass[PEM_BUFSIZE];
591 	int len, ret = 0;
592 	PKCS12 *p12;
593 
594 	p12 = d2i_PKCS12_bio(in, NULL);
595 	if (p12 == NULL) {
596 		BIO_printf(err, "Error loading PKCS12 file for %s\n", desc);
597 		goto die;
598 	}
599 	/* See if an empty password will do */
600 	if (PKCS12_verify_mac(p12, "", 0) || PKCS12_verify_mac(p12, NULL, 0))
601 		pass = "";
602 	else {
603 		if (!pem_cb)
604 			pem_cb = password_callback;
605 		len = pem_cb(tpass, PEM_BUFSIZE, 0, cb_data);
606 		if (len < 0) {
607 			BIO_printf(err, "Passpharse callback error for %s\n",
608 			    desc);
609 			goto die;
610 		}
611 		if (len < PEM_BUFSIZE)
612 			tpass[len] = 0;
613 		if (!PKCS12_verify_mac(p12, tpass, len)) {
614 			BIO_printf(err,
615 			    "Mac verify error (wrong password?) in PKCS12 file for %s\n", desc);
616 			goto die;
617 		}
618 		pass = tpass;
619 	}
620 	ret = PKCS12_parse(p12, pass, pkey, cert, ca);
621 
622 die:
623 	if (p12)
624 		PKCS12_free(p12);
625 	return ret;
626 }
627 
628 X509 *
629 load_cert(BIO *err, const char *file, int format, const char *pass, ENGINE *e,
630     const char *cert_descrip)
631 {
632 	X509 *x = NULL;
633 	BIO *cert;
634 
635 	if ((cert = BIO_new(BIO_s_file())) == NULL) {
636 		ERR_print_errors(err);
637 		goto end;
638 	}
639 	if (file == NULL) {
640 		setvbuf(stdin, NULL, _IONBF, 0);
641 		BIO_set_fp(cert, stdin, BIO_NOCLOSE);
642 	} else {
643 		if (BIO_read_filename(cert, file) <= 0) {
644 			BIO_printf(err, "Error opening %s %s\n",
645 			    cert_descrip, file);
646 			ERR_print_errors(err);
647 			goto end;
648 		}
649 	}
650 
651 	if (format == FORMAT_ASN1)
652 		x = d2i_X509_bio(cert, NULL);
653 	else if (format == FORMAT_NETSCAPE) {
654 		NETSCAPE_X509 *nx;
655 		nx = ASN1_item_d2i_bio(ASN1_ITEM_rptr(NETSCAPE_X509),
656 		    cert, NULL);
657 		if (nx == NULL)
658 			goto end;
659 
660 		if ((strncmp(NETSCAPE_CERT_HDR, (char *) nx->header->data,
661 		    nx->header->length) != 0)) {
662 			NETSCAPE_X509_free(nx);
663 			BIO_printf(err,
664 			    "Error reading header on certificate\n");
665 			goto end;
666 		}
667 		x = nx->cert;
668 		nx->cert = NULL;
669 		NETSCAPE_X509_free(nx);
670 	} else if (format == FORMAT_PEM)
671 		x = PEM_read_bio_X509_AUX(cert, NULL, password_callback, NULL);
672 	else if (format == FORMAT_PKCS12) {
673 		if (!load_pkcs12(err, cert, cert_descrip, NULL, NULL,
674 		    NULL, &x, NULL))
675 			goto end;
676 	} else {
677 		BIO_printf(err, "bad input format specified for %s\n",
678 		    cert_descrip);
679 		goto end;
680 	}
681 
682 end:
683 	if (x == NULL) {
684 		BIO_printf(err, "unable to load certificate\n");
685 		ERR_print_errors(err);
686 	}
687 	BIO_free(cert);
688 	return (x);
689 }
690 
691 EVP_PKEY *
692 load_key(BIO *err, const char *file, int format, int maybe_stdin,
693     const char *pass, ENGINE *e, const char *key_descrip)
694 {
695 	BIO *key = NULL;
696 	EVP_PKEY *pkey = NULL;
697 	PW_CB_DATA cb_data;
698 
699 	cb_data.password = pass;
700 	cb_data.prompt_info = file;
701 
702 	if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE)) {
703 		BIO_printf(err, "no keyfile specified\n");
704 		goto end;
705 	}
706 #ifndef OPENSSL_NO_ENGINE
707 	if (format == FORMAT_ENGINE) {
708 		if (!e)
709 			BIO_printf(err, "no engine specified\n");
710 		else {
711 			pkey = ENGINE_load_private_key(e, file,
712 			    ui_method, &cb_data);
713 			if (!pkey) {
714 				BIO_printf(err, "cannot load %s from engine\n",
715 				    key_descrip);
716 				ERR_print_errors(err);
717 			}
718 		}
719 		goto end;
720 	}
721 #endif
722 	key = BIO_new(BIO_s_file());
723 	if (key == NULL) {
724 		ERR_print_errors(err);
725 		goto end;
726 	}
727 	if (file == NULL && maybe_stdin) {
728 		setvbuf(stdin, NULL, _IONBF, 0);
729 		BIO_set_fp(key, stdin, BIO_NOCLOSE);
730 	} else if (BIO_read_filename(key, file) <= 0) {
731 		BIO_printf(err, "Error opening %s %s\n",
732 		    key_descrip, file);
733 		ERR_print_errors(err);
734 		goto end;
735 	}
736 	if (format == FORMAT_ASN1) {
737 		pkey = d2i_PrivateKey_bio(key, NULL);
738 	} else if (format == FORMAT_PEM) {
739 		pkey = PEM_read_bio_PrivateKey(key, NULL, password_callback, &cb_data);
740 	}
741 #if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
742 	else if (format == FORMAT_NETSCAPE || format == FORMAT_IISSGC)
743 		pkey = load_netscape_key(err, key, file, key_descrip, format);
744 #endif
745 	else if (format == FORMAT_PKCS12) {
746 		if (!load_pkcs12(err, key, key_descrip, password_callback, &cb_data,
747 		    &pkey, NULL, NULL))
748 			goto end;
749 	}
750 #if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA) && !defined (OPENSSL_NO_RC4)
751 	else if (format == FORMAT_MSBLOB)
752 		pkey = b2i_PrivateKey_bio(key);
753 	else if (format == FORMAT_PVK)
754 		pkey = b2i_PVK_bio(key, password_callback,
755 		    &cb_data);
756 #endif
757 	else {
758 		BIO_printf(err, "bad input format specified for key file\n");
759 		goto end;
760 	}
761 end:
762 	BIO_free(key);
763 	if (pkey == NULL) {
764 		BIO_printf(err, "unable to load %s\n", key_descrip);
765 		ERR_print_errors(err);
766 	}
767 	return (pkey);
768 }
769 
770 EVP_PKEY *
771 load_pubkey(BIO *err, const char *file, int format, int maybe_stdin,
772     const char *pass, ENGINE *e, const char *key_descrip)
773 {
774 	BIO *key = NULL;
775 	EVP_PKEY *pkey = NULL;
776 	PW_CB_DATA cb_data;
777 
778 	cb_data.password = pass;
779 	cb_data.prompt_info = file;
780 
781 	if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE)) {
782 		BIO_printf(err, "no keyfile specified\n");
783 		goto end;
784 	}
785 #ifndef OPENSSL_NO_ENGINE
786 	if (format == FORMAT_ENGINE) {
787 		if (!e)
788 			BIO_printf(bio_err, "no engine specified\n");
789 		else
790 			pkey = ENGINE_load_public_key(e, file,
791 			    ui_method, &cb_data);
792 		goto end;
793 	}
794 #endif
795 	key = BIO_new(BIO_s_file());
796 	if (key == NULL) {
797 		ERR_print_errors(err);
798 		goto end;
799 	}
800 	if (file == NULL && maybe_stdin) {
801 		setvbuf(stdin, NULL, _IONBF, 0);
802 		BIO_set_fp(key, stdin, BIO_NOCLOSE);
803 	} else if (BIO_read_filename(key, file) <= 0) {
804 		BIO_printf(err, "Error opening %s %s\n", key_descrip, file);
805 		ERR_print_errors(err);
806 		goto end;
807 	}
808 	if (format == FORMAT_ASN1) {
809 		pkey = d2i_PUBKEY_bio(key, NULL);
810 	}
811 	else if (format == FORMAT_ASN1RSA) {
812 		RSA *rsa;
813 		rsa = d2i_RSAPublicKey_bio(key, NULL);
814 		if (rsa) {
815 			pkey = EVP_PKEY_new();
816 			if (pkey)
817 				EVP_PKEY_set1_RSA(pkey, rsa);
818 			RSA_free(rsa);
819 		} else
820 			pkey = NULL;
821 	} else if (format == FORMAT_PEMRSA) {
822 		RSA *rsa;
823 		rsa = PEM_read_bio_RSAPublicKey(key, NULL, password_callback, &cb_data);
824 		if (rsa) {
825 			pkey = EVP_PKEY_new();
826 			if (pkey)
827 				EVP_PKEY_set1_RSA(pkey, rsa);
828 			RSA_free(rsa);
829 		} else
830 			pkey = NULL;
831 	}
832 	else if (format == FORMAT_PEM) {
833 		pkey = PEM_read_bio_PUBKEY(key, NULL, password_callback, &cb_data);
834 	}
835 #if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
836 	else if (format == FORMAT_NETSCAPE || format == FORMAT_IISSGC)
837 		pkey = load_netscape_key(err, key, file, key_descrip, format);
838 #endif
839 #if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA)
840 	else if (format == FORMAT_MSBLOB)
841 		pkey = b2i_PublicKey_bio(key);
842 #endif
843 	else {
844 		BIO_printf(err, "bad input format specified for key file\n");
845 		goto end;
846 	}
847 
848 end:
849 	BIO_free(key);
850 	if (pkey == NULL)
851 		BIO_printf(err, "unable to load %s\n", key_descrip);
852 	return (pkey);
853 }
854 
855 #if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
856 static EVP_PKEY *
857 load_netscape_key(BIO *err, BIO *key, const char *file,
858     const char *key_descrip, int format)
859 {
860 	EVP_PKEY *pkey;
861 	BUF_MEM *buf;
862 	RSA *rsa;
863 	const unsigned char *p;
864 	int size, i;
865 
866 	buf = BUF_MEM_new();
867 	pkey = EVP_PKEY_new();
868 	size = 0;
869 	if (buf == NULL || pkey == NULL)
870 		goto error;
871 	for (;;) {
872 		if (!BUF_MEM_grow_clean(buf, size + 1024 * 10))
873 			goto error;
874 		i = BIO_read(key, &(buf->data[size]), 1024 * 10);
875 		size += i;
876 		if (i == 0)
877 			break;
878 		if (i < 0) {
879 			BIO_printf(err, "Error reading %s %s",
880 			    key_descrip, file);
881 			goto error;
882 		}
883 	}
884 	p = (unsigned char *) buf->data;
885 	rsa = d2i_RSA_NET(NULL, &p, (long) size, NULL,
886 	    (format == FORMAT_IISSGC ? 1 : 0));
887 	if (rsa == NULL)
888 		goto error;
889 	BUF_MEM_free(buf);
890 	EVP_PKEY_set1_RSA(pkey, rsa);
891 	return pkey;
892 
893 error:
894 	BUF_MEM_free(buf);
895 	EVP_PKEY_free(pkey);
896 	return NULL;
897 }
898 #endif				/* ndef OPENSSL_NO_RC4 */
899 
900 static int
901 load_certs_crls(BIO *err, const char *file, int format, const char *pass,
902     ENGINE *e, const char *desc, STACK_OF(X509) **pcerts,
903     STACK_OF(X509_CRL) **pcrls)
904 {
905 	int i;
906 	BIO *bio;
907 	STACK_OF(X509_INFO) *xis = NULL;
908 	X509_INFO *xi;
909 	PW_CB_DATA cb_data;
910 	int rv = 0;
911 
912 	cb_data.password = pass;
913 	cb_data.prompt_info = file;
914 
915 	if (format != FORMAT_PEM) {
916 		BIO_printf(err, "bad input format specified for %s\n", desc);
917 		return 0;
918 	}
919 	if (file == NULL)
920 		bio = BIO_new_fp(stdin, BIO_NOCLOSE);
921 	else
922 		bio = BIO_new_file(file, "r");
923 
924 	if (bio == NULL) {
925 		BIO_printf(err, "Error opening %s %s\n",
926 		    desc, file ? file : "stdin");
927 		ERR_print_errors(err);
928 		return 0;
929 	}
930 	xis = PEM_X509_INFO_read_bio(bio, NULL, password_callback, &cb_data);
931 
932 	BIO_free(bio);
933 
934 	if (pcerts) {
935 		*pcerts = sk_X509_new_null();
936 		if (!*pcerts)
937 			goto end;
938 	}
939 	if (pcrls) {
940 		*pcrls = sk_X509_CRL_new_null();
941 		if (!*pcrls)
942 			goto end;
943 	}
944 	for (i = 0; i < sk_X509_INFO_num(xis); i++) {
945 		xi = sk_X509_INFO_value(xis, i);
946 		if (xi->x509 && pcerts) {
947 			if (!sk_X509_push(*pcerts, xi->x509))
948 				goto end;
949 			xi->x509 = NULL;
950 		}
951 		if (xi->crl && pcrls) {
952 			if (!sk_X509_CRL_push(*pcrls, xi->crl))
953 				goto end;
954 			xi->crl = NULL;
955 		}
956 	}
957 
958 	if (pcerts && sk_X509_num(*pcerts) > 0)
959 		rv = 1;
960 
961 	if (pcrls && sk_X509_CRL_num(*pcrls) > 0)
962 		rv = 1;
963 
964 end:
965 	if (xis)
966 		sk_X509_INFO_pop_free(xis, X509_INFO_free);
967 
968 	if (rv == 0) {
969 		if (pcerts) {
970 			sk_X509_pop_free(*pcerts, X509_free);
971 			*pcerts = NULL;
972 		}
973 		if (pcrls) {
974 			sk_X509_CRL_pop_free(*pcrls, X509_CRL_free);
975 			*pcrls = NULL;
976 		}
977 		BIO_printf(err, "unable to load %s\n",
978 		    pcerts ? "certificates" : "CRLs");
979 		ERR_print_errors(err);
980 	}
981 	return rv;
982 }
983 
984 STACK_OF(X509) *
985 load_certs(BIO *err, const char *file, int format, const char *pass,
986     ENGINE *e, const char *desc)
987 {
988 	STACK_OF(X509) *certs;
989 
990 	if (!load_certs_crls(err, file, format, pass, e, desc, &certs, NULL))
991 		return NULL;
992 	return certs;
993 }
994 
995 STACK_OF(X509_CRL) *
996 load_crls(BIO *err, const char *file, int format, const char *pass, ENGINE *e,
997     const char *desc)
998 {
999 	STACK_OF(X509_CRL) *crls;
1000 
1001 	if (!load_certs_crls(err, file, format, pass, e, desc, NULL, &crls))
1002 		return NULL;
1003 	return crls;
1004 }
1005 
1006 #define X509V3_EXT_UNKNOWN_MASK		(0xfL << 16)
1007 /* Return error for unknown extensions */
1008 #define X509V3_EXT_DEFAULT		0
1009 /* Print error for unknown extensions */
1010 #define X509V3_EXT_ERROR_UNKNOWN	(1L << 16)
1011 /* ASN1 parse unknown extensions */
1012 #define X509V3_EXT_PARSE_UNKNOWN	(2L << 16)
1013 /* BIO_dump unknown extensions */
1014 #define X509V3_EXT_DUMP_UNKNOWN		(3L << 16)
1015 
1016 #define X509_FLAG_CA (X509_FLAG_NO_ISSUER | X509_FLAG_NO_PUBKEY | \
1017 			 X509_FLAG_NO_HEADER | X509_FLAG_NO_VERSION)
1018 
1019 int
1020 set_cert_ex(unsigned long *flags, const char *arg)
1021 {
1022 	static const NAME_EX_TBL cert_tbl[] = {
1023 		{"compatible", X509_FLAG_COMPAT, 0xffffffffl},
1024 		{"ca_default", X509_FLAG_CA, 0xffffffffl},
1025 		{"no_header", X509_FLAG_NO_HEADER, 0},
1026 		{"no_version", X509_FLAG_NO_VERSION, 0},
1027 		{"no_serial", X509_FLAG_NO_SERIAL, 0},
1028 		{"no_signame", X509_FLAG_NO_SIGNAME, 0},
1029 		{"no_validity", X509_FLAG_NO_VALIDITY, 0},
1030 		{"no_subject", X509_FLAG_NO_SUBJECT, 0},
1031 		{"no_issuer", X509_FLAG_NO_ISSUER, 0},
1032 		{"no_pubkey", X509_FLAG_NO_PUBKEY, 0},
1033 		{"no_extensions", X509_FLAG_NO_EXTENSIONS, 0},
1034 		{"no_sigdump", X509_FLAG_NO_SIGDUMP, 0},
1035 		{"no_aux", X509_FLAG_NO_AUX, 0},
1036 		{"no_attributes", X509_FLAG_NO_ATTRIBUTES, 0},
1037 		{"ext_default", X509V3_EXT_DEFAULT, X509V3_EXT_UNKNOWN_MASK},
1038 		{"ext_error", X509V3_EXT_ERROR_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
1039 		{"ext_parse", X509V3_EXT_PARSE_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
1040 		{"ext_dump", X509V3_EXT_DUMP_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
1041 		{NULL, 0, 0}
1042 	};
1043 	return set_multi_opts(flags, arg, cert_tbl);
1044 }
1045 
1046 int
1047 set_name_ex(unsigned long *flags, const char *arg)
1048 {
1049 	static const NAME_EX_TBL ex_tbl[] = {
1050 		{"esc_2253", ASN1_STRFLGS_ESC_2253, 0},
1051 		{"esc_ctrl", ASN1_STRFLGS_ESC_CTRL, 0},
1052 		{"esc_msb", ASN1_STRFLGS_ESC_MSB, 0},
1053 		{"use_quote", ASN1_STRFLGS_ESC_QUOTE, 0},
1054 		{"utf8", ASN1_STRFLGS_UTF8_CONVERT, 0},
1055 		{"ignore_type", ASN1_STRFLGS_IGNORE_TYPE, 0},
1056 		{"show_type", ASN1_STRFLGS_SHOW_TYPE, 0},
1057 		{"dump_all", ASN1_STRFLGS_DUMP_ALL, 0},
1058 		{"dump_nostr", ASN1_STRFLGS_DUMP_UNKNOWN, 0},
1059 		{"dump_der", ASN1_STRFLGS_DUMP_DER, 0},
1060 		{"compat", XN_FLAG_COMPAT, 0xffffffffL},
1061 		{"sep_comma_plus", XN_FLAG_SEP_COMMA_PLUS, XN_FLAG_SEP_MASK},
1062 		{"sep_comma_plus_space", XN_FLAG_SEP_CPLUS_SPC, XN_FLAG_SEP_MASK},
1063 		{"sep_semi_plus_space", XN_FLAG_SEP_SPLUS_SPC, XN_FLAG_SEP_MASK},
1064 		{"sep_multiline", XN_FLAG_SEP_MULTILINE, XN_FLAG_SEP_MASK},
1065 		{"dn_rev", XN_FLAG_DN_REV, 0},
1066 		{"nofname", XN_FLAG_FN_NONE, XN_FLAG_FN_MASK},
1067 		{"sname", XN_FLAG_FN_SN, XN_FLAG_FN_MASK},
1068 		{"lname", XN_FLAG_FN_LN, XN_FLAG_FN_MASK},
1069 		{"align", XN_FLAG_FN_ALIGN, 0},
1070 		{"oid", XN_FLAG_FN_OID, XN_FLAG_FN_MASK},
1071 		{"space_eq", XN_FLAG_SPC_EQ, 0},
1072 		{"dump_unknown", XN_FLAG_DUMP_UNKNOWN_FIELDS, 0},
1073 		{"RFC2253", XN_FLAG_RFC2253, 0xffffffffL},
1074 		{"oneline", XN_FLAG_ONELINE, 0xffffffffL},
1075 		{"multiline", XN_FLAG_MULTILINE, 0xffffffffL},
1076 		{"ca_default", XN_FLAG_MULTILINE, 0xffffffffL},
1077 		{NULL, 0, 0}
1078 	};
1079 	return set_multi_opts(flags, arg, ex_tbl);
1080 }
1081 
1082 int
1083 set_ext_copy(int *copy_type, const char *arg)
1084 {
1085 	if (!strcasecmp(arg, "none"))
1086 		*copy_type = EXT_COPY_NONE;
1087 	else if (!strcasecmp(arg, "copy"))
1088 		*copy_type = EXT_COPY_ADD;
1089 	else if (!strcasecmp(arg, "copyall"))
1090 		*copy_type = EXT_COPY_ALL;
1091 	else
1092 		return 0;
1093 	return 1;
1094 }
1095 
1096 int
1097 copy_extensions(X509 *x, X509_REQ *req, int copy_type)
1098 {
1099 	STACK_OF(X509_EXTENSION) *exts = NULL;
1100 	X509_EXTENSION *ext, *tmpext;
1101 	ASN1_OBJECT *obj;
1102 	int i, idx, ret = 0;
1103 
1104 	if (!x || !req || (copy_type == EXT_COPY_NONE))
1105 		return 1;
1106 	exts = X509_REQ_get_extensions(req);
1107 
1108 	for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
1109 		ext = sk_X509_EXTENSION_value(exts, i);
1110 		obj = X509_EXTENSION_get_object(ext);
1111 		idx = X509_get_ext_by_OBJ(x, obj, -1);
1112 		/* Does extension exist? */
1113 		if (idx != -1) {
1114 			/* If normal copy don't override existing extension */
1115 			if (copy_type == EXT_COPY_ADD)
1116 				continue;
1117 			/* Delete all extensions of same type */
1118 			do {
1119 				tmpext = X509_get_ext(x, idx);
1120 				X509_delete_ext(x, idx);
1121 				X509_EXTENSION_free(tmpext);
1122 				idx = X509_get_ext_by_OBJ(x, obj, -1);
1123 			} while (idx != -1);
1124 		}
1125 		if (!X509_add_ext(x, ext, -1))
1126 			goto end;
1127 	}
1128 
1129 	ret = 1;
1130 
1131 end:
1132 	sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
1133 
1134 	return ret;
1135 }
1136 
1137 static int
1138 set_multi_opts(unsigned long *flags, const char *arg,
1139     const NAME_EX_TBL *in_tbl)
1140 {
1141 	STACK_OF(CONF_VALUE) *vals;
1142 	CONF_VALUE *val;
1143 	int i, ret = 1;
1144 
1145 	if (!arg)
1146 		return 0;
1147 	vals = X509V3_parse_list(arg);
1148 	for (i = 0; i < sk_CONF_VALUE_num(vals); i++) {
1149 		val = sk_CONF_VALUE_value(vals, i);
1150 		if (!set_table_opts(flags, val->name, in_tbl))
1151 			ret = 0;
1152 	}
1153 	sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
1154 	return ret;
1155 }
1156 
1157 static int
1158 set_table_opts(unsigned long *flags, const char *arg,
1159     const NAME_EX_TBL *in_tbl)
1160 {
1161 	char c;
1162 	const NAME_EX_TBL *ptbl;
1163 
1164 	c = arg[0];
1165 	if (c == '-') {
1166 		c = 0;
1167 		arg++;
1168 	} else if (c == '+') {
1169 		c = 1;
1170 		arg++;
1171 	} else
1172 		c = 1;
1173 
1174 	for (ptbl = in_tbl; ptbl->name; ptbl++) {
1175 		if (!strcasecmp(arg, ptbl->name)) {
1176 			*flags &= ~ptbl->mask;
1177 			if (c)
1178 				*flags |= ptbl->flag;
1179 			else
1180 				*flags &= ~ptbl->flag;
1181 			return 1;
1182 		}
1183 	}
1184 	return 0;
1185 }
1186 
1187 void
1188 print_name(BIO *out, const char *title, X509_NAME *nm, unsigned long lflags)
1189 {
1190 	char *buf;
1191 	char mline = 0;
1192 	int indent = 0;
1193 
1194 	if (title)
1195 		BIO_puts(out, title);
1196 	if ((lflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
1197 		mline = 1;
1198 		indent = 4;
1199 	}
1200 	if (lflags == XN_FLAG_COMPAT) {
1201 		buf = X509_NAME_oneline(nm, 0, 0);
1202 		BIO_puts(out, buf);
1203 		BIO_puts(out, "\n");
1204 		free(buf);
1205 	} else {
1206 		if (mline)
1207 			BIO_puts(out, "\n");
1208 		X509_NAME_print_ex(out, nm, indent, lflags);
1209 		BIO_puts(out, "\n");
1210 	}
1211 }
1212 
1213 X509_STORE *
1214 setup_verify(BIO *bp, char *CAfile, char *CApath)
1215 {
1216 	X509_STORE *store;
1217 	X509_LOOKUP *lookup;
1218 
1219 	if (!(store = X509_STORE_new()))
1220 		goto end;
1221 	lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
1222 	if (lookup == NULL)
1223 		goto end;
1224 	if (CAfile) {
1225 		if (!X509_LOOKUP_load_file(lookup, CAfile, X509_FILETYPE_PEM)) {
1226 			BIO_printf(bp, "Error loading file %s\n", CAfile);
1227 			goto end;
1228 		}
1229 	} else
1230 		X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT);
1231 
1232 	lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
1233 	if (lookup == NULL)
1234 		goto end;
1235 	if (CApath) {
1236 		if (!X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM)) {
1237 			BIO_printf(bp, "Error loading directory %s\n", CApath);
1238 			goto end;
1239 		}
1240 	} else
1241 		X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT);
1242 
1243 	ERR_clear_error();
1244 	return store;
1245 
1246 end:
1247 	X509_STORE_free(store);
1248 	return NULL;
1249 }
1250 
1251 #ifndef OPENSSL_NO_ENGINE
1252 /* Try to load an engine in a shareable library */
1253 static ENGINE *
1254 try_load_engine(BIO *err, const char *engine, int debug)
1255 {
1256 	ENGINE *e = ENGINE_by_id("dynamic");
1257 
1258 	if (e) {
1259 		if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", engine, 0) ||
1260 		    !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0)) {
1261 			ENGINE_free(e);
1262 			e = NULL;
1263 		}
1264 	}
1265 	return e;
1266 }
1267 
1268 ENGINE *
1269 setup_engine(BIO *err, const char *engine, int debug)
1270 {
1271 	ENGINE *e = NULL;
1272 
1273 	if (engine) {
1274 		if (strcmp(engine, "auto") == 0) {
1275 			BIO_printf(err, "enabling auto ENGINE support\n");
1276 			ENGINE_register_all_complete();
1277 			return NULL;
1278 		}
1279 		if ((e = ENGINE_by_id(engine)) == NULL &&
1280 		    (e = try_load_engine(err, engine, debug)) == NULL) {
1281 			BIO_printf(err, "invalid engine \"%s\"\n", engine);
1282 			ERR_print_errors(err);
1283 			return NULL;
1284 		}
1285 		if (debug) {
1286 			ENGINE_ctrl(e, ENGINE_CTRL_SET_LOGSTREAM,
1287 			    0, err, 0);
1288 		}
1289 		ENGINE_ctrl_cmd(e, "SET_USER_INTERFACE", 0, ui_method, 0, 1);
1290 		if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
1291 			BIO_printf(err, "can't use that engine\n");
1292 			ERR_print_errors(err);
1293 			ENGINE_free(e);
1294 			return NULL;
1295 		}
1296 		BIO_printf(err, "engine \"%s\" set.\n", ENGINE_get_id(e));
1297 
1298 		/* Free our "structural" reference. */
1299 		ENGINE_free(e);
1300 	}
1301 	return e;
1302 }
1303 #endif
1304 
1305 int
1306 load_config(BIO *err, CONF *cnf)
1307 {
1308 	static int load_config_called = 0;
1309 
1310 	if (load_config_called)
1311 		return 1;
1312 	load_config_called = 1;
1313 	if (cnf == NULL)
1314 		cnf = config;
1315 	if (cnf == NULL)
1316 		return 1;
1317 
1318 	OPENSSL_load_builtin_modules();
1319 
1320 	if (CONF_modules_load(cnf, NULL, 0) <= 0) {
1321 		BIO_printf(err, "Error configuring OpenSSL\n");
1322 		ERR_print_errors(err);
1323 		return 0;
1324 	}
1325 	return 1;
1326 }
1327 
1328 char *
1329 make_config_name()
1330 {
1331 	const char *t = X509_get_default_cert_area();
1332 	char *p;
1333 
1334 	if (asprintf(&p, "%s/openssl.cnf", t) == -1)
1335 		return NULL;
1336 	return p;
1337 }
1338 
1339 static unsigned long
1340 index_serial_hash(const OPENSSL_CSTRING *a)
1341 {
1342 	const char *n;
1343 
1344 	n = a[DB_serial];
1345 	while (*n == '0')
1346 		n++;
1347 	return (lh_strhash(n));
1348 }
1349 
1350 static int
1351 index_serial_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b)
1352 {
1353 	const char *aa, *bb;
1354 
1355 	for (aa = a[DB_serial]; *aa == '0'; aa++)
1356 		;
1357 	for (bb = b[DB_serial]; *bb == '0'; bb++)
1358 		;
1359 	return (strcmp(aa, bb));
1360 }
1361 
1362 static int
1363 index_name_qual(char **a)
1364 {
1365 	return (a[0][0] == 'V');
1366 }
1367 
1368 static unsigned long
1369 index_name_hash(const OPENSSL_CSTRING *a)
1370 {
1371 	return (lh_strhash(a[DB_name]));
1372 }
1373 
1374 int
1375 index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b)
1376 {
1377 	return (strcmp(a[DB_name], b[DB_name]));
1378 }
1379 
1380 static IMPLEMENT_LHASH_HASH_FN(index_serial, OPENSSL_CSTRING)
1381 static IMPLEMENT_LHASH_COMP_FN(index_serial, OPENSSL_CSTRING)
1382 static IMPLEMENT_LHASH_HASH_FN(index_name, OPENSSL_CSTRING)
1383 static IMPLEMENT_LHASH_COMP_FN(index_name, OPENSSL_CSTRING)
1384 
1385 #define BSIZE 256
1386 
1387 BIGNUM *
1388 load_serial(char *serialfile, int create, ASN1_INTEGER **retai)
1389 {
1390 	BIO *in = NULL;
1391 	BIGNUM *ret = NULL;
1392 	char buf[1024];
1393 	ASN1_INTEGER *ai = NULL;
1394 
1395 	ai = ASN1_INTEGER_new();
1396 	if (ai == NULL)
1397 		goto err;
1398 
1399 	if ((in = BIO_new(BIO_s_file())) == NULL) {
1400 		ERR_print_errors(bio_err);
1401 		goto err;
1402 	}
1403 	if (BIO_read_filename(in, serialfile) <= 0) {
1404 		if (!create) {
1405 			perror(serialfile);
1406 			goto err;
1407 		} else {
1408 			ret = BN_new();
1409 			if (ret == NULL || !rand_serial(ret, ai))
1410 				BIO_printf(bio_err, "Out of memory\n");
1411 		}
1412 	} else {
1413 		if (!a2i_ASN1_INTEGER(in, ai, buf, 1024)) {
1414 			BIO_printf(bio_err, "unable to load number from %s\n",
1415 			    serialfile);
1416 			goto err;
1417 		}
1418 		ret = ASN1_INTEGER_to_BN(ai, NULL);
1419 		if (ret == NULL) {
1420 			BIO_printf(bio_err,
1421 			    "error converting number from bin to BIGNUM\n");
1422 			goto err;
1423 		}
1424 	}
1425 
1426 	if (ret && retai) {
1427 		*retai = ai;
1428 		ai = NULL;
1429 	}
1430 
1431 err:
1432 	if (in != NULL)
1433 		BIO_free(in);
1434 	if (ai != NULL)
1435 		ASN1_INTEGER_free(ai);
1436 	return (ret);
1437 }
1438 
1439 int
1440 save_serial(char *serialfile, char *suffix, BIGNUM *serial,
1441     ASN1_INTEGER **retai)
1442 {
1443 	char buf[1][BSIZE];
1444 	BIO *out = NULL;
1445 	int ret = 0, n;
1446 	ASN1_INTEGER *ai = NULL;
1447 	int j;
1448 
1449 	if (suffix == NULL)
1450 		j = strlen(serialfile);
1451 	else
1452 		j = strlen(serialfile) + strlen(suffix) + 1;
1453 	if (j >= BSIZE) {
1454 		BIO_printf(bio_err, "file name too long\n");
1455 		goto err;
1456 	}
1457 	if (suffix == NULL)
1458 		n = strlcpy(buf[0], serialfile, BSIZE);
1459 	else
1460 		n = snprintf(buf[0], sizeof buf[0], "%s.%s",
1461 		    serialfile, suffix);
1462 	if (n == -1 || n >= sizeof(buf[0])) {
1463 		BIO_printf(bio_err, "serial too long\n");
1464 		goto err;
1465 	}
1466 	out = BIO_new(BIO_s_file());
1467 	if (out == NULL) {
1468 		ERR_print_errors(bio_err);
1469 		goto err;
1470 	}
1471 	if (BIO_write_filename(out, buf[0]) <= 0) {
1472 		perror(serialfile);
1473 		goto err;
1474 	}
1475 	if ((ai = BN_to_ASN1_INTEGER(serial, NULL)) == NULL) {
1476 		BIO_printf(bio_err,
1477 		    "error converting serial to ASN.1 format\n");
1478 		goto err;
1479 	}
1480 	i2a_ASN1_INTEGER(out, ai);
1481 	BIO_puts(out, "\n");
1482 	ret = 1;
1483 	if (retai) {
1484 		*retai = ai;
1485 		ai = NULL;
1486 	}
1487 
1488 err:
1489 	if (out != NULL)
1490 		BIO_free_all(out);
1491 	if (ai != NULL)
1492 		ASN1_INTEGER_free(ai);
1493 	return (ret);
1494 }
1495 
1496 int
1497 rotate_serial(char *serialfile, char *new_suffix, char *old_suffix)
1498 {
1499 	char buf[5][BSIZE];
1500 	int i, j;
1501 
1502 	i = strlen(serialfile) + strlen(old_suffix);
1503 	j = strlen(serialfile) + strlen(new_suffix);
1504 	if (i > j)
1505 		j = i;
1506 	if (j + 1 >= BSIZE) {
1507 		BIO_printf(bio_err, "file name too long\n");
1508 		goto err;
1509 	}
1510 	snprintf(buf[0], sizeof buf[0], "%s.%s", serialfile, new_suffix);
1511 	snprintf(buf[1], sizeof buf[1], "%s.%s", serialfile, old_suffix);
1512 
1513 
1514 	if (rename(serialfile, buf[1]) < 0 &&
1515 	    errno != ENOENT && errno != ENOTDIR) {
1516 		BIO_printf(bio_err, "unable to rename %s to %s\n",
1517 		    serialfile, buf[1]);
1518 		perror("reason");
1519 		goto err;
1520 	}
1521 
1522 
1523 	if (rename(buf[0], serialfile) < 0) {
1524 		BIO_printf(bio_err, "unable to rename %s to %s\n",
1525 		    buf[0], serialfile);
1526 		perror("reason");
1527 		rename(buf[1], serialfile);
1528 		goto err;
1529 	}
1530 	return 1;
1531 
1532 err:
1533 	return 0;
1534 }
1535 
1536 int
1537 rand_serial(BIGNUM *b, ASN1_INTEGER *ai)
1538 {
1539 	BIGNUM *btmp;
1540 	int ret = 0;
1541 
1542 	if (b)
1543 		btmp = b;
1544 	else
1545 		btmp = BN_new();
1546 
1547 	if (!btmp)
1548 		return 0;
1549 
1550 	if (!BN_pseudo_rand(btmp, SERIAL_RAND_BITS, 0, 0))
1551 		goto error;
1552 	if (ai && !BN_to_ASN1_INTEGER(btmp, ai))
1553 		goto error;
1554 
1555 	ret = 1;
1556 
1557 error:
1558 	if (!b)
1559 		BN_free(btmp);
1560 
1561 	return ret;
1562 }
1563 
1564 CA_DB *
1565 load_index(char *dbfile, DB_ATTR *db_attr)
1566 {
1567 	CA_DB *retdb = NULL;
1568 	TXT_DB *tmpdb = NULL;
1569 	BIO *in = BIO_new(BIO_s_file());
1570 	CONF *dbattr_conf = NULL;
1571 	char buf[1][BSIZE];
1572 	long errorline = -1;
1573 
1574 	if (in == NULL) {
1575 		ERR_print_errors(bio_err);
1576 		goto err;
1577 	}
1578 	if (BIO_read_filename(in, dbfile) <= 0) {
1579 		perror(dbfile);
1580 		BIO_printf(bio_err, "unable to open '%s'\n", dbfile);
1581 		goto err;
1582 	}
1583 	if ((tmpdb = TXT_DB_read(in, DB_NUMBER)) == NULL)
1584 		goto err;
1585 
1586 	snprintf(buf[0], sizeof buf[0], "%s.attr", dbfile);
1587 	dbattr_conf = NCONF_new(NULL);
1588 	if (NCONF_load(dbattr_conf, buf[0], &errorline) <= 0) {
1589 		if (errorline > 0) {
1590 			BIO_printf(bio_err,
1591 			    "error on line %ld of db attribute file '%s'\n",
1592 			    errorline, buf[0]);
1593 			goto err;
1594 		} else {
1595 			NCONF_free(dbattr_conf);
1596 			dbattr_conf = NULL;
1597 		}
1598 	}
1599 	if ((retdb = malloc(sizeof(CA_DB))) == NULL) {
1600 		fprintf(stderr, "Out of memory\n");
1601 		goto err;
1602 	}
1603 	retdb->db = tmpdb;
1604 	tmpdb = NULL;
1605 	if (db_attr)
1606 		retdb->attributes = *db_attr;
1607 	else {
1608 		retdb->attributes.unique_subject = 1;
1609 	}
1610 
1611 	if (dbattr_conf) {
1612 		char *p = NCONF_get_string(dbattr_conf, NULL, "unique_subject");
1613 		if (p) {
1614 			retdb->attributes.unique_subject = parse_yesno(p, 1);
1615 		}
1616 	}
1617 
1618 err:
1619 	if (dbattr_conf)
1620 		NCONF_free(dbattr_conf);
1621 	if (tmpdb)
1622 		TXT_DB_free(tmpdb);
1623 	if (in)
1624 		BIO_free_all(in);
1625 	return retdb;
1626 }
1627 
1628 int
1629 index_index(CA_DB *db)
1630 {
1631 	if (!TXT_DB_create_index(db->db, DB_serial, NULL,
1632 	    LHASH_HASH_FN(index_serial), LHASH_COMP_FN(index_serial))) {
1633 		BIO_printf(bio_err,
1634 		    "error creating serial number index:(%ld,%ld,%ld)\n",
1635 		    db->db->error, db->db->arg1, db->db->arg2);
1636 		return 0;
1637 	}
1638 	if (db->attributes.unique_subject &&
1639 	    !TXT_DB_create_index(db->db, DB_name, index_name_qual,
1640 	    LHASH_HASH_FN(index_name), LHASH_COMP_FN(index_name))) {
1641 		BIO_printf(bio_err, "error creating name index:(%ld,%ld,%ld)\n",
1642 		    db->db->error, db->db->arg1, db->db->arg2);
1643 		return 0;
1644 	}
1645 	return 1;
1646 }
1647 
1648 int
1649 save_index(const char *dbfile, const char *suffix, CA_DB *db)
1650 {
1651 	char buf[3][BSIZE];
1652 	BIO *out = BIO_new(BIO_s_file());
1653 	int j;
1654 
1655 	if (out == NULL) {
1656 		ERR_print_errors(bio_err);
1657 		goto err;
1658 	}
1659 	j = strlen(dbfile) + strlen(suffix);
1660 	if (j + 6 >= BSIZE) {
1661 		BIO_printf(bio_err, "file name too long\n");
1662 		goto err;
1663 	}
1664 	snprintf(buf[2], sizeof buf[2], "%s.attr", dbfile);
1665 	snprintf(buf[1], sizeof buf[1], "%s.attr.%s", dbfile, suffix);
1666 	snprintf(buf[0], sizeof buf[0], "%s.%s", dbfile, suffix);
1667 
1668 
1669 	if (BIO_write_filename(out, buf[0]) <= 0) {
1670 		perror(dbfile);
1671 		BIO_printf(bio_err, "unable to open '%s'\n", dbfile);
1672 		goto err;
1673 	}
1674 	j = TXT_DB_write(out, db->db);
1675 	if (j <= 0)
1676 		goto err;
1677 
1678 	BIO_free(out);
1679 
1680 	out = BIO_new(BIO_s_file());
1681 
1682 
1683 	if (BIO_write_filename(out, buf[1]) <= 0) {
1684 		perror(buf[2]);
1685 		BIO_printf(bio_err, "unable to open '%s'\n", buf[2]);
1686 		goto err;
1687 	}
1688 	BIO_printf(out, "unique_subject = %s\n",
1689 	    db->attributes.unique_subject ? "yes" : "no");
1690 	BIO_free(out);
1691 
1692 	return 1;
1693 
1694 err:
1695 	return 0;
1696 }
1697 
1698 int
1699 rotate_index(const char *dbfile, const char *new_suffix, const char *old_suffix)
1700 {
1701 	char buf[5][BSIZE];
1702 	int i, j;
1703 
1704 	i = strlen(dbfile) + strlen(old_suffix);
1705 	j = strlen(dbfile) + strlen(new_suffix);
1706 	if (i > j)
1707 		j = i;
1708 	if (j + 6 >= BSIZE) {
1709 		BIO_printf(bio_err, "file name too long\n");
1710 		goto err;
1711 	}
1712 	snprintf(buf[4], sizeof buf[4], "%s.attr", dbfile);
1713 	snprintf(buf[2], sizeof buf[2], "%s.attr.%s", dbfile, new_suffix);
1714 	snprintf(buf[0], sizeof buf[0], "%s.%s", dbfile, new_suffix);
1715 	snprintf(buf[1], sizeof buf[1], "%s.%s", dbfile, old_suffix);
1716 	snprintf(buf[3], sizeof buf[3], "%s.attr.%s", dbfile, old_suffix);
1717 
1718 
1719 	if (rename(dbfile, buf[1]) < 0 && errno != ENOENT && errno != ENOTDIR) {
1720 		BIO_printf(bio_err, "unable to rename %s to %s\n",
1721 		    dbfile, buf[1]);
1722 		perror("reason");
1723 		goto err;
1724 	}
1725 
1726 
1727 	if (rename(buf[0], dbfile) < 0) {
1728 		BIO_printf(bio_err, "unable to rename %s to %s\n",
1729 		    buf[0], dbfile);
1730 		perror("reason");
1731 		rename(buf[1], dbfile);
1732 		goto err;
1733 	}
1734 
1735 
1736 	if (rename(buf[4], buf[3]) < 0 && errno != ENOENT && errno != ENOTDIR) {
1737 		BIO_printf(bio_err, "unable to rename %s to %s\n",
1738 		    buf[4], buf[3]);
1739 		perror("reason");
1740 		rename(dbfile, buf[0]);
1741 		rename(buf[1], dbfile);
1742 		goto err;
1743 	}
1744 
1745 
1746 	if (rename(buf[2], buf[4]) < 0) {
1747 		BIO_printf(bio_err, "unable to rename %s to %s\n",
1748 		    buf[2], buf[4]);
1749 		perror("reason");
1750 		rename(buf[3], buf[4]);
1751 		rename(dbfile, buf[0]);
1752 		rename(buf[1], dbfile);
1753 		goto err;
1754 	}
1755 	return 1;
1756 
1757 err:
1758 	return 0;
1759 }
1760 
1761 void
1762 free_index(CA_DB *db)
1763 {
1764 	if (db) {
1765 		if (db->db)
1766 			TXT_DB_free(db->db);
1767 		free(db);
1768 	}
1769 }
1770 
1771 int
1772 parse_yesno(const char *str, int def)
1773 {
1774 	int ret = def;
1775 
1776 	if (str) {
1777 		switch (*str) {
1778 		case 'f':	/* false */
1779 		case 'F':	/* FALSE */
1780 		case 'n':	/* no */
1781 		case 'N':	/* NO */
1782 		case '0':	/* 0 */
1783 			ret = 0;
1784 			break;
1785 		case 't':	/* true */
1786 		case 'T':	/* TRUE */
1787 		case 'y':	/* yes */
1788 		case 'Y':	/* YES */
1789 		case '1':	/* 1 */
1790 			ret = 1;
1791 			break;
1792 		default:
1793 			ret = def;
1794 			break;
1795 		}
1796 	}
1797 	return ret;
1798 }
1799 
1800 /*
1801  * subject is expected to be in the format /type0=value0/type1=value1/type2=...
1802  * where characters may be escaped by \
1803  */
1804 X509_NAME *
1805 parse_name(char *subject, long chtype, int multirdn)
1806 {
1807 	X509_NAME *name = NULL;
1808 	size_t buflen, max_ne;
1809 	char **ne_types, **ne_values;
1810 	char *buf, *bp, *sp;
1811 	int i, nid, ne_num = 0;
1812 	int *mval;
1813 
1814 	/*
1815 	 * Buffer to copy the types and values into. Due to escaping the
1816 	 * copy can only become shorter.
1817 	 */
1818 	buflen = strlen(subject) + 1;
1819 	buf = malloc(buflen);
1820 
1821 	/* Maximum number of name elements. */
1822 	max_ne = buflen / 2 + 1;
1823 	ne_types = reallocarray(NULL, max_ne, sizeof(char *));
1824 	ne_values = reallocarray(NULL, max_ne, sizeof(char *));
1825 	mval = reallocarray(NULL, max_ne, sizeof(int));
1826 
1827 	if (buf == NULL || ne_types == NULL || ne_values == NULL ||
1828 	    mval == NULL) {
1829 		BIO_printf(bio_err, "malloc error\n");
1830 		goto error;
1831 	}
1832 
1833 	bp = buf;
1834 	sp = subject;
1835 
1836 	if (*subject != '/') {
1837 		BIO_printf(bio_err, "Subject does not start with '/'.\n");
1838 		goto error;
1839 	}
1840 
1841 	/* Skip leading '/'. */
1842 	sp++;
1843 
1844 	/* No multivalued RDN by default. */
1845 	mval[ne_num] = 0;
1846 
1847 	while (*sp) {
1848 		/* Collect type. */
1849 		ne_types[ne_num] = bp;
1850 		while (*sp) {
1851 			/* is there anything to escape in the type...? */
1852 			if (*sp == '\\') {
1853 				if (*++sp)
1854 					*bp++ = *sp++;
1855 				else {
1856 					BIO_printf(bio_err, "escape character "
1857 					    "at end of string\n");
1858 					goto error;
1859 				}
1860 			} else if (*sp == '=') {
1861 				sp++;
1862 				*bp++ = '\0';
1863 				break;
1864 			} else
1865 				*bp++ = *sp++;
1866 		}
1867 		if (!*sp) {
1868 			BIO_printf(bio_err, "end of string encountered while "
1869 			    "processing type of subject name element #%d\n",
1870 			    ne_num);
1871 			goto error;
1872 		}
1873 		ne_values[ne_num] = bp;
1874 		while (*sp) {
1875 			if (*sp == '\\') {
1876 				if (*++sp)
1877 					*bp++ = *sp++;
1878 				else {
1879 					BIO_printf(bio_err, "escape character "
1880 					    "at end of string\n");
1881 					goto error;
1882 				}
1883 			} else if (*sp == '/') {
1884 				sp++;
1885 				/* no multivalued RDN by default */
1886 				mval[ne_num + 1] = 0;
1887 				break;
1888 			} else if (*sp == '+' && multirdn) {
1889 				/* a not escaped + signals a mutlivalued RDN */
1890 				sp++;
1891 				mval[ne_num + 1] = -1;
1892 				break;
1893 			} else
1894 				*bp++ = *sp++;
1895 		}
1896 		*bp++ = '\0';
1897 		ne_num++;
1898 	}
1899 
1900 	if ((name = X509_NAME_new()) == NULL)
1901 		goto error;
1902 
1903 	for (i = 0; i < ne_num; i++) {
1904 		if ((nid = OBJ_txt2nid(ne_types[i])) == NID_undef) {
1905 			BIO_printf(bio_err,
1906 			    "Subject Attribute %s has no known NID, skipped\n",
1907 			    ne_types[i]);
1908 			continue;
1909 		}
1910 		if (!*ne_values[i]) {
1911 			BIO_printf(bio_err, "No value provided for Subject "
1912 			    "Attribute %s, skipped\n", ne_types[i]);
1913 			continue;
1914 		}
1915 		if (!X509_NAME_add_entry_by_NID(name, nid, chtype,
1916 		    (unsigned char *) ne_values[i], -1, -1, mval[i]))
1917 			goto error;
1918 	}
1919 	goto done;
1920 
1921 error:
1922 	X509_NAME_free(name);
1923 	name = NULL;
1924 
1925 done:
1926 	free(ne_values);
1927 	free(ne_types);
1928 	free(mval);
1929 	free(buf);
1930 
1931 	return name;
1932 }
1933 
1934 int
1935 args_verify(char ***pargs, int *pargc, int *badarg, BIO *err,
1936     X509_VERIFY_PARAM **pm)
1937 {
1938 	ASN1_OBJECT *otmp = NULL;
1939 	unsigned long flags = 0;
1940 	int i;
1941 	int purpose = 0, depth = -1;
1942 	char **oldargs = *pargs;
1943 	char *arg = **pargs, *argn = (*pargs)[1];
1944 	time_t at_time = 0;
1945 	const char *errstr = NULL;
1946 
1947 	if (!strcmp(arg, "-policy")) {
1948 		if (!argn)
1949 			*badarg = 1;
1950 		else {
1951 			otmp = OBJ_txt2obj(argn, 0);
1952 			if (!otmp) {
1953 				BIO_printf(err, "Invalid Policy \"%s\"\n",
1954 				    argn);
1955 				*badarg = 1;
1956 			}
1957 		}
1958 		(*pargs)++;
1959 	} else if (strcmp(arg, "-purpose") == 0) {
1960 		X509_PURPOSE *xptmp;
1961 		if (!argn)
1962 			*badarg = 1;
1963 		else {
1964 			i = X509_PURPOSE_get_by_sname(argn);
1965 			if (i < 0) {
1966 				BIO_printf(err, "unrecognized purpose\n");
1967 				*badarg = 1;
1968 			} else {
1969 				xptmp = X509_PURPOSE_get0(i);
1970 				purpose = X509_PURPOSE_get_id(xptmp);
1971 			}
1972 		}
1973 		(*pargs)++;
1974 	} else if (strcmp(arg, "-verify_depth") == 0) {
1975 		if (!argn)
1976 			*badarg = 1;
1977 		else {
1978 			depth = strtonum(argn, 1, INT_MAX, &errstr);
1979 			if (errstr) {
1980 				BIO_printf(err, "invalid depth %s: %s\n",
1981 				    argn, errstr);
1982 				*badarg = 1;
1983 			}
1984 		}
1985 		(*pargs)++;
1986 	} else if (strcmp(arg, "-attime") == 0) {
1987 		if (!argn)
1988 			*badarg = 1;
1989 		else {
1990 			long long timestamp;
1991 			/*
1992 			 * interpret the -attime argument as seconds since
1993 			 * Epoch
1994 			 */
1995 			if (sscanf(argn, "%lli", &timestamp) != 1) {
1996 				BIO_printf(bio_err,
1997 				    "Error parsing timestamp %s\n",
1998 				    argn);
1999 				*badarg = 1;
2000 			}
2001 			/* XXX 2038 truncation */
2002 			at_time = (time_t) timestamp;
2003 		}
2004 		(*pargs)++;
2005 	} else if (!strcmp(arg, "-ignore_critical"))
2006 		flags |= X509_V_FLAG_IGNORE_CRITICAL;
2007 	else if (!strcmp(arg, "-issuer_checks"))
2008 		flags |= X509_V_FLAG_CB_ISSUER_CHECK;
2009 	else if (!strcmp(arg, "-crl_check"))
2010 		flags |= X509_V_FLAG_CRL_CHECK;
2011 	else if (!strcmp(arg, "-crl_check_all"))
2012 		flags |= X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL;
2013 	else if (!strcmp(arg, "-policy_check"))
2014 		flags |= X509_V_FLAG_POLICY_CHECK;
2015 	else if (!strcmp(arg, "-explicit_policy"))
2016 		flags |= X509_V_FLAG_EXPLICIT_POLICY;
2017 	else if (!strcmp(arg, "-inhibit_any"))
2018 		flags |= X509_V_FLAG_INHIBIT_ANY;
2019 	else if (!strcmp(arg, "-inhibit_map"))
2020 		flags |= X509_V_FLAG_INHIBIT_MAP;
2021 	else if (!strcmp(arg, "-x509_strict"))
2022 		flags |= X509_V_FLAG_X509_STRICT;
2023 	else if (!strcmp(arg, "-extended_crl"))
2024 		flags |= X509_V_FLAG_EXTENDED_CRL_SUPPORT;
2025 	else if (!strcmp(arg, "-use_deltas"))
2026 		flags |= X509_V_FLAG_USE_DELTAS;
2027 	else if (!strcmp(arg, "-policy_print"))
2028 		flags |= X509_V_FLAG_NOTIFY_POLICY;
2029 	else if (!strcmp(arg, "-check_ss_sig"))
2030 		flags |= X509_V_FLAG_CHECK_SS_SIGNATURE;
2031 	else
2032 		return 0;
2033 
2034 	if (*badarg) {
2035 		if (*pm)
2036 			X509_VERIFY_PARAM_free(*pm);
2037 		*pm = NULL;
2038 		goto end;
2039 	}
2040 	if (!*pm && !(*pm = X509_VERIFY_PARAM_new())) {
2041 		*badarg = 1;
2042 		goto end;
2043 	}
2044 	if (otmp)
2045 		X509_VERIFY_PARAM_add0_policy(*pm, otmp);
2046 	if (flags)
2047 		X509_VERIFY_PARAM_set_flags(*pm, flags);
2048 
2049 	if (purpose)
2050 		X509_VERIFY_PARAM_set_purpose(*pm, purpose);
2051 
2052 	if (depth >= 0)
2053 		X509_VERIFY_PARAM_set_depth(*pm, depth);
2054 
2055 	if (at_time)
2056 		X509_VERIFY_PARAM_set_time(*pm, at_time);
2057 
2058 end:
2059 	(*pargs)++;
2060 
2061 	if (pargc)
2062 		*pargc -= *pargs - oldargs;
2063 
2064 	return 1;
2065 }
2066 
2067 /* Read whole contents of a BIO into an allocated memory buffer and
2068  * return it.
2069  */
2070 
2071 int
2072 bio_to_mem(unsigned char **out, int maxlen, BIO *in)
2073 {
2074 	BIO *mem;
2075 	int len, ret;
2076 	unsigned char tbuf[1024];
2077 
2078 	mem = BIO_new(BIO_s_mem());
2079 	if (!mem)
2080 		return -1;
2081 	for (;;) {
2082 		if ((maxlen != -1) && maxlen < 1024)
2083 			len = maxlen;
2084 		else
2085 			len = 1024;
2086 		len = BIO_read(in, tbuf, len);
2087 		if (len <= 0)
2088 			break;
2089 		if (BIO_write(mem, tbuf, len) != len) {
2090 			BIO_free(mem);
2091 			return -1;
2092 		}
2093 		maxlen -= len;
2094 
2095 		if (maxlen == 0)
2096 			break;
2097 	}
2098 	ret = BIO_get_mem_data(mem, (char **) out);
2099 	BIO_set_flags(mem, BIO_FLAGS_MEM_RDONLY);
2100 	BIO_free(mem);
2101 	return ret;
2102 }
2103 
2104 int
2105 pkey_ctrl_string(EVP_PKEY_CTX *ctx, char *value)
2106 {
2107 	int rv;
2108 	char *stmp, *vtmp = NULL;
2109 
2110 	if (value == NULL)
2111 		return -1;
2112 	stmp = strdup(value);
2113 	if (!stmp)
2114 		return -1;
2115 	vtmp = strchr(stmp, ':');
2116 	if (vtmp) {
2117 		*vtmp = 0;
2118 		vtmp++;
2119 	}
2120 	rv = EVP_PKEY_CTX_ctrl_str(ctx, stmp, vtmp);
2121 	free(stmp);
2122 
2123 	return rv;
2124 }
2125 
2126 static void
2127 nodes_print(BIO *out, const char *name, STACK_OF(X509_POLICY_NODE) *nodes)
2128 {
2129 	X509_POLICY_NODE *node;
2130 	int i;
2131 
2132 	BIO_printf(out, "%s Policies:", name);
2133 	if (nodes) {
2134 		BIO_puts(out, "\n");
2135 		for (i = 0; i < sk_X509_POLICY_NODE_num(nodes); i++) {
2136 			node = sk_X509_POLICY_NODE_value(nodes, i);
2137 			X509_POLICY_NODE_print(out, node, 2);
2138 		}
2139 	} else
2140 		BIO_puts(out, " <empty>\n");
2141 }
2142 
2143 void
2144 policies_print(BIO *out, X509_STORE_CTX *ctx)
2145 {
2146 	X509_POLICY_TREE *tree;
2147 	int explicit_policy;
2148 	int free_out = 0;
2149 
2150 	if (out == NULL) {
2151 		out = BIO_new_fp(stderr, BIO_NOCLOSE);
2152 		free_out = 1;
2153 	}
2154 	tree = X509_STORE_CTX_get0_policy_tree(ctx);
2155 	explicit_policy = X509_STORE_CTX_get_explicit_policy(ctx);
2156 
2157 	BIO_printf(out, "Require explicit Policy: %s\n",
2158 	    explicit_policy ? "True" : "False");
2159 
2160 	nodes_print(out, "Authority", X509_policy_tree_get0_policies(tree));
2161 	nodes_print(out, "User", X509_policy_tree_get0_user_policies(tree));
2162 	if (free_out)
2163 		BIO_free(out);
2164 }
2165 
2166 #if !defined(OPENSSL_NO_NEXTPROTONEG)
2167 /* next_protos_parse parses a comma separated list of strings into a string
2168  * in a format suitable for passing to SSL_CTX_set_next_protos_advertised.
2169  *   outlen: (output) set to the length of the resulting buffer on success.
2170  *   err: (maybe NULL) on failure, an error message line is written to this BIO.
2171  *   in: a NUL termianted string like "abc,def,ghi"
2172  *
2173  *   returns: a malloced buffer or NULL on failure.
2174  */
2175 unsigned char *
2176 next_protos_parse(unsigned short *outlen, const char *in)
2177 {
2178 	size_t len;
2179 	unsigned char *out;
2180 	size_t i, start = 0;
2181 
2182 	len = strlen(in);
2183 	if (len >= 65535)
2184 		return NULL;
2185 
2186 	out = malloc(strlen(in) + 1);
2187 	if (!out)
2188 		return NULL;
2189 
2190 	for (i = 0; i <= len; ++i) {
2191 		if (i == len || in[i] == ',') {
2192 			if (i - start > 255) {
2193 				free(out);
2194 				return NULL;
2195 			}
2196 			out[start] = i - start;
2197 			start = i + 1;
2198 		} else
2199 			out[i + 1] = in[i];
2200 	}
2201 
2202 	*outlen = len + 1;
2203 	return out;
2204 }
2205 #endif
2206 /* !OPENSSL_NO_NEXTPROTONEG */
2207 
2208 double
2209 app_tminterval(int stop, int usertime)
2210 {
2211 	double ret = 0;
2212 	struct tms rus;
2213 	clock_t now = times(&rus);
2214 	static clock_t tmstart;
2215 
2216 	if (usertime)
2217 		now = rus.tms_utime;
2218 
2219 	if (stop == TM_START)
2220 		tmstart = now;
2221 	else {
2222 		long int tck = sysconf(_SC_CLK_TCK);
2223 		ret = (now - tmstart) / (double) tck;
2224 	}
2225 
2226 	return (ret);
2227 }
2228 
2229 int
2230 app_isdir(const char *name)
2231 {
2232 	struct stat st;
2233 
2234 	if (stat(name, &st) == 0)
2235 		return S_ISDIR(st.st_mode);
2236 	return -1;
2237 }
2238 
2239 #define OPTION_WIDTH 18
2240 
2241 void
2242 options_usage(struct option *opts)
2243 {
2244 	const char *p, *q;
2245 	char optstr[32];
2246 	int i;
2247 
2248 	for (i = 0; opts[i].name != NULL; i++) {
2249 		if (opts[i].desc == NULL)
2250 			continue;
2251 
2252 		snprintf(optstr, sizeof(optstr), "-%s %s", opts[i].name,
2253 		    (opts[i].argname != NULL) ? opts[i].argname : "");
2254 		fprintf(stderr, " %-*s", OPTION_WIDTH, optstr);
2255 		if (strlen(optstr) > OPTION_WIDTH)
2256 			fprintf(stderr, "\n %-*s", OPTION_WIDTH, "");
2257 
2258 		p = opts[i].desc;
2259 		while ((q = strchr(p, '\n')) != NULL) {
2260 			fprintf(stderr, " %.*s", (int)(q - p), p);
2261 			fprintf(stderr, "\n %-*s", OPTION_WIDTH, "");
2262 			p = q + 1;
2263 		}
2264 		fprintf(stderr, " %s\n", p);
2265 	}
2266 }
2267 
2268 int
2269 options_parse(int argc, char **argv, struct option *opts, char **unnamed)
2270 {
2271 	const char *errstr;
2272 	struct option *opt;
2273 	long long val;
2274 	char *arg, *p;
2275 	int ord = 0;
2276 	int i, j;
2277 	int fmt;
2278 
2279 	for (i = 1; i < argc; i++) {
2280 		p = arg = argv[i];
2281 
2282 		if (*p++ != '-') {
2283 			if (unnamed == NULL)
2284 				goto unknown;
2285 			*unnamed = arg;
2286 			continue;
2287 		}
2288 		if (*p == '\0') /* XXX - end of named options. */
2289 			goto unknown;
2290 
2291 		for (j = 0; opts[j].name != NULL; j++) {
2292 			opt = &opts[j];
2293 			if (strcmp(p, opt->name) != 0)
2294 				continue;
2295 
2296 			if (opt->type == OPTION_ARG ||
2297 			    opt->type == OPTION_ARG_FORMAT ||
2298 			    opt->type == OPTION_ARG_FUNC ||
2299 			    opt->type == OPTION_ARG_INT) {
2300 				if (++i >= argc) {
2301 					fprintf(stderr,
2302 					    "missing %s argument for -%s\n",
2303 					    opt->argname, opt->name);
2304 					return (1);
2305 				}
2306 			}
2307 
2308 			switch (opt->type) {
2309 			case OPTION_ARG:
2310 				*opt->opt.arg = argv[i];
2311 				break;
2312 
2313 			case OPTION_ARG_FORMAT:
2314 				fmt = str2fmt(argv[i]);
2315 				if (fmt == FORMAT_UNDEF) {
2316 					fprintf(stderr,
2317 					    "unknown %s '%s' for -%s\n",
2318 					    opt->argname, argv[i], opt->name);
2319 					return (1);
2320 				}
2321 				*opt->opt.value = fmt;
2322 				break;
2323 
2324 			case OPTION_ARG_FUNC:
2325 				if (opt->func(opt, argv[i]) != 0)
2326 					return (1);
2327 				break;
2328 
2329 			case OPTION_ARG_INT:
2330 				val = strtonum(argv[i], 0, INT_MAX, &errstr);
2331 				if (errstr != NULL) {
2332 					fprintf(stderr,
2333 					    "%s %s argument for -%s\n",
2334 					    errstr, opt->argname, opt->name);
2335 					return (1);
2336 				}
2337 				*opt->opt.value = (int)val;
2338 				break;
2339 
2340 			case OPTION_FUNC:
2341 				if (opt->func(opt, NULL) != 0)
2342 					return (1);
2343 				break;
2344 
2345 			case OPTION_FLAG:
2346 				*opt->opt.flag = 1;
2347 				break;
2348 
2349 			case OPTION_FLAG_ORD:
2350 				*opt->opt.flag = ++ord;
2351 				break;
2352 
2353 			case OPTION_VALUE:
2354 				*opt->opt.value = opt->value;
2355 				break;
2356 
2357 			default:
2358 				fprintf(stderr,
2359 				    "option %s - unknown type %i\n",
2360 				    opt->name, opt->type);
2361 				return (1);
2362 			}
2363 
2364 			break;
2365 		}
2366 
2367 		if (opts[j].name == NULL)
2368 			goto unknown;
2369 	}
2370 
2371 	return (0);
2372 
2373 unknown:
2374 	fprintf(stderr, "unknown option '%s'\n", arg);
2375 	return (1);
2376 }
2377