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