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")
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)])