From 7164ab94bd02201f492f6b47698a1e9d14944eb6 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sat, 26 Feb 2022 11:26:36 +0100 Subject: -remove query hash from what is being signed over --- contrib/gana | 2 +- src/dht/dht_api.c | 101 +++------------ src/dht/gnunet-service-dht_clients.c | 10 +- src/dht/gnunet-service-dht_neighbours.c | 212 +++++++++++++++----------------- src/dht/test_dht_topo.c | 3 +- src/include/gnunet_dht_service.h | 47 +------ 6 files changed, 131 insertions(+), 244 deletions(-) diff --git a/contrib/gana b/contrib/gana index 887d4485e..6b889c206 160000 --- a/contrib/gana +++ b/contrib/gana @@ -1 +1 @@ -Subproject commit 887d4485ea88e42e0b339b7a992420bc1e4e1e7f +Subproject commit 6b889c206c1948cf7180e9d5478fd8fba65617ec diff --git a/src/dht/dht_api.c b/src/dht/dht_api.c index a16db6d4b..474198004 100644 --- a/src/dht/dht_api.c +++ b/src/dht/dht_api.c @@ -1300,8 +1300,7 @@ GNUNET_DHT_pp2s (const struct GNUNET_DHT_PathElement *path, unsigned int -GNUNET_DHT_verify_path (const struct GNUNET_HashCode *query_hash, - const void *data, +GNUNET_DHT_verify_path (const void *data, size_t data_size, struct GNUNET_TIME_Absolute exp_time, const struct GNUNET_DHT_PathElement *put_path, @@ -1310,40 +1309,29 @@ GNUNET_DHT_verify_path (const struct GNUNET_HashCode *query_hash, unsigned int get_path_len, const struct GNUNET_PeerIdentity *me) { - struct GNUNET_DHT_PutHopSignature phs = { - .purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_DHT_PUT_HOP), - .purpose.size = htonl (sizeof (phs)), + struct GNUNET_DHT_HopSignature hs = { + .purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_DHT_HOP), + .purpose.size = htonl (sizeof (hs)), .expiration_time = GNUNET_TIME_absolute_hton (exp_time) }; - struct GNUNET_DHT_ResultHopSignature ghs = { - .purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_DHT_RESULT_HOP), - .purpose.size = htonl (sizeof (ghs)), - .expiration_time = GNUNET_TIME_absolute_hton (exp_time), - }; const struct GNUNET_PeerIdentity *pred; const struct GNUNET_PeerIdentity *succ; unsigned int i; if (0 == get_path_len + put_path_len) return 0; - if (0 != get_path_len) - { - GNUNET_assert (NULL != query_hash); - ghs.query_hash = *query_hash; - } - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "%s is verifying signatures for %s with GPL: %u PPL: %u!\n", + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "%s is verifying signatures with GPL: %u PPL: %u!\n", GNUNET_i2s (me), - NULL != query_hash ? GNUNET_h2s (query_hash) : "", get_path_len, put_path_len); for (unsigned int j = 0; j 0) { pred = (i - 1 >= put_path_len) @@ -1364,71 +1351,21 @@ GNUNET_DHT_verify_path (const struct GNUNET_HashCode *query_hash, succ = (i + 1 >= put_path_len) ? &get_path[i + 1 - put_path_len].pred : &put_path[i + 1].pred; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "PRED: %s\n", - GNUNET_i2s (pred)); - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "SUCC: %s\n", - GNUNET_i2s (succ)); - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "SIGNER: %s\n", - GNUNET_i2s ((i >= put_path_len) - ? &get_path[i - put_path_len].pred - : &put_path[i].pred)); - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "SIG: %s\n", - GNUNET_B2S ((i - 1 >= put_path_len) - ? &get_path[i - put_path_len - 1].sig - : &put_path[i - 1].sig)); - if ( (i + 1 >= put_path_len) && - (0 != get_path_len) ) - { - /* NOTE: the last signature inside the 'PUT' - path is from the cross-over point and already - of type RESULT_HOP, but only if we have - a non-empty 'GET' path! */ - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Key: %s offset %u\n", - GNUNET_h2s (query_hash), - i); - ghs.pred = *pred; - ghs.succ = *succ; - if (GNUNET_OK != - GNUNET_CRYPTO_eddsa_verify ( - GNUNET_SIGNATURE_PURPOSE_DHT_RESULT_HOP, - &ghs, - (i - 1 >= put_path_len) + hs.pred = *pred; + hs.succ = *succ; + if (GNUNET_OK != + GNUNET_CRYPTO_eddsa_verify ( + GNUNET_SIGNATURE_PURPOSE_DHT_HOP, + &hs, + (i - 1 >= put_path_len) ? &get_path[i - put_path_len - 1].sig : &put_path[i - 1].sig, - (i >= put_path_len) + (i >= put_path_len) ? &get_path[i - put_path_len].pred.public_key : &put_path[i].pred.public_key)) - { - GNUNET_break_op (0); - return i; - } - } - else { - phs.pred = *pred; - phs.succ = *succ; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "offset %u\n", - i); - if (GNUNET_OK != - GNUNET_CRYPTO_eddsa_verify ( - GNUNET_SIGNATURE_PURPOSE_DHT_PUT_HOP, - &phs, - (i - 1 >= put_path_len) - ? &get_path[i - put_path_len - 1].sig - : &put_path[i - 1].sig, - (i >= put_path_len) - ? &get_path[i - put_path_len].pred.public_key - : &put_path[i].pred.public_key)) - { - GNUNET_break_op (0); - return i; - } + GNUNET_break_op (0); + return i; } i--; } diff --git a/src/dht/gnunet-service-dht_clients.c b/src/dht/gnunet-service-dht_clients.c index d6ce97666..5735b2420 100644 --- a/src/dht/gnunet-service-dht_clients.c +++ b/src/dht/gnunet-service-dht_clients.c @@ -36,8 +36,11 @@ /** * Enable slow sanity checks to debug issues. + * 0: do not check + * 1: check all external inputs + * 2: check internal computations as well */ -#define SANITY_CHECKS 1 +#define SANITY_CHECKS 2 /** * Should routing details be logged to stderr (for debugging)? @@ -1044,10 +1047,9 @@ GDS_CLIENTS_handle_reply (const struct GDS_DATACACHE_BlockData *bd, GNUNET_break (0); return false; } -#if SANITY_CHECKS +#if SANITY_CHECKS > 1 if (0 != - GNUNET_DHT_verify_path (query_hash, - bd->data, + GNUNET_DHT_verify_path (bd->data, bd->data_size, bd->expiration_time, bd->put_path, diff --git a/src/dht/gnunet-service-dht_neighbours.c b/src/dht/gnunet-service-dht_neighbours.c index f542dd6af..db4ecb34a 100644 --- a/src/dht/gnunet-service-dht_neighbours.c +++ b/src/dht/gnunet-service-dht_neighbours.c @@ -40,8 +40,11 @@ /** * Enable slow sanity checks to debug issues. + * 0: do not check + * 1: check all external inputs + * 2: check internal computations as well */ -#define SANITY_CHECKS 1 +#define SANITY_CHECKS 2 /** * How many buckets will we allow in total. @@ -522,15 +525,15 @@ do_send (struct PeerInfo *pi, * (of purpose #GNUNET_SIGNATURE_PURPOSE_DHT_PUT_HOP) */ static void -sign_put_path (const void *data, - size_t data_size, - struct GNUNET_TIME_Absolute exp_time, - const struct GNUNET_PeerIdentity *pred, - const struct GNUNET_PeerIdentity *succ, - struct GNUNET_CRYPTO_EddsaSignature *sig) +sign_path (const void *data, + size_t data_size, + struct GNUNET_TIME_Absolute exp_time, + const struct GNUNET_PeerIdentity *pred, + const struct GNUNET_PeerIdentity *succ, + struct GNUNET_CRYPTO_EddsaSignature *sig) { - struct GNUNET_DHT_PutHopSignature hs = { - .purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_DHT_PUT_HOP), + struct GNUNET_DHT_HopSignature hs = { + .purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_DHT_HOP), .purpose.size = htonl (sizeof (hs)), .expiration_time = GNUNET_TIME_absolute_hton (exp_time), .pred = *pred, @@ -546,46 +549,6 @@ sign_put_path (const void *data, } -/** - * Sign that we are routing a message from @a pred to @a succ. - * (So the route is $PRED->us->$SUCC). - * - * @param query_hash query being answered - * @param data payload (the block) - * @param data_size number of bytes in @a data - * @param exp_time expiration time of @a data - * @param pred predecessor peer ID - * @param succ successor peer ID - * @param[out] sig where to write the signature - * (of purpose #GNUNET_SIGNATURE_PURPOSE_DHT_HOP) - */ -static void -sign_result_path (const struct GNUNET_HashCode *query_hash, - const void *data, - size_t data_size, - struct GNUNET_TIME_Absolute exp_time, - const struct GNUNET_PeerIdentity *pred, - const struct GNUNET_PeerIdentity *succ, - struct GNUNET_CRYPTO_EddsaSignature *sig) -{ - struct GNUNET_DHT_ResultHopSignature hs = { - .purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_DHT_RESULT_HOP), - .purpose.size = htonl (sizeof (hs)), - .expiration_time = GNUNET_TIME_absolute_hton (exp_time), - .query_hash = *query_hash, - .pred = *pred, - .succ = *succ - }; - - GNUNET_CRYPTO_hash (data, - data_size, - &hs.h_data); - GNUNET_CRYPTO_eddsa_sign (&GDS_my_private_key, - &hs, - sig); -} - - /** * Find the optimal bucket for this key. * @@ -1335,10 +1298,9 @@ GDS_NEIGHBOURS_handle_put (const struct GDS_DATACACHE_BlockData *bd, unsigned int put_path_length = bd->put_path_length; GNUNET_assert (NULL != bf); -#if SANITY_CHECKS +#if SANITY_CHECKS > 1 if (0 != - GNUNET_DHT_verify_path (NULL, - bd->data, + GNUNET_DHT_verify_path (bd->data, bd->data_size, bd->expiration_time, bd->put_path, @@ -1431,12 +1393,12 @@ GDS_NEIGHBOURS_handle_put (const struct GDS_DATACACHE_BlockData *bd, { /* Note that the signature in 'put_path' was not initialized before, so this is crucial to avoid sending garbage. */ - sign_put_path (bd->data, - bd->data_size, - bd->expiration_time, - &pp[put_path_length - 1].pred, - &target->id, - &pp[put_path_length - 1].sig); + sign_path (bd->data, + bd->data_size, + bd->expiration_time, + &pp[put_path_length - 1].pred, + &target->id, + &pp[put_path_length - 1].sig); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Signing PUT PATH %u => %s\n", put_path_length, @@ -1594,10 +1556,9 @@ GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi, size_t msize; unsigned int ppl = bd->put_path_length; -#if SANITY_CHECKS +#if SANITY_CHECKS > 1 if (0 != - GNUNET_DHT_verify_path (query_hash, - bd->data, + GNUNET_DHT_verify_path (bd->data, bd->data_size, bd->expiration_time, bd->put_path, @@ -1634,7 +1595,7 @@ GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi, GNUNET_break (0); return false; } - GNUNET_log (GNUNET_ERROR_TYPE_INFO, + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Forwarding reply for key %s to peer %s\n", GNUNET_h2s (query_hash), GNUNET_i2s (&pi->id)); @@ -1681,13 +1642,12 @@ GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi, { /* Note that the last signature in 'paths' was not initialized before, so this is crucial to avoid sending garbage. */ - sign_result_path (query_hash, - bd->data, - bd->data_size, - bd->expiration_time, - &paths[ppl + get_path_length - 1].pred, - &pi->id, - &paths[ppl + get_path_length - 1].sig); + sign_path (bd->data, + bd->data_size, + bd->expiration_time, + &paths[ppl + get_path_length - 1].pred, + &pi->id, + &paths[ppl + get_path_length - 1].sig); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Signing GET PATH %u/%u of %s => %s\n", ppl, @@ -1699,7 +1659,7 @@ GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi, bd->data, bd->data_size); -#if SANITY_CHECKS +#if SANITY_CHECKS > 1 { struct GNUNET_DHT_PathElement xpaths[get_path_length + 1]; @@ -1708,8 +1668,7 @@ GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi, get_path_length * sizeof (struct GNUNET_DHT_PathElement)); xpaths[get_path_length].pred = GDS_my_identity; if (0 != - GNUNET_DHT_verify_path (&prm->key, - bd->data, + GNUNET_DHT_verify_path (bd->data, bd->data_size, bd->expiration_time, paths, @@ -1743,10 +1702,24 @@ static enum GNUNET_GenericReturnValue check_dht_p2p_put (void *cls, const struct PeerPutMessage *put) { + struct Target *t = cls; + struct PeerInfo *peer = t->pi; + enum GNUNET_DHT_RouteOption options + = (enum GNUNET_DHT_RouteOption) ntohs (put->options); + const struct GNUNET_DHT_PathElement *put_path + = (const struct GNUNET_DHT_PathElement *) &put[1]; uint16_t msize = ntohs (put->header.size); uint16_t putlen = ntohs (put->put_path_length); + struct GDS_DATACACHE_BlockData bd = { + .key = put->key, + .expiration_time = GNUNET_TIME_absolute_ntoh (put->expiration_time), + .type = ntohl (put->type), + .data_size = msize - (sizeof(*put) + + putlen * sizeof(struct GNUNET_DHT_PathElement)), + .data = &put_path[putlen] + }; + struct GNUNET_DHT_PathElement pp[putlen + 1]; - (void) cls; if ( (msize < sizeof(struct PeerPutMessage) + putlen * sizeof(struct GNUNET_DHT_PathElement)) || @@ -1756,6 +1729,52 @@ check_dht_p2p_put (void *cls, GNUNET_break_op (0); return GNUNET_SYSERR; } + + GNUNET_memcpy (pp, + put_path, + putlen * sizeof(struct GNUNET_DHT_PathElement)); + pp[putlen].pred = peer->id; + /* zero-out signature, not valid until we actually do forward! */ + memset (&pp[putlen].sig, + 0, + sizeof (pp[putlen].sig)); +#if SANITY_CHECKS + /* extend 'put path' by sender */ + if (0 != (options & GNUNET_DHT_RO_RECORD_ROUTE)) + { + for (unsigned int i = 0; i <= putlen; i++) + { + for (unsigned int j = 0; j < i; j++) + { + GNUNET_break (0 != + GNUNET_memcmp (&pp[i].pred, + &pp[j].pred)); + } + if (i < putlen) + GNUNET_break (0 != + GNUNET_memcmp (&pp[i].pred, + &peer->id)); + } + if (0 != + GNUNET_DHT_verify_path (bd.data, + bd.data_size, + bd.expiration_time, + pp, + putlen + 1, + NULL, 0, /* get_path */ + &GDS_my_identity)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + } + else if (0 != putlen) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } +#endif + return GNUNET_OK; } @@ -1775,19 +1794,19 @@ handle_dht_p2p_put (void *cls, uint16_t msize = ntohs (put->header.size); enum GNUNET_DHT_RouteOption options = (enum GNUNET_DHT_RouteOption) ntohs (put->options); - struct GDS_DATACACHE_BlockData bd = { - .key = put->key, - .expiration_time = GNUNET_TIME_absolute_ntoh (put->expiration_time), - .type = ntohl (put->type) - }; const struct GNUNET_DHT_PathElement *put_path = (const struct GNUNET_DHT_PathElement *) &put[1]; uint16_t putlen = ntohs (put->put_path_length); + struct GDS_DATACACHE_BlockData bd = { + .key = put->key, + .expiration_time = GNUNET_TIME_absolute_ntoh (put->expiration_time), + .type = ntohl (put->type), + .data_size = msize - (sizeof(*put) + + putlen * sizeof(struct GNUNET_DHT_PathElement)), + .data = &put_path[putlen] + }; - bd.data_size = msize - (sizeof(*put) - + putlen * sizeof(struct GNUNET_DHT_PathElement)); - bd.data = &put_path[putlen]; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "PUT for `%s' from %s with RO (%s/%s)\n", GNUNET_h2s (&put->key), @@ -1872,34 +1891,6 @@ handle_dht_p2p_put (void *cls, memset (&pp[putlen].sig, 0, sizeof (pp[putlen].sig)); -#if SANITY_CHECKS - for (unsigned int i = 0; i <= putlen; i++) - { - for (unsigned int j = 0; j < i; j++) - { - GNUNET_break (0 != - GNUNET_memcmp (&pp[i].pred, - &pp[j].pred)); - } - if (i < putlen) - GNUNET_break (0 != - GNUNET_memcmp (&pp[i].pred, - &peer->id)); - } - if (0 != - GNUNET_DHT_verify_path (&bd.key, - bd.data, - bd.data_size, - bd.expiration_time, - bd.put_path, - putlen, - NULL, 0, /* get_path */ - &GDS_my_identity)) - { - GNUNET_break_op (0); - putlen = 0; - } -#endif } else { @@ -2359,8 +2350,7 @@ check_dht_p2p_result (void *cls, 0, sizeof (gpx[get_path_length].sig)); if (0 != - GNUNET_DHT_verify_path (&prm->key, - &gp[get_path_length], + GNUNET_DHT_verify_path (&gp[get_path_length], msize - (sizeof(struct PeerResultMessage) + (get_path_length + put_path_length) * sizeof(struct GNUNET_DHT_PathElement)), diff --git a/src/dht/test_dht_topo.c b/src/dht/test_dht_topo.c index fa57e13b5..4830ba629 100644 --- a/src/dht/test_dht_topo.c +++ b/src/dht/test_dht_topo.c @@ -377,8 +377,7 @@ dht_get_handler (void *cls, return; } if (0 != - GNUNET_DHT_verify_path (query, - data, + GNUNET_DHT_verify_path (data, size, exp, put_path, diff --git a/src/include/gnunet_dht_service.h b/src/include/gnunet_dht_service.h index 4e14d981d..22b659d66 100644 --- a/src/include/gnunet_dht_service.h +++ b/src/include/gnunet_dht_service.h @@ -118,10 +118,10 @@ GNUNET_NETWORK_STRUCT_BEGIN /** * Message signed by a peer when doing path tracking. */ -struct GNUNET_DHT_PutHopSignature +struct GNUNET_DHT_HopSignature { /** - * Must be #GNUNET_SIGNATURE_PURPOSE_DHT_PUT_HOP. + * Must be #GNUNET_SIGNATURE_PURPOSE_DHT_HOP. */ struct GNUNET_CRYPTO_EccSignaturePurpose purpose; @@ -148,45 +148,6 @@ struct GNUNET_DHT_PutHopSignature }; -/** - * Message signed by a peer when doing path tracking - * for RESULT (GET) hops. - */ -struct GNUNET_DHT_ResultHopSignature -{ - /** - * Must be #GNUNET_SIGNATURE_PURPOSE_DHT_RESULT_HOP. - */ - struct GNUNET_CRYPTO_EccSignaturePurpose purpose; - - /** - * Expiration time of the block. - */ - struct GNUNET_TIME_AbsoluteNBO expiration_time; - - /** - * Query hash of the GET that is being answered. - */ - struct GNUNET_HashCode query_hash; - - /** - * Hash over the payload of the block. - */ - struct GNUNET_HashCode h_data; - - /** - * Previous hop the message was received from. All zeros - * if this peer was the initiator. - */ - struct GNUNET_PeerIdentity pred; - - /** - * Next hop the message was forwarded to. - */ - struct GNUNET_PeerIdentity succ; -}; - - /** * A (signed) path tracking a block's flow through the DHT is represented by * an array of path elements, each consisting of a peer on the path and a @@ -522,7 +483,6 @@ GNUNET_DHT_pp2s (const struct GNUNET_DHT_PathElement *path, * the last signature on the path is never verified as that is the slot where * our peer (@a me) would need to sign. * - * @param query_hash the query hash, not necessarily the key of the block * @param data payload (the block) * @param data_size number of bytes in @a data * @param exp_time expiration time of @a data @@ -536,8 +496,7 @@ GNUNET_DHT_pp2s (const struct GNUNET_DHT_PathElement *path, * @a get_path_len + @a put_path_len - 1 if no signature was valid */ unsigned int -GNUNET_DHT_verify_path (const struct GNUNET_HashCode *query_hash, - const void *data, +GNUNET_DHT_verify_path (const void *data, size_t data_size, struct GNUNET_TIME_Absolute exp_time, const struct GNUNET_DHT_PathElement *put_path, -- cgit v1.2.3