Skip to content

Commit b8a99c7

Browse files
committed
Update repository_lib and client/updater to use the canonical json representation when hashing snapshot information.
By using the canonical json representation, this commit ensures that the hash will be consistent across different python versions. this commit additionally updates the test data to use the correct hashes. Signed-off-by: marinamoore <[email protected]>
1 parent 78e4c36 commit b8a99c7

File tree

7 files changed

+25
-16
lines changed

7 files changed

+25
-16
lines changed
Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
{
22
"leaf_contents": {
3+
"name": "role1",
34
"version": 1
45
},
56
"merkle_path": {
6-
"0": "d0657b1fe8cd74976421241692e36b86ebd8f923a3f71ec99dbcacac319a11eb"
7+
"0": "3bd2912d01accd816767dcde96a2b470dc5bb51cefe3b3aeb3aca7fdc1704d6b",
8+
"1": "70304860310d2c6f0a05f2ccbfb49a4a6d6d3c7a9ff9c93e0b91b2e0ab7fff97"
79
},
810
"path_directions": {
9-
"0": 1
11+
"0": -1,
12+
"1": -1
1013
}
1114
}

tests/repository_data/repository/metadata/role2-snapshot.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
{
22
"leaf_contents": {
3+
"name": "role2",
34
"version": 1
45
},
56
"merkle_path": {
6-
"0": "abcfdd2bed858c5d7e8866a21bbdee0ca94cc03fd61f9a8c7ccbe4e50a78044a",
7-
"1": "d5d4546f9bfcce78a079fff48828b922091b5be9e874d5d2ce075e314dd19e13"
7+
"0": "9a8cf4b3e3cf611d339867f295792c3105d3d8ebfcd559607f9528ba7511e52a",
8+
"1": "70304860310d2c6f0a05f2ccbfb49a4a6d6d3c7a9ff9c93e0b91b2e0ab7fff97"
89
},
910
"path_directions": {
1011
"0": 1,
Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
{
22
"leaf_contents": {
3+
"name": "targets",
34
"version": 1
45
},
56
"merkle_path": {
6-
"0": "4d9f52a07628625e664bfd96868b69d5b4e81debf3f00ed3940e00cd8dc3da70",
7-
"1": "d5d4546f9bfcce78a079fff48828b922091b5be9e874d5d2ce075e314dd19e13"
7+
"0": "30e11c75a8fa88fd36cc2a4796c5c9f405c9ae52b7adf4180d1c351141e5037a"
88
},
99
"path_directions": {
10-
"0": -1,
11-
"1": -1
10+
"0": 1
1211
}
1312
}

tests/repository_data/repository/metadata/timestamp-merkle.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22
"signatures": [
33
{
44
"keyid": "8a1c4a3ac2d515dec982ba9910c5fd79b91ae57f625b9cff25d06bf0a61c1758",
5-
"sig": "c900d68461b8defb7d5d081376576c54f6e619ef8fde33d07b88e2763f123fbb10844168b7dfc638e0b137a8289bf56253a528e4b771ea5277182950f1517c0c"
5+
"sig": "1790a53390ab9928ba5c46e7a30a4e0348976e26f34d8cdd29ee11d644276dfc72e3fff6d1a7a913a42a1443cda12a738a3e4803818e970446a91e0e99f24601"
66
}
77
],
88
"signed": {
99
"_type": "timestamp",
1010
"expires": "2030-01-01T00:00:00Z",
11-
"merkle_root": "2b232a308f285d2ef594fa4410d3982f3982e33c28cd73fe1f23a0014be7da77",
11+
"merkle_root": "76eb3066cb278633fda18fa6e3ae33d783ff154e813e2752eb7bc8b65568a41b",
1212
"meta": {
1313
"snapshot.json": {
1414
"hashes": {

tests/test_updater.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1783,7 +1783,9 @@ def test_snapshot_merkle(self):
17831783

17841784
# Test verify merkle path
17851785
snapshot_info = repository_updater._verify_merkle_path('targets')
1786+
self.assertEqual(snapshot_info['version'], 1)
17861787

1788+
snapshot_info = repository_updater._verify_merkle_path('role1')
17871789
self.assertEqual(snapshot_info['version'], 1)
17881790

17891791
# verify merkle path with invalid role

tuf/client/updater.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1901,8 +1901,9 @@ def _verify_merkle_path(self, metadata_role):
19011901

19021902
# hash the contents to determine the leaf hash in the merkle tree
19031903
contents = snapshot_merkle['leaf_contents']
1904+
json_contents = securesystemslib.formats.encode_canonical(contents)
19041905
digest_object = securesystemslib.hash.digest()
1905-
digest_object.update((metadata_role + str(contents) + '0').encode('utf-8'))
1906+
digest_object.update((json_contents).encode('utf-8'))
19061907
node_hash = digest_object.hexdigest()
19071908

19081909
# For each hash in the merkle_path, determine if the current node is

tuf/repository_lib.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1594,7 +1594,7 @@ def __init__(self, left, right):
15941594

15951595
left.set_parent(self)
15961596
right.set_parent(self)
1597-
digest_object = securesystemslib.hash.digest()
1597+
digest_object = securesystemslib.hash.digest(algorithm=HASH_FUNCTION)
15981598

15991599
digest_object.update((left.hash() + right.hash()).encode('utf-8'))
16001600

@@ -1627,16 +1627,19 @@ class Leaf(Node):
16271627

16281628
def __init__(self, name, contents, digest = None):
16291629
super(Leaf, self).__init__()
1630+
# Include the name to ensure the hash differs between elements and cannot be replayed
1631+
contents["name"] = name
16301632
self._contents = contents
16311633
self._name = name
16321634

16331635
if digest:
16341636
self._hash = digest
16351637
else:
1636-
digest_object = securesystemslib.hash.digest()
1637-
# Append a 0 for reverse preimage protection
1638-
# Include the name to ensure the hash differs between elements
1639-
digest_object.update((name + str(contents) + '0').encode('utf-8'))
1638+
digest_object = securesystemslib.hash.digest(algorithm=HASH_FUNCTION)
1639+
# Hash the canonical json form of the data to ensure consistency
1640+
json_contents = securesystemslib.formats.encode_canonical(contents)
1641+
1642+
digest_object.update(json_contents.encode('utf-8'))
16401643
self._hash = digest_object.hexdigest()
16411644

16421645
def name(self):

0 commit comments

Comments
 (0)