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
132
133
134
135
136
137
138
139
140
|
package eduvpn
import (
"bufio"
"errors"
"fmt"
"io/ioutil"
"os"
"testing"
)
func Test_verifyWithKeys(t *testing.T) {
var err error
var pk []string
{
file, err := os.Open("test_data/public.key")
if err != nil {
panic(err)
}
defer file.Close()
// Get last line (key string) from file
scanner := bufio.NewScanner(file)
for i := 0; i < 2; i++ {
if !scanner.Scan() {
panic(scanner.Err())
}
}
pk = []string{scanner.Text()}
}
var (
verifyCreatePublicKeyError *VerifyCreatePublicKeyError
verifyInvalidSignatureAlgorithmError *VerifyInvalidSignatureAlgorithmError
verifyWrongSigFilenameError *VerifyWrongSigFilenameError
verifyInvalidTrustedCommentError *VerifyInvalidTrustedCommentError
verifyInvalidSignatureFormatError *VerifyInvalidSignatureFormatError
verifyInvalidSignatureError *VerifyInvalidSignatureError
verifySigTimeEarlierError *VerifySigTimeEarlierError
verifyUnknownExpectedFilenameError *VerifyUnknownExpectedFilenameError
verifyUnknownKeyError *VerifyUnknownKeyError
)
tests := []struct {
expectedErr interface{}
testName string
signatureFile string
jsonFile string
expectedFileName string
minSignTime uint64
allowedPks []string
}{
{&verifyInvalidSignatureAlgorithmError, "pure", "server_list.json.pure.minisig", "server_list.json", "server_list.json", 10, pk},
{nil, "valid server_list", "server_list.json.minisig", "server_list.json", "server_list.json", 10, pk},
{nil, "TC no hashed", "server_list.json.tc_nohashed.minisig", "server_list.json", "server_list.json", 10, pk},
{nil, "TC later time", "server_list.json.tc_latertime.minisig", "server_list.json", "server_list.json", 10, pk},
{&verifyWrongSigFilenameError, "server_list TC file:organization_list", "server_list.json.tc_orglist.minisig", "server_list.json", "server_list.json", 10, pk},
{&verifyWrongSigFilenameError, "organization_list as server_list", "organization_list.json.minisig", "organization_list.json", "server_list.json", 10, pk},
{&verifyWrongSigFilenameError, "TC file:otherfile", "server_list.json.tc_otherfile.minisig", "server_list.json", "server_list.json", 10, pk},
{&verifySigTimeEarlierError, "TC no file", "server_list.json.tc_nofile.minisig", "server_list.json", "server_list.json", 10, pk},
{&verifySigTimeEarlierError, "TC no time", "server_list.json.tc_notime.minisig", "server_list.json", "server_list.json", 10, pk},
{&verifySigTimeEarlierError, "TC empty time", "server_list.json.tc_emptytime.minisig", "server_list.json", "server_list.json", 10, pk},
{&verifyInvalidSignatureFormatError, "TC empty file", "server_list.json.tc_emptyfile.minisig", "server_list.json", "server_list.json", 10, pk},
{&verifyInvalidTrustedCommentError, "TC random", "server_list.json.tc_random.minisig", "server_list.json", "server_list.json", 10, pk},
{nil, "large time", "server_list.json.large_time.minisig", "server_list.json", "server_list.json", 43e8, pk},
{nil, "lower min time", "server_list.json.minisig", "server_list.json", "server_list.json", 5, pk},
{&verifySigTimeEarlierError, "higher min time", "server_list.json.minisig", "server_list.json", "server_list.json", 11, pk},
{nil, "valid organization_list", "organization_list.json.minisig", "organization_list.json", "organization_list.json", 10, pk},
{&verifyWrongSigFilenameError, "organization_list TC file:server_list", "organization_list.json.tc_servlist.minisig", "organization_list.json", "organization_list.json", 10, pk},
{&verifyWrongSigFilenameError, "server_list as organization_list", "server_list.json.minisig", "server_list.json", "organization_list.json", 10, pk},
{&verifyUnknownExpectedFilenameError, "valid other_list", "other_list.json.minisig", "other_list.json", "other_list.json", 10, pk},
{&verifyWrongSigFilenameError, "other_list as server_list", "other_list.json.minisig", "other_list.json", "server_list.json", 10, pk},
{&verifyInvalidSignatureFormatError, "invalid signature file", "random.txt", "server_list.json", "server_list.json", 10, pk},
{&verifyInvalidSignatureFormatError, "empty signature file", "empty", "server_list.json", "server_list.json", 10, pk},
{&verifyUnknownKeyError, "wrong key", "server_list.json.wrong_key.minisig", "server_list.json", "server_list.json", 10, pk},
{&verifyInvalidSignatureAlgorithmError, "forged pure signature", "server_list.json.forged_pure.minisig", "server_list.json.blake2b", "server_list.json", 10, pk},
{&verifyInvalidSignatureError, "forged key ID", "server_list.json.forged_keyid.minisig", "server_list.json", "server_list.json", 10, pk},
{&verifyUnknownKeyError, "no allowed keys", "server_list.json.minisig", "server_list.json", "server_list.json", 10, []string{}},
{nil, "multiple allowed keys 1", "server_list.json.minisig", "server_list.json", "server_list.json", 10, []string{
pk[0], "RWSf0PYToIUJmDlsz21YOXvgQzHj9NSdyJUqEY5ZdfS9GepeXt3+JJRZ",
}},
{nil, "multiple allowed keys 2", "server_list.json.minisig", "server_list.json", "server_list.json", 10, []string{
"RWSf0PYToIUJmDlsz21YOXvgQzHj9NSdyJUqEY5ZdfS9GepeXt3+JJRZ", pk[0],
}},
{&verifyCreatePublicKeyError, "invalid allowed key", "server_list.json.minisig", "server_list.json", "server_list.json", 10, []string{"AAA"}},
}
// Cache file contents in map, mapping file names to contents
files := map[string][]byte{}
loadFile := func(name string) {
content, loaded := files[name]
if !loaded {
content, err = ioutil.ReadFile("test_data/" + name)
if err != nil {
panic(err)
}
files[name] = content
}
}
for _, test := range tests {
loadFile(test.signatureFile)
loadFile(test.jsonFile)
}
forcePrehash := true
for _, tt := range tests {
t.Run(tt.testName, func(t *testing.T) {
t.Parallel()
valid, err := verifyWithKeys(string(files[tt.signatureFile]), files[tt.jsonFile],
tt.expectedFileName, tt.minSignTime, tt.allowedPks, forcePrehash)
compareResults(t, valid, err, tt.expectedErr, func() string {
return fmt.Sprintf("verifyWithKeys(%q, %q, %q, %v, %v, %t)",
tt.signatureFile, tt.jsonFile, tt.expectedFileName, tt.minSignTime, tt.allowedPks, forcePrehash)
})
})
}
}
// compareResults compares returned ret, err from a verify function with expected error code expected.
// callStr is called to get the formatted parameters passed to the function.
func compareResults(t *testing.T, ret bool, err error, expectedErr interface{}, callStr func() string) {
// different error returned
if expectedErr != nil && !errors.As(err, expectedErr) {
t.Errorf("%v\nerror %T = %v, wantErr %T", callStr(), err, err, expectedErr)
return
}
// different boolean returned
expectedBool := expectedErr == nil
if ret != expectedBool {
t.Errorf("%v\n= %v, want %v", callStr(), ret, expectedBool)
}
}
|