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\
resolver.go \
types.go\
dnssec.go\
edns.go\
include $(GOROOT)/src/Make.pkg

9
README
View File

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

View File

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

View File

@ -1,13 +1,15 @@
package dns
package dnssec
import (
"dns"
"crypto/sha1"
"crypto/sha256"
// "crypto/rsa"
"crypto/rsa"
"encoding/hex"
"encoding/base64"
"encoding/base64"
"time"
"io"
"big"
"sort"
"strings"
"fmt" //tmp
@ -94,15 +96,11 @@ func (k *RR_DNSKEY) KeyTag() uint16 {
// 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
buf := make([]byte, 4096)
off1, ok := packRR(k, buf, 0)
wire, ok := wireRdata(k)
if !ok {
return 0
}
start := off1 - int(k.Header().Rdlength)
end := start + int(k.Header().Rdlength)
for i, v := range buf[start:end] {
for i, v := range wire {
if i&1 != 0 {
keytag += int(v) // must be larger than uint32
} 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
signeddata := make([]byte, 10240) // 10 Kb??
buf := make([]byte, 4096)
s1 := s // does this copy??
s1.Signature = "" // Unset signature data
off, ok := packRR(s1, buf, 0)
// Copy the sig, except the rrsig data
// Can this be done easier? TODO(mg)
s1 := &RR_RRSIG{s.Hdr, s.TypeCovered, s.Algorithm, s.Labels, s.OrigTtl, s.Expiration, s.Inception, s.KeyTag, s.SignerName, ""}
buf, ok := wireRdata(s1)
if !ok {
return false
}
start := off - int(s.Header().Rdlength)
end := start + int(s.Header().Rdlength)
fmt.Fprintf(os.Stderr, "start %d, end %d\n", start, end)
copy(signeddata, buf[start:end])
off = end - start
copy(signeddata, buf)
off := len(buf)
fmt.Fprintf(os.Stderr, "off %d\n", off)
for _, r := range rrset {
h := r.Header()
// 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
switch r.Header().Rrtype {
switch h.Rrtype {
case TypeNS, TypeCNAME, TypeSOA, TypeMB, TypeMG, TypeMR, TypePTR:
case TypeHINFO, TypeMINFO, TypeMX /* TypeRP, TypeAFSDB, TypeRT */ :
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. (5) - origTTL
r.Header().Ttl = s.OrigTtl
fmt.Fprintf(os.Stderr, "%v\n", r)
ttl := h.Ttl
h.Ttl = s.OrigTtl
off, ok = packRR(r, signeddata, off)
h.Ttl = ttl // restore the order in the universe
h.Name = name
if !ok {
println("Failure to pack")
return false
}
}
signeddata = signeddata[:off]
fmt.Fprintf(os.Stderr, "length %d", len(signeddata))
keybuf := make([]byte, 1024)
keybuflen := base64.StdEncoding.DecodedLen(len(k.PubKey))
base64.StdEncoding.Decode(keybuf[0:keybuflen], []byte(k.PubKey))
sigbuf := make([]byte, 1024)
sigbuflen := base64.StdEncoding.DecodedLen(len(s.Signature))
base64.StdEncoding.Decode(sigbuf[0:sigbuflen], []byte(s.Signature))
keybuf := make([]byte, 1024)
keybuflen := base64.StdEncoding.DecodedLen(len(k.PubKey))
base64.StdEncoding.Decode(keybuf[0:keybuflen], []byte(k.PubKey))
sigbuf := make([]byte, 1024)
sigbuflen := base64.StdEncoding.DecodedLen(len(s.Signature))
base64.StdEncoding.Decode(sigbuf[0:sigbuflen], []byte(s.Signature))
switch s.Algorithm {
case AlgRSASHA1:
switch s.Algorithm {
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
}

View File

@ -1,13 +1,15 @@
package dns
package dnssec
import (
"testing"
"fmt"
"os"
)
func TestSecure(t *testing.T) {
// once this was valid
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.Mbox = "miekg.atoom.net."
soa.Serial = 1293513905
@ -38,9 +40,11 @@ func TestSecure(t *testing.T) {
key.Algorithm = AlgRSASHA256
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
if ! sig.Verify([]RR{soa}, key) {
t.Log("Failure to validate")
t.Fail()
}
fmt.Fprintf(os.Stderr, "%v\n%v\n", sig, soa)
}

View File

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