Add property based test for nsec3hash utility

Check the correctness of NSEC3 hash generation by generating random
combinations of name, salt, and iterations and comparing the outputs
of the nsec3hash tool against the dnspython nsec3_hash function
for the same inputs.

(cherry picked from commit e263df8848)
This commit is contained in:
Evan Hunt 2025-04-29 17:03:47 -07:00 committed by Petr Špaček
parent 2f97258d35
commit a074b2acbb

View file

@ -15,6 +15,12 @@ import subprocess
import pytest
import isctest
from isctest.hypothesis.strategies import dns_names
from hypothesis import strategies, given, settings
from dns.dnssectypes import NSEC3Hash
import dns.dnssec
NSEC3HASH = os.environ.get("NSEC3HASH")
@ -120,3 +126,51 @@ def test_nsec3_missing_args(args):
def test_nsec3_bad_option():
with pytest.raises(subprocess.CalledProcessError):
isctest.run.cmd([NSEC3HASH, "-?"])
@given(
domain=dns_names(),
it=strategies.integers(min_value=0, max_value=65535),
salt_bytes=strategies.binary(min_size=0, max_size=255),
)
def test_nsec3hash_acceptable_values(domain, it, salt_bytes) -> None:
if not salt_bytes:
salt_text = "-"
else:
salt_text = salt_bytes.hex()
# calculate the hash using dnspython:
hash1 = dns.dnssec.nsec3_hash(
domain, salt=salt_bytes, iterations=it, algorithm=NSEC3Hash.SHA1
)
# calculate the hash using nsec3hash:
output = isctest.run.cmd(
[NSEC3HASH, salt_text, "1", str(it), str(domain)]
).stdout.decode("ascii")
hash2 = output.partition(" ")[0]
assert hash1 == hash2
@settings(max_examples=5)
@given(
domain=dns_names(),
it=strategies.integers(min_value=0, max_value=65535),
salt_bytes=strategies.binary(min_size=256),
)
def test_nsec3hash_salt_too_long(domain, it, salt_bytes) -> None:
salt_text = salt_bytes.hex()
with pytest.raises(subprocess.CalledProcessError):
isctest.run.cmd([NSEC3HASH, salt_text, "1", str(it), str(domain)])
@settings(max_examples=5)
@given(
domain=dns_names(),
it=strategies.integers(min_value=65536),
salt_bytes=strategies.binary(min_size=0, max_size=255),
)
def test_nsec3hash_too_many_iterations(domain, it, salt_bytes) -> None:
salt_text = salt_bytes.hex()
with pytest.raises(subprocess.CalledProcessError):
isctest.run.cmd([NSEC3HASH, salt_text, "1", str(it), str(domain)])