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