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