diff options
Diffstat (limited to 'lib/ext/session_ticket.c')
-rw-r--r-- | lib/ext/session_ticket.c | 81 |
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; } |