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