Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
6008929
add decorate reader warning (#1596)
johanbrandhorst Aug 21, 2024
794abd7
edns0 cleanups (#1595)
miekg Aug 21, 2024
b77d1ed
Bump golang.org/x/net from 0.27.0 to 0.28.0 (#1600)
dependabot[bot] Sep 9, 2024
cbe4275
Allow SO_REUSEADDR and SO_REUSEPORT to be set simultaneously (#1623)
rtpt-erikgeiser Jan 24, 2025
8a00a2f
add zdns as a user of miekg/dns (#1608)
phillip-stephens Jan 24, 2025
ca39c8b
fix: input validation for RRSIG.Verify() (#1618)
developStorm Jan 24, 2025
fb0c220
Bump golang.org/x/net from 0.28.0 to 0.31.0 (#1622)
dependabot[bot] Jan 24, 2025
c705e5a
Bump golang.org/x/sys from 0.23.0 to 0.27.0 (#1619)
dependabot[bot] Jan 24, 2025
97c29ff
Release 1.1.63
miekg Jan 24, 2025
b5cf059
Bump golang.org/x/sys from 0.27.0 to 0.29.0 (#1632)
dependabot[bot] Feb 22, 2025
b911878
Bump golang.org/x/net from 0.31.0 to 0.34.0 (#1631)
dependabot[bot] Feb 22, 2025
72fe95a
SVCB is no RFC 9460. (#1636)
miekg Feb 22, 2025
75e8f27
Bump golang.org/x/sync from 0.7.0 to 0.11.0 (#1635)
dependabot[bot] Feb 24, 2025
37f4827
Try to group the dependabot prs
miekg Feb 24, 2025
494e4d2
Merge branch 'master' of github.com:miekg/dns
miekg Feb 24, 2025
1c19e49
Manually run a go get -u
miekg Feb 24, 2025
6425a08
Add the check-soa program, which uses the library (#1638)
bortzmeyer Mar 10, 2025
8d0c412
Add support for Compact Answers OK flag in EDNS (#1639)
chreo Mar 12, 2025
d912518
Add RESINFO rr (#1641)
frcroth Mar 18, 2025
f83d075
Release 1.1.64
miekg Mar 18, 2025
ca3b34e
Document how to create RRs without rdata (#1642)
miekg Mar 19, 2025
42d8cc5
Avoid sendmsg control messages on darwin (#1643)
stek29 Mar 28, 2025
8b1c521
Release 1.1.65
miekg Apr 6, 2025
739cf21
Return error for empty target (#1627)
taoso Apr 6, 2025
8a570c6
A comment concerning newline while scanning (#1645)
miekg Apr 6, 2025
8ec9f67
Upgrade all deps (#1647)
miekg Apr 9, 2025
64211b3
Add the rcode DSO-TYPE Not Implemented / RFC8490 (#1648)
rrobgill Apr 20, 2025
01abd80
DSO: Use Stateful as the suffix
miekg Apr 20, 2025
27318b9
RFC 8490: Implement DSO type registry
miekg Apr 20, 2025
ed312a3
Fix logic in xfr ReadMsg + add test (#1649)
ddevine-NS1 Apr 23, 2025
10d76bc
Release 1.1.66
miekg May 7, 2025
c825975
Merge branch 'sync-v1.1.66' into bc16443
May 16, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,7 @@ updates:
directory: "/"
schedule:
interval: "monthly"
groups:
all:
patterns:
- "*"
2 changes: 1 addition & 1 deletion .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
go: [ 1.22.x, 1.23.x ]
go: [ 1.22.x, 1.23.x, 1.24.x ]
steps:

- name: Set up Go
Expand Down
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ A not-so-up-to-date-list-that-may-be-actually-current:
* https://github.com/wintbiit/NineDNS
* https://linuxcontainers.org/incus/
* https://ifconfig.es

* https://github.com/zmap/zdns
* https://framagit.org/bortzmeyer/check-soa

Send pull request if you want to be listed here.

Expand Down Expand Up @@ -184,6 +185,7 @@ Example programs can be found in the `github.com/miekg/exdns` repository.
* 7871 - EDNS0 Client Subnet
* 7873 - Domain Name System (DNS) Cookies
* 8080 - EdDSA for DNSSEC
* 8490 - DNS Stateful Operations
* 8499 - DNS Terminology
* 8659 - DNS Certification Authority Authorization (CAA) Resource Record
* 8777 - DNS Reverse IP Automatic Multicast Tunneling (AMT) Discovery
Expand All @@ -192,6 +194,9 @@ Example programs can be found in the `github.com/miekg/exdns` repository.
* 9460 - Service Binding and Parameter Specification via the DNS
* 9461 - Service Binding Mapping for DNS Servers
* 9462 - Discovery of Designated Resolvers
* 9460 - SVCB and HTTPS Records
* 9606 - DNS Resolver Information
* Draft - Compact Denial of Existence in DNSSEC

## Loosely Based Upon

Expand Down
42 changes: 29 additions & 13 deletions dnssec.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,14 +250,6 @@ func (d *DS) ToCDS() *CDS {
// zero, it is used as-is, otherwise the TTL of the RRset is used as the
// OrigTTL.
func (rr *RRSIG) Sign(k crypto.Signer, rrset []RR) error {
if k == nil {
return ErrPrivKey
}
// s.Inception and s.Expiration may be 0 (rollover etc.), the rest must be set
if rr.KeyTag == 0 || len(rr.SignerName) == 0 || rr.Algorithm == 0 {
return ErrKey
}

h0 := rrset[0].Header()
rr.Hdr.Rrtype = TypeRRSIG
rr.Hdr.Name = h0.Name
Expand All @@ -272,6 +264,18 @@ func (rr *RRSIG) Sign(k crypto.Signer, rrset []RR) error {
rr.Labels-- // wildcard, remove from label count
}

return rr.signAsIs(k, rrset)
}

func (rr *RRSIG) signAsIs(k crypto.Signer, rrset []RR) error {
if k == nil {
return ErrPrivKey
}
// s.Inception and s.Expiration may be 0 (rollover etc.), the rest must be set
if rr.KeyTag == 0 || len(rr.SignerName) == 0 || rr.Algorithm == 0 {
return ErrKey
}

sigwire := new(rrsigWireFmt)
sigwire.TypeCovered = rr.TypeCovered
sigwire.Algorithm = rr.Algorithm
Expand Down Expand Up @@ -370,9 +374,12 @@ func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error {
if rr.Algorithm != k.Algorithm {
return ErrKey
}
if !strings.EqualFold(rr.SignerName, k.Hdr.Name) {

signerName := CanonicalName(rr.SignerName)
if !equal(signerName, k.Hdr.Name) {
return ErrKey
}

if k.Protocol != 3 {
return ErrKey
}
Expand All @@ -384,9 +391,18 @@ func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error {
}

// IsRRset checked that we have at least one RR and that the RRs in
// the set have consistent type, class, and name. Also check that type and
// class matches the RRSIG record.
if h0 := rrset[0].Header(); h0.Class != rr.Hdr.Class || h0.Rrtype != rr.TypeCovered {
// the set have consistent type, class, and name. Also check that type,
// class and name matches the RRSIG record.
// Also checks RFC 4035 5.3.1 the number of labels in the RRset owner
// name MUST be greater than or equal to the value in the RRSIG RR's Labels field.
// RFC 4035 5.3.1 Signer's Name MUST be the name of the zone that [contains the RRset].
// Since we don't have SOA info, checking suffix may be the best we can do...?
if h0 := rrset[0].Header(); h0.Class != rr.Hdr.Class ||
h0.Rrtype != rr.TypeCovered ||
uint8(CountLabel(h0.Name)) < rr.Labels ||
!equal(h0.Name, rr.Hdr.Name) ||
!strings.HasSuffix(CanonicalName(h0.Name), signerName) {

return ErrRRset
}

Expand All @@ -400,7 +416,7 @@ func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error {
sigwire.Expiration = rr.Expiration
sigwire.Inception = rr.Inception
sigwire.KeyTag = rr.KeyTag
sigwire.SignerName = CanonicalName(rr.SignerName)
sigwire.SignerName = signerName
// Create the desired binary blob
signeddata := make([]byte, DefaultMsgSize)
n, err := packSigWire(sigwire, signeddata)
Expand Down
111 changes: 111 additions & 0 deletions dnssec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,117 @@ func TestSignVerify(t *testing.T) {
}
}

// Test if RRSIG.Verify() conforms to RFC 4035 Section 5.3.1
func TestShouldNotVerifyInvalidSig(t *testing.T) {
// The RRSIG RR and the RRset MUST have the same owner name
rrNameMismatch := getSoa()
rrNameMismatch.Hdr.Name = "example.com."

// ... and the same class
rrClassMismatch := getSoa()
rrClassMismatch.Hdr.Class = ClassCHAOS

// The RRSIG RR's Type Covered field MUST equal the RRset's type.
rrTypeMismatch := getSoa()
rrTypeMismatch.Hdr.Rrtype = TypeA

// The number of labels in the RRset owner name MUST be greater than
// or equal to the value in the RRSIG RR's Labels field.
rrLabelLessThan := getSoa()
rrLabelLessThan.Hdr.Name = "nl."

// Time checks are done in ValidityPeriod

// With this key
key := new(DNSKEY)
key.Hdr.Rrtype = TypeDNSKEY
key.Hdr.Name = "miek.nl."
key.Hdr.Class = ClassINET
key.Hdr.Ttl = 14400
key.Flags = 256
key.Protocol = 3
key.Algorithm = RSASHA256
privkey, _ := key.Generate(512)

normalSoa := getSoa()

// Fill in the normal values of the Sig, before signing
sig := new(RRSIG)
sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0}
sig.TypeCovered = TypeSOA
sig.Labels = uint8(CountLabel(normalSoa.Hdr.Name))
sig.OrigTtl = normalSoa.Hdr.Ttl
sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05"
sig.Inception = 1293942305 // date -u '+%s' -d"2011-01-02 04:25:05"
sig.KeyTag = key.KeyTag() // Get the keyfrom the Key
sig.SignerName = key.Hdr.Name
sig.Algorithm = RSASHA256

for i, rr := range []RR{rrNameMismatch, rrClassMismatch, rrTypeMismatch, rrLabelLessThan} {
if i != 0 { // Just for the rrNameMismatch case, we need the name to mismatch
sig := sig.copy().(*RRSIG)
sig.SignerName = rr.Header().Name
sig.Hdr.Name = rr.Header().Name
key := key.copy().(*DNSKEY)
key.Hdr.Name = rr.Header().Name
}

if err := sig.signAsIs(privkey.(*rsa.PrivateKey), []RR{rr}); err != nil {
t.Error("failure to sign the record:", err)
continue
}

if err := sig.Verify(key, []RR{rr}); err == nil {
t.Error("should not validate: ", rr)
continue
} else {
t.Logf("expected failure: %v for RR name %s, class %d, type %d, rrsig labels %d", err, rr.Header().Name, rr.Header().Class, rr.Header().Rrtype, CountLabel(rr.Header().Name))
}
}

// The RRSIG RR's Signer's Name field MUST be the name of the zone that contains the RRset.
// The RRSIG RR's Signer's Name, Algorithm, and Key Tag fields MUST match the owner name,
// algorithm, and key tag for some DNSKEY RR in the zone's apex DNSKEY RRset.
sigMismatchName := sig.copy().(*RRSIG)
sigMismatchName.SignerName = "example.com."
soaMismatchName := getSoa()
soaMismatchName.Hdr.Name = "example.com."
keyMismatchName := key.copy().(*DNSKEY)
keyMismatchName.Hdr.Name = "example.com."
if err := sigMismatchName.signAsIs(privkey.(*rsa.PrivateKey), []RR{soaMismatchName}); err != nil {
t.Error("failure to sign the record:", err)
} else if err := sigMismatchName.Verify(keyMismatchName, []RR{soaMismatchName}); err == nil {
t.Error("should not validate: ", soaMismatchName, ", RRSIG's signer's name does not match the owner name")
} else {
t.Logf("expected failure: %v for signer %s and owner %s", err, sigMismatchName.SignerName, sigMismatchName.Hdr.Name)
}

sigMismatchAlgo := sig.copy().(*RRSIG)
sigMismatchAlgo.Algorithm = RSASHA1
sigMismatchKeyTag := sig.copy().(*RRSIG)
sigMismatchKeyTag.KeyTag = 12345
for _, sigMismatch := range []*RRSIG{sigMismatchAlgo, sigMismatchKeyTag} {
if err := sigMismatch.Sign(privkey.(*rsa.PrivateKey), []RR{normalSoa}); err != nil {
t.Error("failure to sign the record:", err)
} else if err := sigMismatch.Verify(key, []RR{normalSoa}); err == nil {
t.Error("should not validate: ", normalSoa)
} else {
t.Logf("expected failure: %v for signer %s algo %d keytag %d", err, sigMismatch.SignerName, sigMismatch.Algorithm, sigMismatch.KeyTag)
}
}

// The matching DNSKEY RR MUST have the Zone Flag bit (DNSKEY RDATA Flag bit 7) set.
keyZoneBitWrong := key.copy().(*DNSKEY)
keyZoneBitWrong.Flags = key.Flags &^ ZONE
if err := sig.Sign(privkey.(*rsa.PrivateKey), []RR{normalSoa}); err != nil {
t.Error("failure to sign the record:", err)
} else if err := sig.Verify(keyZoneBitWrong, []RR{normalSoa}); err == nil {
t.Error("should not validate: ", normalSoa)
} else {
t.Logf("expected failure: %v for key flags %d", err, keyZoneBitWrong.Flags)
}
}

func Test65534(t *testing.T) {
t6 := new(RFC3597)
t6.Hdr = RR_Header{"miek.nl.", 65534, ClassINET, 14400, 0}
Expand Down
Loading