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 } 908