From d4c9fa1b47d860ae8e65d56fafdd821d1b44f881 Mon Sep 17 00:00:00 2001 From: Brian Wellington Date: Sat, 26 Jul 2025 08:13:41 -0700 Subject: [PATCH] Fix signing initially empty zone. (#1213) dns.dnssec.sign_zone() fails if the SOA is added in the same transaction that signs the zone, because it's not using the active transaction when looking for the SOA. (#1210) --- dns/dnssec.py | 2 +- tests/test_dnssec.py | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/dns/dnssec.py b/dns/dnssec.py index 76d728a5..5cb7cfcb 100644 --- a/dns/dnssec.py +++ b/dns/dnssec.py @@ -1148,7 +1148,7 @@ def _sign_zone_nsec( if rrset_signer: rrset_signer(txn, rrset) - rrsig_ttl = zone.get_soa().minimum + rrsig_ttl = zone.get_soa(txn).minimum delegation = None last_secure = None diff --git a/tests/test_dnssec.py b/tests/test_dnssec.py index ce468d70..117244b1 100644 --- a/tests/test_dnssec.py +++ b/tests/test_dnssec.py @@ -1090,6 +1090,21 @@ class DNSSECMiscTestCase(unittest.TestCase): zone2 = dns.zone.from_text(test_zone_with_nsec, "example.", relativize=False) self.assertEqual(zone1.to_text(), zone2.to_text()) + def test_sign_zone_initially_empty(self): + zone = dns.zone.Zone("example.") + soa = dns.rdataset.from_text("IN", "SOA", 3600, + "ns.example. hostmaster.example. 1 2 3 4 5") + privkey = ed25519.Ed25519PrivateKey.generate() + dnskey = dns.dnssec.make_dnskey(privkey.public_key(), + dns.dnssec.ED25519) + with zone.writer() as txn: + txn.add(dns.name.empty, soa) + dns.dnssec.sign_zone(zone, txn=txn, keys=[(privkey, dnskey)], + lifetime=3600) + + self.assertIsNotNone(zone.find_rdataset(dns.name.empty, "SOA")) + self.assertIsNotNone(zone.find_rdataset(dns.name.empty, "RRSIG", + covers="SOA")) @unittest.skipUnless(dns.dnssec._have_pyca, "Python Cryptography cannot be imported") class DNSSECMakeDSTestCase(unittest.TestCase): -- 2.47.3