update libressl to v2.7.4
[unleashed.git] / lib / libtls / tls_config.c
blob6094c7426566e5367258cc9621bff4da281fe43c
1 /* $OpenBSD: tls_config.c,v 1.51.2.1 2018/04/18 16:29:11 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>
28 #include "tls_internal.h"
30 int
31 tls_config_load_file(struct tls_error *error, const char *filetype,
32 const char *filename, char **buf, size_t *len)
34 struct stat st;
35 int fd = -1;
36 ssize_t n;
38 free(*buf);
39 *buf = NULL;
40 *len = 0;
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;
47 if (fstat(fd, &st) != 0) {
48 tls_error_set(error, "failed to stat %s file '%s'",
49 filetype, filename);
50 goto err;
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;
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;
66 close(fd);
67 return 0;
69 err:
70 if (fd != -1)
71 close(fd);
72 freezero(*buf, *len);
73 *buf = NULL;
74 *len = 0;
76 return -1;
79 struct tls_config *
80 tls_config_new_internal(void)
82 struct tls_config *config;
83 unsigned char sid[TLS_MAX_SESSION_ID_LENGTH];
85 if ((config = calloc(1, sizeof(*config))) == NULL)
86 return (NULL);
88 if ((config->keypair = tls_keypair_new()) == NULL)
89 goto err;
91 config->refcount = 1;
92 config->session_fd = -1;
95 * Default configuration.
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;
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;
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.
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;
120 tls_config_prefer_ciphers_server(config);
122 tls_config_verify(config);
124 return (config);
126 err:
127 tls_config_free(config);
128 return (NULL);
131 struct tls_config *
132 tls_config_new(void)
134 if (tls_init() == -1)
135 return (NULL);
137 return tls_config_new_internal();
140 void
141 tls_config_free(struct tls_config *config)
143 struct tls_keypair *kp, *nkp;
145 if (config == NULL)
146 return;
148 if (--config->refcount > 0)
149 return;
151 for (kp = config->keypair; kp != NULL; kp = nkp) {
152 nkp = kp->next;
153 tls_keypair_free(kp);
156 free(config->error.msg);
158 free(config->alpn);
159 free((char *)config->ca_mem);
160 free((char *)config->ca_path);
161 free((char *)config->ciphers);
162 free((char *)config->crl_mem);
163 free(config->ecdhecurves);
165 free(config);
168 static void
169 tls_config_keypair_add(struct tls_config *config, struct tls_keypair *keypair)
171 struct tls_keypair *kp;
173 kp = config->keypair;
174 while (kp->next != NULL)
175 kp = kp->next;
177 kp->next = keypair;
180 const char *
181 tls_config_error(struct tls_config *config)
183 return config->error.msg;
186 void
187 tls_config_clear_keys(struct tls_config *config)
189 struct tls_keypair *kp;
191 for (kp = config->keypair; kp != NULL; kp = kp->next)
192 tls_keypair_clear_key(kp);
196 tls_config_parse_protocols(uint32_t *protocols, const char *protostr)
198 uint32_t proto, protos = 0;
199 char *s, *p, *q;
200 int negate;
202 if (protostr == NULL) {
203 *protocols = TLS_PROTOCOLS_DEFAULT;
204 return (0);
207 if ((s = strdup(protostr)) == NULL)
208 return (-1);
210 q = s;
211 while ((p = strsep(&q, ",:")) != NULL) {
212 while (*p == ' ' || *p == '\t')
213 p++;
215 negate = 0;
216 if (*p == '!') {
217 negate = 1;
218 p++;
221 if (negate && protos == 0)
222 protos = TLS_PROTOCOLS_ALL;
224 proto = 0;
225 if (strcasecmp(p, "all") == 0 ||
226 strcasecmp(p, "legacy") == 0)
227 proto = TLS_PROTOCOLS_ALL;
228 else if (strcasecmp(p, "default") == 0 ||
229 strcasecmp(p, "secure") == 0)
230 proto = TLS_PROTOCOLS_DEFAULT;
231 if (strcasecmp(p, "tlsv1") == 0)
232 proto = TLS_PROTOCOL_TLSv1;
233 else if (strcasecmp(p, "tlsv1.0") == 0)
234 proto = TLS_PROTOCOL_TLSv1_0;
235 else if (strcasecmp(p, "tlsv1.1") == 0)
236 proto = TLS_PROTOCOL_TLSv1_1;
237 else if (strcasecmp(p, "tlsv1.2") == 0)
238 proto = TLS_PROTOCOL_TLSv1_2;
240 if (proto == 0) {
241 free(s);
242 return (-1);
245 if (negate)
246 protos &= ~proto;
247 else
248 protos |= proto;
251 *protocols = protos;
253 free(s);
255 return (0);
258 static int
259 tls_config_parse_alpn(struct tls_config *config, const char *alpn,
260 char **alpn_data, size_t *alpn_len)
262 size_t buf_len, i, len;
263 char *buf = NULL;
264 char *s = NULL;
265 char *p, *q;
267 free(*alpn_data);
268 *alpn_data = NULL;
269 *alpn_len = 0;
271 if ((buf_len = strlen(alpn) + 1) > 65535) {
272 tls_config_set_errorx(config, "alpn too large");
273 goto err;
276 if ((buf = malloc(buf_len)) == NULL) {
277 tls_config_set_errorx(config, "out of memory");
278 goto err;
281 if ((s = strdup(alpn)) == NULL) {
282 tls_config_set_errorx(config, "out of memory");
283 goto err;
286 i = 0;
287 q = s;
288 while ((p = strsep(&q, ",")) != NULL) {
289 if ((len = strlen(p)) == 0) {
290 tls_config_set_errorx(config,
291 "alpn protocol with zero length");
292 goto err;
294 if (len > 255) {
295 tls_config_set_errorx(config,
296 "alpn protocol too long");
297 goto err;
299 buf[i++] = len & 0xff;
300 memcpy(&buf[i], p, len);
301 i += len;
304 free(s);
306 *alpn_data = buf;
307 *alpn_len = buf_len;
309 return (0);
311 err:
312 free(buf);
313 free(s);
315 return (-1);
319 tls_config_set_alpn(struct tls_config *config, const char *alpn)
321 return tls_config_parse_alpn(config, alpn, &config->alpn,
322 &config->alpn_len);
325 static int
326 tls_config_add_keypair_file_internal(struct tls_config *config,
327 const char *cert_file, const char *key_file, const char *ocsp_file)
329 struct tls_keypair *keypair;
331 if ((keypair = tls_keypair_new()) == NULL)
332 return (-1);
333 if (tls_keypair_set_cert_file(keypair, &config->error, cert_file) != 0)
334 goto err;
335 if (tls_keypair_set_key_file(keypair, &config->error, key_file) != 0)
336 goto err;
337 if (ocsp_file != NULL &&
338 tls_keypair_set_ocsp_staple_file(keypair, &config->error,
339 ocsp_file) != 0)
340 goto err;
342 tls_config_keypair_add(config, keypair);
344 return (0);
346 err:
347 tls_keypair_free(keypair);
348 return (-1);
351 static int
352 tls_config_add_keypair_mem_internal(struct tls_config *config, const uint8_t *cert,
353 size_t cert_len, const uint8_t *key, size_t key_len,
354 const uint8_t *staple, size_t staple_len)
356 struct tls_keypair *keypair;
358 if ((keypair = tls_keypair_new()) == NULL)
359 return (-1);
360 if (tls_keypair_set_cert_mem(keypair, &config->error, cert, cert_len) != 0)
361 goto err;
362 if (tls_keypair_set_key_mem(keypair, &config->error, key, key_len) != 0)
363 goto err;
364 if (staple != NULL &&
365 tls_keypair_set_ocsp_staple_mem(keypair, &config->error, staple,
366 staple_len) != 0)
367 goto err;
369 tls_config_keypair_add(config, keypair);
371 return (0);
373 err:
374 tls_keypair_free(keypair);
375 return (-1);
379 tls_config_add_keypair_mem(struct tls_config *config, const uint8_t *cert,
380 size_t cert_len, const uint8_t *key, size_t key_len)
382 return tls_config_add_keypair_mem_internal(config, cert, cert_len, key,
383 key_len, NULL, 0);
387 tls_config_add_keypair_file(struct tls_config *config,
388 const char *cert_file, const char *key_file)
390 return tls_config_add_keypair_file_internal(config, cert_file,
391 key_file, NULL);
395 tls_config_add_keypair_ocsp_mem(struct tls_config *config, const uint8_t *cert,
396 size_t cert_len, const uint8_t *key, size_t key_len, const uint8_t *staple,
397 size_t staple_len)
399 return tls_config_add_keypair_mem_internal(config, cert, cert_len, key,
400 key_len, staple, staple_len);
404 tls_config_add_keypair_ocsp_file(struct tls_config *config,
405 const char *cert_file, const char *key_file, const char *ocsp_file)
407 return tls_config_add_keypair_file_internal(config, cert_file,
408 key_file, ocsp_file);
412 tls_config_set_ca_file(struct tls_config *config, const char *ca_file)
414 return tls_config_load_file(&config->error, "CA", ca_file,
415 &config->ca_mem, &config->ca_len);
419 tls_config_set_ca_path(struct tls_config *config, const char *ca_path)
421 return tls_set_string(&config->ca_path, ca_path);
425 tls_config_set_ca_mem(struct tls_config *config, const uint8_t *ca, size_t len)
427 return tls_set_mem(&config->ca_mem, &config->ca_len, ca, len);
431 tls_config_set_cert_file(struct tls_config *config, const char *cert_file)
433 return tls_keypair_set_cert_file(config->keypair, &config->error,
434 cert_file);
438 tls_config_set_cert_mem(struct tls_config *config, const uint8_t *cert,
439 size_t len)
441 return tls_keypair_set_cert_mem(config->keypair, &config->error,
442 cert, len);
446 tls_config_set_ciphers(struct tls_config *config, const char *ciphers)
448 SSL_CTX *ssl_ctx = NULL;
450 if (ciphers == NULL ||
451 strcasecmp(ciphers, "default") == 0 ||
452 strcasecmp(ciphers, "secure") == 0)
453 ciphers = TLS_CIPHERS_DEFAULT;
454 else if (strcasecmp(ciphers, "compat") == 0)
455 ciphers = TLS_CIPHERS_COMPAT;
456 else if (strcasecmp(ciphers, "legacy") == 0)
457 ciphers = TLS_CIPHERS_LEGACY;
458 else if (strcasecmp(ciphers, "all") == 0 ||
459 strcasecmp(ciphers, "insecure") == 0)
460 ciphers = TLS_CIPHERS_ALL;
462 if ((ssl_ctx = SSL_CTX_new(SSLv23_method())) == NULL) {
463 tls_config_set_errorx(config, "out of memory");
464 goto err;
466 if (SSL_CTX_set_cipher_list(ssl_ctx, ciphers) != 1) {
467 tls_config_set_errorx(config, "no ciphers for '%s'", ciphers);
468 goto err;
471 SSL_CTX_free(ssl_ctx);
472 return tls_set_string(&config->ciphers, ciphers);
474 err:
475 SSL_CTX_free(ssl_ctx);
476 return -1;
480 tls_config_set_crl_file(struct tls_config *config, const char *crl_file)
482 return tls_config_load_file(&config->error, "CRL", crl_file,
483 &config->crl_mem, &config->crl_len);
487 tls_config_set_crl_mem(struct tls_config *config, const uint8_t *crl,
488 size_t len)
490 return tls_set_mem(&config->crl_mem, &config->crl_len, crl, len);
494 tls_config_set_dheparams(struct tls_config *config, const char *params)
496 int keylen;
498 if (params == NULL || strcasecmp(params, "none") == 0)
499 keylen = 0;
500 else if (strcasecmp(params, "auto") == 0)
501 keylen = -1;
502 else if (strcasecmp(params, "legacy") == 0)
503 keylen = 1024;
504 else {
505 tls_config_set_errorx(config, "invalid dhe param '%s'", params);
506 return (-1);
509 config->dheparams = keylen;
511 return (0);
515 tls_config_set_ecdhecurve(struct tls_config *config, const char *curve)
517 if (curve == NULL ||
518 strcasecmp(curve, "none") == 0 ||
519 strcasecmp(curve, "auto") == 0) {
520 curve = TLS_ECDHE_CURVES;
521 } else if (strchr(curve, ',') != NULL || strchr(curve, ':') != NULL) {
522 tls_config_set_errorx(config, "invalid ecdhe curve '%s'",
523 curve);
524 return (-1);
527 return tls_config_set_ecdhecurves(config, curve);
531 tls_config_set_ecdhecurves(struct tls_config *config, const char *curves)
533 int *curves_list = NULL, *curves_new;
534 size_t curves_num = 0;
535 char *cs = NULL;
536 char *p, *q;
537 int rv = -1;
538 int nid;
540 free(config->ecdhecurves);
541 config->ecdhecurves = NULL;
542 config->ecdhecurves_len = 0;
544 if (curves == NULL || strcasecmp(curves, "default") == 0)
545 curves = TLS_ECDHE_CURVES;
547 if ((cs = strdup(curves)) == NULL) {
548 tls_config_set_errorx(config, "out of memory");
549 goto err;
552 q = cs;
553 while ((p = strsep(&q, ",:")) != NULL) {
554 while (*p == ' ' || *p == '\t')
555 p++;
557 nid = OBJ_sn2nid(p);
558 if (nid == NID_undef)
559 nid = OBJ_ln2nid(p);
560 if (nid == NID_undef)
561 nid = EC_curve_nist2nid(p);
562 if (nid == NID_undef) {
563 tls_config_set_errorx(config,
564 "invalid ecdhe curve '%s'", p);
565 goto err;
568 if ((curves_new = reallocarray(curves_list, curves_num + 1,
569 sizeof(int))) == NULL) {
570 tls_config_set_errorx(config, "out of memory");
571 goto err;
573 curves_list = curves_new;
574 curves_list[curves_num] = nid;
575 curves_num++;
578 config->ecdhecurves = curves_list;
579 config->ecdhecurves_len = curves_num;
580 curves_list = NULL;
582 rv = 0;
584 err:
585 free(cs);
586 free(curves_list);
588 return (rv);
592 tls_config_set_key_file(struct tls_config *config, const char *key_file)
594 return tls_keypair_set_key_file(config->keypair, &config->error,
595 key_file);
599 tls_config_set_key_mem(struct tls_config *config, const uint8_t *key,
600 size_t len)
602 return tls_keypair_set_key_mem(config->keypair, &config->error,
603 key, len);
606 static int
607 tls_config_set_keypair_file_internal(struct tls_config *config,
608 const char *cert_file, const char *key_file, const char *ocsp_file)
610 if (tls_config_set_cert_file(config, cert_file) != 0)
611 return (-1);
612 if (tls_config_set_key_file(config, key_file) != 0)
613 return (-1);
614 if (tls_config_set_key_file(config, key_file) != 0)
615 return (-1);
616 if (ocsp_file != NULL &&
617 tls_config_set_ocsp_staple_file(config, ocsp_file) != 0)
618 return (-1);
620 return (0);
623 static int
624 tls_config_set_keypair_mem_internal(struct tls_config *config, const uint8_t *cert,
625 size_t cert_len, const uint8_t *key, size_t key_len,
626 const uint8_t *staple, size_t staple_len)
628 if (tls_config_set_cert_mem(config, cert, cert_len) != 0)
629 return (-1);
630 if (tls_config_set_key_mem(config, key, key_len) != 0)
631 return (-1);
632 if ((staple != NULL) &&
633 (tls_config_set_ocsp_staple_mem(config, staple, staple_len) != 0))
634 return (-1);
636 return (0);
640 tls_config_set_keypair_file(struct tls_config *config,
641 const char *cert_file, const char *key_file)
643 return tls_config_set_keypair_file_internal(config, cert_file, key_file,
644 NULL);
648 tls_config_set_keypair_mem(struct tls_config *config, const uint8_t *cert,
649 size_t cert_len, const uint8_t *key, size_t key_len)
651 return tls_config_set_keypair_mem_internal(config, cert, cert_len,
652 key, key_len, NULL, 0);
656 tls_config_set_keypair_ocsp_file(struct tls_config *config,
657 const char *cert_file, const char *key_file, const char *ocsp_file)
659 return tls_config_set_keypair_file_internal(config, cert_file, key_file,
660 ocsp_file);
664 tls_config_set_keypair_ocsp_mem(struct tls_config *config, const uint8_t *cert,
665 size_t cert_len, const uint8_t *key, size_t key_len,
666 const uint8_t *staple, size_t staple_len)
668 return tls_config_set_keypair_mem_internal(config, cert, cert_len,
669 key, key_len, staple, staple_len);
674 tls_config_set_protocols(struct tls_config *config, uint32_t protocols)
676 config->protocols = protocols;
678 return (0);
682 tls_config_set_session_fd(struct tls_config *config, int session_fd)
684 struct stat sb;
685 mode_t mugo;
687 if (session_fd == -1) {
688 config->session_fd = session_fd;
689 return (0);
692 if (fstat(session_fd, &sb) == -1) {
693 tls_config_set_error(config, "failed to stat session file");
694 return (-1);
696 if (!S_ISREG(sb.st_mode)) {
697 tls_config_set_errorx(config,
698 "session file is not a regular file");
699 return (-1);
702 if (sb.st_uid != getuid()) {
703 tls_config_set_errorx(config, "session file has incorrect "
704 "owner (uid %i != %i)", sb.st_uid, getuid());
705 return (-1);
707 mugo = sb.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO);
708 if (mugo != (S_IRUSR|S_IWUSR)) {
709 tls_config_set_errorx(config, "session file has incorrect "
710 "permissions (%o != 600)", mugo);
711 return (-1);
714 config->session_fd = session_fd;
716 return (0);
720 tls_config_set_verify_depth(struct tls_config *config, int verify_depth)
722 config->verify_depth = verify_depth;
724 return (0);
727 void
728 tls_config_prefer_ciphers_client(struct tls_config *config)
730 config->ciphers_server = 0;
733 void
734 tls_config_prefer_ciphers_server(struct tls_config *config)
736 config->ciphers_server = 1;
739 void
740 tls_config_insecure_noverifycert(struct tls_config *config)
742 config->verify_cert = 0;
745 void
746 tls_config_insecure_noverifyname(struct tls_config *config)
748 config->verify_name = 0;
751 void
752 tls_config_insecure_noverifytime(struct tls_config *config)
754 config->verify_time = 0;
757 void
758 tls_config_verify(struct tls_config *config)
760 config->verify_cert = 1;
761 config->verify_name = 1;
762 config->verify_time = 1;
765 void
766 tls_config_ocsp_require_stapling(struct tls_config *config)
768 config->ocsp_require_stapling = 1;
771 void
772 tls_config_verify_client(struct tls_config *config)
774 config->verify_client = 1;
777 void
778 tls_config_verify_client_optional(struct tls_config *config)
780 config->verify_client = 2;
783 void
784 tls_config_skip_private_key_check(struct tls_config *config)
786 config->skip_private_key_check = 1;
790 tls_config_set_ocsp_staple_file(struct tls_config *config, const char *staple_file)
792 return tls_keypair_set_ocsp_staple_file(config->keypair, &config->error,
793 staple_file);
797 tls_config_set_ocsp_staple_mem(struct tls_config *config, const uint8_t *staple,
798 size_t len)
800 return tls_keypair_set_ocsp_staple_mem(config->keypair, &config->error,
801 staple, len);
805 tls_config_set_session_id(struct tls_config *config,
806 const unsigned char *session_id, size_t len)
808 if (len > TLS_MAX_SESSION_ID_LENGTH) {
809 tls_config_set_errorx(config, "session ID too large");
810 return (-1);
812 memset(config->session_id, 0, sizeof(config->session_id));
813 memcpy(config->session_id, session_id, len);
814 return (0);
818 tls_config_set_session_lifetime(struct tls_config *config, int lifetime)
820 if (lifetime > TLS_MAX_SESSION_TIMEOUT) {
821 tls_config_set_errorx(config, "session lifetime too large");
822 return (-1);
824 if (lifetime != 0 && lifetime < TLS_MIN_SESSION_TIMEOUT) {
825 tls_config_set_errorx(config, "session lifetime too small");
826 return (-1);
829 config->session_lifetime = lifetime;
830 return (0);
834 tls_config_add_ticket_key(struct tls_config *config, uint32_t keyrev,
835 unsigned char *key, size_t keylen)
837 struct tls_ticket_key newkey;
838 int i;
840 if (TLS_TICKET_KEY_SIZE != keylen ||
841 sizeof(newkey.aes_key) + sizeof(newkey.hmac_key) > keylen) {
842 tls_config_set_errorx(config,
843 "wrong amount of ticket key data");
844 return (-1);
847 keyrev = htonl(keyrev);
848 memset(&newkey, 0, sizeof(newkey));
849 memcpy(newkey.key_name, &keyrev, sizeof(keyrev));
850 memcpy(newkey.aes_key, key, sizeof(newkey.aes_key));
851 memcpy(newkey.hmac_key, key + sizeof(newkey.aes_key),
852 sizeof(newkey.hmac_key));
853 newkey.time = time(NULL);
855 for (i = 0; i < TLS_NUM_TICKETS; i++) {
856 struct tls_ticket_key *tk = &config->ticket_keys[i];
857 if (memcmp(newkey.key_name, tk->key_name,
858 sizeof(tk->key_name)) != 0)
859 continue;
861 /* allow re-entry of most recent key */
862 if (i == 0 && memcmp(newkey.aes_key, tk->aes_key,
863 sizeof(tk->aes_key)) == 0 && memcmp(newkey.hmac_key,
864 tk->hmac_key, sizeof(tk->hmac_key)) == 0)
865 return (0);
866 tls_config_set_errorx(config, "ticket key already present");
867 return (-1);
870 memmove(&config->ticket_keys[1], &config->ticket_keys[0],
871 sizeof(config->ticket_keys) - sizeof(config->ticket_keys[0]));
872 config->ticket_keys[0] = newkey;
874 config->ticket_autorekey = 0;
876 return (0);
880 tls_config_ticket_autorekey(struct tls_config *config)
882 unsigned char key[TLS_TICKET_KEY_SIZE];
883 int rv;
885 arc4random_buf(key, sizeof(key));
886 rv = tls_config_add_ticket_key(config, config->ticket_keyrev++, key,
887 sizeof(key));
888 config->ticket_autorekey = 1;
889 return (rv);