dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / lib / libtls / tls_config.c
blobe7a746d30b79a15d8e0cd0f33848f4548a370e11
1 /* $OpenBSD: tls_config.c,v 1.44.4.1 2017/12/09 16:49:17 jsing Exp $ */
2 /*
3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
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.
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.
18 #include <sys/stat.h>
20 #include <ctype.h>
21 #include <errno.h>
22 #include <fcntl.h>
23 #include <stdlib.h>
24 #include <unistd.h>
26 #include <tls.h>
27 #include "tls_internal.h"
29 static int
30 set_string(const char **dest, const char *src)
32 free((char *)*dest);
33 *dest = NULL;
34 if (src != NULL)
35 if ((*dest = strdup(src)) == NULL)
36 return -1;
37 return 0;
40 static void *
41 memdup(const void *in, size_t len)
43 void *out;
45 if ((out = malloc(len)) == NULL)
46 return NULL;
47 memcpy(out, in, len);
48 return out;
51 static int
52 set_mem(char **dest, size_t *destlen, const void *src, size_t srclen)
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;
64 static struct tls_keypair *
65 tls_keypair_new(void)
67 return calloc(1, sizeof(struct tls_keypair));
70 static void
71 tls_keypair_clear_key(struct tls_keypair *keypair)
73 freezero(keypair->key_mem, keypair->key_len);
74 keypair->key_mem = NULL;
75 keypair->key_len = 0;
78 static int
79 tls_keypair_set_cert_file(struct tls_keypair *keypair, struct tls_error *error,
80 const char *cert_file)
82 return tls_config_load_file(error, "certificate", cert_file,
83 &keypair->cert_mem, &keypair->cert_len);
86 static int
87 tls_keypair_set_cert_mem(struct tls_keypair *keypair, const uint8_t *cert,
88 size_t len)
90 return set_mem(&keypair->cert_mem, &keypair->cert_len, cert, len);
93 static int
94 tls_keypair_set_key_file(struct tls_keypair *keypair, struct tls_error *error,
95 const char *key_file)
97 tls_keypair_clear_key(keypair);
98 return tls_config_load_file(error, "key", key_file,
99 &keypair->key_mem, &keypair->key_len);
102 static int
103 tls_keypair_set_key_mem(struct tls_keypair *keypair, const uint8_t *key,
104 size_t len)
106 tls_keypair_clear_key(keypair);
107 return set_mem(&keypair->key_mem, &keypair->key_len, key, len);
110 static int
111 tls_keypair_set_ocsp_staple_file(struct tls_keypair *keypair,
112 struct tls_error *error, const char *ocsp_file)
114 return tls_config_load_file(error, "ocsp", ocsp_file,
115 &keypair->ocsp_staple, &keypair->ocsp_staple_len);
118 static int
119 tls_keypair_set_ocsp_staple_mem(struct tls_keypair *keypair,
120 const uint8_t *staple, size_t len)
122 return set_mem(&keypair->ocsp_staple, &keypair->ocsp_staple_len, staple,
123 len);
126 static void
127 tls_keypair_clear(struct tls_keypair *keypair)
129 tls_keypair_set_cert_mem(keypair, NULL, 0);
130 tls_keypair_set_key_mem(keypair, NULL, 0);
133 static void
134 tls_keypair_free(struct tls_keypair *keypair)
136 if (keypair == NULL)
137 return;
139 tls_keypair_clear(keypair);
141 free(keypair->cert_mem);
142 free(keypair->key_mem);
143 free(keypair->ocsp_staple);
144 free(keypair->pubkey_hash);
146 free(keypair);
150 tls_config_load_file(struct tls_error *error, const char *filetype,
151 const char *filename, char **buf, size_t *len)
153 struct stat st;
154 int fd = -1;
155 ssize_t n;
157 free(*buf);
158 *buf = NULL;
159 *len = 0;
161 if ((fd = open(filename, O_RDONLY)) == -1) {
162 tls_error_set(error, "failed to open %s file '%s'",
163 filetype, filename);
164 goto fail;
166 if (fstat(fd, &st) != 0) {
167 tls_error_set(error, "failed to stat %s file '%s'",
168 filetype, filename);
169 goto fail;
171 if (st.st_size < 0)
172 goto fail;
173 *len = (size_t)st.st_size;
174 if ((*buf = malloc(*len)) == NULL) {
175 tls_error_set(error, "failed to allocate buffer for "
176 "%s file", filetype);
177 goto fail;
179 n = read(fd, *buf, *len);
180 if (n < 0 || (size_t)n != *len) {
181 tls_error_set(error, "failed to read %s file '%s'",
182 filetype, filename);
183 goto fail;
185 close(fd);
186 return 0;
188 fail:
189 if (fd != -1)
190 close(fd);
191 freezero(*buf, *len);
192 *buf = NULL;
193 *len = 0;
195 return -1;
198 struct tls_config *
199 tls_config_new(void)
201 struct tls_config *config;
202 unsigned char sid[TLS_MAX_SESSION_ID_LENGTH];
204 if ((config = calloc(1, sizeof(*config))) == NULL)
205 return (NULL);
207 if ((config->keypair = tls_keypair_new()) == NULL)
208 goto err;
210 config->refcount = 1;
213 * Default configuration.
215 if (tls_config_set_dheparams(config, "none") != 0)
216 goto err;
217 if (tls_config_set_ecdhecurves(config, "default") != 0)
218 goto err;
219 if (tls_config_set_ciphers(config, "secure") != 0)
220 goto err;
222 if (tls_config_set_protocols(config, TLS_PROTOCOLS_DEFAULT) != 0)
223 goto err;
224 if (tls_config_set_verify_depth(config, 6) != 0)
225 goto err;
228 * Set session ID context to a random value. For the simple case
229 * of a single process server this is good enough. For multiprocess
230 * servers the session ID needs to be set by the caller.
232 arc4random_buf(sid, sizeof(sid));
233 if (tls_config_set_session_id(config, sid, sizeof(sid)) != 0)
234 goto err;
235 config->ticket_keyrev = arc4random();
236 config->ticket_autorekey = 1;
238 tls_config_prefer_ciphers_server(config);
240 tls_config_verify(config);
242 return (config);
244 err:
245 tls_config_free(config);
246 return (NULL);
249 void
250 tls_config_free(struct tls_config *config)
252 struct tls_keypair *kp, *nkp;
254 if (config == NULL)
255 return;
257 if (--config->refcount > 0)
258 return;
260 for (kp = config->keypair; kp != NULL; kp = nkp) {
261 nkp = kp->next;
262 tls_keypair_free(kp);
265 free(config->error.msg);
267 free(config->alpn);
268 free((char *)config->ca_mem);
269 free((char *)config->ca_path);
270 free((char *)config->ciphers);
271 free((char *)config->crl_mem);
272 free(config->ecdhecurves);
274 free(config);
277 static void
278 tls_config_keypair_add(struct tls_config *config, struct tls_keypair *keypair)
280 struct tls_keypair *kp;
282 kp = config->keypair;
283 while (kp->next != NULL)
284 kp = kp->next;
286 kp->next = keypair;
289 const char *
290 tls_config_error(struct tls_config *config)
292 return config->error.msg;
295 void
296 tls_config_clear_keys(struct tls_config *config)
298 struct tls_keypair *kp;
300 for (kp = config->keypair; kp != NULL; kp = kp->next)
301 tls_keypair_clear(kp);
303 tls_config_set_ca_mem(config, NULL, 0);
304 tls_config_set_crl_mem(config, NULL, 0);
308 tls_config_parse_protocols(uint32_t *protocols, const char *protostr)
310 uint32_t proto, protos = 0;
311 char *s, *p, *q;
312 int negate;
314 if (protostr == NULL) {
315 *protocols = TLS_PROTOCOLS_DEFAULT;
316 return (0);
319 if ((s = strdup(protostr)) == NULL)
320 return (-1);
322 q = s;
323 while ((p = strsep(&q, ",:")) != NULL) {
324 while (*p == ' ' || *p == '\t')
325 p++;
327 negate = 0;
328 if (*p == '!') {
329 negate = 1;
330 p++;
333 if (negate && protos == 0)
334 protos = TLS_PROTOCOLS_ALL;
336 proto = 0;
337 if (strcasecmp(p, "all") == 0 ||
338 strcasecmp(p, "legacy") == 0)
339 proto = TLS_PROTOCOLS_ALL;
340 else if (strcasecmp(p, "default") == 0 ||
341 strcasecmp(p, "secure") == 0)
342 proto = TLS_PROTOCOLS_DEFAULT;
343 if (strcasecmp(p, "tlsv1") == 0)
344 proto = TLS_PROTOCOL_TLSv1;
345 else if (strcasecmp(p, "tlsv1.0") == 0)
346 proto = TLS_PROTOCOL_TLSv1_0;
347 else if (strcasecmp(p, "tlsv1.1") == 0)
348 proto = TLS_PROTOCOL_TLSv1_1;
349 else if (strcasecmp(p, "tlsv1.2") == 0)
350 proto = TLS_PROTOCOL_TLSv1_2;
352 if (proto == 0) {
353 free(s);
354 return (-1);
357 if (negate)
358 protos &= ~proto;
359 else
360 protos |= proto;
363 *protocols = protos;
365 free(s);
367 return (0);
370 static int
371 tls_config_parse_alpn(struct tls_config *config, const char *alpn,
372 char **alpn_data, size_t *alpn_len)
374 size_t buf_len, i, len;
375 char *buf = NULL;
376 char *s = NULL;
377 char *p, *q;
379 free(*alpn_data);
380 *alpn_data = NULL;
381 *alpn_len = 0;
383 if ((buf_len = strlen(alpn) + 1) > 65535) {
384 tls_config_set_errorx(config, "alpn too large");
385 goto err;
388 if ((buf = malloc(buf_len)) == NULL) {
389 tls_config_set_errorx(config, "out of memory");
390 goto err;
393 if ((s = strdup(alpn)) == NULL) {
394 tls_config_set_errorx(config, "out of memory");
395 goto err;
398 i = 0;
399 q = s;
400 while ((p = strsep(&q, ",")) != NULL) {
401 if ((len = strlen(p)) == 0) {
402 tls_config_set_errorx(config,
403 "alpn protocol with zero length");
404 goto err;
406 if (len > 255) {
407 tls_config_set_errorx(config,
408 "alpn protocol too long");
409 goto err;
411 buf[i++] = len & 0xff;
412 memcpy(&buf[i], p, len);
413 i += len;
416 free(s);
418 *alpn_data = buf;
419 *alpn_len = buf_len;
421 return (0);
423 err:
424 free(buf);
425 free(s);
427 return (-1);
431 tls_config_set_alpn(struct tls_config *config, const char *alpn)
433 return tls_config_parse_alpn(config, alpn, &config->alpn,
434 &config->alpn_len);
437 static int
438 tls_config_add_keypair_file_internal(struct tls_config *config,
439 const char *cert_file, const char *key_file, const char *ocsp_file)
441 struct tls_keypair *keypair;
443 if ((keypair = tls_keypair_new()) == NULL)
444 return (-1);
445 if (tls_keypair_set_cert_file(keypair, &config->error, cert_file) != 0)
446 goto err;
447 if (tls_keypair_set_key_file(keypair, &config->error, key_file) != 0)
448 goto err;
449 if (ocsp_file != NULL &&
450 tls_keypair_set_ocsp_staple_file(keypair, &config->error,
451 ocsp_file) != 0)
452 goto err;
454 tls_config_keypair_add(config, keypair);
456 return (0);
458 err:
459 tls_keypair_free(keypair);
460 return (-1);
463 static int
464 tls_config_add_keypair_mem_internal(struct tls_config *config, const uint8_t *cert,
465 size_t cert_len, const uint8_t *key, size_t key_len,
466 const uint8_t *staple, size_t staple_len)
468 struct tls_keypair *keypair;
470 if ((keypair = tls_keypair_new()) == NULL)
471 return (-1);
472 if (tls_keypair_set_cert_mem(keypair, cert, cert_len) != 0)
473 goto err;
474 if (tls_keypair_set_key_mem(keypair, key, key_len) != 0)
475 goto err;
476 if (staple != NULL &&
477 tls_keypair_set_ocsp_staple_mem(keypair, staple, staple_len) != 0)
478 goto err;
480 tls_config_keypair_add(config, keypair);
482 return (0);
484 err:
485 tls_keypair_free(keypair);
486 return (-1);
490 tls_config_add_keypair_mem(struct tls_config *config, const uint8_t *cert,
491 size_t cert_len, const uint8_t *key, size_t key_len)
493 return tls_config_add_keypair_mem_internal(config, cert, cert_len, key,
494 key_len, NULL, 0);
498 tls_config_add_keypair_file(struct tls_config *config,
499 const char *cert_file, const char *key_file)
501 return tls_config_add_keypair_file_internal(config, cert_file,
502 key_file, NULL);
506 tls_config_add_keypair_ocsp_mem(struct tls_config *config, const uint8_t *cert,
507 size_t cert_len, const uint8_t *key, size_t key_len, const uint8_t *staple,
508 size_t staple_len)
510 return tls_config_add_keypair_mem_internal(config, cert, cert_len, key,
511 key_len, staple, staple_len);
515 tls_config_add_keypair_ocsp_file(struct tls_config *config,
516 const char *cert_file, const char *key_file, const char *ocsp_file)
518 return tls_config_add_keypair_file_internal(config, cert_file,
519 key_file, ocsp_file);
523 tls_config_set_ca_file(struct tls_config *config, const char *ca_file)
525 return tls_config_load_file(&config->error, "CA", ca_file,
526 &config->ca_mem, &config->ca_len);
530 tls_config_set_ca_path(struct tls_config *config, const char *ca_path)
532 return set_string(&config->ca_path, ca_path);
536 tls_config_set_ca_mem(struct tls_config *config, const uint8_t *ca, size_t len)
538 return set_mem(&config->ca_mem, &config->ca_len, ca, len);
542 tls_config_set_cert_file(struct tls_config *config, const char *cert_file)
544 return tls_keypair_set_cert_file(config->keypair, &config->error,
545 cert_file);
549 tls_config_set_cert_mem(struct tls_config *config, const uint8_t *cert,
550 size_t len)
552 return tls_keypair_set_cert_mem(config->keypair, cert, len);
556 tls_config_set_ciphers(struct tls_config *config, const char *ciphers)
558 SSL_CTX *ssl_ctx = NULL;
560 if (ciphers == NULL ||
561 strcasecmp(ciphers, "default") == 0 ||
562 strcasecmp(ciphers, "secure") == 0)
563 ciphers = TLS_CIPHERS_DEFAULT;
564 else if (strcasecmp(ciphers, "compat") == 0)
565 ciphers = TLS_CIPHERS_COMPAT;
566 else if (strcasecmp(ciphers, "legacy") == 0)
567 ciphers = TLS_CIPHERS_LEGACY;
568 else if (strcasecmp(ciphers, "all") == 0 ||
569 strcasecmp(ciphers, "insecure") == 0)
570 ciphers = TLS_CIPHERS_ALL;
572 if ((ssl_ctx = SSL_CTX_new(SSLv23_method())) == NULL) {
573 tls_config_set_errorx(config, "out of memory");
574 goto fail;
576 if (SSL_CTX_set_cipher_list(ssl_ctx, ciphers) != 1) {
577 tls_config_set_errorx(config, "no ciphers for '%s'", ciphers);
578 goto fail;
581 SSL_CTX_free(ssl_ctx);
582 return set_string(&config->ciphers, ciphers);
584 fail:
585 SSL_CTX_free(ssl_ctx);
586 return -1;
590 tls_config_set_crl_file(struct tls_config *config, const char *crl_file)
592 return tls_config_load_file(&config->error, "CRL", crl_file,
593 &config->crl_mem, &config->crl_len);
597 tls_config_set_crl_mem(struct tls_config *config, const uint8_t *crl,
598 size_t len)
600 return set_mem(&config->crl_mem, &config->crl_len, crl, len);
604 tls_config_set_dheparams(struct tls_config *config, const char *params)
606 int keylen;
608 if (params == NULL || strcasecmp(params, "none") == 0)
609 keylen = 0;
610 else if (strcasecmp(params, "auto") == 0)
611 keylen = -1;
612 else if (strcasecmp(params, "legacy") == 0)
613 keylen = 1024;
614 else {
615 tls_config_set_errorx(config, "invalid dhe param '%s'", params);
616 return (-1);
619 config->dheparams = keylen;
621 return (0);
625 tls_config_set_ecdhecurve(struct tls_config *config, const char *curve)
627 if (strchr(curve, ',') != NULL || strchr(curve, ':') != NULL) {
628 tls_config_set_errorx(config, "invalid ecdhe curve '%s'",
629 curve);
630 return (-1);
633 if (curve == NULL ||
634 strcasecmp(curve, "none") == 0 ||
635 strcasecmp(curve, "auto") == 0)
636 curve = TLS_ECDHE_CURVES;
638 return tls_config_set_ecdhecurves(config, curve);
642 tls_config_set_ecdhecurves(struct tls_config *config, const char *curves)
644 int *curves_list = NULL, *curves_new;
645 size_t curves_num = 0;
646 char *cs = NULL;
647 char *p, *q;
648 int rv = -1;
649 int nid;
651 free(config->ecdhecurves);
652 config->ecdhecurves = NULL;
653 config->ecdhecurves_len = 0;
655 if (curves == NULL || strcasecmp(curves, "default") == 0)
656 curves = TLS_ECDHE_CURVES;
658 if ((cs = strdup(curves)) == NULL) {
659 tls_config_set_errorx(config, "out of memory");
660 goto err;
663 q = cs;
664 while ((p = strsep(&q, ",:")) != NULL) {
665 while (*p == ' ' || *p == '\t')
666 p++;
668 nid = OBJ_sn2nid(p);
669 if (nid == NID_undef)
670 nid = OBJ_ln2nid(p);
671 if (nid == NID_undef)
672 nid = EC_curve_nist2nid(p);
673 if (nid == NID_undef) {
674 tls_config_set_errorx(config,
675 "invalid ecdhe curve '%s'", p);
676 goto err;
679 if ((curves_new = reallocarray(curves_list, curves_num + 1,
680 sizeof(int))) == NULL) {
681 tls_config_set_errorx(config, "out of memory");
682 goto err;
684 curves_list = curves_new;
685 curves_list[curves_num] = nid;
686 curves_num++;
689 config->ecdhecurves = curves_list;
690 config->ecdhecurves_len = curves_num;
691 curves_list = NULL;
693 rv = 0;
695 err:
696 free(cs);
697 free(curves_list);
699 return (rv);
703 tls_config_set_key_file(struct tls_config *config, const char *key_file)
705 return tls_keypair_set_key_file(config->keypair, &config->error,
706 key_file);
710 tls_config_set_key_mem(struct tls_config *config, const uint8_t *key,
711 size_t len)
713 return tls_keypair_set_key_mem(config->keypair, key, len);
716 static int
717 tls_config_set_keypair_file_internal(struct tls_config *config,
718 const char *cert_file, const char *key_file, const char *ocsp_file)
720 if (tls_config_set_cert_file(config, cert_file) != 0)
721 return (-1);
722 if (tls_config_set_key_file(config, key_file) != 0)
723 return (-1);
724 if (tls_config_set_key_file(config, key_file) != 0)
725 return (-1);
726 if (ocsp_file != NULL &&
727 tls_config_set_ocsp_staple_file(config, ocsp_file) != 0)
728 return (-1);
730 return (0);
733 static int
734 tls_config_set_keypair_mem_internal(struct tls_config *config, const uint8_t *cert,
735 size_t cert_len, const uint8_t *key, size_t key_len,
736 const uint8_t *staple, size_t staple_len)
738 if (tls_config_set_cert_mem(config, cert, cert_len) != 0)
739 return (-1);
740 if (tls_config_set_key_mem(config, key, key_len) != 0)
741 return (-1);
742 if ((staple != NULL) &&
743 (tls_config_set_ocsp_staple_mem(config, staple, staple_len) != 0))
744 return (-1);
746 return (0);
750 tls_config_set_keypair_file(struct tls_config *config,
751 const char *cert_file, const char *key_file)
753 return tls_config_set_keypair_file_internal(config, cert_file, key_file,
754 NULL);
758 tls_config_set_keypair_mem(struct tls_config *config, const uint8_t *cert,
759 size_t cert_len, const uint8_t *key, size_t key_len)
761 return tls_config_set_keypair_mem_internal(config, cert, cert_len,
762 key, key_len, NULL, 0);
766 tls_config_set_keypair_ocsp_file(struct tls_config *config,
767 const char *cert_file, const char *key_file, const char *ocsp_file)
769 return tls_config_set_keypair_file_internal(config, cert_file, key_file,
770 ocsp_file);
774 tls_config_set_keypair_ocsp_mem(struct tls_config *config, const uint8_t *cert,
775 size_t cert_len, const uint8_t *key, size_t key_len,
776 const uint8_t *staple, size_t staple_len)
778 return tls_config_set_keypair_mem_internal(config, cert, cert_len,
779 key, key_len, staple, staple_len);
784 tls_config_set_protocols(struct tls_config *config, uint32_t protocols)
786 config->protocols = protocols;
788 return (0);
792 tls_config_set_verify_depth(struct tls_config *config, int verify_depth)
794 config->verify_depth = verify_depth;
796 return (0);
799 void
800 tls_config_prefer_ciphers_client(struct tls_config *config)
802 config->ciphers_server = 0;
805 void
806 tls_config_prefer_ciphers_server(struct tls_config *config)
808 config->ciphers_server = 1;
811 void
812 tls_config_insecure_noverifycert(struct tls_config *config)
814 config->verify_cert = 0;
817 void
818 tls_config_insecure_noverifyname(struct tls_config *config)
820 config->verify_name = 0;
823 void
824 tls_config_insecure_noverifytime(struct tls_config *config)
826 config->verify_time = 0;
829 void
830 tls_config_verify(struct tls_config *config)
832 config->verify_cert = 1;
833 config->verify_name = 1;
834 config->verify_time = 1;
837 void
838 tls_config_ocsp_require_stapling(struct tls_config *config)
840 config->ocsp_require_stapling = 1;
843 void
844 tls_config_verify_client(struct tls_config *config)
846 config->verify_client = 1;
849 void
850 tls_config_verify_client_optional(struct tls_config *config)
852 config->verify_client = 2;
855 void
856 tls_config_skip_private_key_check(struct tls_config *config)
858 config->skip_private_key_check = 1;
862 tls_config_set_ocsp_staple_file(struct tls_config *config, const char *staple_file)
864 return tls_keypair_set_ocsp_staple_file(config->keypair, &config->error,
865 staple_file);
869 tls_config_set_ocsp_staple_mem(struct tls_config *config, const uint8_t *staple,
870 size_t len)
872 return tls_keypair_set_ocsp_staple_mem(config->keypair, staple, len);
876 tls_config_set_session_id(struct tls_config *config,
877 const unsigned char *session_id, size_t len)
879 if (len > TLS_MAX_SESSION_ID_LENGTH) {
880 tls_config_set_errorx(config, "session ID too large");
881 return (-1);
883 memset(config->session_id, 0, sizeof(config->session_id));
884 memcpy(config->session_id, session_id, len);
885 return (0);
889 tls_config_set_session_lifetime(struct tls_config *config, int lifetime)
891 if (lifetime > TLS_MAX_SESSION_TIMEOUT) {
892 tls_config_set_errorx(config, "session lifetime too large");
893 return (-1);
895 if (lifetime != 0 && lifetime < TLS_MIN_SESSION_TIMEOUT) {
896 tls_config_set_errorx(config, "session lifetime too small");
897 return (-1);
900 config->session_lifetime = lifetime;
901 return (0);
905 tls_config_add_ticket_key(struct tls_config *config, uint32_t keyrev,
906 unsigned char *key, size_t keylen)
908 struct tls_ticket_key newkey;
909 int i;
911 if (TLS_TICKET_KEY_SIZE != keylen ||
912 sizeof(newkey.aes_key) + sizeof(newkey.hmac_key) > keylen) {
913 tls_config_set_errorx(config,
914 "wrong amount of ticket key data");
915 return (-1);
918 keyrev = htonl(keyrev);
919 memset(&newkey, 0, sizeof(newkey));
920 memcpy(newkey.key_name, &keyrev, sizeof(keyrev));
921 memcpy(newkey.aes_key, key, sizeof(newkey.aes_key));
922 memcpy(newkey.hmac_key, key + sizeof(newkey.aes_key),
923 sizeof(newkey.hmac_key));
924 newkey.time = time(NULL);
926 for (i = 0; i < TLS_NUM_TICKETS; i++) {
927 struct tls_ticket_key *tk = &config->ticket_keys[i];
928 if (memcmp(newkey.key_name, tk->key_name,
929 sizeof(tk->key_name)) != 0)
930 continue;
932 /* allow re-entry of most recent key */
933 if (i == 0 && memcmp(newkey.aes_key, tk->aes_key,
934 sizeof(tk->aes_key)) == 0 && memcmp(newkey.hmac_key,
935 tk->hmac_key, sizeof(tk->hmac_key)) == 0)
936 return (0);
937 tls_config_set_errorx(config, "ticket key already present");
938 return (-1);
941 memmove(&config->ticket_keys[1], &config->ticket_keys[0],
942 sizeof(config->ticket_keys) - sizeof(config->ticket_keys[0]));
943 config->ticket_keys[0] = newkey;
945 config->ticket_autorekey = 0;
947 return (0);
951 tls_config_ticket_autorekey(struct tls_config *config)
953 unsigned char key[TLS_TICKET_KEY_SIZE];
954 int rv;
956 arc4random_buf(key, sizeof(key));
957 rv = tls_config_add_ticket_key(config, config->ticket_keyrev++, key,
958 sizeof(key));
959 config->ticket_autorekey = 1;
960 return (rv);