diff --git a/src/or/consdiff.c b/src/or/consdiff.c index f8cf180402..296b43d38b 100644 --- a/src/or/consdiff.c +++ b/src/or/consdiff.c @@ -39,6 +39,15 @@ static const char* ns_diff_version = "network-status-diff-version 1"; static const char* hash_token = "hash"; +STATIC int +consensus_compute_digest(const char *cons, + consensus_digest_t *digest_out) +{ + int r = crypto_digest256((char*)digest_out->sha3_256, + cons, strlen(cons), DIGEST_SHA3_256); + return r; +} + /** Create (allocate) a new slice from a smartlist. Assumes that the start * and the end indexes are within the bounds of the initial smartlist. The end * element is not part of the resulting slice. If end is -1, the slice is to @@ -790,7 +799,7 @@ apply_ed_diff(smartlist_t *cons1, smartlist_t *diff) */ smartlist_t * consdiff_gen_diff(smartlist_t *cons1, smartlist_t *cons2, - common_digests_t *digests1, common_digests_t *digests2) + consensus_digest_t *digests1, consensus_digest_t *digests2) { smartlist_t *ed_diff = gen_ed_diff(cons1, cons2); /* ed diff could not be generated - reason already logged by gen_ed_diff. */ @@ -824,9 +833,9 @@ consdiff_gen_diff(smartlist_t *cons1, smartlist_t *cons2, char cons1_hash_hex[HEX_DIGEST256_LEN+1]; char cons2_hash_hex[HEX_DIGEST256_LEN+1]; base16_encode(cons1_hash_hex, HEX_DIGEST256_LEN+1, - digests1->d[DIGEST_SHA256], DIGEST256_LEN); + (const char*)digests1->sha3_256, DIGEST256_LEN); base16_encode(cons2_hash_hex, HEX_DIGEST256_LEN+1, - digests2->d[DIGEST_SHA256], DIGEST256_LEN); + (const char*)digests2->sha3_256, DIGEST256_LEN); /* Create the resulting consensus diff. */ smartlist_t *result = smartlist_new(); @@ -874,7 +883,7 @@ consdiff_get_digests(smartlist_t *diff, goto error_cleanup; } - /* Grab the SHA256 base16 hashes. */ + /* Grab the base16 digests. */ hash_words = smartlist_new(); smartlist_split_string(hash_words, smartlist_get(diff, 1), " ", 0, 0); @@ -889,7 +898,7 @@ consdiff_get_digests(smartlist_t *diff, /* Expected hashes as found in the consensus diff header. They must be of * length HEX_DIGEST256_LEN, normally 64 hexadecimal characters. * If any of the decodings fail, error to make sure that the hashes are - * proper base16-encoded SHA256 digests. + * proper base16-encoded digests. */ cons1_hash_hex = smartlist_get(hash_words, 1); cons2_hash_hex = smartlist_get(hash_words, 2); @@ -936,7 +945,7 @@ consdiff_get_digests(smartlist_t *diff, */ char * consdiff_apply_diff(smartlist_t *cons1, smartlist_t *diff, - common_digests_t *digests1) + consensus_digest_t *digests1) { smartlist_t *cons2 = NULL; char *cons2_str = NULL; @@ -948,7 +957,7 @@ consdiff_apply_diff(smartlist_t *cons1, smartlist_t *diff, } /* See that the consensus that was given to us matches its hash. */ - if (fast_memneq(digests1->d[DIGEST_SHA256], e_cons1_hash, + if (fast_memneq(digests1->sha3_256, e_cons1_hash, DIGEST256_LEN)) { char hex_digest1[HEX_DIGEST256_LEN+1]; char e_hex_digest1[HEX_DIGEST256_LEN+1]; @@ -956,9 +965,9 @@ consdiff_apply_diff(smartlist_t *cons1, smartlist_t *diff, "the base consensus doesn't match the digest as found in " "the consensus diff header."); base16_encode(hex_digest1, HEX_DIGEST256_LEN+1, - digests1->d[DIGEST_SHA256], DIGEST256_LEN); + (const char *)digests1->sha3_256, DIGEST256_LEN); base16_encode(e_hex_digest1, HEX_DIGEST256_LEN+1, - e_cons1_hash, DIGEST256_LEN); + e_cons1_hash, DIGEST256_LEN); log_warn(LD_CONSDIFF, "Expected: %s; found: %s", hex_digest1, e_hex_digest1); goto error_cleanup; @@ -983,16 +992,17 @@ consdiff_apply_diff(smartlist_t *cons1, smartlist_t *diff, cons2_str = smartlist_join_strings(cons2, "\n", 1, NULL); - common_digests_t cons2_digests; - if (router_get_networkstatus_v3_hashes(cons2_str, - &cons2_digests)<0) { + consensus_digest_t cons2_digests; + if (consensus_compute_digest(cons2_str, &cons2_digests) < 0) { + /* LCOV_EXCL_START -- digest can't fail */ log_warn(LD_CONSDIFF, "Could not compute digests of the consensus " "resulting from applying a consensus diff."); goto error_cleanup; + /* LCOV_EXCL_STOP */ } /* See that the resulting consensus matches its hash. */ - if (fast_memneq(cons2_digests.d[DIGEST_SHA256], e_cons2_hash, + if (fast_memneq(cons2_digests.sha3_256, e_cons2_hash, DIGEST256_LEN)) { log_warn(LD_CONSDIFF, "Refusing to apply consensus diff because " "the resulting consensus doesn't match the digest as found in " @@ -1000,7 +1010,7 @@ consdiff_apply_diff(smartlist_t *cons1, smartlist_t *diff, char hex_digest2[HEX_DIGEST256_LEN+1]; char e_hex_digest2[HEX_DIGEST256_LEN+1]; base16_encode(hex_digest2, HEX_DIGEST256_LEN+1, - cons2_digests.d[DIGEST_SHA256], DIGEST256_LEN); + (const char *)cons2_digests.sha3_256, DIGEST256_LEN); base16_encode(e_hex_digest2, HEX_DIGEST256_LEN+1, e_cons2_hash, DIGEST256_LEN); log_warn(LD_CONSDIFF, "Expected: %s; found: %s", diff --git a/src/or/consdiff.h b/src/or/consdiff.h index 0f4a25a01c..1fffaedb00 100644 --- a/src/or/consdiff.h +++ b/src/or/consdiff.h @@ -7,10 +7,14 @@ #include "or.h" +typedef struct consensus_digest_t { + uint8_t sha3_256[DIGEST256_LEN]; +} consensus_digest_t; + smartlist_t *consdiff_gen_diff(smartlist_t *cons1, smartlist_t *cons2, - common_digests_t *digests1, common_digests_t *digests2); + consensus_digest_t *digests1, consensus_digest_t *digests2); char *consdiff_apply_diff(smartlist_t *cons1, smartlist_t *diff, - common_digests_t *digests1); + consensus_digest_t *digests1); int consdiff_get_digests(smartlist_t *diff, char *digest1_out, char *digest2_out); @@ -45,6 +49,8 @@ STATIC int smartlist_slice_string_pos(smartlist_slice_t *slice, const char *string); STATIC void set_changed(bitarray_t *changed1, bitarray_t *changed2, smartlist_slice_t *slice1, smartlist_slice_t *slice2); +STATIC int consensus_compute_digest(const char *cons, + consensus_digest_t *digest_out); #endif #endif diff --git a/src/test/test_consdiff.c b/src/test/test_consdiff.c index bbe3532e5a..2afebfe2ab 100644 --- a/src/test/test_consdiff.c +++ b/src/test/test_consdiff.c @@ -8,7 +8,6 @@ #include "test.h" #include "consdiff.h" -#include "routerparse.h" #include "log_test_helpers.h" static void @@ -808,7 +807,7 @@ test_consdiff_gen_diff(void *arg) { char *cons1_str=NULL, *cons2_str=NULL; smartlist_t *cons1=NULL, *cons2=NULL, *diff=NULL; - common_digests_t digests1, digests2; + consensus_digest_t digests1, digests2; (void)arg; cons1 = smartlist_new(); cons2 = smartlist_new(); @@ -817,22 +816,22 @@ test_consdiff_gen_diff(void *arg) * Already tested in gen_ed_diff, but see that a NULL ed diff also makes * gen_diff return NULL. */ cons1_str = tor_strdup( - "header\nnetwork-status-version foo\n" + "network-status-version foo\n" "r name bbbbbbbbbbbbbbbbb etc\nfoo\n" "r name aaaaaaaaaaaaaaaaa etc\nbar\n" "directory-signature foo bar\nbar\n" ); cons2_str = tor_strdup( - "header\nnetwork-status-version foo\n" + "network-status-version foo\n" "r name aaaaaaaaaaaaaaaaa etc\nfoo\n" "r name ccccccccccccccccc etc\nbar\n" "directory-signature foo bar\nbar\n" ); tt_int_op(0, OP_EQ, - router_get_networkstatus_v3_hashes(cons1_str, &digests1)); + consensus_compute_digest(cons1_str, &digests1)); tt_int_op(0, OP_EQ, - router_get_networkstatus_v3_hashes(cons2_str, &digests2)); + consensus_compute_digest(cons2_str, &digests2)); tor_split_lines(cons1, cons1_str, (int)strlen(cons1_str)); tor_split_lines(cons2, cons2_str, (int)strlen(cons2_str)); @@ -843,13 +842,13 @@ test_consdiff_gen_diff(void *arg) /* Check that the headers are done properly. */ tor_free(cons1_str); cons1_str = tor_strdup( - "header\nnetwork-status-version foo\n" + "network-status-version foo\n" "r name ccccccccccccccccc etc\nfoo\n" "r name eeeeeeeeeeeeeeeee etc\nbar\n" "directory-signature foo bar\nbar\n" ); tt_int_op(0, OP_EQ, - router_get_networkstatus_v3_hashes(cons1_str, &digests1)); + consensus_compute_digest(cons1_str, &digests1)); smartlist_clear(cons1); tor_split_lines(cons1, cons1_str, (int)strlen(cons1_str)); diff = consdiff_gen_diff(cons1, cons2, &digests1, &digests2); @@ -857,11 +856,11 @@ test_consdiff_gen_diff(void *arg) tt_int_op(7, OP_EQ, smartlist_len(diff)); tt_str_op("network-status-diff-version 1", OP_EQ, smartlist_get(diff, 0)); tt_str_op("hash " - "C2199B6827514F39ED9B3F2E2E73735C6C5468FD636240BB454C526220DE702A " - "B193E5FBFE5C009AEDE56F9218E6421A1AE5C19F43E091786A73F43F60409B60", + "06646D6CF563A41869D3B02E73254372AE3140046C5E7D83C9F71E54976AF9B4 " + "7AFECEFA4599BA33D603653E3D2368F648DF4AC4723929B0F7CF39281596B0C1", OP_EQ, smartlist_get(diff, 1)); - tt_str_op("4,5d", OP_EQ, smartlist_get(diff, 2)); - tt_str_op("2a", OP_EQ, smartlist_get(diff, 3)); + tt_str_op("3,4d", OP_EQ, smartlist_get(diff, 2)); + tt_str_op("1a", OP_EQ, smartlist_get(diff, 3)); tt_str_op("r name aaaaaaaaaaaaaaaaa etc", OP_EQ, smartlist_get(diff, 4)); tt_str_op("foo", OP_EQ, smartlist_get(diff, 5)); tt_str_op(".", OP_EQ, smartlist_get(diff, 6)); @@ -882,20 +881,20 @@ test_consdiff_apply_diff(void *arg) { smartlist_t *cons1=NULL, *diff=NULL; char *cons1_str=NULL, *cons2 = NULL; - common_digests_t digests1; + consensus_digest_t digests1; (void)arg; cons1 = smartlist_new(); diff = smartlist_new(); setup_capture_of_logs(LOG_INFO); cons1_str = tor_strdup( - "header\nnetwork-status-version foo\n" + "network-status-version foo\n" "r name ccccccccccccccccc etc\nfoo\n" "r name eeeeeeeeeeeeeeeee etc\nbar\n" "directory-signature foo bar\nbar\n" ); tt_int_op(0, OP_EQ, - router_get_networkstatus_v3_hashes(cons1_str, &digests1)); + consensus_compute_digest(cons1_str, &digests1)); tor_split_lines(cons1, cons1_str, (int)strlen(cons1_str)); /* diff doesn't have enough lines. */ @@ -930,7 +929,7 @@ test_consdiff_apply_diff(void *arg) tt_ptr_op(NULL, OP_EQ, cons2); expect_single_log_msg_containing("does not include the necessary digests") - /* base16 sha256 digests do not have the expected length. */ + /* base16 digests do not have the expected length. */ smartlist_clear(diff); smartlist_add(diff, (char*)"network-status-diff-version 1"); smartlist_add(diff, (char*)"hash aaa bbb"); @@ -940,7 +939,7 @@ test_consdiff_apply_diff(void *arg) expect_single_log_msg_containing("includes base16-encoded digests of " "incorrect size") - /* base16 sha256 digests contain non-base16 characters. */ + /* base16 digests contain non-base16 characters. */ smartlist_clear(diff); smartlist_add(diff, (char*)"network-status-diff-version 1"); smartlist_add(diff, (char*)"hash" @@ -957,8 +956,8 @@ test_consdiff_apply_diff(void *arg) smartlist_clear(diff); smartlist_add(diff, (char*)"network-status-diff-version 1"); smartlist_add(diff, (char*)"hash" - /* sha256 of cons1. */ - " C2199B6827514F39ED9B3F2E2E73735C6C5468FD636240BB454C526220DE702A" + /* sha3 of cons1. */ + " 06646D6CF563A41869D3B02E73254372AE3140046C5E7D83C9F71E54976AF9B4" /* sha256 of cons2. */ " 635D34593020C08E5ECD865F9986E29D50028EFA62843766A8197AD228A7F6AA"); smartlist_add(diff, (char*)"foobar"); @@ -986,9 +985,9 @@ test_consdiff_apply_diff(void *arg) smartlist_clear(diff); smartlist_add(diff, (char*)"network-status-diff-version 1"); smartlist_add(diff, (char*)"hash" - /* sha256 of cons1. */ - " C2199B6827514F39ED9B3F2E2E73735C6C5468FD636240BB454C526220DE702A" - /* bogus sha256. */ + /* sha3 of cons1. */ + " 06646D6CF563A41869D3B02E73254372AE3140046C5E7D83C9F71E54976AF9B4" + /* bogus sha3. */ " 3333333333333333333333333333333333333333333333333333333333333333"); mock_clean_saved_logs(); cons2 = consdiff_apply_diff(cons1, diff, &digests1); @@ -996,13 +995,15 @@ test_consdiff_apply_diff(void *arg) expect_log_msg_containing("resulting consensus doesn't match the " "digest as found"); +#if 0 + /* XXXX No longer possible, since we aren't using the other algorithm. */ /* Resulting consensus digest cannot be computed */ smartlist_clear(diff); smartlist_add(diff, (char*)"network-status-diff-version 1"); smartlist_add(diff, (char*)"hash" - /* sha256 of cons1. */ - " C2199B6827514F39ED9B3F2E2E73735C6C5468FD636240BB454C526220DE702A" - /* bogus sha256. */ + /* sha3 of cons1. */ + " 06646D6CF563A41869D3B02E73254372AE3140046C5E7D83C9F71E54976AF9B4" + /* bogus sha3. */ " 3333333333333333333333333333333333333333333333333333333333333333"); smartlist_add(diff, (char*)"1,2d"); // remove starting line mock_clean_saved_logs(); @@ -1010,22 +1011,23 @@ test_consdiff_apply_diff(void *arg) tt_ptr_op(NULL, OP_EQ, cons2); expect_log_msg_containing("Could not compute digests of the consensus " "resulting from applying a consensus diff."); +#endif /* Very simple test, only to see that nothing errors. */ smartlist_clear(diff); smartlist_add(diff, (char*)"network-status-diff-version 1"); smartlist_add(diff, (char*)"hash" - /* sha256 of cons1. */ - " C2199B6827514F39ED9B3F2E2E73735C6C5468FD636240BB454C526220DE702A" - /* sha256 of cons2. */ - " 635D34593020C08E5ECD865F9986E29D50028EFA62843766A8197AD228A7F6AA"); - smartlist_add(diff, (char*)"4c"); + /* sha3 of cons1. */ + " 06646D6CF563A41869D3B02E73254372AE3140046C5E7D83C9F71E54976AF9B4" + /* sha3 of cons2. */ + " 90A418881B2FCAB3D9E60EE02E4D666D56CFA38F8A3B7AA3E0ADBA530DDA9353"); + smartlist_add(diff, (char*)"3c"); smartlist_add(diff, (char*)"sample"); smartlist_add(diff, (char*)"."); cons2 = consdiff_apply_diff(cons1, diff, &digests1); tt_ptr_op(NULL, OP_NE, cons2); tt_str_op( - "header\nnetwork-status-version foo\n" + "network-status-version foo\n" "r name ccccccccccccccccc etc\nsample\n" "r name eeeeeeeeeeeeeeeee etc\nbar\n" "directory-signature foo bar\nbar\n", OP_EQ, @@ -1036,17 +1038,17 @@ test_consdiff_apply_diff(void *arg) smartlist_clear(diff); smartlist_add(diff, (char*)"network-status-diff-version 1"); smartlist_add(diff, (char*)"hash" - /* sha256 of cons1. */ - " c2199b6827514f39ed9b3f2e2e73735c6c5468fd636240bb454c526220de702a" - /* sha256 of cons2. */ - " 635d34593020c08e5ecd865f9986e29d50028efa62843766a8197ad228a7f6aa"); - smartlist_add(diff, (char*)"4c"); + /* sha3 of cons1. */ + " 06646d6cf563a41869d3b02e73254372ae3140046c5e7d83c9f71e54976af9b4" + /* sha3 of cons2. */ + " 90a418881b2fcab3d9e60ee02e4d666d56cfa38f8a3b7aa3e0adba530dda9353"); + smartlist_add(diff, (char*)"3c"); smartlist_add(diff, (char*)"sample"); smartlist_add(diff, (char*)"."); cons2 = consdiff_apply_diff(cons1, diff, &digests1); tt_ptr_op(NULL, OP_NE, cons2); tt_str_op( - "header\nnetwork-status-version foo\n" + "network-status-version foo\n" "r name ccccccccccccccccc etc\nsample\n" "r name eeeeeeeeeeeeeeeee etc\nbar\n" "directory-signature foo bar\nbar\n", OP_EQ,