Skip to content

Commit c7a24a3

Browse files
authored
Merge pull request #7582 from ipfs/petar/keys
use b36 keys by default for keys and IPNS
2 parents 8ae5aa5 + 4975d9b commit c7a24a3

15 files changed

+197
-126
lines changed

core/commands/keyencode/keyencode.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package keyencode
2+
3+
import (
4+
peer "github.com/libp2p/go-libp2p-core/peer"
5+
mbase "github.com/multiformats/go-multibase"
6+
)
7+
8+
const IPNSKeyFormatOptionName = "ipns-base"
9+
10+
type KeyEncoder struct {
11+
baseEnc *mbase.Encoder
12+
}
13+
14+
func KeyEncoderFromString(formatLabel string) (KeyEncoder, error) {
15+
switch formatLabel {
16+
case "b58mh", "v0":
17+
return KeyEncoder{}, nil
18+
default:
19+
if enc, err := mbase.EncoderByName(formatLabel); err != nil {
20+
return KeyEncoder{}, err
21+
} else {
22+
return KeyEncoder{&enc}, nil
23+
}
24+
}
25+
}
26+
27+
func (enc KeyEncoder) FormatID(id peer.ID) string {
28+
if enc.baseEnc == nil {
29+
//nolint deprecated
30+
return peer.IDB58Encode(id)
31+
}
32+
if s, err := peer.ToCid(id).StringOfBase(enc.baseEnc.Encoding()); err != nil {
33+
panic(err)
34+
} else {
35+
return s
36+
}
37+
}

core/commands/keystore.go

Lines changed: 35 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ import (
1515
oldcmds "github.com/ipfs/go-ipfs/commands"
1616
cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv"
1717
"github.com/ipfs/go-ipfs/core/commands/e"
18+
ke "github.com/ipfs/go-ipfs/core/commands/keyencode"
1819
fsrepo "github.com/ipfs/go-ipfs/repo/fsrepo"
1920
options "github.com/ipfs/interface-go-ipfs-core/options"
2021
"github.com/libp2p/go-libp2p-core/crypto"
2122
peer "github.com/libp2p/go-libp2p-core/peer"
22-
mbase "github.com/multiformats/go-multibase"
2323
)
2424

2525
var KeyCmd = &cmds.Command{
@@ -68,11 +68,10 @@ type KeyRenameOutput struct {
6868
}
6969

7070
const (
71-
keyStoreAlgorithmDefault = options.RSAKey
72-
keyStoreTypeOptionName = "type"
73-
keyStoreSizeOptionName = "size"
74-
keyFormatOptionName = "format"
75-
oldKeyOptionName = "oldkey"
71+
keyStoreAlgorithmDefault = options.RSAKey
72+
keyStoreTypeOptionName = "type"
73+
keyStoreSizeOptionName = "size"
74+
oldKeyOptionName = "oldkey"
7675
)
7776

7877
var keyGenCmd = &cmds.Command{
@@ -82,7 +81,7 @@ var keyGenCmd = &cmds.Command{
8281
Options: []cmds.Option{
8382
cmds.StringOption(keyStoreTypeOptionName, "t", "type of the key to create: rsa, ed25519").WithDefault(keyStoreAlgorithmDefault),
8483
cmds.IntOption(keyStoreSizeOptionName, "s", "size of the key to generate"),
85-
cmds.StringOption(keyFormatOptionName, "f", "output format: b58mh or b36cid").WithDefault("b58mh"),
84+
cmds.StringOption(ke.IPNSKeyFormatOptionName, "", "Encoding used for keys: Can either be a multibase encoded CID or a base58btc encoded multihash. Takes {b58mh|base36|k|base32|b...}.").WithDefault("base36"),
8685
},
8786
Arguments: []cmds.Argument{
8887
cmds.StringArg("name", true, false, "name of key to create"),
@@ -109,7 +108,8 @@ var keyGenCmd = &cmds.Command{
109108
if sizefound {
110109
opts = append(opts, options.Key.Size(size))
111110
}
112-
if err = verifyIDFormatLabel(req.Options[keyFormatOptionName].(string)); err != nil {
111+
keyEnc, err := ke.KeyEncoderFromString(req.Options[ke.IPNSKeyFormatOptionName].(string))
112+
if err != nil {
113113
return err
114114
}
115115

@@ -121,7 +121,7 @@ var keyGenCmd = &cmds.Command{
121121

122122
return cmds.EmitOnce(res, &KeyOutput{
123123
Name: name,
124-
Id: formatID(key.ID(), req.Options[keyFormatOptionName].(string)),
124+
Id: keyEnc.FormatID(key.ID()),
125125
})
126126
},
127127
Encoders: cmds.EncoderMap{
@@ -223,7 +223,7 @@ var keyImportCmd = &cmds.Command{
223223
Tagline: "Import a key and prints imported key id",
224224
},
225225
Options: []cmds.Option{
226-
cmds.StringOption(keyFormatOptionName, "f", "output format: b58mh or b36cid").WithDefault("b58mh"),
226+
cmds.StringOption(ke.IPNSKeyFormatOptionName, "", "Encoding used for keys: Can either be a multibase encoded CID or a base58btc encoded multihash. Takes {b58mh|base36|k|base32|b...}.").WithDefault("base36"),
227227
},
228228
Arguments: []cmds.Argument{
229229
cmds.StringArg("name", true, false, "name to associate with key in keychain"),
@@ -236,6 +236,11 @@ var keyImportCmd = &cmds.Command{
236236
return fmt.Errorf("cannot import key with name 'self'")
237237
}
238238

239+
keyEnc, err := ke.KeyEncoderFromString(req.Options[ke.IPNSKeyFormatOptionName].(string))
240+
if err != nil {
241+
return err
242+
}
243+
239244
file, err := cmdenv.GetFileArg(req.Files.Entries())
240245
if err != nil {
241246
return err
@@ -280,7 +285,7 @@ var keyImportCmd = &cmds.Command{
280285

281286
return cmds.EmitOnce(res, &KeyOutput{
282287
Name: name,
283-
Id: formatID(pid, req.Options[keyFormatOptionName].(string)),
288+
Id: keyEnc.FormatID(pid),
284289
})
285290
},
286291
Encoders: cmds.EncoderMap{
@@ -298,10 +303,11 @@ var keyListCmd = &cmds.Command{
298303
},
299304
Options: []cmds.Option{
300305
cmds.BoolOption("l", "Show extra information about keys."),
301-
cmds.StringOption(keyFormatOptionName, "f", "output format: b58mh or b36cid").WithDefault("b58mh"),
306+
cmds.StringOption(ke.IPNSKeyFormatOptionName, "", "Encoding used for keys: Can either be a multibase encoded CID or a base58btc encoded multihash. Takes {b58mh|base36|k|base32|b...}.").WithDefault("base36"),
302307
},
303308
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
304-
if err := verifyIDFormatLabel(req.Options[keyFormatOptionName].(string)); err != nil {
309+
keyEnc, err := ke.KeyEncoderFromString(req.Options[ke.IPNSKeyFormatOptionName].(string))
310+
if err != nil {
305311
return err
306312
}
307313

@@ -320,7 +326,7 @@ var keyListCmd = &cmds.Command{
320326
for _, key := range keys {
321327
list = append(list, KeyOutput{
322328
Name: key.Name(),
323-
Id: formatID(key.ID(), req.Options[keyFormatOptionName].(string)),
329+
Id: keyEnc.FormatID(key.ID()),
324330
})
325331
}
326332

@@ -346,12 +352,17 @@ var keyRenameCmd = &cmds.Command{
346352
},
347353
Options: []cmds.Option{
348354
cmds.BoolOption(keyStoreForceOptionName, "f", "Allow to overwrite an existing key."),
355+
cmds.StringOption(ke.IPNSKeyFormatOptionName, "", "Encoding used for keys: Can either be a multibase encoded CID or a base58btc encoded multihash. Takes {b58mh|base36|k|base32|b...}.").WithDefault("base36"),
349356
},
350357
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
351358
api, err := cmdenv.GetApi(env, req)
352359
if err != nil {
353360
return err
354361
}
362+
keyEnc, err := ke.KeyEncoderFromString(req.Options[ke.IPNSKeyFormatOptionName].(string))
363+
if err != nil {
364+
return err
365+
}
355366

356367
name := req.Arguments[0]
357368
newName := req.Arguments[1]
@@ -365,7 +376,7 @@ var keyRenameCmd = &cmds.Command{
365376
return cmds.EmitOnce(res, &KeyRenameOutput{
366377
Was: name,
367378
Now: newName,
368-
Id: key.ID().Pretty(),
379+
Id: keyEnc.FormatID(key.ID()),
369380
Overwrite: overwritten,
370381
})
371382
},
@@ -391,12 +402,17 @@ var keyRmCmd = &cmds.Command{
391402
},
392403
Options: []cmds.Option{
393404
cmds.BoolOption("l", "Show extra information about keys."),
405+
cmds.StringOption(ke.IPNSKeyFormatOptionName, "", "Encoding used for keys: Can either be a multibase encoded CID or a base58btc encoded multihash. Takes {b58mh|base36|k|base32|b...}.").WithDefault("base36"),
394406
},
395407
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
396408
api, err := cmdenv.GetApi(env, req)
397409
if err != nil {
398410
return err
399411
}
412+
keyEnc, err := ke.KeyEncoderFromString(req.Options[ke.IPNSKeyFormatOptionName].(string))
413+
if err != nil {
414+
return err
415+
}
400416

401417
names := req.Arguments
402418

@@ -407,7 +423,10 @@ var keyRmCmd = &cmds.Command{
407423
return err
408424
}
409425

410-
list = append(list, KeyOutput{Name: name, Id: key.ID().Pretty()})
426+
list = append(list, KeyOutput{
427+
Name: name,
428+
Id: keyEnc.FormatID(key.ID()),
429+
})
411430
}
412431

413432
return cmds.EmitOnce(res, &KeyOutputList{list})
@@ -517,31 +536,6 @@ func doRotate(out io.Writer, repoRoot string, oldKey string, algorithm string, n
517536
return nil
518537
}
519538

520-
func verifyIDFormatLabel(formatLabel string) error {
521-
switch formatLabel {
522-
case "b58mh":
523-
return nil
524-
case "b36cid":
525-
return nil
526-
}
527-
return fmt.Errorf("invalid output format option")
528-
}
529-
530-
func formatID(id peer.ID, formatLabel string) string {
531-
switch formatLabel {
532-
case "b58mh":
533-
return id.Pretty()
534-
case "b36cid":
535-
if s, err := peer.ToCid(id).StringOfBase(mbase.Base36); err != nil {
536-
panic(err)
537-
} else {
538-
return s
539-
}
540-
default:
541-
panic("unreachable")
542-
}
543-
}
544-
545539
func keyOutputListEncoders() cmds.EncoderFunc {
546540
return cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, list *KeyOutputList) error {
547541
withID, _ := req.Options["l"].(bool)

core/commands/name/ipnsps.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@ import (
55
"io"
66
"strings"
77

8-
"github.com/ipfs/go-ipfs-cmds"
8+
cmds "github.com/ipfs/go-ipfs-cmds"
99
"github.com/ipfs/go-ipfs/core/commands/cmdenv"
10+
ke "github.com/ipfs/go-ipfs/core/commands/keyencode"
1011
"github.com/libp2p/go-libp2p-core/peer"
11-
"github.com/libp2p/go-libp2p-record"
12+
record "github.com/libp2p/go-libp2p-record"
1213
)
1314

1415
type ipnsPubsubState struct {
@@ -72,7 +73,15 @@ var ipnspsSubsCmd = &cmds.Command{
7273
Helptext: cmds.HelpText{
7374
Tagline: "Show current name subscriptions",
7475
},
76+
Options: []cmds.Option{
77+
cmds.StringOption(ke.IPNSKeyFormatOptionName, "", "Encoding used for keys: Can either be a multibase encoded CID or a base58btc encoded multihash. Takes {b58mh|base36|k|base32|b...}.").WithDefault("base36"),
78+
},
7579
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
80+
keyEnc, err := ke.KeyEncoderFromString(req.Options[ke.IPNSKeyFormatOptionName].(string))
81+
if err != nil {
82+
return err
83+
}
84+
7685
n, err := cmdenv.GetNode(env)
7786
if err != nil {
7887
return err
@@ -93,7 +102,7 @@ var ipnspsSubsCmd = &cmds.Command{
93102
log.Errorf("ipns key not a valid peer ID: %s", err)
94103
continue
95104
}
96-
paths = append(paths, "/ipns/"+peer.Encode(pid))
105+
paths = append(paths, "/ipns/"+keyEnc.FormatID(pid))
97106
}
98107

99108
return cmds.EmitOnce(res, &stringList{paths})

core/commands/name/publish.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@ import (
99
cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv"
1010

1111
cmds "github.com/ipfs/go-ipfs-cmds"
12+
ke "github.com/ipfs/go-ipfs/core/commands/keyencode"
1213
iface "github.com/ipfs/interface-go-ipfs-core"
1314
options "github.com/ipfs/interface-go-ipfs-core/options"
1415
path "github.com/ipfs/interface-go-ipfs-core/path"
16+
peer "github.com/libp2p/go-libp2p-core/peer"
1517
)
1618

1719
var (
@@ -81,12 +83,17 @@ Alternatively, publish an <ipfs-path> using a valid PeerID (as listed by
8183
cmds.StringOption(ttlOptionName, "Time duration this record should be cached for. Uses the same syntax as the lifetime option. (caution: experimental)"),
8284
cmds.StringOption(keyOptionName, "k", "Name of the key to be used or a valid PeerID, as listed by 'ipfs key list -l'.").WithDefault("self"),
8385
cmds.BoolOption(quieterOptionName, "Q", "Write only final hash."),
86+
cmds.StringOption(ke.IPNSKeyFormatOptionName, "", "Encoding used for keys: Can either be a multibase encoded CID or a base58btc encoded multihash. Takes {b58mh|base36|k|base32|b...}.").WithDefault("base36"),
8487
},
8588
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
8689
api, err := cmdenv.GetApi(env, req)
8790
if err != nil {
8891
return err
8992
}
93+
keyEnc, err := ke.KeyEncoderFromString(req.Options[ke.IPNSKeyFormatOptionName].(string))
94+
if err != nil {
95+
return err
96+
}
9097

9198
allowOffline, _ := req.Options[allowOfflineOptionName].(bool)
9299
kname, _ := req.Options[keyOptionName].(string)
@@ -129,8 +136,14 @@ Alternatively, publish an <ipfs-path> using a valid PeerID (as listed by
129136
return err
130137
}
131138

139+
// parse path, extract cid, re-base cid, reconstruct path
140+
pid, err := peer.Decode(out.Name())
141+
if err != nil {
142+
return err
143+
}
144+
132145
return cmds.EmitOnce(res, &IpnsEntry{
133-
Name: out.Name(),
146+
Name: keyEnc.FormatID(pid),
134147
Value: out.Value().String(),
135148
})
136149
},

core/commands/resolve.go

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -82,23 +82,6 @@ Resolve the value of an IPFS DAG path:
8282
name := req.Arguments[0]
8383
recursive, _ := req.Options[resolveRecursiveOptionName].(bool)
8484

85-
var enc cidenc.Encoder
86-
switch {
87-
case !cmdenv.CidBaseDefined(req):
88-
// Not specified, check the path.
89-
enc, err = cmdenv.CidEncoderFromPath(name)
90-
if err == nil {
91-
break
92-
}
93-
// Nope, fallback on the default.
94-
fallthrough
95-
default:
96-
enc, err = cmdenv.GetCidEncoder(req)
97-
if err != nil {
98-
return err
99-
}
100-
}
101-
10285
// the case when ipns is resolved step by step
10386
if strings.HasPrefix(name, "/ipns/") && !recursive {
10487
rc, rcok := req.Options[resolveDhtRecordCountOptionName].(uint)
@@ -128,6 +111,23 @@ Resolve the value of an IPFS DAG path:
128111
return cmds.EmitOnce(res, &ncmd.ResolvedPath{Path: ipfspath.Path(p.String())})
129112
}
130113

114+
var enc cidenc.Encoder
115+
switch {
116+
case !cmdenv.CidBaseDefined(req) && !strings.HasPrefix(name, "/ipns/"):
117+
// Not specified, check the path.
118+
enc, err = cmdenv.CidEncoderFromPath(name)
119+
if err == nil {
120+
break
121+
}
122+
// Nope, fallback on the default.
123+
fallthrough
124+
default:
125+
enc, err = cmdenv.GetCidEncoder(req)
126+
if err != nil {
127+
return err
128+
}
129+
}
130+
131131
// else, ipfs path or ipns with recursive flag
132132
rp, err := api.ResolvePath(req.Context, path.New(name))
133133
if err != nil {

0 commit comments

Comments
 (0)