use standard multibase format labels
Petar Maymounkov committed
Aug 11, 2020 at 08:42 UTC
2b013a1ac52d33c1f0be77c70b5e892c39eaa466
8 files changed
+105
-52
core/commands/keybase/keybase.go
new
+35
@@ -0,0 +1,35 @@
1
+package keybase
2
+
3
+import (
4
+ peer "github.com/libp2p/go-libp2p-core/peer"
5
+ mbase "github.com/multiformats/go-multibase"
6
+)
7
+
8
+type KeyEncoder struct {
9
+ baseEnc *mbase.Encoder
10
+}
11
+
12
+func KeyEncoderFromString(formatLabel string) (KeyEncoder, error) {
13
+ switch formatLabel {
14
+ case "b58mh", "v0":
15
+ return KeyEncoder{}, nil
16
+ default:
17
+ if enc, err := mbase.EncoderByName(formatLabel); err != nil {
18
+ return KeyEncoder{}, err
19
+ } else {
20
+ return KeyEncoder{&enc}, nil
21
+ }
22
+ }
23
+}
24
+
25
+func (enc KeyEncoder) FormatID(id peer.ID) string {
26
+ if enc.baseEnc == nil {
27
+ //nolint deprecated
28
+ return peer.IDB58Encode(id)
29
+ }
30
+ if s, err := peer.ToCid(id).StringOfBase(enc.baseEnc.Encoding()); err != nil {
31
+ panic(err)
32
+ } else {
33
+ return s
34
+ }
35
+}
core/commands/keystore.go
+47
-27
@@ -15,6 +15,7 @@ import (
15
oldcmds "github.com/ipfs/go-ipfs/commands"
16
cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv"
17
"github.com/ipfs/go-ipfs/core/commands/e"
18
+ kb "github.com/ipfs/go-ipfs/core/commands/keybase"
19
fsrepo "github.com/ipfs/go-ipfs/repo/fsrepo"
20
options "github.com/ipfs/interface-go-ipfs-core/options"
21
"github.com/libp2p/go-libp2p-core/crypto"
@@ -82,7 +83,7 @@ var keyGenCmd = &cmds.Command{
83
Options: []cmds.Option{
84
cmds.StringOption(keyStoreTypeOptionName, "t", "type of the key to create: rsa, ed25519").WithDefault(keyStoreAlgorithmDefault),
85
cmds.IntOption(keyStoreSizeOptionName, "s", "size of the key to generate"),
85
- cmds.StringOption(keyFormatOptionName, "", "output format: b58mh or b36cid").WithDefault("b36cid"),
86
+ cmds.StringOption(keyFormatOptionName, "", "Encoding used for keys: Can either be a multibase encoded CID or a base58btc encoded multihash. Takes {b58mh|base36|k|base32|b...}.").WithDefault("base36"),
87
},
88
Arguments: []cmds.Argument{
89
cmds.StringArg("name", true, false, "name of key to create"),
@@ -109,7 +110,8 @@ var keyGenCmd = &cmds.Command{
110
if sizefound {
111
opts = append(opts, options.Key.Size(size))
112
}
112
- if err = verifyIDFormatLabel(req.Options[keyFormatOptionName].(string)); err != nil {
113
+ keyEnc, err := kb.KeyEncoderFromString(req.Options[keyFormatOptionName].(string))
114
+ if err != nil {
115
return err
116
}
117
@@ -121,7 +123,7 @@ var keyGenCmd = &cmds.Command{
123
124
return cmds.EmitOnce(res, &KeyOutput{
125
Name: name,
124
- Id: formatID(key.ID(), req.Options[keyFormatOptionName].(string)),
126
+ Id: keyEnc.FormatID(key.ID()),
127
})
128
},
129
Encoders: cmds.EncoderMap{
@@ -223,7 +225,7 @@ var keyImportCmd = &cmds.Command{
225
Tagline: "Import a key and prints imported key id",
226
},
227
Options: []cmds.Option{
226
- cmds.StringOption(keyFormatOptionName, "", "output format: b58mh or b36cid").WithDefault("b58mh"),
228
+ cmds.StringOption(keyFormatOptionName, "", "Encoding used for keys: Can either be a multibase encoded CID or a base58btc encoded multihash. Takes {b58mh|base36|k|base32|b...}.").WithDefault("base36"),
229
},
230
Arguments: []cmds.Argument{
231
cmds.StringArg("name", true, false, "name to associate with key in keychain"),
@@ -236,6 +238,11 @@ var keyImportCmd = &cmds.Command{
238
return fmt.Errorf("cannot import key with name 'self'")
239
}
240
241
+ keyEnc, err := kb.KeyEncoderFromString(req.Options[keyFormatOptionName].(string))
242
+ if err != nil {
243
+ return err
244
+ }
245
+
246
file, err := cmdenv.GetFileArg(req.Files.Entries())
247
if err != nil {
248
return err
@@ -280,7 +287,7 @@ var keyImportCmd = &cmds.Command{
287
288
return cmds.EmitOnce(res, &KeyOutput{
289
Name: name,
283
- Id: formatID(pid, req.Options[keyFormatOptionName].(string)),
290
+ Id: keyEnc.FormatID(pid),
291
})
292
},
293
Encoders: cmds.EncoderMap{
@@ -298,10 +305,11 @@ var keyListCmd = &cmds.Command{
305
},
306
Options: []cmds.Option{
307
cmds.BoolOption("l", "Show extra information about keys."),
301
- cmds.StringOption(keyFormatOptionName, "", "output format: b58mh or b36cid").WithDefault("b36cid"),
308
+ cmds.StringOption(keyFormatOptionName, "", "Encoding used for keys: Can either be a multibase encoded CID or a base58btc encoded multihash. Takes {b58mh|base36|k|base32|b...}.").WithDefault("base36"),
309
},
310
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
304
- if err := verifyIDFormatLabel(req.Options[keyFormatOptionName].(string)); err != nil {
311
+ keyEnc, err := kb.KeyEncoderFromString(req.Options[keyFormatOptionName].(string))
312
+ if err != nil {
313
return err
314
}
315
@@ -320,7 +328,7 @@ var keyListCmd = &cmds.Command{
328
for _, key := range keys {
329
list = append(list, KeyOutput{
330
Name: key.Name(),
323
- Id: formatID(key.ID(), req.Options[keyFormatOptionName].(string)),
331
+ Id: keyEnc.FormatID(key.ID()),
332
})
333
}
334
@@ -346,14 +354,15 @@ var keyRenameCmd = &cmds.Command{
354
},
355
Options: []cmds.Option{
356
cmds.BoolOption(keyStoreForceOptionName, "f", "Allow to overwrite an existing key."),
349
- cmds.StringOption(keyFormatOptionName, "", "output format: b58mh or b36cid").WithDefault("b36cid"),
357
+ cmds.StringOption(keyFormatOptionName, "", "Encoding used for keys: Can either be a multibase encoded CID or a base58btc encoded multihash. Takes {b58mh|base36|k|base32|b...}.").WithDefault("base36"),
358
},
359
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
360
api, err := cmdenv.GetApi(env, req)
361
if err != nil {
362
return err
363
}
356
- if err = verifyIDFormatLabel(req.Options[keyFormatOptionName].(string)); err != nil {
364
+ keyEnc, err := kb.KeyEncoderFromString(req.Options[keyFormatOptionName].(string))
365
+ if err != nil {
366
return err
367
}
368
@@ -369,7 +378,7 @@ var keyRenameCmd = &cmds.Command{
378
return cmds.EmitOnce(res, &KeyRenameOutput{
379
Was: name,
380
Now: newName,
372
- Id: formatID(key.ID(), req.Options[keyFormatOptionName].(string)), // key.ID().Pretty(),
381
+ Id: keyEnc.FormatID(key.ID()),
382
Overwrite: overwritten,
383
})
384
},
@@ -395,14 +404,15 @@ var keyRmCmd = &cmds.Command{
404
},
405
Options: []cmds.Option{
406
cmds.BoolOption("l", "Show extra information about keys."),
398
- cmds.StringOption(keyFormatOptionName, "", "output format: b58mh or b36cid").WithDefault("b36cid"),
407
+ cmds.StringOption(keyFormatOptionName, "", "Encoding used for keys: Can either be a multibase encoded CID or a base58btc encoded multihash. Takes {b58mh|base36|k|base32|b...}.").WithDefault("base36"),
408
},
409
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
410
api, err := cmdenv.GetApi(env, req)
411
if err != nil {
412
return err
413
}
405
- if err = verifyIDFormatLabel(req.Options[keyFormatOptionName].(string)); err != nil {
414
+ keyEnc, err := kb.KeyEncoderFromString(req.Options[keyFormatOptionName].(string))
415
+ if err != nil {
416
return err
417
}
418
@@ -417,7 +427,7 @@ var keyRmCmd = &cmds.Command{
427
428
list = append(list, KeyOutput{
429
Name: name,
420
- Id: formatID(key.ID(), req.Options[keyFormatOptionName].(string)),
430
+ Id: keyEnc.FormatID(key.ID()),
431
})
432
}
433
@@ -530,26 +540,36 @@ func doRotate(out io.Writer, repoRoot string, oldKey string, algorithm string, n
540
541
func verifyIDFormatLabel(formatLabel string) error {
542
switch formatLabel {
533
- case "b58mh":
534
- return nil
535
- case "b36cid":
543
+ case "b58mh", "v0":
544
return nil
545
+ default:
546
+ _, err := mbase.EncoderByName(formatLabel)
547
+ return err
548
}
538
- return fmt.Errorf("invalid output format option")
549
}
550
541
-func formatID(id peer.ID, formatLabel string) string {
551
+func keyEncoderFromString(formatLabel string) (keyEncoder, error) {
552
switch formatLabel {
543
- case "b58mh":
544
- return id.Pretty()
545
- case "b36cid":
546
- if s, err := peer.ToCid(id).StringOfBase(mbase.Base36); err != nil {
547
- panic(err)
553
+ case "b58mh", "v0":
554
+ return keyEncoder{}, nil
555
+ default:
556
+ if enc, err := mbase.EncoderByName(formatLabel); err != nil {
557
+ return keyEncoder{}, err
558
} else {
549
- return s
559
+ return keyEncoder{&enc}, nil
560
}
551
- default:
552
- panic("unreachable")
561
+ }
562
+}
563
+
564
+func (enc keyEncoder) FormatID(id peer.ID) string {
565
+ if enc.baseEnc == nil {
566
+ //nolint deprecated
567
+ return peer.IDB58Encode(id)
568
+ }
569
+ if s, err := peer.ToCid(id).StringOfBase(enc.baseEnc.Encoding()); err != nil {
570
+ panic(err)
571
+ } else {
572
+ return s
573
}
574
}
575
test/sharness/lib/test-lib.sh
+4
-4
@@ -445,8 +445,8 @@ file_size() {
445
446
# len 46: 2048-bit RSA keys, b58mh-encoded
447
# len 52: ED25519 keys, b58mh-encoded
448
-# len 56: 2048-bit RSA keys, b36cid-encoded
449
-# len 62: ED25519 keys, b36cid-encoded
448
+# len 56: 2048-bit RSA keys, base36-encoded
449
+# len 62: ED25519 keys, base36-encoded
450
test_check_peerid() {
451
peeridlen=$(echo "$1" | tr -dC "[:alnum:]" | wc -c | tr -d " ") &&
452
test "$peeridlen" = "46" -o "$peeridlen" = "52" -o "$peeridlen" = "56" -o "$peeridlen" = "62" || {
@@ -471,7 +471,7 @@ test_check_ed25519_b58mh_peerid() {
471
}
472
}
473
474
-test_check_rsa2048_b36cid_peerid() {
474
+test_check_rsa2048_base36_peerid() {
475
peeridlen=$(echo "$1" | tr -dC "[:alnum:]" | wc -c | tr -d " ") &&
476
test "$peeridlen" = "56" || {
477
echo "Bad RSA2048 B36CID peerid '$1' with len '$peeridlen'"
@@ -479,7 +479,7 @@ test_check_rsa2048_b36cid_peerid() {
479
}
480
}
481
482
-test_check_ed25519_b36cid_peerid() {
482
+test_check_ed25519_base36_peerid() {
483
peeridlen=$(echo "$1" | tr -dC "[:alnum:]" | wc -c | tr -d " ") &&
484
test "$peeridlen" = "62" || {
485
echo "Bad ED25519 B36CID peerid '$1' with len '$peeridlen'"
test/sharness/t0100-name.sh
+7
-7
@@ -24,7 +24,7 @@ test_name_with_self() {
24
ipfs init --profile=test -a=ed25519 > /dev/null
25
;;
26
esac &&
27
- export PEERID=`ipfs key list --ipns-base=b36cid -l | grep self | cut -d " " -f1` &&
27
+ export PEERID=`ipfs key list --ipns-base=base36 -l | grep self | cut -d " " -f1` &&
28
test_check_peerid "${PEERID}"
29
'
30
@@ -110,20 +110,20 @@ test_name_with_self() {
110
111
test_expect_success "verify self key output" '
112
B58MH_ID=`ipfs key list --ipns-base=b58mh -l | grep self | cut -d " " -f1` &&
113
- B36CID_ID=`ipfs key list --ipns-base=b36cid -l | grep self | cut -d " " -f1` &&
113
+ B36CID_ID=`ipfs key list --ipns-base=base36 -l | grep self | cut -d " " -f1` &&
114
test_check_peerid "${B58MH_ID}" &&
115
test_check_peerid "${B36CID_ID}"
116
'
117
118
test_expect_success "'ipfs name publish --allow-offline --key=<peer-id> <hash>' succeeds" '
119
ipfs name publish --allow-offline --key=${B58MH_ID} "/ipfs/$HASH_WELCOME_DOCS" >b58mh_published_id &&
120
- ipfs name publish --allow-offline --key=${B36CID_ID} "/ipfs/$HASH_WELCOME_DOCS" >b36cid_published_id
120
+ ipfs name publish --allow-offline --key=${B36CID_ID} "/ipfs/$HASH_WELCOME_DOCS" >base36_published_id
121
'
122
123
test_expect_success "publish an explicit node ID as two key in B58MH and B36CID, name looks good" '
124
echo "Published to ${B36CID_ID}: /ipfs/$HASH_WELCOME_DOCS" >expected_published_id &&
125
test_cmp expected_published_id b58mh_published_id &&
126
- test_cmp expected_published_id b36cid_published_id
126
+ test_cmp expected_published_id base36_published_id
127
'
128
129
test_expect_success "'ipfs name resolve' succeeds" '
@@ -251,14 +251,14 @@ test_name_with_key() {
251
case $GEN_ALG in
252
rsa)
253
export KEY=`ipfs key gen --ipns-base=b58mh --type=rsa --size=2048 key` &&
254
- export KEY_B36CID=`ipfs key list --ipns-base=b36cid -l | grep key | cut -d " " -f1`
254
+ export KEY_B36CID=`ipfs key list --ipns-base=base36 -l | grep key | cut -d " " -f1`
255
;;
256
ed25519_b58)
257
export KEY=`ipfs key gen --ipns-base=b58mh --type=ed25519 key`
258
- export KEY_B36CID=`ipfs key list --ipns-base=b36cid -l | grep key | cut -d " " -f1`
258
+ export KEY_B36CID=`ipfs key list --ipns-base=base36 -l | grep key | cut -d " " -f1`
259
;;
260
ed25519_b36)
261
- export KEY=`ipfs key gen --ipns-base=b36cid --type=ed25519 key`
261
+ export KEY=`ipfs key gen --ipns-base=base36 --type=ed25519 key`
262
export KEY_B36CID=$KEY
263
;;
264
esac &&
test/sharness/t0114-gateway-subdomains.sh
+1
-1
@@ -127,7 +127,7 @@ test_expect_success "Publish test text file to IPNS using RSA keys" '
127
test_expect_success "Publish test text file to IPNS using ED25519 keys" '
128
ED25519_KEY=$(ipfs key gen --ipns-base=b58mh --type=ed25519 test_key_ed25519 | head -n1 | tr -d "\n")
129
ED25519_IPNS_IDv0=$ED25519_KEY
130
- ED25519_IPNS_IDv1=$(ipfs key list -l --ipns-base=b36cid | grep test_key_ed25519 | cut -d " " -f1 | tr -d "\n")
130
+ ED25519_IPNS_IDv1=$(ipfs key list -l --ipns-base=base36 | grep test_key_ed25519 | cut -d " " -f1 | tr -d "\n")
131
ED25519_IPNS_IDv1_DAGPB=$(echo "$ED25519_IPNS_IDv1" | ipfs cid format -v 1 -b base36 --codec protobuf)
132
test_check_peerid "${ED25519_KEY}" &&
133
ipfs name publish --key test_key_ed25519 --allow-offline -Q "/ipfs/$CIDv1" > name_publish_out &&
test/sharness/t0160-resolve.sh
+2
-4
@@ -22,10 +22,8 @@ test_expect_success "resolve: prepare dag" '
22
'
23
24
test_expect_success "resolve: prepare keys" '
25
- self_hash=$(ipfs key list --ipns-base=b36cid -l | grep self | cut -d " " -f1) &&
26
- alt_hash=$(ipfs key gen --ipns-base=b36cid -t rsa alt)
27
- echo self_hash $self_hash
28
- echo $(ipfs id -f="<id>")
25
+ self_hash=$(ipfs key list --ipns-base=base36 -l | grep self | cut -d " " -f1) &&
26
+ alt_hash=$(ipfs key gen --ipns-base=base36 -t rsa alt)
27
'
28
29
test_resolve_setup_name() {
test/sharness/t0165-keystore.sh
+8
-8
@@ -16,8 +16,8 @@ test_expect_success "create an RSA key and test B58MH/B36CID output formats" '
16
PEERID=$(ipfs key gen --ipns-base=b58mh --type=rsa --size=2048 key_rsa) &&
17
test_check_rsa2048_b58mh_peerid $PEERID &&
18
ipfs key rm key_rsa &&
19
-PEERID=$(ipfs key gen --ipns-base=b36cid --type=rsa --size=2048 key_rsa) &&
20
-test_check_rsa2048_b36cid_peerid $PEERID
19
+PEERID=$(ipfs key gen --ipns-base=base36 --type=rsa --size=2048 key_rsa) &&
20
+test_check_rsa2048_base36_peerid $PEERID
21
'
22
23
test_expect_success "test RSA key sk export format" '
@@ -29,8 +29,8 @@ rm key_rsa.key
29
test_expect_success "test RSA key B58MH/B36CID multihash format" '
30
PEERID=$(ipfs key list --ipns-base=b58mh -l | grep key_rsa | head -n 1 | cut -d " " -f1) &&
31
test_check_rsa2048_b58mh_peerid $PEERID &&
32
-PEERID=$(ipfs key list --ipns-base=b36cid -l | grep key_rsa | head -n 1 | cut -d " " -f1) &&
33
-test_check_rsa2048_b36cid_peerid $PEERID &&
32
+PEERID=$(ipfs key list --ipns-base=base36 -l | grep key_rsa | head -n 1 | cut -d " " -f1) &&
33
+test_check_rsa2048_base36_peerid $PEERID &&
34
ipfs key rm key_rsa
35
'
36
@@ -38,8 +38,8 @@ test_expect_success "create an ED25519 key and test B58MH/B36CID output formats"
38
PEERID=$(ipfs key gen --ipns-base=b58mh --type=ed25519 key_ed25519) &&
39
test_check_ed25519_b58mh_peerid $PEERID &&
40
ipfs key rm key_ed25519 &&
41
-PEERID=$(ipfs key gen --ipns-base=b36cid --type=ed25519 key_ed25519) &&
42
-test_check_ed25519_b36cid_peerid $PEERID
41
+PEERID=$(ipfs key gen --ipns-base=base36 --type=ed25519 key_ed25519) &&
42
+test_check_ed25519_base36_peerid $PEERID
43
'
44
45
test_expect_success "test ED25519 key sk export format" '
@@ -51,8 +51,8 @@ rm key_ed25519.key
51
test_expect_success "test ED25519 key B58MH/B36CID multihash format" '
52
PEERID=$(ipfs key list --ipns-base=b58mh -l | grep key_ed25519 | head -n 1 | cut -d " " -f1) &&
53
test_check_ed25519_b58mh_peerid $PEERID &&
54
-PEERID=$(ipfs key list --ipns-base=b36cid -l | grep key_ed25519 | head -n 1 | cut -d " " -f1) &&
55
-test_check_ed25519_b36cid_peerid $PEERID &&
54
+PEERID=$(ipfs key list --ipns-base=base36 -l | grep key_ed25519 | head -n 1 | cut -d " " -f1) &&
55
+test_check_ed25519_base36_peerid $PEERID &&
56
ipfs key rm key_ed25519
57
'
58
# end of format test
test/sharness/t0600-issues-and-regressions-online.sh
+1
-1
@@ -62,7 +62,7 @@ test_expect_success "ipfs daemon --offline --mount fails - #2995" '
62
test_launch_ipfs_daemon --offline
63
64
test_expect_success "'ipfs name resolve' succeeds after ipfs id when daemon offline" '
65
- PEERID=`ipfs key list --ipns-base=b36cid -l | grep self | cut -d " " -f1` &&
65
+ PEERID=`ipfs key list --ipns-base=base36 -l | grep self | cut -d " " -f1` &&
66
test_check_peerid "${PEERID}" &&
67
ipfs name publish --allow-offline -Q "/ipfs/$HASH_WELCOME_DOCS" >publish_out
68
'