mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-10 13:13:44 +01:00
Merge branch 'tor-gitlab/mr/710'
This commit is contained in:
commit
0781c2968d
@ -155,7 +155,7 @@ static token_rule_t hs_desc_encrypted_v3_token_table[] = {
|
||||
T01(str_intro_auth_required, R3_INTRO_AUTH_REQUIRED, GE(1), NO_OBJ),
|
||||
T01(str_single_onion, R3_SINGLE_ONION_SERVICE, ARGS, NO_OBJ),
|
||||
T01(str_flow_control, R3_FLOW_CONTROL, GE(2), NO_OBJ),
|
||||
T01(str_pow_params, R3_POW_PARAMS, GE(3), NO_OBJ),
|
||||
T01(str_pow_params, R3_POW_PARAMS, GE(4), NO_OBJ),
|
||||
END_OF_TABLE
|
||||
};
|
||||
|
||||
@ -771,6 +771,13 @@ get_inner_encrypted_layer_plaintext(const hs_descriptor_t *desc)
|
||||
smartlist_add_asprintf(lines, "%s %d\n", str_create2_formats,
|
||||
ONION_HANDSHAKE_TYPE_NTOR);
|
||||
|
||||
#ifdef TOR_UNIT_TESTS
|
||||
if (desc->encrypted_data.test_extra_plaintext) {
|
||||
smartlist_add(lines,
|
||||
tor_strdup(desc->encrypted_data.test_extra_plaintext));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (desc->encrypted_data.intro_auth_types &&
|
||||
smartlist_len(desc->encrypted_data.intro_auth_types)) {
|
||||
/* Put the authentication-required line. */
|
||||
@ -2817,9 +2824,15 @@ hs_desc_encode_descriptor,(const hs_descriptor_t *desc,
|
||||
}
|
||||
|
||||
/* Try to decode what we just encoded. Symmetry is nice!, but it is
|
||||
* symmetric only if the client auth is disabled. That is, the descriptor
|
||||
* cookie will be NULL. */
|
||||
if (!descriptor_cookie) {
|
||||
* symmetric only if the client auth is disabled (That is, the descriptor
|
||||
* cookie will be NULL) and the test-only mock plaintext isn't in use. */
|
||||
bool do_round_trip_test = !descriptor_cookie;
|
||||
#ifdef TOR_UNIT_TESTS
|
||||
if (desc->encrypted_data.test_extra_plaintext) {
|
||||
do_round_trip_test = false;
|
||||
}
|
||||
#endif
|
||||
if (do_round_trip_test) {
|
||||
ret = hs_desc_decode_descriptor(*encoded_out, &desc->subcredential,
|
||||
NULL, NULL);
|
||||
if (BUG(ret != HS_DESC_DECODE_OK)) {
|
||||
|
@ -177,6 +177,13 @@ typedef struct hs_desc_encrypted_data_t {
|
||||
|
||||
/** A list of intro points. Contains hs_desc_intro_point_t objects. */
|
||||
smartlist_t *intro_points;
|
||||
|
||||
#ifdef TOR_UNIT_TESTS
|
||||
/** In unit tests only, we can include additional arbitrary plaintext.
|
||||
* This is used to test parser validation by adding invalid inner data to
|
||||
* descriptors that are otherwise correct and correctly encrypted. */
|
||||
const char *test_extra_plaintext;
|
||||
#endif
|
||||
} hs_desc_encrypted_data_t;
|
||||
|
||||
/** The superencrypted data section of a descriptor. Obviously the data in
|
||||
|
@ -354,6 +354,18 @@ hs_helper_desc_equal(const hs_descriptor_t *desc1,
|
||||
}
|
||||
}
|
||||
|
||||
/* Proof of Work DoS mitigation options */
|
||||
tt_int_op(!!desc1->encrypted_data.pow_params, OP_EQ,
|
||||
!!desc2->encrypted_data.pow_params);
|
||||
if (desc1->encrypted_data.pow_params && desc2->encrypted_data.pow_params) {
|
||||
hs_pow_desc_params_t *params1 = desc1->encrypted_data.pow_params;
|
||||
hs_pow_desc_params_t *params2 = desc2->encrypted_data.pow_params;
|
||||
tt_int_op(params1->type, OP_EQ, params2->type);
|
||||
tt_mem_op(params1->seed, OP_EQ, params2->seed, HS_POW_SEED_LEN);
|
||||
tt_int_op(params1->suggested_effort, OP_EQ, params2->suggested_effort);
|
||||
tt_int_op(params1->expiration_time, OP_EQ, params2->expiration_time);
|
||||
}
|
||||
|
||||
/* Introduction points. */
|
||||
{
|
||||
tt_assert(desc1->encrypted_data.intro_points);
|
||||
|
@ -364,6 +364,75 @@ test_decode_descriptor(void *arg)
|
||||
hs_helper_desc_equal(desc, decoded);
|
||||
}
|
||||
|
||||
/* Decode a descriptor without auth clients, and with PoW data added via
|
||||
* test_extra_plaintext to test both the normal case of PoW decoding and the
|
||||
* extra plaintext mechanism itself. */
|
||||
{
|
||||
tor_assert(!desc->encrypted_data.pow_params);
|
||||
|
||||
char pow_seed_base64[HS_POW_SEED_LEN*2];
|
||||
uint8_t pow_seed[HS_POW_SEED_LEN];
|
||||
crypto_strongest_rand(pow_seed, sizeof pow_seed);
|
||||
tt_int_op(base64_encode_nopad(pow_seed_base64, sizeof pow_seed_base64,
|
||||
pow_seed, sizeof pow_seed), OP_GT, 0);
|
||||
|
||||
time_t expiration_time = time(NULL);
|
||||
char time_buf[ISO_TIME_LEN + 1];
|
||||
format_iso_time_nospace(time_buf, expiration_time);
|
||||
|
||||
const unsigned suggested_effort = 123456;
|
||||
char *extra_plaintext = NULL;
|
||||
tor_asprintf(&extra_plaintext,
|
||||
"pow-params v1 %s %u %s\n",
|
||||
pow_seed_base64, suggested_effort, time_buf);
|
||||
|
||||
tor_free(encoded);
|
||||
desc->encrypted_data.test_extra_plaintext = extra_plaintext;
|
||||
ret = hs_desc_encode_descriptor(desc, &signing_kp, NULL, &encoded);
|
||||
tor_free(extra_plaintext);
|
||||
desc->encrypted_data.test_extra_plaintext = extra_plaintext;
|
||||
|
||||
tt_int_op(ret, OP_EQ, 0);
|
||||
tt_assert(encoded);
|
||||
|
||||
desc->encrypted_data.pow_params =
|
||||
tor_malloc_zero(sizeof(hs_pow_desc_params_t));
|
||||
desc->encrypted_data.pow_params->type = HS_POW_DESC_V1;
|
||||
memcpy(desc->encrypted_data.pow_params->seed, pow_seed, HS_POW_SEED_LEN);
|
||||
desc->encrypted_data.pow_params->suggested_effort = suggested_effort;
|
||||
desc->encrypted_data.pow_params->expiration_time = expiration_time;
|
||||
|
||||
hs_descriptor_free(decoded);
|
||||
ret = hs_desc_decode_descriptor(encoded, &subcredential, NULL, &decoded);
|
||||
tt_int_op(ret, OP_EQ, HS_DESC_DECODE_OK);
|
||||
tt_assert(decoded);
|
||||
|
||||
hs_helper_desc_equal(desc, decoded);
|
||||
|
||||
tor_free(desc->encrypted_data.pow_params);
|
||||
}
|
||||
|
||||
/* Now a version of the above that's expected to fail. This reproduces the
|
||||
* issue from ticket tor#40793, in which pow_params gets too few parameters
|
||||
* but this would cause an assert instead of an early validation fail.
|
||||
* Make sure it fails to parse. Prior to the fix for #40793 this fails
|
||||
* an assertion instead. */
|
||||
{
|
||||
tor_free(encoded);
|
||||
tor_assert(!desc->encrypted_data.pow_params);
|
||||
desc->encrypted_data.test_extra_plaintext = "pow-params v1 a a\n";
|
||||
ret = hs_desc_encode_descriptor(desc, &signing_kp, NULL, &encoded);
|
||||
desc->encrypted_data.test_extra_plaintext = NULL;
|
||||
|
||||
tt_int_op(ret, OP_EQ, 0);
|
||||
tt_assert(encoded);
|
||||
|
||||
hs_descriptor_free(decoded);
|
||||
ret = hs_desc_decode_descriptor(encoded, &subcredential, NULL, &decoded);
|
||||
tt_int_op(ret, OP_EQ, HS_DESC_DECODE_ENCRYPTED_ERROR);
|
||||
tt_assert(!decoded);
|
||||
}
|
||||
|
||||
done:
|
||||
hs_descriptor_free(desc);
|
||||
hs_descriptor_free(desc_no_ip);
|
||||
|
Loading…
Reference in New Issue
Block a user