Add Algo-signal-draft impl. for EDNS0

This commit is contained in:
Miek Gieben 2013-05-11 21:02:17 +02:00
parent ce95cddec1
commit 320d981509
3 changed files with 132 additions and 8 deletions

View File

@ -8,7 +8,7 @@
// //
// Requesting DNSSEC information for a zone is done by adding the DO (DNSSEC OK) bit // Requesting DNSSEC information for a zone is done by adding the DO (DNSSEC OK) bit
// to an request. // to an request.
// //
// m := new(dns.Msg) // m := new(dns.Msg)
// m.SetEdns0(4096, true) // m.SetEdns0(4096, true)
// //
@ -61,7 +61,7 @@ const (
const ( const (
_ = iota _ = iota
SHA1 // RFC 4034 SHA1 // RFC 4034
SHA256 // RFC 4509 SHA256 // RFC 4509
GOST94 // RFC 5933 GOST94 // RFC 5933
SHA384 // Experimental SHA384 // Experimental
SHA512 // Experimental SHA512 // Experimental
@ -309,7 +309,7 @@ func (rr *RRSIG) Sign(k PrivateKey, rrset []RR) error {
// Verify validates an RRSet with the signature and key. This is only the // Verify validates an RRSet with the signature and key. This is only the
// cryptographic test, the signature validity period must be checked separately. // cryptographic test, the signature validity period must be checked separately.
// This function copies the rdata of some RRs (to lowercase domain names) for the validation to work. // 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 { func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error {
// First the easy checks // First the easy checks
if len(rrset) == 0 { if len(rrset) == 0 {
@ -423,7 +423,7 @@ func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error {
return ErrAlg return ErrAlg
} }
// ValidityPeriod uses RFC1982 serial arithmetic to calculate // ValidityPeriod uses RFC1982 serial arithmetic to calculate
// if a signature period is valid. // if a signature period is valid.
func (rr *RRSIG) ValidityPeriod() bool { func (rr *RRSIG) ValidityPeriod() bool {
utc := time.Now().UTC().Unix() utc := time.Now().UTC().Unix()
@ -443,7 +443,7 @@ func (s *RRSIG) sigBuf() []byte {
return sigbuf return sigbuf
} }
// setPublicKeyInPrivate sets the public key in the private key. // setPublicKeyInPrivate sets the public key in the private key.
func (k *DNSKEY) setPublicKeyInPrivate(p PrivateKey) bool { func (k *DNSKEY) setPublicKeyInPrivate(p PrivateKey) bool {
switch t := p.(type) { switch t := p.(type) {
case *dsa.PrivateKey: case *dsa.PrivateKey:
@ -606,7 +606,7 @@ func exponentToBuf(_E int) []byte {
return buf return buf
} }
// Set the public key for X and Y for Curve. The two // Set the public key for X and Y for Curve. The two
// values are just concatenated. // values are just concatenated.
func curveToBuf(_X, _Y *big.Int) []byte { func curveToBuf(_X, _Y *big.Int) []byte {
buf := _X.Bytes() buf := _X.Bytes()
@ -614,7 +614,7 @@ func curveToBuf(_X, _Y *big.Int) []byte {
return buf return buf
} }
// Set the public key for X and Y for Curve. The two // Set the public key for X and Y for Curve. The two
// values are just concatenated. // values are just concatenated.
func dsaToBuf(_Q, _P, _G, _Y *big.Int) []byte { func dsaToBuf(_Q, _P, _G, _Y *big.Int) []byte {
t := byte((len(_G.Bytes()) - 64) / 8) t := byte((len(_G.Bytes()) - 64) / 8)
@ -720,3 +720,15 @@ var AlgorithmToString = map[uint8]string{
// Map of algorithm strings. // Map of algorithm strings.
var StringToAlgorithm = reverseInt8(AlgorithmToString) var StringToAlgorithm = reverseInt8(AlgorithmToString)
// Map for hash names.
var HashToString = map[uint8]string{
SHA1: "SHA1",
SHA256: "SHA256",
GOST94: "GOST94",
SHA384: "SHA384",
SHA512: "SHA512",
}
// Map of hash strings.
var StringToHash = reverseInt8(HashToString)

99
edns.go
View File

@ -38,6 +38,9 @@ const (
EDNS0UL = 0x2 // update lease draft: http://files.dns-sd.org/draft-sekar-dns-ul.txt EDNS0UL = 0x2 // update lease draft: http://files.dns-sd.org/draft-sekar-dns-ul.txt
EDNS0NSID = 0x3 // nsid (RFC5001) EDNS0NSID = 0x3 // nsid (RFC5001)
EDNS0SUBNET = 0x50fa // client-subnet draft: http://tools.ietf.org/html/draft-vandergaast-edns-client-subnet-01 EDNS0SUBNET = 0x50fa // client-subnet draft: http://tools.ietf.org/html/draft-vandergaast-edns-client-subnet-01
EDNS0DAU = 0x4 // DNSSEC Algorithm Understood - not the final number!
EDNS0DHU = 0x5 // DS Hash Understood - not the final number!
EDNS0N3U = 0x6 // NSEC3 Hash Understood - not the final number!
_DO = 1 << 7 // dnssec ok _DO = 1 << 7 // dnssec ok
) )
@ -74,7 +77,15 @@ func (rr *OPT) String() string {
case *EDNS0_SUBNET: case *EDNS0_SUBNET:
s += "\n; SUBNET: " + o.String() s += "\n; SUBNET: " + o.String()
case *EDNS0_UL: case *EDNS0_UL:
s += "\n; LEASE: " + o.String() s += "\n; UPDATE LEASE: " + o.String()
case *EDNS0_LLQ:
s += "\n; LONG LIVED QUERIES: " + o.String()
case *EDNS0_DAU:
s += "\n; DNSSEC ALGORITHM UNDERSTOOD: " + o.String()
case *EDNS0_DHU:
s += "\n; DS HASH UNDERSTOOD: " + o.String()
case *EDNS0_N3U:
s += "\n; NSEC3 HASH UNDERSTOOD: " + o.String()
} }
} }
return s return s
@ -391,3 +402,89 @@ func (e *EDNS0_LLQ) String() string {
" " + strconv.FormatUint(uint64(e.LeaseLife), 10) " " + strconv.FormatUint(uint64(e.LeaseLife), 10)
return s return s
} }
type EDNS0_DAU struct {
Code uint16 // Always EDNS0DAU
AlgCode []uint8
}
func (e *EDNS0_DAU) Option() uint16 {
return EDNS0DAU
}
func (e *EDNS0_DAU) pack() ([]byte, error) {
return e.AlgCode, nil
}
func (e *EDNS0_DAU) unpack(b []byte) {
e.AlgCode = b
}
func (e *EDNS0_DAU) String() string {
s := ""
for i := 0; i < len(e.AlgCode); i++ {
if a, ok := AlgorithmToString[e.AlgCode[i]]; ok {
s += " " + a
} else {
s += " " + strconv.Itoa(int(e.AlgCode[i]))
}
}
return s
}
type EDNS0_DHU struct {
Code uint16 // Always EDNS0DHU
AlgCode []uint8
}
func (e *EDNS0_DHU) Option() uint16 {
return EDNS0DHU
}
func (e *EDNS0_DHU) pack() ([]byte, error) {
return e.AlgCode, nil
}
func (e *EDNS0_DHU) unpack(b []byte) {
e.AlgCode = b
}
func (e *EDNS0_DHU) String() string {
s := ""
for i := 0; i < len(e.AlgCode); i++ {
if a, ok := HashToString[e.AlgCode[i]]; ok {
s += " " + a
} else {
s += " " + strconv.Itoa(int(e.AlgCode[i]))
}
}
return s
}
type EDNS0_N3U struct {
Code uint16 // Always EDNS0N3U
AlgCode []uint8
}
func (e *EDNS0_N3U) Option() uint16 {
return EDNS0N3U
}
func (e *EDNS0_N3U) pack() ([]byte, error) {
return e.AlgCode, nil
}
func (e *EDNS0_N3U) unpack(b []byte) {
e.AlgCode = b
}
func (e *EDNS0_N3U) String() string {
// Re-use the hash map
s := ""
for i := 0; i < len(e.AlgCode); i++ {
if a, ok := HashToString[e.AlgCode[i]]; ok {
s += " " + a
} else {
s += " " + strconv.Itoa(int(e.AlgCode[i]))
}
}
return s
}

15
msg.go
View File

@ -760,6 +760,21 @@ func unpackStructValue(val reflect.Value, msg []byte, off int) (off1 int, err er
e.unpack(msg[off1 : off1+int(optlen)]) e.unpack(msg[off1 : off1+int(optlen)])
edns = append(edns, e) edns = append(edns, e)
off = off1 + int(optlen) off = off1 + int(optlen)
case EDNS0DAU:
e := new(EDNS0_DAU)
e.unpack(msg[off1 : off1+int(optlen)])
edns = append(edns, e)
off = off1 + int(optlen)
case EDNS0DHU:
e := new(EDNS0_DHU)
e.unpack(msg[off1 : off1+int(optlen)])
edns = append(edns, e)
off = off1 + int(optlen)
case EDNS0N3U:
e := new(EDNS0_N3U)
e.unpack(msg[off1 : off1+int(optlen)])
edns = append(edns, e)
off = off1 + int(optlen)
default: default:
// do nothing? // do nothing?
off = off1 + int(optlen) off = off1 + int(optlen)