xref: /openbsd-src/lib/libtls/tls_config.c (revision 1ad61ae0a79a724d2d3ec69e69c8e1d1ff6b53a0)
1 /* $OpenBSD: tls_config.c,v 1.67 2023/07/02 06:37:27 beck 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 
18 #include <sys/stat.h>
19 
20 #include <ctype.h>
21 #include <errno.h>
22 #include <fcntl.h>
23 #include <pthread.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <unistd.h>
27 
28 #include <tls.h>
29 
30 #include "tls_internal.h"
31 
32 static const char default_ca_file[] = TLS_DEFAULT_CA_FILE;
33 
34 const char *
35 tls_default_ca_cert_file(void)
36 {
37 	return default_ca_file;
38 }
39 
40 int
41 tls_config_load_file(struct tls_error *error, const char *filetype,
42     const char *filename, char **buf, size_t *len)
43 {
44 	struct stat st;
45 	int fd = -1;
46 	ssize_t n;
47 
48 	free(*buf);
49 	*buf = NULL;
50 	*len = 0;
51 
52 	if ((fd = open(filename, O_RDONLY)) == -1) {
53 		tls_error_set(error, "failed to open %s file '%s'",
54 		    filetype, filename);
55 		goto err;
56 	}
57 	if (fstat(fd, &st) != 0) {
58 		tls_error_set(error, "failed to stat %s file '%s'",
59 		    filetype, filename);
60 		goto err;
61 	}
62 	if (st.st_size < 0)
63 		goto err;
64 	*len = (size_t)st.st_size;
65 	if ((*buf = malloc(*len)) == NULL) {
66 		tls_error_set(error, "failed to allocate buffer for "
67 		    "%s file", filetype);
68 		goto err;
69 	}
70 	n = read(fd, *buf, *len);
71 	if (n < 0 || (size_t)n != *len) {
72 		tls_error_set(error, "failed to read %s file '%s'",
73 		    filetype, filename);
74 		goto err;
75 	}
76 	close(fd);
77 	return 0;
78 
79  err:
80 	if (fd != -1)
81 		close(fd);
82 	freezero(*buf, *len);
83 	*buf = NULL;
84 	*len = 0;
85 
86 	return -1;
87 }
88 
89 struct tls_config *
90 tls_config_new_internal(void)
91 {
92 	struct tls_config *config;
93 	unsigned char sid[TLS_MAX_SESSION_ID_LENGTH];
94 
95 	if ((config = calloc(1, sizeof(*config))) == NULL)
96 		return (NULL);
97 
98 	if (pthread_mutex_init(&config->mutex, NULL) != 0)
99 		goto err;
100 
101 	config->refcount = 1;
102 	config->session_fd = -1;
103 
104 	if ((config->keypair = tls_keypair_new()) == NULL)
105 		goto err;
106 
107 	/*
108 	 * Default configuration.
109 	 */
110 	if (tls_config_set_dheparams(config, "none") != 0)
111 		goto err;
112 	if (tls_config_set_ecdhecurves(config, "default") != 0)
113 		goto err;
114 	if (tls_config_set_ciphers(config, "secure") != 0)
115 		goto err;
116 
117 	if (tls_config_set_protocols(config, TLS_PROTOCOLS_DEFAULT) != 0)
118 		goto err;
119 	if (tls_config_set_verify_depth(config, 6) != 0)
120 		goto err;
121 
122 	/*
123 	 * Set session ID context to a random value.  For the simple case
124 	 * of a single process server this is good enough. For multiprocess
125 	 * servers the session ID needs to be set by the caller.
126 	 */
127 	arc4random_buf(sid, sizeof(sid));
128 	if (tls_config_set_session_id(config, sid, sizeof(sid)) != 0)
129 		goto err;
130 	config->ticket_keyrev = arc4random();
131 	config->ticket_autorekey = 1;
132 
133 	tls_config_prefer_ciphers_server(config);
134 
135 	tls_config_verify(config);
136 
137 	return (config);
138 
139  err:
140 	tls_config_free(config);
141 	return (NULL);
142 }
143 
144 struct tls_config *
145 tls_config_new(void)
146 {
147 	if (tls_init() == -1)
148 		return (NULL);
149 
150 	return tls_config_new_internal();
151 }
152 
153 void
154 tls_config_free(struct tls_config *config)
155 {
156 	struct tls_keypair *kp, *nkp;
157 	int refcount;
158 
159 	if (config == NULL)
160 		return;
161 
162 	pthread_mutex_lock(&config->mutex);
163 	refcount = --config->refcount;
164 	pthread_mutex_unlock(&config->mutex);
165 
166 	if (refcount > 0)
167 		return;
168 
169 	for (kp = config->keypair; kp != NULL; kp = nkp) {
170 		nkp = kp->next;
171 		tls_keypair_free(kp);
172 	}
173 
174 	free(config->error.msg);
175 
176 	free(config->alpn);
177 	free((char *)config->ca_mem);
178 	free((char *)config->ca_path);
179 	free((char *)config->ciphers);
180 	free((char *)config->crl_mem);
181 	free(config->ecdhecurves);
182 
183 	pthread_mutex_destroy(&config->mutex);
184 
185 	free(config);
186 }
187 
188 static void
189 tls_config_keypair_add(struct tls_config *config, struct tls_keypair *keypair)
190 {
191 	struct tls_keypair *kp;
192 
193 	kp = config->keypair;
194 	while (kp->next != NULL)
195 		kp = kp->next;
196 
197 	kp->next = keypair;
198 }
199 
200 const char *
201 tls_config_error(struct tls_config *config)
202 {
203 	return config->error.msg;
204 }
205 
206 void
207 tls_config_clear_keys(struct tls_config *config)
208 {
209 	struct tls_keypair *kp;
210 
211 	for (kp = config->keypair; kp != NULL; kp = kp->next)
212 		tls_keypair_clear_key(kp);
213 }
214 
215 int
216 tls_config_parse_protocols(uint32_t *protocols, const char *protostr)
217 {
218 	uint32_t proto, protos = 0;
219 	char *s, *p, *q;
220 	int negate;
221 
222 	if (protostr == NULL) {
223 		*protocols = TLS_PROTOCOLS_DEFAULT;
224 		return (0);
225 	}
226 
227 	if ((s = strdup(protostr)) == NULL)
228 		return (-1);
229 
230 	q = s;
231 	while ((p = strsep(&q, ",:")) != NULL) {
232 		while (*p == ' ' || *p == '\t')
233 			p++;
234 
235 		negate = 0;
236 		if (*p == '!') {
237 			negate = 1;
238 			p++;
239 		}
240 
241 		if (negate && protos == 0)
242 			protos = TLS_PROTOCOLS_ALL;
243 
244 		proto = 0;
245 		if (strcasecmp(p, "all") == 0 ||
246 		    strcasecmp(p, "legacy") == 0)
247 			proto = TLS_PROTOCOLS_ALL;
248 		else if (strcasecmp(p, "default") == 0 ||
249 		    strcasecmp(p, "secure") == 0)
250 			proto = TLS_PROTOCOLS_DEFAULT;
251 		if (strcasecmp(p, "tlsv1") == 0)
252 			proto = TLS_PROTOCOL_TLSv1;
253 		else if (strcasecmp(p, "tlsv1.0") == 0)
254 			proto = TLS_PROTOCOL_TLSv1_2;
255 		else if (strcasecmp(p, "tlsv1.1") == 0)
256 			proto = TLS_PROTOCOL_TLSv1_2;
257 		else if (strcasecmp(p, "tlsv1.2") == 0)
258 			proto = TLS_PROTOCOL_TLSv1_2;
259 		else if (strcasecmp(p, "tlsv1.3") == 0)
260 			proto = TLS_PROTOCOL_TLSv1_3;
261 
262 		if (proto == 0) {
263 			free(s);
264 			return (-1);
265 		}
266 
267 		if (negate)
268 			protos &= ~proto;
269 		else
270 			protos |= proto;
271 	}
272 
273 	*protocols = protos;
274 
275 	free(s);
276 
277 	return (0);
278 }
279 
280 static int
281 tls_config_parse_alpn(struct tls_config *config, const char *alpn,
282     char **alpn_data, size_t *alpn_len)
283 {
284 	size_t buf_len, i, len;
285 	char *buf = NULL;
286 	char *s = NULL;
287 	char *p, *q;
288 
289 	free(*alpn_data);
290 	*alpn_data = NULL;
291 	*alpn_len = 0;
292 
293 	if ((buf_len = strlen(alpn) + 1) > 65535) {
294 		tls_config_set_errorx(config, "alpn too large");
295 		goto err;
296 	}
297 
298 	if ((buf = malloc(buf_len)) == NULL) {
299 		tls_config_set_errorx(config, "out of memory");
300 		goto err;
301 	}
302 
303 	if ((s = strdup(alpn)) == NULL) {
304 		tls_config_set_errorx(config, "out of memory");
305 		goto err;
306 	}
307 
308 	i = 0;
309 	q = s;
310 	while ((p = strsep(&q, ",")) != NULL) {
311 		if ((len = strlen(p)) == 0) {
312 			tls_config_set_errorx(config,
313 			    "alpn protocol with zero length");
314 			goto err;
315 		}
316 		if (len > 255) {
317 			tls_config_set_errorx(config,
318 			    "alpn protocol too long");
319 			goto err;
320 		}
321 		buf[i++] = len & 0xff;
322 		memcpy(&buf[i], p, len);
323 		i += len;
324 	}
325 
326 	free(s);
327 
328 	*alpn_data = buf;
329 	*alpn_len = buf_len;
330 
331 	return (0);
332 
333  err:
334 	free(buf);
335 	free(s);
336 
337 	return (-1);
338 }
339 
340 int
341 tls_config_set_alpn(struct tls_config *config, const char *alpn)
342 {
343 	return tls_config_parse_alpn(config, alpn, &config->alpn,
344 	    &config->alpn_len);
345 }
346 
347 static int
348 tls_config_add_keypair_file_internal(struct tls_config *config,
349     const char *cert_file, const char *key_file, const char *ocsp_file)
350 {
351 	struct tls_keypair *keypair;
352 
353 	if ((keypair = tls_keypair_new()) == NULL)
354 		return (-1);
355 	if (tls_keypair_set_cert_file(keypair, &config->error, cert_file) != 0)
356 		goto err;
357 	if (key_file != NULL &&
358 	    tls_keypair_set_key_file(keypair, &config->error, key_file) != 0)
359 		goto err;
360 	if (ocsp_file != NULL &&
361 	    tls_keypair_set_ocsp_staple_file(keypair, &config->error,
362 		ocsp_file) != 0)
363 		goto err;
364 
365 	tls_config_keypair_add(config, keypair);
366 
367 	return (0);
368 
369  err:
370 	tls_keypair_free(keypair);
371 	return (-1);
372 }
373 
374 static int
375 tls_config_add_keypair_mem_internal(struct tls_config *config, const uint8_t *cert,
376     size_t cert_len, const uint8_t *key, size_t key_len,
377     const uint8_t *staple, size_t staple_len)
378 {
379 	struct tls_keypair *keypair;
380 
381 	if ((keypair = tls_keypair_new()) == NULL)
382 		return (-1);
383 	if (tls_keypair_set_cert_mem(keypair, &config->error, cert, cert_len) != 0)
384 		goto err;
385 	if (key != NULL &&
386 	    tls_keypair_set_key_mem(keypair, &config->error, key, key_len) != 0)
387 		goto err;
388 	if (staple != NULL &&
389 	    tls_keypair_set_ocsp_staple_mem(keypair, &config->error, staple,
390 		staple_len) != 0)
391 		goto err;
392 
393 	tls_config_keypair_add(config, keypair);
394 
395 	return (0);
396 
397  err:
398 	tls_keypair_free(keypair);
399 	return (-1);
400 }
401 
402 int
403 tls_config_add_keypair_mem(struct tls_config *config, const uint8_t *cert,
404     size_t cert_len, const uint8_t *key, size_t key_len)
405 {
406 	return tls_config_add_keypair_mem_internal(config, cert, cert_len, key,
407 	    key_len, NULL, 0);
408 }
409 
410 int
411 tls_config_add_keypair_file(struct tls_config *config,
412     const char *cert_file, const char *key_file)
413 {
414 	return tls_config_add_keypair_file_internal(config, cert_file,
415 	    key_file, NULL);
416 }
417 
418 int
419 tls_config_add_keypair_ocsp_mem(struct tls_config *config, const uint8_t *cert,
420     size_t cert_len, const uint8_t *key, size_t key_len, const uint8_t *staple,
421     size_t staple_len)
422 {
423 	return tls_config_add_keypair_mem_internal(config, cert, cert_len, key,
424 	    key_len, staple, staple_len);
425 }
426 
427 int
428 tls_config_add_keypair_ocsp_file(struct tls_config *config,
429     const char *cert_file, const char *key_file, const char *ocsp_file)
430 {
431 	return tls_config_add_keypair_file_internal(config, cert_file,
432 	    key_file, ocsp_file);
433 }
434 
435 int
436 tls_config_set_ca_file(struct tls_config *config, const char *ca_file)
437 {
438 	return tls_config_load_file(&config->error, "CA", ca_file,
439 	    &config->ca_mem, &config->ca_len);
440 }
441 
442 int
443 tls_config_set_ca_path(struct tls_config *config, const char *ca_path)
444 {
445 	return tls_set_string(&config->ca_path, ca_path);
446 }
447 
448 int
449 tls_config_set_ca_mem(struct tls_config *config, const uint8_t *ca, size_t len)
450 {
451 	return tls_set_mem(&config->ca_mem, &config->ca_len, ca, len);
452 }
453 
454 int
455 tls_config_set_cert_file(struct tls_config *config, const char *cert_file)
456 {
457 	return tls_keypair_set_cert_file(config->keypair, &config->error,
458 	    cert_file);
459 }
460 
461 int
462 tls_config_set_cert_mem(struct tls_config *config, const uint8_t *cert,
463     size_t len)
464 {
465 	return tls_keypair_set_cert_mem(config->keypair, &config->error,
466 	    cert, len);
467 }
468 
469 int
470 tls_config_set_ciphers(struct tls_config *config, const char *ciphers)
471 {
472 	SSL_CTX *ssl_ctx = NULL;
473 
474 	if (ciphers == NULL ||
475 	    strcasecmp(ciphers, "default") == 0 ||
476 	    strcasecmp(ciphers, "secure") == 0)
477 		ciphers = TLS_CIPHERS_DEFAULT;
478 	else if (strcasecmp(ciphers, "compat") == 0)
479 		ciphers = TLS_CIPHERS_COMPAT;
480 	else if (strcasecmp(ciphers, "legacy") == 0)
481 		ciphers = TLS_CIPHERS_LEGACY;
482 	else if (strcasecmp(ciphers, "all") == 0 ||
483 	    strcasecmp(ciphers, "insecure") == 0)
484 		ciphers = TLS_CIPHERS_ALL;
485 
486 	if ((ssl_ctx = SSL_CTX_new(SSLv23_method())) == NULL) {
487 		tls_config_set_errorx(config, "out of memory");
488 		goto err;
489 	}
490 	if (SSL_CTX_set_cipher_list(ssl_ctx, ciphers) != 1) {
491 		tls_config_set_errorx(config, "no ciphers for '%s'", ciphers);
492 		goto err;
493 	}
494 
495 	SSL_CTX_free(ssl_ctx);
496 	return tls_set_string(&config->ciphers, ciphers);
497 
498  err:
499 	SSL_CTX_free(ssl_ctx);
500 	return -1;
501 }
502 
503 int
504 tls_config_set_crl_file(struct tls_config *config, const char *crl_file)
505 {
506 	return tls_config_load_file(&config->error, "CRL", crl_file,
507 	    &config->crl_mem, &config->crl_len);
508 }
509 
510 int
511 tls_config_set_crl_mem(struct tls_config *config, const uint8_t *crl,
512     size_t len)
513 {
514 	return tls_set_mem(&config->crl_mem, &config->crl_len, crl, len);
515 }
516 
517 int
518 tls_config_set_dheparams(struct tls_config *config, const char *params)
519 {
520 	int keylen;
521 
522 	if (params == NULL || strcasecmp(params, "none") == 0)
523 		keylen = 0;
524 	else if (strcasecmp(params, "auto") == 0)
525 		keylen = -1;
526 	else if (strcasecmp(params, "legacy") == 0)
527 		keylen = 1024;
528 	else {
529 		tls_config_set_errorx(config, "invalid dhe param '%s'", params);
530 		return (-1);
531 	}
532 
533 	config->dheparams = keylen;
534 
535 	return (0);
536 }
537 
538 int
539 tls_config_set_ecdhecurve(struct tls_config *config, const char *curve)
540 {
541 	if (curve == NULL ||
542 	    strcasecmp(curve, "none") == 0 ||
543 	    strcasecmp(curve, "auto") == 0) {
544 		curve = TLS_ECDHE_CURVES;
545 	} else if (strchr(curve, ',') != NULL || strchr(curve, ':') != NULL) {
546 		tls_config_set_errorx(config, "invalid ecdhe curve '%s'",
547 		    curve);
548 		return (-1);
549 	}
550 
551 	return tls_config_set_ecdhecurves(config, curve);
552 }
553 
554 int
555 tls_config_set_ecdhecurves(struct tls_config *config, const char *curves)
556 {
557 	int *curves_list = NULL, *curves_new;
558 	size_t curves_num = 0;
559 	char *cs = NULL;
560 	char *p, *q;
561 	int rv = -1;
562 	int nid;
563 
564 	free(config->ecdhecurves);
565 	config->ecdhecurves = NULL;
566 	config->ecdhecurves_len = 0;
567 
568 	if (curves == NULL || strcasecmp(curves, "default") == 0)
569 		curves = TLS_ECDHE_CURVES;
570 
571 	if ((cs = strdup(curves)) == NULL) {
572 		tls_config_set_errorx(config, "out of memory");
573 		goto err;
574 	}
575 
576 	q = cs;
577 	while ((p = strsep(&q, ",:")) != NULL) {
578 		while (*p == ' ' || *p == '\t')
579 			p++;
580 
581 		nid = OBJ_sn2nid(p);
582 		if (nid == NID_undef)
583 			nid = OBJ_ln2nid(p);
584 		if (nid == NID_undef)
585 			nid = EC_curve_nist2nid(p);
586 		if (nid == NID_undef) {
587 			tls_config_set_errorx(config,
588 			    "invalid ecdhe curve '%s'", p);
589 			goto err;
590 		}
591 
592 		if ((curves_new = reallocarray(curves_list, curves_num + 1,
593 		    sizeof(int))) == NULL) {
594 			tls_config_set_errorx(config, "out of memory");
595 			goto err;
596 		}
597 		curves_list = curves_new;
598 		curves_list[curves_num] = nid;
599 		curves_num++;
600 	}
601 
602 	config->ecdhecurves = curves_list;
603 	config->ecdhecurves_len = curves_num;
604 	curves_list = NULL;
605 
606 	rv = 0;
607 
608  err:
609 	free(cs);
610 	free(curves_list);
611 
612 	return (rv);
613 }
614 
615 int
616 tls_config_set_key_file(struct tls_config *config, const char *key_file)
617 {
618 	return tls_keypair_set_key_file(config->keypair, &config->error,
619 	    key_file);
620 }
621 
622 int
623 tls_config_set_key_mem(struct tls_config *config, const uint8_t *key,
624     size_t len)
625 {
626 	return tls_keypair_set_key_mem(config->keypair, &config->error,
627 	    key, len);
628 }
629 
630 static int
631 tls_config_set_keypair_file_internal(struct tls_config *config,
632     const char *cert_file, const char *key_file, const char *ocsp_file)
633 {
634 	if (tls_config_set_cert_file(config, cert_file) != 0)
635 		return (-1);
636 	if (tls_config_set_key_file(config, key_file) != 0)
637 		return (-1);
638 	if (ocsp_file != NULL &&
639 	    tls_config_set_ocsp_staple_file(config, ocsp_file) != 0)
640 		return (-1);
641 
642 	return (0);
643 }
644 
645 static int
646 tls_config_set_keypair_mem_internal(struct tls_config *config, const uint8_t *cert,
647     size_t cert_len, const uint8_t *key, size_t key_len,
648     const uint8_t *staple, size_t staple_len)
649 {
650 	if (tls_config_set_cert_mem(config, cert, cert_len) != 0)
651 		return (-1);
652 	if (tls_config_set_key_mem(config, key, key_len) != 0)
653 		return (-1);
654 	if ((staple != NULL) &&
655 	    (tls_config_set_ocsp_staple_mem(config, staple, staple_len) != 0))
656 		return (-1);
657 
658 	return (0);
659 }
660 
661 int
662 tls_config_set_keypair_file(struct tls_config *config,
663     const char *cert_file, const char *key_file)
664 {
665 	return tls_config_set_keypair_file_internal(config, cert_file, key_file,
666 	    NULL);
667 }
668 
669 int
670 tls_config_set_keypair_mem(struct tls_config *config, const uint8_t *cert,
671     size_t cert_len, const uint8_t *key, size_t key_len)
672 {
673 	return tls_config_set_keypair_mem_internal(config, cert, cert_len,
674 	    key, key_len, NULL, 0);
675 }
676 
677 int
678 tls_config_set_keypair_ocsp_file(struct tls_config *config,
679     const char *cert_file, const char *key_file, const char *ocsp_file)
680 {
681 	return tls_config_set_keypair_file_internal(config, cert_file, key_file,
682 	    ocsp_file);
683 }
684 
685 int
686 tls_config_set_keypair_ocsp_mem(struct tls_config *config, const uint8_t *cert,
687     size_t cert_len, const uint8_t *key, size_t key_len,
688     const uint8_t *staple, size_t staple_len)
689 {
690 	return tls_config_set_keypair_mem_internal(config, cert, cert_len,
691 	    key, key_len, staple, staple_len);
692 }
693 
694 
695 int
696 tls_config_set_protocols(struct tls_config *config, uint32_t protocols)
697 {
698 	config->protocols = protocols;
699 
700 	return (0);
701 }
702 
703 int
704 tls_config_set_session_fd(struct tls_config *config, int session_fd)
705 {
706 	struct stat sb;
707 	mode_t mugo;
708 
709 	if (session_fd == -1) {
710 		config->session_fd = session_fd;
711 		return (0);
712 	}
713 
714 	if (fstat(session_fd, &sb) == -1) {
715 		tls_config_set_error(config, "failed to stat session file");
716 		return (-1);
717 	}
718 	if (!S_ISREG(sb.st_mode)) {
719 		tls_config_set_errorx(config,
720 		    "session file is not a regular file");
721 		return (-1);
722 	}
723 
724 	if (sb.st_uid != getuid()) {
725 		tls_config_set_errorx(config, "session file has incorrect "
726 		    "owner (uid %u != %u)", sb.st_uid, getuid());
727 		return (-1);
728 	}
729 	mugo = sb.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO);
730 	if (mugo != (S_IRUSR|S_IWUSR)) {
731 		tls_config_set_errorx(config, "session file has incorrect "
732 		    "permissions (%o != 600)", mugo);
733 		return (-1);
734 	}
735 
736 	config->session_fd = session_fd;
737 
738 	return (0);
739 }
740 
741 int
742 tls_config_set_sign_cb(struct tls_config *config, tls_sign_cb cb, void *cb_arg)
743 {
744 	config->use_fake_private_key = 1;
745 	config->skip_private_key_check = 1;
746 	config->sign_cb = cb;
747 	config->sign_cb_arg = cb_arg;
748 
749 	return (0);
750 }
751 
752 int
753 tls_config_set_verify_depth(struct tls_config *config, int verify_depth)
754 {
755 	config->verify_depth = verify_depth;
756 
757 	return (0);
758 }
759 
760 void
761 tls_config_prefer_ciphers_client(struct tls_config *config)
762 {
763 	config->ciphers_server = 0;
764 }
765 
766 void
767 tls_config_prefer_ciphers_server(struct tls_config *config)
768 {
769 	config->ciphers_server = 1;
770 }
771 
772 void
773 tls_config_insecure_noverifycert(struct tls_config *config)
774 {
775 	config->verify_cert = 0;
776 }
777 
778 void
779 tls_config_insecure_noverifyname(struct tls_config *config)
780 {
781 	config->verify_name = 0;
782 }
783 
784 void
785 tls_config_insecure_noverifytime(struct tls_config *config)
786 {
787 	config->verify_time = 0;
788 }
789 
790 void
791 tls_config_verify(struct tls_config *config)
792 {
793 	config->verify_cert = 1;
794 	config->verify_name = 1;
795 	config->verify_time = 1;
796 }
797 
798 void
799 tls_config_ocsp_require_stapling(struct tls_config *config)
800 {
801 	config->ocsp_require_stapling = 1;
802 }
803 
804 void
805 tls_config_verify_client(struct tls_config *config)
806 {
807 	config->verify_client = 1;
808 }
809 
810 void
811 tls_config_verify_client_optional(struct tls_config *config)
812 {
813 	config->verify_client = 2;
814 }
815 
816 void
817 tls_config_skip_private_key_check(struct tls_config *config)
818 {
819 	config->skip_private_key_check = 1;
820 }
821 
822 void
823 tls_config_use_fake_private_key(struct tls_config *config)
824 {
825 	config->use_fake_private_key = 1;
826 	config->skip_private_key_check = 1;
827 }
828 
829 int
830 tls_config_set_ocsp_staple_file(struct tls_config *config, const char *staple_file)
831 {
832 	return tls_keypair_set_ocsp_staple_file(config->keypair, &config->error,
833 	    staple_file);
834 }
835 
836 int
837 tls_config_set_ocsp_staple_mem(struct tls_config *config, const uint8_t *staple,
838     size_t len)
839 {
840 	return tls_keypair_set_ocsp_staple_mem(config->keypair, &config->error,
841 	    staple, len);
842 }
843 
844 int
845 tls_config_set_session_id(struct tls_config *config,
846     const unsigned char *session_id, size_t len)
847 {
848 	if (len > TLS_MAX_SESSION_ID_LENGTH) {
849 		tls_config_set_errorx(config, "session ID too large");
850 		return (-1);
851 	}
852 	memset(config->session_id, 0, sizeof(config->session_id));
853 	memcpy(config->session_id, session_id, len);
854 	return (0);
855 }
856 
857 int
858 tls_config_set_session_lifetime(struct tls_config *config, int lifetime)
859 {
860 	if (lifetime > TLS_MAX_SESSION_TIMEOUT) {
861 		tls_config_set_errorx(config, "session lifetime too large");
862 		return (-1);
863 	}
864 	if (lifetime != 0 && lifetime < TLS_MIN_SESSION_TIMEOUT) {
865 		tls_config_set_errorx(config, "session lifetime too small");
866 		return (-1);
867 	}
868 
869 	config->session_lifetime = lifetime;
870 	return (0);
871 }
872 
873 int
874 tls_config_add_ticket_key(struct tls_config *config, uint32_t keyrev,
875     unsigned char *key, size_t keylen)
876 {
877 	struct tls_ticket_key newkey;
878 	int i;
879 
880 	if (TLS_TICKET_KEY_SIZE != keylen ||
881 	    sizeof(newkey.aes_key) + sizeof(newkey.hmac_key) > keylen) {
882 		tls_config_set_errorx(config,
883 		    "wrong amount of ticket key data");
884 		return (-1);
885 	}
886 
887 	keyrev = htonl(keyrev);
888 	memset(&newkey, 0, sizeof(newkey));
889 	memcpy(newkey.key_name, &keyrev, sizeof(keyrev));
890 	memcpy(newkey.aes_key, key, sizeof(newkey.aes_key));
891 	memcpy(newkey.hmac_key, key + sizeof(newkey.aes_key),
892 	    sizeof(newkey.hmac_key));
893 	newkey.time = time(NULL);
894 
895 	for (i = 0; i < TLS_NUM_TICKETS; i++) {
896 		struct tls_ticket_key *tk = &config->ticket_keys[i];
897 		if (memcmp(newkey.key_name, tk->key_name,
898 		    sizeof(tk->key_name)) != 0)
899 			continue;
900 
901 		/* allow re-entry of most recent key */
902 		if (i == 0 && memcmp(newkey.aes_key, tk->aes_key,
903 		    sizeof(tk->aes_key)) == 0 && memcmp(newkey.hmac_key,
904 		    tk->hmac_key, sizeof(tk->hmac_key)) == 0)
905 			return (0);
906 		tls_config_set_errorx(config, "ticket key already present");
907 		return (-1);
908 	}
909 
910 	memmove(&config->ticket_keys[1], &config->ticket_keys[0],
911 	    sizeof(config->ticket_keys) - sizeof(config->ticket_keys[0]));
912 	config->ticket_keys[0] = newkey;
913 
914 	config->ticket_autorekey = 0;
915 
916 	return (0);
917 }
918 
919 int
920 tls_config_ticket_autorekey(struct tls_config *config)
921 {
922 	unsigned char key[TLS_TICKET_KEY_SIZE];
923 	int rv;
924 
925 	arc4random_buf(key, sizeof(key));
926 	rv = tls_config_add_ticket_key(config, config->ticket_keyrev++, key,
927 	    sizeof(key));
928 	config->ticket_autorekey = 1;
929 	return (rv);
930 }
931