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