1 package verify
2
3 import (
4 "crypto"
5 "crypto/ecdsa"
6 "crypto/elliptic"
7 "crypto/rand"
8 "crypto/sha256"
9 "encoding/json"
10 "errors"
11 "testing"
12 "time"
13
14 "github.com/theupdateframework/go-tuf/data"
15 "github.com/theupdateframework/go-tuf/pkg/keys"
16 "github.com/theupdateframework/go-tuf/sign"
17 "golang.org/x/crypto/ed25519"
18
19 . "gopkg.in/check.v1"
20 )
21
22
23 func Test(t *testing.T) { TestingT(t) }
24
25 type VerifySuite struct{}
26
27 var _ = Suite(&VerifySuite{})
28
29 type ecdsaSigner struct {
30 *ecdsa.PrivateKey
31 }
32
33 type ecdsaPublic struct {
34 PublicKey *keys.PKIXPublicKey `json:"public"`
35 }
36
37 func (s ecdsaSigner) PublicData() *data.PublicKey {
38 keyValBytes, _ := json.Marshal(ecdsaPublic{PublicKey: &keys.PKIXPublicKey{PublicKey: s.Public()}})
39 return &data.PublicKey{
40 Type: data.KeyTypeECDSA_SHA2_P256,
41 Scheme: data.KeySchemeECDSA_SHA2_P256,
42 Algorithms: data.HashAlgorithms,
43 Value: keyValBytes,
44 }
45 }
46
47 func (s ecdsaSigner) SignMessage(message []byte) ([]byte, error) {
48 hash := sha256.Sum256(message)
49 return s.PrivateKey.Sign(rand.Reader, hash[:], crypto.SHA256)
50 }
51
52 func (s ecdsaSigner) ContainsID(id string) bool {
53 return s.PublicData().ContainsID(id)
54 }
55
56 func (ecdsaSigner) MarshalPrivateKey() (*data.PrivateKey, error) {
57 return nil, errors.New("not implemented for test")
58 }
59
60 func (ecdsaSigner) UnmarshalPrivateKey(key *data.PrivateKey) error {
61 return errors.New("not implemented for test")
62 }
63
64 func (VerifySuite) Test(c *C) {
65 type test struct {
66 name string
67 keys []*data.PublicKey
68 roles map[string]*data.Role
69 s *data.Signed
70 ver int64
71 exp *time.Time
72 typ string
73 role string
74 err error
75 mut func(*test)
76 }
77
78 expiredTime := time.Now().Add(-time.Hour)
79 minVer := int64(10)
80 tests := []test{
81 {
82 name: "no signatures",
83 mut: func(t *test) { t.s.Signatures = []data.Signature{} },
84 err: ErrNoSignatures,
85 },
86 {
87 name: "unknown role",
88 role: "foo",
89 err: ErrUnknownRole{"foo"},
90 },
91 {
92
93
94
95 name: "signature wrong length",
96 mut: func(t *test) { t.s.Signatures[0].Signature = []byte{0} },
97 err: ErrRoleThreshold{1, 0},
98 },
99 {
100 name: "key missing from role",
101 mut: func(t *test) { t.roles["root"].KeyIDs = nil },
102 err: ErrRoleThreshold{1, 0},
103 },
104 {
105 name: "invalid signature",
106 mut: func(t *test) { t.s.Signatures[0].Signature = make([]byte, ed25519.SignatureSize) },
107 err: ErrRoleThreshold{1, 0},
108 },
109 {
110 name: "enough signatures with extra invalid signature",
111 mut: func(t *test) {
112 t.s.Signatures = append(t.s.Signatures, data.Signature{
113 KeyID: t.s.Signatures[0].KeyID,
114 Signature: make([]byte, ed25519.SignatureSize)})
115 },
116 },
117 {
118 name: "not enough signatures",
119 mut: func(t *test) { t.roles["root"].Threshold = 2 },
120 err: ErrRoleThreshold{2, 1},
121 },
122 {
123 name: "exactly enough signatures",
124 },
125 {
126 name: "more than enough signatures",
127 mut: func(t *test) {
128 k, _ := keys.GenerateEd25519Key()
129 sign.Sign(t.s, k)
130 t.keys = append(t.keys, k.PublicData())
131 t.roles["root"].KeyIDs = append(t.roles["root"].KeyIDs, k.PublicData().IDs()...)
132 },
133 },
134 {
135 name: "duplicate key id",
136 mut: func(t *test) {
137 t.roles["root"].Threshold = 2
138 t.s.Signatures = append(t.s.Signatures, t.s.Signatures[0])
139 },
140 err: ErrRoleThreshold{2, 1},
141 },
142 {
143 name: "unknown key",
144 mut: func(t *test) {
145 k, _ := keys.GenerateEd25519Key()
146 sign.Sign(t.s, k)
147 },
148 },
149 {
150 name: "unknown key below threshold",
151 mut: func(t *test) {
152 k, _ := keys.GenerateEd25519Key()
153 sign.Sign(t.s, k)
154 t.roles["root"].Threshold = 2
155 },
156 err: ErrRoleThreshold{2, 1},
157 },
158 {
159 name: "unknown keys in db",
160 mut: func(t *test) {
161 k, _ := keys.GenerateEd25519Key()
162 sign.Sign(t.s, k)
163 t.keys = append(t.keys, k.PublicData())
164 },
165 },
166 {
167 name: "unknown keys in db below threshold",
168 mut: func(t *test) {
169 k, _ := keys.GenerateEd25519Key()
170 sign.Sign(t.s, k)
171 t.keys = append(t.keys, k.PublicData())
172 t.roles["root"].Threshold = 2
173 },
174 err: ErrRoleThreshold{2, 1},
175 },
176 {
177 name: "wrong type",
178 typ: "bar",
179 err: ErrWrongMetaType,
180 },
181 {
182 name: "low version",
183 ver: minVer - 1,
184 err: ErrLowVersion{minVer - 1, minVer},
185 },
186 {
187 name: "expired",
188 exp: &expiredTime,
189 err: ErrExpired{expiredTime},
190 },
191 {
192 name: "valid ecdsa signature",
193 mut: func(t *test) {
194 k, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
195 s := ecdsaSigner{k}
196 sign.Sign(t.s, s)
197 t.s.Signatures = t.s.Signatures[1:]
198 t.keys = []*data.PublicKey{s.PublicData()}
199 t.roles["root"].KeyIDs = s.PublicData().IDs()
200 },
201 },
202 {
203
204 name: "invalid second ecdsa signature",
205 mut: func(t *test) {
206 k, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
207 s := ecdsaSigner{k}
208 sign.Sign(t.s, s)
209 t.s.Signatures[1].Signature[0]++
210 t.keys = append(t.keys, s.PublicData())
211 t.roles["root"].KeyIDs = append(t.roles["root"].KeyIDs, s.PublicData().IDs()...)
212 },
213 },
214 }
215 for _, t := range tests {
216 if t.role == "" {
217 t.role = "root"
218 }
219 if t.ver == 0 {
220 t.ver = minVer
221 }
222 if t.exp == nil {
223 expires := time.Now().Add(time.Hour)
224 t.exp = &expires
225 }
226 if t.typ == "" {
227 t.typ = t.role
228 }
229 if t.keys == nil && t.s == nil {
230 k, _ := keys.GenerateEd25519Key()
231 t.s, _ = sign.Marshal(&signedMeta{Type: t.typ, Version: t.ver, Expires: *t.exp}, k)
232 t.keys = []*data.PublicKey{k.PublicData()}
233 }
234 if t.roles == nil {
235 t.roles = map[string]*data.Role{
236 "root": {
237 KeyIDs: t.keys[0].IDs(),
238 Threshold: 1,
239 },
240 }
241 }
242 if t.mut != nil {
243 t.mut(&t)
244 }
245
246 db := NewDB()
247 for _, k := range t.keys {
248 for _, id := range k.IDs() {
249 err := db.AddKey(id, k)
250 c.Assert(err, IsNil)
251 }
252 }
253 for n, r := range t.roles {
254 err := db.AddRole(n, r)
255 c.Assert(err, IsNil)
256 }
257
258 err := db.Verify(t.s, t.role, minVer)
259 if e, ok := t.err.(ErrExpired); ok {
260 assertErrExpired(c, err, e)
261 } else {
262 c.Assert(err, DeepEquals, t.err, Commentf("name = %s", t.name))
263 }
264 }
265 }
266
267 func (VerifySuite) TestVerifyIgnoreExpired(c *C) {
268 minVer := int64(10)
269 role := "root"
270 k, _ := keys.GenerateEd25519Key()
271 s, _ := sign.Marshal(&signedMeta{Type: role, Version: minVer, Expires: time.Now().Add(-time.Hour)}, k)
272 keys := []*data.PublicKey{k.PublicData()}
273 roles := map[string]*data.Role{
274 "root": {
275 KeyIDs: keys[0].IDs(),
276 Threshold: 1,
277 },
278 }
279
280 db := NewDB()
281 for _, k := range keys {
282 for _, id := range k.IDs() {
283 err := db.AddKey(id, k)
284 c.Assert(err, IsNil)
285 }
286 }
287 for n, r := range roles {
288 err := db.AddRole(n, r)
289 c.Assert(err, IsNil)
290 }
291
292 err := db.VerifyIgnoreExpiredCheck(s, role, minVer)
293 c.Assert(err, IsNil)
294 }
295
296 func assertErrExpired(c *C, err error, expected ErrExpired) {
297 actual, ok := err.(ErrExpired)
298 if !ok {
299 c.Fatalf("expected err to have type ErrExpired, got %T", err)
300 }
301 c.Assert(actual.Expired.Unix(), Equals, expected.Expired.Unix())
302 }
303
View as plain text