xref: /openbsd/usr.bin/openssl/apps.c (revision 646e9a2f)
1 /* $OpenBSD: apps.c,v 1.69 2024/08/29 17:01:02 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 
150 typedef struct {
151 	const char *name;
152 	unsigned long flag;
153 	unsigned long mask;
154 } NAME_EX_TBL;
155 
156 UI_METHOD *ui_method = NULL;
157 
158 static int set_table_opts(unsigned long *flags, const char *arg,
159     const NAME_EX_TBL *in_tbl);
160 static int set_multi_opts(unsigned long *flags, const char *arg,
161     const NAME_EX_TBL *in_tbl);
162 
163 int
str2fmt(char * s)164 str2fmt(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 
189 void
program_name(char * in,char * out,int size)190 program_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 
202 int
dump_cert_text(BIO * out,X509 * x)203 dump_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 
221 int
ui_open(UI * ui)222 ui_open(UI *ui)
223 {
224 	return UI_method_get_opener(UI_OpenSSL()) (ui);
225 }
226 
227 int
ui_read(UI * ui,UI_STRING * uis)228 ui_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 
248 int
ui_write(UI * ui,UI_STRING * uis)249 ui_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 
267 int
ui_close(UI * ui)268 ui_close(UI *ui)
269 {
270 	return UI_method_get_closer(UI_OpenSSL()) (ui);
271 }
272 
273 int
password_callback(char * buf,int bufsiz,int verify,void * arg)274 password_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 
342 static char *app_get_pass(BIO *err, char *arg, int keepbio);
343 
344 int
app_passwd(BIO * err,char * arg1,char * arg2,char ** pass1,char ** pass2)345 app_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 
368 static char *
app_get_pass(BIO * err,char * arg,int keepbio)369 app_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 
444 int
add_oid_section(BIO * err,CONF * conf)445 add_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 
471 static int
load_pkcs12(BIO * err,BIO * in,const char * desc,pem_password_cb * pem_cb,void * cb_data,EVP_PKEY ** pkey,X509 ** cert,STACK_OF (X509)** ca)472 load_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 
513 X509 *
load_cert(BIO * err,const char * file,int format,const char * pass,const char * cert_descrip)514 load_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 
559 EVP_PKEY *
load_key(BIO * err,const char * file,int format,int maybe_stdin,const char * pass,const char * key_descrip)560 load_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 
618 EVP_PKEY *
load_pubkey(BIO * err,const char * file,int format,int maybe_stdin,const char * pass,const char * key_descrip)619 load_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 
689 static int
load_certs_crls(BIO * err,const char * file,int format,const char * pass,const char * desc,STACK_OF (X509)** pcerts,STACK_OF (X509_CRL)** pcrls)690 load_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 
STACK_OF(X509)772 STACK_OF(X509) *
773 load_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 
STACK_OF(X509_CRL)783 STACK_OF(X509_CRL) *
784 load_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 
807 int
set_cert_ex(unsigned long * flags,const char * arg)808 set_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 
834 int
set_name_ex(unsigned long * flags,const char * arg)835 set_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 
874 int
set_ext_copy(int * copy_type,const char * arg)875 set_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 
888 int
copy_extensions(X509 * x,X509_REQ * req,int copy_type)889 copy_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 
929 static int
set_multi_opts(unsigned long * flags,const char * arg,const NAME_EX_TBL * in_tbl)930 set_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 
949 static int
set_table_opts(unsigned long * flags,const char * arg,const NAME_EX_TBL * in_tbl)950 set_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 
979 void
print_name(BIO * out,const char * title,X509_NAME * nm,unsigned long lflags)980 print_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 
1005 X509_STORE *
setup_verify(BIO * bp,char * CAfile,char * CApath)1006 setup_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 
1043 int
load_config(BIO * err,CONF * cnf)1044 load_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_config(NULL);
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 
1066 char *
make_config_name(void)1067 make_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 
1077 static unsigned long
index_serial_hash(const OPENSSL_CSTRING * a)1078 index_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 
1088 static int
index_serial_cmp(const OPENSSL_CSTRING * a,const OPENSSL_CSTRING * b)1089 index_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 
1100 static int
index_name_qual(char ** a)1101 index_name_qual(char **a)
1102 {
1103 	return (a[0][0] == 'V');
1104 }
1105 
1106 static unsigned long
index_name_hash(const OPENSSL_CSTRING * a)1107 index_name_hash(const OPENSSL_CSTRING *a)
1108 {
1109 	return (lh_strhash(a[DB_name]));
1110 }
1111 
1112 int
index_name_cmp(const OPENSSL_CSTRING * a,const OPENSSL_CSTRING * b)1113 index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b)
1114 {
1115 	return (strcmp(a[DB_name], b[DB_name]));
1116 }
1117 
IMPLEMENT_LHASH_HASH_FN(index_serial,OPENSSL_CSTRING)1118 static IMPLEMENT_LHASH_HASH_FN(index_serial, OPENSSL_CSTRING)
1119 static IMPLEMENT_LHASH_COMP_FN(index_serial, OPENSSL_CSTRING)
1120 static IMPLEMENT_LHASH_HASH_FN(index_name, OPENSSL_CSTRING)
1121 static IMPLEMENT_LHASH_COMP_FN(index_name, OPENSSL_CSTRING)
1122 
1123 BIGNUM *
1124 load_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 
1173 int
save_serial(char * serialfile,char * suffix,BIGNUM * serial,ASN1_INTEGER ** retai)1174 save_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 
1219 int
rotate_serial(char * serialfile,char * new_suffix,char * old_suffix)1220 rotate_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 
1262 int
rand_serial(BIGNUM * b,ASN1_INTEGER * ai)1263 rand_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 
1290 CA_DB *
load_index(char * dbfile,DB_ATTR * db_attr)1291 load_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 
1356 int
index_index(CA_DB * db)1357 index_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 
1376 int
save_index(const char * file,const char * suffix,CA_DB * db)1377 save_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 
1426 int
rotate_index(const char * dbfile,const char * new_suffix,const char * old_suffix)1427 rotate_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 
1521 void
free_index(CA_DB * db)1522 free_index(CA_DB *db)
1523 {
1524 	if (db) {
1525 		TXT_DB_free(db->db);
1526 		free(db);
1527 	}
1528 }
1529 
1530 int
parse_yesno(const char * str,int def)1531 parse_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  */
1563 X509_NAME *
parse_name(char * subject,long chtype,int multirdn)1564 parse_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 
1693 int
args_verify(char *** pargs,int * pargc,int * badarg,BIO * err,X509_VERIFY_PARAM ** pm)1694 args_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 
1834 int
bio_to_mem(unsigned char ** out,int maxlen,BIO * in)1835 bio_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 
1867 int
pkey_ctrl_string(EVP_PKEY_CTX * ctx,char * value)1868 pkey_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  */
1898 unsigned char *
next_protos_parse(unsigned short * outlen,const char * in)1899 next_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 
1929 int
app_isdir(const char * name)1930 app_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 
1941 void
options_usage(const struct option * opts)1942 options_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 
1968 int
options_parse(int argc,char ** argv,const struct option * opts,char ** unnamed,int * argsused)1969 options_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 
2149 void
show_cipher(const OBJ_NAME * name,void * arg)2150 show_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