diff options
Diffstat (limited to 'src/lib/libtls/tls_config.c')
| -rw-r--r-- | src/lib/libtls/tls_config.c | 102 |
1 files changed, 101 insertions, 1 deletions
diff --git a/src/lib/libtls/tls_config.c b/src/lib/libtls/tls_config.c index 5bc671fc99..8fa810461c 100644 --- a/src/lib/libtls/tls_config.c +++ b/src/lib/libtls/tls_config.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: tls_config.c,v 1.33 2016/11/11 14:02:24 jsing Exp $ */ | 1 | /* $OpenBSD: tls_config.c,v 1.34 2017/01/24 01:48:05 claudio Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> |
| 4 | * | 4 | * |
| @@ -177,6 +177,7 @@ struct tls_config * | |||
| 177 | tls_config_new(void) | 177 | tls_config_new(void) |
| 178 | { | 178 | { |
| 179 | struct tls_config *config; | 179 | struct tls_config *config; |
| 180 | unsigned char sid[TLS_MAX_SESSION_ID_LENGTH]; | ||
| 180 | 181 | ||
| 181 | if ((config = calloc(1, sizeof(*config))) == NULL) | 182 | if ((config = calloc(1, sizeof(*config))) == NULL) |
| 182 | return (NULL); | 183 | return (NULL); |
| @@ -199,6 +200,17 @@ tls_config_new(void) | |||
| 199 | if (tls_config_set_verify_depth(config, 6) != 0) | 200 | if (tls_config_set_verify_depth(config, 6) != 0) |
| 200 | goto err; | 201 | goto err; |
| 201 | 202 | ||
| 203 | /* | ||
| 204 | * Set session ID context to a random value. For the simple case | ||
| 205 | * of a single process server this is good enough. For multiprocess | ||
| 206 | * servers the session ID needs to be set by the caller. | ||
| 207 | */ | ||
| 208 | arc4random_buf(sid, sizeof(sid)); | ||
| 209 | if (tls_config_set_session_id(config, sid, sizeof(sid)) != 0) | ||
| 210 | goto err; | ||
| 211 | config->ticket_keyrev = arc4random(); | ||
| 212 | config->ticket_autorekey = 1; | ||
| 213 | |||
| 202 | tls_config_prefer_ciphers_server(config); | 214 | tls_config_prefer_ciphers_server(config); |
| 203 | 215 | ||
| 204 | tls_config_verify(config); | 216 | tls_config_verify(config); |
| @@ -661,3 +673,91 @@ tls_config_set_ocsp_staple_mem(struct tls_config *config, char *staple, size_t l | |||
| 661 | { | 673 | { |
| 662 | return set_mem(&config->ocsp_staple, &config->ocsp_staple_len, staple, len); | 674 | return set_mem(&config->ocsp_staple, &config->ocsp_staple_len, staple, len); |
| 663 | } | 675 | } |
| 676 | |||
| 677 | int | ||
| 678 | tls_config_set_session_id(struct tls_config *config, | ||
| 679 | const unsigned char *session_id, size_t len) | ||
| 680 | { | ||
| 681 | if (len > TLS_MAX_SESSION_ID_LENGTH) { | ||
| 682 | tls_config_set_errorx(config, "session ID too large"); | ||
| 683 | return (-1); | ||
| 684 | } | ||
| 685 | memset(config->session_id, 0, sizeof(config->session_id)); | ||
| 686 | memcpy(config->session_id, session_id, len); | ||
| 687 | return (0); | ||
| 688 | } | ||
| 689 | |||
| 690 | int | ||
| 691 | tls_config_set_session_lifetime(struct tls_config *config, int lifetime) | ||
| 692 | { | ||
| 693 | if (lifetime > TLS_MAX_SESSION_TIMEOUT) { | ||
| 694 | tls_config_set_errorx(config, "session lifetime too large"); | ||
| 695 | return (-1); | ||
| 696 | } | ||
| 697 | if (lifetime != 0 && lifetime < TLS_MIN_SESSION_TIMEOUT) { | ||
| 698 | tls_config_set_errorx(config, "session lifetime too small"); | ||
| 699 | return (-1); | ||
| 700 | } | ||
| 701 | |||
| 702 | config->session_lifetime = lifetime; | ||
| 703 | return (0); | ||
| 704 | } | ||
| 705 | |||
| 706 | int | ||
| 707 | tls_config_add_ticket_key(struct tls_config *config, uint32_t keyrev, | ||
| 708 | unsigned char *key, size_t keylen) | ||
| 709 | { | ||
| 710 | struct tls_ticket_key newkey; | ||
| 711 | int i; | ||
| 712 | |||
| 713 | if (TLS_TICKET_KEY_SIZE != keylen || | ||
| 714 | sizeof(newkey.aes_key) + sizeof(newkey.hmac_key) > keylen) { | ||
| 715 | tls_config_set_errorx(config, | ||
| 716 | "wrong amount of ticket key data"); | ||
| 717 | return (-1); | ||
| 718 | } | ||
| 719 | |||
| 720 | keyrev = htonl(keyrev); | ||
| 721 | memset(&newkey, 0, sizeof(newkey)); | ||
| 722 | memcpy(newkey.key_name, &keyrev, sizeof(keyrev)); | ||
| 723 | memcpy(newkey.aes_key, key, sizeof(newkey.aes_key)); | ||
| 724 | memcpy(newkey.hmac_key, key + sizeof(newkey.aes_key), | ||
| 725 | sizeof(newkey.hmac_key)); | ||
| 726 | newkey.time = time(NULL); | ||
| 727 | |||
| 728 | for (i = 0; i < TLS_NUM_TICKETS; i++) { | ||
| 729 | struct tls_ticket_key *tk = &config->ticket_keys[i]; | ||
| 730 | if (memcmp(newkey.key_name, tk->key_name, | ||
| 731 | sizeof(tk->key_name)) != 0) | ||
| 732 | continue; | ||
| 733 | |||
| 734 | /* allow re-entry of most recent key */ | ||
| 735 | if (i == 0 && memcmp(newkey.aes_key, tk->aes_key, | ||
| 736 | sizeof(tk->aes_key)) == 0 && memcmp(newkey.hmac_key, | ||
| 737 | tk->hmac_key, sizeof(tk->hmac_key)) == 0) | ||
| 738 | return (0); | ||
| 739 | tls_config_set_errorx(config, "ticket key already present"); | ||
| 740 | return (-1); | ||
| 741 | } | ||
| 742 | |||
| 743 | memmove(&config->ticket_keys[1], &config->ticket_keys[0], | ||
| 744 | sizeof(config->ticket_keys) - sizeof(config->ticket_keys[0])); | ||
| 745 | config->ticket_keys[0] = newkey; | ||
| 746 | |||
| 747 | config->ticket_autorekey = 0; | ||
| 748 | |||
| 749 | return (0); | ||
| 750 | } | ||
| 751 | |||
| 752 | int | ||
| 753 | tls_config_ticket_autorekey(struct tls_config *config) | ||
| 754 | { | ||
| 755 | unsigned char key[TLS_TICKET_KEY_SIZE]; | ||
| 756 | int rv; | ||
| 757 | |||
| 758 | arc4random_buf(key, sizeof(key)); | ||
| 759 | rv = tls_config_add_ticket_key(config, config->ticket_keyrev++, key, | ||
| 760 | sizeof(key)); | ||
| 761 | config->ticket_autorekey = 1; | ||
| 762 | return (rv); | ||
| 763 | } | ||
