This commit is contained in:
Miek Gieben 2010-12-29 16:11:23 +01:00
parent 1b5608d373
commit de5b30f781
6 changed files with 87 additions and 52 deletions

View File

@ -9,7 +9,6 @@ GOFILES=\
msg.go\ msg.go\
resolver.go \ resolver.go \
types.go\ types.go\
dnssec.go\
edns.go\ edns.go\
include $(GOROOT)/src/Make.pkg include $(GOROOT)/src/Make.pkg

9
README
View File

@ -11,10 +11,11 @@ Miek Gieben - 2010
Implemented RFCS: Implemented RFCS:
* RFC2671, EDNS * RFC 2671, EDNS
* RFC1034/1035 * RFC 3110, RSA in DNS
* RFC4033/4034/4035 * RFC 1034/1035
* RFC5155 (NSEC3) * RFC 4033/4034/4035
* RFC 5155 (NSEC3)
Loosely based upon: Loosely based upon:
* ldns * ldns

View File

@ -1,4 +1,4 @@
package dns package dnssec
import ( import (
"testing" "testing"

View File

@ -1,13 +1,15 @@
package dns package dnssec
import ( import (
"dns"
"crypto/sha1" "crypto/sha1"
"crypto/sha256" "crypto/sha256"
// "crypto/rsa" "crypto/rsa"
"encoding/hex" "encoding/hex"
"encoding/base64" "encoding/base64"
"time" "time"
"io" "io"
"big"
"sort" "sort"
"strings" "strings"
"fmt" //tmp "fmt" //tmp
@ -94,15 +96,11 @@ func (k *RR_DNSKEY) KeyTag() uint16 {
// Might encode header length too, so that // Might encode header length too, so that
// we dont need to pack/unpack all the time // we dont need to pack/unpack all the time
// Or a shadow structure, with the wiredata and header // Or a shadow structure, with the wiredata and header
buf := make([]byte, 4096) wire, ok := wireRdata(k)
off1, ok := packRR(k, buf, 0)
if !ok { if !ok {
return 0 return 0
} }
for i, v := range wire {
start := off1 - int(k.Header().Rdlength)
end := start + int(k.Header().Rdlength)
for i, v := range buf[start:end] {
if i&1 != 0 { if i&1 != 0 {
keytag += int(v) // must be larger than uint32 keytag += int(v) // must be larger than uint32
} else { } else {
@ -150,25 +148,24 @@ func (s *RR_RRSIG) Verify(rrset RRset, k *RR_DNSKEY) bool {
// RFC 4035 5.3.2. Reconstructing the Signed Data // RFC 4035 5.3.2. Reconstructing the Signed Data
signeddata := make([]byte, 10240) // 10 Kb?? signeddata := make([]byte, 10240) // 10 Kb??
buf := make([]byte, 4096) // Copy the sig, except the rrsig data
s1 := s // does this copy?? // Can this be done easier? TODO(mg)
s1.Signature = "" // Unset signature data s1 := &RR_RRSIG{s.Hdr, s.TypeCovered, s.Algorithm, s.Labels, s.OrigTtl, s.Expiration, s.Inception, s.KeyTag, s.SignerName, ""}
off, ok := packRR(s1, buf, 0) buf, ok := wireRdata(s1)
if !ok { if !ok {
return false return false
} }
start := off - int(s.Header().Rdlength) copy(signeddata, buf)
end := start + int(s.Header().Rdlength) off := len(buf)
fmt.Fprintf(os.Stderr, "start %d, end %d\n", start, end)
copy(signeddata, buf[start:end])
off = end - start
fmt.Fprintf(os.Stderr, "off %d\n", off) fmt.Fprintf(os.Stderr, "off %d\n", off)
for _, r := range rrset { for _, r := range rrset {
h := r.Header()
// RFC 4034: 6.2. Canonical RR Form. (2) - domain name to lowercase // RFC 4034: 6.2. Canonical RR Form. (2) - domain name to lowercase
r.Header().Name = strings.ToLower(r.Header().Name) name := h.Name
h.Name = strings.ToLower(h.Name)
// 6.2. Canonical RR Form. (3) - domain rdata to lowercaser // 6.2. Canonical RR Form. (3) - domain rdata to lowercaser
switch r.Header().Rrtype { switch h.Rrtype {
case TypeNS, TypeCNAME, TypeSOA, TypeMB, TypeMG, TypeMR, TypePTR: case TypeNS, TypeCNAME, TypeSOA, TypeMB, TypeMG, TypeMR, TypePTR:
case TypeHINFO, TypeMINFO, TypeMX /* TypeRP, TypeAFSDB, TypeRT */ : case TypeHINFO, TypeMINFO, TypeMX /* TypeRP, TypeAFSDB, TypeRT */ :
case TypeSIG /* TypePX, TypeNXT /* TypeNAPTR, TypeKX */ : case TypeSIG /* TypePX, TypeNXT /* TypeNAPTR, TypeKX */ :
@ -179,31 +176,52 @@ func (s *RR_RRSIG) Verify(rrset RRset, k *RR_DNSKEY) 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
r.Header().Ttl = s.OrigTtl ttl := h.Ttl
h.Ttl = s.OrigTtl
fmt.Fprintf(os.Stderr, "%v\n", r)
off, ok = packRR(r, signeddata, off) off, ok = packRR(r, signeddata, off)
h.Ttl = ttl // restore the order in the universe
h.Name = name
if !ok { if !ok {
println("Failure to pack") println("Failure to pack")
return false return false
} }
} }
signeddata = signeddata[:off] signeddata = signeddata[:off]
fmt.Fprintf(os.Stderr, "length %d", len(signeddata)) keybuf := make([]byte, 1024)
keybuf := make([]byte, 1024) keybuflen := base64.StdEncoding.DecodedLen(len(k.PubKey))
keybuflen := base64.StdEncoding.DecodedLen(len(k.PubKey)) base64.StdEncoding.Decode(keybuf[0:keybuflen], []byte(k.PubKey))
base64.StdEncoding.Decode(keybuf[0:keybuflen], []byte(k.PubKey)) sigbuf := make([]byte, 1024)
sigbuf := make([]byte, 1024) sigbuflen := base64.StdEncoding.DecodedLen(len(s.Signature))
sigbuflen := base64.StdEncoding.DecodedLen(len(s.Signature)) base64.StdEncoding.Decode(sigbuf[0:sigbuflen], []byte(s.Signature))
base64.StdEncoding.Decode(sigbuf[0:sigbuflen], []byte(s.Signature))
switch s.Algorithm { switch s.Algorithm {
case AlgRSASHA1: case AlgRSASHA1:
case AlgRSASHA256: case AlgRSASHA256:
// RFC 3110, section 2. RSA Public KEY Resource Records
// Assume length is in the first byte!
// l := int(keybuf[0])
_E := int(keybuf[3]) <<16
_E += int(keybuf[2]) <<8
_E += int(keybuf[1])
pubkey := new(rsa.PublicKey)
pubkey.E = _E
// var modulus uint64
// buf := bytes.NewBuffer(keybuf[4:])
// binary.Read(buf, binary.BigEndian, &modulus)
pubkey.N = big.NewInt(0)
_, ok := pubkey.N.SetString(string(keybuf[4:]), 2)
if !ok {
fmt.Fprintf(os.Stderr, "Ging niet goed\n")
}
// pubkey.N = big.NewInt(int64(modulus))
// for i,v := range keybuf[4:] {
} //
// }
// l := int(keybuf[0])
// pubkey.E = keybuf[1:l] // First byte has the length
}
return true return true
} }

View File

@ -1,13 +1,15 @@
package dns package dnssec
import ( import (
"testing" "testing"
"fmt"
"os"
) )
func TestSecure(t *testing.T) { func TestSecure(t *testing.T) {
// once this was valid // once this was valid
soa := new(RR_SOA) soa := new(RR_SOA)
soa.Hdr = RR_Header{"miek.nl.", TypeSOA, ClassINET, 14400, 0} soa.Hdr = RR_Header{"Miek.nl.", TypeSOA, ClassINET, 875, 0}
soa.Ns = "open.nlnetlabs.nl." soa.Ns = "open.nlnetlabs.nl."
soa.Mbox = "miekg.atoom.net." soa.Mbox = "miekg.atoom.net."
soa.Serial = 1293513905 soa.Serial = 1293513905
@ -38,9 +40,11 @@ func TestSecure(t *testing.T) {
key.Algorithm = AlgRSASHA256 key.Algorithm = AlgRSASHA256
key.PubKey = "AwEAAcNEU67LJI5GEgF9QLNqLO1SMq1EdoQ6E9f85ha0k0ewQGCblyW2836GiVsm6k8Kr5ECIoMJ6fZWf3CQSQ9ycWfTyOHfmI3eQ/1Covhb2y4bAmL/07PhrL7ozWBW3wBfM335Ft9xjtXHPy7ztCbV9qZ4TVDTW/Iyg0PiwgoXVesz" key.PubKey = "AwEAAcNEU67LJI5GEgF9QLNqLO1SMq1EdoQ6E9f85ha0k0ewQGCblyW2836GiVsm6k8Kr5ECIoMJ6fZWf3CQSQ9ycWfTyOHfmI3eQ/1Covhb2y4bAmL/07PhrL7ozWBW3wBfM335Ft9xjtXHPy7ztCbV9qZ4TVDTW/Iyg0PiwgoXVesz"
fmt.Fprintf(os.Stderr, "%v\n%v\n", sig, soa)
// It should validate, at least this month dec 2010 // It should validate, at least this month dec 2010
if ! sig.Verify([]RR{soa}, key) { if ! sig.Verify([]RR{soa}, key) {
t.Log("Failure to validate") t.Log("Failure to validate")
t.Fail() t.Fail()
} }
fmt.Fprintf(os.Stderr, "%v\n%v\n", sig, soa)
} }

View File

@ -23,7 +23,7 @@ package dns
import ( import (
"net" "net"
"strconv" "strconv"
"strings" "strings"
) )
// Packet formats // Packet formats
@ -53,10 +53,10 @@ const (
// EDNS // EDNS
TypeOPT = 41 TypeOPT = 41
// Old DNSSEC // Old DNSSEC
TypeSIG = 24 TypeSIG = 24
TypeKEY = 25 TypeKEY = 25
TypeNXT = 30 TypeNXT = 30
// DNSSEC // DNSSEC
TypeDS = 43 TypeDS = 43
TypeRRSIG = 46 TypeRRSIG = 46
@ -121,9 +121,9 @@ const (
// DNSSEC hashing codes. // DNSSEC hashing codes.
const ( const (
HashSHA1 = iota HashSHA1 = iota
HashSHA256 HashSHA256
HashGOST94 HashGOST94
) )
// DNS queries. // DNS queries.
@ -481,7 +481,7 @@ type RR_NSEC3 struct {
func (rr *RR_NSEC3) Header() *RR_Header { func (rr *RR_NSEC3) Header() *RR_Header {
return &rr.Hdr return &rr.Hdr
// Salt with strings.ToUpper() // Salt with strings.ToUpper()
} }
func (rr *RR_NSEC3) String() string { func (rr *RR_NSEC3) String() string {
@ -503,7 +503,7 @@ func (rr *RR_NSEC3PARAM) Header() *RR_Header {
func (rr *RR_NSEC3PARAM) String() string { func (rr *RR_NSEC3PARAM) String() string {
return rr.Hdr.String() + "BLAH" return rr.Hdr.String() + "BLAH"
// Salt with strings.ToUpper() // Salt with strings.ToUpper()
} }
// Map of constructors for each RR wire type. // Map of constructors for each RR wire type.
@ -566,3 +566,16 @@ var alg_str = map[uint8]string{
AlgRSASHA512: "RSASHA512", AlgRSASHA512: "RSASHA512",
AlgECCGOST: "ECC-GOST", AlgECCGOST: "ECC-GOST",
} }
// Return the rdata of the RR in wireform.
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)
end := start + int(r.Header().Rdlength)
buf = buf[start:end]
return buf, true
}