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)
|
||||
// * 1995 - IXFR
|
||||
// * 1996 - DNS notify
|
||||
// * 2181 - RRset definition
|
||||
// * 2537 - RSAMD5 DNS keys
|
||||
// * 2065 - DNSSEC (updated in later RFCs)
|
||||
// * 2671 - EDNS
|
||||
// * 2845 - TSIG
|
||||
// * 2915 - NAPTR record (incomplete)
|
||||
|
@ -27,24 +29,22 @@ package dns
|
|||
|
||||
import (
|
||||
"strconv"
|
||||
"os"
|
||||
"net"
|
||||
)
|
||||
|
||||
const Year68 = 2 << (32 - 1)
|
||||
|
||||
type Error struct {
|
||||
Error string
|
||||
Name string
|
||||
Server string
|
||||
Timeout bool
|
||||
Error string
|
||||
Name string
|
||||
Server string
|
||||
Timeout bool
|
||||
}
|
||||
|
||||
func (e *Error) String() string {
|
||||
if e == nil {
|
||||
return "<nil>"
|
||||
}
|
||||
return e.Error
|
||||
if e == nil {
|
||||
return "<nil>"
|
||||
}
|
||||
return e.Error
|
||||
}
|
||||
|
||||
type RR interface {
|
||||
|
@ -93,85 +93,12 @@ func (h *RR_Header) String() string {
|
|||
return s
|
||||
}
|
||||
|
||||
func SendTCP(c net.Conn, m []byte) os.Error {
|
||||
l := make([]byte, 2)
|
||||
l[0] = byte(len(m) >> 8)
|
||||
l[1] = byte(len(m))
|
||||
// First we send the length
|
||||
_, 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
|
||||
// Return number of labels in a dname
|
||||
func labelCount(a string) (c int) {
|
||||
for _, v := range a {
|
||||
if v == '.' {
|
||||
c++
|
||||
}
|
||||
}
|
||||
start := off1 - int(r.Header().Rdlength)
|
||||
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
|
||||
return
|
||||
}
|
||||
|
|
141
dnssec.go
141
dnssec.go
|
@ -37,6 +37,29 @@ const (
|
|||
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.
|
||||
func (k *RR_DNSKEY) KeyTag() uint16 {
|
||||
var keytag int
|
||||
|
@ -45,13 +68,17 @@ func (k *RR_DNSKEY) KeyTag() uint16 {
|
|||
println("Keytag RSAMD5. Todo")
|
||||
keytag = 0
|
||||
default:
|
||||
// Might encode header length too, so that
|
||||
// we dont need to pack/unpack all the time
|
||||
// Or a shadow structure, with the wiredata and header
|
||||
wire, ok := WireRdata(k)
|
||||
keywire := new(dnskeyWireFmt)
|
||||
keywire.Flags = k.Flags
|
||||
keywire.Protocol = k.Protocol
|
||||
keywire.Algorithm = k.Algorithm
|
||||
keywire.PubKey = k.PubKey
|
||||
wire := make([]byte, 2048) // TODO(mg) lenght!
|
||||
n, ok := packStruct(keywire, wire, 0)
|
||||
if !ok {
|
||||
return 0
|
||||
}
|
||||
wire = wire[:n]
|
||||
for i, v := range wire {
|
||||
if i&1 != 0 {
|
||||
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.KeyTag = k.KeyTag()
|
||||
|
||||
wire, ok := WireRdata(k)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
owner, ok1 := WireDomainName(k.Hdr.Name)
|
||||
keywire := new(dnskeyWireFmt)
|
||||
keywire.Flags = k.Flags
|
||||
keywire.Protocol = k.Protocol
|
||||
keywire.Algorithm = k.Algorithm
|
||||
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 {
|
||||
return nil
|
||||
}
|
||||
owner = owner[:off]
|
||||
/*
|
||||
* from RFC4034
|
||||
* digest = digest_algorithm( DNSKEY owner name | DNSKEY RDATA);
|
||||
|
@ -110,9 +147,32 @@ func (k *RR_DNSKEY) ToDS(h int) *RR_DS {
|
|||
return ds
|
||||
}
|
||||
|
||||
// Sign rrset with k and return the signature RR.
|
||||
func (k *RR_DNSKEY) Sign(rrset RRset) (*RR_RRSIG) {
|
||||
return nil
|
||||
// Sign rrset with k and return the signature RR. There
|
||||
// is no check if rrset is a proper (RFC 2181) RRSet
|
||||
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
|
||||
|
@ -150,11 +210,22 @@ func (s *RR_RRSIG) Verify(k *RR_DNSKEY, rrset RRset) bool {
|
|||
|
||||
// RFC 4035 5.3.2. Reconstructing the Signed 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, ""}
|
||||
signeddata, ok := WireRdata(s1)
|
||||
sigwire := new(rrsigWireFmt)
|
||||
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 {
|
||||
return false
|
||||
}
|
||||
signeddata = signeddata[:n]
|
||||
|
||||
for _, r := range rrset {
|
||||
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. (5) - origTTL
|
||||
|
||||
ttl := h.Ttl
|
||||
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.Name = name
|
||||
if !ok1 {
|
||||
|
@ -184,22 +262,12 @@ func (s *RR_RRSIG) Verify(k *RR_DNSKEY, rrset RRset) bool {
|
|||
signeddata = append(signeddata, wire...)
|
||||
}
|
||||
|
||||
// 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]
|
||||
|
||||
// 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]
|
||||
sigbuf := s.sigBuf() // Get the binary signature data
|
||||
|
||||
var err os.Error
|
||||
switch s.Algorithm {
|
||||
case AlgRSASHA1, AlgRSASHA256, AlgRSASHA512, AlgRSAMD5:
|
||||
pubkey := rsaPubKey(keybuf)
|
||||
pubkey := k.pubKeyRSA() // Get the key
|
||||
// Setup the hash as defined for this alg.
|
||||
var h hash.Hash
|
||||
var ch rsa.PKCS1v15Hash
|
||||
|
@ -239,8 +307,23 @@ func (s *RR_RRSIG) PeriodOK() bool {
|
|||
return ti <= utc && utc <= te
|
||||
}
|
||||
|
||||
// Extra the RSA public key from the buffer
|
||||
func rsaPubKey(keybuf []byte) *rsa.PublicKey {
|
||||
// Return the signatures base64 encodedig sigdata as a byte slice.
|
||||
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
|
||||
// Length is in the 0th byte, unless its zero, then it
|
||||
// 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
|
||||
// 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
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// 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
|
||||
|
||||
import (
|
||||
|
@ -13,6 +24,7 @@ import (
|
|||
"dns"
|
||||
)
|
||||
|
||||
// Options for a nameserver.
|
||||
type Server struct {
|
||||
Address string // interface to use, for multiple interfaces, use multiple servers
|
||||
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 MAC can be calculated
|
||||
// RFC 2845, section 3.4.2. TSIG Variables
|
||||
type tsig_generation_fmt struct {
|
||||
type tsigWireFmt struct {
|
||||
// From RR_HEADER
|
||||
Name string "domain-name"
|
||||
Class uint16
|
||||
|
@ -70,7 +70,7 @@ type tsig_generation_fmt struct {
|
|||
// secret is encoded in base64 in BIND9
|
||||
func (rr *RR_TSIG) Generate(msg *Msg, secret string) bool {
|
||||
buf := make([]byte, 4096) // TODO(mg) bufsize!
|
||||
tsig := new(tsig_generation_fmt)
|
||||
tsig := new(tsigWireFmt)
|
||||
|
||||
// Fill the struct and generate the wiredata
|
||||
tsig.Name = rr.Header().Name
|
||||
|
|
Loading…
Reference in New Issue