Blob


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 */
18 #include "config.h"
20 #include <sys/stat.h>
22 #include <ctype.h>
23 #include <errno.h>
24 #include <fcntl.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <unistd.h>
29 #include <tls.h>
31 #include "tls_internal.h"
33 const char *
34 tls_default_ca_cert_file(void)
35 {
36 #ifdef OPENSMTPD_CA_FILE
37 return OPENSMTPD_CA_FILE;
38 #else
39 return X509_get_default_cert_file();
40 #endif
41 }
43 int
44 tls_config_load_file(struct tls_error *error, const char *filetype,
45 const char *filename, char **buf, size_t *len)
46 {
47 struct stat st;
48 int fd = -1;
49 ssize_t n;
51 free(*buf);
52 *buf = NULL;
53 *len = 0;
55 if ((fd = open(filename, O_RDONLY)) == -1) {
56 tls_error_set(error, "failed to open %s file '%s'",
57 filetype, filename);
58 goto err;
59 }
60 if (fstat(fd, &st) != 0) {
61 tls_error_set(error, "failed to stat %s file '%s'",
62 filetype, filename);
63 goto err;
64 }
65 if (st.st_size < 0)
66 goto err;
67 *len = (size_t)st.st_size;
68 if ((*buf = malloc(*len)) == NULL) {
69 tls_error_set(error, "failed to allocate buffer for "
70 "%s file", filetype);
71 goto err;
72 }
73 n = read(fd, *buf, *len);
74 if (n < 0 || (size_t)n != *len) {
75 tls_error_set(error, "failed to read %s file '%s'",
76 filetype, filename);
77 goto err;
78 }
79 close(fd);
80 return 0;
82 err:
83 if (fd != -1)
84 close(fd);
85 freezero(*buf, *len);
86 *buf = NULL;
87 *len = 0;
89 return -1;
90 }
92 struct tls_config *
93 tls_config_new_internal(void)
94 {
95 struct tls_config *config;
96 unsigned char sid[TLS_MAX_SESSION_ID_LENGTH];
98 if ((config = calloc(1, sizeof(*config))) == NULL)
99 return (NULL);
101 config->refcount = 1;
102 config->session_fd = -1;
104 if ((config->keypair = tls_keypair_new()) == NULL)
105 goto err;
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;
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;
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;
133 tls_config_prefer_ciphers_server(config);
135 tls_config_verify(config);
137 return (config);
139 err:
140 tls_config_free(config);
141 return (NULL);
144 struct tls_config *
145 tls_config_new(void)
147 if (tls_init() == -1)
148 return (NULL);
150 return tls_config_new_internal();
153 void
154 tls_config_free(struct tls_config *config)
156 struct tls_keypair *kp, *nkp;
157 int refcount;
159 if (config == NULL)
160 return;
162 refcount = --config->refcount;
164 if (refcount > 0)
165 return;
167 for (kp = config->keypair; kp != NULL; kp = nkp) {
168 nkp = kp->next;
169 tls_keypair_free(kp);
172 free(config->error.msg);
174 free(config->alpn);
175 free((char *)config->ca_mem);
176 free((char *)config->ca_path);
177 free((char *)config->ciphers);
178 free((char *)config->crl_mem);
179 free(config->ecdhecurves);
181 free(config);
184 static void
185 tls_config_keypair_add(struct tls_config *config, struct tls_keypair *keypair)
187 struct tls_keypair *kp;
189 kp = config->keypair;
190 while (kp->next != NULL)
191 kp = kp->next;
193 kp->next = keypair;
196 const char *
197 tls_config_error(struct tls_config *config)
199 return config->error.msg;
202 void
203 tls_config_clear_keys(struct tls_config *config)
205 struct tls_keypair *kp;
207 for (kp = config->keypair; kp != NULL; kp = kp->next)
208 tls_keypair_clear_key(kp);
211 int
212 tls_config_parse_protocols(uint32_t *protocols, const char *protostr)
214 uint32_t proto, protos = 0;
215 char *s, *p, *q;
216 int negate;
218 if (protostr == NULL) {
219 *protocols = TLS_PROTOCOLS_DEFAULT;
220 return (0);
223 if ((s = strdup(protostr)) == NULL)
224 return (-1);
226 q = s;
227 while ((p = strsep(&q, ",:")) != NULL) {
228 while (*p == ' ' || *p == '\t')
229 p++;
231 negate = 0;
232 if (*p == '!') {
233 negate = 1;
234 p++;
237 if (negate && protos == 0)
238 protos = TLS_PROTOCOLS_ALL;
240 proto = 0;
241 if (strcasecmp(p, "all") == 0 ||
242 strcasecmp(p, "legacy") == 0)
243 proto = TLS_PROTOCOLS_ALL;
244 else if (strcasecmp(p, "default") == 0 ||
245 strcasecmp(p, "secure") == 0)
246 proto = TLS_PROTOCOLS_DEFAULT;
247 if (strcasecmp(p, "tlsv1") == 0)
248 proto = TLS_PROTOCOL_TLSv1;
249 else if (strcasecmp(p, "tlsv1.0") == 0)
250 proto = TLS_PROTOCOL_TLSv1_2;
251 else if (strcasecmp(p, "tlsv1.1") == 0)
252 proto = TLS_PROTOCOL_TLSv1_2;
253 else if (strcasecmp(p, "tlsv1.2") == 0)
254 proto = TLS_PROTOCOL_TLSv1_2;
255 else if (strcasecmp(p, "tlsv1.3") == 0)
256 proto = TLS_PROTOCOL_TLSv1_3;
258 if (proto == 0) {
259 free(s);
260 return (-1);
263 if (negate)
264 protos &= ~proto;
265 else
266 protos |= proto;
269 *protocols = protos;
271 free(s);
273 return (0);
276 static int
277 tls_config_parse_alpn(struct tls_config *config, const char *alpn,
278 char **alpn_data, size_t *alpn_len)
280 size_t buf_len, i, len;
281 char *buf = NULL;
282 char *s = NULL;
283 char *p, *q;
285 free(*alpn_data);
286 *alpn_data = NULL;
287 *alpn_len = 0;
289 if ((buf_len = strlen(alpn) + 1) > 65535) {
290 tls_config_set_errorx(config, "alpn too large");
291 goto err;
294 if ((buf = malloc(buf_len)) == NULL) {
295 tls_config_set_errorx(config, "out of memory");
296 goto err;
299 if ((s = strdup(alpn)) == NULL) {
300 tls_config_set_errorx(config, "out of memory");
301 goto err;
304 i = 0;
305 q = s;
306 while ((p = strsep(&q, ",")) != NULL) {
307 if ((len = strlen(p)) == 0) {
308 tls_config_set_errorx(config,
309 "alpn protocol with zero length");
310 goto err;
312 if (len > 255) {
313 tls_config_set_errorx(config,
314 "alpn protocol too long");
315 goto err;
317 buf[i++] = len & 0xff;
318 memcpy(&buf[i], p, len);
319 i += len;
322 free(s);
324 *alpn_data = buf;
325 *alpn_len = buf_len;
327 return (0);
329 err:
330 free(buf);
331 free(s);
333 return (-1);
336 int
337 tls_config_set_alpn(struct tls_config *config, const char *alpn)
339 return tls_config_parse_alpn(config, alpn, &config->alpn,
340 &config->alpn_len);
343 static int
344 tls_config_add_keypair_file_internal(struct tls_config *config,
345 const char *cert_file, const char *key_file, const char *ocsp_file)
347 struct tls_keypair *keypair;
349 if ((keypair = tls_keypair_new()) == NULL)
350 return (-1);
351 if (tls_keypair_set_cert_file(keypair, &config->error, cert_file) != 0)
352 goto err;
353 if (key_file != NULL &&
354 tls_keypair_set_key_file(keypair, &config->error, key_file) != 0)
355 goto err;
356 if (ocsp_file != NULL &&
357 tls_keypair_set_ocsp_staple_file(keypair, &config->error,
358 ocsp_file) != 0)
359 goto err;
361 tls_config_keypair_add(config, keypair);
363 return (0);
365 err:
366 tls_keypair_free(keypair);
367 return (-1);
370 static int
371 tls_config_add_keypair_mem_internal(struct tls_config *config, const uint8_t *cert,
372 size_t cert_len, const uint8_t *key, size_t key_len,
373 const uint8_t *staple, size_t staple_len)
375 struct tls_keypair *keypair;
377 if ((keypair = tls_keypair_new()) == NULL)
378 return (-1);
379 if (tls_keypair_set_cert_mem(keypair, &config->error, cert, cert_len) != 0)
380 goto err;
381 if (key != NULL &&
382 tls_keypair_set_key_mem(keypair, &config->error, key, key_len) != 0)
383 goto err;
384 if (staple != NULL &&
385 tls_keypair_set_ocsp_staple_mem(keypair, &config->error, staple,
386 staple_len) != 0)
387 goto err;
389 tls_config_keypair_add(config, keypair);
391 return (0);
393 err:
394 tls_keypair_free(keypair);
395 return (-1);
398 int
399 tls_config_add_keypair_mem(struct tls_config *config, const uint8_t *cert,
400 size_t cert_len, const uint8_t *key, size_t key_len)
402 return tls_config_add_keypair_mem_internal(config, cert, cert_len, key,
403 key_len, NULL, 0);
406 int
407 tls_config_add_keypair_file(struct tls_config *config,
408 const char *cert_file, const char *key_file)
410 return tls_config_add_keypair_file_internal(config, cert_file,
411 key_file, NULL);
414 int
415 tls_config_add_keypair_ocsp_mem(struct tls_config *config, const uint8_t *cert,
416 size_t cert_len, const uint8_t *key, size_t key_len, const uint8_t *staple,
417 size_t staple_len)
419 return tls_config_add_keypair_mem_internal(config, cert, cert_len, key,
420 key_len, staple, staple_len);
423 int
424 tls_config_add_keypair_ocsp_file(struct tls_config *config,
425 const char *cert_file, const char *key_file, const char *ocsp_file)
427 return tls_config_add_keypair_file_internal(config, cert_file,
428 key_file, ocsp_file);
431 int
432 tls_config_set_ca_file(struct tls_config *config, const char *ca_file)
434 return tls_config_load_file(&config->error, "CA", ca_file,
435 &config->ca_mem, &config->ca_len);
438 int
439 tls_config_set_ca_path(struct tls_config *config, const char *ca_path)
441 return tls_set_string(&config->ca_path, ca_path);
444 int
445 tls_config_set_ca_mem(struct tls_config *config, const uint8_t *ca, size_t len)
447 return tls_set_mem(&config->ca_mem, &config->ca_len, ca, len);
450 int
451 tls_config_set_cert_file(struct tls_config *config, const char *cert_file)
453 return tls_keypair_set_cert_file(config->keypair, &config->error,
454 cert_file);
457 int
458 tls_config_set_cert_mem(struct tls_config *config, const uint8_t *cert,
459 size_t len)
461 return tls_keypair_set_cert_mem(config->keypair, &config->error,
462 cert, len);
465 int
466 tls_config_set_ciphers(struct tls_config *config, const char *ciphers)
468 SSL_CTX *ssl_ctx = NULL;
470 if (ciphers == NULL ||
471 strcasecmp(ciphers, "default") == 0 ||
472 strcasecmp(ciphers, "secure") == 0)
473 ciphers = TLS_CIPHERS_DEFAULT;
474 else if (strcasecmp(ciphers, "compat") == 0)
475 ciphers = TLS_CIPHERS_COMPAT;
476 else if (strcasecmp(ciphers, "legacy") == 0)
477 ciphers = TLS_CIPHERS_LEGACY;
478 else if (strcasecmp(ciphers, "all") == 0 ||
479 strcasecmp(ciphers, "insecure") == 0)
480 ciphers = TLS_CIPHERS_ALL;
482 if ((ssl_ctx = SSL_CTX_new(SSLv23_method())) == NULL) {
483 tls_config_set_errorx(config, "out of memory");
484 goto err;
486 if (SSL_CTX_set_cipher_list(ssl_ctx, ciphers) != 1) {
487 tls_config_set_errorx(config, "no ciphers for '%s'", ciphers);
488 goto err;
491 SSL_CTX_free(ssl_ctx);
492 return tls_set_string(&config->ciphers, ciphers);
494 err:
495 SSL_CTX_free(ssl_ctx);
496 return -1;
499 int
500 tls_config_set_crl_file(struct tls_config *config, const char *crl_file)
502 return tls_config_load_file(&config->error, "CRL", crl_file,
503 &config->crl_mem, &config->crl_len);
506 int
507 tls_config_set_crl_mem(struct tls_config *config, const uint8_t *crl,
508 size_t len)
510 return tls_set_mem(&config->crl_mem, &config->crl_len, crl, len);
513 int
514 tls_config_set_dheparams(struct tls_config *config, const char *params)
516 int keylen;
518 if (params == NULL || strcasecmp(params, "none") == 0)
519 keylen = 0;
520 else if (strcasecmp(params, "auto") == 0)
521 keylen = -1;
522 else if (strcasecmp(params, "legacy") == 0)
523 keylen = 1024;
524 else {
525 tls_config_set_errorx(config, "invalid dhe param '%s'", params);
526 return (-1);
529 config->dheparams = keylen;
531 return (0);
534 int
535 tls_config_set_ecdhecurve(struct tls_config *config, const char *curve)
537 if (curve == NULL ||
538 strcasecmp(curve, "none") == 0 ||
539 strcasecmp(curve, "auto") == 0) {
540 curve = TLS_ECDHE_CURVES;
541 } else if (strchr(curve, ',') != NULL || strchr(curve, ':') != NULL) {
542 tls_config_set_errorx(config, "invalid ecdhe curve '%s'",
543 curve);
544 return (-1);
547 return tls_config_set_ecdhecurves(config, curve);
550 int
551 tls_config_set_ecdhecurves(struct tls_config *config, const char *curves)
553 int *curves_list = NULL, *curves_new;
554 size_t curves_num = 0;
555 char *cs = NULL;
556 char *p, *q;
557 int rv = -1;
558 int nid;
560 free(config->ecdhecurves);
561 config->ecdhecurves = NULL;
562 config->ecdhecurves_len = 0;
564 if (curves == NULL || strcasecmp(curves, "default") == 0)
565 curves = TLS_ECDHE_CURVES;
567 if ((cs = strdup(curves)) == NULL) {
568 tls_config_set_errorx(config, "out of memory");
569 goto err;
572 q = cs;
573 while ((p = strsep(&q, ",:")) != NULL) {
574 while (*p == ' ' || *p == '\t')
575 p++;
577 nid = OBJ_sn2nid(p);
578 if (nid == NID_undef)
579 nid = OBJ_ln2nid(p);
580 if (nid == NID_undef)
581 nid = EC_curve_nist2nid(p);
582 if (nid == NID_undef) {
583 tls_config_set_errorx(config,
584 "invalid ecdhe curve '%s'", p);
585 goto err;
588 if ((curves_new = reallocarray(curves_list, curves_num + 1,
589 sizeof(int))) == NULL) {
590 tls_config_set_errorx(config, "out of memory");
591 goto err;
593 curves_list = curves_new;
594 curves_list[curves_num] = nid;
595 curves_num++;
598 config->ecdhecurves = curves_list;
599 config->ecdhecurves_len = curves_num;
600 curves_list = NULL;
602 rv = 0;
604 err:
605 free(cs);
606 free(curves_list);
608 return (rv);
611 int
612 tls_config_set_key_file(struct tls_config *config, const char *key_file)
614 return tls_keypair_set_key_file(config->keypair, &config->error,
615 key_file);
618 int
619 tls_config_set_key_mem(struct tls_config *config, const uint8_t *key,
620 size_t len)
622 return tls_keypair_set_key_mem(config->keypair, &config->error,
623 key, len);
626 static int
627 tls_config_set_keypair_file_internal(struct tls_config *config,
628 const char *cert_file, const char *key_file, const char *ocsp_file)
630 if (tls_config_set_cert_file(config, cert_file) != 0)
631 return (-1);
632 if (tls_config_set_key_file(config, key_file) != 0)
633 return (-1);
634 if (ocsp_file != NULL &&
635 tls_config_set_ocsp_staple_file(config, ocsp_file) != 0)
636 return (-1);
638 return (0);
641 static int
642 tls_config_set_keypair_mem_internal(struct tls_config *config, const uint8_t *cert,
643 size_t cert_len, const uint8_t *key, size_t key_len,
644 const uint8_t *staple, size_t staple_len)
646 if (tls_config_set_cert_mem(config, cert, cert_len) != 0)
647 return (-1);
648 if (tls_config_set_key_mem(config, key, key_len) != 0)
649 return (-1);
650 if ((staple != NULL) &&
651 (tls_config_set_ocsp_staple_mem(config, staple, staple_len) != 0))
652 return (-1);
654 return (0);
657 int
658 tls_config_set_keypair_file(struct tls_config *config,
659 const char *cert_file, const char *key_file)
661 return tls_config_set_keypair_file_internal(config, cert_file, key_file,
662 NULL);
665 int
666 tls_config_set_keypair_mem(struct tls_config *config, const uint8_t *cert,
667 size_t cert_len, const uint8_t *key, size_t key_len)
669 return tls_config_set_keypair_mem_internal(config, cert, cert_len,
670 key, key_len, NULL, 0);
673 int
674 tls_config_set_keypair_ocsp_file(struct tls_config *config,
675 const char *cert_file, const char *key_file, const char *ocsp_file)
677 return tls_config_set_keypair_file_internal(config, cert_file, key_file,
678 ocsp_file);
681 int
682 tls_config_set_keypair_ocsp_mem(struct tls_config *config, const uint8_t *cert,
683 size_t cert_len, const uint8_t *key, size_t key_len,
684 const uint8_t *staple, size_t staple_len)
686 return tls_config_set_keypair_mem_internal(config, cert, cert_len,
687 key, key_len, staple, staple_len);
691 int
692 tls_config_set_protocols(struct tls_config *config, uint32_t protocols)
694 config->protocols = protocols;
696 return (0);
699 int
700 tls_config_set_session_fd(struct tls_config *config, int session_fd)
702 struct stat sb;
703 mode_t mugo;
705 if (session_fd == -1) {
706 config->session_fd = session_fd;
707 return (0);
710 if (fstat(session_fd, &sb) == -1) {
711 tls_config_set_error(config, "failed to stat session file");
712 return (-1);
714 if (!S_ISREG(sb.st_mode)) {
715 tls_config_set_errorx(config,
716 "session file is not a regular file");
717 return (-1);
720 if (sb.st_uid != getuid()) {
721 tls_config_set_errorx(config, "session file has incorrect "
722 "owner (uid %u != %u)", sb.st_uid, getuid());
723 return (-1);
725 mugo = sb.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO);
726 if (mugo != (S_IRUSR|S_IWUSR)) {
727 tls_config_set_errorx(config, "session file has incorrect "
728 "permissions (%o != 600)", mugo);
729 return (-1);
732 config->session_fd = session_fd;
734 return (0);
737 int
738 tls_config_set_sign_cb(struct tls_config *config, tls_sign_cb cb, void *cb_arg)
740 config->use_fake_private_key = 1;
741 config->skip_private_key_check = 1;
742 config->sign_cb = cb;
743 config->sign_cb_arg = cb_arg;
745 return (0);
748 int
749 tls_config_set_verify_depth(struct tls_config *config, int verify_depth)
751 config->verify_depth = verify_depth;
753 return (0);
756 void
757 tls_config_prefer_ciphers_client(struct tls_config *config)
759 config->ciphers_server = 0;
762 void
763 tls_config_prefer_ciphers_server(struct tls_config *config)
765 config->ciphers_server = 1;
768 void
769 tls_config_insecure_noverifycert(struct tls_config *config)
771 config->verify_cert = 0;
774 void
775 tls_config_insecure_noverifyname(struct tls_config *config)
777 config->verify_name = 0;
780 void
781 tls_config_insecure_noverifytime(struct tls_config *config)
783 config->verify_time = 0;
786 void
787 tls_config_verify(struct tls_config *config)
789 config->verify_cert = 1;
790 config->verify_name = 1;
791 config->verify_time = 1;
794 void
795 tls_config_ocsp_require_stapling(struct tls_config *config)
797 config->ocsp_require_stapling = 1;
800 void
801 tls_config_verify_client(struct tls_config *config)
803 config->verify_client = 1;
806 void
807 tls_config_verify_client_optional(struct tls_config *config)
809 config->verify_client = 2;
812 void
813 tls_config_skip_private_key_check(struct tls_config *config)
815 config->skip_private_key_check = 1;
818 void
819 tls_config_use_fake_private_key(struct tls_config *config)
821 config->use_fake_private_key = 1;
822 config->skip_private_key_check = 1;
825 int
826 tls_config_set_ocsp_staple_file(struct tls_config *config, const char *staple_file)
828 return tls_keypair_set_ocsp_staple_file(config->keypair, &config->error,
829 staple_file);
832 int
833 tls_config_set_ocsp_staple_mem(struct tls_config *config, const uint8_t *staple,
834 size_t len)
836 return tls_keypair_set_ocsp_staple_mem(config->keypair, &config->error,
837 staple, len);
840 int
841 tls_config_set_session_id(struct tls_config *config,
842 const unsigned char *session_id, size_t len)
844 if (len > TLS_MAX_SESSION_ID_LENGTH) {
845 tls_config_set_errorx(config, "session ID too large");
846 return (-1);
848 memset(config->session_id, 0, sizeof(config->session_id));
849 memcpy(config->session_id, session_id, len);
850 return (0);
853 int
854 tls_config_set_session_lifetime(struct tls_config *config, int lifetime)
856 if (lifetime > TLS_MAX_SESSION_TIMEOUT) {
857 tls_config_set_errorx(config, "session lifetime too large");
858 return (-1);
860 if (lifetime != 0 && lifetime < TLS_MIN_SESSION_TIMEOUT) {
861 tls_config_set_errorx(config, "session lifetime too small");
862 return (-1);
865 config->session_lifetime = lifetime;
866 return (0);
869 int
870 tls_config_add_ticket_key(struct tls_config *config, uint32_t keyrev,
871 unsigned char *key, size_t keylen)
873 struct tls_ticket_key newkey;
874 int i;
876 if (TLS_TICKET_KEY_SIZE != keylen ||
877 sizeof(newkey.aes_key) + sizeof(newkey.hmac_key) > keylen) {
878 tls_config_set_errorx(config,
879 "wrong amount of ticket key data");
880 return (-1);
883 keyrev = htonl(keyrev);
884 memset(&newkey, 0, sizeof(newkey));
885 memcpy(newkey.key_name, &keyrev, sizeof(keyrev));
886 memcpy(newkey.aes_key, key, sizeof(newkey.aes_key));
887 memcpy(newkey.hmac_key, key + sizeof(newkey.aes_key),
888 sizeof(newkey.hmac_key));
889 newkey.time = time(NULL);
891 for (i = 0; i < TLS_NUM_TICKETS; i++) {
892 struct tls_ticket_key *tk = &config->ticket_keys[i];
893 if (memcmp(newkey.key_name, tk->key_name,
894 sizeof(tk->key_name)) != 0)
895 continue;
897 /* allow re-entry of most recent key */
898 if (i == 0 && memcmp(newkey.aes_key, tk->aes_key,
899 sizeof(tk->aes_key)) == 0 && memcmp(newkey.hmac_key,
900 tk->hmac_key, sizeof(tk->hmac_key)) == 0)
901 return (0);
902 tls_config_set_errorx(config, "ticket key already present");
903 return (-1);
906 memmove(&config->ticket_keys[1], &config->ticket_keys[0],
907 sizeof(config->ticket_keys) - sizeof(config->ticket_keys[0]));
908 config->ticket_keys[0] = newkey;
910 config->ticket_autorekey = 0;
912 return (0);
915 int
916 tls_config_ticket_autorekey(struct tls_config *config)
918 unsigned char key[TLS_TICKET_KEY_SIZE];
919 int rv;
921 arc4random_buf(key, sizeof(key));
922 rv = tls_config_add_ticket_key(config, config->ticket_keyrev++, key,
923 sizeof(key));
924 config->ticket_autorekey = 1;
925 return (rv);