GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/openssl/apps.c Lines: 540 1138 47.5 %
Date: 2017-11-13 Branches: 329 799 41.2 %

Line Branch Exec Source
1
/* $OpenBSD: apps.c,v 1.44 2017/08/12 21:04:33 jsing Exp $ */
2
/*
3
 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
4
 *
5
 * Permission to use, copy, modify, and distribute this software for any
6
 * purpose with or without fee is hereby granted, provided that the above
7
 * copyright notice and this permission notice appear in all copies.
8
 *
9
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
 */
17
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
18
 * All rights reserved.
19
 *
20
 * This package is an SSL implementation written
21
 * by Eric Young (eay@cryptsoft.com).
22
 * The implementation was written so as to conform with Netscapes SSL.
23
 *
24
 * This library is free for commercial and non-commercial use as long as
25
 * the following conditions are aheared to.  The following conditions
26
 * apply to all code found in this distribution, be it the RC4, RSA,
27
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
28
 * included with this distribution is covered by the same copyright terms
29
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
30
 *
31
 * Copyright remains Eric Young's, and as such any Copyright notices in
32
 * the code are not to be removed.
33
 * If this package is used in a product, Eric Young should be given attribution
34
 * as the author of the parts of the library used.
35
 * This can be in the form of a textual message at program startup or
36
 * in documentation (online or textual) provided with the package.
37
 *
38
 * Redistribution and use in source and binary forms, with or without
39
 * modification, are permitted provided that the following conditions
40
 * are met:
41
 * 1. Redistributions of source code must retain the copyright
42
 *    notice, this list of conditions and the following disclaimer.
43
 * 2. Redistributions in binary form must reproduce the above copyright
44
 *    notice, this list of conditions and the following disclaimer in the
45
 *    documentation and/or other materials provided with the distribution.
46
 * 3. All advertising materials mentioning features or use of this software
47
 *    must display the following acknowledgement:
48
 *    "This product includes cryptographic software written by
49
 *     Eric Young (eay@cryptsoft.com)"
50
 *    The word 'cryptographic' can be left out if the rouines from the library
51
 *    being used are not cryptographic related :-).
52
 * 4. If you include any Windows specific code (or a derivative thereof) from
53
 *    the apps directory (application code) you must include an acknowledgement:
54
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
55
 *
56
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
57
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
58
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
59
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
60
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
61
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
62
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
63
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
64
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
65
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
66
 * SUCH DAMAGE.
67
 *
68
 * The licence and distribution terms for any publically available version or
69
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
70
 * copied and put under another distribution licence
71
 * [including the GNU Public Licence.]
72
 */
73
/* ====================================================================
74
 * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
75
 *
76
 * Redistribution and use in source and binary forms, with or without
77
 * modification, are permitted provided that the following conditions
78
 * are met:
79
 *
80
 * 1. Redistributions of source code must retain the above copyright
81
 *    notice, this list of conditions and the following disclaimer.
82
 *
83
 * 2. Redistributions in binary form must reproduce the above copyright
84
 *    notice, this list of conditions and the following disclaimer in
85
 *    the documentation and/or other materials provided with the
86
 *    distribution.
87
 *
88
 * 3. All advertising materials mentioning features or use of this
89
 *    software must display the following acknowledgment:
90
 *    "This product includes software developed by the OpenSSL Project
91
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
92
 *
93
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
94
 *    endorse or promote products derived from this software without
95
 *    prior written permission. For written permission, please contact
96
 *    openssl-core@openssl.org.
97
 *
98
 * 5. Products derived from this software may not be called "OpenSSL"
99
 *    nor may "OpenSSL" appear in their names without prior written
100
 *    permission of the OpenSSL Project.
101
 *
102
 * 6. Redistributions of any form whatsoever must retain the following
103
 *    acknowledgment:
104
 *    "This product includes software developed by the OpenSSL Project
105
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
106
 *
107
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
108
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
109
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
110
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
111
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
112
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
113
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
114
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
115
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
116
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
117
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
118
 * OF THE POSSIBILITY OF SUCH DAMAGE.
119
 * ====================================================================
120
 *
121
 * This product includes cryptographic software written by Eric Young
122
 * (eay@cryptsoft.com).  This product includes software written by Tim
123
 * Hudson (tjh@cryptsoft.com).
124
 *
125
 */
126
127
#include <sys/types.h>
128
#include <sys/stat.h>
129
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/safestack.h>
145
#include <openssl/x509.h>
146
#include <openssl/x509v3.h>
147
148
#include <openssl/rsa.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
#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
164
/* Looks like this stuff is worth moving into separate function */
165
static EVP_PKEY *load_netscape_key(BIO *err, BIO *key, const char *file,
166
    const char *key_descrip, int format);
167
#endif
168
169
int
170
str2fmt(char *s)
171
{
172
24
	if (s == NULL)
173
		return FORMAT_UNDEF;
174

16
	if ((*s == 'D') || (*s == 'd'))
175
8
		return (FORMAT_ASN1);
176

8
	else if ((*s == 'T') || (*s == 't'))
177
		return (FORMAT_TEXT);
178

8
	else if ((*s == 'N') || (*s == 'n'))
179
		return (FORMAT_NETSCAPE);
180

8
	else if ((*s == 'S') || (*s == 's'))
181
		return (FORMAT_SMIME);
182

8
	else if ((*s == 'M') || (*s == 'm'))
183
		return (FORMAT_MSBLOB);
184

8
	else if ((*s == '1') ||
185

8
	    (strcmp(s, "PKCS12") == 0) || (strcmp(s, "pkcs12") == 0) ||
186
8
	    (strcmp(s, "P12") == 0) || (strcmp(s, "p12") == 0))
187
		return (FORMAT_PKCS12);
188

4
	else if ((*s == 'P') || (*s == 'p')) {
189

8
		if (s[1] == 'V' || s[1] == 'v')
190
			return FORMAT_PVK;
191
		else
192
4
			return (FORMAT_PEM);
193
	} else
194
		return (FORMAT_UNDEF);
195
12
}
196
197
void
198
program_name(char *in, char *out, int size)
199
{
200
	char *p;
201
202
8390
	p = strrchr(in, '/');
203
4195
	if (p != NULL)
204
2708
		p++;
205
	else
206
		p = in;
207
4195
	strlcpy(out, p, size);
208
4195
}
209
210
int
211
chopup_args(ARGS *arg, char *buf, int *argc, char **argv[])
212
{
213
	int num, i;
214
	char *p;
215
216
16
	*argc = 0;
217
8
	*argv = NULL;
218
219
	i = 0;
220
8
	if (arg->count == 0) {
221
4
		arg->count = 20;
222
4
		arg->data = reallocarray(NULL, arg->count, sizeof(char *));
223
4
		if (arg->data == NULL)
224
			return 0;
225
	}
226
336
	for (i = 0; i < arg->count; i++)
227
160
		arg->data[i] = NULL;
228
229
	num = 0;
230
	p = buf;
231
16
	for (;;) {
232
		/* first scan over white space */
233
16
		if (!*p)
234
			break;
235


48
		while (*p && ((*p == ' ') || (*p == '\t') || (*p == '\n')))
236
			p++;
237
8
		if (!*p)
238
			break;
239
240
		/* The start of something good :-) */
241
8
		if (num >= arg->count) {
242
			char **tmp_p;
243
			int tlen = arg->count + 20;
244
			tmp_p = reallocarray(arg->data, tlen, sizeof(char *));
245
			if (tmp_p == NULL)
246
				return 0;
247
			arg->data = tmp_p;
248
			arg->count = tlen;
249
			/* initialize newly allocated data */
250
			for (i = num; i < arg->count; i++)
251
				arg->data[i] = NULL;
252
		}
253
8
		arg->data[num++] = p;
254
255
		/* now look for the end of this */
256

16
		if ((*p == '\'') || (*p == '\"')) {	/* scan for closing
257
							 * quote */
258
			i = *(p++);
259
			arg->data[num - 1]++;	/* jump over quote */
260
			while (*p && (*p != i))
261
				p++;
262
			*p = '\0';
263
		} else {
264

160
			while (*p && ((*p != ' ') &&
265
80
			    (*p != '\t') && (*p != '\n')))
266
32
				p++;
267
268
8
			if (*p == '\0')
269
				p--;
270
			else
271
8
				*p = '\0';
272
		}
273
8
		p++;
274
	}
275
8
	*argc = num;
276
8
	*argv = arg->data;
277
8
	return (1);
278
8
}
279
280
int
281
dump_cert_text(BIO *out, X509 *x)
282
{
283
	char *p;
284
285
24
	p = X509_NAME_oneline(X509_get_subject_name(x), NULL, 0);
286
12
	BIO_puts(out, "subject=");
287
12
	BIO_puts(out, p);
288
12
	free(p);
289
290
12
	p = X509_NAME_oneline(X509_get_issuer_name(x), NULL, 0);
291
12
	BIO_puts(out, "\nissuer=");
292
12
	BIO_puts(out, p);
293
12
	BIO_puts(out, "\n");
294
12
	free(p);
295
296
12
	return 0;
297
}
298
299
int
300
ui_open(UI *ui)
301
{
302
	return UI_method_get_opener(UI_OpenSSL()) (ui);
303
}
304
305
int
306
ui_read(UI *ui, UI_STRING *uis)
307
{
308
	const char *password;
309
	int string_type;
310
311
	if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD &&
312
	    UI_get0_user_data(ui)) {
313
		string_type = UI_get_string_type(uis);
314
		if (string_type == UIT_PROMPT || string_type == UIT_VERIFY) {
315
			password =
316
			    ((PW_CB_DATA *)UI_get0_user_data(ui))->password;
317
			if (password && password[0] != '\0') {
318
				UI_set_result(ui, uis, password);
319
				return 1;
320
			}
321
		}
322
	}
323
	return UI_method_get_reader(UI_OpenSSL()) (ui, uis);
324
}
325
326
int
327
ui_write(UI *ui, UI_STRING *uis)
328
{
329
	const char *password;
330
	int string_type;
331
332
	if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD &&
333
	    UI_get0_user_data(ui)) {
334
		string_type = UI_get_string_type(uis);
335
		if (string_type == UIT_PROMPT || string_type == UIT_VERIFY) {
336
			password =
337
			    ((PW_CB_DATA *)UI_get0_user_data(ui))->password;
338
			if (password && password[0] != '\0')
339
				return 1;
340
		}
341
	}
342
	return UI_method_get_writer(UI_OpenSSL()) (ui, uis);
343
}
344
345
int
346
ui_close(UI *ui)
347
{
348
	return UI_method_get_closer(UI_OpenSSL()) (ui);
349
}
350
351
int
352
password_callback(char *buf, int bufsiz, int verify, void *arg)
353
{
354
120
	PW_CB_DATA *cb_tmp = arg;
355
	UI *ui = NULL;
356
	int res = 0;
357
	const char *prompt_info = NULL;
358
	const char *password = NULL;
359
	PW_CB_DATA *cb_data = (PW_CB_DATA *) cb_tmp;
360
361
60
	if (cb_data) {
362
60
		if (cb_data->password)
363
60
			password = cb_data->password;
364
60
		if (cb_data->prompt_info)
365
60
			prompt_info = cb_data->prompt_info;
366
	}
367
60
	if (password) {
368
60
		res = strlen(password);
369
60
		if (res > bufsiz)
370
			res = bufsiz;
371
60
		memcpy(buf, password, res);
372
60
		return res;
373
	}
374
	ui = UI_new_method(ui_method);
375
	if (ui) {
376
		int ok = 0;
377
		char *buff = NULL;
378
		int ui_flags = 0;
379
		char *prompt = NULL;
380
381
		prompt = UI_construct_prompt(ui, "pass phrase", prompt_info);
382
383
		ui_flags |= UI_INPUT_FLAG_DEFAULT_PWD;
384
		UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0);
385
386
		if (ok >= 0)
387
			ok = UI_add_input_string(ui, prompt, ui_flags, buf,
388
			    PW_MIN_LENGTH, bufsiz - 1);
389
		if (ok >= 0 && verify) {
390
			buff = malloc(bufsiz);
391
			ok = UI_add_verify_string(ui, prompt, ui_flags, buff,
392
			    PW_MIN_LENGTH, bufsiz - 1, buf);
393
		}
394
		if (ok >= 0)
395
			do {
396
				ok = UI_process(ui);
397
			} while (ok < 0 &&
398
			    UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0));
399
400
		freezero(buff, (unsigned int) bufsiz);
401
		if (ok >= 0)
402
			res = strlen(buf);
403
		if (ok == -1) {
404
			BIO_printf(bio_err, "User interface error\n");
405
			ERR_print_errors(bio_err);
406
			explicit_bzero(buf, (unsigned int) bufsiz);
407
			res = 0;
408
		}
409
		if (ok == -2) {
410
			BIO_printf(bio_err, "aborted!\n");
411
			explicit_bzero(buf, (unsigned int) bufsiz);
412
			res = 0;
413
		}
414
		UI_free(ui);
415
		free(prompt);
416
	}
417
	return res;
418
60
}
419
420
static char *app_get_pass(BIO *err, char *arg, int keepbio);
421
422
int
423
app_passwd(BIO *err, char *arg1, char *arg2, char **pass1, char **pass2)
424
{
425
	int same;
426
427

2402
	if (!arg2 || !arg1 || strcmp(arg1, arg2))
428
1187
		same = 0;
429
	else
430
		same = 1;
431
1195
	if (arg1) {
432
484
		*pass1 = app_get_pass(err, arg1, same);
433
484
		if (!*pass1)
434
			return 0;
435
711
	} else if (pass1)
436
699
		*pass1 = NULL;
437
1195
	if (arg2) {
438
40
		*pass2 = app_get_pass(err, arg2, same ? 2 : 0);
439
40
		if (!*pass2)
440
			return 0;
441
1155
	} else if (pass2)
442
428
		*pass2 = NULL;
443
1195
	return 1;
444
1195
}
445
446
static char *
447
app_get_pass(BIO *err, char *arg, int keepbio)
448
{
449
1048
	char *tmp, tpass[APP_PASS_LEN];
450
	static BIO *pwdbio = NULL;
451
524
	const char *errstr = NULL;
452
	int i;
453
454
524
	if (!strncmp(arg, "pass:", 5))
455
524
		return strdup(arg + 5);
456
	if (!strncmp(arg, "env:", 4)) {
457
		tmp = getenv(arg + 4);
458
		if (!tmp) {
459
			BIO_printf(err, "Can't read environment variable %s\n",
460
			    arg + 4);
461
			return NULL;
462
		}
463
		return strdup(tmp);
464
	}
465
	if (!keepbio || !pwdbio) {
466
		if (!strncmp(arg, "file:", 5)) {
467
			pwdbio = BIO_new_file(arg + 5, "r");
468
			if (!pwdbio) {
469
				BIO_printf(err, "Can't open file %s\n",
470
				    arg + 5);
471
				return NULL;
472
			}
473
		} else if (!strncmp(arg, "fd:", 3)) {
474
			BIO *btmp;
475
			i = strtonum(arg + 3, 0, INT_MAX, &errstr);
476
			if (errstr) {
477
				BIO_printf(err,
478
				    "Invalid file descriptor %s: %s\n",
479
				    arg, errstr);
480
				return NULL;
481
			}
482
			pwdbio = BIO_new_fd(i, BIO_NOCLOSE);
483
			if (!pwdbio) {
484
				BIO_printf(err,
485
				    "Can't access file descriptor %s\n",
486
				    arg + 3);
487
				return NULL;
488
			}
489
			/*
490
			 * Can't do BIO_gets on an fd BIO so add a buffering
491
			 * BIO
492
			 */
493
			btmp = BIO_new(BIO_f_buffer());
494
			pwdbio = BIO_push(btmp, pwdbio);
495
		} else if (!strcmp(arg, "stdin")) {
496
			pwdbio = BIO_new_fp(stdin, BIO_NOCLOSE);
497
			if (!pwdbio) {
498
				BIO_printf(err, "Can't open BIO for stdin\n");
499
				return NULL;
500
			}
501
		} else {
502
			BIO_printf(err, "Invalid password argument \"%s\"\n",
503
			    arg);
504
			return NULL;
505
		}
506
	}
507
	i = BIO_gets(pwdbio, tpass, APP_PASS_LEN);
508
	if (keepbio != 1) {
509
		BIO_free_all(pwdbio);
510
		pwdbio = NULL;
511
	}
512
	if (i <= 0) {
513
		BIO_printf(err, "Error reading password from BIO\n");
514
		return NULL;
515
	}
516
	tmp = strchr(tpass, '\n');
517
	if (tmp)
518
		*tmp = 0;
519
	return strdup(tpass);
520
524
}
521
522
int
523
add_oid_section(BIO *err, CONF *conf)
524
{
525
	char *p;
526
	STACK_OF(CONF_VALUE) *sktmp;
527
	CONF_VALUE *cnf;
528
	int i;
529
530
176
	if (!(p = NCONF_get_string(conf, NULL, "oid_section"))) {
531
28
		ERR_clear_error();
532
28
		return 1;
533
	}
534
60
	if (!(sktmp = NCONF_get_section(conf, p))) {
535
		BIO_printf(err, "problem loading oid section %s\n", p);
536
		return 0;
537
	}
538
480
	for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) {
539
180
		cnf = sk_CONF_VALUE_value(sktmp, i);
540
180
		if (OBJ_create(cnf->value, cnf->name, cnf->name) == NID_undef) {
541
			BIO_printf(err, "problem creating object %s=%s\n",
542
			    cnf->name, cnf->value);
543
			return 0;
544
		}
545
	}
546
60
	return 1;
547
88
}
548
549
static int
550
load_pkcs12(BIO *err, BIO *in, const char *desc, pem_password_cb *pem_cb,
551
    void *cb_data, EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca)
552
{
553
	const char *pass;
554
	char tpass[PEM_BUFSIZE];
555
	int len, ret = 0;
556
	PKCS12 *p12;
557
558
	p12 = d2i_PKCS12_bio(in, NULL);
559
	if (p12 == NULL) {
560
		BIO_printf(err, "Error loading PKCS12 file for %s\n", desc);
561
		goto die;
562
	}
563
	/* See if an empty password will do */
564
	if (PKCS12_verify_mac(p12, "", 0) || PKCS12_verify_mac(p12, NULL, 0))
565
		pass = "";
566
	else {
567
		if (!pem_cb)
568
			pem_cb = password_callback;
569
		len = pem_cb(tpass, PEM_BUFSIZE, 0, cb_data);
570
		if (len < 0) {
571
			BIO_printf(err, "Passpharse callback error for %s\n",
572
			    desc);
573
			goto die;
574
		}
575
		if (len < PEM_BUFSIZE)
576
			tpass[len] = 0;
577
		if (!PKCS12_verify_mac(p12, tpass, len)) {
578
			BIO_printf(err,
579
			    "Mac verify error (wrong password?) in PKCS12 file for %s\n", desc);
580
			goto die;
581
		}
582
		pass = tpass;
583
	}
584
	ret = PKCS12_parse(p12, pass, pkey, cert, ca);
585
586
die:
587
	if (p12)
588
		PKCS12_free(p12);
589
	return ret;
590
}
591
592
X509 *
593
load_cert(BIO *err, const char *file, int format, const char *pass,
594
    const char *cert_descrip)
595
{
596
230
	X509 *x = NULL;
597
	BIO *cert;
598
599
115
	if ((cert = BIO_new(BIO_s_file())) == NULL) {
600
		ERR_print_errors(err);
601
		goto end;
602
	}
603
115
	if (file == NULL) {
604
		setvbuf(stdin, NULL, _IONBF, 0);
605
		BIO_set_fp(cert, stdin, BIO_NOCLOSE);
606
	} else {
607
115
		if (BIO_read_filename(cert, file) <= 0) {
608
			BIO_printf(err, "Error opening %s %s\n",
609
			    cert_descrip, file);
610
			ERR_print_errors(err);
611
			goto end;
612
		}
613
	}
614
615
115
	if (format == FORMAT_ASN1)
616
4
		x = d2i_X509_bio(cert, NULL);
617
111
	else if (format == FORMAT_NETSCAPE) {
618
		NETSCAPE_X509 *nx;
619
		nx = ASN1_item_d2i_bio(&NETSCAPE_X509_it,
620
		    cert, NULL);
621
		if (nx == NULL)
622
			goto end;
623
624
		if ((strncmp(NETSCAPE_CERT_HDR, (char *) nx->header->data,
625
		    nx->header->length) != 0)) {
626
			NETSCAPE_X509_free(nx);
627
			BIO_printf(err,
628
			    "Error reading header on certificate\n");
629
			goto end;
630
		}
631
		x = nx->cert;
632
		nx->cert = NULL;
633
		NETSCAPE_X509_free(nx);
634

111
	} else if (format == FORMAT_PEM)
635
111
		x = PEM_read_bio_X509_AUX(cert, NULL, password_callback, NULL);
636
	else if (format == FORMAT_PKCS12) {
637
		if (!load_pkcs12(err, cert, cert_descrip, NULL, NULL,
638
		    NULL, &x, NULL))
639
			goto end;
640
	} else {
641
		BIO_printf(err, "bad input format specified for %s\n",
642
		    cert_descrip);
643
		goto end;
644
	}
645
646
end:
647
115
	if (x == NULL) {
648
		BIO_printf(err, "unable to load certificate\n");
649
		ERR_print_errors(err);
650
	}
651
115
	BIO_free(cert);
652
115
	return (x);
653
115
}
654
655
EVP_PKEY *
656
load_key(BIO *err, const char *file, int format, int maybe_stdin,
657
    const char *pass, const char *key_descrip)
658
{
659
	BIO *key = NULL;
660
224
	EVP_PKEY *pkey = NULL;
661
112
	PW_CB_DATA cb_data;
662
663
112
	cb_data.password = pass;
664
112
	cb_data.prompt_info = file;
665
666
112
	if (file == NULL && (!maybe_stdin)) {
667
		BIO_printf(err, "no keyfile specified\n");
668
		goto end;
669
	}
670
112
	key = BIO_new(BIO_s_file());
671
112
	if (key == NULL) {
672
		ERR_print_errors(err);
673
		goto end;
674
	}
675
112
	if (file == NULL && maybe_stdin) {
676
		setvbuf(stdin, NULL, _IONBF, 0);
677
		BIO_set_fp(key, stdin, BIO_NOCLOSE);
678
112
	} else if (BIO_read_filename(key, file) <= 0) {
679
		BIO_printf(err, "Error opening %s %s\n",
680
		    key_descrip, file);
681
		ERR_print_errors(err);
682
		goto end;
683
	}
684
112
	if (format == FORMAT_ASN1) {
685
		pkey = d2i_PrivateKey_bio(key, NULL);
686
112
	} else if (format == FORMAT_PEM) {
687
112
		pkey = PEM_read_bio_PrivateKey(key, NULL, password_callback, &cb_data);
688
112
	}
689
#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
690
	else if (format == FORMAT_NETSCAPE || format == FORMAT_IISSGC)
691
		pkey = load_netscape_key(err, key, file, key_descrip, format);
692
#endif
693
	else if (format == FORMAT_PKCS12) {
694
		if (!load_pkcs12(err, key, key_descrip, password_callback, &cb_data,
695
		    &pkey, NULL, NULL))
696
			goto end;
697
	}
698
#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA) && !defined (OPENSSL_NO_RC4)
699
	else if (format == FORMAT_MSBLOB)
700
		pkey = b2i_PrivateKey_bio(key);
701
	else if (format == FORMAT_PVK)
702
		pkey = b2i_PVK_bio(key, password_callback,
703
		    &cb_data);
704
#endif
705
	else {
706
		BIO_printf(err, "bad input format specified for key file\n");
707
		goto end;
708
	}
709
end:
710
112
	BIO_free(key);
711
112
	if (pkey == NULL) {
712
		BIO_printf(err, "unable to load %s\n", key_descrip);
713
		ERR_print_errors(err);
714
	}
715
224
	return (pkey);
716
112
}
717
718
EVP_PKEY *
719
load_pubkey(BIO *err, const char *file, int format, int maybe_stdin,
720
    const char *pass, const char *key_descrip)
721
{
722
	BIO *key = NULL;
723
	EVP_PKEY *pkey = NULL;
724
	PW_CB_DATA cb_data;
725
726
	cb_data.password = pass;
727
	cb_data.prompt_info = file;
728
729
	if (file == NULL && !maybe_stdin) {
730
		BIO_printf(err, "no keyfile specified\n");
731
		goto end;
732
	}
733
	key = BIO_new(BIO_s_file());
734
	if (key == NULL) {
735
		ERR_print_errors(err);
736
		goto end;
737
	}
738
	if (file == NULL && maybe_stdin) {
739
		setvbuf(stdin, NULL, _IONBF, 0);
740
		BIO_set_fp(key, stdin, BIO_NOCLOSE);
741
	} else if (BIO_read_filename(key, file) <= 0) {
742
		BIO_printf(err, "Error opening %s %s\n", key_descrip, file);
743
		ERR_print_errors(err);
744
		goto end;
745
	}
746
	if (format == FORMAT_ASN1) {
747
		pkey = d2i_PUBKEY_bio(key, NULL);
748
	}
749
	else if (format == FORMAT_ASN1RSA) {
750
		RSA *rsa;
751
		rsa = d2i_RSAPublicKey_bio(key, NULL);
752
		if (rsa) {
753
			pkey = EVP_PKEY_new();
754
			if (pkey)
755
				EVP_PKEY_set1_RSA(pkey, rsa);
756
			RSA_free(rsa);
757
		} else
758
			pkey = NULL;
759
	} else if (format == FORMAT_PEMRSA) {
760
		RSA *rsa;
761
		rsa = PEM_read_bio_RSAPublicKey(key, NULL, password_callback, &cb_data);
762
		if (rsa) {
763
			pkey = EVP_PKEY_new();
764
			if (pkey)
765
				EVP_PKEY_set1_RSA(pkey, rsa);
766
			RSA_free(rsa);
767
		} else
768
			pkey = NULL;
769
	}
770
	else if (format == FORMAT_PEM) {
771
		pkey = PEM_read_bio_PUBKEY(key, NULL, password_callback, &cb_data);
772
	}
773
#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
774
	else if (format == FORMAT_NETSCAPE || format == FORMAT_IISSGC)
775
		pkey = load_netscape_key(err, key, file, key_descrip, format);
776
#endif
777
#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA)
778
	else if (format == FORMAT_MSBLOB)
779
		pkey = b2i_PublicKey_bio(key);
780
#endif
781
	else {
782
		BIO_printf(err, "bad input format specified for key file\n");
783
		goto end;
784
	}
785
786
end:
787
	BIO_free(key);
788
	if (pkey == NULL)
789
		BIO_printf(err, "unable to load %s\n", key_descrip);
790
	return (pkey);
791
}
792
793
#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
794
static EVP_PKEY *
795
load_netscape_key(BIO *err, BIO *key, const char *file,
796
    const char *key_descrip, int format)
797
{
798
	EVP_PKEY *pkey;
799
	BUF_MEM *buf;
800
	RSA *rsa;
801
	const unsigned char *p;
802
	int size, i;
803
804
	buf = BUF_MEM_new();
805
	pkey = EVP_PKEY_new();
806
	size = 0;
807
	if (buf == NULL || pkey == NULL)
808
		goto error;
809
	for (;;) {
810
		if (!BUF_MEM_grow_clean(buf, size + 1024 * 10))
811
			goto error;
812
		i = BIO_read(key, &(buf->data[size]), 1024 * 10);
813
		size += i;
814
		if (i == 0)
815
			break;
816
		if (i < 0) {
817
			BIO_printf(err, "Error reading %s %s",
818
			    key_descrip, file);
819
			goto error;
820
		}
821
	}
822
	p = (unsigned char *) buf->data;
823
	rsa = d2i_RSA_NET(NULL, &p, (long) size, NULL,
824
	    (format == FORMAT_IISSGC ? 1 : 0));
825
	if (rsa == NULL)
826
		goto error;
827
	BUF_MEM_free(buf);
828
	EVP_PKEY_set1_RSA(pkey, rsa);
829
	return pkey;
830
831
error:
832
	BUF_MEM_free(buf);
833
	EVP_PKEY_free(pkey);
834
	return NULL;
835
}
836
#endif				/* ndef OPENSSL_NO_RC4 */
837
838
static int
839
load_certs_crls(BIO *err, const char *file, int format, const char *pass,
840
    const char *desc, STACK_OF(X509) **pcerts,
841
    STACK_OF(X509_CRL) **pcrls)
842
{
843
	int i;
844
	BIO *bio;
845
	STACK_OF(X509_INFO) *xis = NULL;
846
	X509_INFO *xi;
847
16
	PW_CB_DATA cb_data;
848
	int rv = 0;
849
850
8
	cb_data.password = pass;
851
8
	cb_data.prompt_info = file;
852
853
8
	if (format != FORMAT_PEM) {
854
		BIO_printf(err, "bad input format specified for %s\n", desc);
855
		return 0;
856
	}
857
8
	if (file == NULL)
858
		bio = BIO_new_fp(stdin, BIO_NOCLOSE);
859
	else
860
8
		bio = BIO_new_file(file, "r");
861
862
8
	if (bio == NULL) {
863
		BIO_printf(err, "Error opening %s %s\n",
864
		    desc, file ? file : "stdin");
865
		ERR_print_errors(err);
866
		return 0;
867
	}
868
8
	xis = PEM_X509_INFO_read_bio(bio, NULL, password_callback, &cb_data);
869
870
8
	BIO_free(bio);
871
872
8
	if (pcerts) {
873
8
		*pcerts = sk_X509_new_null();
874
8
		if (!*pcerts)
875
			goto end;
876
	}
877
8
	if (pcrls) {
878
		*pcrls = sk_X509_CRL_new_null();
879
		if (!*pcrls)
880
			goto end;
881
	}
882
32
	for (i = 0; i < sk_X509_INFO_num(xis); i++) {
883
8
		xi = sk_X509_INFO_value(xis, i);
884
8
		if (xi->x509 && pcerts) {
885
8
			if (!sk_X509_push(*pcerts, xi->x509))
886
				goto end;
887
8
			xi->x509 = NULL;
888
8
		}
889
8
		if (xi->crl && pcrls) {
890
			if (!sk_X509_CRL_push(*pcrls, xi->crl))
891
				goto end;
892
			xi->crl = NULL;
893
		}
894
	}
895
896

16
	if (pcerts && sk_X509_num(*pcerts) > 0)
897
8
		rv = 1;
898
899

8
	if (pcrls && sk_X509_CRL_num(*pcrls) > 0)
900
		rv = 1;
901
902
end:
903
8
	if (xis)
904
8
		sk_X509_INFO_pop_free(xis, X509_INFO_free);
905
906
8
	if (rv == 0) {
907
		if (pcerts) {
908
			sk_X509_pop_free(*pcerts, X509_free);
909
			*pcerts = NULL;
910
		}
911
		if (pcrls) {
912
			sk_X509_CRL_pop_free(*pcrls, X509_CRL_free);
913
			*pcrls = NULL;
914
		}
915
		BIO_printf(err, "unable to load %s\n",
916
		    pcerts ? "certificates" : "CRLs");
917
		ERR_print_errors(err);
918
	}
919
8
	return rv;
920
8
}
921
922
STACK_OF(X509) *
923
load_certs(BIO *err, const char *file, int format, const char *pass,
924
    const char *desc)
925
{
926
16
	STACK_OF(X509) *certs;
927
928
8
	if (!load_certs_crls(err, file, format, pass, desc, &certs, NULL))
929
		return NULL;
930
8
	return certs;
931
8
}
932
933
STACK_OF(X509_CRL) *
934
load_crls(BIO *err, const char *file, int format, const char *pass,
935
    const char *desc)
936
{
937
	STACK_OF(X509_CRL) *crls;
938
939
	if (!load_certs_crls(err, file, format, pass, desc, NULL, &crls))
940
		return NULL;
941
	return crls;
942
}
943
944
#define X509V3_EXT_UNKNOWN_MASK		(0xfL << 16)
945
/* Return error for unknown extensions */
946
#define X509V3_EXT_DEFAULT		0
947
/* Print error for unknown extensions */
948
#define X509V3_EXT_ERROR_UNKNOWN	(1L << 16)
949
/* ASN1 parse unknown extensions */
950
#define X509V3_EXT_PARSE_UNKNOWN	(2L << 16)
951
/* BIO_dump unknown extensions */
952
#define X509V3_EXT_DUMP_UNKNOWN		(3L << 16)
953
954
#define X509_FLAG_CA (X509_FLAG_NO_ISSUER | X509_FLAG_NO_PUBKEY | \
955
			 X509_FLAG_NO_HEADER | X509_FLAG_NO_VERSION)
956
957
int
958
set_cert_ex(unsigned long *flags, const char *arg)
959
{
960
	static const NAME_EX_TBL cert_tbl[] = {
961
		{"compatible", X509_FLAG_COMPAT, 0xffffffffl},
962
		{"ca_default", X509_FLAG_CA, 0xffffffffl},
963
		{"no_header", X509_FLAG_NO_HEADER, 0},
964
		{"no_version", X509_FLAG_NO_VERSION, 0},
965
		{"no_serial", X509_FLAG_NO_SERIAL, 0},
966
		{"no_signame", X509_FLAG_NO_SIGNAME, 0},
967
		{"no_validity", X509_FLAG_NO_VALIDITY, 0},
968
		{"no_subject", X509_FLAG_NO_SUBJECT, 0},
969
		{"no_issuer", X509_FLAG_NO_ISSUER, 0},
970
		{"no_pubkey", X509_FLAG_NO_PUBKEY, 0},
971
		{"no_extensions", X509_FLAG_NO_EXTENSIONS, 0},
972
		{"no_sigdump", X509_FLAG_NO_SIGDUMP, 0},
973
		{"no_aux", X509_FLAG_NO_AUX, 0},
974
		{"no_attributes", X509_FLAG_NO_ATTRIBUTES, 0},
975
		{"ext_default", X509V3_EXT_DEFAULT, X509V3_EXT_UNKNOWN_MASK},
976
		{"ext_error", X509V3_EXT_ERROR_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
977
		{"ext_parse", X509V3_EXT_PARSE_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
978
		{"ext_dump", X509V3_EXT_DUMP_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
979
		{NULL, 0, 0}
980
	};
981
	return set_multi_opts(flags, arg, cert_tbl);
982
}
983
984
int
985
set_name_ex(unsigned long *flags, const char *arg)
986
{
987
	static const NAME_EX_TBL ex_tbl[] = {
988
		{"esc_2253", ASN1_STRFLGS_ESC_2253, 0},
989
		{"esc_ctrl", ASN1_STRFLGS_ESC_CTRL, 0},
990
		{"esc_msb", ASN1_STRFLGS_ESC_MSB, 0},
991
		{"use_quote", ASN1_STRFLGS_ESC_QUOTE, 0},
992
		{"utf8", ASN1_STRFLGS_UTF8_CONVERT, 0},
993
		{"ignore_type", ASN1_STRFLGS_IGNORE_TYPE, 0},
994
		{"show_type", ASN1_STRFLGS_SHOW_TYPE, 0},
995
		{"dump_all", ASN1_STRFLGS_DUMP_ALL, 0},
996
		{"dump_nostr", ASN1_STRFLGS_DUMP_UNKNOWN, 0},
997
		{"dump_der", ASN1_STRFLGS_DUMP_DER, 0},
998
		{"compat", XN_FLAG_COMPAT, 0xffffffffL},
999
		{"sep_comma_plus", XN_FLAG_SEP_COMMA_PLUS, XN_FLAG_SEP_MASK},
1000
		{"sep_comma_plus_space", XN_FLAG_SEP_CPLUS_SPC, XN_FLAG_SEP_MASK},
1001
		{"sep_semi_plus_space", XN_FLAG_SEP_SPLUS_SPC, XN_FLAG_SEP_MASK},
1002
		{"sep_multiline", XN_FLAG_SEP_MULTILINE, XN_FLAG_SEP_MASK},
1003
		{"dn_rev", XN_FLAG_DN_REV, 0},
1004
		{"nofname", XN_FLAG_FN_NONE, XN_FLAG_FN_MASK},
1005
		{"sname", XN_FLAG_FN_SN, XN_FLAG_FN_MASK},
1006
		{"lname", XN_FLAG_FN_LN, XN_FLAG_FN_MASK},
1007
		{"align", XN_FLAG_FN_ALIGN, 0},
1008
		{"oid", XN_FLAG_FN_OID, XN_FLAG_FN_MASK},
1009
		{"space_eq", XN_FLAG_SPC_EQ, 0},
1010
		{"dump_unknown", XN_FLAG_DUMP_UNKNOWN_FIELDS, 0},
1011
		{"RFC2253", XN_FLAG_RFC2253, 0xffffffffL},
1012
		{"oneline", XN_FLAG_ONELINE, 0xffffffffL},
1013
		{"multiline", XN_FLAG_MULTILINE, 0xffffffffL},
1014
		{"ca_default", XN_FLAG_MULTILINE, 0xffffffffL},
1015
		{NULL, 0, 0}
1016
	};
1017
	return set_multi_opts(flags, arg, ex_tbl);
1018
}
1019
1020
int
1021
set_ext_copy(int *copy_type, const char *arg)
1022
{
1023
	if (!strcasecmp(arg, "none"))
1024
		*copy_type = EXT_COPY_NONE;
1025
	else if (!strcasecmp(arg, "copy"))
1026
		*copy_type = EXT_COPY_ADD;
1027
	else if (!strcasecmp(arg, "copyall"))
1028
		*copy_type = EXT_COPY_ALL;
1029
	else
1030
		return 0;
1031
	return 1;
1032
}
1033
1034
int
1035
copy_extensions(X509 *x, X509_REQ *req, int copy_type)
1036
{
1037
	STACK_OF(X509_EXTENSION) *exts = NULL;
1038
	X509_EXTENSION *ext, *tmpext;
1039
	ASN1_OBJECT *obj;
1040
	int i, idx, ret = 0;
1041
1042
40
	if (!x || !req || (copy_type == EXT_COPY_NONE))
1043
20
		return 1;
1044
	exts = X509_REQ_get_extensions(req);
1045
1046
	for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
1047
		ext = sk_X509_EXTENSION_value(exts, i);
1048
		obj = X509_EXTENSION_get_object(ext);
1049
		idx = X509_get_ext_by_OBJ(x, obj, -1);
1050
		/* Does extension exist? */
1051
		if (idx != -1) {
1052
			/* If normal copy don't override existing extension */
1053
			if (copy_type == EXT_COPY_ADD)
1054
				continue;
1055
			/* Delete all extensions of same type */
1056
			do {
1057
				tmpext = X509_get_ext(x, idx);
1058
				X509_delete_ext(x, idx);
1059
				X509_EXTENSION_free(tmpext);
1060
				idx = X509_get_ext_by_OBJ(x, obj, -1);
1061
			} while (idx != -1);
1062
		}
1063
		if (!X509_add_ext(x, ext, -1))
1064
			goto end;
1065
	}
1066
1067
	ret = 1;
1068
1069
end:
1070
	sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
1071
1072
	return ret;
1073
20
}
1074
1075
static int
1076
set_multi_opts(unsigned long *flags, const char *arg,
1077
    const NAME_EX_TBL *in_tbl)
1078
{
1079
	STACK_OF(CONF_VALUE) *vals;
1080
	CONF_VALUE *val;
1081
	int i, ret = 1;
1082
1083
	if (!arg)
1084
		return 0;
1085
	vals = X509V3_parse_list(arg);
1086
	for (i = 0; i < sk_CONF_VALUE_num(vals); i++) {
1087
		val = sk_CONF_VALUE_value(vals, i);
1088
		if (!set_table_opts(flags, val->name, in_tbl))
1089
			ret = 0;
1090
	}
1091
	sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
1092
	return ret;
1093
}
1094
1095
static int
1096
set_table_opts(unsigned long *flags, const char *arg,
1097
    const NAME_EX_TBL *in_tbl)
1098
{
1099
	char c;
1100
	const NAME_EX_TBL *ptbl;
1101
1102
	c = arg[0];
1103
	if (c == '-') {
1104
		c = 0;
1105
		arg++;
1106
	} else if (c == '+') {
1107
		c = 1;
1108
		arg++;
1109
	} else
1110
		c = 1;
1111
1112
	for (ptbl = in_tbl; ptbl->name; ptbl++) {
1113
		if (!strcasecmp(arg, ptbl->name)) {
1114
			*flags &= ~ptbl->mask;
1115
			if (c)
1116
				*flags |= ptbl->flag;
1117
			else
1118
				*flags &= ~ptbl->flag;
1119
			return 1;
1120
		}
1121
	}
1122
	return 0;
1123
}
1124
1125
void
1126
print_name(BIO *out, const char *title, X509_NAME *nm, unsigned long lflags)
1127
{
1128
	char *buf;
1129
	char mline = 0;
1130
	int indent = 0;
1131
1132
40
	if (title)
1133
20
		BIO_puts(out, title);
1134
20
	if ((lflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
1135
		mline = 1;
1136
		indent = 4;
1137
	}
1138
20
	if (lflags == XN_FLAG_COMPAT) {
1139
20
		buf = X509_NAME_oneline(nm, 0, 0);
1140
20
		BIO_puts(out, buf);
1141
20
		BIO_puts(out, "\n");
1142
20
		free(buf);
1143
20
	} else {
1144
		if (mline)
1145
			BIO_puts(out, "\n");
1146
		X509_NAME_print_ex(out, nm, indent, lflags);
1147
		BIO_puts(out, "\n");
1148
	}
1149
20
}
1150
1151
X509_STORE *
1152
setup_verify(BIO *bp, char *CAfile, char *CApath)
1153
{
1154
	X509_STORE *store;
1155
	X509_LOOKUP *lookup;
1156
1157
24
	if (!(store = X509_STORE_new()))
1158
		goto end;
1159
12
	lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
1160
12
	if (lookup == NULL)
1161
		goto end;
1162
12
	if (CAfile) {
1163
12
		if (!X509_LOOKUP_load_file(lookup, CAfile, X509_FILETYPE_PEM)) {
1164
			BIO_printf(bp, "Error loading file %s\n", CAfile);
1165
			goto end;
1166
		}
1167
	} else
1168
		X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT);
1169
1170
12
	lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
1171
12
	if (lookup == NULL)
1172
		goto end;
1173
12
	if (CApath) {
1174
		if (!X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM)) {
1175
			BIO_printf(bp, "Error loading directory %s\n", CApath);
1176
			goto end;
1177
		}
1178
	} else
1179
12
		X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT);
1180
1181
12
	ERR_clear_error();
1182
12
	return store;
1183
1184
end:
1185
	X509_STORE_free(store);
1186
	return NULL;
1187
12
}
1188
1189
int
1190
load_config(BIO *err, CONF *cnf)
1191
{
1192
	static int load_config_called = 0;
1193
1194
5654
	if (load_config_called)
1195
52
		return 1;
1196
2775
	load_config_called = 1;
1197
2775
	if (cnf == NULL)
1198
2775
		cnf = config;
1199
2775
	if (cnf == NULL)
1200
		return 1;
1201
1202
2775
	OPENSSL_load_builtin_modules();
1203
1204
2775
	if (CONF_modules_load(cnf, NULL, 0) <= 0) {
1205
		BIO_printf(err, "Error configuring OpenSSL\n");
1206
		ERR_print_errors(err);
1207
		return 0;
1208
	}
1209
2775
	return 1;
1210
2827
}
1211
1212
char *
1213
make_config_name()
1214
{
1215
1782
	const char *t = X509_get_default_cert_area();
1216
891
	char *p;
1217
1218
891
	if (asprintf(&p, "%s/openssl.cnf", t) == -1)
1219
		return NULL;
1220
891
	return p;
1221
891
}
1222
1223
static unsigned long
1224
index_serial_hash(const OPENSSL_CSTRING *a)
1225
{
1226
	const char *n;
1227
1228
400
	n = a[DB_serial];
1229
720
	while (*n == '0')
1230
160
		n++;
1231
200
	return (lh_strhash(n));
1232
}
1233
1234
static int
1235
index_serial_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b)
1236
{
1237
	const char *aa, *bb;
1238
1239
76
	for (aa = a[DB_serial]; *aa == '0'; aa++)
1240
		;
1241
56
	for (bb = b[DB_serial]; *bb == '0'; bb++)
1242
		;
1243
20
	return (strcmp(aa, bb));
1244
}
1245
1246
static int
1247
index_name_qual(char **a)
1248
{
1249
312
	return (a[0][0] == 'V');
1250
}
1251
1252
static unsigned long
1253
index_name_hash(const OPENSSL_CSTRING *a)
1254
{
1255
320
	return (lh_strhash(a[DB_name]));
1256
}
1257
1258
int
1259
index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b)
1260
{
1261
8
	return (strcmp(a[DB_name], b[DB_name]));
1262
}
1263
1264
400
static IMPLEMENT_LHASH_HASH_FN(index_serial, OPENSSL_CSTRING)
1265
40
static IMPLEMENT_LHASH_COMP_FN(index_serial, OPENSSL_CSTRING)
1266
320
static IMPLEMENT_LHASH_HASH_FN(index_name, OPENSSL_CSTRING)
1267
static IMPLEMENT_LHASH_COMP_FN(index_name, OPENSSL_CSTRING)
1268
1269
BIGNUM *
1270
load_serial(char *serialfile, int create, ASN1_INTEGER **retai)
1271
{
1272
	BIO *in = NULL;
1273
	BIGNUM *ret = NULL;
1274
72
	char buf[1024];
1275
	ASN1_INTEGER *ai = NULL;
1276
1277
36
	ai = ASN1_INTEGER_new();
1278
36
	if (ai == NULL)
1279
		goto err;
1280
1281
36
	if ((in = BIO_new(BIO_s_file())) == NULL) {
1282
		ERR_print_errors(bio_err);
1283
		goto err;
1284
	}
1285
36
	if (BIO_read_filename(in, serialfile) <= 0) {
1286
10
		if (!create) {
1287
			perror(serialfile);
1288
			goto err;
1289
		} else {
1290
10
			ret = BN_new();
1291

20
			if (ret == NULL || !rand_serial(ret, ai))
1292
				BIO_printf(bio_err, "Out of memory\n");
1293
		}
1294
	} else {
1295
26
		if (!a2i_ASN1_INTEGER(in, ai, buf, sizeof buf)) {
1296
			BIO_printf(bio_err, "unable to load number from %s\n",
1297
			    serialfile);
1298
			goto err;
1299
		}
1300
26
		ret = ASN1_INTEGER_to_BN(ai, NULL);
1301
26
		if (ret == NULL) {
1302
			BIO_printf(bio_err,
1303
			    "error converting number from bin to BIGNUM\n");
1304
			goto err;
1305
		}
1306
	}
1307
1308
36
	if (ret && retai) {
1309
		*retai = ai;
1310
		ai = NULL;
1311
	}
1312
1313
err:
1314
36
	if (in != NULL)
1315
36
		BIO_free(in);
1316
36
	if (ai != NULL)
1317
36
		ASN1_INTEGER_free(ai);
1318
36
	return (ret);
1319
36
}
1320
1321
int
1322
save_serial(char *serialfile, char *suffix, BIGNUM *serial,
1323
    ASN1_INTEGER **retai)
1324
{
1325
72
	char serialpath[PATH_MAX];
1326
	BIO *out = NULL;
1327
	int ret = 0, n;
1328
	ASN1_INTEGER *ai = NULL;
1329
1330
36
	if (suffix == NULL)
1331
12
		n = strlcpy(serialpath, serialfile, sizeof serialpath);
1332
	else
1333
24
		n = snprintf(serialpath, sizeof serialpath, "%s.%s",
1334
		    serialfile, suffix);
1335

72
	if (n == -1 || n >= sizeof(serialpath)) {
1336
		BIO_printf(bio_err, "serial too long\n");
1337
		goto err;
1338
	}
1339
36
	out = BIO_new(BIO_s_file());
1340
36
	if (out == NULL) {
1341
		ERR_print_errors(bio_err);
1342
		goto err;
1343
	}
1344
36
	if (BIO_write_filename(out, serialpath) <= 0) {
1345
		perror(serialfile);
1346
		goto err;
1347
	}
1348
36
	if ((ai = BN_to_ASN1_INTEGER(serial, NULL)) == NULL) {
1349
		BIO_printf(bio_err,
1350
		    "error converting serial to ASN.1 format\n");
1351
		goto err;
1352
	}
1353
36
	i2a_ASN1_INTEGER(out, ai);
1354
36
	BIO_puts(out, "\n");
1355
	ret = 1;
1356
36
	if (retai) {
1357
12
		*retai = ai;
1358
		ai = NULL;
1359
12
	}
1360
1361
err:
1362
36
	if (out != NULL)
1363
36
		BIO_free_all(out);
1364
36
	if (ai != NULL)
1365
24
		ASN1_INTEGER_free(ai);
1366
36
	return (ret);
1367
36
}
1368
1369
int
1370
rotate_serial(char *serialfile, char *new_suffix, char *old_suffix)
1371
{
1372
48
	char opath[PATH_MAX], npath[PATH_MAX];
1373
1374
48
	if (snprintf(npath, sizeof npath, "%s.%s", serialfile,
1375
24
	    new_suffix) >= sizeof npath) {
1376
		BIO_printf(bio_err, "file name too long\n");
1377
		goto err;
1378
	}
1379
1380
48
	if (snprintf(opath, sizeof opath, "%s.%s", serialfile,
1381
24
	    old_suffix) >= sizeof opath) {
1382
		BIO_printf(bio_err, "file name too long\n");
1383
		goto err;
1384
	}
1385
1386

24
	if (rename(serialfile, opath) < 0 &&
1387
	    errno != ENOENT && errno != ENOTDIR) {
1388
		BIO_printf(bio_err, "unable to rename %s to %s\n",
1389
		    serialfile, opath);
1390
		perror("reason");
1391
		goto err;
1392
	}
1393
1394
1395
24
	if (rename(npath, serialfile) < 0) {
1396
		BIO_printf(bio_err, "unable to rename %s to %s\n",
1397
		    npath, serialfile);
1398
		perror("reason");
1399
		if (rename(opath, serialfile) < 0) {
1400
			BIO_printf(bio_err, "unable to rename %s to %s\n",
1401
			    opath, serialfile);
1402
			perror("reason");
1403
		}
1404
		goto err;
1405
	}
1406
24
	return 1;
1407
1408
err:
1409
	return 0;
1410
24
}
1411
1412
int
1413
rand_serial(BIGNUM *b, ASN1_INTEGER *ai)
1414
{
1415
	BIGNUM *btmp;
1416
	int ret = 0;
1417
1418
92
	if (b)
1419
10
		btmp = b;
1420
	else
1421
36
		btmp = BN_new();
1422
1423
46
	if (!btmp)
1424
		return 0;
1425
1426
46
	if (!BN_pseudo_rand(btmp, SERIAL_RAND_BITS, 0, 0))
1427
		goto error;
1428

92
	if (ai && !BN_to_ASN1_INTEGER(btmp, ai))
1429
		goto error;
1430
1431
46
	ret = 1;
1432
1433
error:
1434
46
	if (!b)
1435
36
		BN_free(btmp);
1436
1437
46
	return ret;
1438
46
}
1439
1440
CA_DB *
1441
load_index(char *dbfile, DB_ATTR *db_attr)
1442
{
1443
	CA_DB *retdb = NULL;
1444
	TXT_DB *tmpdb = NULL;
1445
64
	BIO *in = BIO_new(BIO_s_file());
1446
	CONF *dbattr_conf = NULL;
1447
32
	char attrpath[PATH_MAX];
1448
32
	long errorline = -1;
1449
1450
32
	if (in == NULL) {
1451
		ERR_print_errors(bio_err);
1452
		goto err;
1453
	}
1454
32
	if (BIO_read_filename(in, dbfile) <= 0) {
1455
		perror(dbfile);
1456
		BIO_printf(bio_err, "unable to open '%s'\n", dbfile);
1457
		goto err;
1458
	}
1459
32
	if ((tmpdb = TXT_DB_read(in, DB_NUMBER)) == NULL)
1460
		goto err;
1461
1462
64
	if (snprintf(attrpath, sizeof attrpath, "%s.attr", dbfile)
1463
32
	    >= sizeof attrpath) {
1464
		BIO_printf(bio_err, "attr filename too long\n");
1465
		goto err;
1466
	}
1467
1468
32
	dbattr_conf = NCONF_new(NULL);
1469
32
	if (NCONF_load(dbattr_conf, attrpath, &errorline) <= 0) {
1470
4
		if (errorline > 0) {
1471
			BIO_printf(bio_err,
1472
			    "error on line %ld of db attribute file '%s'\n",
1473
			    errorline, attrpath);
1474
			goto err;
1475
		} else {
1476
4
			NCONF_free(dbattr_conf);
1477
			dbattr_conf = NULL;
1478
		}
1479
4
	}
1480
32
	if ((retdb = malloc(sizeof(CA_DB))) == NULL) {
1481
		fprintf(stderr, "Out of memory\n");
1482
		goto err;
1483
	}
1484
32
	retdb->db = tmpdb;
1485
	tmpdb = NULL;
1486
32
	if (db_attr)
1487
24
		retdb->attributes = *db_attr;
1488
	else {
1489
8
		retdb->attributes.unique_subject = 1;
1490
	}
1491
1492
32
	if (dbattr_conf) {
1493
28
		char *p = NCONF_get_string(dbattr_conf, NULL, "unique_subject");
1494
28
		if (p) {
1495
28
			retdb->attributes.unique_subject = parse_yesno(p, 1);
1496
28
		}
1497
28
	}
1498
1499
err:
1500
32
	if (dbattr_conf)
1501
28
		NCONF_free(dbattr_conf);
1502
32
	if (tmpdb)
1503
		TXT_DB_free(tmpdb);
1504
32
	if (in)
1505
32
		BIO_free_all(in);
1506
32
	return retdb;
1507
32
}
1508
1509
int
1510
index_index(CA_DB *db)
1511
{
1512
64
	if (!TXT_DB_create_index(db->db, DB_serial, NULL,
1513
	    LHASH_HASH_FN(index_serial), LHASH_COMP_FN(index_serial))) {
1514
		BIO_printf(bio_err,
1515
		    "error creating serial number index:(%ld,%ld,%ld)\n",
1516
		    db->db->error, db->db->arg1, db->db->arg2);
1517
		return 0;
1518
	}
1519

64
	if (db->attributes.unique_subject &&
1520
32
	    !TXT_DB_create_index(db->db, DB_name, index_name_qual,
1521
	    LHASH_HASH_FN(index_name), LHASH_COMP_FN(index_name))) {
1522
		BIO_printf(bio_err, "error creating name index:(%ld,%ld,%ld)\n",
1523
		    db->db->error, db->db->arg1, db->db->arg2);
1524
		return 0;
1525
	}
1526
32
	return 1;
1527
32
}
1528
1529
int
1530
save_index(const char *file, const char *suffix, CA_DB *db)
1531
{
1532
48
	char attrpath[PATH_MAX], dbfile[PATH_MAX];
1533
24
	BIO *out = BIO_new(BIO_s_file());
1534
	int j;
1535
1536
24
	if (out == NULL) {
1537
		ERR_print_errors(bio_err);
1538
		goto err;
1539
	}
1540
48
	if (snprintf(attrpath, sizeof attrpath, "%s.attr.%s",
1541
24
	    file, suffix) >= sizeof attrpath) {
1542
		BIO_printf(bio_err, "file name too long\n");
1543
		goto err;
1544
	}
1545
48
	if (snprintf(dbfile, sizeof dbfile, "%s.%s",
1546
24
	    file, suffix) >= sizeof dbfile) {
1547
		BIO_printf(bio_err, "file name too long\n");
1548
		goto err;
1549
	}
1550
1551
24
	if (BIO_write_filename(out, dbfile) <= 0) {
1552
		perror(dbfile);
1553
		BIO_printf(bio_err, "unable to open '%s'\n", dbfile);
1554
		goto err;
1555
	}
1556
24
	j = TXT_DB_write(out, db->db);
1557
24
	if (j <= 0)
1558
		goto err;
1559
1560
24
	BIO_free(out);
1561
1562
24
	out = BIO_new(BIO_s_file());
1563
1564
24
	if (BIO_write_filename(out, attrpath) <= 0) {
1565
		perror(attrpath);
1566
		BIO_printf(bio_err, "unable to open '%s'\n", attrpath);
1567
		goto err;
1568
	}
1569
24
	BIO_printf(out, "unique_subject = %s\n",
1570
24
	    db->attributes.unique_subject ? "yes" : "no");
1571
24
	BIO_free(out);
1572
1573
24
	return 1;
1574
1575
err:
1576
	return 0;
1577
24
}
1578
1579
int
1580
rotate_index(const char *dbfile, const char *new_suffix, const char *old_suffix)
1581
{
1582
48
	char attrpath[PATH_MAX], nattrpath[PATH_MAX], oattrpath[PATH_MAX];
1583
24
	char dbpath[PATH_MAX], odbpath[PATH_MAX];
1584
1585
48
	if (snprintf(attrpath, sizeof attrpath, "%s.attr",
1586
24
	    dbfile) >= sizeof attrpath) {
1587
		BIO_printf(bio_err, "file name too long\n");
1588
		goto err;
1589
	}
1590
48
	if (snprintf(nattrpath, sizeof nattrpath, "%s.attr.%s",
1591
24
	    dbfile, new_suffix) >= sizeof nattrpath) {
1592
		BIO_printf(bio_err, "file name too long\n");
1593
		goto err;
1594
	}
1595
48
	if (snprintf(oattrpath, sizeof oattrpath, "%s.attr.%s",
1596
24
	    dbfile, old_suffix) >= sizeof oattrpath) {
1597
		BIO_printf(bio_err, "file name too long\n");
1598
		goto err;
1599
	}
1600
48
	if (snprintf(dbpath, sizeof dbpath, "%s.%s",
1601
24
	    dbfile, new_suffix) >= sizeof dbpath) {
1602
		BIO_printf(bio_err, "file name too long\n");
1603
		goto err;
1604
	}
1605
48
	if (snprintf(odbpath, sizeof odbpath, "%s.%s",
1606
24
	    dbfile, old_suffix) >= sizeof odbpath) {
1607
		BIO_printf(bio_err, "file name too long\n");
1608
		goto err;
1609
	}
1610
1611

24
	if (rename(dbfile, odbpath) < 0 && errno != ENOENT && errno != ENOTDIR) {
1612
		BIO_printf(bio_err, "unable to rename %s to %s\n",
1613
		    dbfile, odbpath);
1614
		perror("reason");
1615
		goto err;
1616
	}
1617
1618
24
	if (rename(dbpath, dbfile) < 0) {
1619
		BIO_printf(bio_err, "unable to rename %s to %s\n",
1620
		    dbpath, dbfile);
1621
		perror("reason");
1622
		if (rename(odbpath, dbfile) < 0) {
1623
			BIO_printf(bio_err, "unable to rename %s to %s\n",
1624
			    odbpath, dbfile);
1625
			perror("reason");
1626
		}
1627
		goto err;
1628
	}
1629
1630

28
	if (rename(attrpath, oattrpath) < 0 && errno != ENOENT && errno != ENOTDIR) {
1631
		BIO_printf(bio_err, "unable to rename %s to %s\n",
1632
		    attrpath, oattrpath);
1633
		perror("reason");
1634
		if (rename(dbfile, dbpath) < 0) {
1635
			BIO_printf(bio_err, "unable to rename %s to %s\n",
1636
			    dbfile, dbpath);
1637
			perror("reason");
1638
		}
1639
		if (rename(odbpath, dbfile) < 0) {
1640
			BIO_printf(bio_err, "unable to rename %s to %s\n",
1641
			    odbpath, dbfile);
1642
			perror("reason");
1643
		}
1644
		goto err;
1645
	}
1646
1647
24
	if (rename(nattrpath, attrpath) < 0) {
1648
		BIO_printf(bio_err, "unable to rename %s to %s\n",
1649
		    nattrpath, attrpath);
1650
		perror("reason");
1651
		if (rename(oattrpath, attrpath) < 0) {
1652
			BIO_printf(bio_err, "unable to rename %s to %s\n",
1653
			    oattrpath, attrpath);
1654
			perror("reason");
1655
		}
1656
		if (rename(dbfile, dbpath) < 0) {
1657
			BIO_printf(bio_err, "unable to rename %s to %s\n",
1658
			    dbfile, dbpath);
1659
			perror("reason");
1660
		}
1661
		if (rename(odbpath, dbfile) < 0) {
1662
			BIO_printf(bio_err, "unable to rename %s to %s\n",
1663
			    odbpath, dbfile);
1664
			perror("reason");
1665
		}
1666
		goto err;
1667
	}
1668
24
	return 1;
1669
1670
err:
1671
	return 0;
1672
24
}
1673
1674
void
1675
free_index(CA_DB *db)
1676
{
1677
96
	if (db) {
1678
32
		if (db->db)
1679
32
			TXT_DB_free(db->db);
1680
32
		free(db);
1681
32
	}
1682
48
}
1683
1684
int
1685
parse_yesno(const char *str, int def)
1686
{
1687
	int ret = def;
1688
1689
56
	if (str) {
1690


28
		switch (*str) {
1691
		case 'f':	/* false */
1692
		case 'F':	/* FALSE */
1693
		case 'n':	/* no */
1694
		case 'N':	/* NO */
1695
		case '0':	/* 0 */
1696
			ret = 0;
1697
			break;
1698
		case 't':	/* true */
1699
		case 'T':	/* TRUE */
1700
		case 'y':	/* yes */
1701
		case 'Y':	/* YES */
1702
		case '1':	/* 1 */
1703
			ret = 1;
1704
28
			break;
1705
		default:
1706
			ret = def;
1707
			break;
1708
		}
1709
	}
1710
28
	return ret;
1711
}
1712
1713
/*
1714
 * subject is expected to be in the format /type0=value0/type1=value1/type2=...
1715
 * where characters may be escaped by \
1716
 */
1717
X509_NAME *
1718
parse_name(char *subject, long chtype, int multirdn)
1719
{
1720
	X509_NAME *name = NULL;
1721
	size_t buflen, max_ne;
1722
	char **ne_types, **ne_values;
1723
	char *buf, *bp, *sp;
1724
	int i, nid, ne_num = 0;
1725
	int *mval;
1726
1727
	/*
1728
	 * Buffer to copy the types and values into. Due to escaping the
1729
	 * copy can only become shorter.
1730
	 */
1731
80
	buflen = strlen(subject) + 1;
1732
40
	buf = malloc(buflen);
1733
1734
	/* Maximum number of name elements. */
1735
40
	max_ne = buflen / 2 + 1;
1736
40
	ne_types = reallocarray(NULL, max_ne, sizeof(char *));
1737
40
	ne_values = reallocarray(NULL, max_ne, sizeof(char *));
1738
40
	mval = reallocarray(NULL, max_ne, sizeof(int));
1739
1740
80
	if (buf == NULL || ne_types == NULL || ne_values == NULL ||
1741
40
	    mval == NULL) {
1742
		BIO_printf(bio_err, "malloc error\n");
1743
		goto error;
1744
	}
1745
1746
	bp = buf;
1747
	sp = subject;
1748
1749
40
	if (*subject != '/') {
1750
		BIO_printf(bio_err, "Subject does not start with '/'.\n");
1751
		goto error;
1752
	}
1753
1754
	/* Skip leading '/'. */
1755
40
	sp++;
1756
1757
	/* No multivalued RDN by default. */
1758
40
	mval[ne_num] = 0;
1759
1760
400
	while (*sp) {
1761
		/* Collect type. */
1762
160
		ne_types[ne_num] = bp;
1763
800
		while (*sp) {
1764
			/* is there anything to escape in the type...? */
1765
400
			if (*sp == '\\') {
1766
				if (*++sp)
1767
					*bp++ = *sp++;
1768
				else {
1769
					BIO_printf(bio_err, "escape character "
1770
					    "at end of string\n");
1771
					goto error;
1772
				}
1773
400
			} else if (*sp == '=') {
1774
				sp++;
1775
160
				*bp++ = '\0';
1776
160
				break;
1777
			} else
1778
240
				*bp++ = *sp++;
1779
		}
1780
160
		if (!*sp) {
1781
			BIO_printf(bio_err, "end of string encountered while "
1782
			    "processing type of subject name element #%d\n",
1783
			    ne_num);
1784
			goto error;
1785
		}
1786
160
		ne_values[ne_num] = bp;
1787
3512
		while (*sp) {
1788
1756
			if (*sp == '\\') {
1789
				if (*++sp)
1790
					*bp++ = *sp++;
1791
				else {
1792
					BIO_printf(bio_err, "escape character "
1793
					    "at end of string\n");
1794
					goto error;
1795
				}
1796
1756
			} else if (*sp == '/') {
1797
160
				sp++;
1798
				/* no multivalued RDN by default */
1799
				mval[ne_num + 1] = 0;
1800
160
				break;
1801
1596
			} else if (*sp == '+' && multirdn) {
1802
				/* a not escaped + signals a multivalued RDN */
1803
				sp++;
1804
				mval[ne_num + 1] = -1;
1805
				break;
1806
			} else
1807
1596
				*bp++ = *sp++;
1808
		}
1809
320
		*bp++ = '\0';
1810
160
		ne_num++;
1811
	}
1812
1813
40
	if ((name = X509_NAME_new()) == NULL)
1814
		goto error;
1815
1816
400
	for (i = 0; i < ne_num; i++) {
1817
160
		if ((nid = OBJ_txt2nid(ne_types[i])) == NID_undef) {
1818
			BIO_printf(bio_err,
1819
			    "Subject Attribute %s has no known NID, skipped\n",
1820
			    ne_types[i]);
1821
			continue;
1822
		}
1823
160
		if (!*ne_values[i]) {
1824
			BIO_printf(bio_err, "No value provided for Subject "
1825
			    "Attribute %s, skipped\n", ne_types[i]);
1826
			continue;
1827
		}
1828
320
		if (!X509_NAME_add_entry_by_NID(name, nid, chtype,
1829
160
		    (unsigned char *) ne_values[i], -1, -1, mval[i]))
1830
			goto error;
1831
	}
1832
	goto done;
1833
1834
error:
1835
	X509_NAME_free(name);
1836
	name = NULL;
1837
1838
done:
1839
40
	free(ne_values);
1840
40
	free(ne_types);
1841
40
	free(mval);
1842
40
	free(buf);
1843
1844
40
	return name;
1845
}
1846
1847
int
1848
args_verify(char ***pargs, int *pargc, int *badarg, BIO *err,
1849
    X509_VERIFY_PARAM **pm)
1850
{
1851
	ASN1_OBJECT *otmp = NULL;
1852
	unsigned long flags = 0;
1853
	int i;
1854
	int purpose = 0, depth = -1;
1855
120
	char **oldargs = *pargs;
1856
60
	char *arg = **pargs, *argn = (*pargs)[1];
1857
	time_t at_time = 0;
1858
60
	const char *errstr = NULL;
1859
1860
60
	if (!strcmp(arg, "-policy")) {
1861
		if (!argn)
1862
			*badarg = 1;
1863
		else {
1864
			otmp = OBJ_txt2obj(argn, 0);
1865
			if (!otmp) {
1866
				BIO_printf(err, "Invalid Policy \"%s\"\n",
1867
				    argn);
1868
				*badarg = 1;
1869
			}
1870
		}
1871
		(*pargs)++;
1872
60
	} else if (strcmp(arg, "-purpose") == 0) {
1873
		X509_PURPOSE *xptmp;
1874
		if (!argn)
1875
			*badarg = 1;
1876
		else {
1877
			i = X509_PURPOSE_get_by_sname(argn);
1878
			if (i < 0) {
1879
				BIO_printf(err, "unrecognized purpose\n");
1880
				*badarg = 1;
1881
			} else {
1882
				xptmp = X509_PURPOSE_get0(i);
1883
				purpose = X509_PURPOSE_get_id(xptmp);
1884
			}
1885
		}
1886
		(*pargs)++;
1887
60
	} else if (strcmp(arg, "-verify_depth") == 0) {
1888
		if (!argn)
1889
			*badarg = 1;
1890
		else {
1891
			depth = strtonum(argn, 1, INT_MAX, &errstr);
1892
			if (errstr) {
1893
				BIO_printf(err, "invalid depth %s: %s\n",
1894
				    argn, errstr);
1895
				*badarg = 1;
1896
			}
1897
		}
1898
		(*pargs)++;
1899
60
	} else if (strcmp(arg, "-attime") == 0) {
1900
		if (!argn)
1901
			*badarg = 1;
1902
		else {
1903
			long long timestamp;
1904
			/*
1905
			 * interpret the -attime argument as seconds since
1906
			 * Epoch
1907
			 */
1908
			if (sscanf(argn, "%lli", &timestamp) != 1) {
1909
				BIO_printf(bio_err,
1910
				    "Error parsing timestamp %s\n",
1911
				    argn);
1912
				*badarg = 1;
1913
			}
1914
			/* XXX 2038 truncation */
1915
			at_time = (time_t) timestamp;
1916
		}
1917
		(*pargs)++;
1918
60
	} else if (!strcmp(arg, "-ignore_critical"))
1919
		flags |= X509_V_FLAG_IGNORE_CRITICAL;
1920
60
	else if (!strcmp(arg, "-issuer_checks"))
1921
4
		flags |= X509_V_FLAG_CB_ISSUER_CHECK;
1922
56
	else if (!strcmp(arg, "-crl_check"))
1923
4
		flags |= X509_V_FLAG_CRL_CHECK;
1924
52
	else if (!strcmp(arg, "-crl_check_all"))
1925
		flags |= X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL;
1926
52
	else if (!strcmp(arg, "-policy_check"))
1927
4
		flags |= X509_V_FLAG_POLICY_CHECK;
1928
48
	else if (!strcmp(arg, "-explicit_policy"))
1929
		flags |= X509_V_FLAG_EXPLICIT_POLICY;
1930
48
	else if (!strcmp(arg, "-inhibit_any"))
1931
		flags |= X509_V_FLAG_INHIBIT_ANY;
1932
48
	else if (!strcmp(arg, "-inhibit_map"))
1933
		flags |= X509_V_FLAG_INHIBIT_MAP;
1934
48
	else if (!strcmp(arg, "-x509_strict"))
1935
		flags |= X509_V_FLAG_X509_STRICT;
1936
48
	else if (!strcmp(arg, "-extended_crl"))
1937
		flags |= X509_V_FLAG_EXTENDED_CRL_SUPPORT;
1938
48
	else if (!strcmp(arg, "-use_deltas"))
1939
		flags |= X509_V_FLAG_USE_DELTAS;
1940
48
	else if (!strcmp(arg, "-policy_print"))
1941
		flags |= X509_V_FLAG_NOTIFY_POLICY;
1942
48
	else if (!strcmp(arg, "-check_ss_sig"))
1943
		flags |= X509_V_FLAG_CHECK_SS_SIGNATURE;
1944
	else
1945
48
		return 0;
1946
1947
12
	if (*badarg) {
1948
		if (*pm)
1949
			X509_VERIFY_PARAM_free(*pm);
1950
		*pm = NULL;
1951
		goto end;
1952
	}
1953

16
	if (!*pm && !(*pm = X509_VERIFY_PARAM_new())) {
1954
		*badarg = 1;
1955
		goto end;
1956
	}
1957
12
	if (otmp) {
1958
		X509_VERIFY_PARAM_add0_policy(*pm, otmp);
1959
		otmp = NULL;
1960
	}
1961
12
	if (flags)
1962
12
		X509_VERIFY_PARAM_set_flags(*pm, flags);
1963
1964
12
	if (purpose)
1965
		X509_VERIFY_PARAM_set_purpose(*pm, purpose);
1966
1967
12
	if (depth >= 0)
1968
		X509_VERIFY_PARAM_set_depth(*pm, depth);
1969
1970
12
	if (at_time)
1971
		X509_VERIFY_PARAM_set_time(*pm, at_time);
1972
1973
end:
1974
12
	(*pargs)++;
1975
1976
12
	if (pargc)
1977
12
		*pargc -= *pargs - oldargs;
1978
1979
12
	ASN1_OBJECT_free(otmp);
1980
12
	return 1;
1981
60
}
1982
1983
/* Read whole contents of a BIO into an allocated memory buffer and
1984
 * return it.
1985
 */
1986
1987
int
1988
bio_to_mem(unsigned char **out, int maxlen, BIO *in)
1989
{
1990
	BIO *mem;
1991
	int len, ret;
1992
32
	unsigned char tbuf[1024];
1993
1994
16
	mem = BIO_new(BIO_s_mem());
1995
16
	if (!mem)
1996
		return -1;
1997
32
	for (;;) {
1998
32
		if ((maxlen != -1) && maxlen < 1024)
1999
			len = maxlen;
2000
		else
2001
			len = 1024;
2002
32
		len = BIO_read(in, tbuf, len);
2003
32
		if (len <= 0)
2004
			break;
2005
16
		if (BIO_write(mem, tbuf, len) != len) {
2006
			BIO_free(mem);
2007
			return -1;
2008
		}
2009
16
		maxlen -= len;
2010
2011
16
		if (maxlen == 0)
2012
			break;
2013
	}
2014
16
	ret = BIO_get_mem_data(mem, (char **) out);
2015
16
	BIO_set_flags(mem, BIO_FLAGS_MEM_RDONLY);
2016
16
	BIO_free(mem);
2017
16
	return ret;
2018
16
}
2019
2020
int
2021
pkey_ctrl_string(EVP_PKEY_CTX *ctx, char *value)
2022
{
2023
	int rv;
2024
	char *stmp, *vtmp = NULL;
2025
2026
248
	if (value == NULL)
2027
		return -1;
2028
124
	stmp = strdup(value);
2029
124
	if (!stmp)
2030
		return -1;
2031
124
	vtmp = strchr(stmp, ':');
2032
124
	if (vtmp) {
2033
124
		*vtmp = 0;
2034
124
		vtmp++;
2035
124
	}
2036
124
	rv = EVP_PKEY_CTX_ctrl_str(ctx, stmp, vtmp);
2037
124
	free(stmp);
2038
2039
124
	return rv;
2040
124
}
2041
2042
static void
2043
nodes_print(BIO *out, const char *name, STACK_OF(X509_POLICY_NODE) *nodes)
2044
{
2045
	X509_POLICY_NODE *node;
2046
	int i;
2047
2048
	BIO_printf(out, "%s Policies:", name);
2049
	if (nodes) {
2050
		BIO_puts(out, "\n");
2051
		for (i = 0; i < sk_X509_POLICY_NODE_num(nodes); i++) {
2052
			node = sk_X509_POLICY_NODE_value(nodes, i);
2053
			X509_POLICY_NODE_print(out, node, 2);
2054
		}
2055
	} else
2056
		BIO_puts(out, " <empty>\n");
2057
}
2058
2059
void
2060
policies_print(BIO *out, X509_STORE_CTX *ctx)
2061
{
2062
	X509_POLICY_TREE *tree;
2063
	int explicit_policy;
2064
	int free_out = 0;
2065
2066
	if (out == NULL) {
2067
		out = BIO_new_fp(stderr, BIO_NOCLOSE);
2068
		free_out = 1;
2069
	}
2070
	tree = X509_STORE_CTX_get0_policy_tree(ctx);
2071
	explicit_policy = X509_STORE_CTX_get_explicit_policy(ctx);
2072
2073
	BIO_printf(out, "Require explicit Policy: %s\n",
2074
	    explicit_policy ? "True" : "False");
2075
2076
	nodes_print(out, "Authority", X509_policy_tree_get0_policies(tree));
2077
	nodes_print(out, "User", X509_policy_tree_get0_user_policies(tree));
2078
	if (free_out)
2079
		BIO_free(out);
2080
}
2081
2082
/*
2083
 * next_protos_parse parses a comma separated list of strings into a string
2084
 * in a format suitable for passing to SSL_CTX_set_next_protos_advertised.
2085
 *   outlen: (output) set to the length of the resulting buffer on success.
2086
 *   err: (maybe NULL) on failure, an error message line is written to this BIO.
2087
 *   in: a NUL termianted string like "abc,def,ghi"
2088
 *
2089
 *   returns: a malloced buffer or NULL on failure.
2090
 */
2091
unsigned char *
2092
next_protos_parse(unsigned short *outlen, const char *in)
2093
{
2094
	size_t len;
2095
	unsigned char *out;
2096
	size_t i, start = 0;
2097
2098
8
	len = strlen(in);
2099
4
	if (len >= 65535)
2100
		return NULL;
2101
2102
4
	out = malloc(strlen(in) + 1);
2103
4
	if (!out)
2104
		return NULL;
2105
2106
136
	for (i = 0; i <= len; ++i) {
2107

124
		if (i == len || in[i] == ',') {
2108
8
			if (i - start > 255) {
2109
				free(out);
2110
				return NULL;
2111
			}
2112
8
			out[start] = i - start;
2113
8
			start = i + 1;
2114
8
		} else
2115
56
			out[i + 1] = in[i];
2116
	}
2117
2118
4
	*outlen = len + 1;
2119
4
	return out;
2120
4
}
2121
2122
int
2123
app_isdir(const char *name)
2124
{
2125
	struct stat st;
2126
2127
	if (stat(name, &st) == 0)
2128
		return S_ISDIR(st.st_mode);
2129
	return -1;
2130
}
2131
2132
#define OPTION_WIDTH 18
2133
2134
void
2135
options_usage(struct option *opts)
2136
{
2137
	const char *p, *q;
2138
208
	char optstr[32];
2139
	int i;
2140
2141
2136
	for (i = 0; opts[i].name != NULL; i++) {
2142
964
		if (opts[i].desc == NULL)
2143
			continue;
2144
2145
1840
		snprintf(optstr, sizeof(optstr), "-%s %s", opts[i].name,
2146
2288
		    (opts[i].argname != NULL) ? opts[i].argname : "");
2147
920
		fprintf(stderr, " %-*s", OPTION_WIDTH, optstr);
2148
920
		if (strlen(optstr) > OPTION_WIDTH)
2149
			fprintf(stderr, "\n %-*s", OPTION_WIDTH, "");
2150
2151
920
		p = opts[i].desc;
2152
1864
		while ((q = strchr(p, '\n')) != NULL) {
2153
12
			fprintf(stderr, " %.*s", (int)(q - p), p);
2154
12
			fprintf(stderr, "\n %-*s", OPTION_WIDTH, "");
2155
12
			p = q + 1;
2156
		}
2157
920
		fprintf(stderr, " %s\n", p);
2158
920
	}
2159
104
}
2160
2161
int
2162
options_parse(int argc, char **argv, struct option *opts, char **unnamed,
2163
    int *argsused)
2164
{
2165
4426
	const char *errstr;
2166
	struct option *opt;
2167
	long long val;
2168
	char *arg, *p;
2169
2213
	int fmt, used;
2170
	int ord = 0;
2171
	int i, j;
2172
2173
2213
	if (unnamed != NULL)
2174
82
		*unnamed = NULL;
2175
2176
23974
	for (i = 1; i < argc; i++) {
2177
9890
		p = arg = argv[i];
2178
2179
		/* Single unnamed argument (without leading hyphen). */
2180
9890
		if (*p++ != '-') {
2181
46
			if (argsused != NULL)
2182
				goto done;
2183
34
			if (unnamed == NULL)
2184
				goto unknown;
2185
34
			if (*unnamed != NULL)
2186
				goto toomany;
2187
34
			*unnamed = arg;
2188
34
			continue;
2189
		}
2190
2191
		/* End of named options (single hyphen). */
2192
9844
		if (*p == '\0') {
2193
			if (++i >= argc)
2194
				goto done;
2195
			if (argsused != NULL)
2196
				goto done;
2197
			if (unnamed != NULL && i == argc - 1) {
2198
				if (*unnamed != NULL)
2199
					goto toomany;
2200
				*unnamed = argv[i];
2201
				continue;
2202
			}
2203
			goto unknown;
2204
		}
2205
2206
		/* See if there is a matching option... */
2207
188400
		for (j = 0; opts[j].name != NULL; j++) {
2208
92888
			if (strcmp(p, opts[j].name) == 0)
2209
				break;
2210
		}
2211
		opt = &opts[j];
2212

11156
		if (opt->name == NULL && opt->type == 0)
2213
			goto unknown;
2214
2215

14280
		if (opt->type == OPTION_ARG ||
2216
5280
		    opt->type == OPTION_ARG_FORMAT ||
2217
5276
		    opt->type == OPTION_ARG_FUNC ||
2218
4532
		    opt->type == OPTION_ARG_INT ||
2219
4524
		    opt->type == OPTION_ARG_LONG ||
2220
4524
		    opt->type == OPTION_ARG_TIME) {
2221
5236
			if (++i >= argc) {
2222
				fprintf(stderr, "missing %s argument for -%s\n",
2223
				    opt->argname, opt->name);
2224
				return (1);
2225
			}
2226
		}
2227
2228



19512
		switch (opt->type) {
2229
		case OPTION_ARG:
2230
4476
			*opt->opt.arg = argv[i];
2231
4476
			break;
2232
2233
		case OPTION_ARGV_FUNC:
2234
1224
			if (opt->opt.argvfunc(argc - i, &argv[i], &used) != 0)
2235
16
				return (1);
2236
1208
			i += used - 1;
2237
1208
			break;
2238
2239
		case OPTION_ARG_FORMAT:
2240
4
			fmt = str2fmt(argv[i]);
2241
4
			if (fmt == FORMAT_UNDEF) {
2242
				fprintf(stderr, "unknown %s '%s' for -%s\n",
2243
				    opt->argname, argv[i], opt->name);
2244
				return (1);
2245
			}
2246
4
			*opt->opt.value = fmt;
2247
4
			break;
2248
2249
		case OPTION_ARG_FUNC:
2250
744
			if (opt->opt.argfunc(argv[i]) != 0)
2251
				return (1);
2252
			break;
2253
2254
		case OPTION_ARG_INT:
2255
8
			val = strtonum(argv[i], 0, INT_MAX, &errstr);
2256
8
			if (errstr != NULL) {
2257
				fprintf(stderr, "%s %s argument for -%s\n",
2258
				    errstr, opt->argname, opt->name);
2259
				return (1);
2260
			}
2261
8
			*opt->opt.value = (int)val;
2262
8
			break;
2263
2264
		case OPTION_ARG_LONG:
2265
			val = strtonum(argv[i], 0, LONG_MAX, &errstr);
2266
			if (errstr != NULL) {
2267
				fprintf(stderr, "%s %s argument for -%s\n",
2268
				    errstr, opt->argname, opt->name);
2269
				return (1);
2270
			}
2271
			*opt->opt.lvalue = (long)val;
2272
			break;
2273
2274
		case OPTION_ARG_TIME:
2275
4
			val = strtonum(argv[i], 0, LLONG_MAX, &errstr);
2276
4
			if (errstr != NULL) {
2277
				fprintf(stderr, "%s %s argument for -%s\n",
2278
				    errstr, opt->argname, opt->name);
2279
				return (1);
2280
			}
2281
4
			*opt->opt.tvalue = val;
2282
4
			break;
2283
2284
		case OPTION_DISCARD:
2285
			break;
2286
2287
		case OPTION_FUNC:
2288
4
			if (opt->opt.func() != 0)
2289
				return (1);
2290
			break;
2291
2292
		case OPTION_FLAG:
2293
2052
			*opt->opt.flag = 1;
2294
2052
			break;
2295
2296
		case OPTION_FLAG_ORD:
2297
4
			*opt->opt.flag = ++ord;
2298
4
			break;
2299
2300
		case OPTION_VALUE:
2301
1236
			*opt->opt.value = opt->value;
2302
1236
			break;
2303
2304
		case OPTION_VALUE_AND:
2305
			*opt->opt.value &= opt->value;
2306
			break;
2307
2308
		case OPTION_VALUE_OR:
2309
			*opt->opt.value |= opt->value;
2310
			break;
2311
2312
		default:
2313
			fprintf(stderr, "option %s - unknown type %i\n",
2314
			    opt->name, opt->type);
2315
			return (1);
2316
		}
2317
	}
2318
2319
done:
2320
2109
	if (argsused != NULL)
2321
24
		*argsused = i;
2322
2323
2109
	return (0);
2324
2325
toomany:
2326
	fprintf(stderr, "too many arguments\n");
2327
	return (1);
2328
2329
unknown:
2330
88
	fprintf(stderr, "unknown option '%s'\n", arg);
2331
88
	return (1);
2332
2213
}