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