diff options
Diffstat (limited to 'src/or/onion.c')
-rw-r--r-- | src/or/onion.c | 67 |
1 files changed, 27 insertions, 40 deletions
diff --git a/src/or/onion.c b/src/or/onion.c index ae39f451f4..d6ef3673dd 100644 --- a/src/or/onion.c +++ b/src/or/onion.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2013, The Tor Project, Inc. */ + * Copyright (c) 2007-2016, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -111,15 +111,11 @@ have_room_for_onionskin(uint16_t type) (uint64_t)options->MaxOnionQueueDelay) return 0; -#ifdef CURVE25519_ENABLED /* If we support the ntor handshake, then don't let TAP handshakes use * more than 2/3 of the space on the queue. */ if (type == ONION_HANDSHAKE_TYPE_TAP && tap_usec / 1000 > (uint64_t)options->MaxOnionQueueDelay * 2 / 3) return 0; -#else - (void) type; -#endif return 1; } @@ -299,6 +295,8 @@ onion_pending_remove(or_circuit_t *circ) victim = circ->onionqueue_entry; if (victim) onion_queue_entry_remove(victim); + + cpuworker_cancel_circ_handshake(circ); } /** Remove a queue entry <b>victim</b> from the queue, unlinking it from @@ -343,38 +341,35 @@ clear_pending_onions(void) /* ============================================================ */ -/** Fill in a server_onion_keys_t object at <b>keys</b> with all of the keys +/** Return a new server_onion_keys_t object with all of the keys * and other info we might need to do onion handshakes. (We make a copy of * our keys for each cpuworker to avoid race conditions with the main thread, * and to avoid locking) */ -void -setup_server_onion_keys(server_onion_keys_t *keys) +server_onion_keys_t * +server_onion_keys_new(void) { - memset(keys, 0, sizeof(server_onion_keys_t)); + server_onion_keys_t *keys = tor_malloc_zero(sizeof(server_onion_keys_t)); memcpy(keys->my_identity, router_get_my_id_digest(), DIGEST_LEN); dup_onion_keys(&keys->onion_key, &keys->last_onion_key); -#ifdef CURVE25519_ENABLED keys->curve25519_key_map = construct_ntor_key_map(); keys->junk_keypair = tor_malloc_zero(sizeof(curve25519_keypair_t)); curve25519_keypair_generate(keys->junk_keypair, 0); -#endif + return keys; } -/** Release all storage held in <b>keys</b>, but do not free <b>keys</b> - * itself (as it's likely to be stack-allocated.) */ +/** Release all storage held in <b>keys</b>. */ void -release_server_onion_keys(server_onion_keys_t *keys) +server_onion_keys_free(server_onion_keys_t *keys) { if (! keys) return; crypto_pk_free(keys->onion_key); crypto_pk_free(keys->last_onion_key); -#ifdef CURVE25519_ENABLED ntor_key_map_free(keys->curve25519_key_map); tor_free(keys->junk_keypair); -#endif - memset(keys, 0, sizeof(server_onion_keys_t)); + memwipe(keys, 0, sizeof(server_onion_keys_t)); + tor_free(keys); } /** Release whatever storage is held in <b>state</b>, depending on its @@ -391,12 +386,10 @@ onion_handshake_state_release(onion_handshake_state_t *state) fast_handshake_state_free(state->u.fast); state->u.fast = NULL; break; -#ifdef CURVE25519_ENABLED case ONION_HANDSHAKE_TYPE_NTOR: ntor_handshake_state_free(state->u.ntor); state->u.ntor = NULL; break; -#endif default: log_warn(LD_BUG, "called with unknown handshake state type %d", (int)state->tag); @@ -436,7 +429,6 @@ onion_skin_create(int type, r = CREATE_FAST_LEN; break; case ONION_HANDSHAKE_TYPE_NTOR: -#ifdef CURVE25519_ENABLED if (tor_mem_is_zero((const char*)node->curve25519_onion_key.public_key, CURVE25519_PUBKEY_LEN)) return -1; @@ -447,9 +439,6 @@ onion_skin_create(int type, return -1; r = NTOR_ONIONSKIN_LEN; -#else - return -1; -#endif break; default: log_warn(LD_BUG, "called with unknown handshake state type %d", type); @@ -501,7 +490,6 @@ onion_skin_server_handshake(int type, memcpy(rend_nonce_out, reply_out+DIGEST_LEN, DIGEST_LEN); break; case ONION_HANDSHAKE_TYPE_NTOR: -#ifdef CURVE25519_ENABLED if (onionskin_len < NTOR_ONIONSKIN_LEN) return -1; { @@ -522,9 +510,6 @@ onion_skin_server_handshake(int type, tor_free(keys_tmp); r = NTOR_REPLY_LEN; } -#else - return -1; -#endif break; default: log_warn(LD_BUG, "called with unknown handshake state type %d", type); @@ -541,13 +526,15 @@ onion_skin_server_handshake(int type, * bytes worth of key material in <b>keys_out_len</b>, set * <b>rend_authenticator_out</b> to the "KH" field that can be used to * establish introduction points at this hop, and return 0. On failure, - * return -1. */ + * return -1, and set *msg_out to an error message if this is worth + * complaining to the usre about. */ int onion_skin_client_handshake(int type, const onion_handshake_state_t *handshake_state, const uint8_t *reply, size_t reply_len, uint8_t *keys_out, size_t keys_out_len, - uint8_t *rend_authenticator_out) + uint8_t *rend_authenticator_out, + const char **msg_out) { if (handshake_state->tag != type) return -1; @@ -555,12 +542,14 @@ onion_skin_client_handshake(int type, switch (type) { case ONION_HANDSHAKE_TYPE_TAP: if (reply_len != TAP_ONIONSKIN_REPLY_LEN) { - log_warn(LD_CIRC, "TAP reply was not of the correct length."); + if (msg_out) + *msg_out = "TAP reply was not of the correct length."; return -1; } if (onion_skin_TAP_client_handshake(handshake_state->u.tap, (const char*)reply, - (char *)keys_out, keys_out_len) < 0) + (char *)keys_out, keys_out_len, + msg_out) < 0) return -1; memcpy(rend_authenticator_out, reply+DH_KEY_LEN, DIGEST_LEN); @@ -568,27 +557,28 @@ onion_skin_client_handshake(int type, return 0; case ONION_HANDSHAKE_TYPE_FAST: if (reply_len != CREATED_FAST_LEN) { - log_warn(LD_CIRC, "CREATED_FAST reply was not of the correct length."); + if (msg_out) + *msg_out = "TAP reply was not of the correct length."; return -1; } if (fast_client_handshake(handshake_state->u.fast, reply, - keys_out, keys_out_len) < 0) + keys_out, keys_out_len, msg_out) < 0) return -1; memcpy(rend_authenticator_out, reply+DIGEST_LEN, DIGEST_LEN); return 0; -#ifdef CURVE25519_ENABLED case ONION_HANDSHAKE_TYPE_NTOR: if (reply_len < NTOR_REPLY_LEN) { - log_warn(LD_CIRC, "ntor reply was not of the correct length."); + if (msg_out) + *msg_out = "ntor reply was not of the correct length."; return -1; } { size_t keys_tmp_len = keys_out_len + DIGEST_LEN; uint8_t *keys_tmp = tor_malloc(keys_tmp_len); if (onion_skin_ntor_client_handshake(handshake_state->u.ntor, - reply, - keys_tmp, keys_tmp_len) < 0) { + reply, + keys_tmp, keys_tmp_len, msg_out) < 0) { tor_free(keys_tmp); return -1; } @@ -598,7 +588,6 @@ onion_skin_client_handshake(int type, tor_free(keys_tmp); } return 0; -#endif default: log_warn(LD_BUG, "called with unknown handshake state type %d", type); tor_fragile_assert(); @@ -637,12 +626,10 @@ check_create_cell(const create_cell_t *cell, int unknown_ok) if (cell->handshake_len != CREATE_FAST_LEN) return -1; break; -#ifdef CURVE25519_ENABLED case ONION_HANDSHAKE_TYPE_NTOR: if (cell->handshake_len != NTOR_ONIONSKIN_LEN) return -1; break; -#endif default: if (! unknown_ok) return -1; |