diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index 5ac2692bd4..43ad9f4235 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -1471,24 +1471,25 @@ circuit_truncated(origin_circuit_t *circ, crypt_path_t *layer, int reason) * cell back. */ int -onionskin_answer(or_circuit_t *circ, uint8_t cell_type, const char *payload, - size_t payload_len, const char *keys, +onionskin_answer(or_circuit_t *circ, + const created_cell_t *created_cell, + const char *keys, const uint8_t *rend_circ_nonce) { cell_t cell; crypt_path_t *tmp_cpath; + if (created_cell_format(&cell, created_cell) < 0) { + log_warn(LD_BUG,"couldn't format created cell"); + return -1; + } + cell.circ_id = circ->p_circ_id; + tmp_cpath = tor_malloc_zero(sizeof(crypt_path_t)); tmp_cpath->magic = CRYPT_PATH_MAGIC; - memset(&cell, 0, sizeof(cell_t)); - cell.command = cell_type; - cell.circ_id = circ->p_circ_id; - circuit_set_state(TO_CIRCUIT(circ), CIRCUIT_STATE_OPEN); - memcpy(cell.payload, payload, payload_len); - log_debug(LD_CIRC,"init digest forward 0x%.8x, backward 0x%.8x.", (unsigned int)get_uint32(keys), (unsigned int)get_uint32(keys+20)); @@ -1506,7 +1507,7 @@ onionskin_answer(or_circuit_t *circ, uint8_t cell_type, const char *payload, memcpy(circ->rend_circ_nonce, rend_circ_nonce, DIGEST_LEN); - circ->is_first_hop = (cell_type == CELL_CREATED_FAST); + circ->is_first_hop = (created_cell->cell_type == CELL_CREATED_FAST); append_cell_to_circuit_queue(TO_CIRCUIT(circ), circ->p_chan, &cell, CELL_DIRECTION_IN, 0); diff --git a/src/or/circuitbuild.h b/src/or/circuitbuild.h index e53e6ba874..23213e8e83 100644 --- a/src/or/circuitbuild.h +++ b/src/or/circuitbuild.h @@ -35,8 +35,8 @@ int circuit_finish_handshake(origin_circuit_t *circ, const struct created_cell_t *created_cell); int circuit_truncated(origin_circuit_t *circ, crypt_path_t *layer, int reason); -int onionskin_answer(or_circuit_t *circ, uint8_t cell_type, - const char *payload, size_t payload_len, +int onionskin_answer(or_circuit_t *circ, + const struct created_cell_t *created_cell, const char *keys, const uint8_t *rend_circ_nonce); int circuit_all_predicted_ports_handled(time_t now, int *need_uptime, diff --git a/src/or/command.c b/src/or/command.c index c77e2ec8b0..773d19cb5d 100644 --- a/src/or/command.c +++ b/src/or/command.c @@ -274,19 +274,21 @@ command_process_create_cell(cell_t *cell, channel_t *chan) /* This is a CREATE_FAST cell; we can handle it immediately without using * a CPU worker. */ uint8_t keys[CPATH_KEY_MATERIAL_LEN]; - uint8_t reply[MAX_ONIONSKIN_REPLY_LEN]; uint8_t rend_circ_nonce[DIGEST_LEN]; int len; + created_cell_t created_cell; /* Make sure we never try to use the OR connection on which we * received this cell to satisfy an EXTEND request, */ channel_mark_client(chan); + memset(&created_cell, 0, sizeof(created_cell)); len = onion_skin_server_handshake(ONION_HANDSHAKE_TYPE_FAST, create_cell->onionskin, create_cell->handshake_len, NULL, - reply, keys, CPATH_KEY_MATERIAL_LEN, + created_cell.reply, + keys, CPATH_KEY_MATERIAL_LEN, rend_circ_nonce); tor_free(create_cell); if (len < 0) { @@ -295,7 +297,10 @@ command_process_create_cell(cell_t *cell, channel_t *chan) tor_free(create_cell); return; } - if (onionskin_answer(circ, CELL_CREATED_FAST, (const char *)reply, len, + created_cell.cell_type = CELL_CREATED_FAST; + created_cell.handshake_len = len; + + if (onionskin_answer(circ, &created_cell, (const char *)keys, rend_circ_nonce)<0) { log_warn(LD_OR,"Failed to reply to CREATE_FAST cell. Closing."); circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_INTERNAL); diff --git a/src/or/cpuworker.c b/src/or/cpuworker.c index a8ec0275a5..1ac8cd59af 100644 --- a/src/or/cpuworker.c +++ b/src/or/cpuworker.c @@ -206,9 +206,7 @@ connection_cpu_process_inbuf(connection_t *conn) } tor_assert(! CIRCUIT_IS_ORIGIN(circ)); if (onionskin_answer(TO_OR_CIRCUIT(circ), - rpl.created_cell.cell_type, - (const char*)rpl.created_cell.reply, - rpl.created_cell.handshake_len, + &rpl.created_cell, (const char*)rpl.keys, rpl.rend_auth_material) < 0) { log_warn(LD_OR,"onionskin_answer failed. Closing."); diff --git a/src/or/onion.c b/src/or/onion.c index 9326c2fff9..ce5eb93b1a 100644 --- a/src/or/onion.c +++ b/src/or/onion.c @@ -496,6 +496,8 @@ parse_create2_payload(create_cell_t *cell_out, const uint8_t *p, size_t p_len) if (cell_out->handshake_len > CELL_PAYLOAD_SIZE - 4 || cell_out->handshake_len > p_len - 4) return -1; + if (cell_out->handshake_type == ONION_HANDSHAKE_TYPE_FAST) + return -1; memcpy(cell_out->onionskin, p+4, cell_out->handshake_len); return 0; } @@ -710,7 +712,6 @@ extend_cell_parse(extend_cell_t *cell_out, const uint8_t command, return -1; if (parse_create2_payload(&cell_out->create_cell,payload,eop-payload)<0) return -1; - break; } default: