diff --git a/defaults.go b/defaults.go index 09331c9f6..7c5ecae03 100644 --- a/defaults.go +++ b/defaults.go @@ -188,6 +188,33 @@ func IsFqdn(s string) bool { return s[l-1] == '.' } +// IsRRset checks if a set of RRs is a valid RRset as defined by RFC 2181. +// This means the RRs need to have the same type, name, and class. Returns true +// if the RR set is valid, otherwise false. +func IsRRset(rrset []RR) bool { + if len(rrset) == 0 { + return false + } + if len(rrset) == 1 { + return true + } + rrHeader := rrset[0].Header() + rrType := rrHeader.Rrtype + rrClass := rrHeader.Class + rrName := rrHeader.Name + + for _, rr := range rrset[1:] { + curRRHeader := rr.Header() + if curRRHeader.Rrtype != rrType || curRRHeader.Class != rrClass || curRRHeader.Name != rrName { + // Mismatch between the records, so this is not a valid rrset for + //signing/verifying + return false + } + } + + return true +} + // Fqdn return the fully qualified domain name from s. // If s is already fully qualified, it behaves as the identity function. func Fqdn(s string) string { diff --git a/dnssec.go b/dnssec.go index 3b1263c4f..1a993a0e9 100644 --- a/dnssec.go +++ b/dnssec.go @@ -205,33 +205,6 @@ func (d *DS) ToCDS() *CDS { return c } -// isValidRRSet checks if a set of RRs is a valid RRset as defined by RFC 2181. -// This means the RRs need to have the same type, name, and class. Returns true -// if the RR set is valid, otherwise false. -func isValidRRSet(rrset []RR) bool { - if len(rrset) == 0 { - return false - } - if len(rrset) == 1 { - return true - } - rrHeader := rrset[0].Header() - rrType := rrHeader.Rrtype - rrClass := rrHeader.Class - rrName := rrHeader.Name - - for _, rr := range rrset[1:] { - curRRHeader := rr.Header() - if curRRHeader.Rrtype != rrType || curRRHeader.Class != rrClass || curRRHeader.Name != rrName { - // Mismatch between the records, so this is not a valid rrset for - //signing/verifying - return false - } - } - - return true -} - // Sign signs an RRSet. The signature needs to be filled in with // the values: Inception, Expiration, KeyTag, SignerName and Algorithm. // The rest is copied from the RRset. Sign returns true when the signing went OK, @@ -323,7 +296,7 @@ func (rr *RRSIG) Sign(k PrivateKey, rrset []RR) error { // This function copies the rdata of some RRs (to lowercase domain names) for the validation to work. func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error { // First the easy checks - if !isValidRRSet(rrset) { + if !IsRRset(rrset) { return ErrRRset } if rr.KeyTag != k.KeyTag() { @@ -342,7 +315,7 @@ func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error { return ErrKey } - // isValidRRSet checked that we have at least one RR and that the RRs in + // 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 rrset[0].Header().Class != rr.Hdr.Class { diff --git a/dnssec_test.go b/dnssec_test.go index e6c8384fe..0975ed507 100644 --- a/dnssec_test.go +++ b/dnssec_test.go @@ -690,21 +690,21 @@ func TestInvalidRRSet(t *testing.T) { badRecords[0] = &TXT{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello world"}} badRecords[1] = &TXT{Hdr: RR_Header{Name: "nama.cloudflare.com.", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"_o/"}} - if isValidRRSet(badRecords) { + if IsRRset(badRecords) { t.Fatal("Record set with inconsistent names considered valid") } badRecords[0] = &TXT{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello world"}} badRecords[1] = &A{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeA, Class: ClassINET, Ttl: 0}} - if isValidRRSet(badRecords) { + if IsRRset(badRecords) { t.Fatal("Record set with inconsistent record types considered valid") } badRecords[0] = &TXT{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello world"}} badRecords[1] = &TXT{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeTXT, Class: ClassCHAOS, Ttl: 0}, Txt: []string{"_o/"}} - if isValidRRSet(badRecords) { + if IsRRset(badRecords) { t.Fatal("Record set with inconsistent record class considered valid") }