mirror of
https://github.com/miekg/dns.git
synced 2025-09-25 01:51:01 +02:00
* Remove unused bytes.Buffer from dns/idn.encode. This buffer is truncated and written to but never read from. It serves no purpose and all tests pass with it removed. It appears to have been introduced when puncycode.go was first added in miekg/dns@e3c2c07. * Produce less pointless garbage. This change: - removes several needless []byte -> string conversions, - removes two needless append calls in HashName, and - writes the hash to the same nsec3 []byte in HashName rather than creating a new []byte on each of the k iterations. These are all minor performance improvements that will likely go entirely unnoticed. The changes will reduce the ammount of garbage produced when calling CertificateToDANE, HashName, (*SIG).Sign and TsigGenerate.
119 lines
2.7 KiB
Go
119 lines
2.7 KiB
Go
package dns
|
|
|
|
import (
|
|
"crypto/sha1"
|
|
"hash"
|
|
"strings"
|
|
)
|
|
|
|
type saltWireFmt struct {
|
|
Salt string `dns:"size-hex"`
|
|
}
|
|
|
|
// HashName hashes a string (label) according to RFC 5155. It returns the hashed string in uppercase.
|
|
func HashName(label string, ha uint8, iter uint16, salt string) string {
|
|
saltwire := new(saltWireFmt)
|
|
saltwire.Salt = salt
|
|
wire := make([]byte, DefaultMsgSize)
|
|
n, err := packSaltWire(saltwire, wire)
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
wire = wire[:n]
|
|
name := make([]byte, 255)
|
|
off, err := PackDomainName(strings.ToLower(label), name, 0, nil, false)
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
name = name[:off]
|
|
var s hash.Hash
|
|
switch ha {
|
|
case SHA1:
|
|
s = sha1.New()
|
|
default:
|
|
return ""
|
|
}
|
|
|
|
// k = 0
|
|
s.Write(name)
|
|
s.Write(wire)
|
|
nsec3 := s.Sum(nil)
|
|
// k > 0
|
|
for k := uint16(0); k < iter; k++ {
|
|
s.Reset()
|
|
s.Write(nsec3)
|
|
s.Write(wire)
|
|
nsec3 = s.Sum(nsec3[:0])
|
|
}
|
|
return toBase32(nsec3)
|
|
}
|
|
|
|
// Denialer is an interface that should be implemented by types that are used to denial
|
|
// answers in DNSSEC.
|
|
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 {
|
|
return true
|
|
}
|
|
|
|
// Match implements the Denialer interface.
|
|
func (rr *NSEC) Match(name string) bool {
|
|
return true
|
|
}
|
|
|
|
// 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
|
|
}
|
|
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
|
|
}
|
|
|
|
// 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
|
|
}
|
|
|
|
func packSaltWire(sw *saltWireFmt, msg []byte) (int, error) {
|
|
off, err := packStringHex(sw.Salt, msg, 0)
|
|
if err != nil {
|
|
return off, err
|
|
}
|
|
return off, nil
|
|
}
|