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 | } | ||