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