summaryrefslogtreecommitdiff
path: root/src/lib/libtls/tls_config.c
diff options
context:
space:
mode:
authorclaudio <>2017-01-24 01:48:05 +0000
committerclaudio <>2017-01-24 01:48:05 +0000
commitd78c389be49cfb5c1e450de1ffe9b19331871124 (patch)
treedf70a1321916b965fd5fe88a72940612ae3642f4 /src/lib/libtls/tls_config.c
parent2367558cf5d952b4f895457cfb15046d05a01529 (diff)
downloadopenbsd-d78c389be49cfb5c1e450de1ffe9b19331871124.tar.gz
openbsd-d78c389be49cfb5c1e450de1ffe9b19331871124.tar.bz2
openbsd-d78c389be49cfb5c1e450de1ffe9b19331871124.zip
Introduce ticket support. To enable them it is enough to set a positive
lifetime with tls_config_set_session_lifetime(). This enables tickets and uses an internal automatic rekeying mode for the ticket keys. If multiple processes are involved the following functions can be used to make tickets work accross all instances: - tls_config_set_session_id() sets the session identifier - tls_config_add_ticket_key() adds an encryption and authentication key For now only the last 4 keys added will be used (unless they are too old). If tls_config_add_ticket_key() is used the caller must ensure to add new keys regularly. It is best to do this 4 times per session lifetime (which is also the ticket key lifetime). Since tickets break PFS it is best to minimize the session lifetime according to needs. With a lot of help, input and OK beck@, jsing@
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}