1package dns
2
3import (
4	"crypto"
5	"testing"
6	"time"
7)
8
9func TestSIG0(t *testing.T) {
10	if testing.Short() {
11		t.Skip("skipping test in short mode.")
12	}
13	m := new(Msg)
14	m.SetQuestion("example.org.", TypeSOA)
15	for _, alg := range []uint8{ECDSAP256SHA256, ECDSAP384SHA384, RSASHA1, RSASHA256, RSASHA512} {
16		algstr := AlgorithmToString[alg]
17		keyrr := new(KEY)
18		keyrr.Hdr.Name = algstr + "."
19		keyrr.Hdr.Rrtype = TypeKEY
20		keyrr.Hdr.Class = ClassINET
21		keyrr.Algorithm = alg
22		keysize := 512
23		switch alg {
24		case ECDSAP256SHA256:
25			keysize = 256
26		case ECDSAP384SHA384:
27			keysize = 384
28		case RSASHA512:
29			keysize = 1024
30		}
31		pk, err := keyrr.Generate(keysize)
32		if err != nil {
33			t.Errorf("failed to generate key for “%s”: %v", algstr, err)
34			continue
35		}
36		now := uint32(time.Now().Unix())
37		sigrr := new(SIG)
38		sigrr.Hdr.Name = "."
39		sigrr.Hdr.Rrtype = TypeSIG
40		sigrr.Hdr.Class = ClassANY
41		sigrr.Algorithm = alg
42		sigrr.Expiration = now + 300
43		sigrr.Inception = now - 300
44		sigrr.KeyTag = keyrr.KeyTag()
45		sigrr.SignerName = keyrr.Hdr.Name
46		mb, err := sigrr.Sign(pk.(crypto.Signer), m)
47		if err != nil {
48			t.Errorf("failed to sign message using “%s”: %v", algstr, err)
49			continue
50		}
51		m := new(Msg)
52		if err := m.Unpack(mb); err != nil {
53			t.Errorf("failed to unpack message signed using “%s”: %v", algstr, err)
54			continue
55		}
56		if len(m.Extra) != 1 {
57			t.Errorf("missing SIG for message signed using “%s”", algstr)
58			continue
59		}
60		var sigrrwire *SIG
61		switch rr := m.Extra[0].(type) {
62		case *SIG:
63			sigrrwire = rr
64		default:
65			t.Errorf("expected SIG RR, instead: %v", rr)
66			continue
67		}
68		for _, rr := range []*SIG{sigrr, sigrrwire} {
69			id := "sigrr"
70			if rr == sigrrwire {
71				id = "sigrrwire"
72			}
73			if err := rr.Verify(keyrr, mb); err != nil {
74				t.Errorf("failed to verify “%s” signed SIG(%s): %v", algstr, id, err)
75				continue
76			}
77		}
78		mb[13]++
79		if err := sigrr.Verify(keyrr, mb); err == nil {
80			t.Errorf("verify succeeded on an altered message using “%s”", algstr)
81			continue
82		}
83		sigrr.Expiration = 2
84		sigrr.Inception = 1
85		mb, _ = sigrr.Sign(pk.(crypto.Signer), m)
86		if err := sigrr.Verify(keyrr, mb); err == nil {
87			t.Errorf("verify succeeded on an expired message using “%s”", algstr)
88			continue
89		}
90	}
91}
92