summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnder Juaristi <a@juaristi.eus>2018-04-19 16:42:58 +0200
committerAnder Juaristi <a@juaristi.eus>2018-04-19 16:42:58 +0200
commitab4e78b6a471bdc2cf9f7360ed7145dd043725c5 (patch)
tree45cf86cc95f55e144e39dc9bdedad3c745fd6a3d
parent9153d76d5ef0ca00371daa8cb618ce33cb047b50 (diff)
downloadgnutls-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.c81
-rw-r--r--lib/gnutls_int.h9
-rw-r--r--lib/tls13/session_ticket.c14
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;
}