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