summaryrefslogtreecommitdiff
path: root/src/lib/libtls/tls_config.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libtls/tls_config.c')
-rw-r--r--src/lib/libtls/tls_config.c102
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 *
177tls_config_new(void) 177tls_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
677int
678tls_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
690int
691tls_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
706int
707tls_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
752int
753tls_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}