Merge branch 'bug23019_squashed'

This commit is contained in:
Nick Mathewson 2017-09-14 09:13:28 -04:00
commit fde18fed60
4 changed files with 35 additions and 17 deletions

View File

@ -918,22 +918,31 @@ hs_address_is_valid(const char *address)
uint8_t version; uint8_t version;
uint8_t checksum[HS_SERVICE_ADDR_CHECKSUM_LEN_USED]; uint8_t checksum[HS_SERVICE_ADDR_CHECKSUM_LEN_USED];
uint8_t target_checksum[DIGEST256_LEN]; uint8_t target_checksum[DIGEST256_LEN];
ed25519_public_key_t key; ed25519_public_key_t service_pubkey;
/* Parse the decoded address into the fields we need. */ /* Parse the decoded address into the fields we need. */
if (hs_parse_address(address, &key, checksum, &version) < 0) { if (hs_parse_address(address, &service_pubkey, checksum, &version) < 0) {
goto invalid; goto invalid;
} }
/* Get the checksum it's suppose to be and compare it with what we have /* Get the checksum it's suppose to be and compare it with what we have
* encoded in the address. */ * encoded in the address. */
build_hs_checksum(&key, version, target_checksum); build_hs_checksum(&service_pubkey, version, target_checksum);
if (tor_memcmp(checksum, target_checksum, sizeof(checksum))) { if (tor_memcmp(checksum, target_checksum, sizeof(checksum))) {
log_warn(LD_REND, "Service address %s invalid checksum.", log_warn(LD_REND, "Service address %s invalid checksum.",
escaped_safe_str(address)); escaped_safe_str(address));
goto invalid; goto invalid;
} }
/* Validate that this pubkey does not have a torsion component. We need to do
* this on the prop224 client-side so that attackers can't give equivalent
* forms of an onion address to users. */
if (ed25519_validate_pubkey(&service_pubkey) < 0) {
log_warn(LD_REND, "Service address %s has bad pubkey .",
escaped_safe_str(address));
goto invalid;
}
/* Valid address. */ /* Valid address. */
return 1; return 1;
invalid: invalid:

View File

@ -21,8 +21,9 @@ if TEST_VALUE != sha3.sha3_256(b"Hello World").hexdigest():
# Checksum is built like so: # Checksum is built like so:
# CHECKSUM = SHA3(".onion checksum" || PUBKEY || VERSION) # CHECKSUM = SHA3(".onion checksum" || PUBKEY || VERSION)
PREFIX = ".onion checksum".encode() PREFIX = ".onion checksum".encode()
# 32 bytes ed25519 pubkey. # 32 bytes ed25519 pubkey from first test vector of
PUBKEY = ("\x42" * 32).encode() # https://tools.ietf.org/html/draft-josefsson-eddsa-ed25519-02#section-6
PUBKEY = "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a".decode('hex')
# Version 3 is proposal224 # Version 3 is proposal224
VERSION = 3 VERSION = 3

View File

@ -801,7 +801,7 @@ test_entryconn_rewrite_onion_v3(void *arg)
/* Make a SOCKS request */ /* Make a SOCKS request */
conn->socks_request->command = SOCKS_COMMAND_CONNECT; conn->socks_request->command = SOCKS_COMMAND_CONNECT;
strlcpy(conn->socks_request->address, strlcpy(conn->socks_request->address,
"git.p3xnclpu4mu22dwaurjtsybyqk4xfjmcfz6z62yl24uwmhjatiwnlnad.onion", "git.25njqamcweflpvkl73j4szahhihoc4xt3ktcgjnpaingr5yhkenl5sid.onion",
sizeof(conn->socks_request->address)); sizeof(conn->socks_request->address));
/* Make an onion connection using the SOCKS request */ /* Make an onion connection using the SOCKS request */
@ -818,7 +818,7 @@ test_entryconn_rewrite_onion_v3(void *arg)
tt_int_op(ENTRY_TO_CONN(conn)->state, OP_EQ, AP_CONN_STATE_CIRCUIT_WAIT); tt_int_op(ENTRY_TO_CONN(conn)->state, OP_EQ, AP_CONN_STATE_CIRCUIT_WAIT);
/* check that the address got rewritten */ /* check that the address got rewritten */
tt_str_op(conn->socks_request->address, OP_EQ, tt_str_op(conn->socks_request->address, OP_EQ,
"p3xnclpu4mu22dwaurjtsybyqk4xfjmcfz6z62yl24uwmhjatiwnlnad"); "25njqamcweflpvkl73j4szahhihoc4xt3ktcgjnpaingr5yhkenl5sid");
/* check that HS information got attached to the connection */ /* check that HS information got attached to the connection */
tt_assert(ENTRY_TO_EDGE_CONN(conn)->hs_ident); tt_assert(ENTRY_TO_EDGE_CONN(conn)->hs_ident);
tt_assert(!ENTRY_TO_EDGE_CONN(conn)->rend_data); tt_assert(!ENTRY_TO_EDGE_CONN(conn)->rend_data);

View File

@ -77,7 +77,7 @@ test_validate_address(void *arg)
/* Valid address. */ /* Valid address. */
ret = hs_address_is_valid( ret = hs_address_is_valid(
"p3xnclpu4mu22dwaurjtsybyqk4xfjmcfz6z62yl24uwmhjatiwnlnad"); "25njqamcweflpvkl73j4szahhihoc4xt3ktcgjnpaingr5yhkenl5sid");
tt_int_op(ret, OP_EQ, 1); tt_int_op(ret, OP_EQ, 1);
done: done:
@ -90,19 +90,23 @@ mock_write_str_to_file(const char *path, const char *str, int bin)
(void)bin; (void)bin;
tt_str_op(path, OP_EQ, "/double/five"PATH_SEPARATOR"squared"); tt_str_op(path, OP_EQ, "/double/five"PATH_SEPARATOR"squared");
tt_str_op(str, OP_EQ, tt_str_op(str, OP_EQ,
"ijbeeqscijbeeqscijbeeqscijbeeqscijbeeqscijbeeqscijbezhid.onion\n"); "25njqamcweflpvkl73j4szahhihoc4xt3ktcgjnpaingr5yhkenl5sid.onion\n");
done: done:
return 0; return 0;
} }
/** Test building HS v3 onion addresses */ /** Test building HS v3 onion addresses. Uses test vectors from the
* ./hs_build_address.py script. */
static void static void
test_build_address(void *arg) test_build_address(void *arg)
{ {
int ret; int ret;
char onion_addr[HS_SERVICE_ADDR_LEN_BASE32 + 1]; char onion_addr[HS_SERVICE_ADDR_LEN_BASE32 + 1];
ed25519_public_key_t pubkey; ed25519_public_key_t pubkey;
/* hex-encoded ed25519 pubkey used in hs_build_address.py */
char pubkey_hex[] =
"d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a";
hs_service_t *service = NULL; hs_service_t *service = NULL;
(void) arg; (void) arg;
@ -112,11 +116,11 @@ test_build_address(void *arg)
/* The following has been created with hs_build_address.py script that /* The following has been created with hs_build_address.py script that
* follows proposal 224 specification to build an onion address. */ * follows proposal 224 specification to build an onion address. */
static const char *test_addr = static const char *test_addr =
"ijbeeqscijbeeqscijbeeqscijbeeqscijbeeqscijbeeqscijbezhid"; "25njqamcweflpvkl73j4szahhihoc4xt3ktcgjnpaingr5yhkenl5sid";
/* Let's try to build the same onion address that the script can do. Key is /* Let's try to build the same onion address as the script */
* a long set of very random \x42 :). */ base16_decode((char*)pubkey.pubkey, sizeof(pubkey.pubkey),
memset(&pubkey, '\x42', sizeof(pubkey)); pubkey_hex, strlen(pubkey_hex));
hs_build_address(&pubkey, HS_VERSION_THREE, onion_addr); hs_build_address(&pubkey, HS_VERSION_THREE, onion_addr);
tt_str_op(test_addr, OP_EQ, onion_addr); tt_str_op(test_addr, OP_EQ, onion_addr);
/* Validate that address. */ /* Validate that address. */
@ -474,9 +478,13 @@ test_desc_reupload_logic(void *arg)
/* Let's start by building our descriptor and service */ /* Let's start by building our descriptor and service */
hs_service_descriptor_t *desc = service_descriptor_new(); hs_service_descriptor_t *desc = service_descriptor_new();
hs_service_t *service = NULL; hs_service_t *service = NULL;
/* hex-encoded ed25519 pubkey used in hs_build_address.py */
char pubkey_hex[] =
"d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a";
char onion_addr[HS_SERVICE_ADDR_LEN_BASE32 + 1]; char onion_addr[HS_SERVICE_ADDR_LEN_BASE32 + 1];
ed25519_public_key_t pubkey; ed25519_public_key_t pubkey;
memset(&pubkey, '\x42', sizeof(pubkey)); base16_decode((char*)pubkey.pubkey, sizeof(pubkey.pubkey),
pubkey_hex, strlen(pubkey_hex));
hs_build_address(&pubkey, HS_VERSION_THREE, onion_addr); hs_build_address(&pubkey, HS_VERSION_THREE, onion_addr);
service = tor_malloc_zero(sizeof(hs_service_t)); service = tor_malloc_zero(sizeof(hs_service_t));
memcpy(service->onion_address, onion_addr, sizeof(service->onion_address)); memcpy(service->onion_address, onion_addr, sizeof(service->onion_address));
@ -758,7 +766,7 @@ test_parse_extended_hostname(void *arg)
char address6[] = "foo.bar.abcdefghijklmnop.onion"; char address6[] = "foo.bar.abcdefghijklmnop.onion";
char address7[] = ".abcdefghijklmnop.onion"; char address7[] = ".abcdefghijklmnop.onion";
char address8[] = char address8[] =
"www.p3xnclpu4mu22dwaurjtsybyqk4xfjmcfz6z62yl24uwmhjatiwnlnad.onion"; "www.25njqamcweflpvkl73j4szahhihoc4xt3ktcgjnpaingr5yhkenl5sid.onion";
tt_assert(BAD_HOSTNAME == parse_extended_hostname(address1)); tt_assert(BAD_HOSTNAME == parse_extended_hostname(address1));
tt_assert(ONION_V2_HOSTNAME == parse_extended_hostname(address2)); tt_assert(ONION_V2_HOSTNAME == parse_extended_hostname(address2));
@ -772,7 +780,7 @@ test_parse_extended_hostname(void *arg)
tt_assert(BAD_HOSTNAME == parse_extended_hostname(address7)); tt_assert(BAD_HOSTNAME == parse_extended_hostname(address7));
tt_assert(ONION_V3_HOSTNAME == parse_extended_hostname(address8)); tt_assert(ONION_V3_HOSTNAME == parse_extended_hostname(address8));
tt_str_op(address8, OP_EQ, tt_str_op(address8, OP_EQ,
"p3xnclpu4mu22dwaurjtsybyqk4xfjmcfz6z62yl24uwmhjatiwnlnad"); "25njqamcweflpvkl73j4szahhihoc4xt3ktcgjnpaingr5yhkenl5sid");
done: ; done: ;
} }