summaryrefslogtreecommitdiffstats
path: root/verify/db_test.go
blob: 01d7a308171f05da27565e373cd1dabe4865875d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package verify

import (
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/theupdateframework/go-tuf/data"
	"github.com/theupdateframework/go-tuf/pkg/keys"
)

func TestDelegationsDB(t *testing.T) {
	key, err := keys.GenerateEd25519Key()
	assert.Nil(t, err, "generating key failed")
	var dbTests = []struct {
		testName     string
		delegations  *data.Delegations
		initErr      error
		unmarshalErr error
	}{
		{
			testName:     "empty state",
			delegations:  &data.Delegations{},
			unmarshalErr: ErrNoSignatures,
		},
		{
			testName: "top level role",
			delegations: &data.Delegations{Roles: []data.DelegatedRole{
				{Name: "root"},
			}},
			initErr: ErrInvalidDelegatedRole,
		},
		{
			testName: "invalid role",
			delegations: &data.Delegations{Roles: []data.DelegatedRole{
				{Threshold: 0},
			}},
			initErr: ErrInvalidThreshold,
		},
		{
			testName: "standard (SHA256) key IDs supported",
			delegations: &data.Delegations{
				Keys: map[string]*data.PublicKey{
					key.PublicData().IDs()[0]: key.PublicData(),
				},
				Roles: []data.DelegatedRole{{
					Name:      "rolename",
					KeyIDs:    key.PublicData().IDs(),
					Threshold: 1,
				},
				},
			},
			// If we get to ErrNoSignatures, we've passed key loading; see
			// delegations_test.go to see tests that delegation DB *fully* works
			// with valid signatures set up.
			unmarshalErr: ErrNoSignatures,
		},
		{
			testName: "arbitrary (non-SHA256, per TAP-12) key IDs supported",
			delegations: &data.Delegations{
				Keys: map[string]*data.PublicKey{
					"a": key.PublicData(),
				},
				Roles: []data.DelegatedRole{{
					Name:      "rolename",
					KeyIDs:    []string{"a"},
					Threshold: 1,
				},
				},
			},
			// If we get to ErrNoSignatures, we've passed key loading; see
			// delegations_test.go to see tests that delegation DB *fully* works
			// with valid signatures set up.
			unmarshalErr: ErrNoSignatures,
		},
	}

	for _, tt := range dbTests {
		t.Run(tt.testName, func(t *testing.T) {
			db, err := NewDBFromDelegations(tt.delegations)
			assert.Equal(t, tt.initErr, err)
			if err == nil {
				assert.NotNil(t, db)
				var targets data.Targets
				err = db.Unmarshal([]byte(`{"a":"b"}`), targets, "tree", 0)
				assert.Equal(t, tt.unmarshalErr, err)
			}
		})
	}
}

// Test key database for compliance with TAP-12.
//
// Previously, every key's key ID was the SHA256 of the public key. TAP-12
// allows arbitrary key IDs, with no loss in security.
//
// TAP-12: https://github.com/theupdateframework/taps/blob/master/tap12.md
func TestTAP12(t *testing.T) {
	db := NewDB()
	// Need to use a signer type that supports random signatures.
	key1, _ := keys.GenerateRsaKey()
	key2, _ := keys.GenerateRsaKey()
	msg := []byte("{}")
	sig1, _ := key1.SignMessage(msg)
	sig1Duplicate, _ := key1.SignMessage(msg)
	assert.NotEqual(t, sig1, sig1Duplicate, "Signatures should be random")
	sig2, _ := key2.SignMessage(msg)

	// Idempotent: adding the same key with the same ID is okay.
	assert.Nil(t, db.AddKey("key1", key1.PublicData()), "initial add")
	assert.Nil(t, db.AddKey("key1", key1.PublicData()), "re-add")
	// Adding a different key is allowed, unless the key ID is the same.
	assert.Nil(t, db.AddKey("key2", key2.PublicData()), "different key with different ID")
	assert.ErrorIs(t, db.AddKey("key1", key2.PublicData()), ErrRepeatID{"key1"}, "different key with same key ID")
	assert.Nil(t, db.AddKey("key1-duplicate", key1.PublicData()), "same key with different ID should succeed")
	assert.Nil(t, db.AddRole("diffkeys", &data.Role{
		KeyIDs:    []string{"key1", "key2"},
		Threshold: 2,
	}), "adding role")
	assert.Nil(t, db.AddRole("samekeys", &data.Role{
		KeyIDs:    []string{"key1", "key1-alt"},
		Threshold: 2,
	}), "adding role")
	assert.Nil(t, db.VerifySignatures(&data.Signed{
		Signed:     msg,
		Signatures: []data.Signature{{KeyID: "key1", Signature: sig1}, {KeyID: "key2", Signature: sig2}},
	}, "diffkeys"), "Signature with different keys: ")
	assert.ErrorIs(t, db.VerifySignatures(&data.Signed{
		Signed:     msg,
		Signatures: []data.Signature{{KeyID: "key1", Signature: sig1}, {KeyID: "key1-alt", Signature: sig1Duplicate}},
	}, "samekeys"), ErrRoleThreshold{2, 1}, "Threshold signing with repeat key")
}