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