xref: /dragonfly/crypto/libressl/tls/tls_config.c (revision 961e30ea7dc61d1112b778ea4981eac68129fb86)
1 /* $OpenBSD: tls_config.c,v 1.65 2022/01/25 21:51:24 eric 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 *
tls_default_ca_cert_file(void)34 tls_default_ca_cert_file(void)
35 {
36           return default_ca_file;
37 }
38 
39 int
tls_config_load_file(struct tls_error * error,const char * filetype,const char * filename,char ** buf,size_t * len)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 *
tls_config_new_internal(void)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 *
tls_config_new(void)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
tls_config_free(struct tls_config * config)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           pthread_mutex_destroy(&config->mutex);
183 
184           free(config);
185 }
186 
187 static void
tls_config_keypair_add(struct tls_config * config,struct tls_keypair * keypair)188 tls_config_keypair_add(struct tls_config *config, struct tls_keypair *keypair)
189 {
190           struct tls_keypair *kp;
191 
192           kp = config->keypair;
193           while (kp->next != NULL)
194                     kp = kp->next;
195 
196           kp->next = keypair;
197 }
198 
199 const char *
tls_config_error(struct tls_config * config)200 tls_config_error(struct tls_config *config)
201 {
202           return config->error.msg;
203 }
204 
205 void
tls_config_clear_keys(struct tls_config * config)206 tls_config_clear_keys(struct tls_config *config)
207 {
208           struct tls_keypair *kp;
209 
210           for (kp = config->keypair; kp != NULL; kp = kp->next)
211                     tls_keypair_clear_key(kp);
212 }
213 
214 int
tls_config_parse_protocols(uint32_t * protocols,const char * protostr)215 tls_config_parse_protocols(uint32_t *protocols, const char *protostr)
216 {
217           uint32_t proto, protos = 0;
218           char *s, *p, *q;
219           int negate;
220 
221           if (protostr == NULL) {
222                     *protocols = TLS_PROTOCOLS_DEFAULT;
223                     return (0);
224           }
225 
226           if ((s = strdup(protostr)) == NULL)
227                     return (-1);
228 
229           q = s;
230           while ((p = strsep(&q, ",:")) != NULL) {
231                     while (*p == ' ' || *p == '\t')
232                               p++;
233 
234                     negate = 0;
235                     if (*p == '!') {
236                               negate = 1;
237                               p++;
238                     }
239 
240                     if (negate && protos == 0)
241                               protos = TLS_PROTOCOLS_ALL;
242 
243                     proto = 0;
244                     if (strcasecmp(p, "all") == 0 ||
245                         strcasecmp(p, "legacy") == 0)
246                               proto = TLS_PROTOCOLS_ALL;
247                     else if (strcasecmp(p, "default") == 0 ||
248                         strcasecmp(p, "secure") == 0)
249                               proto = TLS_PROTOCOLS_DEFAULT;
250                     if (strcasecmp(p, "tlsv1") == 0)
251                               proto = TLS_PROTOCOL_TLSv1;
252                     else if (strcasecmp(p, "tlsv1.0") == 0)
253                               proto = TLS_PROTOCOL_TLSv1_0;
254                     else if (strcasecmp(p, "tlsv1.1") == 0)
255                               proto = TLS_PROTOCOL_TLSv1_1;
256                     else if (strcasecmp(p, "tlsv1.2") == 0)
257                               proto = TLS_PROTOCOL_TLSv1_2;
258                     else if (strcasecmp(p, "tlsv1.3") == 0)
259                               proto = TLS_PROTOCOL_TLSv1_3;
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
tls_config_parse_alpn(struct tls_config * config,const char * alpn,char ** alpn_data,size_t * alpn_len)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
tls_config_set_alpn(struct tls_config * config,const char * alpn)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
tls_config_add_keypair_file_internal(struct tls_config * config,const char * cert_file,const char * key_file,const char * ocsp_file)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 (key_file != NULL &&
357               tls_keypair_set_key_file(keypair, &config->error, key_file) != 0)
358                     goto err;
359           if (ocsp_file != NULL &&
360               tls_keypair_set_ocsp_staple_file(keypair, &config->error,
361                     ocsp_file) != 0)
362                     goto err;
363 
364           tls_config_keypair_add(config, keypair);
365 
366           return (0);
367 
368  err:
369           tls_keypair_free(keypair);
370           return (-1);
371 }
372 
373 static int
tls_config_add_keypair_mem_internal(struct tls_config * config,const uint8_t * cert,size_t cert_len,const uint8_t * key,size_t key_len,const uint8_t * staple,size_t staple_len)374 tls_config_add_keypair_mem_internal(struct tls_config *config, const uint8_t *cert,
375     size_t cert_len, const uint8_t *key, size_t key_len,
376     const uint8_t *staple, size_t staple_len)
377 {
378           struct tls_keypair *keypair;
379 
380           if ((keypair = tls_keypair_new()) == NULL)
381                     return (-1);
382           if (tls_keypair_set_cert_mem(keypair, &config->error, cert, cert_len) != 0)
383                     goto err;
384           if (key != NULL &&
385               tls_keypair_set_key_mem(keypair, &config->error, key, key_len) != 0)
386                     goto err;
387           if (staple != NULL &&
388               tls_keypair_set_ocsp_staple_mem(keypair, &config->error, staple,
389                     staple_len) != 0)
390                     goto err;
391 
392           tls_config_keypair_add(config, keypair);
393 
394           return (0);
395 
396  err:
397           tls_keypair_free(keypair);
398           return (-1);
399 }
400 
401 int
tls_config_add_keypair_mem(struct tls_config * config,const uint8_t * cert,size_t cert_len,const uint8_t * key,size_t key_len)402 tls_config_add_keypair_mem(struct tls_config *config, const uint8_t *cert,
403     size_t cert_len, const uint8_t *key, size_t key_len)
404 {
405           return tls_config_add_keypair_mem_internal(config, cert, cert_len, key,
406               key_len, NULL, 0);
407 }
408 
409 int
tls_config_add_keypair_file(struct tls_config * config,const char * cert_file,const char * key_file)410 tls_config_add_keypair_file(struct tls_config *config,
411     const char *cert_file, const char *key_file)
412 {
413           return tls_config_add_keypair_file_internal(config, cert_file,
414               key_file, NULL);
415 }
416 
417 int
tls_config_add_keypair_ocsp_mem(struct tls_config * config,const uint8_t * cert,size_t cert_len,const uint8_t * key,size_t key_len,const uint8_t * staple,size_t staple_len)418 tls_config_add_keypair_ocsp_mem(struct tls_config *config, const uint8_t *cert,
419     size_t cert_len, const uint8_t *key, size_t key_len, const uint8_t *staple,
420     size_t staple_len)
421 {
422           return tls_config_add_keypair_mem_internal(config, cert, cert_len, key,
423               key_len, staple, staple_len);
424 }
425 
426 int
tls_config_add_keypair_ocsp_file(struct tls_config * config,const char * cert_file,const char * key_file,const char * ocsp_file)427 tls_config_add_keypair_ocsp_file(struct tls_config *config,
428     const char *cert_file, const char *key_file, const char *ocsp_file)
429 {
430           return tls_config_add_keypair_file_internal(config, cert_file,
431               key_file, ocsp_file);
432 }
433 
434 int
tls_config_set_ca_file(struct tls_config * config,const char * ca_file)435 tls_config_set_ca_file(struct tls_config *config, const char *ca_file)
436 {
437           return tls_config_load_file(&config->error, "CA", ca_file,
438               &config->ca_mem, &config->ca_len);
439 }
440 
441 int
tls_config_set_ca_path(struct tls_config * config,const char * ca_path)442 tls_config_set_ca_path(struct tls_config *config, const char *ca_path)
443 {
444           return tls_set_string(&config->ca_path, ca_path);
445 }
446 
447 int
tls_config_set_ca_mem(struct tls_config * config,const uint8_t * ca,size_t len)448 tls_config_set_ca_mem(struct tls_config *config, const uint8_t *ca, size_t len)
449 {
450           return tls_set_mem(&config->ca_mem, &config->ca_len, ca, len);
451 }
452 
453 int
tls_config_set_cert_file(struct tls_config * config,const char * cert_file)454 tls_config_set_cert_file(struct tls_config *config, const char *cert_file)
455 {
456           return tls_keypair_set_cert_file(config->keypair, &config->error,
457               cert_file);
458 }
459 
460 int
tls_config_set_cert_mem(struct tls_config * config,const uint8_t * cert,size_t len)461 tls_config_set_cert_mem(struct tls_config *config, const uint8_t *cert,
462     size_t len)
463 {
464           return tls_keypair_set_cert_mem(config->keypair, &config->error,
465               cert, len);
466 }
467 
468 int
tls_config_set_ciphers(struct tls_config * config,const char * ciphers)469 tls_config_set_ciphers(struct tls_config *config, const char *ciphers)
470 {
471           SSL_CTX *ssl_ctx = NULL;
472 
473           if (ciphers == NULL ||
474               strcasecmp(ciphers, "default") == 0 ||
475               strcasecmp(ciphers, "secure") == 0)
476                     ciphers = TLS_CIPHERS_DEFAULT;
477           else if (strcasecmp(ciphers, "compat") == 0)
478                     ciphers = TLS_CIPHERS_COMPAT;
479           else if (strcasecmp(ciphers, "legacy") == 0)
480                     ciphers = TLS_CIPHERS_LEGACY;
481           else if (strcasecmp(ciphers, "all") == 0 ||
482               strcasecmp(ciphers, "insecure") == 0)
483                     ciphers = TLS_CIPHERS_ALL;
484 
485           if ((ssl_ctx = SSL_CTX_new(SSLv23_method())) == NULL) {
486                     tls_config_set_errorx(config, "out of memory");
487                     goto err;
488           }
489           if (SSL_CTX_set_cipher_list(ssl_ctx, ciphers) != 1) {
490                     tls_config_set_errorx(config, "no ciphers for '%s'", ciphers);
491                     goto err;
492           }
493 
494           SSL_CTX_free(ssl_ctx);
495           return tls_set_string(&config->ciphers, ciphers);
496 
497  err:
498           SSL_CTX_free(ssl_ctx);
499           return -1;
500 }
501 
502 int
tls_config_set_crl_file(struct tls_config * config,const char * crl_file)503 tls_config_set_crl_file(struct tls_config *config, const char *crl_file)
504 {
505           return tls_config_load_file(&config->error, "CRL", crl_file,
506               &config->crl_mem, &config->crl_len);
507 }
508 
509 int
tls_config_set_crl_mem(struct tls_config * config,const uint8_t * crl,size_t len)510 tls_config_set_crl_mem(struct tls_config *config, const uint8_t *crl,
511     size_t len)
512 {
513           return tls_set_mem(&config->crl_mem, &config->crl_len, crl, len);
514 }
515 
516 int
tls_config_set_dheparams(struct tls_config * config,const char * params)517 tls_config_set_dheparams(struct tls_config *config, const char *params)
518 {
519           int keylen;
520 
521           if (params == NULL || strcasecmp(params, "none") == 0)
522                     keylen = 0;
523           else if (strcasecmp(params, "auto") == 0)
524                     keylen = -1;
525           else if (strcasecmp(params, "legacy") == 0)
526                     keylen = 1024;
527           else {
528                     tls_config_set_errorx(config, "invalid dhe param '%s'", params);
529                     return (-1);
530           }
531 
532           config->dheparams = keylen;
533 
534           return (0);
535 }
536 
537 int
tls_config_set_ecdhecurve(struct tls_config * config,const char * curve)538 tls_config_set_ecdhecurve(struct tls_config *config, const char *curve)
539 {
540           if (curve == NULL ||
541               strcasecmp(curve, "none") == 0 ||
542               strcasecmp(curve, "auto") == 0) {
543                     curve = TLS_ECDHE_CURVES;
544           } else if (strchr(curve, ',') != NULL || strchr(curve, ':') != NULL) {
545                     tls_config_set_errorx(config, "invalid ecdhe curve '%s'",
546                         curve);
547                     return (-1);
548           }
549 
550           return tls_config_set_ecdhecurves(config, curve);
551 }
552 
553 int
tls_config_set_ecdhecurves(struct tls_config * config,const char * curves)554 tls_config_set_ecdhecurves(struct tls_config *config, const char *curves)
555 {
556           int *curves_list = NULL, *curves_new;
557           size_t curves_num = 0;
558           char *cs = NULL;
559           char *p, *q;
560           int rv = -1;
561           int nid;
562 
563           free(config->ecdhecurves);
564           config->ecdhecurves = NULL;
565           config->ecdhecurves_len = 0;
566 
567           if (curves == NULL || strcasecmp(curves, "default") == 0)
568                     curves = TLS_ECDHE_CURVES;
569 
570           if ((cs = strdup(curves)) == NULL) {
571                     tls_config_set_errorx(config, "out of memory");
572                     goto err;
573           }
574 
575           q = cs;
576           while ((p = strsep(&q, ",:")) != NULL) {
577                     while (*p == ' ' || *p == '\t')
578                               p++;
579 
580                     nid = OBJ_sn2nid(p);
581                     if (nid == NID_undef)
582                               nid = OBJ_ln2nid(p);
583                     if (nid == NID_undef)
584                               nid = EC_curve_nist2nid(p);
585                     if (nid == NID_undef) {
586                               tls_config_set_errorx(config,
587                                   "invalid ecdhe curve '%s'", p);
588                               goto err;
589                     }
590 
591                     if ((curves_new = reallocarray(curves_list, curves_num + 1,
592                         sizeof(int))) == NULL) {
593                               tls_config_set_errorx(config, "out of memory");
594                               goto err;
595                     }
596                     curves_list = curves_new;
597                     curves_list[curves_num] = nid;
598                     curves_num++;
599           }
600 
601           config->ecdhecurves = curves_list;
602           config->ecdhecurves_len = curves_num;
603           curves_list = NULL;
604 
605           rv = 0;
606 
607  err:
608           free(cs);
609           free(curves_list);
610 
611           return (rv);
612 }
613 
614 int
tls_config_set_key_file(struct tls_config * config,const char * key_file)615 tls_config_set_key_file(struct tls_config *config, const char *key_file)
616 {
617           return tls_keypair_set_key_file(config->keypair, &config->error,
618               key_file);
619 }
620 
621 int
tls_config_set_key_mem(struct tls_config * config,const uint8_t * key,size_t len)622 tls_config_set_key_mem(struct tls_config *config, const uint8_t *key,
623     size_t len)
624 {
625           return tls_keypair_set_key_mem(config->keypair, &config->error,
626               key, len);
627 }
628 
629 static int
tls_config_set_keypair_file_internal(struct tls_config * config,const char * cert_file,const char * key_file,const char * ocsp_file)630 tls_config_set_keypair_file_internal(struct tls_config *config,
631     const char *cert_file, const char *key_file, const char *ocsp_file)
632 {
633           if (tls_config_set_cert_file(config, cert_file) != 0)
634                     return (-1);
635           if (tls_config_set_key_file(config, key_file) != 0)
636                     return (-1);
637           if (ocsp_file != NULL &&
638               tls_config_set_ocsp_staple_file(config, ocsp_file) != 0)
639                     return (-1);
640 
641           return (0);
642 }
643 
644 static int
tls_config_set_keypair_mem_internal(struct tls_config * config,const uint8_t * cert,size_t cert_len,const uint8_t * key,size_t key_len,const uint8_t * staple,size_t staple_len)645 tls_config_set_keypair_mem_internal(struct tls_config *config, const uint8_t *cert,
646     size_t cert_len, const uint8_t *key, size_t key_len,
647     const uint8_t *staple, size_t staple_len)
648 {
649           if (tls_config_set_cert_mem(config, cert, cert_len) != 0)
650                     return (-1);
651           if (tls_config_set_key_mem(config, key, key_len) != 0)
652                     return (-1);
653           if ((staple != NULL) &&
654               (tls_config_set_ocsp_staple_mem(config, staple, staple_len) != 0))
655                     return (-1);
656 
657           return (0);
658 }
659 
660 int
tls_config_set_keypair_file(struct tls_config * config,const char * cert_file,const char * key_file)661 tls_config_set_keypair_file(struct tls_config *config,
662     const char *cert_file, const char *key_file)
663 {
664           return tls_config_set_keypair_file_internal(config, cert_file, key_file,
665               NULL);
666 }
667 
668 int
tls_config_set_keypair_mem(struct tls_config * config,const uint8_t * cert,size_t cert_len,const uint8_t * key,size_t key_len)669 tls_config_set_keypair_mem(struct tls_config *config, const uint8_t *cert,
670     size_t cert_len, const uint8_t *key, size_t key_len)
671 {
672           return tls_config_set_keypair_mem_internal(config, cert, cert_len,
673               key, key_len, NULL, 0);
674 }
675 
676 int
tls_config_set_keypair_ocsp_file(struct tls_config * config,const char * cert_file,const char * key_file,const char * ocsp_file)677 tls_config_set_keypair_ocsp_file(struct tls_config *config,
678     const char *cert_file, const char *key_file, const char *ocsp_file)
679 {
680           return tls_config_set_keypair_file_internal(config, cert_file, key_file,
681               ocsp_file);
682 }
683 
684 int
tls_config_set_keypair_ocsp_mem(struct tls_config * config,const uint8_t * cert,size_t cert_len,const uint8_t * key,size_t key_len,const uint8_t * staple,size_t staple_len)685 tls_config_set_keypair_ocsp_mem(struct tls_config *config, const uint8_t *cert,
686     size_t cert_len, const uint8_t *key, size_t key_len,
687     const uint8_t *staple, size_t staple_len)
688 {
689           return tls_config_set_keypair_mem_internal(config, cert, cert_len,
690               key, key_len, staple, staple_len);
691 }
692 
693 
694 int
tls_config_set_protocols(struct tls_config * config,uint32_t protocols)695 tls_config_set_protocols(struct tls_config *config, uint32_t protocols)
696 {
697           config->protocols = protocols;
698 
699           return (0);
700 }
701 
702 int
tls_config_set_session_fd(struct tls_config * config,int session_fd)703 tls_config_set_session_fd(struct tls_config *config, int session_fd)
704 {
705           struct stat sb;
706           mode_t mugo;
707 
708           if (session_fd == -1) {
709                     config->session_fd = session_fd;
710                     return (0);
711           }
712 
713           if (fstat(session_fd, &sb) == -1) {
714                     tls_config_set_error(config, "failed to stat session file");
715                     return (-1);
716           }
717           if (!S_ISREG(sb.st_mode)) {
718                     tls_config_set_errorx(config,
719                         "session file is not a regular file");
720                     return (-1);
721           }
722 
723           if (sb.st_uid != getuid()) {
724                     tls_config_set_errorx(config, "session file has incorrect "
725                         "owner (uid %u != %u)", sb.st_uid, getuid());
726                     return (-1);
727           }
728           mugo = sb.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO);
729           if (mugo != (S_IRUSR|S_IWUSR)) {
730                     tls_config_set_errorx(config, "session file has incorrect "
731                         "permissions (%o != 600)", mugo);
732                     return (-1);
733           }
734 
735           config->session_fd = session_fd;
736 
737           return (0);
738 }
739 
740 int
tls_config_set_sign_cb(struct tls_config * config,tls_sign_cb cb,void * cb_arg)741 tls_config_set_sign_cb(struct tls_config *config, tls_sign_cb cb, void *cb_arg)
742 {
743           config->use_fake_private_key = 1;
744           config->skip_private_key_check = 1;
745           config->sign_cb = cb;
746           config->sign_cb_arg = cb_arg;
747 
748           return (0);
749 }
750 
751 int
tls_config_set_verify_depth(struct tls_config * config,int verify_depth)752 tls_config_set_verify_depth(struct tls_config *config, int verify_depth)
753 {
754           config->verify_depth = verify_depth;
755 
756           return (0);
757 }
758 
759 void
tls_config_prefer_ciphers_client(struct tls_config * config)760 tls_config_prefer_ciphers_client(struct tls_config *config)
761 {
762           config->ciphers_server = 0;
763 }
764 
765 void
tls_config_prefer_ciphers_server(struct tls_config * config)766 tls_config_prefer_ciphers_server(struct tls_config *config)
767 {
768           config->ciphers_server = 1;
769 }
770 
771 void
tls_config_insecure_noverifycert(struct tls_config * config)772 tls_config_insecure_noverifycert(struct tls_config *config)
773 {
774           config->verify_cert = 0;
775 }
776 
777 void
tls_config_insecure_noverifyname(struct tls_config * config)778 tls_config_insecure_noverifyname(struct tls_config *config)
779 {
780           config->verify_name = 0;
781 }
782 
783 void
tls_config_insecure_noverifytime(struct tls_config * config)784 tls_config_insecure_noverifytime(struct tls_config *config)
785 {
786           config->verify_time = 0;
787 }
788 
789 void
tls_config_verify(struct tls_config * config)790 tls_config_verify(struct tls_config *config)
791 {
792           config->verify_cert = 1;
793           config->verify_name = 1;
794           config->verify_time = 1;
795 }
796 
797 void
tls_config_ocsp_require_stapling(struct tls_config * config)798 tls_config_ocsp_require_stapling(struct tls_config *config)
799 {
800           config->ocsp_require_stapling = 1;
801 }
802 
803 void
tls_config_verify_client(struct tls_config * config)804 tls_config_verify_client(struct tls_config *config)
805 {
806           config->verify_client = 1;
807 }
808 
809 void
tls_config_verify_client_optional(struct tls_config * config)810 tls_config_verify_client_optional(struct tls_config *config)
811 {
812           config->verify_client = 2;
813 }
814 
815 void
tls_config_skip_private_key_check(struct tls_config * config)816 tls_config_skip_private_key_check(struct tls_config *config)
817 {
818           config->skip_private_key_check = 1;
819 }
820 
821 void
tls_config_use_fake_private_key(struct tls_config * config)822 tls_config_use_fake_private_key(struct tls_config *config)
823 {
824           config->use_fake_private_key = 1;
825           config->skip_private_key_check = 1;
826 }
827 
828 int
tls_config_set_ocsp_staple_file(struct tls_config * config,const char * staple_file)829 tls_config_set_ocsp_staple_file(struct tls_config *config, const char *staple_file)
830 {
831           return tls_keypair_set_ocsp_staple_file(config->keypair, &config->error,
832               staple_file);
833 }
834 
835 int
tls_config_set_ocsp_staple_mem(struct tls_config * config,const uint8_t * staple,size_t len)836 tls_config_set_ocsp_staple_mem(struct tls_config *config, const uint8_t *staple,
837     size_t len)
838 {
839           return tls_keypair_set_ocsp_staple_mem(config->keypair, &config->error,
840               staple, len);
841 }
842 
843 int
tls_config_set_session_id(struct tls_config * config,const unsigned char * session_id,size_t len)844 tls_config_set_session_id(struct tls_config *config,
845     const unsigned char *session_id, size_t len)
846 {
847           if (len > TLS_MAX_SESSION_ID_LENGTH) {
848                     tls_config_set_errorx(config, "session ID too large");
849                     return (-1);
850           }
851           memset(config->session_id, 0, sizeof(config->session_id));
852           memcpy(config->session_id, session_id, len);
853           return (0);
854 }
855 
856 int
tls_config_set_session_lifetime(struct tls_config * config,int lifetime)857 tls_config_set_session_lifetime(struct tls_config *config, int lifetime)
858 {
859           if (lifetime > TLS_MAX_SESSION_TIMEOUT) {
860                     tls_config_set_errorx(config, "session lifetime too large");
861                     return (-1);
862           }
863           if (lifetime != 0 && lifetime < TLS_MIN_SESSION_TIMEOUT) {
864                     tls_config_set_errorx(config, "session lifetime too small");
865                     return (-1);
866           }
867 
868           config->session_lifetime = lifetime;
869           return (0);
870 }
871 
872 int
tls_config_add_ticket_key(struct tls_config * config,uint32_t keyrev,unsigned char * key,size_t keylen)873 tls_config_add_ticket_key(struct tls_config *config, uint32_t keyrev,
874     unsigned char *key, size_t keylen)
875 {
876           struct tls_ticket_key newkey;
877           int i;
878 
879           if (TLS_TICKET_KEY_SIZE != keylen ||
880               sizeof(newkey.aes_key) + sizeof(newkey.hmac_key) > keylen) {
881                     tls_config_set_errorx(config,
882                         "wrong amount of ticket key data");
883                     return (-1);
884           }
885 
886           keyrev = htonl(keyrev);
887           memset(&newkey, 0, sizeof(newkey));
888           memcpy(newkey.key_name, &keyrev, sizeof(keyrev));
889           memcpy(newkey.aes_key, key, sizeof(newkey.aes_key));
890           memcpy(newkey.hmac_key, key + sizeof(newkey.aes_key),
891               sizeof(newkey.hmac_key));
892           newkey.time = time(NULL);
893 
894           for (i = 0; i < TLS_NUM_TICKETS; i++) {
895                     struct tls_ticket_key *tk = &config->ticket_keys[i];
896                     if (memcmp(newkey.key_name, tk->key_name,
897                         sizeof(tk->key_name)) != 0)
898                               continue;
899 
900                     /* allow re-entry of most recent key */
901                     if (i == 0 && memcmp(newkey.aes_key, tk->aes_key,
902                         sizeof(tk->aes_key)) == 0 && memcmp(newkey.hmac_key,
903                         tk->hmac_key, sizeof(tk->hmac_key)) == 0)
904                               return (0);
905                     tls_config_set_errorx(config, "ticket key already present");
906                     return (-1);
907           }
908 
909           memmove(&config->ticket_keys[1], &config->ticket_keys[0],
910               sizeof(config->ticket_keys) - sizeof(config->ticket_keys[0]));
911           config->ticket_keys[0] = newkey;
912 
913           config->ticket_autorekey = 0;
914 
915           return (0);
916 }
917 
918 int
tls_config_ticket_autorekey(struct tls_config * config)919 tls_config_ticket_autorekey(struct tls_config *config)
920 {
921           unsigned char key[TLS_TICKET_KEY_SIZE];
922           int rv;
923 
924           arc4random_buf(key, sizeof(key));
925           rv = tls_config_add_ticket_key(config, config->ticket_keyrev++, key,
926               sizeof(key));
927           config->ticket_autorekey = 1;
928           return (rv);
929 }
930