| 
									
										
										
										
											2016-04-26 17:57:11 +01:00
										 |  |  | package dnssec
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import (
 | 
					
						
							|  |  |  | 	"testing"
 | 
					
						
							|  |  |  | 	"time"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-14 09:36:06 +01:00
										 |  |  | 	"github.com/coredns/coredns/plugin/pkg/cache"
 | 
					
						
							|  |  |  | 	"github.com/coredns/coredns/plugin/test"
 | 
					
						
							| 
									
										
										
										
											2017-02-21 22:51:47 -08:00
										 |  |  | 	"github.com/coredns/coredns/request"
 | 
					
						
							| 
									
										
										
										
											2016-04-26 17:57:11 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/miekg/dns"
 | 
					
						
							|  |  |  | )
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestZoneSigning(t *testing.T) {
 | 
					
						
							|  |  |  | 	d, rm1, rm2 := newDnssec(t, []string{"miek.nl."})
 | 
					
						
							|  |  |  | 	defer rm1()
 | 
					
						
							|  |  |  | 	defer rm2()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	m := testMsg()
 | 
					
						
							| 
									
										
										
										
											2018-01-03 11:11:56 +00:00
										 |  |  | 	state := request.Request{Req: m, Zone: "miek.nl."}
 | 
					
						
							| 
									
										
										
										
											2016-04-26 17:57:11 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-03 11:11:56 +00:00
										 |  |  | 	m = d.Sign(state, time.Now().UTC())
 | 
					
						
							| 
									
										
										
										
											2016-04-26 17:57:11 +01:00
										 |  |  | 	if !section(m.Answer, 1) {
 | 
					
						
							| 
									
										
										
										
											2017-10-20 09:22:02 +01:00
										 |  |  | 		t.Errorf("Answer section should have 1 RRSIG")
 | 
					
						
							| 
									
										
										
										
											2016-04-26 17:57:11 +01:00
										 |  |  | 	}
 | 
					
						
							|  |  |  | 	if !section(m.Ns, 1) {
 | 
					
						
							| 
									
										
										
										
											2017-10-20 09:22:02 +01:00
										 |  |  | 		t.Errorf("Authority section should have 1 RRSIG")
 | 
					
						
							| 
									
										
										
										
											2016-04-26 17:57:11 +01:00
										 |  |  | 	}
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestZoneSigningDouble(t *testing.T) {
 | 
					
						
							|  |  |  | 	d, rm1, rm2 := newDnssec(t, []string{"miek.nl."})
 | 
					
						
							|  |  |  | 	defer rm1()
 | 
					
						
							|  |  |  | 	defer rm2()
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-02 15:58:01 +01:00
										 |  |  | 	fPriv1, rmPriv1, _ := test.TempFile(".", privKey1)
 | 
					
						
							|  |  |  | 	fPub1, rmPub1, _ := test.TempFile(".", pubKey1)
 | 
					
						
							| 
									
										
										
										
											2016-04-26 17:57:11 +01:00
										 |  |  | 	defer rmPriv1()
 | 
					
						
							|  |  |  | 	defer rmPub1()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	key1, err := ParseKeyFile(fPub1, fPriv1)
 | 
					
						
							|  |  |  | 	if err != nil {
 | 
					
						
							| 
									
										
										
										
											2017-10-20 09:22:02 +01:00
										 |  |  | 		t.Fatalf("Failed to parse key: %v\n", err)
 | 
					
						
							| 
									
										
										
										
											2016-04-26 17:57:11 +01:00
										 |  |  | 	}
 | 
					
						
							|  |  |  | 	d.keys = append(d.keys, key1)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	m := testMsg()
 | 
					
						
							| 
									
										
										
										
											2018-01-03 11:11:56 +00:00
										 |  |  | 	state := request.Request{Req: m, Zone: "miek.nl."}
 | 
					
						
							|  |  |  | 	m = d.Sign(state, time.Now().UTC())
 | 
					
						
							| 
									
										
										
										
											2016-04-26 17:57:11 +01:00
										 |  |  | 	if !section(m.Answer, 2) {
 | 
					
						
							| 
									
										
										
										
											2017-10-20 09:22:02 +01:00
										 |  |  | 		t.Errorf("Answer section should have 1 RRSIG")
 | 
					
						
							| 
									
										
										
										
											2016-04-26 17:57:11 +01:00
										 |  |  | 	}
 | 
					
						
							|  |  |  | 	if !section(m.Ns, 2) {
 | 
					
						
							| 
									
										
										
										
											2017-10-20 09:22:02 +01:00
										 |  |  | 		t.Errorf("Authority section should have 1 RRSIG")
 | 
					
						
							| 
									
										
										
										
											2016-04-26 17:57:11 +01:00
										 |  |  | 	}
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // TestSigningDifferentZone tests if a key for miek.nl and be used for example.org.
 | 
					
						
							|  |  |  | func TestSigningDifferentZone(t *testing.T) {
 | 
					
						
							| 
									
										
										
										
											2016-10-02 15:58:01 +01:00
										 |  |  | 	fPriv, rmPriv, _ := test.TempFile(".", privKey)
 | 
					
						
							|  |  |  | 	fPub, rmPub, _ := test.TempFile(".", pubKey)
 | 
					
						
							| 
									
										
										
										
											2016-04-26 17:57:11 +01:00
										 |  |  | 	defer rmPriv()
 | 
					
						
							|  |  |  | 	defer rmPub()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	key, err := ParseKeyFile(fPub, fPriv)
 | 
					
						
							|  |  |  | 	if err != nil {
 | 
					
						
							| 
									
										
										
										
											2017-10-20 09:22:02 +01:00
										 |  |  | 		t.Fatalf("Failed to parse key: %v\n", err)
 | 
					
						
							| 
									
										
										
										
											2016-04-26 17:57:11 +01:00
										 |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	m := testMsgEx()
 | 
					
						
							| 
									
										
										
										
											2018-01-03 11:11:56 +00:00
										 |  |  | 	state := request.Request{Req: m, Zone: "example.org."}
 | 
					
						
							| 
									
										
										
										
											2017-06-13 12:39:10 -07:00
										 |  |  | 	c := cache.New(defaultCap)
 | 
					
						
							|  |  |  | 	d := New([]string{"example.org."}, []*DNSKEY{key}, nil, c)
 | 
					
						
							| 
									
										
										
										
											2018-01-03 11:11:56 +00:00
										 |  |  | 	m = d.Sign(state, time.Now().UTC())
 | 
					
						
							| 
									
										
										
										
											2016-04-26 17:57:11 +01:00
										 |  |  | 	if !section(m.Answer, 1) {
 | 
					
						
							| 
									
										
										
										
											2017-10-20 09:22:02 +01:00
										 |  |  | 		t.Errorf("Answer section should have 1 RRSIG")
 | 
					
						
							| 
									
										
										
										
											2016-10-08 15:22:31 +01:00
										 |  |  | 		t.Logf("%+v\n", m)
 | 
					
						
							| 
									
										
										
										
											2016-04-26 17:57:11 +01:00
										 |  |  | 	}
 | 
					
						
							|  |  |  | 	if !section(m.Ns, 1) {
 | 
					
						
							| 
									
										
										
										
											2017-10-20 09:22:02 +01:00
										 |  |  | 		t.Errorf("Authority section should have 1 RRSIG")
 | 
					
						
							| 
									
										
										
										
											2016-10-08 15:22:31 +01:00
										 |  |  | 		t.Logf("%+v\n", m)
 | 
					
						
							| 
									
										
										
										
											2016-04-26 17:57:11 +01:00
										 |  |  | 	}
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestSigningCname(t *testing.T) {
 | 
					
						
							|  |  |  | 	d, rm1, rm2 := newDnssec(t, []string{"miek.nl."})
 | 
					
						
							|  |  |  | 	defer rm1()
 | 
					
						
							|  |  |  | 	defer rm2()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	m := testMsgCname()
 | 
					
						
							| 
									
										
										
										
											2018-01-03 11:11:56 +00:00
										 |  |  | 	state := request.Request{Req: m, Zone: "miek.nl."}
 | 
					
						
							|  |  |  | 	m = d.Sign(state, time.Now().UTC())
 | 
					
						
							| 
									
										
										
										
											2016-04-26 17:57:11 +01:00
										 |  |  | 	if !section(m.Answer, 1) {
 | 
					
						
							| 
									
										
										
										
											2017-10-20 09:22:02 +01:00
										 |  |  | 		t.Errorf("Answer section should have 1 RRSIG")
 | 
					
						
							| 
									
										
										
										
											2016-04-26 17:57:11 +01:00
										 |  |  | 	}
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-01 11:14:39 +00:00
										 |  |  | // Disabled for now, see #1211.
 | 
					
						
							|  |  |  | func testZoneSigningDelegation(t *testing.T) {
 | 
					
						
							| 
									
										
										
										
											2016-04-26 17:57:11 +01:00
										 |  |  | 	d, rm1, rm2 := newDnssec(t, []string{"miek.nl."})
 | 
					
						
							|  |  |  | 	defer rm1()
 | 
					
						
							|  |  |  | 	defer rm2()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	m := testDelegationMsg()
 | 
					
						
							| 
									
										
										
										
											2018-01-03 11:11:56 +00:00
										 |  |  | 	state := request.Request{Req: m, Zone: "miek.nl."}
 | 
					
						
							|  |  |  | 	m = d.Sign(state, time.Now().UTC())
 | 
					
						
							| 
									
										
										
										
											2017-10-20 09:22:02 +01:00
										 |  |  | 	if !section(m.Ns, 1) {
 | 
					
						
							|  |  |  | 		t.Errorf("Authority section should have 1 RRSIG")
 | 
					
						
							| 
									
										
										
										
											2016-04-26 17:57:11 +01:00
										 |  |  | 		t.Logf("%v\n", m)
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							| 
									
										
										
										
											2017-10-20 09:22:02 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	ds := 0
 | 
					
						
							|  |  |  | 	for i := range m.Ns {
 | 
					
						
							|  |  |  | 		if _, ok := m.Ns[i].(*dns.DS); ok {
 | 
					
						
							|  |  |  | 			ds++
 | 
					
						
							|  |  |  | 		}
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 	if ds != 1 {
 | 
					
						
							|  |  |  | 		t.Errorf("Authority section should have 1 DS")
 | 
					
						
							|  |  |  | 		t.Logf("%v\n", m)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							| 
									
										
										
										
											2016-04-26 17:57:11 +01:00
										 |  |  | 	if !section(m.Extra, 0) {
 | 
					
						
							| 
									
										
										
										
											2017-10-20 09:22:02 +01:00
										 |  |  | 		t.Errorf("Answer section should have 0 RRSIGs")
 | 
					
						
							| 
									
										
										
										
											2016-04-26 17:57:11 +01:00
										 |  |  | 		t.Logf("%v\n", m)
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-02 17:18:58 +01:00
										 |  |  | func TestSigningDname(t *testing.T) {
 | 
					
						
							|  |  |  | 	d, rm1, rm2 := newDnssec(t, []string{"miek.nl."})
 | 
					
						
							|  |  |  | 	defer rm1()
 | 
					
						
							|  |  |  | 	defer rm2()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	m := testMsgDname()
 | 
					
						
							| 
									
										
										
										
											2018-01-03 11:11:56 +00:00
										 |  |  | 	state := request.Request{Req: m, Zone: "miek.nl."}
 | 
					
						
							| 
									
										
										
										
											2017-06-02 17:18:58 +01:00
										 |  |  | 	// We sign *everything* we see, also the synthesized CNAME.
 | 
					
						
							| 
									
										
										
										
											2018-01-03 11:11:56 +00:00
										 |  |  | 	m = d.Sign(state, time.Now().UTC())
 | 
					
						
							| 
									
										
										
										
											2017-06-02 17:18:58 +01:00
										 |  |  | 	if !section(m.Answer, 3) {
 | 
					
						
							| 
									
										
										
										
											2017-10-20 09:22:02 +01:00
										 |  |  | 		t.Errorf("Answer section should have 3 RRSIGs")
 | 
					
						
							| 
									
										
										
										
											2017-06-02 17:18:58 +01:00
										 |  |  | 	}
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-08 13:28:35 +02:00
										 |  |  | func TestSigningEmpty(t *testing.T) {
 | 
					
						
							|  |  |  | 	d, rm1, rm2 := newDnssec(t, []string{"miek.nl."})
 | 
					
						
							|  |  |  | 	defer rm1()
 | 
					
						
							|  |  |  | 	defer rm2()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	m := testEmptyMsg()
 | 
					
						
							|  |  |  | 	m.SetQuestion("a.miek.nl.", dns.TypeA)
 | 
					
						
							| 
									
										
										
										
											2018-01-03 11:11:56 +00:00
										 |  |  | 	state := request.Request{Req: m, Zone: "miek.nl."}
 | 
					
						
							|  |  |  | 	m = d.Sign(state, time.Now().UTC())
 | 
					
						
							| 
									
										
										
										
											2017-10-08 13:28:35 +02:00
										 |  |  | 	if !section(m.Ns, 2) {
 | 
					
						
							| 
									
										
										
										
											2017-10-20 09:22:02 +01:00
										 |  |  | 		t.Errorf("Authority section should have 2 RRSIGs")
 | 
					
						
							| 
									
										
										
										
											2017-10-08 13:28:35 +02:00
										 |  |  | 	}
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-26 17:57:11 +01:00
										 |  |  | func section(rss []dns.RR, nrSigs int) bool {
 | 
					
						
							|  |  |  | 	i := 0
 | 
					
						
							|  |  |  | 	for _, r := range rss {
 | 
					
						
							|  |  |  | 		if r.Header().Rrtype == dns.TypeRRSIG {
 | 
					
						
							|  |  |  | 			i++
 | 
					
						
							|  |  |  | 		}
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 	return nrSigs == i
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func testMsg() *dns.Msg {
 | 
					
						
							|  |  |  | 	// don't care about the message header
 | 
					
						
							|  |  |  | 	return &dns.Msg{
 | 
					
						
							|  |  |  | 		Answer: []dns.RR{test.MX("miek.nl.	1703	IN	MX	1 aspmx.l.google.com.")},
 | 
					
						
							|  |  |  | 		Ns: []dns.RR{test.NS("miek.nl.	1703	IN	NS	omval.tednet.nl.")},
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | func testMsgEx() *dns.Msg {
 | 
					
						
							|  |  |  | 	return &dns.Msg{
 | 
					
						
							|  |  |  | 		Answer: []dns.RR{test.MX("example.org.	1703	IN	MX	1 aspmx.l.google.com.")},
 | 
					
						
							|  |  |  | 		Ns: []dns.RR{test.NS("example.org.	1703	IN	NS	omval.tednet.nl.")},
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func testMsgCname() *dns.Msg {
 | 
					
						
							|  |  |  | 	return &dns.Msg{
 | 
					
						
							|  |  |  | 		Answer: []dns.RR{test.CNAME("www.miek.nl.	1800	IN	CNAME	a.miek.nl.")},
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func testDelegationMsg() *dns.Msg {
 | 
					
						
							|  |  |  | 	return &dns.Msg{
 | 
					
						
							|  |  |  | 		Ns: []dns.RR{
 | 
					
						
							|  |  |  | 			test.NS("miek.nl.	3600	IN	NS	linode.atoom.net."),
 | 
					
						
							|  |  |  | 			test.NS("miek.nl.	3600	IN	NS	ns-ext.nlnetlabs.nl."),
 | 
					
						
							|  |  |  | 			test.NS("miek.nl.	3600	IN	NS	omval.tednet.nl."),
 | 
					
						
							|  |  |  | 		},
 | 
					
						
							|  |  |  | 		Extra: []dns.RR{
 | 
					
						
							|  |  |  | 			test.A("omval.tednet.nl.	3600	IN	A	185.49.141.42"),
 | 
					
						
							|  |  |  | 			test.AAAA("omval.tednet.nl.	3600	IN	AAAA	2a04:b900:0:100::42"),
 | 
					
						
							|  |  |  | 		},
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-02 17:18:58 +01:00
										 |  |  | func testMsgDname() *dns.Msg {
 | 
					
						
							|  |  |  | 	return &dns.Msg{
 | 
					
						
							|  |  |  | 		Answer: []dns.RR{
 | 
					
						
							|  |  |  | 			test.CNAME("a.dname.miek.nl.	1800	IN	CNAME	a.test.miek.nl."),
 | 
					
						
							|  |  |  | 			test.A("a.test.miek.nl.	1800	IN	A	139.162.196.78"),
 | 
					
						
							|  |  |  | 			test.DNAME("dname.miek.nl.	1800	IN	DNAME	test.miek.nl."),
 | 
					
						
							|  |  |  | 		},
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-08 13:28:35 +02:00
										 |  |  | func testEmptyMsg() *dns.Msg {
 | 
					
						
							|  |  |  | 	// don't care about the message header
 | 
					
						
							|  |  |  | 	return &dns.Msg{
 | 
					
						
							|  |  |  | 		Ns: []dns.RR{test.SOA("miek.nl.	1800	IN	SOA	ns.miek.nl. dnsmaster.miek.nl. 2017100301 200 100 604800 3600")},
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-26 17:57:11 +01:00
										 |  |  | func newDnssec(t *testing.T, zones []string) (Dnssec, func(), func()) {
 | 
					
						
							|  |  |  | 	k, rm1, rm2 := newKey(t)
 | 
					
						
							| 
									
										
										
										
											2017-06-13 12:39:10 -07:00
										 |  |  | 	c := cache.New(defaultCap)
 | 
					
						
							|  |  |  | 	d := New(zones, []*DNSKEY{k}, nil, c)
 | 
					
						
							| 
									
										
										
										
											2016-04-26 17:57:11 +01:00
										 |  |  | 	return d, rm1, rm2
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func newKey(t *testing.T) (*DNSKEY, func(), func()) {
 | 
					
						
							| 
									
										
										
										
											2016-10-02 15:58:01 +01:00
										 |  |  | 	fPriv, rmPriv, _ := test.TempFile(".", privKey)
 | 
					
						
							|  |  |  | 	fPub, rmPub, _ := test.TempFile(".", pubKey)
 | 
					
						
							| 
									
										
										
										
											2016-04-26 17:57:11 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	key, err := ParseKeyFile(fPub, fPriv)
 | 
					
						
							|  |  |  | 	if err != nil {
 | 
					
						
							|  |  |  | 		t.Fatalf("failed to parse key: %v\n", err)
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 	return key, rmPriv, rmPub
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const (
 | 
					
						
							|  |  |  | 	pubKey  = `miek.nl. IN DNSKEY 257 3 13 0J8u0XJ9GNGFEBXuAmLu04taHG4BXPP3gwhetiOUMnGA+x09nqzgF5IY OyjWB7N3rXqQbnOSILhH1hnuyh7mmA==`
 | 
					
						
							|  |  |  | 	privKey = `Private-key-format: v1.3
 | 
					
						
							|  |  |  | Algorithm: 13 (ECDSAP256SHA256)
 | 
					
						
							|  |  |  | PrivateKey: /4BZk8AFvyW5hL3cOLSVxIp1RTqHSAEloWUxj86p3gs=
 | 
					
						
							|  |  |  | Created: 20160423195532
 | 
					
						
							|  |  |  | Publish: 20160423195532
 | 
					
						
							|  |  |  | Activate: 20160423195532
 | 
					
						
							|  |  |  | `
 | 
					
						
							|  |  |  | 	pubKey1  = `example.org. IN DNSKEY 257 3 13 tVRWNSGpHZbCi7Pr7OmbADVUO3MxJ0Lb8Lk3o/HBHqCxf5K/J50lFqRa 98lkdAIiFOVRy8LyMvjwmxZKwB5MNw==`
 | 
					
						
							|  |  |  | 	privKey1 = `Private-key-format: v1.3
 | 
					
						
							|  |  |  | Algorithm: 13 (ECDSAP256SHA256)
 | 
					
						
							|  |  |  | PrivateKey: i8j4OfDGT8CQt24SDwLz2hg9yx4qKOEOh1LvbAuSp1c=
 | 
					
						
							|  |  |  | Created: 20160423211746
 | 
					
						
							|  |  |  | Publish: 20160423211746
 | 
					
						
							|  |  |  | Activate: 20160423211746
 | 
					
						
							|  |  |  | `
 | 
					
						
							|  |  |  | )
 |