summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnder Juaristi <a@juaristi.eus>2018-01-02 00:00:50 +0100
committerAnder Juaristi <a@juaristi.eus>2018-01-02 00:00:50 +0100
commitdfd21da5bf5011b0e0cd6bc4e6deaafe3a6f51a8 (patch)
treee95ca67281431107b8f3a12728c16407adddccf6
parent2107cec1bb6fd8f6c4c6598436133c3dc92182b5 (diff)
downloadgnutls-tmp-draft-ietf-tls-tls13-21-ajuaristi-2.tar.gz
Move session ticket key to its own buffertmp-draft-ietf-tls-tls13-21-ajuaristi-2
Signed-off-by: Ander Juaristi <a@juaristi.eus>
-rw-r--r--lib/ext/session_ticket.c136
-rw-r--r--lib/gnutls_int.h12
-rw-r--r--lib/session.c1
3 files changed, 59 insertions, 90 deletions
diff --git a/lib/ext/session_ticket.c b/lib/ext/session_ticket.c
index 7e0a0b2f8d..279c8e252a 100644
--- a/lib/ext/session_ticket.c
+++ b/lib/ext/session_ticket.c
@@ -38,13 +38,10 @@
#ifdef ENABLE_SESSION_TICKETS
-#define KEY_NAME_SIZE 16
-#define CIPHER_KEY_SIZE 32
#define CIPHER GNUTLS_CIPHER_AES_256_CBC
#define IV_SIZE 16
#define BLOCK_SIZE 16
-#define MAC_SECRET_SIZE 16
#define MAC_ALGO GNUTLS_MAC_SHA1
#define MAC_SIZE 20 /* HMAC-SHA1 */
@@ -74,19 +71,13 @@ const hello_ext_entry_st ext_mod_session_ticket = {
.cannot_be_overriden = 1
};
-#define SESSION_KEY_SIZE (KEY_NAME_SIZE+CIPHER_KEY_SIZE+MAC_SECRET_SIZE)
#define NAME_POS (0)
#define KEY_POS (KEY_NAME_SIZE)
#define MAC_SECRET_POS (KEY_NAME_SIZE+CIPHER_KEY_SIZE)
typedef struct {
- int session_ticket_enable;
- int session_ticket_renew;
-
uint8_t *session_ticket;
int session_ticket_len;
-
- uint8_t key[SESSION_KEY_SIZE];
} session_ticket_ext_st;
struct ticket_st {
@@ -124,7 +115,7 @@ int digest_ticket(const gnutls_datum_t * key, struct ticket_st *ticket,
}
static int
-decrypt_ticket(gnutls_session_t session, session_ticket_ext_st * priv,
+decrypt_ticket(gnutls_session_t session,
struct ticket_st *ticket)
{
cipher_hd_st cipher_hd;
@@ -134,7 +125,7 @@ decrypt_ticket(gnutls_session_t session, session_ticket_ext_st * priv,
int ret;
/* Check the integrity of ticket */
- mac_secret.data = (void *) &priv->key[MAC_SECRET_POS];
+ mac_secret.data = (void *) &session->key.session_ticket_key[MAC_SECRET_POS];
mac_secret.size = MAC_SECRET_SIZE;
ret = digest_ticket(&mac_secret, ticket, cmac);
if (ret < 0)
@@ -147,7 +138,7 @@ decrypt_ticket(gnutls_session_t session, session_ticket_ext_st * priv,
return gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED);
/* Decrypt encrypted_state */
- key.data = (void *) &priv->key[KEY_POS];
+ key.data = (void *) &session->key.session_ticket_key[KEY_POS];
key.size = CIPHER_KEY_SIZE;
IV.data = ticket->IV;
IV.size = IV_SIZE;
@@ -202,7 +193,7 @@ cleanup:
}
static int
-encrypt_ticket(gnutls_session_t session, session_ticket_ext_st * priv,
+encrypt_ticket(gnutls_session_t session,
struct ticket_st *ticket)
{
cipher_hd_st cipher_hd;
@@ -230,7 +221,7 @@ encrypt_ticket(gnutls_session_t session, session_ticket_ext_st * priv,
memcpy(encrypted_state.data, state.data, state.size);
/* Encrypt state */
- key.data = (void *) &priv->key[KEY_POS];
+ key.data = (void *) &session->key.session_ticket_key[KEY_POS];
key.size = CIPHER_KEY_SIZE;
IV.data = iv;
IV.size = IV_SIZE;
@@ -261,12 +252,12 @@ encrypt_ticket(gnutls_session_t session, session_ticket_ext_st * priv,
/* Fill the ticket structure to compute MAC. */
- memcpy(ticket->key_name, &priv->key[NAME_POS], KEY_NAME_SIZE);
+ memcpy(ticket->key_name, &session->key.session_ticket_key[NAME_POS], KEY_NAME_SIZE);
memcpy(ticket->IV, IV.data, IV.size);
ticket->encrypted_state_len = encrypted_state.size;
ticket->encrypted_state = encrypted_state.data;
- mac_secret.data = &priv->key[MAC_SECRET_POS];
+ mac_secret.data = &session->key.session_ticket_key[MAC_SECRET_POS];
mac_secret.size = MAC_SECRET_SIZE;
ret = digest_ticket(&mac_secret, ticket, ticket->mac);
if (ret < 0) {
@@ -293,20 +284,9 @@ session_ticket_recv_params(gnutls_session_t session,
const uint8_t * data, size_t _data_size)
{
ssize_t data_size = _data_size;
- session_ticket_ext_st *priv = NULL;
- gnutls_ext_priv_data_t epriv;
int ret;
- ret =
- _gnutls_hello_ext_get_priv(session,
- GNUTLS_EXTENSION_SESSION_TICKET,
- &epriv);
- if (ret < 0) {
- return 0;
- }
- priv = epriv;
-
- if (!priv->session_ticket_enable)
+ if (!session->internals.session_ticket_enable)
return 0;
if (session->security_parameters.entity == GNUTLS_SERVER) {
@@ -315,7 +295,7 @@ session_ticket_recv_params(gnutls_session_t session,
/* The client requested a new session ticket. */
if (data_size == 0) {
- priv->session_ticket_renew = 1;
+ session->internals.session_ticket_renew = 1;
return 0;
}
@@ -333,9 +313,9 @@ session_ticket_recv_params(gnutls_session_t session,
/* If the key name of the ticket does not match the one that we
hold, issue a new ticket. */
if (memcmp
- (ticket.key_name, &priv->key[NAME_POS],
+ (ticket.key_name, &session->key.session_ticket_key[NAME_POS],
KEY_NAME_SIZE)) {
- priv->session_ticket_renew = 1;
+ session->internals.session_ticket_renew = 1;
return 0;
}
@@ -364,19 +344,19 @@ session_ticket_recv_params(gnutls_session_t session,
memcpy(ticket.encrypted_state, encrypted_state,
ticket.encrypted_state_len);
- ret = decrypt_ticket(session, priv, &ticket);
+ ret = decrypt_ticket(session, &ticket);
gnutls_free(ticket.encrypted_state);
ticket.encrypted_state = NULL;
if (ret < 0) {
- priv->session_ticket_renew = 1;
+ session->internals.session_ticket_renew = 1;
return 0;
}
} else { /* Client */
if (data_size == 0) {
- priv->session_ticket_renew = 1;
+ session->internals.session_ticket_renew = 1;
return 0;
}
}
@@ -402,11 +382,11 @@ session_ticket_send_params(gnutls_session_t session,
if (ret >= 0)
priv = epriv;
- if (priv == NULL || !priv->session_ticket_enable)
+ if (priv == NULL || !session->internals.session_ticket_enable)
return 0;
if (session->security_parameters.entity == GNUTLS_SERVER) {
- if (priv && priv->session_ticket_renew) {
+ if (priv && session->internals.session_ticket_renew) {
return GNUTLS_E_INT_RET_0;
}
} else {
@@ -422,7 +402,7 @@ session_ticket_send_params(gnutls_session_t session,
return GNUTLS_E_INT_RET_0;
/* previous data had session tickets disabled. Don't advertize. Ignore. */
- if (!priv->session_ticket_enable)
+ if (!session->internals.session_ticket_enable)
return 0;
if (priv->session_ticket_len > 0) {
@@ -458,7 +438,6 @@ session_ticket_pack(gnutls_ext_priv_data_t epriv, gnutls_buffer_st * ps)
BUFFER_APPEND_PFX4(ps, priv->session_ticket,
priv->session_ticket_len);
- BUFFER_APPEND_NUM(ps, priv->session_ticket_enable);
return 0;
}
@@ -480,7 +459,6 @@ session_ticket_unpack(gnutls_buffer_st * ps, gnutls_ext_priv_data_t * _priv)
BUFFER_POP_DATUM(ps, &ticket);
priv->session_ticket = ticket.data;
priv->session_ticket_len = ticket.size;
- BUFFER_POP_NUM(ps, priv->session_ticket_enable);
epriv = priv;
*_priv = epriv;
@@ -546,25 +524,12 @@ int gnutls_session_ticket_key_generate(gnutls_datum_t * key)
**/
int gnutls_session_ticket_enable_client(gnutls_session_t session)
{
- session_ticket_ext_st *priv = NULL;
- gnutls_ext_priv_data_t epriv;
-
if (!session) {
gnutls_assert();
return GNUTLS_E_INVALID_REQUEST;
}
- priv = gnutls_calloc(1, sizeof(*priv));
- if (priv == NULL) {
- gnutls_assert();
- return GNUTLS_E_MEMORY_ERROR;
- }
- priv->session_ticket_enable = 1;
- epriv = priv;
-
- _gnutls_hello_ext_set_priv(session,
- GNUTLS_EXTENSION_SESSION_TICKET,
- epriv);
+ session->internals.session_ticket_enable = 1;
return 0;
}
@@ -588,31 +553,20 @@ int
gnutls_session_ticket_enable_server(gnutls_session_t session,
const gnutls_datum_t * key)
{
- session_ticket_ext_st *priv = NULL;
- gnutls_ext_priv_data_t epriv;
-
if (!session || !key || key->size != SESSION_KEY_SIZE) {
gnutls_assert();
return GNUTLS_E_INVALID_REQUEST;
}
- priv = gnutls_calloc(1, sizeof(*priv));
- if (priv == NULL) {
- gnutls_assert();
- return GNUTLS_E_MEMORY_ERROR;
- }
- epriv = priv;
-
- memcpy(&priv->key, key->data, key->size);
- priv->session_ticket_enable = 1;
-
- _gnutls_hello_ext_set_priv(session,
- GNUTLS_EXTENSION_SESSION_TICKET,
- epriv);
+ memcpy(session->key.session_ticket_key, key->data, key->size);
+ session->internals.session_ticket_enable = 1;
return 0;
}
+/*
+ * Return zero if session tickets haven't been enabled.
+ */
int _gnutls_send_new_session_ticket(gnutls_session_t session, int again)
{
mbuffer_st *bufel = NULL;
@@ -621,20 +575,12 @@ int _gnutls_send_new_session_ticket(gnutls_session_t session, int again)
int ret;
struct ticket_st ticket;
uint16_t ticket_len;
- session_ticket_ext_st *priv = NULL;
- gnutls_ext_priv_data_t epriv;
uint16_t epoch_saved = session->security_parameters.epoch_write;
if (again == 0) {
- ret =
- _gnutls_hello_ext_get_priv(session,
- GNUTLS_EXTENSION_SESSION_TICKET,
- &epriv);
- if (ret < 0)
+ if (!session->internals.session_ticket_enable)
return 0;
- priv = epriv;
-
- if (!priv->session_ticket_renew)
+ if (!session->internals.session_ticket_renew)
return 0;
/* XXX: Temporarily set write algorithms to be used.
@@ -653,7 +599,7 @@ int _gnutls_send_new_session_ticket(gnutls_session_t session, int again)
session->security_parameters.epoch_write =
session->security_parameters.epoch_next;
- ret = encrypt_ticket(session, priv, &ticket);
+ ret = encrypt_ticket(session, &ticket);
session->security_parameters.epoch_write = epoch_saved;
if (ret < 0) {
gnutls_assert();
@@ -706,6 +652,9 @@ int _gnutls_send_new_session_ticket(gnutls_session_t session, int again)
GNUTLS_HANDSHAKE_NEW_SESSION_TICKET);
}
+/*
+ * Return zero if session ticets haven't been enabled.
+ */
int _gnutls_recv_new_session_ticket(gnutls_session_t session)
{
uint8_t *p;
@@ -716,17 +665,9 @@ int _gnutls_recv_new_session_ticket(gnutls_session_t session)
session_ticket_ext_st *priv = NULL;
gnutls_ext_priv_data_t epriv;
- ret =
- _gnutls_hello_ext_get_priv(session,
- GNUTLS_EXTENSION_SESSION_TICKET,
- &epriv);
- if (ret < 0) {
- gnutls_assert();
+ if (!session->internals.session_ticket_enable)
return 0;
- }
- priv = epriv;
-
- if (!priv->session_ticket_renew)
+ if (!session->internals.session_ticket_renew)
return 0;
/* This is the last flight and peer cannot be sure
@@ -764,6 +705,16 @@ int _gnutls_recv_new_session_ticket(gnutls_session_t session)
DECR_LENGTH_COM(data_size, ticket_len, ret =
GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
goto error);
+
+ ret =
+ _gnutls_hello_ext_get_priv(session,
+ GNUTLS_EXTENSION_SESSION_TICKET,
+ &epriv);
+ if (ret < 0) {
+ gnutls_assert();
+ return 0;
+ }
+ priv = epriv;
priv->session_ticket =
gnutls_realloc_fast(priv->session_ticket, ticket_len);
if (!priv->session_ticket) {
@@ -789,6 +740,11 @@ int _gnutls_recv_new_session_ticket(gnutls_session_t session)
}
ret = 0;
+ epriv = priv;
+ _gnutls_hello_ext_set_priv(session,
+ GNUTLS_EXTENSION_SESSION_TICKET,
+ epriv);
+
error:
_gnutls_buffer_clear(&buf);
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index f5ce5a2165..a45bb4db9f 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -497,6 +497,15 @@ struct gnutls_key_st {
/* TLS pre-master key; applies to 1.2 and 1.3 */
gnutls_datum_t key;
+#ifdef ENABLE_SESSION_TICKETS
+ /* The key to encrypt and decrypt session tickets */
+#define KEY_NAME_SIZE 16
+#define CIPHER_KEY_SIZE 32
+#define MAC_SECRET_SIZE 16
+#define SESSION_KEY_SIZE (KEY_NAME_SIZE+CIPHER_KEY_SIZE+MAC_SECRET_SIZE)
+ uint8_t session_ticket_key[SESSION_KEY_SIZE];
+#endif
+
/* this is used to hold the peers authentication data
*/
/* auth_info_t structures SHOULD NOT contain malloced
@@ -1271,6 +1280,9 @@ typedef struct {
/* the ciphersuite received in HRR */
uint8_t hrr_cs[2];
+ int session_ticket_enable;
+ int session_ticket_renew;
+
/* If you add anything here, check _gnutls_handshake_internal_state_clear().
*/
} internals_st;
diff --git a/lib/session.c b/lib/session.c
index 6c2671d70e..41018349ea 100644
--- a/lib/session.c
+++ b/lib/session.c
@@ -228,6 +228,7 @@ gnutls_session_set_data(gnutls_session_t session,
}
session->internals.resumption_requested = 1;
+ session->internals.session_ticket_enable = 1;
if (session->internals.resumption_data.data != NULL)
gnutls_free(session->internals.resumption_data.data);