diff options
author | Ander Juaristi <a@juaristi.eus> | 2018-01-02 00:00:50 +0100 |
---|---|---|
committer | Ander Juaristi <a@juaristi.eus> | 2018-01-02 00:00:50 +0100 |
commit | dfd21da5bf5011b0e0cd6bc4e6deaafe3a6f51a8 (patch) | |
tree | e95ca67281431107b8f3a12728c16407adddccf6 | |
parent | 2107cec1bb6fd8f6c4c6598436133c3dc92182b5 (diff) | |
download | gnutls-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.c | 136 | ||||
-rw-r--r-- | lib/gnutls_int.h | 12 | ||||
-rw-r--r-- | lib/session.c | 1 |
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); |