1 /* $OpenBSD: tls_config.c,v 1.62 2021/01/21 19:09:10 eric 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 pthread_mutex_destroy(&config->mutex); 183 184 free(config); 185 } 186 187 static void 188 tls_config_keypair_add(struct tls_config *config, struct tls_keypair *keypair) 189 { 190 struct tls_keypair *kp; 191 192 kp = config->keypair; 193 while (kp->next != NULL) 194 kp = kp->next; 195 196 kp->next = keypair; 197 } 198 199 const char * 200 tls_config_error(struct tls_config *config) 201 { 202 return config->error.msg; 203 } 204 205 void 206 tls_config_clear_keys(struct tls_config *config) 207 { 208 struct tls_keypair *kp; 209 210 for (kp = config->keypair; kp != NULL; kp = kp->next) 211 tls_keypair_clear_key(kp); 212 } 213 214 int 215 tls_config_parse_protocols(uint32_t *protocols, const char *protostr) 216 { 217 uint32_t proto, protos = 0; 218 char *s, *p, *q; 219 int negate; 220 221 if (protostr == NULL) { 222 *protocols = TLS_PROTOCOLS_DEFAULT; 223 return (0); 224 } 225 226 if ((s = strdup(protostr)) == NULL) 227 return (-1); 228 229 q = s; 230 while ((p = strsep(&q, ",:")) != NULL) { 231 while (*p == ' ' || *p == '\t') 232 p++; 233 234 negate = 0; 235 if (*p == '!') { 236 negate = 1; 237 p++; 238 } 239 240 if (negate && protos == 0) 241 protos = TLS_PROTOCOLS_ALL; 242 243 proto = 0; 244 if (strcasecmp(p, "all") == 0 || 245 strcasecmp(p, "legacy") == 0) 246 proto = TLS_PROTOCOLS_ALL; 247 else if (strcasecmp(p, "default") == 0 || 248 strcasecmp(p, "secure") == 0) 249 proto = TLS_PROTOCOLS_DEFAULT; 250 if (strcasecmp(p, "tlsv1") == 0) 251 proto = TLS_PROTOCOL_TLSv1; 252 else if (strcasecmp(p, "tlsv1.0") == 0) 253 proto = TLS_PROTOCOL_TLSv1_0; 254 else if (strcasecmp(p, "tlsv1.1") == 0) 255 proto = TLS_PROTOCOL_TLSv1_1; 256 else if (strcasecmp(p, "tlsv1.2") == 0) 257 proto = TLS_PROTOCOL_TLSv1_2; 258 else if (strcasecmp(p, "tlsv1.3") == 0) 259 proto = TLS_PROTOCOL_TLSv1_3; 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 (key_file != NULL && 357 tls_keypair_set_key_file(keypair, &config->error, key_file) != 0) 358 goto err; 359 if (ocsp_file != NULL && 360 tls_keypair_set_ocsp_staple_file(keypair, &config->error, 361 ocsp_file) != 0) 362 goto err; 363 364 tls_config_keypair_add(config, keypair); 365 366 return (0); 367 368 err: 369 tls_keypair_free(keypair); 370 return (-1); 371 } 372 373 static int 374 tls_config_add_keypair_mem_internal(struct tls_config *config, const uint8_t *cert, 375 size_t cert_len, const uint8_t *key, size_t key_len, 376 const uint8_t *staple, size_t staple_len) 377 { 378 struct tls_keypair *keypair; 379 380 if ((keypair = tls_keypair_new()) == NULL) 381 return (-1); 382 if (tls_keypair_set_cert_mem(keypair, &config->error, cert, cert_len) != 0) 383 goto err; 384 if (key != NULL && 385 tls_keypair_set_key_mem(keypair, &config->error, key, key_len) != 0) 386 goto err; 387 if (staple != NULL && 388 tls_keypair_set_ocsp_staple_mem(keypair, &config->error, staple, 389 staple_len) != 0) 390 goto err; 391 392 tls_config_keypair_add(config, keypair); 393 394 return (0); 395 396 err: 397 tls_keypair_free(keypair); 398 return (-1); 399 } 400 401 int 402 tls_config_add_keypair_mem(struct tls_config *config, const uint8_t *cert, 403 size_t cert_len, const uint8_t *key, size_t key_len) 404 { 405 return tls_config_add_keypair_mem_internal(config, cert, cert_len, key, 406 key_len, NULL, 0); 407 } 408 409 int 410 tls_config_add_keypair_file(struct tls_config *config, 411 const char *cert_file, const char *key_file) 412 { 413 return tls_config_add_keypair_file_internal(config, cert_file, 414 key_file, NULL); 415 } 416 417 int 418 tls_config_add_keypair_ocsp_mem(struct tls_config *config, const uint8_t *cert, 419 size_t cert_len, const uint8_t *key, size_t key_len, const uint8_t *staple, 420 size_t staple_len) 421 { 422 return tls_config_add_keypair_mem_internal(config, cert, cert_len, key, 423 key_len, staple, staple_len); 424 } 425 426 int 427 tls_config_add_keypair_ocsp_file(struct tls_config *config, 428 const char *cert_file, const char *key_file, const char *ocsp_file) 429 { 430 return tls_config_add_keypair_file_internal(config, cert_file, 431 key_file, ocsp_file); 432 } 433 434 int 435 tls_config_set_ca_file(struct tls_config *config, const char *ca_file) 436 { 437 return tls_config_load_file(&config->error, "CA", ca_file, 438 &config->ca_mem, &config->ca_len); 439 } 440 441 int 442 tls_config_set_ca_path(struct tls_config *config, const char *ca_path) 443 { 444 return tls_set_string(&config->ca_path, ca_path); 445 } 446 447 int 448 tls_config_set_ca_mem(struct tls_config *config, const uint8_t *ca, size_t len) 449 { 450 return tls_set_mem(&config->ca_mem, &config->ca_len, ca, len); 451 } 452 453 int 454 tls_config_set_cert_file(struct tls_config *config, const char *cert_file) 455 { 456 return tls_keypair_set_cert_file(config->keypair, &config->error, 457 cert_file); 458 } 459 460 int 461 tls_config_set_cert_mem(struct tls_config *config, const uint8_t *cert, 462 size_t len) 463 { 464 return tls_keypair_set_cert_mem(config->keypair, &config->error, 465 cert, len); 466 } 467 468 int 469 tls_config_set_ciphers(struct tls_config *config, const char *ciphers) 470 { 471 SSL_CTX *ssl_ctx = NULL; 472 473 if (ciphers == NULL || 474 strcasecmp(ciphers, "default") == 0 || 475 strcasecmp(ciphers, "secure") == 0) 476 ciphers = TLS_CIPHERS_DEFAULT; 477 else if (strcasecmp(ciphers, "compat") == 0) 478 ciphers = TLS_CIPHERS_COMPAT; 479 else if (strcasecmp(ciphers, "legacy") == 0) 480 ciphers = TLS_CIPHERS_LEGACY; 481 else if (strcasecmp(ciphers, "all") == 0 || 482 strcasecmp(ciphers, "insecure") == 0) 483 ciphers = TLS_CIPHERS_ALL; 484 485 if ((ssl_ctx = SSL_CTX_new(SSLv23_method())) == NULL) { 486 tls_config_set_errorx(config, "out of memory"); 487 goto err; 488 } 489 if (SSL_CTX_set_cipher_list(ssl_ctx, ciphers) != 1) { 490 tls_config_set_errorx(config, "no ciphers for '%s'", ciphers); 491 goto err; 492 } 493 494 SSL_CTX_free(ssl_ctx); 495 return tls_set_string(&config->ciphers, ciphers); 496 497 err: 498 SSL_CTX_free(ssl_ctx); 499 return -1; 500 } 501 502 int 503 tls_config_set_crl_file(struct tls_config *config, const char *crl_file) 504 { 505 return tls_config_load_file(&config->error, "CRL", crl_file, 506 &config->crl_mem, &config->crl_len); 507 } 508 509 int 510 tls_config_set_crl_mem(struct tls_config *config, const uint8_t *crl, 511 size_t len) 512 { 513 return tls_set_mem(&config->crl_mem, &config->crl_len, crl, len); 514 } 515 516 int 517 tls_config_set_dheparams(struct tls_config *config, const char *params) 518 { 519 int keylen; 520 521 if (params == NULL || strcasecmp(params, "none") == 0) 522 keylen = 0; 523 else if (strcasecmp(params, "auto") == 0) 524 keylen = -1; 525 else if (strcasecmp(params, "legacy") == 0) 526 keylen = 1024; 527 else { 528 tls_config_set_errorx(config, "invalid dhe param '%s'", params); 529 return (-1); 530 } 531 532 config->dheparams = keylen; 533 534 return (0); 535 } 536 537 int 538 tls_config_set_ecdhecurve(struct tls_config *config, const char *curve) 539 { 540 if (curve == NULL || 541 strcasecmp(curve, "none") == 0 || 542 strcasecmp(curve, "auto") == 0) { 543 curve = TLS_ECDHE_CURVES; 544 } else if (strchr(curve, ',') != NULL || strchr(curve, ':') != NULL) { 545 tls_config_set_errorx(config, "invalid ecdhe curve '%s'", 546 curve); 547 return (-1); 548 } 549 550 return tls_config_set_ecdhecurves(config, curve); 551 } 552 553 int 554 tls_config_set_ecdhecurves(struct tls_config *config, const char *curves) 555 { 556 int *curves_list = NULL, *curves_new; 557 size_t curves_num = 0; 558 char *cs = NULL; 559 char *p, *q; 560 int rv = -1; 561 int nid; 562 563 free(config->ecdhecurves); 564 config->ecdhecurves = NULL; 565 config->ecdhecurves_len = 0; 566 567 if (curves == NULL || strcasecmp(curves, "default") == 0) 568 curves = TLS_ECDHE_CURVES; 569 570 if ((cs = strdup(curves)) == NULL) { 571 tls_config_set_errorx(config, "out of memory"); 572 goto err; 573 } 574 575 q = cs; 576 while ((p = strsep(&q, ",:")) != NULL) { 577 while (*p == ' ' || *p == '\t') 578 p++; 579 580 nid = OBJ_sn2nid(p); 581 if (nid == NID_undef) 582 nid = OBJ_ln2nid(p); 583 if (nid == NID_undef) 584 nid = EC_curve_nist2nid(p); 585 if (nid == NID_undef) { 586 tls_config_set_errorx(config, 587 "invalid ecdhe curve '%s'", p); 588 goto err; 589 } 590 591 if ((curves_new = reallocarray(curves_list, curves_num + 1, 592 sizeof(int))) == NULL) { 593 tls_config_set_errorx(config, "out of memory"); 594 goto err; 595 } 596 curves_list = curves_new; 597 curves_list[curves_num] = nid; 598 curves_num++; 599 } 600 601 config->ecdhecurves = curves_list; 602 config->ecdhecurves_len = curves_num; 603 curves_list = NULL; 604 605 rv = 0; 606 607 err: 608 free(cs); 609 free(curves_list); 610 611 return (rv); 612 } 613 614 int 615 tls_config_set_key_file(struct tls_config *config, const char *key_file) 616 { 617 return tls_keypair_set_key_file(config->keypair, &config->error, 618 key_file); 619 } 620 621 int 622 tls_config_set_key_mem(struct tls_config *config, const uint8_t *key, 623 size_t len) 624 { 625 return tls_keypair_set_key_mem(config->keypair, &config->error, 626 key, len); 627 } 628 629 static int 630 tls_config_set_keypair_file_internal(struct tls_config *config, 631 const char *cert_file, const char *key_file, const char *ocsp_file) 632 { 633 if (tls_config_set_cert_file(config, cert_file) != 0) 634 return (-1); 635 if (tls_config_set_key_file(config, key_file) != 0) 636 return (-1); 637 if (ocsp_file != NULL && 638 tls_config_set_ocsp_staple_file(config, ocsp_file) != 0) 639 return (-1); 640 641 return (0); 642 } 643 644 static int 645 tls_config_set_keypair_mem_internal(struct tls_config *config, const uint8_t *cert, 646 size_t cert_len, const uint8_t *key, size_t key_len, 647 const uint8_t *staple, size_t staple_len) 648 { 649 if (tls_config_set_cert_mem(config, cert, cert_len) != 0) 650 return (-1); 651 if (tls_config_set_key_mem(config, key, key_len) != 0) 652 return (-1); 653 if ((staple != NULL) && 654 (tls_config_set_ocsp_staple_mem(config, staple, staple_len) != 0)) 655 return (-1); 656 657 return (0); 658 } 659 660 int 661 tls_config_set_keypair_file(struct tls_config *config, 662 const char *cert_file, const char *key_file) 663 { 664 return tls_config_set_keypair_file_internal(config, cert_file, key_file, 665 NULL); 666 } 667 668 int 669 tls_config_set_keypair_mem(struct tls_config *config, const uint8_t *cert, 670 size_t cert_len, const uint8_t *key, size_t key_len) 671 { 672 return tls_config_set_keypair_mem_internal(config, cert, cert_len, 673 key, key_len, NULL, 0); 674 } 675 676 int 677 tls_config_set_keypair_ocsp_file(struct tls_config *config, 678 const char *cert_file, const char *key_file, const char *ocsp_file) 679 { 680 return tls_config_set_keypair_file_internal(config, cert_file, key_file, 681 ocsp_file); 682 } 683 684 int 685 tls_config_set_keypair_ocsp_mem(struct tls_config *config, const uint8_t *cert, 686 size_t cert_len, const uint8_t *key, size_t key_len, 687 const uint8_t *staple, size_t staple_len) 688 { 689 return tls_config_set_keypair_mem_internal(config, cert, cert_len, 690 key, key_len, staple, staple_len); 691 } 692 693 694 int 695 tls_config_set_protocols(struct tls_config *config, uint32_t protocols) 696 { 697 config->protocols = protocols; 698 699 return (0); 700 } 701 702 int 703 tls_config_set_session_fd(struct tls_config *config, int session_fd) 704 { 705 struct stat sb; 706 mode_t mugo; 707 708 if (session_fd == -1) { 709 config->session_fd = session_fd; 710 return (0); 711 } 712 713 if (fstat(session_fd, &sb) == -1) { 714 tls_config_set_error(config, "failed to stat session file"); 715 return (-1); 716 } 717 if (!S_ISREG(sb.st_mode)) { 718 tls_config_set_errorx(config, 719 "session file is not a regular file"); 720 return (-1); 721 } 722 723 if (sb.st_uid != getuid()) { 724 tls_config_set_errorx(config, "session file has incorrect " 725 "owner (uid %i != %i)", sb.st_uid, getuid()); 726 return (-1); 727 } 728 mugo = sb.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO); 729 if (mugo != (S_IRUSR|S_IWUSR)) { 730 tls_config_set_errorx(config, "session file has incorrect " 731 "permissions (%o != 600)", mugo); 732 return (-1); 733 } 734 735 config->session_fd = session_fd; 736 737 return (0); 738 } 739 740 int 741 tls_config_set_verify_depth(struct tls_config *config, int verify_depth) 742 { 743 config->verify_depth = verify_depth; 744 745 return (0); 746 } 747 748 void 749 tls_config_prefer_ciphers_client(struct tls_config *config) 750 { 751 config->ciphers_server = 0; 752 } 753 754 void 755 tls_config_prefer_ciphers_server(struct tls_config *config) 756 { 757 config->ciphers_server = 1; 758 } 759 760 void 761 tls_config_insecure_noverifycert(struct tls_config *config) 762 { 763 config->verify_cert = 0; 764 } 765 766 void 767 tls_config_insecure_noverifyname(struct tls_config *config) 768 { 769 config->verify_name = 0; 770 } 771 772 void 773 tls_config_insecure_noverifytime(struct tls_config *config) 774 { 775 config->verify_time = 0; 776 } 777 778 void 779 tls_config_verify(struct tls_config *config) 780 { 781 config->verify_cert = 1; 782 config->verify_name = 1; 783 config->verify_time = 1; 784 } 785 786 void 787 tls_config_ocsp_require_stapling(struct tls_config *config) 788 { 789 config->ocsp_require_stapling = 1; 790 } 791 792 void 793 tls_config_verify_client(struct tls_config *config) 794 { 795 config->verify_client = 1; 796 } 797 798 void 799 tls_config_verify_client_optional(struct tls_config *config) 800 { 801 config->verify_client = 2; 802 } 803 804 void 805 tls_config_skip_private_key_check(struct tls_config *config) 806 { 807 config->skip_private_key_check = 1; 808 } 809 810 void 811 tls_config_use_fake_private_key(struct tls_config *config) 812 { 813 config->use_fake_private_key = 1; 814 } 815 816 int 817 tls_config_set_ocsp_staple_file(struct tls_config *config, const char *staple_file) 818 { 819 return tls_keypair_set_ocsp_staple_file(config->keypair, &config->error, 820 staple_file); 821 } 822 823 int 824 tls_config_set_ocsp_staple_mem(struct tls_config *config, const uint8_t *staple, 825 size_t len) 826 { 827 return tls_keypair_set_ocsp_staple_mem(config->keypair, &config->error, 828 staple, len); 829 } 830 831 int 832 tls_config_set_session_id(struct tls_config *config, 833 const unsigned char *session_id, size_t len) 834 { 835 if (len > TLS_MAX_SESSION_ID_LENGTH) { 836 tls_config_set_errorx(config, "session ID too large"); 837 return (-1); 838 } 839 memset(config->session_id, 0, sizeof(config->session_id)); 840 memcpy(config->session_id, session_id, len); 841 return (0); 842 } 843 844 int 845 tls_config_set_session_lifetime(struct tls_config *config, int lifetime) 846 { 847 if (lifetime > TLS_MAX_SESSION_TIMEOUT) { 848 tls_config_set_errorx(config, "session lifetime too large"); 849 return (-1); 850 } 851 if (lifetime != 0 && lifetime < TLS_MIN_SESSION_TIMEOUT) { 852 tls_config_set_errorx(config, "session lifetime too small"); 853 return (-1); 854 } 855 856 config->session_lifetime = lifetime; 857 return (0); 858 } 859 860 int 861 tls_config_add_ticket_key(struct tls_config *config, uint32_t keyrev, 862 unsigned char *key, size_t keylen) 863 { 864 struct tls_ticket_key newkey; 865 int i; 866 867 if (TLS_TICKET_KEY_SIZE != keylen || 868 sizeof(newkey.aes_key) + sizeof(newkey.hmac_key) > keylen) { 869 tls_config_set_errorx(config, 870 "wrong amount of ticket key data"); 871 return (-1); 872 } 873 874 keyrev = htonl(keyrev); 875 memset(&newkey, 0, sizeof(newkey)); 876 memcpy(newkey.key_name, &keyrev, sizeof(keyrev)); 877 memcpy(newkey.aes_key, key, sizeof(newkey.aes_key)); 878 memcpy(newkey.hmac_key, key + sizeof(newkey.aes_key), 879 sizeof(newkey.hmac_key)); 880 newkey.time = time(NULL); 881 882 for (i = 0; i < TLS_NUM_TICKETS; i++) { 883 struct tls_ticket_key *tk = &config->ticket_keys[i]; 884 if (memcmp(newkey.key_name, tk->key_name, 885 sizeof(tk->key_name)) != 0) 886 continue; 887 888 /* allow re-entry of most recent key */ 889 if (i == 0 && memcmp(newkey.aes_key, tk->aes_key, 890 sizeof(tk->aes_key)) == 0 && memcmp(newkey.hmac_key, 891 tk->hmac_key, sizeof(tk->hmac_key)) == 0) 892 return (0); 893 tls_config_set_errorx(config, "ticket key already present"); 894 return (-1); 895 } 896 897 memmove(&config->ticket_keys[1], &config->ticket_keys[0], 898 sizeof(config->ticket_keys) - sizeof(config->ticket_keys[0])); 899 config->ticket_keys[0] = newkey; 900 901 config->ticket_autorekey = 0; 902 903 return (0); 904 } 905 906 int 907 tls_config_ticket_autorekey(struct tls_config *config) 908 { 909 unsigned char key[TLS_TICKET_KEY_SIZE]; 910 int rv; 911 912 arc4random_buf(key, sizeof(key)); 913 rv = tls_config_add_ticket_key(config, config->ticket_keyrev++, key, 914 sizeof(key)); 915 config->ticket_autorekey = 1; 916 return (rv); 917 } 918