dns/nsecx.go

111 lines
2.5 KiB
Go
Raw Normal View History

2011-01-27 14:52:58 +00:00
package dns
2011-03-07 20:56:36 +00:00
import (
2011-12-09 20:45:57 +00:00
"crypto/sha1"
2011-03-07 21:47:20 +00:00
"hash"
"io"
2011-03-07 21:47:20 +00:00
"strings"
2011-03-07 20:56:36 +00:00
)
2011-03-07 21:47:20 +00:00
type saltWireFmt struct {
Salt string `dns:"size-hex"`
2011-03-07 21:47:20 +00:00
}
2011-01-27 14:52:58 +00:00
2014-06-14 11:48:44 +00:00
// HashName hashes a string (label) according to RFC 5155. It returns the hashed string in
// uppercase.
2012-01-22 09:52:06 +00:00
func HashName(label string, ha uint8, iter uint16, salt string) string {
2011-03-07 21:47:20 +00:00
saltwire := new(saltWireFmt)
saltwire.Salt = salt
wire := make([]byte, DefaultMsgSize)
n, err := PackStruct(saltwire, wire, 0)
if err != nil {
2011-03-07 21:47:20 +00:00
return ""
}
wire = wire[:n]
2011-03-09 13:27:41 +00:00
name := make([]byte, 255)
off, err := PackDomainName(strings.ToLower(label), name, 0, nil, false)
if err != nil {
2011-03-07 21:47:20 +00:00
return ""
}
2011-03-09 13:27:41 +00:00
name = name[:off]
2011-03-07 21:47:20 +00:00
var s hash.Hash
switch ha {
2011-07-08 15:27:44 +00:00
case SHA1:
2011-03-07 21:47:20 +00:00
s = sha1.New()
2011-03-24 08:24:49 +00:00
default:
return ""
2011-03-07 21:47:20 +00:00
}
// k = 0
2011-03-09 13:27:41 +00:00
name = append(name, wire...)
2011-12-16 18:42:30 +00:00
io.WriteString(s, string(name))
nsec3 := s.Sum(nil)
2011-03-24 08:24:49 +00:00
// k > 0
2012-01-22 09:52:06 +00:00
for k := uint16(0); k < iter; k++ {
2011-03-24 08:24:49 +00:00
s.Reset()
nsec3 = append(nsec3, wire...)
2011-12-16 18:42:30 +00:00
io.WriteString(s, string(nsec3))
2011-12-16 14:12:01 +00:00
nsec3 = s.Sum(nil)
2011-03-24 08:24:49 +00:00
}
2011-03-07 21:47:20 +00:00
return unpackBase32(nsec3)
2011-03-07 20:56:36 +00:00
}
2013-12-25 16:01:39 +00:00
type Denialer interface {
// Cover will check if the (unhashed) name is being covered by this NSEC or NSEC3.
Cover(name string) bool
// Match will check if the ownername matches the (unhashed) name for this NSEC3 or NSEC3.
Match(name string) bool
}
// Cover implements the Denialer interface.
func (rr *NSEC) Cover(name string) bool {
2013-12-24 16:54:20 +00:00
return true
}
2013-12-24 16:54:20 +00:00
// Match implements the Denialer interface.
func (rr *NSEC) Match(name string) bool {
return true
}
2013-12-24 16:54:20 +00:00
// Cover implements the Denialer interface.
func (rr *NSEC3) Cover(name string) bool {
// FIXME(miek): check if the zones match
// FIXME(miek): check if we're not dealing with parent nsec3
hname := HashName(name, rr.Hash, rr.Iterations, rr.Salt)
labels := Split(rr.Hdr.Name)
if len(labels) < 2 {
return false
}
2013-12-25 16:01:39 +00:00
hash := strings.ToUpper(rr.Hdr.Name[labels[0] : labels[1]-1]) // -1 to remove the dot
if hash == rr.NextDomain {
return false // empty interval
}
if hash > rr.NextDomain { // last name, points to apex
// hname > hash
// hname > rr.NextDomain
// TODO(miek)
}
if hname <= hash {
return false
}
if hname >= rr.NextDomain {
return false
}
return true
}
2013-12-24 16:54:20 +00:00
// Match implements the Denialer interface.
func (rr *NSEC3) Match(name string) bool {
// FIXME(miek): Check if we are in the same zone
hname := HashName(name, rr.Hash, rr.Iterations, rr.Salt)
labels := Split(rr.Hdr.Name)
if len(labels) < 2 {
return false
}
hash := strings.ToUpper(rr.Hdr.Name[labels[0] : labels[1]-1]) // -1 to remove the .
if hash == hname {
return true
}
return false
}