Loading src/or/circuitbuild.c +68 −54 Original line number Original line Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include "main.h" #include "main.h" #include "networkstatus.h" #include "networkstatus.h" #include "nodelist.h" #include "nodelist.h" #include "onion.h" #include "onion_tap.h" #include "onion_tap.h" #include "onion_fast.h" #include "onion_fast.h" #include "policies.h" #include "policies.h" Loading Loading @@ -54,7 +55,9 @@ static channel_t * channel_connect_for_circuit(const tor_addr_t *addr, uint16_t port, uint16_t port, const char *id_digest); const char *id_digest); static int circuit_deliver_create_cell(circuit_t *circ, static int circuit_deliver_create_cell(circuit_t *circ, uint8_t cell_type, const char *payload); uint8_t cell_type, const uint8_t *payload, size_t payload_len); static int onion_pick_cpath_exit(origin_circuit_t *circ, extend_info_t *exit); static int onion_pick_cpath_exit(origin_circuit_t *circ, extend_info_t *exit); static crypt_path_t *onion_next_hop_in_cpath(crypt_path_t *cpath); static crypt_path_t *onion_next_hop_in_cpath(crypt_path_t *cpath); static int onion_extend_cpath(origin_circuit_t *circ); static int onion_extend_cpath(origin_circuit_t *circ); Loading Loading @@ -474,7 +477,8 @@ circuit_n_chan_done(channel_t *chan, int status) /* pull the create cell out of circ->onionskin, and send it */ /* pull the create cell out of circ->onionskin, and send it */ tor_assert(circ->n_chan_onionskin); tor_assert(circ->n_chan_onionskin); if (circuit_deliver_create_cell(circ,CELL_CREATE, if (circuit_deliver_create_cell(circ,CELL_CREATE, circ->n_chan_onionskin)<0) { (const uint8_t*)circ->n_chan_onionskin, circ->n_chan_onionskin_len)<0) { circuit_mark_for_close(circ, END_CIRC_REASON_RESOURCELIMIT); circuit_mark_for_close(circ, END_CIRC_REASON_RESOURCELIMIT); continue; continue; } } Loading @@ -491,12 +495,12 @@ circuit_n_chan_done(channel_t *chan, int status) * for the outgoing * for the outgoing * circuit <b>circ</b>, and deliver a cell of type <b>cell_type</b> * circuit <b>circ</b>, and deliver a cell of type <b>cell_type</b> * (either CELL_CREATE or CELL_CREATE_FAST) with payload <b>payload</b> * (either CELL_CREATE or CELL_CREATE_FAST) with payload <b>payload</b> * to this circuit. * to this circuit. DOCDOC payload_len * Return -1 if we failed to find a suitable circid, else return 0. * Return -1 if we failed to find a suitable circid, else return 0. */ */ static int static int circuit_deliver_create_cell(circuit_t *circ, uint8_t cell_type, circuit_deliver_create_cell(circuit_t *circ, uint8_t cell_type, const char *payload) const uint8_t *payload, size_t payload_len) { { cell_t cell; cell_t cell; circid_t id; circid_t id; Loading @@ -518,7 +522,7 @@ circuit_deliver_create_cell(circuit_t *circ, uint8_t cell_type, cell.command = cell_type; cell.command = cell_type; cell.circ_id = circ->n_circ_id; cell.circ_id = circ->n_circ_id; memcpy(cell.payload, payload, ONIONSKIN_CHALLENGE_LEN); memcpy(cell.payload, payload, payload_len); append_cell_to_circuit_queue(circ, circ->n_chan, &cell, append_cell_to_circuit_queue(circ, circ->n_chan, &cell, CELL_DIRECTION_OUT, 0); CELL_DIRECTION_OUT, 0); Loading Loading @@ -611,8 +615,10 @@ circuit_send_next_onion_skin(origin_circuit_t *circ) { { crypt_path_t *hop; crypt_path_t *hop; const node_t *node; const node_t *node; char payload[2+4+DIGEST_LEN+ONIONSKIN_CHALLENGE_LEN]; uint8_t payload[2+4+DIGEST_LEN+MAX_ONIONSKIN_CHALLENGE_LEN]; char *onionskin; uint8_t *onionskin; uint16_t handshake_type; int onionskin_len; size_t payload_len; size_t payload_len; tor_assert(circ); tor_assert(circ); Loading @@ -633,30 +639,29 @@ circuit_send_next_onion_skin(origin_circuit_t *circ) * send an old slow create cell. * send an old slow create cell. */ */ cell_type = CELL_CREATE; cell_type = CELL_CREATE; if (onion_skin_create(circ->cpath->extend_info->onion_key, handshake_type = ONION_HANDSHAKE_TYPE_TAP; &(circ->cpath->dh_handshake_state), payload) < 0) { log_warn(LD_CIRC,"onion_skin_create (first hop) failed."); return - END_CIRC_REASON_INTERNAL; } note_request("cell: create", 1); note_request("cell: create", 1); } else { } else { /* We are not an OR, and we're building the first hop of a circuit to a /* We are not an OR, and we're building the first hop of a circuit to a * new OR: we can be speedy and use CREATE_FAST to save an RSA operation * new OR: we can be speedy and use CREATE_FAST to save an RSA operation * and a DH operation. */ * and a DH operation. */ cell_type = CELL_CREATE_FAST; cell_type = CELL_CREATE_FAST; handshake_type = ONION_HANDSHAKE_TYPE_FAST; note_request("cell: create fast", 1); } memset(payload, 0, sizeof(payload)); memset(payload, 0, sizeof(payload)); if (fast_onionskin_create(&circ->cpath->fast_handshake_state, onionskin_len = onion_skin_create(handshake_type, (uint8_t *)payload) < 0) { circ->cpath->extend_info, log_warn(LD_CIRC,"onion_skin_create FAST (first hop) failed."); &circ->cpath->handshake_state, payload); if (onionskin_len < 0) { log_warn(LD_CIRC,"onion_skin_create (first hop) failed."); return - END_CIRC_REASON_INTERNAL; return - END_CIRC_REASON_INTERNAL; } } note_request("cell: create fast", 1); if (circuit_deliver_create_cell(TO_CIRCUIT(circ), cell_type, payload, } onionskin_len) < 0) if (circuit_deliver_create_cell(TO_CIRCUIT(circ), cell_type, payload) < 0) return - END_CIRC_REASON_RESOURCELIMIT; return - END_CIRC_REASON_RESOURCELIMIT; circ->cpath->state = CPATH_STATE_AWAITING_KEYS; circ->cpath->state = CPATH_STATE_AWAITING_KEYS; Loading Loading @@ -742,12 +747,16 @@ circuit_send_next_onion_skin(origin_circuit_t *circ) set_uint16(payload+4, htons(hop->extend_info->port)); set_uint16(payload+4, htons(hop->extend_info->port)); onionskin = payload+2+4; onionskin = payload+2+4; memcpy(payload+2+4+ONIONSKIN_CHALLENGE_LEN, memcpy(payload+2+4+TAP_ONIONSKIN_CHALLENGE_LEN, hop->extend_info->identity_digest, DIGEST_LEN); hop->extend_info->identity_digest, DIGEST_LEN); payload_len = 2+4+ONIONSKIN_CHALLENGE_LEN+DIGEST_LEN; payload_len = 2+4+TAP_ONIONSKIN_CHALLENGE_LEN+DIGEST_LEN; if (onion_skin_create(hop->extend_info->onion_key, handshake_type = ONION_HANDSHAKE_TYPE_TAP; &(hop->dh_handshake_state), onionskin) < 0) { if (onion_skin_create(handshake_type, hop->extend_info, &hop->handshake_state, onionskin) < 0) { log_warn(LD_CIRC,"onion_skin_create failed."); log_warn(LD_CIRC,"onion_skin_create failed."); return - END_CIRC_REASON_INTERNAL; return - END_CIRC_REASON_INTERNAL; } } Loading @@ -758,7 +767,8 @@ circuit_send_next_onion_skin(origin_circuit_t *circ) * it to a create cell and then send to hop */ * it to a create cell and then send to hop */ if (relay_send_command_from_edge(0, TO_CIRCUIT(circ), if (relay_send_command_from_edge(0, TO_CIRCUIT(circ), RELAY_COMMAND_EXTEND, RELAY_COMMAND_EXTEND, payload, payload_len, hop->prev) < 0) (char*)payload, payload_len, hop->prev) < 0) return 0; /* circuit is closed */ return 0; /* circuit is closed */ hop->state = CPATH_STATE_AWAITING_KEYS; hop->state = CPATH_STATE_AWAITING_KEYS; Loading Loading @@ -826,7 +836,7 @@ circuit_extend(cell_t *cell, circuit_t *circ) relay_header_unpack(&rh, cell->payload); relay_header_unpack(&rh, cell->payload); if (rh.length < 4+2+ONIONSKIN_CHALLENGE_LEN+DIGEST_LEN) { if (rh.length < 4+2+TAP_ONIONSKIN_CHALLENGE_LEN+DIGEST_LEN) { log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, "Wrong length %d on extend cell. Closing circuit.", "Wrong length %d on extend cell. Closing circuit.", rh.length); rh.length); Loading @@ -837,7 +847,7 @@ circuit_extend(cell_t *cell, circuit_t *circ) n_port = ntohs(get_uint16(cell->payload+RELAY_HEADER_SIZE+4)); n_port = ntohs(get_uint16(cell->payload+RELAY_HEADER_SIZE+4)); onionskin = (char*) cell->payload+RELAY_HEADER_SIZE+4+2; onionskin = (char*) cell->payload+RELAY_HEADER_SIZE+4+2; id_digest = (char*) cell->payload+RELAY_HEADER_SIZE+4+2+ id_digest = (char*) cell->payload+RELAY_HEADER_SIZE+4+2+ ONIONSKIN_CHALLENGE_LEN; TAP_ONIONSKIN_CHALLENGE_LEN; tor_addr_from_ipv4h(&n_addr, n_addr32); tor_addr_from_ipv4h(&n_addr, n_addr32); if (!n_port || !n_addr32) { if (!n_port || !n_addr32) { Loading Loading @@ -890,8 +900,10 @@ circuit_extend(cell_t *cell, circuit_t *circ) NULL /*onion_key*/, NULL /*onion_key*/, &n_addr, n_port); &n_addr, n_port); circ->n_chan_onionskin = tor_malloc(ONIONSKIN_CHALLENGE_LEN); circ->n_chan_onionskin = tor_malloc(TAP_ONIONSKIN_CHALLENGE_LEN); memcpy(circ->n_chan_onionskin, onionskin, ONIONSKIN_CHALLENGE_LEN); memcpy(circ->n_chan_onionskin, onionskin, TAP_ONIONSKIN_CHALLENGE_LEN); circ->n_chan_onionskin_len = TAP_ONIONSKIN_CHALLENGE_LEN; circuit_set_state(circ, CIRCUIT_STATE_CHAN_WAIT); circuit_set_state(circ, CIRCUIT_STATE_CHAN_WAIT); if (should_launch) { if (should_launch) { Loading @@ -917,7 +929,8 @@ circuit_extend(cell_t *cell, circuit_t *circ) "n_chan is %s", "n_chan is %s", channel_get_canonical_remote_descr(n_chan)); channel_get_canonical_remote_descr(n_chan)); if (circuit_deliver_create_cell(circ, CELL_CREATE, onionskin) < 0) if (circuit_deliver_create_cell(circ, CELL_CREATE, (uint8_t*)onionskin, TAP_ONIONSKIN_CHALLENGE_LEN) < 0) return -1; return -1; return 0; return 0; } } Loading Loading @@ -1377,31 +1390,32 @@ circuit_finish_handshake(origin_circuit_t *circ, uint8_t reply_type, } } tor_assert(hop->state == CPATH_STATE_AWAITING_KEYS); tor_assert(hop->state == CPATH_STATE_AWAITING_KEYS); if (reply_type == CELL_CREATED && hop->dh_handshake_state) { { if (onion_skin_client_handshake(hop->dh_handshake_state, (char*)reply,keys, uint16_t handshake_type = 0xffff; DIGEST_LEN*2+CIPHER_KEY_LEN*2) < 0) { if (reply_type == CELL_CREATED) log_warn(LD_CIRC,"onion_skin_client_handshake failed."); handshake_type = ONION_HANDSHAKE_TYPE_TAP; else if (reply_type == CELL_CREATED_FAST) handshake_type = ONION_HANDSHAKE_TYPE_FAST; if (handshake_type != hop->handshake_state.tag) { log_warn(LD_PROTOCOL,"CREATED cell onionskin type (%u) did not " "match CREATE cell onionskin type (%u).", (unsigned)handshake_type, (unsigned) hop->handshake_state.tag); return -END_CIRC_REASON_TORPROTOCOL; return -END_CIRC_REASON_TORPROTOCOL; } } /* Remember hash of g^xy */ memcpy(hop->handshake_digest, reply+DH_KEY_LEN, DIGEST_LEN); if (onion_skin_client_handshake(handshake_type, } else if (reply_type == CELL_CREATED_FAST && !hop->dh_handshake_state) { &hop->handshake_state, if (fast_client_handshake(hop->fast_handshake_state, reply, reply, (uint8_t*)keys, (uint8_t*)keys, sizeof(keys), DIGEST_LEN*2+CIPHER_KEY_LEN*2) < 0) { (uint8_t*)hop->handshake_digest) < 0) { log_warn(LD_CIRC,"fast_client_handshake failed."); log_warn(LD_CIRC,"onion_skin_client_handshake failed."); return -END_CIRC_REASON_TORPROTOCOL; return -END_CIRC_REASON_TORPROTOCOL; } } memcpy(hop->handshake_digest, reply+DIGEST_LEN, DIGEST_LEN); } else { log_warn(LD_PROTOCOL,"CREATED cell type did not match CREATE cell type."); return -END_CIRC_REASON_TORPROTOCOL; } } crypto_dh_free(hop->dh_handshake_state); /* don't need it anymore */ onion_handshake_state_release(&hop->handshake_state); hop->dh_handshake_state = NULL; memset(hop->fast_handshake_state, 0, sizeof(hop->fast_handshake_state)); if (circuit_init_cpath_crypto(hop, keys, 0)<0) { if (circuit_init_cpath_crypto(hop, keys, 0)<0) { return -END_CIRC_REASON_TORPROTOCOL; return -END_CIRC_REASON_TORPROTOCOL; Loading Loading @@ -1470,7 +1484,7 @@ circuit_truncated(origin_circuit_t *circ, crypt_path_t *layer, int reason) */ */ int int onionskin_answer(or_circuit_t *circ, uint8_t cell_type, const char *payload, onionskin_answer(or_circuit_t *circ, uint8_t cell_type, const char *payload, const char *keys) size_t payload_len, const char *keys) { { cell_t cell; cell_t cell; crypt_path_t *tmp_cpath; crypt_path_t *tmp_cpath; Loading @@ -1484,8 +1498,7 @@ onionskin_answer(or_circuit_t *circ, uint8_t cell_type, const char *payload, circuit_set_state(TO_CIRCUIT(circ), CIRCUIT_STATE_OPEN); circuit_set_state(TO_CIRCUIT(circ), CIRCUIT_STATE_OPEN); memcpy(cell.payload, payload, memcpy(cell.payload, payload, payload_len); cell_type == CELL_CREATED ? ONIONSKIN_REPLY_LEN : DIGEST_LEN*2); log_debug(LD_CIRC,"init digest forward 0x%.8x, backward 0x%.8x.", log_debug(LD_CIRC,"init digest forward 0x%.8x, backward 0x%.8x.", (unsigned int)get_uint32(keys), (unsigned int)get_uint32(keys), Loading @@ -1502,6 +1515,7 @@ onionskin_answer(or_circuit_t *circ, uint8_t cell_type, const char *payload, tmp_cpath->magic = 0; tmp_cpath->magic = 0; tor_free(tmp_cpath); tor_free(tmp_cpath); /* XXXX Move responsibility for extracting this. */ if (cell_type == CELL_CREATED) if (cell_type == CELL_CREATED) memcpy(circ->handshake_digest, cell.payload+DH_KEY_LEN, DIGEST_LEN); memcpy(circ->handshake_digest, cell.payload+DH_KEY_LEN, DIGEST_LEN); else else Loading src/or/circuitbuild.h +2 −1 Original line number Original line Diff line number Diff line Loading @@ -35,7 +35,8 @@ int circuit_finish_handshake(origin_circuit_t *circ, uint8_t cell_type, int circuit_truncated(origin_circuit_t *circ, crypt_path_t *layer, int circuit_truncated(origin_circuit_t *circ, crypt_path_t *layer, int reason); int reason); int onionskin_answer(or_circuit_t *circ, uint8_t cell_type, int onionskin_answer(or_circuit_t *circ, uint8_t cell_type, const char *payload, const char *keys); const char *payload, size_t payload_len, const char *keys); int circuit_all_predicted_ports_handled(time_t now, int *need_uptime, int circuit_all_predicted_ports_handled(time_t now, int *need_uptime, int *need_capacity); int *need_capacity); Loading src/or/circuitlist.c +4 −3 Original line number Original line Diff line number Diff line Loading @@ -744,8 +744,8 @@ circuit_free_cpath_node(crypt_path_t *victim) crypto_cipher_free(victim->b_crypto); crypto_cipher_free(victim->b_crypto); crypto_digest_free(victim->f_digest); crypto_digest_free(victim->f_digest); crypto_digest_free(victim->b_digest); crypto_digest_free(victim->b_digest); crypto_dh_free(victim->dh_handshake_state); onion_handshake_state_release(&victim->handshake_state); fast_handshake_state_free(victim->fast_handshake_state); crypto_dh_free(victim->rend_dh_handshake_state); extend_info_free(victim->extend_info); extend_info_free(victim->extend_info); memwipe(victim, 0xBB, sizeof(crypt_path_t)); /* poison memory */ memwipe(victim, 0xBB, sizeof(crypt_path_t)); /* poison memory */ Loading Loading @@ -1494,7 +1494,8 @@ assert_cpath_layer_ok(const crypt_path_t *cp) tor_assert(cp->b_crypto); tor_assert(cp->b_crypto); /* fall through */ /* fall through */ case CPATH_STATE_CLOSED: case CPATH_STATE_CLOSED: tor_assert(!cp->dh_handshake_state); /*XXXX Assert that there's no handshake_state either. */ tor_assert(!cp->rend_dh_handshake_state); break; break; case CPATH_STATE_AWAITING_KEYS: case CPATH_STATE_AWAITING_KEYS: /* tor_assert(cp->dh_handshake_state); */ /* tor_assert(cp->dh_handshake_state); */ Loading src/or/command.c +6 −4 Original line number Original line Diff line number Diff line Loading @@ -30,6 +30,7 @@ #include "hibernate.h" #include "hibernate.h" #include "nodelist.h" #include "nodelist.h" //#include "onion.h" //#include "onion.h" #include "onion_tap.h" #include "onion_fast.h" #include "onion_fast.h" #include "relay.h" #include "relay.h" #include "router.h" #include "router.h" Loading Loading @@ -254,8 +255,8 @@ command_process_create_cell(cell_t *cell, channel_t *chan) circ->base_.purpose = CIRCUIT_PURPOSE_OR; circ->base_.purpose = CIRCUIT_PURPOSE_OR; circuit_set_state(TO_CIRCUIT(circ), CIRCUIT_STATE_ONIONSKIN_PENDING); circuit_set_state(TO_CIRCUIT(circ), CIRCUIT_STATE_ONIONSKIN_PENDING); if (cell->command == CELL_CREATE) { if (cell->command == CELL_CREATE) { char *onionskin = tor_malloc(ONIONSKIN_CHALLENGE_LEN); char *onionskin = tor_malloc(TAP_ONIONSKIN_CHALLENGE_LEN); memcpy(onionskin, cell->payload, ONIONSKIN_CHALLENGE_LEN); memcpy(onionskin, cell->payload, TAP_ONIONSKIN_CHALLENGE_LEN); /* hand it off to the cpuworkers, and then return. */ /* hand it off to the cpuworkers, and then return. */ if (assign_onionskin_to_cpuworker(NULL, circ, onionskin) < 0) { if (assign_onionskin_to_cpuworker(NULL, circ, onionskin) < 0) { Loading @@ -282,7 +283,8 @@ command_process_create_cell(cell_t *cell, channel_t *chan) circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_INTERNAL); circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_INTERNAL); return; return; } } if (onionskin_answer(circ, CELL_CREATED_FAST, reply, keys)<0) { if (onionskin_answer(circ, CELL_CREATED_FAST, reply, sizeof(reply), keys)<0) { log_warn(LD_OR,"Failed to reply to CREATE_FAST cell. Closing."); log_warn(LD_OR,"Failed to reply to CREATE_FAST cell. Closing."); circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_INTERNAL); circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_INTERNAL); return; return; Loading Loading @@ -340,7 +342,7 @@ command_process_created_cell(cell_t *cell, channel_t *chan) log_debug(LD_OR, log_debug(LD_OR, "Converting created cell to extended relay cell, sending."); "Converting created cell to extended relay cell, sending."); relay_send_command_from_edge(0, circ, RELAY_COMMAND_EXTENDED, relay_send_command_from_edge(0, circ, RELAY_COMMAND_EXTENDED, (char*)cell->payload, ONIONSKIN_REPLY_LEN, (char*)cell->payload, TAP_ONIONSKIN_REPLY_LEN, NULL); NULL); } } } } Loading src/or/cpuworker.c +21 −19 Original line number Original line Diff line number Diff line Loading @@ -35,7 +35,7 @@ #define TAG_LEN 10 #define TAG_LEN 10 /** How many bytes are sent from the cpuworker back to tor? */ /** How many bytes are sent from the cpuworker back to tor? */ #define LEN_ONION_RESPONSE \ #define LEN_ONION_RESPONSE \ (1+TAG_LEN+ONIONSKIN_REPLY_LEN+CPATH_KEY_MATERIAL_LEN) (1+TAG_LEN+TAP_ONIONSKIN_REPLY_LEN+CPATH_KEY_MATERIAL_LEN) /** How many cpuworkers we have running right now. */ /** How many cpuworkers we have running right now. */ static int num_cpuworkers=0; static int num_cpuworkers=0; Loading Loading @@ -185,7 +185,8 @@ connection_cpu_process_inbuf(connection_t *conn) } } tor_assert(! CIRCUIT_IS_ORIGIN(circ)); tor_assert(! CIRCUIT_IS_ORIGIN(circ)); if (onionskin_answer(TO_OR_CIRCUIT(circ), CELL_CREATED, buf+TAG_LEN, if (onionskin_answer(TO_OR_CIRCUIT(circ), CELL_CREATED, buf+TAG_LEN, buf+TAG_LEN+ONIONSKIN_REPLY_LEN) < 0) { TAP_ONIONSKIN_REPLY_LEN, buf+TAG_LEN+TAP_ONIONSKIN_REPLY_LEN) < 0) { log_warn(LD_OR,"onionskin_answer failed. Closing."); log_warn(LD_OR,"onionskin_answer failed. Closing."); circuit_mark_for_close(circ, END_CIRC_REASON_INTERNAL); circuit_mark_for_close(circ, END_CIRC_REASON_INTERNAL); goto done_processing; goto done_processing; Loading Loading @@ -214,11 +215,11 @@ connection_cpu_process_inbuf(connection_t *conn) * Request format: * Request format: * Task type [1 byte, always CPUWORKER_TASK_ONION] * Task type [1 byte, always CPUWORKER_TASK_ONION] * Opaque tag TAG_LEN * Opaque tag TAG_LEN * Onionskin challenge ONIONSKIN_CHALLENGE_LEN * Onionskin challenge TAP_ONIONSKIN_CHALLENGE_LEN * Response format: * Response format: * Success/failure [1 byte, boolean.] * Success/failure [1 byte, boolean.] * Opaque tag TAG_LEN * Opaque tag TAG_LEN * Onionskin challenge ONIONSKIN_REPLY_LEN * Onionskin challenge TAP_ONIONSKIN_REPLY_LEN * Negotiated keys KEY_LEN*2+DIGEST_LEN*2 * Negotiated keys KEY_LEN*2+DIGEST_LEN*2 * * * (Note: this _should_ be by addr/port, since we're concerned with specific * (Note: this _should_ be by addr/port, since we're concerned with specific Loading @@ -227,17 +228,17 @@ connection_cpu_process_inbuf(connection_t *conn) static void static void cpuworker_main(void *data) cpuworker_main(void *data) { { char question[ONIONSKIN_CHALLENGE_LEN]; char question[TAP_ONIONSKIN_CHALLENGE_LEN]; uint8_t question_type; uint8_t question_type; tor_socket_t *fdarray = data; tor_socket_t *fdarray = data; tor_socket_t fd; tor_socket_t fd; /* variables for onion processing */ /* variables for onion processing */ char keys[CPATH_KEY_MATERIAL_LEN]; char keys[CPATH_KEY_MATERIAL_LEN]; char reply_to_proxy[ONIONSKIN_REPLY_LEN]; char reply_to_proxy[MAX_ONIONSKIN_REPLY_LEN]; char buf[LEN_ONION_RESPONSE]; char buf[LEN_ONION_RESPONSE]; char tag[TAG_LEN]; char tag[TAG_LEN]; crypto_pk_t *onion_key = NULL, *last_onion_key = NULL; server_onion_keys_t onion_keys; fd = fdarray[1]; /* this side is ours */ fd = fdarray[1]; /* this side is ours */ #ifndef TOR_IS_MULTITHREADED #ifndef TOR_IS_MULTITHREADED Loading @@ -248,7 +249,7 @@ cpuworker_main(void *data) #endif #endif tor_free(data); tor_free(data); dup_onion_keys(&onion_key, &last_onion_key); setup_server_onion_keys(&onion_keys); for (;;) { for (;;) { ssize_t r; ssize_t r; Loading @@ -275,15 +276,18 @@ cpuworker_main(void *data) goto end; goto end; } } if (read_all(fd, question, ONIONSKIN_CHALLENGE_LEN, 1) != if (read_all(fd, question, TAP_ONIONSKIN_CHALLENGE_LEN, 1) != ONIONSKIN_CHALLENGE_LEN) { TAP_ONIONSKIN_CHALLENGE_LEN) { log_err(LD_BUG,"read question failed. Exiting."); log_err(LD_BUG,"read question failed. Exiting."); goto end; goto end; } } if (question_type == CPUWORKER_TASK_ONION) { if (question_type == CPUWORKER_TASK_ONION) { if (onion_skin_server_handshake(question, onion_key, last_onion_key, if (onion_skin_server_handshake(ONION_HANDSHAKE_TYPE_TAP, reply_to_proxy, keys, CPATH_KEY_MATERIAL_LEN) < 0) { (const uint8_t*)question, &onion_keys, (uint8_t*)reply_to_proxy, (uint8_t*)keys, CPATH_KEY_MATERIAL_LEN) < 0) { /* failure */ /* failure */ log_debug(LD_OR,"onion_skin_server_handshake failed."); log_debug(LD_OR,"onion_skin_server_handshake failed."); *buf = 0; /* indicate failure in first byte */ *buf = 0; /* indicate failure in first byte */ Loading @@ -295,8 +299,9 @@ cpuworker_main(void *data) log_debug(LD_OR,"onion_skin_server_handshake succeeded."); log_debug(LD_OR,"onion_skin_server_handshake succeeded."); buf[0] = 1; /* 1 means success */ buf[0] = 1; /* 1 means success */ memcpy(buf+1,tag,TAG_LEN); memcpy(buf+1,tag,TAG_LEN); memcpy(buf+1+TAG_LEN,reply_to_proxy,ONIONSKIN_REPLY_LEN); memcpy(buf+1+TAG_LEN,reply_to_proxy,TAP_ONIONSKIN_REPLY_LEN); memcpy(buf+1+TAG_LEN+ONIONSKIN_REPLY_LEN,keys,CPATH_KEY_MATERIAL_LEN); memcpy(buf+1+TAG_LEN+TAP_ONIONSKIN_REPLY_LEN,keys, CPATH_KEY_MATERIAL_LEN); } } if (write_all(fd, buf, LEN_ONION_RESPONSE, 1) != LEN_ONION_RESPONSE) { if (write_all(fd, buf, LEN_ONION_RESPONSE, 1) != LEN_ONION_RESPONSE) { log_err(LD_BUG,"writing response buf failed. Exiting."); log_err(LD_BUG,"writing response buf failed. Exiting."); Loading @@ -306,10 +311,7 @@ cpuworker_main(void *data) } } } } end: end: if (onion_key) release_server_onion_keys(&onion_keys); crypto_pk_free(onion_key); if (last_onion_key) crypto_pk_free(last_onion_key); tor_close_socket(fd); tor_close_socket(fd); crypto_thread_cleanup(); crypto_thread_cleanup(); spawn_exit(); spawn_exit(); Loading Loading @@ -497,7 +499,7 @@ assign_onionskin_to_cpuworker(connection_t *cpuworker, qbuf[0] = CPUWORKER_TASK_ONION; qbuf[0] = CPUWORKER_TASK_ONION; connection_write_to_buf(qbuf, 1, cpuworker); connection_write_to_buf(qbuf, 1, cpuworker); connection_write_to_buf(tag, sizeof(tag), cpuworker); connection_write_to_buf(tag, sizeof(tag), cpuworker); connection_write_to_buf(onionskin, ONIONSKIN_CHALLENGE_LEN, cpuworker); connection_write_to_buf(onionskin, TAP_ONIONSKIN_CHALLENGE_LEN, cpuworker); tor_free(onionskin); tor_free(onionskin); } } return 0; return 0; Loading Loading
src/or/circuitbuild.c +68 −54 Original line number Original line Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include "main.h" #include "main.h" #include "networkstatus.h" #include "networkstatus.h" #include "nodelist.h" #include "nodelist.h" #include "onion.h" #include "onion_tap.h" #include "onion_tap.h" #include "onion_fast.h" #include "onion_fast.h" #include "policies.h" #include "policies.h" Loading Loading @@ -54,7 +55,9 @@ static channel_t * channel_connect_for_circuit(const tor_addr_t *addr, uint16_t port, uint16_t port, const char *id_digest); const char *id_digest); static int circuit_deliver_create_cell(circuit_t *circ, static int circuit_deliver_create_cell(circuit_t *circ, uint8_t cell_type, const char *payload); uint8_t cell_type, const uint8_t *payload, size_t payload_len); static int onion_pick_cpath_exit(origin_circuit_t *circ, extend_info_t *exit); static int onion_pick_cpath_exit(origin_circuit_t *circ, extend_info_t *exit); static crypt_path_t *onion_next_hop_in_cpath(crypt_path_t *cpath); static crypt_path_t *onion_next_hop_in_cpath(crypt_path_t *cpath); static int onion_extend_cpath(origin_circuit_t *circ); static int onion_extend_cpath(origin_circuit_t *circ); Loading Loading @@ -474,7 +477,8 @@ circuit_n_chan_done(channel_t *chan, int status) /* pull the create cell out of circ->onionskin, and send it */ /* pull the create cell out of circ->onionskin, and send it */ tor_assert(circ->n_chan_onionskin); tor_assert(circ->n_chan_onionskin); if (circuit_deliver_create_cell(circ,CELL_CREATE, if (circuit_deliver_create_cell(circ,CELL_CREATE, circ->n_chan_onionskin)<0) { (const uint8_t*)circ->n_chan_onionskin, circ->n_chan_onionskin_len)<0) { circuit_mark_for_close(circ, END_CIRC_REASON_RESOURCELIMIT); circuit_mark_for_close(circ, END_CIRC_REASON_RESOURCELIMIT); continue; continue; } } Loading @@ -491,12 +495,12 @@ circuit_n_chan_done(channel_t *chan, int status) * for the outgoing * for the outgoing * circuit <b>circ</b>, and deliver a cell of type <b>cell_type</b> * circuit <b>circ</b>, and deliver a cell of type <b>cell_type</b> * (either CELL_CREATE or CELL_CREATE_FAST) with payload <b>payload</b> * (either CELL_CREATE or CELL_CREATE_FAST) with payload <b>payload</b> * to this circuit. * to this circuit. DOCDOC payload_len * Return -1 if we failed to find a suitable circid, else return 0. * Return -1 if we failed to find a suitable circid, else return 0. */ */ static int static int circuit_deliver_create_cell(circuit_t *circ, uint8_t cell_type, circuit_deliver_create_cell(circuit_t *circ, uint8_t cell_type, const char *payload) const uint8_t *payload, size_t payload_len) { { cell_t cell; cell_t cell; circid_t id; circid_t id; Loading @@ -518,7 +522,7 @@ circuit_deliver_create_cell(circuit_t *circ, uint8_t cell_type, cell.command = cell_type; cell.command = cell_type; cell.circ_id = circ->n_circ_id; cell.circ_id = circ->n_circ_id; memcpy(cell.payload, payload, ONIONSKIN_CHALLENGE_LEN); memcpy(cell.payload, payload, payload_len); append_cell_to_circuit_queue(circ, circ->n_chan, &cell, append_cell_to_circuit_queue(circ, circ->n_chan, &cell, CELL_DIRECTION_OUT, 0); CELL_DIRECTION_OUT, 0); Loading Loading @@ -611,8 +615,10 @@ circuit_send_next_onion_skin(origin_circuit_t *circ) { { crypt_path_t *hop; crypt_path_t *hop; const node_t *node; const node_t *node; char payload[2+4+DIGEST_LEN+ONIONSKIN_CHALLENGE_LEN]; uint8_t payload[2+4+DIGEST_LEN+MAX_ONIONSKIN_CHALLENGE_LEN]; char *onionskin; uint8_t *onionskin; uint16_t handshake_type; int onionskin_len; size_t payload_len; size_t payload_len; tor_assert(circ); tor_assert(circ); Loading @@ -633,30 +639,29 @@ circuit_send_next_onion_skin(origin_circuit_t *circ) * send an old slow create cell. * send an old slow create cell. */ */ cell_type = CELL_CREATE; cell_type = CELL_CREATE; if (onion_skin_create(circ->cpath->extend_info->onion_key, handshake_type = ONION_HANDSHAKE_TYPE_TAP; &(circ->cpath->dh_handshake_state), payload) < 0) { log_warn(LD_CIRC,"onion_skin_create (first hop) failed."); return - END_CIRC_REASON_INTERNAL; } note_request("cell: create", 1); note_request("cell: create", 1); } else { } else { /* We are not an OR, and we're building the first hop of a circuit to a /* We are not an OR, and we're building the first hop of a circuit to a * new OR: we can be speedy and use CREATE_FAST to save an RSA operation * new OR: we can be speedy and use CREATE_FAST to save an RSA operation * and a DH operation. */ * and a DH operation. */ cell_type = CELL_CREATE_FAST; cell_type = CELL_CREATE_FAST; handshake_type = ONION_HANDSHAKE_TYPE_FAST; note_request("cell: create fast", 1); } memset(payload, 0, sizeof(payload)); memset(payload, 0, sizeof(payload)); if (fast_onionskin_create(&circ->cpath->fast_handshake_state, onionskin_len = onion_skin_create(handshake_type, (uint8_t *)payload) < 0) { circ->cpath->extend_info, log_warn(LD_CIRC,"onion_skin_create FAST (first hop) failed."); &circ->cpath->handshake_state, payload); if (onionskin_len < 0) { log_warn(LD_CIRC,"onion_skin_create (first hop) failed."); return - END_CIRC_REASON_INTERNAL; return - END_CIRC_REASON_INTERNAL; } } note_request("cell: create fast", 1); if (circuit_deliver_create_cell(TO_CIRCUIT(circ), cell_type, payload, } onionskin_len) < 0) if (circuit_deliver_create_cell(TO_CIRCUIT(circ), cell_type, payload) < 0) return - END_CIRC_REASON_RESOURCELIMIT; return - END_CIRC_REASON_RESOURCELIMIT; circ->cpath->state = CPATH_STATE_AWAITING_KEYS; circ->cpath->state = CPATH_STATE_AWAITING_KEYS; Loading Loading @@ -742,12 +747,16 @@ circuit_send_next_onion_skin(origin_circuit_t *circ) set_uint16(payload+4, htons(hop->extend_info->port)); set_uint16(payload+4, htons(hop->extend_info->port)); onionskin = payload+2+4; onionskin = payload+2+4; memcpy(payload+2+4+ONIONSKIN_CHALLENGE_LEN, memcpy(payload+2+4+TAP_ONIONSKIN_CHALLENGE_LEN, hop->extend_info->identity_digest, DIGEST_LEN); hop->extend_info->identity_digest, DIGEST_LEN); payload_len = 2+4+ONIONSKIN_CHALLENGE_LEN+DIGEST_LEN; payload_len = 2+4+TAP_ONIONSKIN_CHALLENGE_LEN+DIGEST_LEN; if (onion_skin_create(hop->extend_info->onion_key, handshake_type = ONION_HANDSHAKE_TYPE_TAP; &(hop->dh_handshake_state), onionskin) < 0) { if (onion_skin_create(handshake_type, hop->extend_info, &hop->handshake_state, onionskin) < 0) { log_warn(LD_CIRC,"onion_skin_create failed."); log_warn(LD_CIRC,"onion_skin_create failed."); return - END_CIRC_REASON_INTERNAL; return - END_CIRC_REASON_INTERNAL; } } Loading @@ -758,7 +767,8 @@ circuit_send_next_onion_skin(origin_circuit_t *circ) * it to a create cell and then send to hop */ * it to a create cell and then send to hop */ if (relay_send_command_from_edge(0, TO_CIRCUIT(circ), if (relay_send_command_from_edge(0, TO_CIRCUIT(circ), RELAY_COMMAND_EXTEND, RELAY_COMMAND_EXTEND, payload, payload_len, hop->prev) < 0) (char*)payload, payload_len, hop->prev) < 0) return 0; /* circuit is closed */ return 0; /* circuit is closed */ hop->state = CPATH_STATE_AWAITING_KEYS; hop->state = CPATH_STATE_AWAITING_KEYS; Loading Loading @@ -826,7 +836,7 @@ circuit_extend(cell_t *cell, circuit_t *circ) relay_header_unpack(&rh, cell->payload); relay_header_unpack(&rh, cell->payload); if (rh.length < 4+2+ONIONSKIN_CHALLENGE_LEN+DIGEST_LEN) { if (rh.length < 4+2+TAP_ONIONSKIN_CHALLENGE_LEN+DIGEST_LEN) { log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, "Wrong length %d on extend cell. Closing circuit.", "Wrong length %d on extend cell. Closing circuit.", rh.length); rh.length); Loading @@ -837,7 +847,7 @@ circuit_extend(cell_t *cell, circuit_t *circ) n_port = ntohs(get_uint16(cell->payload+RELAY_HEADER_SIZE+4)); n_port = ntohs(get_uint16(cell->payload+RELAY_HEADER_SIZE+4)); onionskin = (char*) cell->payload+RELAY_HEADER_SIZE+4+2; onionskin = (char*) cell->payload+RELAY_HEADER_SIZE+4+2; id_digest = (char*) cell->payload+RELAY_HEADER_SIZE+4+2+ id_digest = (char*) cell->payload+RELAY_HEADER_SIZE+4+2+ ONIONSKIN_CHALLENGE_LEN; TAP_ONIONSKIN_CHALLENGE_LEN; tor_addr_from_ipv4h(&n_addr, n_addr32); tor_addr_from_ipv4h(&n_addr, n_addr32); if (!n_port || !n_addr32) { if (!n_port || !n_addr32) { Loading Loading @@ -890,8 +900,10 @@ circuit_extend(cell_t *cell, circuit_t *circ) NULL /*onion_key*/, NULL /*onion_key*/, &n_addr, n_port); &n_addr, n_port); circ->n_chan_onionskin = tor_malloc(ONIONSKIN_CHALLENGE_LEN); circ->n_chan_onionskin = tor_malloc(TAP_ONIONSKIN_CHALLENGE_LEN); memcpy(circ->n_chan_onionskin, onionskin, ONIONSKIN_CHALLENGE_LEN); memcpy(circ->n_chan_onionskin, onionskin, TAP_ONIONSKIN_CHALLENGE_LEN); circ->n_chan_onionskin_len = TAP_ONIONSKIN_CHALLENGE_LEN; circuit_set_state(circ, CIRCUIT_STATE_CHAN_WAIT); circuit_set_state(circ, CIRCUIT_STATE_CHAN_WAIT); if (should_launch) { if (should_launch) { Loading @@ -917,7 +929,8 @@ circuit_extend(cell_t *cell, circuit_t *circ) "n_chan is %s", "n_chan is %s", channel_get_canonical_remote_descr(n_chan)); channel_get_canonical_remote_descr(n_chan)); if (circuit_deliver_create_cell(circ, CELL_CREATE, onionskin) < 0) if (circuit_deliver_create_cell(circ, CELL_CREATE, (uint8_t*)onionskin, TAP_ONIONSKIN_CHALLENGE_LEN) < 0) return -1; return -1; return 0; return 0; } } Loading Loading @@ -1377,31 +1390,32 @@ circuit_finish_handshake(origin_circuit_t *circ, uint8_t reply_type, } } tor_assert(hop->state == CPATH_STATE_AWAITING_KEYS); tor_assert(hop->state == CPATH_STATE_AWAITING_KEYS); if (reply_type == CELL_CREATED && hop->dh_handshake_state) { { if (onion_skin_client_handshake(hop->dh_handshake_state, (char*)reply,keys, uint16_t handshake_type = 0xffff; DIGEST_LEN*2+CIPHER_KEY_LEN*2) < 0) { if (reply_type == CELL_CREATED) log_warn(LD_CIRC,"onion_skin_client_handshake failed."); handshake_type = ONION_HANDSHAKE_TYPE_TAP; else if (reply_type == CELL_CREATED_FAST) handshake_type = ONION_HANDSHAKE_TYPE_FAST; if (handshake_type != hop->handshake_state.tag) { log_warn(LD_PROTOCOL,"CREATED cell onionskin type (%u) did not " "match CREATE cell onionskin type (%u).", (unsigned)handshake_type, (unsigned) hop->handshake_state.tag); return -END_CIRC_REASON_TORPROTOCOL; return -END_CIRC_REASON_TORPROTOCOL; } } /* Remember hash of g^xy */ memcpy(hop->handshake_digest, reply+DH_KEY_LEN, DIGEST_LEN); if (onion_skin_client_handshake(handshake_type, } else if (reply_type == CELL_CREATED_FAST && !hop->dh_handshake_state) { &hop->handshake_state, if (fast_client_handshake(hop->fast_handshake_state, reply, reply, (uint8_t*)keys, (uint8_t*)keys, sizeof(keys), DIGEST_LEN*2+CIPHER_KEY_LEN*2) < 0) { (uint8_t*)hop->handshake_digest) < 0) { log_warn(LD_CIRC,"fast_client_handshake failed."); log_warn(LD_CIRC,"onion_skin_client_handshake failed."); return -END_CIRC_REASON_TORPROTOCOL; return -END_CIRC_REASON_TORPROTOCOL; } } memcpy(hop->handshake_digest, reply+DIGEST_LEN, DIGEST_LEN); } else { log_warn(LD_PROTOCOL,"CREATED cell type did not match CREATE cell type."); return -END_CIRC_REASON_TORPROTOCOL; } } crypto_dh_free(hop->dh_handshake_state); /* don't need it anymore */ onion_handshake_state_release(&hop->handshake_state); hop->dh_handshake_state = NULL; memset(hop->fast_handshake_state, 0, sizeof(hop->fast_handshake_state)); if (circuit_init_cpath_crypto(hop, keys, 0)<0) { if (circuit_init_cpath_crypto(hop, keys, 0)<0) { return -END_CIRC_REASON_TORPROTOCOL; return -END_CIRC_REASON_TORPROTOCOL; Loading Loading @@ -1470,7 +1484,7 @@ circuit_truncated(origin_circuit_t *circ, crypt_path_t *layer, int reason) */ */ int int onionskin_answer(or_circuit_t *circ, uint8_t cell_type, const char *payload, onionskin_answer(or_circuit_t *circ, uint8_t cell_type, const char *payload, const char *keys) size_t payload_len, const char *keys) { { cell_t cell; cell_t cell; crypt_path_t *tmp_cpath; crypt_path_t *tmp_cpath; Loading @@ -1484,8 +1498,7 @@ onionskin_answer(or_circuit_t *circ, uint8_t cell_type, const char *payload, circuit_set_state(TO_CIRCUIT(circ), CIRCUIT_STATE_OPEN); circuit_set_state(TO_CIRCUIT(circ), CIRCUIT_STATE_OPEN); memcpy(cell.payload, payload, memcpy(cell.payload, payload, payload_len); cell_type == CELL_CREATED ? ONIONSKIN_REPLY_LEN : DIGEST_LEN*2); log_debug(LD_CIRC,"init digest forward 0x%.8x, backward 0x%.8x.", log_debug(LD_CIRC,"init digest forward 0x%.8x, backward 0x%.8x.", (unsigned int)get_uint32(keys), (unsigned int)get_uint32(keys), Loading @@ -1502,6 +1515,7 @@ onionskin_answer(or_circuit_t *circ, uint8_t cell_type, const char *payload, tmp_cpath->magic = 0; tmp_cpath->magic = 0; tor_free(tmp_cpath); tor_free(tmp_cpath); /* XXXX Move responsibility for extracting this. */ if (cell_type == CELL_CREATED) if (cell_type == CELL_CREATED) memcpy(circ->handshake_digest, cell.payload+DH_KEY_LEN, DIGEST_LEN); memcpy(circ->handshake_digest, cell.payload+DH_KEY_LEN, DIGEST_LEN); else else Loading
src/or/circuitbuild.h +2 −1 Original line number Original line Diff line number Diff line Loading @@ -35,7 +35,8 @@ int circuit_finish_handshake(origin_circuit_t *circ, uint8_t cell_type, int circuit_truncated(origin_circuit_t *circ, crypt_path_t *layer, int circuit_truncated(origin_circuit_t *circ, crypt_path_t *layer, int reason); int reason); int onionskin_answer(or_circuit_t *circ, uint8_t cell_type, int onionskin_answer(or_circuit_t *circ, uint8_t cell_type, const char *payload, const char *keys); const char *payload, size_t payload_len, const char *keys); int circuit_all_predicted_ports_handled(time_t now, int *need_uptime, int circuit_all_predicted_ports_handled(time_t now, int *need_uptime, int *need_capacity); int *need_capacity); Loading
src/or/circuitlist.c +4 −3 Original line number Original line Diff line number Diff line Loading @@ -744,8 +744,8 @@ circuit_free_cpath_node(crypt_path_t *victim) crypto_cipher_free(victim->b_crypto); crypto_cipher_free(victim->b_crypto); crypto_digest_free(victim->f_digest); crypto_digest_free(victim->f_digest); crypto_digest_free(victim->b_digest); crypto_digest_free(victim->b_digest); crypto_dh_free(victim->dh_handshake_state); onion_handshake_state_release(&victim->handshake_state); fast_handshake_state_free(victim->fast_handshake_state); crypto_dh_free(victim->rend_dh_handshake_state); extend_info_free(victim->extend_info); extend_info_free(victim->extend_info); memwipe(victim, 0xBB, sizeof(crypt_path_t)); /* poison memory */ memwipe(victim, 0xBB, sizeof(crypt_path_t)); /* poison memory */ Loading Loading @@ -1494,7 +1494,8 @@ assert_cpath_layer_ok(const crypt_path_t *cp) tor_assert(cp->b_crypto); tor_assert(cp->b_crypto); /* fall through */ /* fall through */ case CPATH_STATE_CLOSED: case CPATH_STATE_CLOSED: tor_assert(!cp->dh_handshake_state); /*XXXX Assert that there's no handshake_state either. */ tor_assert(!cp->rend_dh_handshake_state); break; break; case CPATH_STATE_AWAITING_KEYS: case CPATH_STATE_AWAITING_KEYS: /* tor_assert(cp->dh_handshake_state); */ /* tor_assert(cp->dh_handshake_state); */ Loading
src/or/command.c +6 −4 Original line number Original line Diff line number Diff line Loading @@ -30,6 +30,7 @@ #include "hibernate.h" #include "hibernate.h" #include "nodelist.h" #include "nodelist.h" //#include "onion.h" //#include "onion.h" #include "onion_tap.h" #include "onion_fast.h" #include "onion_fast.h" #include "relay.h" #include "relay.h" #include "router.h" #include "router.h" Loading Loading @@ -254,8 +255,8 @@ command_process_create_cell(cell_t *cell, channel_t *chan) circ->base_.purpose = CIRCUIT_PURPOSE_OR; circ->base_.purpose = CIRCUIT_PURPOSE_OR; circuit_set_state(TO_CIRCUIT(circ), CIRCUIT_STATE_ONIONSKIN_PENDING); circuit_set_state(TO_CIRCUIT(circ), CIRCUIT_STATE_ONIONSKIN_PENDING); if (cell->command == CELL_CREATE) { if (cell->command == CELL_CREATE) { char *onionskin = tor_malloc(ONIONSKIN_CHALLENGE_LEN); char *onionskin = tor_malloc(TAP_ONIONSKIN_CHALLENGE_LEN); memcpy(onionskin, cell->payload, ONIONSKIN_CHALLENGE_LEN); memcpy(onionskin, cell->payload, TAP_ONIONSKIN_CHALLENGE_LEN); /* hand it off to the cpuworkers, and then return. */ /* hand it off to the cpuworkers, and then return. */ if (assign_onionskin_to_cpuworker(NULL, circ, onionskin) < 0) { if (assign_onionskin_to_cpuworker(NULL, circ, onionskin) < 0) { Loading @@ -282,7 +283,8 @@ command_process_create_cell(cell_t *cell, channel_t *chan) circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_INTERNAL); circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_INTERNAL); return; return; } } if (onionskin_answer(circ, CELL_CREATED_FAST, reply, keys)<0) { if (onionskin_answer(circ, CELL_CREATED_FAST, reply, sizeof(reply), keys)<0) { log_warn(LD_OR,"Failed to reply to CREATE_FAST cell. Closing."); log_warn(LD_OR,"Failed to reply to CREATE_FAST cell. Closing."); circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_INTERNAL); circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_INTERNAL); return; return; Loading Loading @@ -340,7 +342,7 @@ command_process_created_cell(cell_t *cell, channel_t *chan) log_debug(LD_OR, log_debug(LD_OR, "Converting created cell to extended relay cell, sending."); "Converting created cell to extended relay cell, sending."); relay_send_command_from_edge(0, circ, RELAY_COMMAND_EXTENDED, relay_send_command_from_edge(0, circ, RELAY_COMMAND_EXTENDED, (char*)cell->payload, ONIONSKIN_REPLY_LEN, (char*)cell->payload, TAP_ONIONSKIN_REPLY_LEN, NULL); NULL); } } } } Loading
src/or/cpuworker.c +21 −19 Original line number Original line Diff line number Diff line Loading @@ -35,7 +35,7 @@ #define TAG_LEN 10 #define TAG_LEN 10 /** How many bytes are sent from the cpuworker back to tor? */ /** How many bytes are sent from the cpuworker back to tor? */ #define LEN_ONION_RESPONSE \ #define LEN_ONION_RESPONSE \ (1+TAG_LEN+ONIONSKIN_REPLY_LEN+CPATH_KEY_MATERIAL_LEN) (1+TAG_LEN+TAP_ONIONSKIN_REPLY_LEN+CPATH_KEY_MATERIAL_LEN) /** How many cpuworkers we have running right now. */ /** How many cpuworkers we have running right now. */ static int num_cpuworkers=0; static int num_cpuworkers=0; Loading Loading @@ -185,7 +185,8 @@ connection_cpu_process_inbuf(connection_t *conn) } } tor_assert(! CIRCUIT_IS_ORIGIN(circ)); tor_assert(! CIRCUIT_IS_ORIGIN(circ)); if (onionskin_answer(TO_OR_CIRCUIT(circ), CELL_CREATED, buf+TAG_LEN, if (onionskin_answer(TO_OR_CIRCUIT(circ), CELL_CREATED, buf+TAG_LEN, buf+TAG_LEN+ONIONSKIN_REPLY_LEN) < 0) { TAP_ONIONSKIN_REPLY_LEN, buf+TAG_LEN+TAP_ONIONSKIN_REPLY_LEN) < 0) { log_warn(LD_OR,"onionskin_answer failed. Closing."); log_warn(LD_OR,"onionskin_answer failed. Closing."); circuit_mark_for_close(circ, END_CIRC_REASON_INTERNAL); circuit_mark_for_close(circ, END_CIRC_REASON_INTERNAL); goto done_processing; goto done_processing; Loading Loading @@ -214,11 +215,11 @@ connection_cpu_process_inbuf(connection_t *conn) * Request format: * Request format: * Task type [1 byte, always CPUWORKER_TASK_ONION] * Task type [1 byte, always CPUWORKER_TASK_ONION] * Opaque tag TAG_LEN * Opaque tag TAG_LEN * Onionskin challenge ONIONSKIN_CHALLENGE_LEN * Onionskin challenge TAP_ONIONSKIN_CHALLENGE_LEN * Response format: * Response format: * Success/failure [1 byte, boolean.] * Success/failure [1 byte, boolean.] * Opaque tag TAG_LEN * Opaque tag TAG_LEN * Onionskin challenge ONIONSKIN_REPLY_LEN * Onionskin challenge TAP_ONIONSKIN_REPLY_LEN * Negotiated keys KEY_LEN*2+DIGEST_LEN*2 * Negotiated keys KEY_LEN*2+DIGEST_LEN*2 * * * (Note: this _should_ be by addr/port, since we're concerned with specific * (Note: this _should_ be by addr/port, since we're concerned with specific Loading @@ -227,17 +228,17 @@ connection_cpu_process_inbuf(connection_t *conn) static void static void cpuworker_main(void *data) cpuworker_main(void *data) { { char question[ONIONSKIN_CHALLENGE_LEN]; char question[TAP_ONIONSKIN_CHALLENGE_LEN]; uint8_t question_type; uint8_t question_type; tor_socket_t *fdarray = data; tor_socket_t *fdarray = data; tor_socket_t fd; tor_socket_t fd; /* variables for onion processing */ /* variables for onion processing */ char keys[CPATH_KEY_MATERIAL_LEN]; char keys[CPATH_KEY_MATERIAL_LEN]; char reply_to_proxy[ONIONSKIN_REPLY_LEN]; char reply_to_proxy[MAX_ONIONSKIN_REPLY_LEN]; char buf[LEN_ONION_RESPONSE]; char buf[LEN_ONION_RESPONSE]; char tag[TAG_LEN]; char tag[TAG_LEN]; crypto_pk_t *onion_key = NULL, *last_onion_key = NULL; server_onion_keys_t onion_keys; fd = fdarray[1]; /* this side is ours */ fd = fdarray[1]; /* this side is ours */ #ifndef TOR_IS_MULTITHREADED #ifndef TOR_IS_MULTITHREADED Loading @@ -248,7 +249,7 @@ cpuworker_main(void *data) #endif #endif tor_free(data); tor_free(data); dup_onion_keys(&onion_key, &last_onion_key); setup_server_onion_keys(&onion_keys); for (;;) { for (;;) { ssize_t r; ssize_t r; Loading @@ -275,15 +276,18 @@ cpuworker_main(void *data) goto end; goto end; } } if (read_all(fd, question, ONIONSKIN_CHALLENGE_LEN, 1) != if (read_all(fd, question, TAP_ONIONSKIN_CHALLENGE_LEN, 1) != ONIONSKIN_CHALLENGE_LEN) { TAP_ONIONSKIN_CHALLENGE_LEN) { log_err(LD_BUG,"read question failed. Exiting."); log_err(LD_BUG,"read question failed. Exiting."); goto end; goto end; } } if (question_type == CPUWORKER_TASK_ONION) { if (question_type == CPUWORKER_TASK_ONION) { if (onion_skin_server_handshake(question, onion_key, last_onion_key, if (onion_skin_server_handshake(ONION_HANDSHAKE_TYPE_TAP, reply_to_proxy, keys, CPATH_KEY_MATERIAL_LEN) < 0) { (const uint8_t*)question, &onion_keys, (uint8_t*)reply_to_proxy, (uint8_t*)keys, CPATH_KEY_MATERIAL_LEN) < 0) { /* failure */ /* failure */ log_debug(LD_OR,"onion_skin_server_handshake failed."); log_debug(LD_OR,"onion_skin_server_handshake failed."); *buf = 0; /* indicate failure in first byte */ *buf = 0; /* indicate failure in first byte */ Loading @@ -295,8 +299,9 @@ cpuworker_main(void *data) log_debug(LD_OR,"onion_skin_server_handshake succeeded."); log_debug(LD_OR,"onion_skin_server_handshake succeeded."); buf[0] = 1; /* 1 means success */ buf[0] = 1; /* 1 means success */ memcpy(buf+1,tag,TAG_LEN); memcpy(buf+1,tag,TAG_LEN); memcpy(buf+1+TAG_LEN,reply_to_proxy,ONIONSKIN_REPLY_LEN); memcpy(buf+1+TAG_LEN,reply_to_proxy,TAP_ONIONSKIN_REPLY_LEN); memcpy(buf+1+TAG_LEN+ONIONSKIN_REPLY_LEN,keys,CPATH_KEY_MATERIAL_LEN); memcpy(buf+1+TAG_LEN+TAP_ONIONSKIN_REPLY_LEN,keys, CPATH_KEY_MATERIAL_LEN); } } if (write_all(fd, buf, LEN_ONION_RESPONSE, 1) != LEN_ONION_RESPONSE) { if (write_all(fd, buf, LEN_ONION_RESPONSE, 1) != LEN_ONION_RESPONSE) { log_err(LD_BUG,"writing response buf failed. Exiting."); log_err(LD_BUG,"writing response buf failed. Exiting."); Loading @@ -306,10 +311,7 @@ cpuworker_main(void *data) } } } } end: end: if (onion_key) release_server_onion_keys(&onion_keys); crypto_pk_free(onion_key); if (last_onion_key) crypto_pk_free(last_onion_key); tor_close_socket(fd); tor_close_socket(fd); crypto_thread_cleanup(); crypto_thread_cleanup(); spawn_exit(); spawn_exit(); Loading Loading @@ -497,7 +499,7 @@ assign_onionskin_to_cpuworker(connection_t *cpuworker, qbuf[0] = CPUWORKER_TASK_ONION; qbuf[0] = CPUWORKER_TASK_ONION; connection_write_to_buf(qbuf, 1, cpuworker); connection_write_to_buf(qbuf, 1, cpuworker); connection_write_to_buf(tag, sizeof(tag), cpuworker); connection_write_to_buf(tag, sizeof(tag), cpuworker); connection_write_to_buf(onionskin, ONIONSKIN_CHALLENGE_LEN, cpuworker); connection_write_to_buf(onionskin, TAP_ONIONSKIN_CHALLENGE_LEN, cpuworker); tor_free(onionskin); tor_free(onionskin); } } return 0; return 0; Loading