Added function to forget saved session parameters (for tests).

This commit is contained in:
Thomas Pornin 2017-07-26 15:52:38 +02:00
parent 127fb4a31d
commit 5414fd525e
2 changed files with 61 additions and 2 deletions

View File

@ -3220,6 +3220,19 @@ typedef struct {
void br_ssl_session_cache_lru_init(br_ssl_session_cache_lru *cc,
unsigned char *store, size_t store_len);
/**
* \brief Forget an entry in an LRU session cache.
*
* The session cache context must have been initialised. The entry
* with the provided session ID (of exactly 32 bytes) is looked for
* in the cache; if located, it is disabled.
*
* \param cc session cache context.
* \param id session ID to forget.
*/
void br_ssl_session_cache_lru_forget(
br_ssl_session_cache_lru *cc, const unsigned char *id);
/**
* \brief Context structure for a SSL server.
*

View File

@ -54,6 +54,10 @@
* tree left child 4 bytes (big endian)
* tree right child 4 bytes (big endian)
*
* If an entry has a protocol version set to 0, then it is "disabled":
* it was a session pushed to the cache at some point, but it has
* been explicitly removed.
*
* We need to keep the tree balanced because an attacker could make
* handshakes, selecting some specific sessions (by reusing them) to
* try to make us make an imbalanced tree that makes lookups expensive
@ -437,8 +441,18 @@ lru_load(const br_ssl_session_cache_class **ctx,
mask_id(cc, params->session_id, id);
x = find_node(cc, id, NULL);
if (x != ADDR_NULL) {
params->version = br_dec16be(
cc->store + x + VERSION_OFF);
unsigned version;
version = br_dec16be(cc->store + x + VERSION_OFF);
if (version == 0) {
/*
* Entry is disabled, we pretend we did not find it.
* Notably, we don't move it to the front of the
* LRU list.
*/
return 0;
}
params->version = version;
params->cipher_suite = br_dec16be(
cc->store + x + CIPHER_SUITE_OFF);
memcpy(params->master_secret,
@ -489,3 +503,35 @@ br_ssl_session_cache_lru_init(br_ssl_session_cache_lru *cc,
cc->tail = ADDR_NULL;
cc->root = ADDR_NULL;
}
/* see bearssl_ssl.h */
void br_ssl_session_cache_lru_forget(
br_ssl_session_cache_lru *cc, const unsigned char *id)
{
unsigned char mid[SESSION_ID_LEN];
uint32_t addr;
/*
* If the cache is not initialised yet, then it is empty, and
* there is nothing to forget.
*/
if (!cc->init_done) {
return;
}
/*
* Look for the node in the tree. If found, the entry is marked
* as "disabled"; it will be reused in due course, as it ages
* through the list.
*
* We do not go through the complex moves of actually releasing
* the entry right away because explicitly forgetting sessions
* should be a rare event, meant mostly for testing purposes,
* so this is not worth the extra code size.
*/
mask_id(cc, id, mid);
addr = find_node(cc, id, NULL);
if (addr != ADDR_NULL) {
br_enc16be(cc->store + addr + VERSION_OFF, 0);
}
}