1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package crypto11
23
24 import (
25 "encoding/json"
26 "fmt"
27 "log"
28 "math/rand"
29 "os"
30 "testing"
31 "time"
32
33 "github.com/miekg/pkcs11"
34
35 "github.com/stretchr/testify/assert"
36
37 "github.com/stretchr/testify/require"
38 )
39
40 func TestKeysPersistAcrossContexts(t *testing.T) {
41
42 ctx, err := ConfigureFromFile("config")
43 require.NoError(t, err)
44
45 id := randomBytes()
46 _, err = ctx.GenerateRSAKeyPair(id, rsaSize)
47 if err != nil {
48 _ = ctx.Close()
49 t.Fatal(err)
50 }
51
52 require.NoError(t, ctx.Close())
53
54 ctx, err = ConfigureFromFile("config")
55 require.NoError(t, err)
56
57 key2, err := ctx.FindKeyPair(id, nil)
58 require.NoError(t, err)
59
60 testRsaSigning(t, key2, false)
61 _ = key2.Delete()
62 require.NoError(t, ctx.Close())
63 }
64
65 func configureWithPin(t *testing.T) (*Context, error) {
66 cfg, err := getConfig("config")
67 if err != nil {
68 t.Fatal(err)
69 }
70
71 if cfg.Pin == "" {
72 t.Fatal("invalid configuration. configuration must have PIN non empty.")
73 }
74
75 ctx, err := Configure(cfg)
76 if err != nil {
77 t.Fatal("failed to configure service:", err)
78 }
79
80 return ctx, nil
81 }
82
83 func getConfig(configLocation string) (ctx *Config, err error) {
84 file, err := os.Open(configLocation)
85 if err != nil {
86 log.Printf("Could not open config file: %s", configLocation)
87 return nil, err
88 }
89 defer func() {
90 err = file.Close()
91 }()
92
93 configDecoder := json.NewDecoder(file)
94 config := &Config{}
95 err = configDecoder.Decode(config)
96 if err != nil {
97 log.Printf("Could decode config file: %s", err.Error())
98 return nil, err
99 }
100 return config, nil
101 }
102
103 func TestKeyPairDelete(t *testing.T) {
104 ctx, err := ConfigureFromFile("config")
105 require.NoError(t, err)
106
107 defer func() {
108 require.NoError(t, ctx.Close())
109 }()
110
111 id := randomBytes()
112 key, err := ctx.GenerateRSAKeyPair(id, 2048)
113 require.NoError(t, err)
114
115
116 _, err = ctx.FindKeyPair(id, nil)
117 require.NoError(t, err)
118
119 err = key.Delete()
120 require.NoError(t, err)
121
122 k, err := ctx.FindKeyPair(id, nil)
123 require.NoError(t, err)
124 require.Nil(t, k)
125 }
126
127 func TestKeyDelete(t *testing.T) {
128 ctx, err := ConfigureFromFile("config")
129 require.NoError(t, err)
130
131 defer func() {
132 require.NoError(t, ctx.Close())
133 }()
134
135 id := randomBytes()
136 key, err := ctx.GenerateSecretKey(id, 128, CipherAES)
137 require.NoError(t, err)
138
139
140 _, err = ctx.FindKey(id, nil)
141 require.NoError(t, err)
142
143 err = key.Delete()
144 require.NoError(t, err)
145
146 k, err := ctx.FindKey(id, nil)
147 require.NoError(t, err)
148 require.Nil(t, k)
149 }
150
151 func TestAmbiguousTokenConfig(t *testing.T) {
152 slotNum := 1
153 tests := []struct {
154 config *Config
155 err string
156 }{
157 {
158 config: &Config{TokenSerial: "serial", TokenLabel: "label"},
159 err: "config must specify exactly one way to select a token: token label, token serial number given",
160 },
161 {
162 config: &Config{TokenSerial: "serial", SlotNumber: &slotNum},
163 err: "config must specify exactly one way to select a token: slot number, token serial number given",
164 },
165 {
166 config: &Config{SlotNumber: &slotNum, TokenLabel: "label"},
167 err: "config must specify exactly one way to select a token: slot number, token label given",
168 },
169 {
170 config: &Config{},
171 err: "config must specify exactly one way to select a token: none given",
172 },
173 }
174 for i, test := range tests {
175 t.Run(fmt.Sprintf("test_%d", i), func(t *testing.T) {
176 _, err := Configure(test.config)
177 if assert.Error(t, err) {
178 assert.Equal(t, test.err, err.Error())
179 }
180 })
181 }
182 }
183
184 func TestSelectBySlot(t *testing.T) {
185 config, err := loadConfigFromFile("config")
186 require.NoError(t, err)
187
188
189 ctx, err := Configure(config)
190 require.NoError(t, err)
191
192 slotNumber := int(ctx.slot)
193 t.Logf("Using slot %d", slotNumber)
194 err = ctx.Close()
195 require.NoError(t, err)
196
197 slotConfig := &Config{
198 SlotNumber: &slotNumber,
199 Pin: config.Pin,
200 Path: config.Path,
201 }
202
203 ctx, err = Configure(slotConfig)
204 require.NoError(t, err)
205
206 slotNumber2 := int(ctx.slot)
207 err = ctx.Close()
208 require.NoError(t, err)
209
210 assert.Equal(t, slotNumber, slotNumber2)
211 }
212
213 func TestSelectByNonExistingSlot(t *testing.T) {
214 config, err := loadConfigFromFile("config")
215 require.NoError(t, err)
216
217 rand.Seed(time.Now().UnixNano())
218 randomSlot := int(rand.Uint32())
219
220 config.TokenLabel = ""
221 config.TokenSerial = ""
222 config.SlotNumber = &randomSlot
223
224
225 _, err = Configure(config)
226 require.Equal(t, errTokenNotFound, err)
227 }
228
229 func TestAccessSameLibraryTwice(t *testing.T) {
230 ctx1, err := ConfigureFromFile("config")
231 require.NoError(t, err)
232
233 ctx2, err := ConfigureFromFile("config")
234 require.NoError(t, err)
235
236
237
238 err = ctx1.Close()
239 require.NoError(t, err)
240
241
242
243 _, err = ctx2.FindKey(randomBytes(), nil)
244 require.NoError(t, err)
245
246 err = ctx2.Close()
247 require.NoError(t, err)
248
249
250 ctx3, err := ConfigureFromFile("config")
251 require.NoError(t, err)
252
253
254
255 _, err = ctx3.FindKey(randomBytes(), nil)
256 require.NoError(t, err)
257
258 err = ctx3.Close()
259 require.NoError(t, err)
260 }
261
262 func TestNoLogin(t *testing.T) {
263
264
265 cfg, err := getConfig("config")
266 require.NoError(t, err)
267 cfg.LoginNotSupported = true
268
269 ctx, err := Configure(cfg)
270 require.NoError(t, err)
271
272 _, err = ctx.GenerateSecretKey(randomBytes(), 256, CipherAES)
273 require.Error(t, err)
274
275 p11Err, ok := err.(pkcs11.Error)
276 require.True(t, ok)
277
278 assert.Equal(t, pkcs11.Error(pkcs11.CKR_USER_NOT_LOGGED_IN), p11Err)
279 }
280
281 func TestInvalidMaxSessions(t *testing.T) {
282 cfg, err := getConfig("config")
283 require.NoError(t, err)
284
285 cfg.MaxSessions = 1
286 _, err = Configure(cfg)
287 require.Error(t, err)
288 }
289
290
291 func randomBytes() []byte {
292 result := make([]byte, 32)
293 rand.Read(result)
294 return result
295 }
296
297 func init() {
298 rand.Seed(time.Now().UnixNano())
299 }
300
View as plain text