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