1package dns
2
3import (
4	"crypto"
5	"crypto/ecdsa"
6	"crypto/rsa"
7	"reflect"
8	"strings"
9	"testing"
10	"time"
11
12	"golang.org/x/crypto/ed25519"
13)
14
15func getSoa() *SOA {
16	soa := new(SOA)
17	soa.Hdr = RR_Header{"miek.nl.", TypeSOA, ClassINET, 14400, 0}
18	soa.Ns = "open.nlnetlabs.nl."
19	soa.Mbox = "miekg.atoom.net."
20	soa.Serial = 1293945905
21	soa.Refresh = 14400
22	soa.Retry = 3600
23	soa.Expire = 604800
24	soa.Minttl = 86400
25	return soa
26}
27
28func TestSecure(t *testing.T) {
29	soa := getSoa()
30
31	sig := new(RRSIG)
32	sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0}
33	sig.TypeCovered = TypeSOA
34	sig.Algorithm = RSASHA256
35	sig.Labels = 2
36	sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05"
37	sig.Inception = 1293942305  // date -u '+%s' -d"2011-01-02 04:25:05"
38	sig.OrigTtl = 14400
39	sig.KeyTag = 12051
40	sig.SignerName = "miek.nl."
41	sig.Signature = "oMCbslaAVIp/8kVtLSms3tDABpcPRUgHLrOR48OOplkYo+8TeEGWwkSwaz/MRo2fB4FxW0qj/hTlIjUGuACSd+b1wKdH5GvzRJc2pFmxtCbm55ygAh4EUL0F6U5cKtGJGSXxxg6UFCQ0doJCmiGFa78LolaUOXImJrk6AFrGa0M="
42
43	key := new(DNSKEY)
44	key.Hdr.Name = "miek.nl."
45	key.Hdr.Class = ClassINET
46	key.Hdr.Ttl = 14400
47	key.Flags = 256
48	key.Protocol = 3
49	key.Algorithm = RSASHA256
50	key.PublicKey = "AwEAAcNEU67LJI5GEgF9QLNqLO1SMq1EdoQ6E9f85ha0k0ewQGCblyW2836GiVsm6k8Kr5ECIoMJ6fZWf3CQSQ9ycWfTyOHfmI3eQ/1Covhb2y4bAmL/07PhrL7ozWBW3wBfM335Ft9xjtXHPy7ztCbV9qZ4TVDTW/Iyg0PiwgoXVesz"
51
52	// It should validate. Period is checked separately, so this will keep on working
53	if sig.Verify(key, []RR{soa}) != nil {
54		t.Error("failure to validate")
55	}
56}
57
58func TestSignature(t *testing.T) {
59	sig := new(RRSIG)
60	sig.Hdr.Name = "miek.nl."
61	sig.Hdr.Class = ClassINET
62	sig.Hdr.Ttl = 3600
63	sig.TypeCovered = TypeDNSKEY
64	sig.Algorithm = RSASHA1
65	sig.Labels = 2
66	sig.OrigTtl = 4000
67	sig.Expiration = 1000 //Thu Jan  1 02:06:40 CET 1970
68	sig.Inception = 800   //Thu Jan  1 01:13:20 CET 1970
69	sig.KeyTag = 34641
70	sig.SignerName = "miek.nl."
71	sig.Signature = "AwEAAaHIwpx3w4VHKi6i1LHnTaWeHCL154Jug0Rtc9ji5qwPXpBo6A5sRv7cSsPQKPIwxLpyCrbJ4mr2L0EPOdvP6z6YfljK2ZmTbogU9aSU2fiq/4wjxbdkLyoDVgtO+JsxNN4bjr4WcWhsmk1Hg93FV9ZpkWb0Tbad8DFqNDzr//kZ"
72
73	// Should not be valid
74	if sig.ValidityPeriod(time.Now()) {
75		t.Error("should not be valid")
76	}
77
78	sig.Inception = 315565800   //Tue Jan  1 10:10:00 CET 1980
79	sig.Expiration = 4102477800 //Fri Jan  1 10:10:00 CET 2100
80	if !sig.ValidityPeriod(time.Now()) {
81		t.Error("should be valid")
82	}
83}
84
85func TestSignVerify(t *testing.T) {
86	// The record we want to sign
87	soa := new(SOA)
88	soa.Hdr = RR_Header{"miek.nl.", TypeSOA, ClassINET, 14400, 0}
89	soa.Ns = "open.nlnetlabs.nl."
90	soa.Mbox = "miekg.atoom.net."
91	soa.Serial = 1293945905
92	soa.Refresh = 14400
93	soa.Retry = 3600
94	soa.Expire = 604800
95	soa.Minttl = 86400
96
97	soa1 := new(SOA)
98	soa1.Hdr = RR_Header{"*.miek.nl.", TypeSOA, ClassINET, 14400, 0}
99	soa1.Ns = "open.nlnetlabs.nl."
100	soa1.Mbox = "miekg.atoom.net."
101	soa1.Serial = 1293945905
102	soa1.Refresh = 14400
103	soa1.Retry = 3600
104	soa1.Expire = 604800
105	soa1.Minttl = 86400
106
107	srv := new(SRV)
108	srv.Hdr = RR_Header{"srv.miek.nl.", TypeSRV, ClassINET, 14400, 0}
109	srv.Port = 1000
110	srv.Weight = 800
111	srv.Target = "web1.miek.nl."
112
113	hinfo := &HINFO{
114		Hdr: RR_Header{
115			Name:   "miek.nl.",
116			Rrtype: TypeHINFO,
117			Class:  ClassINET,
118			Ttl:    3789,
119		},
120		Cpu: "X",
121		Os:  "Y",
122	}
123
124	// With this key
125	key := new(DNSKEY)
126	key.Hdr.Rrtype = TypeDNSKEY
127	key.Hdr.Name = "miek.nl."
128	key.Hdr.Class = ClassINET
129	key.Hdr.Ttl = 14400
130	key.Flags = 256
131	key.Protocol = 3
132	key.Algorithm = RSASHA256
133	privkey, _ := key.Generate(512)
134
135	// Fill in the values of the Sig, before signing
136	sig := new(RRSIG)
137	sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0}
138	sig.TypeCovered = soa.Hdr.Rrtype
139	sig.Labels = uint8(CountLabel(soa.Hdr.Name)) // works for all 3
140	sig.OrigTtl = soa.Hdr.Ttl
141	sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05"
142	sig.Inception = 1293942305  // date -u '+%s' -d"2011-01-02 04:25:05"
143	sig.KeyTag = key.KeyTag()   // Get the keyfrom the Key
144	sig.SignerName = key.Hdr.Name
145	sig.Algorithm = RSASHA256
146
147	for _, r := range []RR{soa, soa1, srv, hinfo} {
148		if err := sig.Sign(privkey.(*rsa.PrivateKey), []RR{r}); err != nil {
149			t.Error("failure to sign the record:", err)
150			continue
151		}
152		if err := sig.Verify(key, []RR{r}); err != nil {
153			t.Errorf("failure to validate: %s", r.Header().Name)
154			continue
155		}
156	}
157}
158
159func Test65534(t *testing.T) {
160	t6 := new(RFC3597)
161	t6.Hdr = RR_Header{"miek.nl.", 65534, ClassINET, 14400, 0}
162	t6.Rdata = "505D870001"
163	key := new(DNSKEY)
164	key.Hdr.Name = "miek.nl."
165	key.Hdr.Rrtype = TypeDNSKEY
166	key.Hdr.Class = ClassINET
167	key.Hdr.Ttl = 14400
168	key.Flags = 256
169	key.Protocol = 3
170	key.Algorithm = RSASHA256
171	privkey, _ := key.Generate(1024)
172
173	sig := new(RRSIG)
174	sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0}
175	sig.TypeCovered = t6.Hdr.Rrtype
176	sig.Labels = uint8(CountLabel(t6.Hdr.Name))
177	sig.OrigTtl = t6.Hdr.Ttl
178	sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05"
179	sig.Inception = 1293942305  // date -u '+%s' -d"2011-01-02 04:25:05"
180	sig.KeyTag = key.KeyTag()
181	sig.SignerName = key.Hdr.Name
182	sig.Algorithm = RSASHA256
183	if err := sig.Sign(privkey.(*rsa.PrivateKey), []RR{t6}); err != nil {
184		t.Error(err)
185		t.Error("failure to sign the TYPE65534 record")
186	}
187	if err := sig.Verify(key, []RR{t6}); err != nil {
188		t.Error(err)
189		t.Errorf("failure to validate %s", t6.Header().Name)
190	}
191}
192
193func TestDnskey(t *testing.T) {
194	pubkey, err := ReadRR(strings.NewReader(`
195miek.nl.	IN	DNSKEY	256 3 10 AwEAAZuMCu2FdugHkTrXYgl5qixvcDw1aDDlvL46/xJKbHBAHY16fNUb2b65cwko2Js/aJxUYJbZk5dwCDZxYfrfbZVtDPQuc3o8QaChVxC7/JYz2AHc9qHvqQ1j4VrH71RWINlQo6VYjzN/BGpMhOZoZOEwzp1HfsOE3lNYcoWU1smL ;{id = 5240 (zsk), size = 1024b}
196`), "Kmiek.nl.+010+05240.key")
197	if err != nil {
198		t.Fatal(err)
199	}
200	privStr := `Private-key-format: v1.3
201Algorithm: 10 (RSASHA512)
202Modulus: m4wK7YV26AeROtdiCXmqLG9wPDVoMOW8vjr/EkpscEAdjXp81RvZvrlzCSjYmz9onFRgltmTl3AINnFh+t9tlW0M9C5zejxBoKFXELv8ljPYAdz2oe+pDWPhWsfvVFYg2VCjpViPM38EakyE5mhk4TDOnUd+w4TeU1hyhZTWyYs=
203PublicExponent: AQAB
204PrivateExponent: UfCoIQ/Z38l8vB6SSqOI/feGjHEl/fxIPX4euKf0D/32k30fHbSaNFrFOuIFmWMB3LimWVEs6u3dpbB9CQeCVg7hwU5puG7OtuiZJgDAhNeOnxvo5btp4XzPZrJSxR4WNQnwIiYWbl0aFlL1VGgHC/3By89ENZyWaZcMLW4KGWE=
205Prime1: yxwC6ogAu8aVcDx2wg1V0b5M5P6jP8qkRFVMxWNTw60Vkn+ECvw6YAZZBHZPaMyRYZLzPgUlyYRd0cjupy4+fQ==
206Prime2: xA1bF8M0RTIQ6+A11AoVG6GIR/aPGg5sogRkIZ7ID/sF6g9HMVU/CM2TqVEBJLRPp73cv6ZeC3bcqOCqZhz+pw==
207Exponent1: xzkblyZ96bGYxTVZm2/vHMOXswod4KWIyMoOepK6B/ZPcZoIT6omLCgtypWtwHLfqyCz3MK51Nc0G2EGzg8rFQ==
208Exponent2: Pu5+mCEb7T5F+kFNZhQadHUklt0JUHbi3hsEvVoHpEGSw3BGDQrtIflDde0/rbWHgDPM4WQY+hscd8UuTXrvLw==
209Coefficient: UuRoNqe7YHnKmQzE6iDWKTMIWTuoqqrFAmXPmKQnC+Y+BQzOVEHUo9bXdDnoI9hzXP1gf8zENMYwYLeWpuYlFQ==
210`
211	privkey, err := pubkey.(*DNSKEY).ReadPrivateKey(strings.NewReader(privStr),
212		"Kmiek.nl.+010+05240.private")
213	if err != nil {
214		t.Fatal(err)
215	}
216	if pubkey.(*DNSKEY).PublicKey != "AwEAAZuMCu2FdugHkTrXYgl5qixvcDw1aDDlvL46/xJKbHBAHY16fNUb2b65cwko2Js/aJxUYJbZk5dwCDZxYfrfbZVtDPQuc3o8QaChVxC7/JYz2AHc9qHvqQ1j4VrH71RWINlQo6VYjzN/BGpMhOZoZOEwzp1HfsOE3lNYcoWU1smL" {
217		t.Error("pubkey is not what we've read")
218	}
219	if pubkey.(*DNSKEY).PrivateKeyString(privkey) != privStr {
220		t.Error("privkey is not what we've read")
221		t.Errorf("%v", pubkey.(*DNSKEY).PrivateKeyString(privkey))
222	}
223}
224
225func TestTag(t *testing.T) {
226	key := new(DNSKEY)
227	key.Hdr.Name = "miek.nl."
228	key.Hdr.Rrtype = TypeDNSKEY
229	key.Hdr.Class = ClassINET
230	key.Hdr.Ttl = 3600
231	key.Flags = 256
232	key.Protocol = 3
233	key.Algorithm = RSASHA256
234	key.PublicKey = "AwEAAcNEU67LJI5GEgF9QLNqLO1SMq1EdoQ6E9f85ha0k0ewQGCblyW2836GiVsm6k8Kr5ECIoMJ6fZWf3CQSQ9ycWfTyOHfmI3eQ/1Covhb2y4bAmL/07PhrL7ozWBW3wBfM335Ft9xjtXHPy7ztCbV9qZ4TVDTW/Iyg0PiwgoXVesz"
235
236	tag := key.KeyTag()
237	if tag != 12051 {
238		t.Errorf("wrong key tag: %d for key %v", tag, key)
239	}
240}
241
242func TestKeyRSA(t *testing.T) {
243	if testing.Short() {
244		t.Skip("skipping test in short mode.")
245	}
246	key := new(DNSKEY)
247	key.Hdr.Name = "miek.nl."
248	key.Hdr.Rrtype = TypeDNSKEY
249	key.Hdr.Class = ClassINET
250	key.Hdr.Ttl = 3600
251	key.Flags = 256
252	key.Protocol = 3
253	key.Algorithm = RSASHA256
254	priv, _ := key.Generate(2048)
255
256	soa := new(SOA)
257	soa.Hdr = RR_Header{"miek.nl.", TypeSOA, ClassINET, 14400, 0}
258	soa.Ns = "open.nlnetlabs.nl."
259	soa.Mbox = "miekg.atoom.net."
260	soa.Serial = 1293945905
261	soa.Refresh = 14400
262	soa.Retry = 3600
263	soa.Expire = 604800
264	soa.Minttl = 86400
265
266	sig := new(RRSIG)
267	sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0}
268	sig.TypeCovered = TypeSOA
269	sig.Algorithm = RSASHA256
270	sig.Labels = 2
271	sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05"
272	sig.Inception = 1293942305  // date -u '+%s' -d"2011-01-02 04:25:05"
273	sig.OrigTtl = soa.Hdr.Ttl
274	sig.KeyTag = key.KeyTag()
275	sig.SignerName = key.Hdr.Name
276
277	if err := sig.Sign(priv.(*rsa.PrivateKey), []RR{soa}); err != nil {
278		t.Error("failed to sign")
279		return
280	}
281	if err := sig.Verify(key, []RR{soa}); err != nil {
282		t.Error("failed to verify")
283	}
284}
285
286func TestKeyToDS(t *testing.T) {
287	key := new(DNSKEY)
288	key.Hdr.Name = "miek.nl."
289	key.Hdr.Rrtype = TypeDNSKEY
290	key.Hdr.Class = ClassINET
291	key.Hdr.Ttl = 3600
292	key.Flags = 256
293	key.Protocol = 3
294	key.Algorithm = RSASHA256
295	key.PublicKey = "AwEAAcNEU67LJI5GEgF9QLNqLO1SMq1EdoQ6E9f85ha0k0ewQGCblyW2836GiVsm6k8Kr5ECIoMJ6fZWf3CQSQ9ycWfTyOHfmI3eQ/1Covhb2y4bAmL/07PhrL7ozWBW3wBfM335Ft9xjtXHPy7ztCbV9qZ4TVDTW/Iyg0PiwgoXVesz"
296
297	ds := key.ToDS(SHA1)
298	if strings.ToUpper(ds.Digest) != "B5121BDB5B8D86D0CC5FFAFBAAABE26C3E20BAC1" {
299		t.Errorf("wrong DS digest for SHA1\n%v", ds)
300	}
301}
302
303func TestSignRSA(t *testing.T) {
304	pub := "miek.nl. IN DNSKEY 256 3 5 AwEAAb+8lGNCxJgLS8rYVer6EnHVuIkQDghdjdtewDzU3G5R7PbMbKVRvH2Ma7pQyYceoaqWZQirSj72euPWfPxQnMy9ucCylA+FuH9cSjIcPf4PqJfdupHk9X6EBYjxrCLY4p1/yBwgyBIRJtZtAqM3ceAH2WovEJD6rTtOuHo5AluJ"
305
306	priv := `Private-key-format: v1.3
307Algorithm: 5 (RSASHA1)
308Modulus: v7yUY0LEmAtLythV6voScdW4iRAOCF2N217APNTcblHs9sxspVG8fYxrulDJhx6hqpZlCKtKPvZ649Z8/FCczL25wLKUD4W4f1xKMhw9/g+ol926keT1foQFiPGsItjinX/IHCDIEhEm1m0Cozdx4AfZai8QkPqtO064ejkCW4k=
309PublicExponent: AQAB
310PrivateExponent: YPwEmwjk5HuiROKU4xzHQ6l1hG8Iiha4cKRG3P5W2b66/EN/GUh07ZSf0UiYB67o257jUDVEgwCuPJz776zfApcCB4oGV+YDyEu7Hp/rL8KcSN0la0k2r9scKwxTp4BTJT23zyBFXsV/1wRDK1A5NxsHPDMYi2SoK63Enm/1ptk=
311Prime1: /wjOG+fD0ybNoSRn7nQ79udGeR1b0YhUA5mNjDx/x2fxtIXzygYk0Rhx9QFfDy6LOBvz92gbNQlzCLz3DJt5hw==
312Prime2: wHZsJ8OGhkp5p3mrJFZXMDc2mbYusDVTA+t+iRPdS797Tj0pjvU2HN4vTnTj8KBQp6hmnY7dLp9Y1qserySGbw==
313Exponent1: N0A7FsSRIg+IAN8YPQqlawoTtG1t1OkJ+nWrurPootScApX6iMvn8fyvw3p2k51rv84efnzpWAYiC8SUaQDNxQ==
314Exponent2: SvuYRaGyvo0zemE3oS+WRm2scxR8eiA8WJGeOc+obwOKCcBgeZblXzfdHGcEC1KaOcetOwNW/vwMA46lpLzJNw==
315Coefficient: 8+7ZN/JgByqv0NfULiFKTjtyegUcijRuyij7yNxYbCBneDvZGxJwKNi4YYXWx743pcAj4Oi4Oh86gcmxLs+hGw==
316Created: 20110302104537
317Publish: 20110302104537
318Activate: 20110302104537`
319
320	xk := testRR(pub)
321	k := xk.(*DNSKEY)
322	p, err := k.NewPrivateKey(priv)
323	if err != nil {
324		t.Error(err)
325	}
326	switch priv := p.(type) {
327	case *rsa.PrivateKey:
328		if 65537 != priv.PublicKey.E {
329			t.Error("exponenent should be 65537")
330		}
331	default:
332		t.Errorf("we should have read an RSA key: %v", priv)
333	}
334	if k.KeyTag() != 37350 {
335		t.Errorf("keytag should be 37350, got %d %v", k.KeyTag(), k)
336	}
337
338	soa := new(SOA)
339	soa.Hdr = RR_Header{"miek.nl.", TypeSOA, ClassINET, 14400, 0}
340	soa.Ns = "open.nlnetlabs.nl."
341	soa.Mbox = "miekg.atoom.net."
342	soa.Serial = 1293945905
343	soa.Refresh = 14400
344	soa.Retry = 3600
345	soa.Expire = 604800
346	soa.Minttl = 86400
347
348	sig := new(RRSIG)
349	sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0}
350	sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05"
351	sig.Inception = 1293942305  // date -u '+%s' -d"2011-01-02 04:25:05"
352	sig.KeyTag = k.KeyTag()
353	sig.SignerName = k.Hdr.Name
354	sig.Algorithm = k.Algorithm
355
356	sig.Sign(p.(*rsa.PrivateKey), []RR{soa})
357	if sig.Signature != "D5zsobpQcmMmYsUMLxCVEtgAdCvTu8V/IEeP4EyLBjqPJmjt96bwM9kqihsccofA5LIJ7DN91qkCORjWSTwNhzCv7bMyr2o5vBZElrlpnRzlvsFIoAZCD9xg6ZY7ZyzUJmU6IcTwG4v3xEYajcpbJJiyaw/RqR90MuRdKPiBzSo=" {
358		t.Errorf("signature is not correct: %v", sig)
359	}
360}
361
362func TestSignVerifyECDSA(t *testing.T) {
363	pub := `example.net. 3600 IN DNSKEY 257 3 14 (
364	xKYaNhWdGOfJ+nPrL8/arkwf2EY3MDJ+SErKivBVSum1
365	w/egsXvSADtNJhyem5RCOpgQ6K8X1DRSEkrbYQ+OB+v8
366	/uX45NBwY8rp65F6Glur8I/mlVNgF6W/qTI37m40 )`
367	priv := `Private-key-format: v1.2
368Algorithm: 14 (ECDSAP384SHA384)
369PrivateKey: WURgWHCcYIYUPWgeLmiPY2DJJk02vgrmTfitxgqcL4vwW7BOrbawVmVe0d9V94SR`
370
371	eckey := testRR(pub)
372	privkey, err := eckey.(*DNSKEY).NewPrivateKey(priv)
373	if err != nil {
374		t.Fatal(err)
375	}
376	// TODO: Create separate test for this
377	ds := eckey.(*DNSKEY).ToDS(SHA384)
378	if ds.KeyTag != 10771 {
379		t.Fatal("wrong keytag on DS")
380	}
381	if ds.Digest != "72d7b62976ce06438e9c0bf319013cf801f09ecc84b8d7e9495f27e305c6a9b0563a9b5f4d288405c3008a946df983d6" {
382		t.Fatal("wrong DS Digest")
383	}
384	a := testRR("www.example.net. 3600 IN A 192.0.2.1")
385	sig := new(RRSIG)
386	sig.Hdr = RR_Header{"example.net.", TypeRRSIG, ClassINET, 14400, 0}
387	sig.Expiration, _ = StringToTime("20100909102025")
388	sig.Inception, _ = StringToTime("20100812102025")
389	sig.KeyTag = eckey.(*DNSKEY).KeyTag()
390	sig.SignerName = eckey.(*DNSKEY).Hdr.Name
391	sig.Algorithm = eckey.(*DNSKEY).Algorithm
392
393	if sig.Sign(privkey.(*ecdsa.PrivateKey), []RR{a}) != nil {
394		t.Fatal("failure to sign the record")
395	}
396
397	if err := sig.Verify(eckey.(*DNSKEY), []RR{a}); err != nil {
398		t.Fatalf("failure to validate:\n%s\n%s\n%s\n\n%s\n\n%v",
399			eckey.(*DNSKEY).String(),
400			a.String(),
401			sig.String(),
402			eckey.(*DNSKEY).PrivateKeyString(privkey),
403			err,
404		)
405	}
406}
407
408func TestSignVerifyECDSA2(t *testing.T) {
409	srv1 := testRR("srv.miek.nl. IN SRV 1000 800 0 web1.miek.nl.")
410	srv := srv1.(*SRV)
411
412	// With this key
413	key := new(DNSKEY)
414	key.Hdr.Rrtype = TypeDNSKEY
415	key.Hdr.Name = "miek.nl."
416	key.Hdr.Class = ClassINET
417	key.Hdr.Ttl = 14400
418	key.Flags = 256
419	key.Protocol = 3
420	key.Algorithm = ECDSAP256SHA256
421	privkey, err := key.Generate(256)
422	if err != nil {
423		t.Fatal("failure to generate key")
424	}
425
426	// Fill in the values of the Sig, before signing
427	sig := new(RRSIG)
428	sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0}
429	sig.TypeCovered = srv.Hdr.Rrtype
430	sig.Labels = uint8(CountLabel(srv.Hdr.Name)) // works for all 3
431	sig.OrigTtl = srv.Hdr.Ttl
432	sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05"
433	sig.Inception = 1293942305  // date -u '+%s' -d"2011-01-02 04:25:05"
434	sig.KeyTag = key.KeyTag()   // Get the keyfrom the Key
435	sig.SignerName = key.Hdr.Name
436	sig.Algorithm = ECDSAP256SHA256
437
438	if sig.Sign(privkey.(*ecdsa.PrivateKey), []RR{srv}) != nil {
439		t.Fatal("failure to sign the record")
440	}
441
442	err = sig.Verify(key, []RR{srv})
443	if err != nil {
444		t.Errorf("failure to validate:\n%s\n%s\n%s\n\n%s\n\n%v",
445			key.String(),
446			srv.String(),
447			sig.String(),
448			key.PrivateKeyString(privkey),
449			err,
450		)
451	}
452}
453
454func TestSignVerifyEd25519(t *testing.T) {
455	srv1, err := NewRR("srv.miek.nl. IN SRV 1000 800 0 web1.miek.nl.")
456	if err != nil {
457		t.Fatal(err)
458	}
459	srv := srv1.(*SRV)
460
461	// With this key
462	key := new(DNSKEY)
463	key.Hdr.Rrtype = TypeDNSKEY
464	key.Hdr.Name = "miek.nl."
465	key.Hdr.Class = ClassINET
466	key.Hdr.Ttl = 14400
467	key.Flags = 256
468	key.Protocol = 3
469	key.Algorithm = ED25519
470	privkey, err := key.Generate(256)
471	if err != nil {
472		t.Fatal("failure to generate key")
473	}
474
475	// Fill in the values of the Sig, before signing
476	sig := new(RRSIG)
477	sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0}
478	sig.TypeCovered = srv.Hdr.Rrtype
479	sig.Labels = uint8(CountLabel(srv.Hdr.Name)) // works for all 3
480	sig.OrigTtl = srv.Hdr.Ttl
481	sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05"
482	sig.Inception = 1293942305  // date -u '+%s' -d"2011-01-02 04:25:05"
483	sig.KeyTag = key.KeyTag()   // Get the keyfrom the Key
484	sig.SignerName = key.Hdr.Name
485	sig.Algorithm = ED25519
486
487	if sig.Sign(privkey.(ed25519.PrivateKey), []RR{srv}) != nil {
488		t.Fatal("failure to sign the record")
489	}
490
491	err = sig.Verify(key, []RR{srv})
492	if err != nil {
493		t.Logf("failure to validate:\n%s\n%s\n%s\n\n%s\n\n%v",
494			key.String(),
495			srv.String(),
496			sig.String(),
497			key.PrivateKeyString(privkey),
498			err,
499		)
500	}
501}
502
503// Here the test vectors from the relevant RFCs are checked.
504// rfc6605 6.1
505func TestRFC6605P256(t *testing.T) {
506	exDNSKEY := `example.net. 3600 IN DNSKEY 257 3 13 (
507                 GojIhhXUN/u4v54ZQqGSnyhWJwaubCvTmeexv7bR6edb
508                 krSqQpF64cYbcB7wNcP+e+MAnLr+Wi9xMWyQLc8NAA== )`
509	exPriv := `Private-key-format: v1.2
510Algorithm: 13 (ECDSAP256SHA256)
511PrivateKey: GU6SnQ/Ou+xC5RumuIUIuJZteXT2z0O/ok1s38Et6mQ=`
512	rrDNSKEY := testRR(exDNSKEY)
513	priv, err := rrDNSKEY.(*DNSKEY).NewPrivateKey(exPriv)
514	if err != nil {
515		t.Fatal(err)
516	}
517
518	exDS := `example.net. 3600 IN DS 55648 13 2 (
519             b4c8c1fe2e7477127b27115656ad6256f424625bf5c1
520             e2770ce6d6e37df61d17 )`
521	rrDS := testRR(exDS)
522	ourDS := rrDNSKEY.(*DNSKEY).ToDS(SHA256)
523	if !reflect.DeepEqual(ourDS, rrDS.(*DS)) {
524		t.Errorf("DS record differs:\n%v\n%v", ourDS, rrDS.(*DS))
525	}
526
527	exA := `www.example.net. 3600 IN A 192.0.2.1`
528	exRRSIG := `www.example.net. 3600 IN RRSIG A 13 3 3600 (
529                20100909100439 20100812100439 55648 example.net.
530                qx6wLYqmh+l9oCKTN6qIc+bw6ya+KJ8oMz0YP107epXA
531                yGmt+3SNruPFKG7tZoLBLlUzGGus7ZwmwWep666VCw== )`
532	rrA := testRR(exA)
533	rrRRSIG := testRR(exRRSIG)
534	if err := rrRRSIG.(*RRSIG).Verify(rrDNSKEY.(*DNSKEY), []RR{rrA}); err != nil {
535		t.Errorf("failure to validate the spec RRSIG: %v", err)
536	}
537
538	ourRRSIG := &RRSIG{
539		Hdr: RR_Header{
540			Ttl: rrA.Header().Ttl,
541		},
542		KeyTag:     rrDNSKEY.(*DNSKEY).KeyTag(),
543		SignerName: rrDNSKEY.(*DNSKEY).Hdr.Name,
544		Algorithm:  rrDNSKEY.(*DNSKEY).Algorithm,
545	}
546	ourRRSIG.Expiration, _ = StringToTime("20100909100439")
547	ourRRSIG.Inception, _ = StringToTime("20100812100439")
548	err = ourRRSIG.Sign(priv.(*ecdsa.PrivateKey), []RR{rrA})
549	if err != nil {
550		t.Fatal(err)
551	}
552
553	if err = ourRRSIG.Verify(rrDNSKEY.(*DNSKEY), []RR{rrA}); err != nil {
554		t.Errorf("failure to validate our RRSIG: %v", err)
555	}
556
557	// Signatures are randomized
558	rrRRSIG.(*RRSIG).Signature = ""
559	ourRRSIG.Signature = ""
560	if !reflect.DeepEqual(ourRRSIG, rrRRSIG.(*RRSIG)) {
561		t.Fatalf("RRSIG record differs:\n%v\n%v", ourRRSIG, rrRRSIG.(*RRSIG))
562	}
563}
564
565// rfc6605 6.2
566func TestRFC6605P384(t *testing.T) {
567	exDNSKEY := `example.net. 3600 IN DNSKEY 257 3 14 (
568                 xKYaNhWdGOfJ+nPrL8/arkwf2EY3MDJ+SErKivBVSum1
569                 w/egsXvSADtNJhyem5RCOpgQ6K8X1DRSEkrbYQ+OB+v8
570                 /uX45NBwY8rp65F6Glur8I/mlVNgF6W/qTI37m40 )`
571	exPriv := `Private-key-format: v1.2
572Algorithm: 14 (ECDSAP384SHA384)
573PrivateKey: WURgWHCcYIYUPWgeLmiPY2DJJk02vgrmTfitxgqcL4vwW7BOrbawVmVe0d9V94SR`
574	rrDNSKEY := testRR(exDNSKEY)
575	priv, err := rrDNSKEY.(*DNSKEY).NewPrivateKey(exPriv)
576	if err != nil {
577		t.Fatal(err)
578	}
579
580	exDS := `example.net. 3600 IN DS 10771 14 4 (
581           72d7b62976ce06438e9c0bf319013cf801f09ecc84b8
582           d7e9495f27e305c6a9b0563a9b5f4d288405c3008a94
583           6df983d6 )`
584	rrDS := testRR(exDS)
585	ourDS := rrDNSKEY.(*DNSKEY).ToDS(SHA384)
586	if !reflect.DeepEqual(ourDS, rrDS.(*DS)) {
587		t.Fatalf("DS record differs:\n%v\n%v", ourDS, rrDS.(*DS))
588	}
589
590	exA := `www.example.net. 3600 IN A 192.0.2.1`
591	exRRSIG := `www.example.net. 3600 IN RRSIG A 14 3 3600 (
592           20100909102025 20100812102025 10771 example.net.
593           /L5hDKIvGDyI1fcARX3z65qrmPsVz73QD1Mr5CEqOiLP
594           95hxQouuroGCeZOvzFaxsT8Glr74hbavRKayJNuydCuz
595           WTSSPdz7wnqXL5bdcJzusdnI0RSMROxxwGipWcJm )`
596	rrA := testRR(exA)
597	rrRRSIG := testRR(exRRSIG)
598	if err != nil {
599		t.Fatal(err)
600	}
601	if err = rrRRSIG.(*RRSIG).Verify(rrDNSKEY.(*DNSKEY), []RR{rrA}); err != nil {
602		t.Errorf("failure to validate the spec RRSIG: %v", err)
603	}
604
605	ourRRSIG := &RRSIG{
606		Hdr: RR_Header{
607			Ttl: rrA.Header().Ttl,
608		},
609		KeyTag:     rrDNSKEY.(*DNSKEY).KeyTag(),
610		SignerName: rrDNSKEY.(*DNSKEY).Hdr.Name,
611		Algorithm:  rrDNSKEY.(*DNSKEY).Algorithm,
612	}
613	ourRRSIG.Expiration, _ = StringToTime("20100909102025")
614	ourRRSIG.Inception, _ = StringToTime("20100812102025")
615	err = ourRRSIG.Sign(priv.(*ecdsa.PrivateKey), []RR{rrA})
616	if err != nil {
617		t.Fatal(err)
618	}
619
620	if err = ourRRSIG.Verify(rrDNSKEY.(*DNSKEY), []RR{rrA}); err != nil {
621		t.Errorf("failure to validate our RRSIG: %v", err)
622	}
623
624	// Signatures are randomized
625	rrRRSIG.(*RRSIG).Signature = ""
626	ourRRSIG.Signature = ""
627	if !reflect.DeepEqual(ourRRSIG, rrRRSIG.(*RRSIG)) {
628		t.Fatalf("RRSIG record differs:\n%v\n%v", ourRRSIG, rrRRSIG.(*RRSIG))
629	}
630}
631
632// rfc8080 6.1
633func TestRFC8080Ed25519Example1(t *testing.T) {
634	exDNSKEY := `example.com. 3600 IN DNSKEY 257 3 15 (
635             l02Woi0iS8Aa25FQkUd9RMzZHJpBoRQwAQEX1SxZJA4= )`
636	exPriv := `Private-key-format: v1.2
637Algorithm: 15 (ED25519)
638PrivateKey: ODIyNjAzODQ2MjgwODAxMjI2NDUxOTAyMDQxNDIyNjI=`
639	rrDNSKEY, err := NewRR(exDNSKEY)
640	if err != nil {
641		t.Fatal(err)
642	}
643	priv, err := rrDNSKEY.(*DNSKEY).NewPrivateKey(exPriv)
644	if err != nil {
645		t.Fatal(err)
646	}
647
648	exDS := `example.com. 3600 IN DS 3613 15 2 (
649             3aa5ab37efce57f737fc1627013fee07bdf241bd10f3b1964ab55c78e79
650             a304b )`
651	rrDS, err := NewRR(exDS)
652	if err != nil {
653		t.Fatal(err)
654	}
655	ourDS := rrDNSKEY.(*DNSKEY).ToDS(SHA256)
656	if !reflect.DeepEqual(ourDS, rrDS.(*DS)) {
657		t.Fatalf("DS record differs:\n%v\n%v", ourDS, rrDS.(*DS))
658	}
659
660	exMX := `example.com. 3600 IN MX 10 mail.example.com.`
661	exRRSIG := `example.com. 3600 IN RRSIG MX 15 2 3600 (
662             1440021600 1438207200 3613 example.com. (
663             oL9krJun7xfBOIWcGHi7mag5/hdZrKWw15jPGrHpjQeRAvTdszaPD+QLs3f
664             x8A4M3e23mRZ9VrbpMngwcrqNAg== ) )`
665	rrMX, err := NewRR(exMX)
666	if err != nil {
667		t.Fatal(err)
668	}
669	rrRRSIG, err := NewRR(exRRSIG)
670	if err != nil {
671		t.Fatal(err)
672	}
673	if err = rrRRSIG.(*RRSIG).Verify(rrDNSKEY.(*DNSKEY), []RR{rrMX}); err != nil {
674		t.Errorf("failure to validate the spec RRSIG: %v", err)
675	}
676
677	ourRRSIG := &RRSIG{
678		Hdr: RR_Header{
679			Ttl: rrMX.Header().Ttl,
680		},
681		KeyTag:     rrDNSKEY.(*DNSKEY).KeyTag(),
682		SignerName: rrDNSKEY.(*DNSKEY).Hdr.Name,
683		Algorithm:  rrDNSKEY.(*DNSKEY).Algorithm,
684	}
685	ourRRSIG.Expiration, _ = StringToTime("20150819220000")
686	ourRRSIG.Inception, _ = StringToTime("20150729220000")
687	err = ourRRSIG.Sign(priv.(ed25519.PrivateKey), []RR{rrMX})
688	if err != nil {
689		t.Fatal(err)
690	}
691
692	if err = ourRRSIG.Verify(rrDNSKEY.(*DNSKEY), []RR{rrMX}); err != nil {
693		t.Errorf("failure to validate our RRSIG: %v", err)
694	}
695
696	if !reflect.DeepEqual(ourRRSIG, rrRRSIG.(*RRSIG)) {
697		t.Fatalf("RRSIG record differs:\n%v\n%v", ourRRSIG, rrRRSIG.(*RRSIG))
698	}
699}
700
701// rfc8080 6.1
702func TestRFC8080Ed25519Example2(t *testing.T) {
703	exDNSKEY := `example.com. 3600 IN DNSKEY 257 3 15 (
704             zPnZ/QwEe7S8C5SPz2OfS5RR40ATk2/rYnE9xHIEijs= )`
705	exPriv := `Private-key-format: v1.2
706Algorithm: 15 (ED25519)
707PrivateKey: DSSF3o0s0f+ElWzj9E/Osxw8hLpk55chkmx0LYN5WiY=`
708	rrDNSKEY, err := NewRR(exDNSKEY)
709	if err != nil {
710		t.Fatal(err)
711	}
712	priv, err := rrDNSKEY.(*DNSKEY).NewPrivateKey(exPriv)
713	if err != nil {
714		t.Fatal(err)
715	}
716
717	exDS := `example.com. 3600 IN DS 35217 15 2 (
718             401781b934e392de492ec77ae2e15d70f6575a1c0bc59c5275c04ebe80c
719             6614c )`
720	rrDS, err := NewRR(exDS)
721	if err != nil {
722		t.Fatal(err)
723	}
724	ourDS := rrDNSKEY.(*DNSKEY).ToDS(SHA256)
725	if !reflect.DeepEqual(ourDS, rrDS.(*DS)) {
726		t.Fatalf("DS record differs:\n%v\n%v", ourDS, rrDS.(*DS))
727	}
728
729	exMX := `example.com. 3600 IN MX 10 mail.example.com.`
730	exRRSIG := `example.com. 3600 IN RRSIG MX 15 2 3600 (
731             1440021600 1438207200 35217 example.com. (
732             zXQ0bkYgQTEFyfLyi9QoiY6D8ZdYo4wyUhVioYZXFdT410QPRITQSqJSnzQ
733             oSm5poJ7gD7AQR0O7KuI5k2pcBg== ) )`
734	rrMX, err := NewRR(exMX)
735	if err != nil {
736		t.Fatal(err)
737	}
738	rrRRSIG, err := NewRR(exRRSIG)
739	if err != nil {
740		t.Fatal(err)
741	}
742	if err = rrRRSIG.(*RRSIG).Verify(rrDNSKEY.(*DNSKEY), []RR{rrMX}); err != nil {
743		t.Errorf("failure to validate the spec RRSIG: %v", err)
744	}
745
746	ourRRSIG := &RRSIG{
747		Hdr: RR_Header{
748			Ttl: rrMX.Header().Ttl,
749		},
750		KeyTag:     rrDNSKEY.(*DNSKEY).KeyTag(),
751		SignerName: rrDNSKEY.(*DNSKEY).Hdr.Name,
752		Algorithm:  rrDNSKEY.(*DNSKEY).Algorithm,
753	}
754	ourRRSIG.Expiration, _ = StringToTime("20150819220000")
755	ourRRSIG.Inception, _ = StringToTime("20150729220000")
756	err = ourRRSIG.Sign(priv.(ed25519.PrivateKey), []RR{rrMX})
757	if err != nil {
758		t.Fatal(err)
759	}
760
761	if err = ourRRSIG.Verify(rrDNSKEY.(*DNSKEY), []RR{rrMX}); err != nil {
762		t.Errorf("failure to validate our RRSIG: %v", err)
763	}
764
765	if !reflect.DeepEqual(ourRRSIG, rrRRSIG.(*RRSIG)) {
766		t.Fatalf("RRSIG record differs:\n%v\n%v", ourRRSIG, rrRRSIG.(*RRSIG))
767	}
768}
769
770func TestInvalidRRSet(t *testing.T) {
771	goodRecords := make([]RR, 2)
772	goodRecords[0] = &TXT{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello world"}}
773	goodRecords[1] = &TXT{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"_o/"}}
774
775	// Generate key
776	keyname := "cloudflare.com."
777	key := &DNSKEY{
778		Hdr:       RR_Header{Name: keyname, Rrtype: TypeDNSKEY, Class: ClassINET, Ttl: 0},
779		Algorithm: ECDSAP256SHA256,
780		Flags:     ZONE,
781		Protocol:  3,
782	}
783	privatekey, err := key.Generate(256)
784	if err != nil {
785		t.Fatal(err.Error())
786	}
787
788	// Need to fill in: Inception, Expiration, KeyTag, SignerName and Algorithm
789	curTime := time.Now()
790	signature := &RRSIG{
791		Inception:  uint32(curTime.Unix()),
792		Expiration: uint32(curTime.Add(time.Hour).Unix()),
793		KeyTag:     key.KeyTag(),
794		SignerName: keyname,
795		Algorithm:  ECDSAP256SHA256,
796	}
797
798	// Inconsistent name between records
799	badRecords := make([]RR, 2)
800	badRecords[0] = &TXT{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello world"}}
801	badRecords[1] = &TXT{Hdr: RR_Header{Name: "nama.cloudflare.com.", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"_o/"}}
802
803	if IsRRset(badRecords) {
804		t.Fatal("Record set with inconsistent names considered valid")
805	}
806
807	badRecords[0] = &TXT{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello world"}}
808	badRecords[1] = &A{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeA, Class: ClassINET, Ttl: 0}}
809
810	if IsRRset(badRecords) {
811		t.Fatal("Record set with inconsistent record types considered valid")
812	}
813
814	badRecords[0] = &TXT{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello world"}}
815	badRecords[1] = &TXT{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeTXT, Class: ClassCHAOS, Ttl: 0}, Txt: []string{"_o/"}}
816
817	if IsRRset(badRecords) {
818		t.Fatal("Record set with inconsistent record class considered valid")
819	}
820
821	// Sign the good record set and then make sure verification fails on the bad record set
822	if err := signature.Sign(privatekey.(crypto.Signer), goodRecords); err != nil {
823		t.Fatal("Signing good records failed")
824	}
825
826	if err := signature.Verify(key, badRecords); err != ErrRRset {
827		t.Fatal("Verification did not return ErrRRset with inconsistent records")
828	}
829}
830
831// Issue #688 - RSA exponent unpacked in reverse
832func TestRsaExponentUnpack(t *testing.T) {
833	zskRrDnskey, _ := NewRR("isc.org.                7200    IN      DNSKEY  256 3 5 AwEAAcdkaRUlsRD4gcF63PpPJJ1E6kOIb3yn/UHptVsPEQtEbgJ2y20O eix4unpwoQkz+bIAd2rrOU/95wgV530x0/qqKwBLWoGkxdcnNcvVT4hl 3SOTZy1VjwkAfyayHPU8VisXqJGbB3KWevBZlb6AtrXzFu8AHuBeeAAe /fOgreCh")
834	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")
835	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==")
836	zskRrRrsig, _ := NewRR("isc.org.                7200    IN      RRSIG   DNSKEY 5 2 7200 20180627230244 20180528230244 19923 isc.org. RgCfzUeq4RJPGoe9RRB6cWf6d/Du+tHK5SxI5QL1waA3O5qVtQKFkY1C dq/yyVjwzfjD9F62TObujOaktv8X80ZMcNPmgHbvK1xOqelMBWv5hxj3 xRe+QQObLZ5NPfHFsphQKXvwgO5Sjk8py2B2iCr3BHCZ8S38oIfuSrQx sn8=")
837
838	zsk, ksk := zskRrDnskey.(*DNSKEY), kskRrDnskey.(*DNSKEY)
839	zskSig, kskSig := zskRrRrsig.(*RRSIG), kskRrRrsig.(*RRSIG)
840
841	if e := zskSig.Verify(zsk, []RR{zsk, ksk}); e != nil {
842		t.Fatalf("cannot verify RRSIG with keytag [%d]. Cause [%s]", zsk.KeyTag(), e.Error())
843	}
844
845	if e := kskSig.Verify(ksk, []RR{zsk, ksk}); e != nil {
846		t.Fatalf("cannot verify RRSIG with keytag [%d]. Cause [%s]", ksk.KeyTag(), e.Error())
847	}
848}
849
850func TestParseKeyReadError(t *testing.T) {
851	m, err := parseKey(errReader{}, "")
852	if err == nil || !strings.Contains(err.Error(), errTestReadError.Error()) {
853		t.Errorf("expected error to contain %q, but got %v", errTestReadError, err)
854	}
855	if m != nil {
856		t.Errorf("expected a nil map, but got %v", m)
857	}
858}
859