Getting there
This commit is contained in:
parent
37fddc0178
commit
858f602a15
150
zone.go
150
zone.go
|
@ -94,6 +94,7 @@ type ZoneData struct {
|
||||||
Name string // Domain name for this node
|
Name string // Domain name for this node
|
||||||
RR map[uint16][]RR // Map of the RR type to the RR
|
RR map[uint16][]RR // Map of the RR type to the RR
|
||||||
Signatures map[uint16][]*RR_RRSIG // DNSSEC signatures for the RRs, stored under type covered
|
Signatures map[uint16][]*RR_RRSIG // DNSSEC signatures for the RRs, stored under type covered
|
||||||
|
// moet een map[uint16]map[uint16]*RR_RRSIG worden, typeocvert + keyid
|
||||||
NonAuth bool // Always false, except for NSsets that differ from z.Origin
|
NonAuth bool // Always false, except for NSsets that differ from z.Origin
|
||||||
*sync.RWMutex
|
*sync.RWMutex
|
||||||
}
|
}
|
||||||
|
@ -408,6 +409,7 @@ func (z *Zone) isSubDomain(child string) bool {
|
||||||
// describes how the zone must be signed and if the SEP flag (for KSK)
|
// describes how the zone must be signed and if the SEP flag (for KSK)
|
||||||
// should be honored. If signatures approach their expriration time, they
|
// should be honored. If signatures approach their expriration time, they
|
||||||
// are refreshed with the current set of keys. Valid signatures are left alone.
|
// are refreshed with the current set of keys. Valid signatures are left alone.
|
||||||
|
// Valid signatures from unknown keys are dropped.
|
||||||
//
|
//
|
||||||
// Basic use pattern for signing a zone with the default SignatureConfig:
|
// Basic use pattern for signing a zone with the default SignatureConfig:
|
||||||
//
|
//
|
||||||
|
@ -417,10 +419,8 @@ func (z *Zone) isSubDomain(child string) bool {
|
||||||
// // signing error
|
// // signing error
|
||||||
// }
|
// }
|
||||||
// // Admire your signed zone...
|
// // Admire your signed zone...
|
||||||
//
|
|
||||||
// TODO(mg): resigning is not implemented
|
|
||||||
// TODO(mg): NSEC3 is not implemented
|
|
||||||
func (z *Zone) Sign(keys map[*RR_DNSKEY]PrivateKey, config *SignatureConfig) error {
|
func (z *Zone) Sign(keys map[*RR_DNSKEY]PrivateKey, config *SignatureConfig) error {
|
||||||
|
// TODO(mg): NSEC3 is not implemented
|
||||||
z.Lock()
|
z.Lock()
|
||||||
defer z.Unlock()
|
defer z.Unlock()
|
||||||
if config == nil {
|
if config == nil {
|
||||||
|
@ -492,66 +492,37 @@ func signerRoutine(wg *sync.WaitGroup, keys map[*RR_DNSKEY]PrivateKey, keytags m
|
||||||
// during the execution. It is important that the nodes' next record does not
|
// during the execution. It is important that the nodes' next record does not
|
||||||
// change. The caller must take care that the zone itself is also locked for writing.
|
// change. The caller must take care that the zone itself is also locked for writing.
|
||||||
// For a more complete description see zone.Sign.
|
// For a more complete description see zone.Sign.
|
||||||
// Note: as this method has no (direct)
|
// Note, because this method has no (direct)
|
||||||
// access to the zone's SOA record, the SOA's Minttl value should be set in *config.
|
// access to the zone's SOA record, the SOA's Minttl value should be set in *config.
|
||||||
func (node *ZoneData) Sign(next *ZoneData, keys map[*RR_DNSKEY]PrivateKey, keytags map[*RR_DNSKEY]uint16, config *SignatureConfig) error {
|
func (node *ZoneData) Sign(next *ZoneData, keys map[*RR_DNSKEY]PrivateKey, keytags map[*RR_DNSKEY]uint16, config *SignatureConfig) error {
|
||||||
node.Lock()
|
node.Lock()
|
||||||
defer node.Unlock()
|
defer node.Unlock()
|
||||||
|
|
||||||
nsec := new(RR_NSEC)
|
// NSEC checks: is it already there, check consitency or add a new one.
|
||||||
nsec.Hdr.Rrtype = TypeNSEC
|
bitmap := make([]uint16, 0)
|
||||||
nsec.Hdr.Ttl = config.Minttl // SOA's minimum value
|
for t, _ := range node.RR {
|
||||||
nsec.Hdr.Name = node.Name
|
bitmap = append(bitmap, t)
|
||||||
nsec.NextDomain = next.Name // Only thing I need from next, actually
|
|
||||||
nsec.Hdr.Class = ClassINET
|
|
||||||
|
|
||||||
// Still need to add NSEC + RRSIG for this data, there might also be a DS record
|
|
||||||
if node.NonAuth == true {
|
|
||||||
for t, _ := range node.RR {
|
|
||||||
nsec.TypeBitMap = append(nsec.TypeBitMap, t)
|
|
||||||
}
|
|
||||||
nsec.TypeBitMap = append(nsec.TypeBitMap, TypeRRSIG) // Add sig too
|
|
||||||
nsec.TypeBitMap = append(nsec.TypeBitMap, TypeNSEC) // Add me too!
|
|
||||||
sort.Sort(uint16Slice(nsec.TypeBitMap))
|
|
||||||
node.RR[TypeNSEC] = []RR{nsec}
|
|
||||||
now := time.Now().UTC()
|
|
||||||
for k, p := range keys {
|
|
||||||
if config.HonorSepFlag && k.Flags&SEP == SEP {
|
|
||||||
// only sign keys with SEP keys
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// which sigs to check??
|
|
||||||
|
|
||||||
s := new(RR_RRSIG)
|
|
||||||
s.SignerName = k.Hdr.Name
|
|
||||||
s.Hdr.Ttl = k.Hdr.Ttl
|
|
||||||
s.Algorithm = k.Algorithm
|
|
||||||
s.KeyTag = keytags[k]
|
|
||||||
s.Inception = timeToUint32(now.Add(-config.InceptionOffset))
|
|
||||||
s.Expiration = timeToUint32(now.Add(jitterDuration(config.Jitter)).Add(config.Validity))
|
|
||||||
e := s.Sign(p, []RR{nsec})
|
|
||||||
if e != nil {
|
|
||||||
return e
|
|
||||||
}
|
|
||||||
node.Signatures[TypeNSEC] = append(node.Signatures[TypeNSEC], s)
|
|
||||||
// DS
|
|
||||||
if ds, ok := node.RR[TypeDS]; ok {
|
|
||||||
s := new(RR_RRSIG)
|
|
||||||
s.SignerName = k.Hdr.Name
|
|
||||||
s.Hdr.Ttl = k.Hdr.Ttl
|
|
||||||
s.Algorithm = k.Algorithm
|
|
||||||
s.KeyTag = keytags[k]
|
|
||||||
s.Inception = timeToUint32(now.Add(-config.InceptionOffset))
|
|
||||||
s.Expiration = timeToUint32(now.Add(jitterDuration(config.Jitter)).Add(config.Validity))
|
|
||||||
e := s.Sign(p, ds)
|
|
||||||
if e != nil {
|
|
||||||
return e
|
|
||||||
}
|
|
||||||
node.Signatures[TypeDS] = append(node.Signatures[TypeDS], s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
bitmap = append(nsec.TypeBitMap, TypeRRSIG) // Add sig too
|
||||||
|
bitmap = append(nsec.TypeBitMap, TypeNSEC) // Add me too!
|
||||||
|
sort.Sort(uint16Slice(bitmap))
|
||||||
|
|
||||||
|
if v, ok := node.RR[TypeNSEC]; ok {
|
||||||
|
// There is an NSEC, check if it still points to the correct next node.
|
||||||
|
// Secondly the type bitmap may have chagned.
|
||||||
|
if v.(*RR_NSEC).NextDomain != next.Name || v.(*RR_NSEC).TypeBitMap != bitmap {
|
||||||
|
v.(*RR_NSEC).NextDomain = next.Name
|
||||||
|
v.(*RR_NSEC).TypeBitMap = bitmap
|
||||||
|
node.Signatures[TypeNSEC] = nil // drop all sigs
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// No NSEC at all, create one
|
||||||
|
nsec := &RR_NSEC{Hdr: RR_Header{node.Name, TypeNSEC, ClassINET, config.MinTtl, 0}, NextDomain: next.Name}
|
||||||
|
nsec.TypeBitMap = bitmap
|
||||||
|
node.RR[TypeNSEC] = []{nsec}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Walk all keys, and check the sigs
|
||||||
now := time.Now().UTC()
|
now := time.Now().UTC()
|
||||||
for k, p := range keys {
|
for k, p := range keys {
|
||||||
for t, rrset := range node.RR {
|
for t, rrset := range node.RR {
|
||||||
|
@ -561,43 +532,48 @@ func (node *ZoneData) Sign(next *ZoneData, keys map[*RR_DNSKEY]PrivateKey, keyta
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if node.NonAuth == true {
|
||||||
s := new(RR_RRSIG)
|
_, ok1 := rrset[0].(*RR_DS)
|
||||||
s.SignerName = k.Hdr.Name
|
_, ok2 := rrset[0].(*RR_NSEC)
|
||||||
s.Hdr.Ttl = k.Hdr.Ttl
|
if !ok1 && !ok2 {
|
||||||
s.Hdr.Class = ClassINET
|
continue
|
||||||
s.Algorithm = k.Algorithm
|
}
|
||||||
s.KeyTag = keytags[k]
|
}
|
||||||
s.Inception = timeToUint32(now.Add(-config.InceptionOffset))
|
|
||||||
s.Expiration = timeToUint32(now.Add(jitterDuration(config.Jitter)).Add(config.Validity))
|
s = signatures(node, t, keytags[k])
|
||||||
e := s.Sign(p, rrset)
|
if s == nil || now.Sub(uint32ToTime(s.Expiration)) < config.Refresh { // no there, are almost expired
|
||||||
if e != nil {
|
s := new(RR_RRSIG)
|
||||||
return e
|
s.SignerName = k.Hdr.Name
|
||||||
|
s.Hdr.Ttl = k.Hdr.Ttl
|
||||||
|
s.Hdr.Class = ClassINET
|
||||||
|
s.Algorithm = k.Algorithm
|
||||||
|
s.KeyTag = keytags[k]
|
||||||
|
s.Inception = timeToUint32(now.Add(-config.InceptionOffset))
|
||||||
|
s.Expiration = timeToUint32(now.Add(jitterDuration(config.Jitter)).Add(config.Validity))
|
||||||
|
e := s.Sign(p, rrset)
|
||||||
|
if e != nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
node.Signatures[t] = append(node.Signatures[t], s)
|
||||||
}
|
}
|
||||||
node.Signatures[t] = append(node.Signatures[t], s)
|
|
||||||
nsec.TypeBitMap = append(nsec.TypeBitMap, t)
|
|
||||||
}
|
}
|
||||||
nsec.TypeBitMap = append(nsec.TypeBitMap, TypeRRSIG) // Add sig too
|
}
|
||||||
nsec.TypeBitMap = append(nsec.TypeBitMap, TypeNSEC) // Add me too!
|
// No cross check, if all sigs are made by a known key
|
||||||
sort.Sort(uint16Slice(nsec.TypeBitMap))
|
return nil
|
||||||
node.RR[TypeNSEC] = []RR{nsec}
|
}
|
||||||
// NSEC
|
|
||||||
s := new(RR_RRSIG)
|
// Return the signature for the typecovered and make with the keytag
|
||||||
s.SignerName = k.Hdr.Name
|
func signatures(z *ZoneData, typecovered, keytag uint16) *RR_RRSIG {
|
||||||
s.Hdr.Ttl = k.Hdr.Ttl
|
for _, s := range z.Signatures[typecovered] {
|
||||||
s.Algorithm = k.Algorithm
|
if s.KeyTag == keytag {
|
||||||
s.KeyTag = keytags[k]
|
return s
|
||||||
s.Inception = timeToUint32(now.Add(-config.InceptionOffset))
|
|
||||||
s.Expiration = timeToUint32(now.Add(jitterDuration(config.Jitter)).Add(config.Validity))
|
|
||||||
e := s.Sign(p, []RR{nsec})
|
|
||||||
if e != nil {
|
|
||||||
return e
|
|
||||||
}
|
}
|
||||||
node.Signatures[TypeNSEC] = append(node.Signatures[TypeNSEC], s)
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// timeToUint32 translates a time.Time to a 32 bit value which
|
// timeToUint32 translates a time.Time to a 32 bit value which
|
||||||
// can be used as the RRSIG's inception or expiration times.
|
// can be used as the RRSIG's inception or expiration times.
|
||||||
func timeToUint32(t time.Time) uint32 {
|
func timeToUint32(t time.Time) uint32 {
|
||||||
|
|
Loading…
Reference in New Issue