aboutsummaryrefslogtreecommitdiff
path: root/src/or/rendservice.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2011-05-10 21:40:10 -0400
committerNick Mathewson <nickm@torproject.org>2011-09-09 12:49:47 -0400
commitcb9226bcdb811c6b30fb4bb2b6b06b378ebf0559 (patch)
tree4ec013d496687f5c3c9eace19252b718602fa5ae /src/or/rendservice.c
parentc75ee94ab41e3a76e8159366defe3159614b497c (diff)
downloadtor-cb9226bcdb811c6b30fb4bb2b6b06b378ebf0559.tar
tor-cb9226bcdb811c6b30fb4bb2b6b06b378ebf0559.tar.gz
Check for replays in PK-encrypted part of intro cell, not just in the g^x value
Diffstat (limited to 'src/or/rendservice.c')
-rw-r--r--src/or/rendservice.c26
1 files changed, 23 insertions, 3 deletions
diff --git a/src/or/rendservice.c b/src/or/rendservice.c
index d1cc7f4f1..af6737b5d 100644
--- a/src/or/rendservice.c
+++ b/src/or/rendservice.c
@@ -976,6 +976,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(
@@ -1109,9 +1132,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 "