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