master
go 405 lines 10.1 KB
Raw
1 package tests
2
3 import (
4 "strings"
5 "testing"
6
7 "github.com/ipfs/boxo/ipns"
8 "github.com/ipfs/go-cid"
9 iface "github.com/ipfs/kubo/core/coreiface"
10 opt "github.com/ipfs/kubo/core/coreiface/options"
11 "github.com/libp2p/go-libp2p/core/peer"
12 mbase "github.com/multiformats/go-multibase"
13 "github.com/stretchr/testify/assert"
14 "github.com/stretchr/testify/require"
15 )
16
17 func (tp *TestSuite) TestKey(t *testing.T) {
18 tp.hasApi(t, func(api iface.CoreAPI) error {
19 if api.Key() == nil {
20 return errAPINotImplemented
21 }
22 return nil
23 })
24
25 t.Run("TestListSelf", tp.TestListSelf)
26 t.Run("TestRenameSelf", tp.TestRenameSelf)
27 t.Run("TestRemoveSelf", tp.TestRemoveSelf)
28 t.Run("TestGenerate", tp.TestGenerate)
29 t.Run("TestGenerateSize", tp.TestGenerateSize)
30 t.Run("TestGenerateType", tp.TestGenerateType)
31 t.Run("TestGenerateExisting", tp.TestGenerateExisting)
32 t.Run("TestList", tp.TestList)
33 t.Run("TestRename", tp.TestRename)
34 t.Run("TestRenameToSelf", tp.TestRenameToSelf)
35 t.Run("TestRenameToSelfForce", tp.TestRenameToSelfForce)
36 t.Run("TestRenameOverwriteNoForce", tp.TestRenameOverwriteNoForce)
37 t.Run("TestRenameOverwrite", tp.TestRenameOverwrite)
38 t.Run("TestRenameSameNameNoForce", tp.TestRenameSameNameNoForce)
39 t.Run("TestRenameSameName", tp.TestRenameSameName)
40 t.Run("TestSign", tp.TestSign)
41 t.Run("TestVerify", tp.TestVerify)
42 }
43
44 func (tp *TestSuite) TestListSelf(t *testing.T) {
45 ctx := t.Context()
46
47 api, err := tp.makeAPI(t, ctx)
48 require.NoError(t, err)
49
50 self, err := api.Key().Self(ctx)
51 require.NoError(t, err)
52
53 keys, err := api.Key().List(ctx)
54 require.NoError(t, err)
55 require.Len(t, keys, 1)
56 assert.Equal(t, "self", keys[0].Name())
57 assert.Equal(t, "/ipns/"+iface.FormatKeyID(self.ID()), keys[0].Path().String())
58 }
59
60 func (tp *TestSuite) TestRenameSelf(t *testing.T) {
61 ctx := t.Context()
62
63 api, err := tp.makeAPI(t, ctx)
64 require.NoError(t, err)
65
66 _, _, err = api.Key().Rename(ctx, "self", "foo")
67 require.ErrorContains(t, err, "cannot rename key with name 'self'")
68
69 _, _, err = api.Key().Rename(ctx, "self", "foo", opt.Key.Force(true))
70 require.ErrorContains(t, err, "cannot rename key with name 'self'")
71 }
72
73 func (tp *TestSuite) TestRemoveSelf(t *testing.T) {
74 ctx := t.Context()
75
76 api, err := tp.makeAPI(t, ctx)
77 require.NoError(t, err)
78
79 _, err = api.Key().Remove(ctx, "self")
80 require.ErrorContains(t, err, "cannot remove key with name 'self'")
81 }
82
83 func (tp *TestSuite) TestGenerate(t *testing.T) {
84 ctx := t.Context()
85
86 api, err := tp.makeAPI(t, ctx)
87 require.NoError(t, err)
88
89 k, err := api.Key().Generate(ctx, "foo")
90 require.NoError(t, err)
91 require.Equal(t, "foo", k.Name())
92
93 verifyIPNSPath(t, k.Path().String())
94 }
95
96 func verifyIPNSPath(t *testing.T, p string) {
97 t.Helper()
98
99 require.True(t, strings.HasPrefix(p, "/ipns/"))
100
101 k := p[len("/ipns/"):]
102 c, err := cid.Decode(k)
103 require.NoError(t, err)
104
105 b36, err := c.StringOfBase(mbase.Base36)
106 require.NoError(t, err)
107 require.Equal(t, k, b36)
108 }
109
110 func (tp *TestSuite) TestGenerateSize(t *testing.T) {
111 ctx := t.Context()
112
113 api, err := tp.makeAPI(t, ctx)
114 require.NoError(t, err)
115
116 k, err := api.Key().Generate(ctx, "foo", opt.Key.Size(2048))
117 require.NoError(t, err)
118 require.Equal(t, "foo", k.Name())
119
120 verifyIPNSPath(t, k.Path().String())
121 }
122
123 func (tp *TestSuite) TestGenerateType(t *testing.T) {
124 t.Skip("disabled until libp2p/specs#111 is fixed")
125
126 ctx := t.Context()
127
128 api, err := tp.makeAPI(t, ctx)
129 require.NoError(t, err)
130
131 k, err := api.Key().Generate(ctx, "bar", opt.Key.Type(opt.Ed25519Key))
132 require.NoError(t, err)
133 require.Equal(t, "bar", k.Name())
134 // Expected to be an inlined identity hash.
135 require.True(t, strings.HasPrefix(k.Path().String(), "/ipns/12"))
136 }
137
138 func (tp *TestSuite) TestGenerateExisting(t *testing.T) {
139 ctx := t.Context()
140
141 api, err := tp.makeAPI(t, ctx)
142 require.NoError(t, err)
143
144 _, err = api.Key().Generate(ctx, "foo")
145 require.NoError(t, err)
146
147 _, err = api.Key().Generate(ctx, "foo")
148 require.ErrorContains(t, err, "key with name 'foo' already exists")
149
150 _, err = api.Key().Generate(ctx, "self")
151 require.ErrorContains(t, err, "cannot create key with name 'self'")
152 }
153
154 func (tp *TestSuite) TestList(t *testing.T) {
155 ctx := t.Context()
156
157 api, err := tp.makeAPI(t, ctx)
158 require.NoError(t, err)
159
160 _, err = api.Key().Generate(ctx, "foo")
161 require.NoError(t, err)
162
163 l, err := api.Key().List(ctx)
164 require.NoError(t, err)
165 require.Len(t, l, 2)
166 require.Equal(t, "self", l[0].Name())
167 require.Equal(t, "foo", l[1].Name())
168
169 verifyIPNSPath(t, l[0].Path().String())
170 verifyIPNSPath(t, l[1].Path().String())
171 }
172
173 func (tp *TestSuite) TestRename(t *testing.T) {
174 ctx := t.Context()
175
176 api, err := tp.makeAPI(t, ctx)
177 require.NoError(t, err)
178
179 _, err = api.Key().Generate(ctx, "foo")
180 require.NoError(t, err)
181
182 k, overwrote, err := api.Key().Rename(ctx, "foo", "bar")
183 require.NoError(t, err)
184 assert.False(t, overwrote)
185 assert.Equal(t, "bar", k.Name())
186 }
187
188 func (tp *TestSuite) TestRenameToSelf(t *testing.T) {
189 ctx := t.Context()
190
191 api, err := tp.makeAPI(t, ctx)
192 require.NoError(t, err)
193
194 _, err = api.Key().Generate(ctx, "foo")
195 require.NoError(t, err)
196
197 _, _, err = api.Key().Rename(ctx, "foo", "self")
198 require.ErrorContains(t, err, "cannot overwrite key with name 'self'")
199 }
200
201 func (tp *TestSuite) TestRenameToSelfForce(t *testing.T) {
202 ctx := t.Context()
203
204 api, err := tp.makeAPI(t, ctx)
205 require.NoError(t, err)
206
207 _, err = api.Key().Generate(ctx, "foo")
208 require.NoError(t, err)
209
210 _, _, err = api.Key().Rename(ctx, "foo", "self", opt.Key.Force(true))
211 require.ErrorContains(t, err, "cannot overwrite key with name 'self'")
212 }
213
214 func (tp *TestSuite) TestRenameOverwriteNoForce(t *testing.T) {
215 ctx := t.Context()
216
217 api, err := tp.makeAPI(t, ctx)
218 require.NoError(t, err)
219
220 _, err = api.Key().Generate(ctx, "foo")
221 require.NoError(t, err)
222
223 _, err = api.Key().Generate(ctx, "bar")
224 require.NoError(t, err)
225
226 _, _, err = api.Key().Rename(ctx, "foo", "bar")
227 require.ErrorContains(t, err, "key by that name already exists, refusing to overwrite")
228 }
229
230 func (tp *TestSuite) TestRenameOverwrite(t *testing.T) {
231 ctx := t.Context()
232
233 api, err := tp.makeAPI(t, ctx)
234 require.NoError(t, err)
235
236 kfoo, err := api.Key().Generate(ctx, "foo")
237 require.NoError(t, err)
238
239 _, err = api.Key().Generate(ctx, "bar")
240 require.NoError(t, err)
241
242 k, overwrote, err := api.Key().Rename(ctx, "foo", "bar", opt.Key.Force(true))
243 require.NoError(t, err)
244 require.True(t, overwrote)
245 assert.Equal(t, "bar", k.Name())
246 assert.Equal(t, kfoo.Path().String(), k.Path().String())
247 }
248
249 func (tp *TestSuite) TestRenameSameNameNoForce(t *testing.T) {
250 ctx := t.Context()
251
252 api, err := tp.makeAPI(t, ctx)
253 require.NoError(t, err)
254
255 _, err = api.Key().Generate(ctx, "foo")
256 require.NoError(t, err)
257
258 k, overwrote, err := api.Key().Rename(ctx, "foo", "foo")
259 require.NoError(t, err)
260 assert.False(t, overwrote)
261 assert.Equal(t, "foo", k.Name())
262 }
263
264 func (tp *TestSuite) TestRenameSameName(t *testing.T) {
265 ctx := t.Context()
266
267 api, err := tp.makeAPI(t, ctx)
268 require.NoError(t, err)
269
270 _, err = api.Key().Generate(ctx, "foo")
271 require.NoError(t, err)
272
273 k, overwrote, err := api.Key().Rename(ctx, "foo", "foo", opt.Key.Force(true))
274 require.NoError(t, err)
275 assert.False(t, overwrote)
276 assert.Equal(t, "foo", k.Name())
277 }
278
279 func (tp *TestSuite) TestRemove(t *testing.T) {
280 ctx := t.Context()
281
282 api, err := tp.makeAPI(t, ctx)
283 require.NoError(t, err)
284
285 k, err := api.Key().Generate(ctx, "foo")
286 require.NoError(t, err)
287
288 l, err := api.Key().List(ctx)
289 require.NoError(t, err)
290 require.Len(t, l, 2)
291
292 p, err := api.Key().Remove(ctx, "foo")
293 require.NoError(t, err)
294 assert.Equal(t, p.Path().String(), k.Path().String())
295
296 l, err = api.Key().List(ctx)
297 require.NoError(t, err)
298 require.Len(t, l, 1)
299 assert.Equal(t, "self", l[0].Name())
300 }
301
302 func (tp *TestSuite) TestSign(t *testing.T) {
303 ctx := t.Context()
304
305 api, err := tp.makeAPI(t, ctx)
306 require.NoError(t, err)
307
308 key1, err := api.Key().Generate(ctx, "foo", opt.Key.Type(opt.Ed25519Key))
309 require.NoError(t, err)
310
311 data := []byte("hello world")
312
313 key2, signature, err := api.Key().Sign(ctx, "foo", data)
314 require.NoError(t, err)
315
316 require.Equal(t, key1.Name(), key2.Name())
317 require.Equal(t, key1.ID(), key2.ID())
318
319 pk, err := key1.ID().ExtractPublicKey()
320 require.NoError(t, err)
321
322 valid, err := pk.Verify(append([]byte("libp2p-key signed message:"), data...), signature)
323 require.NoError(t, err)
324 require.True(t, valid)
325 }
326
327 func (tp *TestSuite) TestVerify(t *testing.T) {
328 t.Parallel()
329
330 t.Run("Verify Own Key", func(t *testing.T) {
331 t.Parallel()
332
333 ctx := t.Context()
334
335 api, err := tp.makeAPI(t, ctx)
336 require.NoError(t, err)
337
338 _, err = api.Key().Generate(ctx, "foo", opt.Key.Type(opt.Ed25519Key))
339 require.NoError(t, err)
340
341 data := []byte("hello world")
342
343 _, signature, err := api.Key().Sign(ctx, "foo", data)
344 require.NoError(t, err)
345
346 _, valid, err := api.Key().Verify(ctx, "foo", signature, data)
347 require.NoError(t, err)
348 require.True(t, valid)
349 })
350
351 t.Run("Verify Self", func(t *testing.T) {
352 t.Parallel()
353
354 ctx := t.Context()
355
356 api, err := tp.makeAPIWithIdentityAndOffline(t, ctx)
357 require.NoError(t, err)
358
359 data := []byte("hello world")
360
361 _, signature, err := api.Key().Sign(ctx, "", data)
362 require.NoError(t, err)
363
364 _, valid, err := api.Key().Verify(ctx, "", signature, data)
365 require.NoError(t, err)
366 require.True(t, valid)
367 })
368
369 t.Run("Verify With Key In Different Formats", func(t *testing.T) {
370 t.Parallel()
371
372 // Spin some node and get signature out.
373 ctx := t.Context()
374
375 api, err := tp.makeAPI(t, ctx)
376 require.NoError(t, err)
377
378 key, err := api.Key().Generate(ctx, "foo", opt.Key.Type(opt.Ed25519Key))
379 require.NoError(t, err)
380
381 data := []byte("hello world")
382
383 _, signature, err := api.Key().Sign(ctx, "foo", data)
384 require.NoError(t, err)
385
386 for _, testCase := range [][]string{
387 {"Base58 Encoded Peer ID", key.ID().String()},
388 {"CIDv1 Encoded Peer ID", peer.ToCid(key.ID()).String()},
389 {"CIDv1 Encoded IPNS Name", ipns.NameFromPeer(key.ID()).String()},
390 {"Prefixed IPNS Path", ipns.NameFromPeer(key.ID()).AsPath().String()},
391 } {
392 t.Run(testCase[0], func(t *testing.T) {
393 ctx := t.Context()
394
395 // Spin new node.
396 api, err := tp.makeAPI(t, ctx)
397 require.NoError(t, err)
398
399 _, valid, err := api.Key().Verify(ctx, testCase[1], signature, data)
400 require.NoError(t, err)
401 require.True(t, valid)
402 })
403 }
404 })
405 }