Add tests for the tag construction code and make it a bit safer

Check for sane inputs, reject insane ones
This commit is contained in:
Jean-Paul Calderone 2021-01-19 14:28:16 -05:00
parent 512897eca0
commit 61d5f920bb
2 changed files with 64 additions and 1 deletions
src/allmydata

@ -126,6 +126,42 @@ class HashUtilTests(unittest.TestCase):
base32.a2b(b"2ckv3dfzh6rgjis6ogfqhyxnzy"),
)
def test_convergence_hasher_tag(self):
"""
``_convergence_hasher_tag`` constructs the convergence hasher tag from a
unique prefix, the required, total, and segment size parameters, and a
convergence secret.
"""
self.assertEqual(
"allmydata_immutable_content_to_key_with_added_secret_v1+"
"16:\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42,"
"9:3,10,1024,",
hashutil._convergence_hasher_tag(
k=3,
n=10,
segsize=1024,
convergence=b"\x42" * 16,
),
)
def test_convergence_hasher_out_of_bounds(self):
"""
``_convergence_hasher_tag`` raises ``ValueError`` if k or n is not between
1 and 256 inclusive or if k is greater than n.
"""
segsize = 1024
secret = b"\x42" * 16
for bad_k in (0, 2, 257):
with self.assertRaises(ValueError):
hashutil._convergence_hasher_tag(
k=bad_k, n=1, segsize=segsize, convergence=secret,
)
for bad_n in (0, 1, 257):
with self.assertRaises(ValueError):
hashutil._convergence_hasher_tag(
k=2, n=bad_n, segsize=segsize, convergence=secret,
)
def test_known_answers(self):
"""
Verify backwards compatibility by comparing hash outputs for some

@ -176,10 +176,37 @@ def convergence_hash(k, n, segsize, data, convergence):
return h.digest()
def convergence_hasher(k, n, segsize, convergence):
def _convergence_hasher_tag(k, n, segsize, convergence):
"""
Create the convergence hashing tag.
:param int k: Required shares.
:param int n: Total shares.
:param int segsize: Maximum segment size.
:param bytes convergence: The convergence secret.
:return bytes: The bytestring to use as a tag in the convergence hash.
"""
assert isinstance(convergence, bytes)
if k > n:
raise ValueError(
"k > n not allowed; k = {}, n = {}".format(k, n),
)
if k < 1 or n < 1:
raise ValueError(
"k, n < 1 not allowed; k = {}, n = {}".format(k, n),
)
if k > 256 or n > 256:
raise ValueError(
"k, n > 256 not allowed; k = {}, n = {}".format(k, n),
)
param_tag = netstring(b"%d,%d,%d" % (k, n, segsize))
tag = CONVERGENT_ENCRYPTION_TAG + netstring(convergence) + param_tag
return tag
def convergence_hasher(k, n, segsize, convergence):
tag = _convergence_hasher_tag(k, n, segsize, convergence)
return tagged_hasher(tag, KEYLEN)