mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-11 13:43:47 +01:00
prop289: Remember the last cell digest for v1 SENDMEs
In order to do so, depending on where the cell is going, we'll keep the last cell digest that is either received inbound or sent outbound. Then it can be used for validation. Part of #26288 Signed-off-by: David Goulet <dgoulet@torproject.org>
This commit is contained in:
parent
bb473a807a
commit
402f0a4f5d
@ -142,6 +142,13 @@ relay_decrypt_cell(circuit_t *circ, cell_t *cell,
|
|||||||
if (relay_digest_matches(thishop->crypto.b_digest, cell)) {
|
if (relay_digest_matches(thishop->crypto.b_digest, cell)) {
|
||||||
*recognized = 1;
|
*recognized = 1;
|
||||||
*layer_hint = thishop;
|
*layer_hint = thishop;
|
||||||
|
/* Keep current digest of this cell for the possible SENDME. */
|
||||||
|
if (thishop->crypto.sendme_digest) {
|
||||||
|
crypto_digest_free(thishop->crypto.sendme_digest);
|
||||||
|
}
|
||||||
|
thishop->crypto.sendme_digest =
|
||||||
|
crypto_digest_dup(thishop->crypto.b_digest);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -212,6 +219,11 @@ relay_encrypt_cell_inbound(cell_t *cell,
|
|||||||
or_circuit_t *or_circ)
|
or_circuit_t *or_circ)
|
||||||
{
|
{
|
||||||
relay_set_digest(or_circ->crypto.b_digest, cell);
|
relay_set_digest(or_circ->crypto.b_digest, cell);
|
||||||
|
/* Keep a record of this cell, we might use it for validating the SENDME. */
|
||||||
|
if (or_circ->crypto.sendme_digest) {
|
||||||
|
crypto_digest_free(or_circ->crypto.sendme_digest);
|
||||||
|
}
|
||||||
|
or_circ->crypto.sendme_digest = crypto_digest_dup(or_circ->crypto.b_digest);
|
||||||
/* encrypt one layer */
|
/* encrypt one layer */
|
||||||
relay_crypt_one_payload(or_circ->crypto.b_crypto, cell->payload);
|
relay_crypt_one_payload(or_circ->crypto.b_crypto, cell->payload);
|
||||||
}
|
}
|
||||||
@ -229,6 +241,7 @@ relay_crypto_clear(relay_crypto_t *crypto)
|
|||||||
crypto_cipher_free(crypto->b_crypto);
|
crypto_cipher_free(crypto->b_crypto);
|
||||||
crypto_digest_free(crypto->f_digest);
|
crypto_digest_free(crypto->f_digest);
|
||||||
crypto_digest_free(crypto->b_digest);
|
crypto_digest_free(crypto->b_digest);
|
||||||
|
crypto_digest_free(crypto->sendme_digest);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Initialize <b>crypto</b> from the key material in key_data.
|
/** Initialize <b>crypto</b> from the key material in key_data.
|
||||||
|
@ -1568,7 +1568,7 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Consider sending a circuit-level SENDME cell. */
|
/* Consider sending a circuit-level SENDME cell. */
|
||||||
sendme_circuit_consider_sending(circ, layer_hint, NULL);
|
sendme_circuit_consider_sending(circ, layer_hint);
|
||||||
|
|
||||||
if (rh.stream_id == 0) {
|
if (rh.stream_id == 0) {
|
||||||
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, "Relay data cell with zero "
|
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, "Relay data cell with zero "
|
||||||
|
@ -25,6 +25,8 @@ struct relay_crypto_t {
|
|||||||
/** Digest state for cells heading away from the OR at this step. */
|
/** Digest state for cells heading away from the OR at this step. */
|
||||||
struct crypto_digest_t *b_digest;
|
struct crypto_digest_t *b_digest;
|
||||||
|
|
||||||
|
/** Digest used for the next SENDME cell if any. */
|
||||||
|
struct crypto_digest_t *sendme_digest;
|
||||||
};
|
};
|
||||||
#undef crypto_cipher_t
|
#undef crypto_cipher_t
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include "core/or/cell_st.h"
|
#include "core/or/cell_st.h"
|
||||||
#include "core/or/circuitlist.h"
|
#include "core/or/circuitlist.h"
|
||||||
#include "core/or/circuituse.h"
|
#include "core/or/circuituse.h"
|
||||||
|
#include "core/or/or_circuit_st.h"
|
||||||
#include "core/or/relay.h"
|
#include "core/or/relay.h"
|
||||||
#include "core/or/sendme.h"
|
#include "core/or/sendme.h"
|
||||||
#include "feature/nodelist/networkstatus.h"
|
#include "feature/nodelist/networkstatus.h"
|
||||||
@ -342,18 +343,20 @@ sendme_connection_edge_consider_sending(edge_connection_t *conn)
|
|||||||
* more.
|
* more.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
sendme_circuit_consider_sending(circuit_t *circ, crypt_path_t *layer_hint,
|
sendme_circuit_consider_sending(circuit_t *circ, crypt_path_t *layer_hint)
|
||||||
crypto_digest_t *digest)
|
|
||||||
{
|
{
|
||||||
tor_assert(digest);
|
crypto_digest_t *digest;
|
||||||
|
|
||||||
while ((layer_hint ? layer_hint->deliver_window : circ->deliver_window) <=
|
while ((layer_hint ? layer_hint->deliver_window : circ->deliver_window) <=
|
||||||
CIRCWINDOW_START - CIRCWINDOW_INCREMENT) {
|
CIRCWINDOW_START - CIRCWINDOW_INCREMENT) {
|
||||||
log_debug(LD_CIRC,"Queuing circuit sendme.");
|
log_debug(LD_CIRC,"Queuing circuit sendme.");
|
||||||
if (layer_hint)
|
if (layer_hint) {
|
||||||
layer_hint->deliver_window += CIRCWINDOW_INCREMENT;
|
layer_hint->deliver_window += CIRCWINDOW_INCREMENT;
|
||||||
else
|
digest = layer_hint->crypto.sendme_digest;
|
||||||
|
} else {
|
||||||
circ->deliver_window += CIRCWINDOW_INCREMENT;
|
circ->deliver_window += CIRCWINDOW_INCREMENT;
|
||||||
|
digest = TO_OR_CIRCUIT(circ)->crypto.sendme_digest;
|
||||||
|
}
|
||||||
if (send_circuit_level_sendme(circ, layer_hint, digest) < 0) {
|
if (send_circuit_level_sendme(circ, layer_hint, digest) < 0) {
|
||||||
return; /* The circuit's closed, don't continue */
|
return; /* The circuit's closed, don't continue */
|
||||||
}
|
}
|
||||||
@ -557,9 +560,16 @@ sendme_note_cell_digest(circuit_t *circ)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Only note the digest if we actually have the digest of the previous cell
|
||||||
|
* recorded. It should never happen in theory as we always record the last
|
||||||
|
* digest for the v1 SENDME. */
|
||||||
|
if (TO_OR_CIRCUIT(circ)->crypto.sendme_digest) {
|
||||||
digest = tor_malloc_zero(4);
|
digest = tor_malloc_zero(4);
|
||||||
|
crypto_digest_get_digest(TO_OR_CIRCUIT(circ)->crypto.sendme_digest,
|
||||||
|
(char *) digest, 4);
|
||||||
if (circ->sendme_last_digests == NULL) {
|
if (circ->sendme_last_digests == NULL) {
|
||||||
circ->sendme_last_digests = smartlist_new();
|
circ->sendme_last_digests = smartlist_new();
|
||||||
}
|
}
|
||||||
smartlist_add(circ->sendme_last_digests, digest);
|
smartlist_add(circ->sendme_last_digests, digest);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -16,8 +16,7 @@
|
|||||||
/* Sending SENDME cell. */
|
/* Sending SENDME cell. */
|
||||||
void sendme_connection_edge_consider_sending(edge_connection_t *edge_conn);
|
void sendme_connection_edge_consider_sending(edge_connection_t *edge_conn);
|
||||||
void sendme_circuit_consider_sending(circuit_t *circ,
|
void sendme_circuit_consider_sending(circuit_t *circ,
|
||||||
crypt_path_t *layer_hint,
|
crypt_path_t *layer_hint);
|
||||||
crypto_digest_t *digest);
|
|
||||||
|
|
||||||
/* Processing SENDME cell. */
|
/* Processing SENDME cell. */
|
||||||
int sendme_process_circuit_level(crypt_path_t *layer_hint,
|
int sendme_process_circuit_level(crypt_path_t *layer_hint,
|
||||||
|
Loading…
Reference in New Issue
Block a user