1
0
mirror of https://github.com/ipfs/kubo.git synced 2025-09-10 05:52:20 +08:00
Files
kubo/namesys/routing.go

78 lines
1.8 KiB
Go

package namesys
import (
"fmt"
"time"
"code.google.com/p/goprotobuf/proto"
ci "github.com/jbenet/go-ipfs/crypto"
mdag "github.com/jbenet/go-ipfs/merkledag"
"github.com/jbenet/go-ipfs/routing"
u "github.com/jbenet/go-ipfs/util"
mh "github.com/jbenet/go-multihash"
)
// RoutingName is the de-serialized name structure that is stored (serialized)
// in the routing system. Basically, a hash + a digital signature. (serialization can be
// protobuf, or a simple binary format)
type RoutingName struct {
Hash u.Key
Signature []byte
}
// RoutingResolver implements NSResolver for the main IPFS SFS-like naming
type RoutingResolver struct {
routing routing.IpfsRouting
dag mdag.DAGService
}
func (r *RoutingResolver) Resolve(name string) (string, error) {
hash, err := mh.FromB58String(name)
if err != nil {
return "", err
}
// name should be a multihash. if it isn't, error out here.
// use the routing system to get the name.
// /ipns/<name>
h, err := u.Hash([]byte("ipns:" + name))
if err != nil {
return "", err
}
inpsKey := u.Key(h)
val, err := r.routing.GetValue(inpsKey, time.Second*10)
if err != nil {
return "", err
}
entry := new(InpsEntry)
err = proto.Unmarshal(val, entry)
if err != nil {
return "", err
}
// name should be a public key retrievable from ipfs
// /ipfs/<name>
key := u.Key(hash)
node, err := r.dag.Get(key)
if err != nil {
return "", err
}
// get PublicKey from node.Data
pk, err := ci.UnmarshalPublicKey(node.Data)
if err != nil {
return "", err
}
// check sig with pk
if ok, err := pk.Verify(entry.GetValue(), entry.GetSignature()); err != nil && ok {
return "", fmt.Errorf("Invalid value. Not signed by PrivateKey corresponding to %v", pk)
}
// ok sig checks out. this is a valid name.
return string(entry.GetValue()), nil
}