[tor-commits] [tor/master] prop289: Remember the last cell digest for v1 SENDMEs

asn at torproject.org asn at torproject.org
Thu May 2 15:16:20 UTC 2019


commit 402f0a4f5d70bee128130f4dbd0ea18de1747410
Author: David Goulet <dgoulet at torproject.org>
Date:   Wed Jan 23 14:39:04 2019 -0500

    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 at torproject.org>
---
 src/core/crypto/relay_crypto.c | 13 +++++++++++++
 src/core/or/relay.c            |  2 +-
 src/core/or/relay_crypto_st.h  |  2 ++
 src/core/or/sendme.c           | 28 +++++++++++++++++++---------
 src/core/or/sendme.h           |  3 +--
 5 files changed, 36 insertions(+), 12 deletions(-)

diff --git a/src/core/crypto/relay_crypto.c b/src/core/crypto/relay_crypto.c
index 0b83b2d0a..d4116d47a 100644
--- a/src/core/crypto/relay_crypto.c
+++ b/src/core/crypto/relay_crypto.c
@@ -142,6 +142,13 @@ relay_decrypt_cell(circuit_t *circ, cell_t *cell,
           if (relay_digest_matches(thishop->crypto.b_digest, cell)) {
             *recognized = 1;
             *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;
           }
         }
@@ -212,6 +219,11 @@ relay_encrypt_cell_inbound(cell_t *cell,
                            or_circuit_t *or_circ)
 {
   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 */
   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_digest_free(crypto->f_digest);
   crypto_digest_free(crypto->b_digest);
+  crypto_digest_free(crypto->sendme_digest);
 }
 
 /** Initialize <b>crypto</b> from the key material in key_data.
diff --git a/src/core/or/relay.c b/src/core/or/relay.c
index b26360b24..47275a811 100644
--- a/src/core/or/relay.c
+++ b/src/core/or/relay.c
@@ -1568,7 +1568,7 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
       }
 
       /* 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) {
         log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, "Relay data cell with zero "
diff --git a/src/core/or/relay_crypto_st.h b/src/core/or/relay_crypto_st.h
index dafce257c..dbdf1599d 100644
--- a/src/core/or/relay_crypto_st.h
+++ b/src/core/or/relay_crypto_st.h
@@ -25,6 +25,8 @@ struct relay_crypto_t {
   /** Digest state for cells heading away from the OR at this step. */
   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
 
diff --git a/src/core/or/sendme.c b/src/core/or/sendme.c
index afade43f7..76f551a92 100644
--- a/src/core/or/sendme.c
+++ b/src/core/or/sendme.c
@@ -14,6 +14,7 @@
 #include "core/or/cell_st.h"
 #include "core/or/circuitlist.h"
 #include "core/or/circuituse.h"
+#include "core/or/or_circuit_st.h"
 #include "core/or/relay.h"
 #include "core/or/sendme.h"
 #include "feature/nodelist/networkstatus.h"
@@ -342,18 +343,20 @@ sendme_connection_edge_consider_sending(edge_connection_t *conn)
  * more.
  */
 void
-sendme_circuit_consider_sending(circuit_t *circ, crypt_path_t *layer_hint,
-                                crypto_digest_t *digest)
+sendme_circuit_consider_sending(circuit_t *circ, crypt_path_t *layer_hint)
 {
-  tor_assert(digest);
+  crypto_digest_t *digest;
 
   while ((layer_hint ? layer_hint->deliver_window : circ->deliver_window) <=
           CIRCWINDOW_START - CIRCWINDOW_INCREMENT) {
     log_debug(LD_CIRC,"Queuing circuit sendme.");
-    if (layer_hint)
+    if (layer_hint) {
       layer_hint->deliver_window += CIRCWINDOW_INCREMENT;
-    else
+      digest = layer_hint->crypto.sendme_digest;
+    } else {
       circ->deliver_window += CIRCWINDOW_INCREMENT;
+      digest = TO_OR_CIRCUIT(circ)->crypto.sendme_digest;
+    }
     if (send_circuit_level_sendme(circ, layer_hint, digest) < 0) {
       return; /* The circuit's closed, don't continue */
     }
@@ -557,9 +560,16 @@ sendme_note_cell_digest(circuit_t *circ)
     return;
   }
 
-  digest = tor_malloc_zero(4);
-  if (circ->sendme_last_digests == NULL) {
-    circ->sendme_last_digests = smartlist_new();
+  /* 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);
+    crypto_digest_get_digest(TO_OR_CIRCUIT(circ)->crypto.sendme_digest,
+                             (char *) digest, 4);
+    if (circ->sendme_last_digests == NULL) {
+      circ->sendme_last_digests = smartlist_new();
+    }
+    smartlist_add(circ->sendme_last_digests, digest);
   }
-  smartlist_add(circ->sendme_last_digests, digest);
 }
diff --git a/src/core/or/sendme.h b/src/core/or/sendme.h
index 300fb25d9..e7cf718bb 100644
--- a/src/core/or/sendme.h
+++ b/src/core/or/sendme.h
@@ -16,8 +16,7 @@
 /* Sending SENDME cell. */
 void sendme_connection_edge_consider_sending(edge_connection_t *edge_conn);
 void sendme_circuit_consider_sending(circuit_t *circ,
-                                     crypt_path_t *layer_hint,
-                                     crypto_digest_t *digest);
+                                     crypt_path_t *layer_hint);
 
 /* Processing SENDME cell. */
 int sendme_process_circuit_level(crypt_path_t *layer_hint,





More information about the tor-commits mailing list