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