aboutsummaryrefslogtreecommitdiff
path: root/src/core/or/sendme.c
diff options
context:
space:
mode:
authorDavid Goulet <dgoulet@torproject.org>2019-05-07 09:16:39 -0400
committerNick Mathewson <nickm@torproject.org>2019-05-22 11:47:20 -0400
commit59b9eecc19877f38b2c9d8b4f7964c6e9875f4c0 (patch)
tree0d993ae7bbf40127fc9779053802df558ecb339d /src/core/or/sendme.c
parentd71fa707dd01bdaa2ed301e82ace6fd23f63e638 (diff)
downloadtor-59b9eecc19877f38b2c9d8b4f7964c6e9875f4c0.tar.gz
tor-59b9eecc19877f38b2c9d8b4f7964c6e9875f4c0.zip
sendme: Record cell digest on both client and exit
It turns out that only the exit side is validating the authenticated SENDME v1 logic and never the client side. Which means that if a client ever uploaded data towards an exit, the authenticated SENDME logic wouldn't apply. For this to work, we have to record the cell digest client side as well which introduced a new function that supports both type of edges. This also removes a test that is not valid anymore which was that we didn't allow cell recording on an origin circuit (client). Part of #30428 Signed-off-by: David Goulet <dgoulet@torproject.org>
Diffstat (limited to 'src/core/or/sendme.c')
-rw-r--r--src/core/or/sendme.c49
1 files changed, 35 insertions, 14 deletions
diff --git a/src/core/or/sendme.c b/src/core/or/sendme.c
index e7c65d99e2..586d4d0ae0 100644
--- a/src/core/or/sendme.c
+++ b/src/core/or/sendme.c
@@ -287,6 +287,21 @@ send_circuit_level_sendme(circuit_t *circ, crypt_path_t *layer_hint,
return 0;
}
+/* Record the cell digest only if the next cell is expected to be a SENDME. */
+static void
+record_cell_digest_on_circ(circuit_t *circ, const uint8_t *sendme_digest)
+{
+ tor_assert(circ);
+ tor_assert(sendme_digest);
+
+ /* Add the digest to the last seen list in the circuit. */
+ if (circ->sendme_last_digests == NULL) {
+ circ->sendme_last_digests = smartlist_new();
+ }
+ smartlist_add(circ->sendme_last_digests,
+ tor_memdup(sendme_digest, DIGEST_LEN));
+}
+
/*
* Public API
*/
@@ -571,31 +586,37 @@ sendme_note_stream_data_packaged(edge_connection_t *conn)
return --conn->package_window;
}
-/* Note the cell digest in the circuit sendme last digests FIFO if applicable.
- * It is safe to pass a circuit that isn't meant to track those digests. */
+/* Record the cell digest into the circuit sendme digest list depending on
+ * which edge we are. The digest is recorded only if we expect the next cell
+ * that we will receive is a SENDME so we can match the digest. */
void
-sendme_record_cell_digest(circuit_t *circ)
+sendme_record_cell_digest_on_circ(circuit_t *circ, crypt_path_t *cpath)
{
- const uint8_t *digest;
+ int package_window;
+ uint8_t *sendme_digest;
tor_assert(circ);
- /* We only keep the cell digest if we are the Exit on that circuit and if
- * this cell is the last one before the client should send a SENDME. */
- if (CIRCUIT_IS_ORIGIN(circ)) {
- return;
+ package_window = circ->package_window;
+ if (cpath) {
+ package_window = cpath->package_window;
}
+
/* Is this the last cell before a SENDME? The idea is that if the
* package_window reaches a multiple of the increment, after this cell, we
* should expect a SENDME. */
- if (!sendme_circuit_cell_is_next(circ->package_window)) {
+ if (!sendme_circuit_cell_is_next(package_window)) {
return;
}
- /* Add the digest to the last seen list in the circuit. */
- digest = relay_crypto_get_sendme_digest(&TO_OR_CIRCUIT(circ)->crypto);
- if (circ->sendme_last_digests == NULL) {
- circ->sendme_last_digests = smartlist_new();
+ /* Getting the digest is expensive so we only do it once we are certain to
+ * record it on the circuit. */
+ if (cpath) {
+ sendme_digest = cpath_get_sendme_digest(cpath);
+ } else {
+ sendme_digest =
+ relay_crypto_get_sendme_digest(&TO_OR_CIRCUIT(circ)->crypto);
}
- smartlist_add(circ->sendme_last_digests, tor_memdup(digest, DIGEST_LEN));
+
+ record_cell_digest_on_circ(circ, sendme_digest);
}