diff options
author | Roger Dingledine <arma@torproject.org> | 2003-12-17 05:58:30 +0000 |
---|---|---|
committer | Roger Dingledine <arma@torproject.org> | 2003-12-17 05:58:30 +0000 |
commit | aba237e3e281c4dc2b08d633040339717df750e5 (patch) | |
tree | 4fb3f3269a555478f56069d74a904bfc21d8d9bc /src/or | |
parent | 389eb48690bb8aa6b50efecb735dbf2cb6ef9665 (diff) | |
download | tor-aba237e3e281c4dc2b08d633040339717df750e5.tar tor-aba237e3e281c4dc2b08d633040339717df750e5.tar.gz |
end-to-end integrity checking now works
initialize digests from shared secrets at handshake
make circuit_send_next_onion_skin use connection_edge_send_command
svn:r948
Diffstat (limited to 'src/or')
-rw-r--r-- | src/or/circuit.c | 56 | ||||
-rw-r--r-- | src/or/cpuworker.c | 8 | ||||
-rw-r--r-- | src/or/onion.c | 16 |
3 files changed, 48 insertions, 32 deletions
diff --git a/src/or/circuit.c b/src/or/circuit.c index a4d39cb3a..a1705a768 100644 --- a/src/or/circuit.c +++ b/src/or/circuit.c @@ -83,6 +83,10 @@ void circuit_free(circuit_t *circ) { crypto_free_cipher_env(circ->n_crypto); if (circ->p_crypto) crypto_free_cipher_env(circ->p_crypto); + if (circ->n_digest) + crypto_free_digest_env(circ->n_digest); + if (circ->p_digest) + crypto_free_digest_env(circ->p_digest); if(circ->build_state) tor_free(circ->build_state->chosen_exit); tor_free(circ->build_state); @@ -309,6 +313,7 @@ void relay_set_digest(crypto_digest_env_t *digest, cell_t *cell) { crypto_digest_add_bytes(digest, cell->payload, CELL_PAYLOAD_SIZE); crypto_digest_get_digest(digest, (char *)&integrity, 4); + log_fn(LOG_DEBUG,"Putting digest of %u into relay cell.",integrity); SET_CELL_RELAY_INTEGRITY(*cell, integrity); } @@ -319,6 +324,7 @@ int relay_check_digest(crypto_digest_env_t *digest, cell_t *cell) { uint32_t received_integrity, calculated_integrity; received_integrity = CELL_RELAY_INTEGRITY(*cell); + log_fn(LOG_DEBUG,"Reading digest of %u from relay cell.",received_integrity); SET_CELL_RELAY_INTEGRITY(*cell, 0); crypto_digest_add_bytes(digest, cell->payload, CELL_PAYLOAD_SIZE); @@ -854,6 +860,7 @@ int circuit_send_next_onion_skin(circuit_t *circ) { routerinfo_t *router; int r; int circ_id_type; + char payload[6+ONIONSKIN_CHALLENGE_LEN]; assert(circ && circ->cpath); @@ -899,27 +906,20 @@ int circuit_send_next_onion_skin(circuit_t *circ) { } hop = circ->cpath->prev; - memset(&cell, 0, sizeof(cell_t)); - cell.command = CELL_RELAY; - cell.circ_id = circ->n_circ_id; - SET_CELL_RELAY_COMMAND(cell, RELAY_COMMAND_EXTEND); - SET_CELL_STREAM_ID(cell, ZERO_STREAM); - SET_CELL_RELAY_LENGTH(cell, 6+ONIONSKIN_CHALLENGE_LEN); - - *(uint32_t*)(cell.payload+RELAY_HEADER_SIZE) = htonl(hop->addr); - *(uint16_t*)(cell.payload+RELAY_HEADER_SIZE+4) = htons(hop->port); - if(onion_skin_create(router->onion_pkey, &(hop->handshake_state), - cell.payload+RELAY_HEADER_SIZE+6) < 0) { + *(uint32_t*)payload = htonl(hop->addr); + *(uint16_t*)(payload+4) = htons(hop->port); + if(onion_skin_create(router->onion_pkey, &(hop->handshake_state), payload+6) < 0) { log_fn(LOG_WARN,"onion_skin_create failed."); return -1; } log_fn(LOG_DEBUG,"Sending extend relay cell."); - /* send it to hop->prev, because it will transfer it to a create cell and then send to hop */ - if(circuit_deliver_relay_cell(&cell, circ, CELL_DIRECTION_OUT, hop->prev) < 0) { - log_fn(LOG_WARN,"failed to deliver extend cell. Closing."); - return -1; - } + /* send it to hop->prev, because it will transfer + * it to a create cell and then send to hop */ + if(connection_edge_send_command(NULL, circ, RELAY_COMMAND_EXTEND, + payload, sizeof(payload), hop->prev) < 0) + return -1; /* circuit is closed */ + hop->state = CPATH_STATE_AWAITING_KEYS; } return 0; @@ -987,7 +987,7 @@ int circuit_extend(cell_t *cell, circuit_t *circ) { int circuit_finish_handshake(circuit_t *circ, char *reply) { unsigned char iv[16]; - unsigned char keys[32]; + unsigned char keys[40+32]; crypt_path_t *hop; memset(iv, 0, 16); @@ -1006,7 +1006,7 @@ int circuit_finish_handshake(circuit_t *circ, char *reply) { } assert(hop->state == CPATH_STATE_AWAITING_KEYS); - if(onion_skin_client_handshake(hop->handshake_state, reply, keys, 32) < 0) { + if(onion_skin_client_handshake(hop->handshake_state, reply, keys, 40+32) < 0) { log_fn(LOG_WARN,"onion_skin_client_handshake failed."); return -1; } @@ -1014,16 +1014,22 @@ int circuit_finish_handshake(circuit_t *circ, char *reply) { crypto_dh_free(hop->handshake_state); /* don't need it anymore */ hop->handshake_state = NULL; - log_fn(LOG_DEBUG,"hop %d init cipher forward %u, backward %u.", - (int)hop, (unsigned)*(uint32_t*)keys, (unsigned) *(uint32_t*)(keys+16)); + log_fn(LOG_INFO,"hop %d init digest forward %u, backward %u.", + (int)hop, (unsigned)*(uint32_t*)keys, (unsigned)*(uint32_t*)(keys+20)); + hop->f_digest = crypto_new_digest_env(CRYPTO_SHA1_DIGEST); + crypto_digest_add_bytes(hop->f_digest, keys, 20); + hop->b_digest = crypto_new_digest_env(CRYPTO_SHA1_DIGEST); + crypto_digest_add_bytes(hop->b_digest, keys+20, 20); + + log_fn(LOG_DEBUG,"hop %d init cipher forward %u, backward %u.", + (int)hop, (unsigned)*(uint32_t*)(keys+40), (unsigned) *(uint32_t*)(keys+40+16)); if (!(hop->f_crypto = - crypto_create_init_cipher(CIRCUIT_CIPHER,keys,iv,1))) { + crypto_create_init_cipher(CIRCUIT_CIPHER,keys+40,iv,1))) { log(LOG_WARN,"forward cipher initialization failed."); return -1; } - if (!(hop->b_crypto = - crypto_create_init_cipher(CIRCUIT_CIPHER,keys+16,iv,0))) { + crypto_create_init_cipher(CIRCUIT_CIPHER,keys+40+16,iv,0))) { log(LOG_WARN,"backward cipher initialization failed."); return -1; } @@ -1135,9 +1141,13 @@ void assert_circuit_ok(const circuit_t *c) if (c->cpath) { assert(!c->n_crypto); assert(!c->p_crypto); + assert(!c->n_digest); + assert(!c->p_digest); } else { assert(c->n_crypto); assert(c->p_crypto); + assert(c->n_digest); + assert(c->p_digest); } } if (c->cpath) { diff --git a/src/or/cpuworker.c b/src/or/cpuworker.c index fee8eebb4..1b33f8dbd 100644 --- a/src/or/cpuworker.c +++ b/src/or/cpuworker.c @@ -10,7 +10,7 @@ extern or_options_t options; /* command-line and config-file options */ #define TAG_LEN 8 #define LEN_ONION_QUESTION (1+TAG_LEN+ONIONSKIN_CHALLENGE_LEN) -#define LEN_ONION_RESPONSE (1+TAG_LEN+ONIONSKIN_REPLY_LEN+32) +#define LEN_ONION_RESPONSE (1+TAG_LEN+ONIONSKIN_REPLY_LEN+40+32) int num_cpuworkers=0; int num_cpuworkers_busy=0; @@ -119,7 +119,7 @@ int cpuworker_main(void *data) { int fd; /* variables for onion processing */ - unsigned char keys[32]; + unsigned char keys[40+32]; unsigned char reply_to_proxy[ONIONSKIN_REPLY_LEN]; unsigned char buf[LEN_ONION_RESPONSE]; char tag[TAG_LEN]; @@ -147,7 +147,7 @@ int cpuworker_main(void *data) { if(question_type == CPUWORKER_TASK_ONION) { if(onion_skin_server_handshake(question, get_onion_key(), - reply_to_proxy, keys, 32) < 0) { + reply_to_proxy, keys, 40+32) < 0) { /* failure */ log_fn(LOG_WARN,"onion_skin_server_handshake failed."); memset(buf,0,LEN_ONION_RESPONSE); /* send all zeros for failure */ @@ -157,7 +157,7 @@ int cpuworker_main(void *data) { buf[0] = 1; /* 1 means success */ memcpy(buf+1,tag,TAG_LEN); memcpy(buf+1+TAG_LEN,reply_to_proxy,ONIONSKIN_REPLY_LEN); - memcpy(buf+1+TAG_LEN+ONIONSKIN_REPLY_LEN,keys,32); + memcpy(buf+1+TAG_LEN+ONIONSKIN_REPLY_LEN,keys,40+32); } if(write_all(fd, buf, LEN_ONION_RESPONSE) != LEN_ONION_RESPONSE) { log_fn(LOG_ERR,"writing response buf failed. Exiting."); diff --git a/src/or/onion.c b/src/or/onion.c index 5c52dd629..dd7db6162 100644 --- a/src/or/onion.c +++ b/src/or/onion.c @@ -131,16 +131,22 @@ int onionskin_answer(circuit_t *circ, unsigned char *payload, unsigned char *key memcpy(cell.payload, payload, ONIONSKIN_REPLY_LEN); - log_fn(LOG_DEBUG,"init cipher forward %d, backward %d.", *(int*)keys, *(int*)(keys+16)); - + log_fn(LOG_INFO,"init digest forward %d, backward %d.", + *(uint32_t*)(keys), *(uint32_t*)(keys+20)); + circ->n_digest = crypto_new_digest_env(CRYPTO_SHA1_DIGEST); + crypto_digest_add_bytes(circ->n_digest, keys, 20); + circ->p_digest = crypto_new_digest_env(CRYPTO_SHA1_DIGEST); + crypto_digest_add_bytes(circ->p_digest, keys+20, 20); + + log_fn(LOG_DEBUG,"init cipher forward %d, backward %d.", + *(uint32_t*)(keys+40), *(uint32_t*)(keys+40+16)); if (!(circ->n_crypto = - crypto_create_init_cipher(CIRCUIT_CIPHER,keys,iv,0))) { + crypto_create_init_cipher(CIRCUIT_CIPHER,keys+40,iv,0))) { log_fn(LOG_WARN,"Cipher initialization failed (n)."); return -1; } - if (!(circ->p_crypto = - crypto_create_init_cipher(CIRCUIT_CIPHER,keys+16,iv,1))) { + crypto_create_init_cipher(CIRCUIT_CIPHER,keys+40+16,iv,1))) { log_fn(LOG_WARN,"Cipher initialization failed (p)."); return -1; } |