diff options
author | Ander Juaristi <a@juaristi.eus> | 2018-04-19 16:42:58 +0200 |
---|---|---|
committer | Ander Juaristi <a@juaristi.eus> | 2018-04-19 16:42:58 +0200 |
commit | ab4e78b6a471bdc2cf9f7360ed7145dd043725c5 (patch) | |
tree | 45cf86cc95f55e144e39dc9bdedad3c745fd6a3d | |
parent | 9153d76d5ef0ca00371daa8cb618ce33cb047b50 (diff) | |
download | gnutls-tmp-draft-ietf-tls-tls13-21-ajuaristi-session-resumption-3.tar.gz |
TLS 1.3: session resumption: abstract away access to STEKtmp-draft-ietf-tls-tls13-21-ajuaristi-session-resumption-3
This commit introduces the new function
_gnutls_get_session_ticket_key(), so that the session ticket keys need
not be accessed directly from session->internals now.
This should fix #340.
Signed-off-by: Ander Juaristi <a@juaristi.eus>
-rw-r--r-- | lib/ext/session_ticket.c | 81 | ||||
-rw-r--r-- | lib/gnutls_int.h | 9 | ||||
-rw-r--r-- | lib/tls13/session_ticket.c | 14 |
3 files changed, 83 insertions, 21 deletions
diff --git a/lib/ext/session_ticket.c b/lib/ext/session_ticket.c index 6c08f9cb3e..34ecb59541 100644 --- a/lib/ext/session_ticket.c +++ b/lib/ext/session_ticket.c @@ -76,6 +76,36 @@ typedef struct { int session_ticket_len; } session_ticket_ext_st; +int _gnutls_get_session_ticket_key(gnutls_session_t session, + gnutls_session_ticket_key_type_t type, + gnutls_datum_t *key) +{ + int ret = 0; + + if (unlikely(key == NULL)) + return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; + + switch (type) { + case STEK_NAME: + key->size = KEY_NAME_SIZE; + key->data = &session->key.session_ticket_key[NAME_POS]; + break; + case STEK_KEY: + key->size = CIPHER_KEY_SIZE; + key->data = &session->key.session_ticket_key[KEY_POS]; + break; + case STEK_MAC_KEY: + key->size = MAC_SECRET_SIZE; + key->data = &session->key.session_ticket_key[MAC_SECRET_POS]; + break; + default: + ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; + break; + } + + return ret; +} + static int unpack_ticket(gnutls_session_t session, const gnutls_datum_t *state) { @@ -141,8 +171,9 @@ _gnutls_decrypt_session_ticket(gnutls_session_t session, int ret; /* Check the integrity of ticket */ - mac_secret.data = (void *) &session->key.session_ticket_key[MAC_SECRET_POS]; - mac_secret.size = MAC_SECRET_SIZE; + if ((ret = _gnutls_get_session_ticket_key(session, STEK_MAC_KEY, &mac_secret)) < 0) + return gnutls_assert_val(ret); + ret = digest_ticket(&mac_secret, ticket, cmac); if (ret < 0) return gnutls_assert_val(ret); @@ -154,8 +185,9 @@ _gnutls_decrypt_session_ticket(gnutls_session_t session, return gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED); /* Decrypt encrypted_state */ - key.data = (void *) &session->key.session_ticket_key[KEY_POS]; - key.size = CIPHER_KEY_SIZE; + if ((ret = _gnutls_get_session_ticket_key(session, STEK_KEY, &key)) < 0) + return gnutls_assert_val(ret); + IV.data = ticket->IV; IV.size = IV_SIZE; ret = @@ -189,7 +221,7 @@ int _gnutls_encrypt_session_ticket(gnutls_session_t session, struct ticket_st *ticket, gnutls_datum_t *state) { cipher_hd_st cipher_hd; - gnutls_datum_t key, IV; + gnutls_datum_t key, IV, key_name; gnutls_datum_t encrypted_state = {NULL,0}; uint8_t iv[IV_SIZE]; gnutls_datum_t mac_secret; @@ -206,8 +238,11 @@ _gnutls_encrypt_session_ticket(gnutls_session_t session, struct ticket_st *ticke memcpy(encrypted_state.data, state->data, state->size); /* Encrypt state */ - key.data = (void *) &session->key.session_ticket_key[KEY_POS]; - key.size = CIPHER_KEY_SIZE; + if ((ret = _gnutls_get_session_ticket_key(session, STEK_KEY, &key)) < 0) { + gnutls_assert(); + goto cleanup; + } + IV.data = iv; IV.size = IV_SIZE; @@ -237,13 +272,20 @@ _gnutls_encrypt_session_ticket(gnutls_session_t session, struct ticket_st *ticke /* Fill the ticket structure to compute MAC. */ - memcpy(ticket->key_name, &session->key.session_ticket_key[NAME_POS], KEY_NAME_SIZE); + if ((ret = _gnutls_get_session_ticket_key(session, STEK_NAME, &key_name)) < 0) { + gnutls_assert(); + goto cleanup; + } + if ((ret = _gnutls_get_session_ticket_key(session, STEK_MAC_KEY, &mac_secret)) < 0) { + gnutls_assert(); + goto cleanup; + } + + memcpy(ticket->key_name, key_name.data, 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 = &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) { gnutls_assert(); @@ -267,7 +309,7 @@ static int session_ticket_recv_params(gnutls_session_t session, const uint8_t * data, size_t _data_size) { - gnutls_datum_t state; + gnutls_datum_t state, key_name; ssize_t data_size = _data_size; int ret; @@ -284,6 +326,13 @@ session_ticket_recv_params(gnutls_session_t session, return 0; } + /* + * If session_ticket_enable == 1, but we're not able to get the session key, + * then something goes very wrong. + */ + if (_gnutls_get_session_ticket_key(session, STEK_NAME, &key_name) < 0) + return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); + /* Format: * Key name * IV @@ -291,15 +340,15 @@ session_ticket_recv_params(gnutls_session_t session, * encrypted data * MAC */ - DECR_LEN(data_size, KEY_NAME_SIZE); - memcpy(ticket.key_name, data, KEY_NAME_SIZE); - data += KEY_NAME_SIZE; + DECR_LEN(data_size, key_name.size); + memcpy(ticket.key_name, data, key_name.size); + data += key_name.size; /* If the key name of the ticket does not match the one that we hold, issue a new ticket. */ if (memcmp - (ticket.key_name, &session->key.session_ticket_key[NAME_POS], - KEY_NAME_SIZE)) { + (ticket.key_name, key_name.data, + key_name.size)) { session->internals.session_ticket_renew = 1; return 0; } diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index 2151a1fb40..095caead88 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -1364,6 +1364,11 @@ struct gnutls_session_int { gnutls_key_st key; }; +typedef enum { + STEK_NAME, + STEK_KEY, + STEK_MAC_KEY, +} gnutls_session_ticket_key_type_t; /* functions */ @@ -1430,4 +1435,8 @@ inline static size_t max_user_send_size(gnutls_session_t session, return max; } +int _gnutls_get_session_ticket_key(gnutls_session_t session, + gnutls_session_ticket_key_type_t type, + gnutls_datum_t *key); + #endif /* GNUTLS_INT_H */ diff --git a/lib/tls13/session_ticket.c b/lib/tls13/session_ticket.c index 1a5522f90b..f3a304658d 100644 --- a/lib/tls13/session_ticket.c +++ b/lib/tls13/session_ticket.c @@ -380,6 +380,7 @@ int _gnutls13_unpack_session_ticket(gnutls_session_t session, const unsigned char *p; ssize_t data_size; struct ticket_st ticket; + gnutls_datum_t key_name; gnutls_datum_t decrypted = { NULL, 0 }; if (unlikely(data == NULL || ticket_data == NULL)) @@ -393,6 +394,9 @@ int _gnutls13_unpack_session_ticket(gnutls_session_t session, memset(&ticket, 0, sizeof(struct ticket_st)); + if ((ret = _gnutls_get_session_ticket_key(session, STEK_NAME, &key_name)) < 0) + return gnutls_assert_val(ret); + /* Parse the ticket fields. * Format: * Key name @@ -401,13 +405,13 @@ int _gnutls13_unpack_session_ticket(gnutls_session_t session, * encrypted data * MAC */ - DECR_LEN(data_size, KEY_NAME_SIZE); - memcpy(ticket.key_name, p, KEY_NAME_SIZE); - p += KEY_NAME_SIZE; + DECR_LEN(data_size, key_name.size); + memcpy(ticket.key_name, p, key_name.size); + p += key_name.size; if (memcmp(ticket.key_name, - &session->key.session_ticket_key[NAME_POS], - KEY_NAME_SIZE)) { + key_name.data, + key_name.size)) { session->internals.session_ticket_renew = 1; return 0; } |