summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2011-09-09 12:53:45 -0400
committerNick Mathewson <nickm@torproject.org>2011-09-09 12:53:45 -0400
commit4467799f45346a59c37de9337b24ace361cb8b6a (patch)
tree9323626d194ba145dda04e2e06c5f2004b06d3d1
parentdfa6cde4d4de57476ea8381199dfbac1afc245d5 (diff)
parentcb9226bcdb811c6b30fb4bb2b6b06b378ebf0559 (diff)
downloadtor-4467799f45346a59c37de9337b24ace361cb8b6a.tar.gz
tor-4467799f45346a59c37de9337b24ace361cb8b6a.zip
Merge remote-tracking branch 'public/enhance_replay_detection' into maint-0.2.2
-rw-r--r--changes/replay-firstpart13
-rw-r--r--src/or/rendservice.c26
2 files changed, 36 insertions, 3 deletions
diff --git a/changes/replay-firstpart b/changes/replay-firstpart
new file mode 100644
index 0000000000..f4a7767fb1
--- /dev/null
+++ b/changes/replay-firstpart
@@ -0,0 +1,13 @@
+ o Minor features (security):
+
+ - Check for replays of the public-key encrypted portion of an
+ INTRODUCE1 cell, in addition to the current check for replays of
+ the g^x value. This prevents a possible class of active attacks
+ by an attacker who controls both an introduction point and a
+ rendezvous point, and who uses the malleability of AES-CTR to
+ alter the encrypted g^x portion of the INTRODUCE1 cell. We
+ think that these attacks is infeasible (requiring the attacker
+ to send on the order of zettabytes of altered cells in a short
+ interval), but we'd rather block them off in case there are any
+ classes of this attack that we missed. Reported by dvorak.
+
diff --git a/src/or/rendservice.c b/src/or/rendservice.c
index 8a0171170c..681c4b8103 100644
--- a/src/or/rendservice.c
+++ b/src/or/rendservice.c
@@ -956,6 +956,29 @@ rend_service_introduce(origin_circuit_t *circuit, const uint8_t *request,
"PK-encrypted portion of INTRODUCE2 cell was truncated.");
return -1;
}
+
+ if (!service->accepted_intros)
+ service->accepted_intros = digestmap_new();
+
+ {
+ char pkpart_digest[DIGEST_LEN];
+ /* Check for replay of PK-encrypted portion. It is slightly naughty to
+ use the same digestmap to check for this and for g^x replays, but
+ collisions are tremendously unlikely.
+ */
+ crypto_digest(pkpart_digest, (char*)request+DIGEST_LEN, keylen);
+ access_time = digestmap_get(service->accepted_intros, pkpart_digest);
+ if (access_time != NULL) {
+ log_warn(LD_REND, "Possible replay detected! We received an "
+ "INTRODUCE2 cell with same PK-encrypted part %d seconds ago. "
+ "Dropping cell.", (int)(now-*access_time));
+ return -1;
+ }
+ access_time = tor_malloc(sizeof(time_t));
+ *access_time = now;
+ digestmap_set(service->accepted_intros, pkpart_digest, access_time);
+ }
+
/* Next N bytes is encrypted with service key */
note_crypto_pk_op(REND_SERVER);
r = crypto_pk_private_hybrid_decrypt(
@@ -1098,9 +1121,6 @@ rend_service_introduce(origin_circuit_t *circuit, const uint8_t *request,
/* Check whether there is a past request with the same Diffie-Hellman,
* part 1. */
- if (!service->accepted_intros)
- service->accepted_intros = digestmap_new();
-
access_time = digestmap_get(service->accepted_intros, diffie_hellman_hash);
if (access_time != NULL) {
log_warn(LD_REND, "Possible replay detected! We received an "