gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

nsecx.go (2442B)


      1 package dns
      2 
      3 import (
      4 	"crypto/sha1"
      5 	"encoding/hex"
      6 	"strings"
      7 )
      8 
      9 // HashName hashes a string (label) according to RFC 5155. It returns the hashed string in uppercase.
     10 func HashName(label string, ha uint8, iter uint16, salt string) string {
     11 	if ha != SHA1 {
     12 		return ""
     13 	}
     14 
     15 	wireSalt := make([]byte, hex.DecodedLen(len(salt)))
     16 	n, err := packStringHex(salt, wireSalt, 0)
     17 	if err != nil {
     18 		return ""
     19 	}
     20 	wireSalt = wireSalt[:n]
     21 
     22 	name := make([]byte, 255)
     23 	off, err := PackDomainName(strings.ToLower(label), name, 0, nil, false)
     24 	if err != nil {
     25 		return ""
     26 	}
     27 	name = name[:off]
     28 
     29 	s := sha1.New()
     30 	// k = 0
     31 	s.Write(name)
     32 	s.Write(wireSalt)
     33 	nsec3 := s.Sum(nil)
     34 
     35 	// k > 0
     36 	for k := uint16(0); k < iter; k++ {
     37 		s.Reset()
     38 		s.Write(nsec3)
     39 		s.Write(wireSalt)
     40 		nsec3 = s.Sum(nsec3[:0])
     41 	}
     42 
     43 	return toBase32(nsec3)
     44 }
     45 
     46 // Cover returns true if a name is covered by the NSEC3 record.
     47 func (rr *NSEC3) Cover(name string) bool {
     48 	nameHash := HashName(name, rr.Hash, rr.Iterations, rr.Salt)
     49 	owner := strings.ToUpper(rr.Hdr.Name)
     50 	labelIndices := Split(owner)
     51 	if len(labelIndices) < 2 {
     52 		return false
     53 	}
     54 	ownerHash := owner[:labelIndices[1]-1]
     55 	ownerZone := owner[labelIndices[1]:]
     56 	if !IsSubDomain(ownerZone, strings.ToUpper(name)) { // name is outside owner zone
     57 		return false
     58 	}
     59 
     60 	nextHash := rr.NextDomain
     61 
     62 	// if empty interval found, try cover wildcard hashes so nameHash shouldn't match with ownerHash
     63 	if ownerHash == nextHash && nameHash != ownerHash { // empty interval
     64 		return true
     65 	}
     66 	if ownerHash > nextHash { // end of zone
     67 		if nameHash > ownerHash { // covered since there is nothing after ownerHash
     68 			return true
     69 		}
     70 		return nameHash < nextHash // if nameHash is before beginning of zone it is covered
     71 	}
     72 	if nameHash < ownerHash { // nameHash is before ownerHash, not covered
     73 		return false
     74 	}
     75 	return nameHash < nextHash // if nameHash is before nextHash is it covered (between ownerHash and nextHash)
     76 }
     77 
     78 // Match returns true if a name matches the NSEC3 record
     79 func (rr *NSEC3) Match(name string) bool {
     80 	nameHash := HashName(name, rr.Hash, rr.Iterations, rr.Salt)
     81 	owner := strings.ToUpper(rr.Hdr.Name)
     82 	labelIndices := Split(owner)
     83 	if len(labelIndices) < 2 {
     84 		return false
     85 	}
     86 	ownerHash := owner[:labelIndices[1]-1]
     87 	ownerZone := owner[labelIndices[1]:]
     88 	if !IsSubDomain(ownerZone, strings.ToUpper(name)) { // name is outside owner zone
     89 		return false
     90 	}
     91 	if ownerHash == nameHash {
     92 		return true
     93 	}
     94 	return false
     95 }