Remove unwanted wire conversion functions
This commit is contained in:
parent
728b575b60
commit
a60238bdde
107
dns.go
107
dns.go
|
@ -10,7 +10,9 @@
|
||||||
// * 1876 - LOC record (incomplete)
|
// * 1876 - LOC record (incomplete)
|
||||||
// * 1995 - IXFR
|
// * 1995 - IXFR
|
||||||
// * 1996 - DNS notify
|
// * 1996 - DNS notify
|
||||||
|
// * 2181 - RRset definition
|
||||||
// * 2537 - RSAMD5 DNS keys
|
// * 2537 - RSAMD5 DNS keys
|
||||||
|
// * 2065 - DNSSEC (updated in later RFCs)
|
||||||
// * 2671 - EDNS
|
// * 2671 - EDNS
|
||||||
// * 2845 - TSIG
|
// * 2845 - TSIG
|
||||||
// * 2915 - NAPTR record (incomplete)
|
// * 2915 - NAPTR record (incomplete)
|
||||||
|
@ -27,24 +29,22 @@ package dns
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"os"
|
|
||||||
"net"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const Year68 = 2 << (32 - 1)
|
const Year68 = 2 << (32 - 1)
|
||||||
|
|
||||||
type Error struct {
|
type Error struct {
|
||||||
Error string
|
Error string
|
||||||
Name string
|
Name string
|
||||||
Server string
|
Server string
|
||||||
Timeout bool
|
Timeout bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Error) String() string {
|
func (e *Error) String() string {
|
||||||
if e == nil {
|
if e == nil {
|
||||||
return "<nil>"
|
return "<nil>"
|
||||||
}
|
}
|
||||||
return e.Error
|
return e.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
type RR interface {
|
type RR interface {
|
||||||
|
@ -93,85 +93,12 @@ func (h *RR_Header) String() string {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
func SendTCP(c net.Conn, m []byte) os.Error {
|
// Return number of labels in a dname
|
||||||
l := make([]byte, 2)
|
func labelCount(a string) (c int) {
|
||||||
l[0] = byte(len(m) >> 8)
|
for _, v := range a {
|
||||||
l[1] = byte(len(m))
|
if v == '.' {
|
||||||
// First we send the length
|
c++
|
||||||
_, err := c.Write(l)
|
}
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// And the the message
|
|
||||||
_, err = c.Write(m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func RecvTCP(c net.Conn) ([]byte, os.Error) {
|
|
||||||
l := make([]byte, 2) // receiver length
|
|
||||||
// The server replies with two bytes length
|
|
||||||
_, err := c.Read(l)
|
|
||||||
if err != nil {
|
|
||||||
return nil,err
|
|
||||||
}
|
|
||||||
length := uint16(l[0])<<8 | uint16(l[1])
|
|
||||||
if length == 0 {
|
|
||||||
return nil, &Error{Error: "received nil msg length", Server: c.RemoteAddr().String()}
|
|
||||||
}
|
|
||||||
m := make([]byte, length)
|
|
||||||
n, cerr := c.Read(m)
|
|
||||||
if cerr != nil {
|
|
||||||
return nil, cerr
|
|
||||||
}
|
|
||||||
i := n
|
|
||||||
if i < int(length) {
|
|
||||||
n, err = c.Read(m[i:])
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
i += n
|
|
||||||
}
|
|
||||||
return m, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Or expose the pack/unpack functions??
|
|
||||||
// These were created for dnssec.go, but now that
|
|
||||||
// that package is included again in dns, they are
|
|
||||||
// not really needed. These will be removed asap.
|
|
||||||
// Return the wiredata of rdata portion of a RR.
|
|
||||||
func WireRdata(r RR) ([]byte, bool) {
|
|
||||||
buf := make([]byte, 4096) // Too large, need to FIX TODO(mg)
|
|
||||||
off1, ok := packRR(r, buf, 0)
|
|
||||||
if !ok {
|
|
||||||
return nil, false
|
|
||||||
}
|
}
|
||||||
start := off1 - int(r.Header().Rdlength)
|
return
|
||||||
end := start + int(r.Header().Rdlength)
|
|
||||||
buf = buf[start:end]
|
|
||||||
return buf, true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the wiredata of a domainname (sans compressions).
|
|
||||||
func WireDomainName(s string) ([]byte, bool) {
|
|
||||||
buf := make([]byte, 255)
|
|
||||||
off, ok := packDomainName(s, buf, 0)
|
|
||||||
if !ok {
|
|
||||||
return nil, ok
|
|
||||||
}
|
|
||||||
buf = buf[:off]
|
|
||||||
return buf, ok
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the wiredata of a complete Resource Record.
|
|
||||||
func WireRR(r RR) ([]byte, bool) {
|
|
||||||
buf := make([]byte, 4096)
|
|
||||||
off, ok := packRR(r, buf, 0)
|
|
||||||
if !ok {
|
|
||||||
return nil, false
|
|
||||||
}
|
|
||||||
buf = buf[:off]
|
|
||||||
return buf, ok
|
|
||||||
}
|
}
|
||||||
|
|
141
dnssec.go
141
dnssec.go
|
@ -37,6 +37,29 @@ const (
|
||||||
HashGOST94
|
HashGOST94
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// The RRSIG needs to be converted to wireformat with some of
|
||||||
|
// the rdata (the signature) missing. Use this struct to easy
|
||||||
|
// the conversion (and re-use the pack/unpack functions.
|
||||||
|
type rrsigWireFmt struct {
|
||||||
|
TypeCovered uint16
|
||||||
|
Algorithm uint8
|
||||||
|
Labels uint8
|
||||||
|
OrigTtl uint32
|
||||||
|
Expiration uint32
|
||||||
|
Inception uint32
|
||||||
|
KeyTag uint16
|
||||||
|
SignerName string "domain-name"
|
||||||
|
/* No Signature */
|
||||||
|
}
|
||||||
|
|
||||||
|
// Used for converting DNSKEY's rdata to wirefmt.
|
||||||
|
type dnskeyWireFmt struct {
|
||||||
|
Flags uint16
|
||||||
|
Protocol uint8
|
||||||
|
Algorithm uint8
|
||||||
|
PubKey string "base64"
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate the keytag of the DNSKEY.
|
// Calculate the keytag of the DNSKEY.
|
||||||
func (k *RR_DNSKEY) KeyTag() uint16 {
|
func (k *RR_DNSKEY) KeyTag() uint16 {
|
||||||
var keytag int
|
var keytag int
|
||||||
|
@ -45,13 +68,17 @@ func (k *RR_DNSKEY) KeyTag() uint16 {
|
||||||
println("Keytag RSAMD5. Todo")
|
println("Keytag RSAMD5. Todo")
|
||||||
keytag = 0
|
keytag = 0
|
||||||
default:
|
default:
|
||||||
// Might encode header length too, so that
|
keywire := new(dnskeyWireFmt)
|
||||||
// we dont need to pack/unpack all the time
|
keywire.Flags = k.Flags
|
||||||
// Or a shadow structure, with the wiredata and header
|
keywire.Protocol = k.Protocol
|
||||||
wire, ok := WireRdata(k)
|
keywire.Algorithm = k.Algorithm
|
||||||
|
keywire.PubKey = k.PubKey
|
||||||
|
wire := make([]byte, 2048) // TODO(mg) lenght!
|
||||||
|
n, ok := packStruct(keywire, wire, 0)
|
||||||
if !ok {
|
if !ok {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
wire = wire[:n]
|
||||||
for i, v := range wire {
|
for i, v := range wire {
|
||||||
if i&1 != 0 {
|
if i&1 != 0 {
|
||||||
keytag += int(v) // must be larger than uint32
|
keytag += int(v) // must be larger than uint32
|
||||||
|
@ -75,14 +102,24 @@ func (k *RR_DNSKEY) ToDS(h int) *RR_DS {
|
||||||
ds.DigestType = uint8(h)
|
ds.DigestType = uint8(h)
|
||||||
ds.KeyTag = k.KeyTag()
|
ds.KeyTag = k.KeyTag()
|
||||||
|
|
||||||
wire, ok := WireRdata(k)
|
keywire := new(dnskeyWireFmt)
|
||||||
if !ok {
|
keywire.Flags = k.Flags
|
||||||
return nil
|
keywire.Protocol = k.Protocol
|
||||||
}
|
keywire.Algorithm = k.Algorithm
|
||||||
owner, ok1 := WireDomainName(k.Hdr.Name)
|
keywire.PubKey = k.PubKey
|
||||||
|
wire := make([]byte, 2048) // TODO(mg) lenght!
|
||||||
|
n, ok := packStruct(keywire, wire, 0)
|
||||||
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
wire = wire[:n]
|
||||||
|
|
||||||
|
owner := make([]byte, 255)
|
||||||
|
off, ok1 := packDomainName(k.Hdr.Name, owner, 0)
|
||||||
if !ok1 {
|
if !ok1 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
owner = owner[:off]
|
||||||
/*
|
/*
|
||||||
* from RFC4034
|
* from RFC4034
|
||||||
* digest = digest_algorithm( DNSKEY owner name | DNSKEY RDATA);
|
* digest = digest_algorithm( DNSKEY owner name | DNSKEY RDATA);
|
||||||
|
@ -110,9 +147,32 @@ func (k *RR_DNSKEY) ToDS(h int) *RR_DS {
|
||||||
return ds
|
return ds
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sign rrset with k and return the signature RR.
|
// Sign rrset with k and return the signature RR. There
|
||||||
func (k *RR_DNSKEY) Sign(rrset RRset) (*RR_RRSIG) {
|
// is no check if rrset is a proper (RFC 2181) RRSet
|
||||||
return nil
|
func (k *RR_DNSKEY) Sign(rrset RRset, expiration, inception uint32) *RR_RRSIG {
|
||||||
|
sig := new(RR_RRSIG)
|
||||||
|
sig.Hdr.Name = rrset[0].Header().Name
|
||||||
|
sig.Hdr.Class = rrset[0].Header().Class
|
||||||
|
sig.Hdr.Rrtype = TypeRRSIG
|
||||||
|
sig.Hdr.Ttl = rrset[0].Header().Ttl // re-use TTL of RRset
|
||||||
|
sig.Inception = inception
|
||||||
|
sig.Expiration = expiration
|
||||||
|
sig.KeyTag = k.KeyTag()
|
||||||
|
sig.SignerName = k.Hdr.Name
|
||||||
|
sig.Labels = uint8(labelCount(rrset[0].Header().Name))
|
||||||
|
sig.TypeCovered = rrset[0].Header().Rrtype
|
||||||
|
|
||||||
|
sigwire := new(rrsigWireFmt)
|
||||||
|
sigwire.TypeCovered = sig.TypeCovered
|
||||||
|
sigwire.Algorithm = sig.Algorithm
|
||||||
|
sigwire.Labels = sig.Labels
|
||||||
|
sigwire.OrigTtl = sig.OrigTtl
|
||||||
|
sigwire.Expiration = sig.Expiration
|
||||||
|
sigwire.Inception = sig.Inception
|
||||||
|
sigwire.KeyTag = sig.KeyTag
|
||||||
|
sigwire.SignerName = sig.SignerName
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate an rrset with the signature and key. This is the
|
// Validate an rrset with the signature and key. This is the
|
||||||
|
@ -150,11 +210,22 @@ func (s *RR_RRSIG) Verify(k *RR_DNSKEY, rrset RRset) bool {
|
||||||
|
|
||||||
// RFC 4035 5.3.2. Reconstructing the Signed Data
|
// RFC 4035 5.3.2. Reconstructing the Signed Data
|
||||||
// Copy the sig, except the rrsig data
|
// Copy the sig, except the rrsig data
|
||||||
s1 := &RR_RRSIG{s.Hdr, s.TypeCovered, s.Algorithm, s.Labels, s.OrigTtl, s.Expiration, s.Inception, s.KeyTag, s.SignerName, ""}
|
sigwire := new(rrsigWireFmt)
|
||||||
signeddata, ok := WireRdata(s1)
|
sigwire.TypeCovered = s.TypeCovered
|
||||||
|
sigwire.Algorithm = s.Algorithm
|
||||||
|
sigwire.Labels = s.Labels
|
||||||
|
sigwire.OrigTtl = s.OrigTtl
|
||||||
|
sigwire.Expiration = s.Expiration
|
||||||
|
sigwire.Inception = s.Inception
|
||||||
|
sigwire.KeyTag = s.KeyTag
|
||||||
|
sigwire.SignerName = s.SignerName
|
||||||
|
// Create the desired binary blob
|
||||||
|
signeddata := make([]byte, 4096)
|
||||||
|
n, ok := packStruct(sigwire, signeddata, 0)
|
||||||
if !ok {
|
if !ok {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
signeddata = signeddata[:n]
|
||||||
|
|
||||||
for _, r := range rrset {
|
for _, r := range rrset {
|
||||||
h := r.Header()
|
h := r.Header()
|
||||||
|
@ -172,9 +243,16 @@ func (s *RR_RRSIG) Verify(k *RR_DNSKEY, rrset RRset) bool {
|
||||||
}
|
}
|
||||||
// 6.2. Canonical RR Form. (4) - wildcards, don't understand
|
// 6.2. Canonical RR Form. (4) - wildcards, don't understand
|
||||||
// 6.2. Canonical RR Form. (5) - origTTL
|
// 6.2. Canonical RR Form. (5) - origTTL
|
||||||
|
|
||||||
ttl := h.Ttl
|
ttl := h.Ttl
|
||||||
h.Ttl = s.OrigTtl
|
h.Ttl = s.OrigTtl
|
||||||
wire, ok1 := WireRR(r)
|
wire := make([]byte, 4096)
|
||||||
|
off, ok1 := packRR(r, wire, 0)
|
||||||
|
if !ok1 {
|
||||||
|
println("Failure to pack")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
wire = wire[:off]
|
||||||
h.Ttl = ttl // restore the order in the universe
|
h.Ttl = ttl // restore the order in the universe
|
||||||
h.Name = name
|
h.Name = name
|
||||||
if !ok1 {
|
if !ok1 {
|
||||||
|
@ -184,22 +262,12 @@ func (s *RR_RRSIG) Verify(k *RR_DNSKEY, rrset RRset) bool {
|
||||||
signeddata = append(signeddata, wire...)
|
signeddata = append(signeddata, wire...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Buffer holding the key data
|
sigbuf := s.sigBuf() // Get the binary signature data
|
||||||
keybuf := make([]byte, 1024)
|
|
||||||
keybuflen := base64.StdEncoding.DecodedLen(len(k.PubKey))
|
|
||||||
keybuflen, _ = base64.StdEncoding.Decode(keybuf[0:keybuflen], []byte(k.PubKey))
|
|
||||||
keybuf = keybuf[:keybuflen]
|
|
||||||
|
|
||||||
// Buffer holding the signature
|
|
||||||
sigbuf := make([]byte, 1024)
|
|
||||||
sigbuflen := base64.StdEncoding.DecodedLen(len(s.Signature))
|
|
||||||
sigbuflen, _ = base64.StdEncoding.Decode(sigbuf[0:sigbuflen], []byte(s.Signature))
|
|
||||||
sigbuf = sigbuf[:sigbuflen]
|
|
||||||
|
|
||||||
var err os.Error
|
var err os.Error
|
||||||
switch s.Algorithm {
|
switch s.Algorithm {
|
||||||
case AlgRSASHA1, AlgRSASHA256, AlgRSASHA512, AlgRSAMD5:
|
case AlgRSASHA1, AlgRSASHA256, AlgRSASHA512, AlgRSAMD5:
|
||||||
pubkey := rsaPubKey(keybuf)
|
pubkey := k.pubKeyRSA() // Get the key
|
||||||
// Setup the hash as defined for this alg.
|
// Setup the hash as defined for this alg.
|
||||||
var h hash.Hash
|
var h hash.Hash
|
||||||
var ch rsa.PKCS1v15Hash
|
var ch rsa.PKCS1v15Hash
|
||||||
|
@ -239,8 +307,23 @@ func (s *RR_RRSIG) PeriodOK() bool {
|
||||||
return ti <= utc && utc <= te
|
return ti <= utc && utc <= te
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extra the RSA public key from the buffer
|
// Return the signatures base64 encodedig sigdata as a byte slice.
|
||||||
func rsaPubKey(keybuf []byte) *rsa.PublicKey {
|
func (s *RR_RRSIG) sigBuf() []byte {
|
||||||
|
sigbuf := make([]byte, 1024) // TODO(mg) length!
|
||||||
|
sigbuflen := base64.StdEncoding.DecodedLen(len(s.Signature))
|
||||||
|
sigbuflen, _ = base64.StdEncoding.Decode(sigbuf[0:sigbuflen], []byte(s.Signature))
|
||||||
|
sigbuf = sigbuf[:sigbuflen]
|
||||||
|
return sigbuf
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract the RSA public key from the Key record
|
||||||
|
func (k *RR_DNSKEY) pubKeyRSA() *rsa.PublicKey {
|
||||||
|
// Buffer holding the key data
|
||||||
|
keybuf := make([]byte, 1024)
|
||||||
|
keybuflen := base64.StdEncoding.DecodedLen(len(k.PubKey))
|
||||||
|
keybuflen, _ = base64.StdEncoding.Decode(keybuf[0:keybuflen], []byte(k.PubKey))
|
||||||
|
keybuf = keybuf[:keybuflen]
|
||||||
|
|
||||||
// RFC 2537/3110, section 2. RSA Public KEY Resource Records
|
// RFC 2537/3110, section 2. RSA Public KEY Resource Records
|
||||||
// Length is in the 0th byte, unless its zero, then it
|
// Length is in the 0th byte, unless its zero, then it
|
||||||
// it in bytes 1 and 2 and its a 16 bit number
|
// it in bytes 1 and 2 and its a 16 bit number
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2009 The Go Authors. All rights reserved.
|
// Copyright 2011 Miek Gieben. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,21 @@
|
||||||
// Copyright 2009 The Go Authors. All rights reserved.
|
// Copyright 2011 Miek Gieben. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// DNS server implementation
|
// DNS server implementation
|
||||||
|
|
||||||
// Package responder implements a DNS server
|
// Package responder implements a DNS server. A nameserver needs to implement
|
||||||
|
// the Responder interface:
|
||||||
|
//
|
||||||
|
// type myserv Server
|
||||||
|
// func (s *myserv) ResponderUDP(c *net.UDPConn, a net.Addr, in []byte) { /* UDP reply */ }
|
||||||
|
// func (s *myserv) ResponderTCP(c *net.TCPConn, in []byte) { /* TCP reply */}
|
||||||
|
// su := new(Server) // create new sever
|
||||||
|
// su.Address = "127.0.0.1" // listen address
|
||||||
|
// su.Port = "8053" // listen port
|
||||||
|
// var us *myserv
|
||||||
|
// uch :=make(chan bool)
|
||||||
|
// go su.NewResponder(us, uch) // start the responder
|
||||||
package responder
|
package responder
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -13,6 +24,7 @@ import (
|
||||||
"dns"
|
"dns"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Options for a nameserver.
|
||||||
type Server struct {
|
type Server struct {
|
||||||
Address string // interface to use, for multiple interfaces, use multiple servers
|
Address string // interface to use, for multiple interfaces, use multiple servers
|
||||||
Port string // what port to use
|
Port string // what port to use
|
||||||
|
|
4
tsig.go
4
tsig.go
|
@ -49,7 +49,7 @@ func (rr *RR_TSIG) String() string {
|
||||||
// The following values must be put in wireformat, so that
|
// The following values must be put in wireformat, so that
|
||||||
// the MAC can be calculated
|
// the MAC can be calculated
|
||||||
// RFC 2845, section 3.4.2. TSIG Variables
|
// RFC 2845, section 3.4.2. TSIG Variables
|
||||||
type tsig_generation_fmt struct {
|
type tsigWireFmt struct {
|
||||||
// From RR_HEADER
|
// From RR_HEADER
|
||||||
Name string "domain-name"
|
Name string "domain-name"
|
||||||
Class uint16
|
Class uint16
|
||||||
|
@ -70,7 +70,7 @@ type tsig_generation_fmt struct {
|
||||||
// secret is encoded in base64 in BIND9
|
// secret is encoded in base64 in BIND9
|
||||||
func (rr *RR_TSIG) Generate(msg *Msg, secret string) bool {
|
func (rr *RR_TSIG) Generate(msg *Msg, secret string) bool {
|
||||||
buf := make([]byte, 4096) // TODO(mg) bufsize!
|
buf := make([]byte, 4096) // TODO(mg) bufsize!
|
||||||
tsig := new(tsig_generation_fmt)
|
tsig := new(tsigWireFmt)
|
||||||
|
|
||||||
// Fill the struct and generate the wiredata
|
// Fill the struct and generate the wiredata
|
||||||
tsig.Name = rr.Header().Name
|
tsig.Name = rr.Header().Name
|
||||||
|
|
Loading…
Reference in New Issue