提交 1b5fbb09 作者: Łukasz Magiera

coreapi: Keystore API proposal

License: MIT
Signed-off-by: 's avatarŁukasz Magiera <magik6k@gmail.com>
上级 027f498b
...@@ -33,6 +33,10 @@ func (api *CoreAPI) Name() coreiface.NameAPI { ...@@ -33,6 +33,10 @@ func (api *CoreAPI) Name() coreiface.NameAPI {
return (*NameAPI)(api) return (*NameAPI)(api)
} }
func (api *CoreAPI) Key() coreiface.KeyAPI {
return (*KeyAPI)(api)
}
func (api *CoreAPI) ResolveNode(ctx context.Context, p coreiface.Path) (coreiface.Node, error) { func (api *CoreAPI) ResolveNode(ctx context.Context, p coreiface.Path) (coreiface.Node, error) {
p, err := api.ResolvePath(ctx, p) p, err := api.ResolvePath(ctx, p)
if err != nil { if err != nil {
......
...@@ -44,6 +44,7 @@ type CoreAPI interface { ...@@ -44,6 +44,7 @@ type CoreAPI interface {
Unixfs() UnixfsAPI Unixfs() UnixfsAPI
Dag() DagAPI Dag() DagAPI
Name() NameAPI Name() NameAPI
Key() KeyAPI
// ResolvePath resolves the path using Unixfs resolver // ResolvePath resolves the path using Unixfs resolver
ResolvePath(context.Context, Path) (Path, error) ResolvePath(context.Context, Path) (Path, error)
...@@ -102,11 +103,11 @@ type NameAPI interface { ...@@ -102,11 +103,11 @@ type NameAPI interface {
Resolve(ctx context.Context, name string, recursive bool, local bool, nocache bool) (Path, error) Resolve(ctx context.Context, name string, recursive bool, local bool, nocache bool) (Path, error)
} }
type KeyApi interface { type KeyAPI interface {
Generate(ctx context.Context, name string, algorithm string, size int) error Generate(ctx context.Context, name string, algorithm string, size int) (string, error)
List(ctx context.Context) (map[string]string, error) //TODO: better key type? List(ctx context.Context) (map[string]string, error) //TODO: better key type?
Rename(ctx context.Context, oldName string, newName string) error Rename(ctx context.Context, oldName string, newName string, force bool) (string, bool, error)
Remove(ctx context.Context, name string) error Remove(ctx context.Context, name string) (string, error)
} }
// type ObjectAPI interface { // type ObjectAPI interface {
......
package coreapi
import (
"context"
"crypto/rand"
"fmt"
"sort"
coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface"
peer "gx/ipfs/QmXYjuNuxVzXKJCfWasQk1RqkhVLDM9jtUKhqc2WPQmFSB/go-libp2p-peer"
crypto "gx/ipfs/QmaPbCnUMBohSGo3KnxEa2bHqyJVVeEEcwtqJAYxerieBo/go-libp2p-crypto"
)
type KeyAPI CoreAPI
func (api *KeyAPI) Generate(ctx context.Context, name string, algorithm string, size int) (string, error) {
var sk crypto.PrivKey
var pk crypto.PubKey
switch algorithm {
case "rsa":
if size == 0 {
return "", fmt.Errorf("please specify a key size with --size")
}
priv, pub, err := crypto.GenerateKeyPairWithReader(crypto.RSA, size, rand.Reader)
if err != nil {
return "", err
}
sk = priv
pk = pub
case "ed25519":
priv, pub, err := crypto.GenerateEd25519Key(rand.Reader)
if err != nil {
return "", err
}
sk = priv
pk = pub
default:
return "", fmt.Errorf("unrecognized key type: %s", algorithm)
}
err := api.node.Repo.Keystore().Put(name, sk)
if err != nil {
return "", err
}
pid, err := peer.IDFromPublicKey(pk)
if err != nil {
return "", err
}
return pid.String(), nil
}
func (api *KeyAPI) List(ctx context.Context) (map[string]string, error) {
keys, err := api.node.Repo.Keystore().List()
if err != nil {
return nil, err
}
sort.Strings(keys)
out := make(map[string]string, len(keys)+1)
out["self"] = api.node.Identity.Pretty()
for _, key := range keys {
privKey, err := api.node.Repo.Keystore().Get(key)
if err != nil {
return nil, err
}
pubKey := privKey.GetPublic()
pid, err := peer.IDFromPublicKey(pubKey)
if err != nil {
return nil, err
}
out[key] = pid.Pretty()
}
return out, nil
}
func (api *KeyAPI) Rename(ctx context.Context, oldName string, newName string, force bool) (string, bool, error) {
ks := api.node.Repo.Keystore()
if oldName == "self" {
return "", false, fmt.Errorf("cannot rename key with name 'self'")
}
if newName == "self" {
return "", false, fmt.Errorf("cannot overwrite key with name 'self'")
}
oldKey, err := ks.Get(oldName)
if err != nil {
return "", false, fmt.Errorf("no key named %s was found", oldName)
}
pubKey := oldKey.GetPublic()
pid, err := peer.IDFromPublicKey(pubKey)
if err != nil {
return "", false, err
}
overwrite := false
if force {
exist, err := ks.Has(newName)
if err != nil {
return "", false, err
}
if exist {
overwrite = true
err := ks.Delete(newName)
if err != nil {
return "", false, err
}
}
}
err = ks.Put(newName, oldKey)
if err != nil {
return "", false, err
}
return pid.Pretty(), overwrite, ks.Delete(oldName)
}
func (api *KeyAPI) Remove(ctx context.Context, name string) (string, error) {
ks := api.node.Repo.Keystore()
if name == "self" {
return "", fmt.Errorf("cannot remove key with name 'self'")
}
removed, err := ks.Get(name)
if err != nil {
return "", fmt.Errorf("no key named %s was found", name)
}
pubKey := removed.GetPublic()
pid, err := peer.IDFromPublicKey(pubKey)
if err != nil {
return "", err
}
err = ks.Delete(name)
if err != nil {
return "", err
}
return pid.Pretty(), nil
}
func (api *KeyAPI) core() coreiface.CoreAPI {
return (*CoreAPI)(api)
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论