summaryrefslogtreecommitdiff
path: root/lib/ext/session_ticket.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ext/session_ticket.c')
-rw-r--r--lib/ext/session_ticket.c81
1 files changed, 65 insertions, 16 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;
}