|
@@ -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 "
|