-
Notifications
You must be signed in to change notification settings - Fork 64
/
verify_test.go
180 lines (150 loc) · 5.47 KB
/
verify_test.go
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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
// Copyright 2015 Keybase, Inc. All rights reserved. Use of
// this source code is governed by the included BSD license.
package saltpack
import (
"bytes"
"encoding/hex"
"errors"
"io"
"sync"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestVerifyVersionValidator(t *testing.T) {
in := []byte{0x01}
key := newSigPrivKey(t)
smg, err := Sign(Version1(), in, key)
require.NoError(t, err)
_, _, err = Verify(SingleVersionValidator(Version2()), smg, kr)
require.NotNil(t, err)
}
func testVerify(t *testing.T, version Version) {
in := randomMsg(t, 128)
key := newSigPrivKey(t)
smsg, err := Sign(version, in, key)
require.NoError(t, err)
skey, msg, err := Verify(SingleVersionValidator(version), smsg, kr)
require.NoError(t, err, "input: %x\nsigned msg: %x", in, smsg)
assert.True(t, PublicKeyEqual(skey, key.GetPublicKey()),
"sender key %x, expected %x", skey.ToKID(), key.GetPublicKey().ToKID())
assert.Equal(t, in, msg)
}
func testVerifyNewMinorVersion(t *testing.T, version Version) {
in := []byte{0x01}
newVersion := version
newVersion.Minor++
tso := testSignOptions{
corruptHeader: func(sh *SignatureHeader) {
sh.Version = newVersion
},
}
key := newSigPrivKey(t)
smg, err := testTweakSign(version, in, key, tso)
require.NoError(t, err)
_, _, err = Verify(SingleVersionValidator(newVersion), smg, kr)
require.NoError(t, err)
}
func testVerifyConcurrent(t *testing.T, version Version) {
in := randomMsg(t, 128)
key := newSigPrivKey(t)
smsg, err := Sign(version, in, key)
require.NoError(t, err)
var wg sync.WaitGroup
for i := 0; i < 100; i++ {
wg.Add(1)
go func() {
defer wg.Done()
skey, msg, err := Verify(SingleVersionValidator(version), smsg, kr)
if !assert.NoError(t, err, "input: %x\nsigned msg: %x", in, smsg) {
// Don't fall through, as the tests below will panic.
return
}
assert.True(t, PublicKeyEqual(skey, key.GetPublicKey()),
"sender key %x, expected %x", skey.ToKID(), key.GetPublicKey().ToKID())
assert.Equal(t, in, msg)
}()
}
wg.Wait()
}
type emptySigKeyring struct{}
func (k emptySigKeyring) LookupSigningPublicKey(kid []byte) SigningPublicKey { return nil }
func testVerifyEmptyKeyring(t *testing.T, version Version) {
in := randomMsg(t, 128)
key := newSigPrivKey(t)
smsg, err := Sign(version, in, key)
require.NoError(t, err)
_, _, err = Verify(SingleVersionValidator(version), smsg, emptySigKeyring{})
require.Equal(t, ErrNoSenderKey{Sender: key.GetPublicKey().ToKID()}, err)
}
func testVerifyDetachedEmptyKeyring(t *testing.T, version Version) {
key := newSigPrivKey(t)
msg := randomMsg(t, 128)
sig, err := SignDetached(version, msg, key)
require.NoError(t, err)
_, err = VerifyDetached(SingleVersionValidator(version), msg, sig, emptySigKeyring{})
require.Equal(t, ErrNoSenderKey{Sender: key.GetPublicKey().ToKID()}, err)
}
func testVerifyErrorAtEOF(t *testing.T, version Version) {
in := randomMsg(t, 128)
key := newSigPrivKey(t)
smsg, err := Sign(version, in, key)
require.NoError(t, err)
var reader io.Reader = bytes.NewReader(smsg)
errAtEOF := errors.New("err at EOF")
reader = errAtEOFReader{reader, errAtEOF}
_, stream, err := NewVerifyStream(SingleVersionValidator(version), reader, kr)
require.NoError(t, err)
msg, err := io.ReadAll(stream)
requireErrSuffix(t, err, errAtEOF.Error())
// Since the bytes are still verified, the verified message
// should still compare equal to the original input.
assert.Equal(t, in, msg)
}
func TestVerify(t *testing.T) {
tests := []func(*testing.T, Version){
testVerify,
testVerifyNewMinorVersion,
testVerifyConcurrent,
testVerifyEmptyKeyring,
testVerifyDetachedEmptyKeyring,
testVerifyErrorAtEOF,
}
runTestsOverVersions(t, "test", tests)
}
type pubkeyOnlySigKeyring struct{}
func (p pubkeyOnlySigKeyring) LookupSigningPublicKey(kid []byte) SigningPublicKey {
return newSigPubKey(kid)
}
const hardcodedV1SignedMessage = `
BEGIN KEYBASE SALTPACK SIGNED MESSAGE. kXR7VktZdyH7rvq v5wcIkHbsMGwMrf
bu4PmUTnBUI2QWi Nu9smFqPCiRfB9h PAUmWFHLkTKGMdN tdrKMtkDu0UhJEj 7gM6Tt8OeykFHq9
R4FnzgakB19YwYa CGVfWxxXpK9OaMI S00BurzWOWBXIxe EoTHvgyx1oHUVdX HRNjJCXTvsSJVa8
Qyg3bN37HAfS8ek gZG6JflV06S2Olp gLdhxNZKIo2zF9P sD5pDFXvoVVzeNC D4vZtMiNQrniEYo
qY903nTYqyGQ4yl UULZ6yP14CcSPfg 8r8CXVi5Z2. END KEYBASE SALTPACK SIGNED
MESSAGE.
`
const hardcodedVerifyKey = "f596585d050597c03a87d653c4be89f7327dbd86b921dd05acfc9df33eb7a962"
func TestHardcodedSignedMessageV1(t *testing.T) {
decodedKey, err := hex.DecodeString(hardcodedVerifyKey)
require.NoError(t, err)
keyring := pubkeyOnlySigKeyring{}
signer, plaintext, _, err := Dearmor62Verify(SingleVersionValidator(Version1()), hardcodedV1SignedMessage, keyring)
require.NoError(t, err)
require.Equal(t, "test message!", string(plaintext))
require.Equal(t, decodedKey, signer.ToKID())
}
const hardcodedV1DetachedSignature = `
BEGIN KEYBASE SALTPACK DETACHED SIGNATURE. kXR7VktZdyH7rvq v5wcIkPOwOUCix9
HfoZZdGgIjzeYWi Nu9smFqPCiRfB9h PAUmWFHLkUaLXQd DTZrK37uaKi9dgf 60zJCgqbheQLTVP
Vr2Dw2x1MLOenwI dt3P0dRsyh2WvQW OeqH28kbuzPiA0f OPQ0Y26dpV8A8uE DUDdJed0edSYEbx
v. END KEYBASE SALTPACK DETACHED SIGNATURE.
`
func TestHardcodedDetachedSignatureV1(t *testing.T) {
decodedKey, err := hex.DecodeString(hardcodedVerifyKey)
require.NoError(t, err)
keyring := pubkeyOnlySigKeyring{}
signer, _, err := Dearmor62VerifyDetached(SingleVersionValidator(Version1()), []byte("test message!"), hardcodedV1DetachedSignature, keyring)
require.NoError(t, err)
require.Equal(t, decodedKey, signer.ToKID())
}