1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package tuf
17
18 import (
19 "bytes"
20 "crypto/ecdsa"
21 "crypto/x509"
22 "io"
23 "os"
24 "reflect"
25 "testing"
26 "time"
27
28 "github.com/sigstore/sigstore/pkg/cryptoutils"
29 _ "github.com/theupdateframework/go-tuf/pkg/deprecated/set_ecdsa"
30 "github.com/theupdateframework/go-tuf/verify"
31 )
32
33 func patchIsExpired() func() {
34
35 old := verify.IsExpired
36 verify.IsExpired = func(_ time.Time) bool {
37 return false
38 }
39 return func() {
40 verify.IsExpired = old
41 }
42 }
43
44 func TestReadPublicKey(t *testing.T) {
45
46 type test struct {
47 caseDesc string
48 inputFile string
49 errorFound bool
50 specVersion string
51 }
52
53 tests := []test{
54 {caseDesc: "Unsigned root manifest", inputFile: "testdata/unsigned_root.json", errorFound: true},
55 {caseDesc: "Invalid TUF root.json (invalid type)", inputFile: "testdata/timestamp.json", errorFound: true, specVersion: "1.0"},
56 {caseDesc: "Valid TUF root.json", inputFile: "testdata/1.root.json", errorFound: false, specVersion: "1.0"},
57 }
58
59
60 defer patchIsExpired()()
61
62 for _, tc := range tests {
63 file, err := os.Open(tc.inputFile)
64 if err != nil {
65 t.Errorf("%v: cannot open %v", tc.caseDesc, tc.inputFile)
66 }
67
68 got, err := NewPublicKey(file)
69 if ((got != nil) == tc.errorFound) || ((err != nil) != tc.errorFound) {
70 t.Errorf("%v: unexpected result testing %v: %v", tc.caseDesc, tc.inputFile, err)
71 }
72
73 if !tc.errorFound {
74 specVersion, err := got.SpecVersion()
75 if err != nil {
76 t.Errorf("%v: unexpected result testing %v: %v", tc.caseDesc, tc.inputFile, err)
77 }
78 if specVersion != tc.specVersion {
79 t.Errorf("%v: unexpected spec version expected %v, got %v", tc.caseDesc, tc.specVersion, specVersion)
80 }
81
82 identities, err := got.Identities()
83 if err != nil {
84 t.Errorf("%v: error getting identities for %v: %v", tc.caseDesc, tc.inputFile, err)
85 }
86 if len(identities) != 7 {
87 t.Errorf("%v: expected 7 identities, got: %d", tc.caseDesc, len(identities))
88 }
89 for _, i := range identities {
90 if _, ok := i.Crypto.(*ecdsa.PublicKey); !ok {
91 t.Errorf("%v: key was not of type *ecdsa.PublicKey: %v", tc.caseDesc, reflect.TypeOf(i.Crypto))
92 }
93 key, err := x509.ParsePKIXPublicKey(i.Raw)
94 if err != nil {
95 t.Fatalf("%v: Raw is not in PKIX format: %v", tc.caseDesc, err)
96 }
97 if err := cryptoutils.EqualKeys(key, i.Crypto); err != nil {
98 t.Errorf("%v: raw key and crypto key not equal: %v", tc.caseDesc, err)
99 }
100 if len(i.Fingerprint) != 64 {
101 t.Errorf("%v: fingerprint is not expected length of 64 (hex 32-byte sha256): %d", tc.caseDesc, len(i.Fingerprint))
102 }
103 }
104 }
105 }
106 }
107
108 func TestReadSignature(t *testing.T) {
109
110 type test struct {
111 caseDesc string
112 inputFile string
113 errorFound bool
114 }
115
116 tests := []test{
117 {caseDesc: "Not a valid TUF manifest", inputFile: "testdata/bogus.json", errorFound: true},
118 {caseDesc: "Valid root.json manifest", inputFile: "testdata/timestamp.json", errorFound: false},
119 {caseDesc: "Valid timestamp.json manifest", inputFile: "testdata/1.root.json", errorFound: false},
120 {caseDesc: "Valid unsigned root.json manifest", inputFile: "testdata/unsigned_root.json", errorFound: false},
121 }
122
123 for _, tc := range tests {
124 file, err := os.Open(tc.inputFile)
125 if err != nil {
126 t.Errorf("%v: cannot open %v", tc.caseDesc, tc.inputFile)
127 }
128 if got, err := NewSignature(file); ((got != nil) == tc.errorFound) || ((err != nil) != tc.errorFound) {
129 t.Errorf("%v: unexpected result testing %v: %v", tc.caseDesc, tc.inputFile, got)
130 }
131 }
132
133 }
134
135 func TestCanonicalValue(t *testing.T) {
136
137 type test struct {
138 caseDesc string
139 input string
140 output string
141 match bool
142 }
143
144 var k PublicKey
145 if _, err := k.CanonicalValue(); err == nil {
146 t.Errorf("CanonicalValue did not error out for uninitialized key")
147 }
148
149
150 defer patchIsExpired()()
151
152 tests := []test{
153 {caseDesc: "root", input: "testdata/1.root.json", output: "testdata/reformat.1.root.json", match: true},
154 }
155
156 for _, tc := range tests {
157 var inputFile, outputFile io.Reader
158 var err error
159 inputFile, err = os.Open(tc.input)
160 if err != nil {
161 t.Errorf("%v: cannot open %v", tc.caseDesc, tc.input)
162 }
163
164 inputKey, err := NewPublicKey(inputFile)
165 if err != nil {
166 t.Errorf("%v: Error reading input for TestCanonicalValue: %v", tc.caseDesc, err)
167 }
168
169 cvInput, err := inputKey.CanonicalValue()
170 if err != nil {
171 t.Errorf("%v: Error canonicalizing public key '%v': %v", tc.caseDesc, tc.input, err)
172 }
173
174 outputFile, err = os.Open(tc.output)
175 if err != nil {
176 t.Errorf("%v: cannot open %v", tc.caseDesc, tc.output)
177 }
178
179 outputKey, err := NewPublicKey(outputFile)
180 if err != nil {
181 t.Fatalf("%v: Error reading input for TestCanonicalValue: %v", tc.caseDesc, err)
182 }
183
184 cvOutput, err := outputKey.CanonicalValue()
185 if err != nil {
186 t.Fatalf("%v: Error canonicalizing public key '%v': %v", tc.caseDesc, tc.input, err)
187 }
188
189 if bytes.Equal(cvInput, cvOutput) != tc.match {
190 t.Errorf("%v: %v equality of canonical values of %v and %v was expected but not generated", tc.caseDesc, tc.match, tc.input, tc.output)
191 }
192 }
193 }
194
195 func TestVerifySignature(t *testing.T) {
196 type test struct {
197 caseDesc string
198 sigFile string
199 keyFile string
200 verified bool
201 }
202
203 tests := []test{
204 {caseDesc: "Valid root.json, valid signed timestamp.json", keyFile: "testdata/1.root.json", sigFile: "testdata/timestamp.json", verified: true},
205 {caseDesc: "Valid root.json, valid signed root.json", keyFile: "testdata/1.root.json", sigFile: "testdata/1.root.json", verified: true},
206 {caseDesc: "Valid root.json, mismatched timestamp.json", keyFile: "testdata/other_root.json", sigFile: "testdata/timestamp.json", verified: false},
207 {caseDesc: "Valid root.json, unsigned root.json", keyFile: "testdata/1.root.json", sigFile: "testdata/unsigned_root.json", verified: false},
208 }
209
210 defer patchIsExpired()()
211
212 for _, tc := range tests {
213 keyFile, err := os.Open(tc.keyFile)
214 if err != nil {
215 t.Errorf("%v: error reading keyfile '%v': %v", tc.caseDesc, tc.keyFile, err)
216 }
217 k, err := NewPublicKey(keyFile)
218 if err != nil {
219 t.Errorf("%v: error reading keyfile '%v': %v", tc.caseDesc, tc.keyFile, err)
220 }
221
222 sigFile, err := os.Open(tc.sigFile)
223 if err != nil {
224 t.Errorf("%v: error reading sigfile '%v': %v", tc.caseDesc, tc.sigFile, err)
225 }
226 s, err := NewSignature(sigFile)
227 if err != nil {
228 t.Errorf("%v: error reading sigfile '%v': %v", tc.caseDesc, tc.sigFile, err)
229 }
230
231 if err := s.Verify(nil, k); (err == nil) != tc.verified {
232 t.Errorf("%v: unexpected result in verifying sigature: %v", tc.caseDesc, err)
233 }
234 }
235
236 emptyKey := PublicKey{}
237 emptySig := Signature{}
238
239 if err := emptySig.Verify(nil, emptyKey); err == nil {
240 t.Errorf("expected error when using empty sig to verify")
241 }
242
243 sigFile, _ := os.Open("testdata/timestamp.json")
244 validSig, _ := NewSignature(sigFile)
245
246 if err := validSig.Verify(bytes.NewReader([]byte("irrelevant")), &emptyKey); err == nil {
247 t.Errorf("expected error when using empty key to verify")
248 }
249 }
250
View as plain text