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