mirror of
https://github.com/miekg/dns.git
synced 2025-09-24 17:41:01 +02:00
* Eliminate zlexer goroutine This replaces the zlexer goroutine and channels with a zlexer struct that maintains state and provides a channel-like API. * Eliminate klexer goroutine This replaces the klexer goroutine and channels with a klexer struct that maintains state and provides a channel-like API. * Merge scan into zlexer and klexer This does result in tokenText existing twice, but it's pretty simple and small so it's not that bad. * Avoid using text/scanner.Position to track position * Track escape within zlexer.Next * Avoid zl.commt check on space and tab in zlexer * Track stri within zlexer.Next * Track comi within zlexer.Next There is one special case at the start of a comment that needs to be handled, otherwise this is as simple as stri was. * Use a single token buffer in zlexer This is safe as there is never both a non-empty string buffer and a non-empty comment buffer. * Don't hardcode length of zl.tok in zlexer * Eliminate lex.length field This is always set to len(l.token) and is only queried in a few places. It was added in 47cc5b052df9b4e5d5a9900cfdd622607de10a6d without any obvious need. * Add whitespace to klexer.Next * Track lex within klexer.Next * Use a strings.Builder in klexer.Next * Simplify : case in klexer.Next * Add whitespace to zlexer.Next * Change for loop style in zlexer.Next and klexer.Next * Surface read errors in zlexer * Surface read errors from klexer * Remove debug line from parseKey * Rename tokenText to readByte * Make readByte return ok bool Also change the for loop style to match the Next for loops. * Make readByte errors sticky klexer.Next calls readByte separately from within the loop. Without readByte being sticky, an error that occurs during that readByte call may be lost. * Panic in testRR if the error is non-nil * Add whitespace and unify field setting in zlexer.Next * Remove eof fields from zlexer and klexer With readByte having sticky errors, this no longer needed. zl.eof = true was also in the wrong place and could mask an unbalanced brace error. * Merge zl.tok blocks in zlexer.Next * Split the tok buffer into separate string and comment buffers The invariant of stri > 0 && comi > 0 never being true was broken when x == '\n' && !zl.quote && zl.commt && zl.brace != 0 (the "If not in a brace this ends the comment AND the RR" block). Split the buffer back out into two separate buffers to avoid clobbering. * Replace token slices with arrays in zlexer * Add a NewRR benchmark * Move token buffers into zlexer.Next These don't need to be retained across Next calls and can be stack allocated inside Next. This drastically reduces memory consumption as they accounted for nearly half of all the memory used. name old alloc/op new alloc/op delta NewRR-12 9.72kB ± 0% 4.98kB ± 0% -48.72% (p=0.000 n=10+10) * Add a ReadRR benchmark Unlike NewRR, this will use an io.Reader that does not implement any methods aside from Read. In particular it does not implement io.ByteReader. * Avoid using a bufio.Reader for io.ByteReader readers At the same time use a smaller buffer size of 1KiB rather than the bufio.NewReader default of 4KiB. name old time/op new time/op delta NewRR-12 11.0µs ± 3% 9.5µs ± 2% -13.77% (p=0.000 n=9+10) ReadRR-12 11.2µs ±16% 9.8µs ± 1% -13.03% (p=0.000 n=10+10) name old alloc/op new alloc/op delta NewRR-12 4.98kB ± 0% 0.81kB ± 0% -83.79% (p=0.000 n=10+10) ReadRR-12 4.87kB ± 0% 1.82kB ± 0% -62.73% (p=0.000 n=10+10) name old allocs/op new allocs/op delta NewRR-12 19.0 ± 0% 17.0 ± 0% -10.53% (p=0.000 n=10+10) ReadRR-12 19.0 ± 0% 19.0 ± 0% ~ (all equal) ReadRR-12 11.2µs ±16% 9.8µs ± 1% -13.03% (p=0.000 n=10+10) * Surface any remaining comment from zlexer.Next * Improve comment handling in zlexer.Next This both fixes a regression where comments could be lost under certain circumstances and now emits comments that occur within braces. * Remove outdated comment from zlexer.Next and klexer.Next * Delay converting LF to space in braced comment * Fixup TestParseZoneComments * Remove tokenUpper field from lex Not computing this for every token, and instead only when needed is a substantial performance improvement. name old time/op new time/op delta NewRR-12 9.56µs ± 0% 6.30µs ± 1% -34.08% (p=0.000 n=9+10) ReadRR-12 9.93µs ± 1% 6.67µs ± 1% -32.77% (p=0.000 n=10+10) name old alloc/op new alloc/op delta NewRR-12 824B ± 0% 808B ± 0% -1.94% (p=0.000 n=10+10) ReadRR-12 1.83kB ± 0% 1.82kB ± 0% -0.87% (p=0.000 n=10+10) name old allocs/op new allocs/op delta NewRR-12 17.0 ± 0% 17.0 ± 0% ~ (all equal) ReadRR-12 19.0 ± 0% 19.0 ± 0% ~ (all equal) * Update ParseZone documentation to match comment changes The zlexer code was changed to return comments more often, so update the ParseZone documentation to match.
859 lines
29 KiB
Go
859 lines
29 KiB
Go
package dns
|
|
|
|
import (
|
|
"crypto"
|
|
"crypto/ecdsa"
|
|
"crypto/rsa"
|
|
"reflect"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"golang.org/x/crypto/ed25519"
|
|
)
|
|
|
|
func getSoa() *SOA {
|
|
soa := new(SOA)
|
|
soa.Hdr = RR_Header{"miek.nl.", TypeSOA, ClassINET, 14400, 0}
|
|
soa.Ns = "open.nlnetlabs.nl."
|
|
soa.Mbox = "miekg.atoom.net."
|
|
soa.Serial = 1293945905
|
|
soa.Refresh = 14400
|
|
soa.Retry = 3600
|
|
soa.Expire = 604800
|
|
soa.Minttl = 86400
|
|
return soa
|
|
}
|
|
|
|
func TestSecure(t *testing.T) {
|
|
soa := getSoa()
|
|
|
|
sig := new(RRSIG)
|
|
sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0}
|
|
sig.TypeCovered = TypeSOA
|
|
sig.Algorithm = RSASHA256
|
|
sig.Labels = 2
|
|
sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05"
|
|
sig.Inception = 1293942305 // date -u '+%s' -d"2011-01-02 04:25:05"
|
|
sig.OrigTtl = 14400
|
|
sig.KeyTag = 12051
|
|
sig.SignerName = "miek.nl."
|
|
sig.Signature = "oMCbslaAVIp/8kVtLSms3tDABpcPRUgHLrOR48OOplkYo+8TeEGWwkSwaz/MRo2fB4FxW0qj/hTlIjUGuACSd+b1wKdH5GvzRJc2pFmxtCbm55ygAh4EUL0F6U5cKtGJGSXxxg6UFCQ0doJCmiGFa78LolaUOXImJrk6AFrGa0M="
|
|
|
|
key := new(DNSKEY)
|
|
key.Hdr.Name = "miek.nl."
|
|
key.Hdr.Class = ClassINET
|
|
key.Hdr.Ttl = 14400
|
|
key.Flags = 256
|
|
key.Protocol = 3
|
|
key.Algorithm = RSASHA256
|
|
key.PublicKey = "AwEAAcNEU67LJI5GEgF9QLNqLO1SMq1EdoQ6E9f85ha0k0ewQGCblyW2836GiVsm6k8Kr5ECIoMJ6fZWf3CQSQ9ycWfTyOHfmI3eQ/1Covhb2y4bAmL/07PhrL7ozWBW3wBfM335Ft9xjtXHPy7ztCbV9qZ4TVDTW/Iyg0PiwgoXVesz"
|
|
|
|
// It should validate. Period is checked separately, so this will keep on working
|
|
if sig.Verify(key, []RR{soa}) != nil {
|
|
t.Error("failure to validate")
|
|
}
|
|
}
|
|
|
|
func TestSignature(t *testing.T) {
|
|
sig := new(RRSIG)
|
|
sig.Hdr.Name = "miek.nl."
|
|
sig.Hdr.Class = ClassINET
|
|
sig.Hdr.Ttl = 3600
|
|
sig.TypeCovered = TypeDNSKEY
|
|
sig.Algorithm = RSASHA1
|
|
sig.Labels = 2
|
|
sig.OrigTtl = 4000
|
|
sig.Expiration = 1000 //Thu Jan 1 02:06:40 CET 1970
|
|
sig.Inception = 800 //Thu Jan 1 01:13:20 CET 1970
|
|
sig.KeyTag = 34641
|
|
sig.SignerName = "miek.nl."
|
|
sig.Signature = "AwEAAaHIwpx3w4VHKi6i1LHnTaWeHCL154Jug0Rtc9ji5qwPXpBo6A5sRv7cSsPQKPIwxLpyCrbJ4mr2L0EPOdvP6z6YfljK2ZmTbogU9aSU2fiq/4wjxbdkLyoDVgtO+JsxNN4bjr4WcWhsmk1Hg93FV9ZpkWb0Tbad8DFqNDzr//kZ"
|
|
|
|
// Should not be valid
|
|
if sig.ValidityPeriod(time.Now()) {
|
|
t.Error("should not be valid")
|
|
}
|
|
|
|
sig.Inception = 315565800 //Tue Jan 1 10:10:00 CET 1980
|
|
sig.Expiration = 4102477800 //Fri Jan 1 10:10:00 CET 2100
|
|
if !sig.ValidityPeriod(time.Now()) {
|
|
t.Error("should be valid")
|
|
}
|
|
}
|
|
|
|
func TestSignVerify(t *testing.T) {
|
|
// The record we want to sign
|
|
soa := new(SOA)
|
|
soa.Hdr = RR_Header{"miek.nl.", TypeSOA, ClassINET, 14400, 0}
|
|
soa.Ns = "open.nlnetlabs.nl."
|
|
soa.Mbox = "miekg.atoom.net."
|
|
soa.Serial = 1293945905
|
|
soa.Refresh = 14400
|
|
soa.Retry = 3600
|
|
soa.Expire = 604800
|
|
soa.Minttl = 86400
|
|
|
|
soa1 := new(SOA)
|
|
soa1.Hdr = RR_Header{"*.miek.nl.", TypeSOA, ClassINET, 14400, 0}
|
|
soa1.Ns = "open.nlnetlabs.nl."
|
|
soa1.Mbox = "miekg.atoom.net."
|
|
soa1.Serial = 1293945905
|
|
soa1.Refresh = 14400
|
|
soa1.Retry = 3600
|
|
soa1.Expire = 604800
|
|
soa1.Minttl = 86400
|
|
|
|
srv := new(SRV)
|
|
srv.Hdr = RR_Header{"srv.miek.nl.", TypeSRV, ClassINET, 14400, 0}
|
|
srv.Port = 1000
|
|
srv.Weight = 800
|
|
srv.Target = "web1.miek.nl."
|
|
|
|
hinfo := &HINFO{
|
|
Hdr: RR_Header{
|
|
Name: "miek.nl.",
|
|
Rrtype: TypeHINFO,
|
|
Class: ClassINET,
|
|
Ttl: 3789,
|
|
},
|
|
Cpu: "X",
|
|
Os: "Y",
|
|
}
|
|
|
|
// With this key
|
|
key := new(DNSKEY)
|
|
key.Hdr.Rrtype = TypeDNSKEY
|
|
key.Hdr.Name = "miek.nl."
|
|
key.Hdr.Class = ClassINET
|
|
key.Hdr.Ttl = 14400
|
|
key.Flags = 256
|
|
key.Protocol = 3
|
|
key.Algorithm = RSASHA256
|
|
privkey, _ := key.Generate(512)
|
|
|
|
// Fill in the values of the Sig, before signing
|
|
sig := new(RRSIG)
|
|
sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0}
|
|
sig.TypeCovered = soa.Hdr.Rrtype
|
|
sig.Labels = uint8(CountLabel(soa.Hdr.Name)) // works for all 3
|
|
sig.OrigTtl = soa.Hdr.Ttl
|
|
sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05"
|
|
sig.Inception = 1293942305 // date -u '+%s' -d"2011-01-02 04:25:05"
|
|
sig.KeyTag = key.KeyTag() // Get the keyfrom the Key
|
|
sig.SignerName = key.Hdr.Name
|
|
sig.Algorithm = RSASHA256
|
|
|
|
for _, r := range []RR{soa, soa1, srv, hinfo} {
|
|
if err := sig.Sign(privkey.(*rsa.PrivateKey), []RR{r}); err != nil {
|
|
t.Error("failure to sign the record:", err)
|
|
continue
|
|
}
|
|
if err := sig.Verify(key, []RR{r}); err != nil {
|
|
t.Errorf("failure to validate: %s", r.Header().Name)
|
|
continue
|
|
}
|
|
}
|
|
}
|
|
|
|
func Test65534(t *testing.T) {
|
|
t6 := new(RFC3597)
|
|
t6.Hdr = RR_Header{"miek.nl.", 65534, ClassINET, 14400, 0}
|
|
t6.Rdata = "505D870001"
|
|
key := new(DNSKEY)
|
|
key.Hdr.Name = "miek.nl."
|
|
key.Hdr.Rrtype = TypeDNSKEY
|
|
key.Hdr.Class = ClassINET
|
|
key.Hdr.Ttl = 14400
|
|
key.Flags = 256
|
|
key.Protocol = 3
|
|
key.Algorithm = RSASHA256
|
|
privkey, _ := key.Generate(1024)
|
|
|
|
sig := new(RRSIG)
|
|
sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0}
|
|
sig.TypeCovered = t6.Hdr.Rrtype
|
|
sig.Labels = uint8(CountLabel(t6.Hdr.Name))
|
|
sig.OrigTtl = t6.Hdr.Ttl
|
|
sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05"
|
|
sig.Inception = 1293942305 // date -u '+%s' -d"2011-01-02 04:25:05"
|
|
sig.KeyTag = key.KeyTag()
|
|
sig.SignerName = key.Hdr.Name
|
|
sig.Algorithm = RSASHA256
|
|
if err := sig.Sign(privkey.(*rsa.PrivateKey), []RR{t6}); err != nil {
|
|
t.Error(err)
|
|
t.Error("failure to sign the TYPE65534 record")
|
|
}
|
|
if err := sig.Verify(key, []RR{t6}); err != nil {
|
|
t.Error(err)
|
|
t.Errorf("failure to validate %s", t6.Header().Name)
|
|
}
|
|
}
|
|
|
|
func TestDnskey(t *testing.T) {
|
|
pubkey, err := ReadRR(strings.NewReader(`
|
|
miek.nl. IN DNSKEY 256 3 10 AwEAAZuMCu2FdugHkTrXYgl5qixvcDw1aDDlvL46/xJKbHBAHY16fNUb2b65cwko2Js/aJxUYJbZk5dwCDZxYfrfbZVtDPQuc3o8QaChVxC7/JYz2AHc9qHvqQ1j4VrH71RWINlQo6VYjzN/BGpMhOZoZOEwzp1HfsOE3lNYcoWU1smL ;{id = 5240 (zsk), size = 1024b}
|
|
`), "Kmiek.nl.+010+05240.key")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
privStr := `Private-key-format: v1.3
|
|
Algorithm: 10 (RSASHA512)
|
|
Modulus: m4wK7YV26AeROtdiCXmqLG9wPDVoMOW8vjr/EkpscEAdjXp81RvZvrlzCSjYmz9onFRgltmTl3AINnFh+t9tlW0M9C5zejxBoKFXELv8ljPYAdz2oe+pDWPhWsfvVFYg2VCjpViPM38EakyE5mhk4TDOnUd+w4TeU1hyhZTWyYs=
|
|
PublicExponent: AQAB
|
|
PrivateExponent: UfCoIQ/Z38l8vB6SSqOI/feGjHEl/fxIPX4euKf0D/32k30fHbSaNFrFOuIFmWMB3LimWVEs6u3dpbB9CQeCVg7hwU5puG7OtuiZJgDAhNeOnxvo5btp4XzPZrJSxR4WNQnwIiYWbl0aFlL1VGgHC/3By89ENZyWaZcMLW4KGWE=
|
|
Prime1: yxwC6ogAu8aVcDx2wg1V0b5M5P6jP8qkRFVMxWNTw60Vkn+ECvw6YAZZBHZPaMyRYZLzPgUlyYRd0cjupy4+fQ==
|
|
Prime2: xA1bF8M0RTIQ6+A11AoVG6GIR/aPGg5sogRkIZ7ID/sF6g9HMVU/CM2TqVEBJLRPp73cv6ZeC3bcqOCqZhz+pw==
|
|
Exponent1: xzkblyZ96bGYxTVZm2/vHMOXswod4KWIyMoOepK6B/ZPcZoIT6omLCgtypWtwHLfqyCz3MK51Nc0G2EGzg8rFQ==
|
|
Exponent2: Pu5+mCEb7T5F+kFNZhQadHUklt0JUHbi3hsEvVoHpEGSw3BGDQrtIflDde0/rbWHgDPM4WQY+hscd8UuTXrvLw==
|
|
Coefficient: UuRoNqe7YHnKmQzE6iDWKTMIWTuoqqrFAmXPmKQnC+Y+BQzOVEHUo9bXdDnoI9hzXP1gf8zENMYwYLeWpuYlFQ==
|
|
`
|
|
privkey, err := pubkey.(*DNSKEY).ReadPrivateKey(strings.NewReader(privStr),
|
|
"Kmiek.nl.+010+05240.private")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if pubkey.(*DNSKEY).PublicKey != "AwEAAZuMCu2FdugHkTrXYgl5qixvcDw1aDDlvL46/xJKbHBAHY16fNUb2b65cwko2Js/aJxUYJbZk5dwCDZxYfrfbZVtDPQuc3o8QaChVxC7/JYz2AHc9qHvqQ1j4VrH71RWINlQo6VYjzN/BGpMhOZoZOEwzp1HfsOE3lNYcoWU1smL" {
|
|
t.Error("pubkey is not what we've read")
|
|
}
|
|
if pubkey.(*DNSKEY).PrivateKeyString(privkey) != privStr {
|
|
t.Error("privkey is not what we've read")
|
|
t.Errorf("%v", pubkey.(*DNSKEY).PrivateKeyString(privkey))
|
|
}
|
|
}
|
|
|
|
func TestTag(t *testing.T) {
|
|
key := new(DNSKEY)
|
|
key.Hdr.Name = "miek.nl."
|
|
key.Hdr.Rrtype = TypeDNSKEY
|
|
key.Hdr.Class = ClassINET
|
|
key.Hdr.Ttl = 3600
|
|
key.Flags = 256
|
|
key.Protocol = 3
|
|
key.Algorithm = RSASHA256
|
|
key.PublicKey = "AwEAAcNEU67LJI5GEgF9QLNqLO1SMq1EdoQ6E9f85ha0k0ewQGCblyW2836GiVsm6k8Kr5ECIoMJ6fZWf3CQSQ9ycWfTyOHfmI3eQ/1Covhb2y4bAmL/07PhrL7ozWBW3wBfM335Ft9xjtXHPy7ztCbV9qZ4TVDTW/Iyg0PiwgoXVesz"
|
|
|
|
tag := key.KeyTag()
|
|
if tag != 12051 {
|
|
t.Errorf("wrong key tag: %d for key %v", tag, key)
|
|
}
|
|
}
|
|
|
|
func TestKeyRSA(t *testing.T) {
|
|
if testing.Short() {
|
|
t.Skip("skipping test in short mode.")
|
|
}
|
|
key := new(DNSKEY)
|
|
key.Hdr.Name = "miek.nl."
|
|
key.Hdr.Rrtype = TypeDNSKEY
|
|
key.Hdr.Class = ClassINET
|
|
key.Hdr.Ttl = 3600
|
|
key.Flags = 256
|
|
key.Protocol = 3
|
|
key.Algorithm = RSASHA256
|
|
priv, _ := key.Generate(2048)
|
|
|
|
soa := new(SOA)
|
|
soa.Hdr = RR_Header{"miek.nl.", TypeSOA, ClassINET, 14400, 0}
|
|
soa.Ns = "open.nlnetlabs.nl."
|
|
soa.Mbox = "miekg.atoom.net."
|
|
soa.Serial = 1293945905
|
|
soa.Refresh = 14400
|
|
soa.Retry = 3600
|
|
soa.Expire = 604800
|
|
soa.Minttl = 86400
|
|
|
|
sig := new(RRSIG)
|
|
sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0}
|
|
sig.TypeCovered = TypeSOA
|
|
sig.Algorithm = RSASHA256
|
|
sig.Labels = 2
|
|
sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05"
|
|
sig.Inception = 1293942305 // date -u '+%s' -d"2011-01-02 04:25:05"
|
|
sig.OrigTtl = soa.Hdr.Ttl
|
|
sig.KeyTag = key.KeyTag()
|
|
sig.SignerName = key.Hdr.Name
|
|
|
|
if err := sig.Sign(priv.(*rsa.PrivateKey), []RR{soa}); err != nil {
|
|
t.Error("failed to sign")
|
|
return
|
|
}
|
|
if err := sig.Verify(key, []RR{soa}); err != nil {
|
|
t.Error("failed to verify")
|
|
}
|
|
}
|
|
|
|
func TestKeyToDS(t *testing.T) {
|
|
key := new(DNSKEY)
|
|
key.Hdr.Name = "miek.nl."
|
|
key.Hdr.Rrtype = TypeDNSKEY
|
|
key.Hdr.Class = ClassINET
|
|
key.Hdr.Ttl = 3600
|
|
key.Flags = 256
|
|
key.Protocol = 3
|
|
key.Algorithm = RSASHA256
|
|
key.PublicKey = "AwEAAcNEU67LJI5GEgF9QLNqLO1SMq1EdoQ6E9f85ha0k0ewQGCblyW2836GiVsm6k8Kr5ECIoMJ6fZWf3CQSQ9ycWfTyOHfmI3eQ/1Covhb2y4bAmL/07PhrL7ozWBW3wBfM335Ft9xjtXHPy7ztCbV9qZ4TVDTW/Iyg0PiwgoXVesz"
|
|
|
|
ds := key.ToDS(SHA1)
|
|
if strings.ToUpper(ds.Digest) != "B5121BDB5B8D86D0CC5FFAFBAAABE26C3E20BAC1" {
|
|
t.Errorf("wrong DS digest for SHA1\n%v", ds)
|
|
}
|
|
}
|
|
|
|
func TestSignRSA(t *testing.T) {
|
|
pub := "miek.nl. IN DNSKEY 256 3 5 AwEAAb+8lGNCxJgLS8rYVer6EnHVuIkQDghdjdtewDzU3G5R7PbMbKVRvH2Ma7pQyYceoaqWZQirSj72euPWfPxQnMy9ucCylA+FuH9cSjIcPf4PqJfdupHk9X6EBYjxrCLY4p1/yBwgyBIRJtZtAqM3ceAH2WovEJD6rTtOuHo5AluJ"
|
|
|
|
priv := `Private-key-format: v1.3
|
|
Algorithm: 5 (RSASHA1)
|
|
Modulus: v7yUY0LEmAtLythV6voScdW4iRAOCF2N217APNTcblHs9sxspVG8fYxrulDJhx6hqpZlCKtKPvZ649Z8/FCczL25wLKUD4W4f1xKMhw9/g+ol926keT1foQFiPGsItjinX/IHCDIEhEm1m0Cozdx4AfZai8QkPqtO064ejkCW4k=
|
|
PublicExponent: AQAB
|
|
PrivateExponent: YPwEmwjk5HuiROKU4xzHQ6l1hG8Iiha4cKRG3P5W2b66/EN/GUh07ZSf0UiYB67o257jUDVEgwCuPJz776zfApcCB4oGV+YDyEu7Hp/rL8KcSN0la0k2r9scKwxTp4BTJT23zyBFXsV/1wRDK1A5NxsHPDMYi2SoK63Enm/1ptk=
|
|
Prime1: /wjOG+fD0ybNoSRn7nQ79udGeR1b0YhUA5mNjDx/x2fxtIXzygYk0Rhx9QFfDy6LOBvz92gbNQlzCLz3DJt5hw==
|
|
Prime2: wHZsJ8OGhkp5p3mrJFZXMDc2mbYusDVTA+t+iRPdS797Tj0pjvU2HN4vTnTj8KBQp6hmnY7dLp9Y1qserySGbw==
|
|
Exponent1: N0A7FsSRIg+IAN8YPQqlawoTtG1t1OkJ+nWrurPootScApX6iMvn8fyvw3p2k51rv84efnzpWAYiC8SUaQDNxQ==
|
|
Exponent2: SvuYRaGyvo0zemE3oS+WRm2scxR8eiA8WJGeOc+obwOKCcBgeZblXzfdHGcEC1KaOcetOwNW/vwMA46lpLzJNw==
|
|
Coefficient: 8+7ZN/JgByqv0NfULiFKTjtyegUcijRuyij7yNxYbCBneDvZGxJwKNi4YYXWx743pcAj4Oi4Oh86gcmxLs+hGw==
|
|
Created: 20110302104537
|
|
Publish: 20110302104537
|
|
Activate: 20110302104537`
|
|
|
|
xk := testRR(pub)
|
|
k := xk.(*DNSKEY)
|
|
p, err := k.NewPrivateKey(priv)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
switch priv := p.(type) {
|
|
case *rsa.PrivateKey:
|
|
if 65537 != priv.PublicKey.E {
|
|
t.Error("exponenent should be 65537")
|
|
}
|
|
default:
|
|
t.Errorf("we should have read an RSA key: %v", priv)
|
|
}
|
|
if k.KeyTag() != 37350 {
|
|
t.Errorf("keytag should be 37350, got %d %v", k.KeyTag(), k)
|
|
}
|
|
|
|
soa := new(SOA)
|
|
soa.Hdr = RR_Header{"miek.nl.", TypeSOA, ClassINET, 14400, 0}
|
|
soa.Ns = "open.nlnetlabs.nl."
|
|
soa.Mbox = "miekg.atoom.net."
|
|
soa.Serial = 1293945905
|
|
soa.Refresh = 14400
|
|
soa.Retry = 3600
|
|
soa.Expire = 604800
|
|
soa.Minttl = 86400
|
|
|
|
sig := new(RRSIG)
|
|
sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0}
|
|
sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05"
|
|
sig.Inception = 1293942305 // date -u '+%s' -d"2011-01-02 04:25:05"
|
|
sig.KeyTag = k.KeyTag()
|
|
sig.SignerName = k.Hdr.Name
|
|
sig.Algorithm = k.Algorithm
|
|
|
|
sig.Sign(p.(*rsa.PrivateKey), []RR{soa})
|
|
if sig.Signature != "D5zsobpQcmMmYsUMLxCVEtgAdCvTu8V/IEeP4EyLBjqPJmjt96bwM9kqihsccofA5LIJ7DN91qkCORjWSTwNhzCv7bMyr2o5vBZElrlpnRzlvsFIoAZCD9xg6ZY7ZyzUJmU6IcTwG4v3xEYajcpbJJiyaw/RqR90MuRdKPiBzSo=" {
|
|
t.Errorf("signature is not correct: %v", sig)
|
|
}
|
|
}
|
|
|
|
func TestSignVerifyECDSA(t *testing.T) {
|
|
pub := `example.net. 3600 IN DNSKEY 257 3 14 (
|
|
xKYaNhWdGOfJ+nPrL8/arkwf2EY3MDJ+SErKivBVSum1
|
|
w/egsXvSADtNJhyem5RCOpgQ6K8X1DRSEkrbYQ+OB+v8
|
|
/uX45NBwY8rp65F6Glur8I/mlVNgF6W/qTI37m40 )`
|
|
priv := `Private-key-format: v1.2
|
|
Algorithm: 14 (ECDSAP384SHA384)
|
|
PrivateKey: WURgWHCcYIYUPWgeLmiPY2DJJk02vgrmTfitxgqcL4vwW7BOrbawVmVe0d9V94SR`
|
|
|
|
eckey := testRR(pub)
|
|
privkey, err := eckey.(*DNSKEY).NewPrivateKey(priv)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
// TODO: Create separate test for this
|
|
ds := eckey.(*DNSKEY).ToDS(SHA384)
|
|
if ds.KeyTag != 10771 {
|
|
t.Fatal("wrong keytag on DS")
|
|
}
|
|
if ds.Digest != "72d7b62976ce06438e9c0bf319013cf801f09ecc84b8d7e9495f27e305c6a9b0563a9b5f4d288405c3008a946df983d6" {
|
|
t.Fatal("wrong DS Digest")
|
|
}
|
|
a := testRR("www.example.net. 3600 IN A 192.0.2.1")
|
|
sig := new(RRSIG)
|
|
sig.Hdr = RR_Header{"example.net.", TypeRRSIG, ClassINET, 14400, 0}
|
|
sig.Expiration, _ = StringToTime("20100909102025")
|
|
sig.Inception, _ = StringToTime("20100812102025")
|
|
sig.KeyTag = eckey.(*DNSKEY).KeyTag()
|
|
sig.SignerName = eckey.(*DNSKEY).Hdr.Name
|
|
sig.Algorithm = eckey.(*DNSKEY).Algorithm
|
|
|
|
if sig.Sign(privkey.(*ecdsa.PrivateKey), []RR{a}) != nil {
|
|
t.Fatal("failure to sign the record")
|
|
}
|
|
|
|
if err := sig.Verify(eckey.(*DNSKEY), []RR{a}); err != nil {
|
|
t.Fatalf("failure to validate:\n%s\n%s\n%s\n\n%s\n\n%v",
|
|
eckey.(*DNSKEY).String(),
|
|
a.String(),
|
|
sig.String(),
|
|
eckey.(*DNSKEY).PrivateKeyString(privkey),
|
|
err,
|
|
)
|
|
}
|
|
}
|
|
|
|
func TestSignVerifyECDSA2(t *testing.T) {
|
|
srv1 := testRR("srv.miek.nl. IN SRV 1000 800 0 web1.miek.nl.")
|
|
srv := srv1.(*SRV)
|
|
|
|
// With this key
|
|
key := new(DNSKEY)
|
|
key.Hdr.Rrtype = TypeDNSKEY
|
|
key.Hdr.Name = "miek.nl."
|
|
key.Hdr.Class = ClassINET
|
|
key.Hdr.Ttl = 14400
|
|
key.Flags = 256
|
|
key.Protocol = 3
|
|
key.Algorithm = ECDSAP256SHA256
|
|
privkey, err := key.Generate(256)
|
|
if err != nil {
|
|
t.Fatal("failure to generate key")
|
|
}
|
|
|
|
// Fill in the values of the Sig, before signing
|
|
sig := new(RRSIG)
|
|
sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0}
|
|
sig.TypeCovered = srv.Hdr.Rrtype
|
|
sig.Labels = uint8(CountLabel(srv.Hdr.Name)) // works for all 3
|
|
sig.OrigTtl = srv.Hdr.Ttl
|
|
sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05"
|
|
sig.Inception = 1293942305 // date -u '+%s' -d"2011-01-02 04:25:05"
|
|
sig.KeyTag = key.KeyTag() // Get the keyfrom the Key
|
|
sig.SignerName = key.Hdr.Name
|
|
sig.Algorithm = ECDSAP256SHA256
|
|
|
|
if sig.Sign(privkey.(*ecdsa.PrivateKey), []RR{srv}) != nil {
|
|
t.Fatal("failure to sign the record")
|
|
}
|
|
|
|
err = sig.Verify(key, []RR{srv})
|
|
if err != nil {
|
|
t.Errorf("failure to validate:\n%s\n%s\n%s\n\n%s\n\n%v",
|
|
key.String(),
|
|
srv.String(),
|
|
sig.String(),
|
|
key.PrivateKeyString(privkey),
|
|
err,
|
|
)
|
|
}
|
|
}
|
|
|
|
func TestSignVerifyEd25519(t *testing.T) {
|
|
srv1, err := NewRR("srv.miek.nl. IN SRV 1000 800 0 web1.miek.nl.")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
srv := srv1.(*SRV)
|
|
|
|
// With this key
|
|
key := new(DNSKEY)
|
|
key.Hdr.Rrtype = TypeDNSKEY
|
|
key.Hdr.Name = "miek.nl."
|
|
key.Hdr.Class = ClassINET
|
|
key.Hdr.Ttl = 14400
|
|
key.Flags = 256
|
|
key.Protocol = 3
|
|
key.Algorithm = ED25519
|
|
privkey, err := key.Generate(256)
|
|
if err != nil {
|
|
t.Fatal("failure to generate key")
|
|
}
|
|
|
|
// Fill in the values of the Sig, before signing
|
|
sig := new(RRSIG)
|
|
sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0}
|
|
sig.TypeCovered = srv.Hdr.Rrtype
|
|
sig.Labels = uint8(CountLabel(srv.Hdr.Name)) // works for all 3
|
|
sig.OrigTtl = srv.Hdr.Ttl
|
|
sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05"
|
|
sig.Inception = 1293942305 // date -u '+%s' -d"2011-01-02 04:25:05"
|
|
sig.KeyTag = key.KeyTag() // Get the keyfrom the Key
|
|
sig.SignerName = key.Hdr.Name
|
|
sig.Algorithm = ED25519
|
|
|
|
if sig.Sign(privkey.(ed25519.PrivateKey), []RR{srv}) != nil {
|
|
t.Fatal("failure to sign the record")
|
|
}
|
|
|
|
err = sig.Verify(key, []RR{srv})
|
|
if err != nil {
|
|
t.Logf("failure to validate:\n%s\n%s\n%s\n\n%s\n\n%v",
|
|
key.String(),
|
|
srv.String(),
|
|
sig.String(),
|
|
key.PrivateKeyString(privkey),
|
|
err,
|
|
)
|
|
}
|
|
}
|
|
|
|
// Here the test vectors from the relevant RFCs are checked.
|
|
// rfc6605 6.1
|
|
func TestRFC6605P256(t *testing.T) {
|
|
exDNSKEY := `example.net. 3600 IN DNSKEY 257 3 13 (
|
|
GojIhhXUN/u4v54ZQqGSnyhWJwaubCvTmeexv7bR6edb
|
|
krSqQpF64cYbcB7wNcP+e+MAnLr+Wi9xMWyQLc8NAA== )`
|
|
exPriv := `Private-key-format: v1.2
|
|
Algorithm: 13 (ECDSAP256SHA256)
|
|
PrivateKey: GU6SnQ/Ou+xC5RumuIUIuJZteXT2z0O/ok1s38Et6mQ=`
|
|
rrDNSKEY := testRR(exDNSKEY)
|
|
priv, err := rrDNSKEY.(*DNSKEY).NewPrivateKey(exPriv)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
exDS := `example.net. 3600 IN DS 55648 13 2 (
|
|
b4c8c1fe2e7477127b27115656ad6256f424625bf5c1
|
|
e2770ce6d6e37df61d17 )`
|
|
rrDS := testRR(exDS)
|
|
ourDS := rrDNSKEY.(*DNSKEY).ToDS(SHA256)
|
|
if !reflect.DeepEqual(ourDS, rrDS.(*DS)) {
|
|
t.Errorf("DS record differs:\n%v\n%v", ourDS, rrDS.(*DS))
|
|
}
|
|
|
|
exA := `www.example.net. 3600 IN A 192.0.2.1`
|
|
exRRSIG := `www.example.net. 3600 IN RRSIG A 13 3 3600 (
|
|
20100909100439 20100812100439 55648 example.net.
|
|
qx6wLYqmh+l9oCKTN6qIc+bw6ya+KJ8oMz0YP107epXA
|
|
yGmt+3SNruPFKG7tZoLBLlUzGGus7ZwmwWep666VCw== )`
|
|
rrA := testRR(exA)
|
|
rrRRSIG := testRR(exRRSIG)
|
|
if err := rrRRSIG.(*RRSIG).Verify(rrDNSKEY.(*DNSKEY), []RR{rrA}); err != nil {
|
|
t.Errorf("failure to validate the spec RRSIG: %v", err)
|
|
}
|
|
|
|
ourRRSIG := &RRSIG{
|
|
Hdr: RR_Header{
|
|
Ttl: rrA.Header().Ttl,
|
|
},
|
|
KeyTag: rrDNSKEY.(*DNSKEY).KeyTag(),
|
|
SignerName: rrDNSKEY.(*DNSKEY).Hdr.Name,
|
|
Algorithm: rrDNSKEY.(*DNSKEY).Algorithm,
|
|
}
|
|
ourRRSIG.Expiration, _ = StringToTime("20100909100439")
|
|
ourRRSIG.Inception, _ = StringToTime("20100812100439")
|
|
err = ourRRSIG.Sign(priv.(*ecdsa.PrivateKey), []RR{rrA})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if err = ourRRSIG.Verify(rrDNSKEY.(*DNSKEY), []RR{rrA}); err != nil {
|
|
t.Errorf("failure to validate our RRSIG: %v", err)
|
|
}
|
|
|
|
// Signatures are randomized
|
|
rrRRSIG.(*RRSIG).Signature = ""
|
|
ourRRSIG.Signature = ""
|
|
if !reflect.DeepEqual(ourRRSIG, rrRRSIG.(*RRSIG)) {
|
|
t.Fatalf("RRSIG record differs:\n%v\n%v", ourRRSIG, rrRRSIG.(*RRSIG))
|
|
}
|
|
}
|
|
|
|
// rfc6605 6.2
|
|
func TestRFC6605P384(t *testing.T) {
|
|
exDNSKEY := `example.net. 3600 IN DNSKEY 257 3 14 (
|
|
xKYaNhWdGOfJ+nPrL8/arkwf2EY3MDJ+SErKivBVSum1
|
|
w/egsXvSADtNJhyem5RCOpgQ6K8X1DRSEkrbYQ+OB+v8
|
|
/uX45NBwY8rp65F6Glur8I/mlVNgF6W/qTI37m40 )`
|
|
exPriv := `Private-key-format: v1.2
|
|
Algorithm: 14 (ECDSAP384SHA384)
|
|
PrivateKey: WURgWHCcYIYUPWgeLmiPY2DJJk02vgrmTfitxgqcL4vwW7BOrbawVmVe0d9V94SR`
|
|
rrDNSKEY := testRR(exDNSKEY)
|
|
priv, err := rrDNSKEY.(*DNSKEY).NewPrivateKey(exPriv)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
exDS := `example.net. 3600 IN DS 10771 14 4 (
|
|
72d7b62976ce06438e9c0bf319013cf801f09ecc84b8
|
|
d7e9495f27e305c6a9b0563a9b5f4d288405c3008a94
|
|
6df983d6 )`
|
|
rrDS := testRR(exDS)
|
|
ourDS := rrDNSKEY.(*DNSKEY).ToDS(SHA384)
|
|
if !reflect.DeepEqual(ourDS, rrDS.(*DS)) {
|
|
t.Fatalf("DS record differs:\n%v\n%v", ourDS, rrDS.(*DS))
|
|
}
|
|
|
|
exA := `www.example.net. 3600 IN A 192.0.2.1`
|
|
exRRSIG := `www.example.net. 3600 IN RRSIG A 14 3 3600 (
|
|
20100909102025 20100812102025 10771 example.net.
|
|
/L5hDKIvGDyI1fcARX3z65qrmPsVz73QD1Mr5CEqOiLP
|
|
95hxQouuroGCeZOvzFaxsT8Glr74hbavRKayJNuydCuz
|
|
WTSSPdz7wnqXL5bdcJzusdnI0RSMROxxwGipWcJm )`
|
|
rrA := testRR(exA)
|
|
rrRRSIG := testRR(exRRSIG)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err = rrRRSIG.(*RRSIG).Verify(rrDNSKEY.(*DNSKEY), []RR{rrA}); err != nil {
|
|
t.Errorf("failure to validate the spec RRSIG: %v", err)
|
|
}
|
|
|
|
ourRRSIG := &RRSIG{
|
|
Hdr: RR_Header{
|
|
Ttl: rrA.Header().Ttl,
|
|
},
|
|
KeyTag: rrDNSKEY.(*DNSKEY).KeyTag(),
|
|
SignerName: rrDNSKEY.(*DNSKEY).Hdr.Name,
|
|
Algorithm: rrDNSKEY.(*DNSKEY).Algorithm,
|
|
}
|
|
ourRRSIG.Expiration, _ = StringToTime("20100909102025")
|
|
ourRRSIG.Inception, _ = StringToTime("20100812102025")
|
|
err = ourRRSIG.Sign(priv.(*ecdsa.PrivateKey), []RR{rrA})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if err = ourRRSIG.Verify(rrDNSKEY.(*DNSKEY), []RR{rrA}); err != nil {
|
|
t.Errorf("failure to validate our RRSIG: %v", err)
|
|
}
|
|
|
|
// Signatures are randomized
|
|
rrRRSIG.(*RRSIG).Signature = ""
|
|
ourRRSIG.Signature = ""
|
|
if !reflect.DeepEqual(ourRRSIG, rrRRSIG.(*RRSIG)) {
|
|
t.Fatalf("RRSIG record differs:\n%v\n%v", ourRRSIG, rrRRSIG.(*RRSIG))
|
|
}
|
|
}
|
|
|
|
// rfc8080 6.1
|
|
func TestRFC8080Ed25519Example1(t *testing.T) {
|
|
exDNSKEY := `example.com. 3600 IN DNSKEY 257 3 15 (
|
|
l02Woi0iS8Aa25FQkUd9RMzZHJpBoRQwAQEX1SxZJA4= )`
|
|
exPriv := `Private-key-format: v1.2
|
|
Algorithm: 15 (ED25519)
|
|
PrivateKey: ODIyNjAzODQ2MjgwODAxMjI2NDUxOTAyMDQxNDIyNjI=`
|
|
rrDNSKEY, err := NewRR(exDNSKEY)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
priv, err := rrDNSKEY.(*DNSKEY).NewPrivateKey(exPriv)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
exDS := `example.com. 3600 IN DS 3613 15 2 (
|
|
3aa5ab37efce57f737fc1627013fee07bdf241bd10f3b1964ab55c78e79
|
|
a304b )`
|
|
rrDS, err := NewRR(exDS)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
ourDS := rrDNSKEY.(*DNSKEY).ToDS(SHA256)
|
|
if !reflect.DeepEqual(ourDS, rrDS.(*DS)) {
|
|
t.Fatalf("DS record differs:\n%v\n%v", ourDS, rrDS.(*DS))
|
|
}
|
|
|
|
exMX := `example.com. 3600 IN MX 10 mail.example.com.`
|
|
exRRSIG := `example.com. 3600 IN RRSIG MX 15 2 3600 (
|
|
1440021600 1438207200 3613 example.com. (
|
|
oL9krJun7xfBOIWcGHi7mag5/hdZrKWw15jPGrHpjQeRAvTdszaPD+QLs3f
|
|
x8A4M3e23mRZ9VrbpMngwcrqNAg== ) )`
|
|
rrMX, err := NewRR(exMX)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
rrRRSIG, err := NewRR(exRRSIG)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err = rrRRSIG.(*RRSIG).Verify(rrDNSKEY.(*DNSKEY), []RR{rrMX}); err != nil {
|
|
t.Errorf("failure to validate the spec RRSIG: %v", err)
|
|
}
|
|
|
|
ourRRSIG := &RRSIG{
|
|
Hdr: RR_Header{
|
|
Ttl: rrMX.Header().Ttl,
|
|
},
|
|
KeyTag: rrDNSKEY.(*DNSKEY).KeyTag(),
|
|
SignerName: rrDNSKEY.(*DNSKEY).Hdr.Name,
|
|
Algorithm: rrDNSKEY.(*DNSKEY).Algorithm,
|
|
}
|
|
ourRRSIG.Expiration, _ = StringToTime("20150819220000")
|
|
ourRRSIG.Inception, _ = StringToTime("20150729220000")
|
|
err = ourRRSIG.Sign(priv.(ed25519.PrivateKey), []RR{rrMX})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if err = ourRRSIG.Verify(rrDNSKEY.(*DNSKEY), []RR{rrMX}); err != nil {
|
|
t.Errorf("failure to validate our RRSIG: %v", err)
|
|
}
|
|
|
|
if !reflect.DeepEqual(ourRRSIG, rrRRSIG.(*RRSIG)) {
|
|
t.Fatalf("RRSIG record differs:\n%v\n%v", ourRRSIG, rrRRSIG.(*RRSIG))
|
|
}
|
|
}
|
|
|
|
// rfc8080 6.1
|
|
func TestRFC8080Ed25519Example2(t *testing.T) {
|
|
exDNSKEY := `example.com. 3600 IN DNSKEY 257 3 15 (
|
|
zPnZ/QwEe7S8C5SPz2OfS5RR40ATk2/rYnE9xHIEijs= )`
|
|
exPriv := `Private-key-format: v1.2
|
|
Algorithm: 15 (ED25519)
|
|
PrivateKey: DSSF3o0s0f+ElWzj9E/Osxw8hLpk55chkmx0LYN5WiY=`
|
|
rrDNSKEY, err := NewRR(exDNSKEY)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
priv, err := rrDNSKEY.(*DNSKEY).NewPrivateKey(exPriv)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
exDS := `example.com. 3600 IN DS 35217 15 2 (
|
|
401781b934e392de492ec77ae2e15d70f6575a1c0bc59c5275c04ebe80c
|
|
6614c )`
|
|
rrDS, err := NewRR(exDS)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
ourDS := rrDNSKEY.(*DNSKEY).ToDS(SHA256)
|
|
if !reflect.DeepEqual(ourDS, rrDS.(*DS)) {
|
|
t.Fatalf("DS record differs:\n%v\n%v", ourDS, rrDS.(*DS))
|
|
}
|
|
|
|
exMX := `example.com. 3600 IN MX 10 mail.example.com.`
|
|
exRRSIG := `example.com. 3600 IN RRSIG MX 15 2 3600 (
|
|
1440021600 1438207200 35217 example.com. (
|
|
zXQ0bkYgQTEFyfLyi9QoiY6D8ZdYo4wyUhVioYZXFdT410QPRITQSqJSnzQ
|
|
oSm5poJ7gD7AQR0O7KuI5k2pcBg== ) )`
|
|
rrMX, err := NewRR(exMX)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
rrRRSIG, err := NewRR(exRRSIG)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err = rrRRSIG.(*RRSIG).Verify(rrDNSKEY.(*DNSKEY), []RR{rrMX}); err != nil {
|
|
t.Errorf("failure to validate the spec RRSIG: %v", err)
|
|
}
|
|
|
|
ourRRSIG := &RRSIG{
|
|
Hdr: RR_Header{
|
|
Ttl: rrMX.Header().Ttl,
|
|
},
|
|
KeyTag: rrDNSKEY.(*DNSKEY).KeyTag(),
|
|
SignerName: rrDNSKEY.(*DNSKEY).Hdr.Name,
|
|
Algorithm: rrDNSKEY.(*DNSKEY).Algorithm,
|
|
}
|
|
ourRRSIG.Expiration, _ = StringToTime("20150819220000")
|
|
ourRRSIG.Inception, _ = StringToTime("20150729220000")
|
|
err = ourRRSIG.Sign(priv.(ed25519.PrivateKey), []RR{rrMX})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if err = ourRRSIG.Verify(rrDNSKEY.(*DNSKEY), []RR{rrMX}); err != nil {
|
|
t.Errorf("failure to validate our RRSIG: %v", err)
|
|
}
|
|
|
|
if !reflect.DeepEqual(ourRRSIG, rrRRSIG.(*RRSIG)) {
|
|
t.Fatalf("RRSIG record differs:\n%v\n%v", ourRRSIG, rrRRSIG.(*RRSIG))
|
|
}
|
|
}
|
|
|
|
func TestInvalidRRSet(t *testing.T) {
|
|
goodRecords := make([]RR, 2)
|
|
goodRecords[0] = &TXT{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello world"}}
|
|
goodRecords[1] = &TXT{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"_o/"}}
|
|
|
|
// Generate key
|
|
keyname := "cloudflare.com."
|
|
key := &DNSKEY{
|
|
Hdr: RR_Header{Name: keyname, Rrtype: TypeDNSKEY, Class: ClassINET, Ttl: 0},
|
|
Algorithm: ECDSAP256SHA256,
|
|
Flags: ZONE,
|
|
Protocol: 3,
|
|
}
|
|
privatekey, err := key.Generate(256)
|
|
if err != nil {
|
|
t.Fatal(err.Error())
|
|
}
|
|
|
|
// Need to fill in: Inception, Expiration, KeyTag, SignerName and Algorithm
|
|
curTime := time.Now()
|
|
signature := &RRSIG{
|
|
Inception: uint32(curTime.Unix()),
|
|
Expiration: uint32(curTime.Add(time.Hour).Unix()),
|
|
KeyTag: key.KeyTag(),
|
|
SignerName: keyname,
|
|
Algorithm: ECDSAP256SHA256,
|
|
}
|
|
|
|
// Inconsistent name between records
|
|
badRecords := make([]RR, 2)
|
|
badRecords[0] = &TXT{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello world"}}
|
|
badRecords[1] = &TXT{Hdr: RR_Header{Name: "nama.cloudflare.com.", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"_o/"}}
|
|
|
|
if IsRRset(badRecords) {
|
|
t.Fatal("Record set with inconsistent names considered valid")
|
|
}
|
|
|
|
badRecords[0] = &TXT{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello world"}}
|
|
badRecords[1] = &A{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeA, Class: ClassINET, Ttl: 0}}
|
|
|
|
if IsRRset(badRecords) {
|
|
t.Fatal("Record set with inconsistent record types considered valid")
|
|
}
|
|
|
|
badRecords[0] = &TXT{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello world"}}
|
|
badRecords[1] = &TXT{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeTXT, Class: ClassCHAOS, Ttl: 0}, Txt: []string{"_o/"}}
|
|
|
|
if IsRRset(badRecords) {
|
|
t.Fatal("Record set with inconsistent record class considered valid")
|
|
}
|
|
|
|
// Sign the good record set and then make sure verification fails on the bad record set
|
|
if err := signature.Sign(privatekey.(crypto.Signer), goodRecords); err != nil {
|
|
t.Fatal("Signing good records failed")
|
|
}
|
|
|
|
if err := signature.Verify(key, badRecords); err != ErrRRset {
|
|
t.Fatal("Verification did not return ErrRRset with inconsistent records")
|
|
}
|
|
}
|
|
|
|
// Issue #688 - RSA exponent unpacked in reverse
|
|
func TestRsaExponentUnpack(t *testing.T) {
|
|
zskRrDnskey, _ := NewRR("isc.org. 7200 IN DNSKEY 256 3 5 AwEAAcdkaRUlsRD4gcF63PpPJJ1E6kOIb3yn/UHptVsPEQtEbgJ2y20O eix4unpwoQkz+bIAd2rrOU/95wgV530x0/qqKwBLWoGkxdcnNcvVT4hl 3SOTZy1VjwkAfyayHPU8VisXqJGbB3KWevBZlb6AtrXzFu8AHuBeeAAe /fOgreCh")
|
|
kskRrDnskey, _ := NewRR("isc.org. 7200 IN DNSKEY 257 3 5 BEAAAAOhHQDBrhQbtphgq2wQUpEQ5t4DtUHxoMVFu2hWLDMvoOMRXjGr hhCeFvAZih7yJHf8ZGfW6hd38hXG/xylYCO6Krpbdojwx8YMXLA5/kA+ u50WIL8ZR1R6KTbsYVMf/Qx5RiNbPClw+vT+U8eXEJmO20jIS1ULgqy3 47cBB1zMnnz/4LJpA0da9CbKj3A254T515sNIMcwsB8/2+2E63/zZrQz Bkj0BrN/9Bexjpiks3jRhZatEsXn3dTy47R09Uix5WcJt+xzqZ7+ysyL KOOedS39Z7SDmsn2eA0FKtQpwA6LXeG2w+jxmw3oA8lVUgEf/rzeC/bB yBNsO70aEFTd")
|
|
kskRrRrsig, _ := NewRR("isc.org. 7200 IN RRSIG DNSKEY 5 2 7200 20180627230244 20180528230244 12892 isc.org. ebKBlhYi1hPGTdPg6zSwvprOIkoFMs+WIhMSjoYW6/K5CS9lDDFdK4cu TgXJRT3etrltTuJiFe2HRpp+7t5cKLy+CeJZVzqrCz200MoHiFuLI9yI DJQGaS5YYCiFbw5+jUGU6aUhZ7Y5/YufeqATkRZzdrKwgK+zri8LPw9T WLoVJPAOW7GR0dgxl9WKmO7Fzi9P8BZR3NuwLV7329X94j+4zyswaw7q e5vif0ybzFveODLsEi/E0a2rTXc4QzzyM0fSVxRkVQyQ7ifIPP4ohnnT d5qpPUbE8xxBzTdWR/TaKADC5aCFkppG9lVAq5CPfClii2949X5RYzy1 rxhuSA==")
|
|
zskRrRrsig, _ := NewRR("isc.org. 7200 IN RRSIG DNSKEY 5 2 7200 20180627230244 20180528230244 19923 isc.org. RgCfzUeq4RJPGoe9RRB6cWf6d/Du+tHK5SxI5QL1waA3O5qVtQKFkY1C dq/yyVjwzfjD9F62TObujOaktv8X80ZMcNPmgHbvK1xOqelMBWv5hxj3 xRe+QQObLZ5NPfHFsphQKXvwgO5Sjk8py2B2iCr3BHCZ8S38oIfuSrQx sn8=")
|
|
|
|
zsk, ksk := zskRrDnskey.(*DNSKEY), kskRrDnskey.(*DNSKEY)
|
|
zskSig, kskSig := zskRrRrsig.(*RRSIG), kskRrRrsig.(*RRSIG)
|
|
|
|
if e := zskSig.Verify(zsk, []RR{zsk, ksk}); e != nil {
|
|
t.Fatalf("cannot verify RRSIG with keytag [%d]. Cause [%s]", zsk.KeyTag(), e.Error())
|
|
}
|
|
|
|
if e := kskSig.Verify(ksk, []RR{zsk, ksk}); e != nil {
|
|
t.Fatalf("cannot verify RRSIG with keytag [%d]. Cause [%s]", ksk.KeyTag(), e.Error())
|
|
}
|
|
}
|
|
|
|
func TestParseKeyReadError(t *testing.T) {
|
|
m, err := parseKey(errReader{}, "")
|
|
if err == nil || !strings.Contains(err.Error(), errTestReadError.Error()) {
|
|
t.Errorf("expected error to contain %q, but got %v", errTestReadError, err)
|
|
}
|
|
if m != nil {
|
|
t.Errorf("expected a nil map, but got %v", m)
|
|
}
|
|
}
|