// VerifyAndSetPrivKey sets private key, given its pubkey matches the peer.ID func (p *peer) VerifyAndSetPrivKey(sk ic.PrivKey) error { // construct and assign pubkey. ensure it matches this peer if err := p.VerifyAndSetPubKey(sk.GetPublic()); err != nil { return err } p.Lock() defer p.Unlock() // if we didn't have the priavte key, assign it if p.privKey == nil { p.privKey = sk return nil } // if we already had the keys, check they're equal. if p.privKey.Equals(sk) { return nil // as expected. keep the old objects. } // keys not equal. invariant violated. this warrants a panic. // these keys should be _the same_ because peer.ID = H(pk) // this mismatch should never happen. log.Errorf("%s had PrivKey: %v -- got %v", p, p.privKey, sk) panic("invariant violated: unexpected key mismatch") }
func createRoutingEntryData(pk ci.PrivKey, val string) ([]byte, error) { entry := new(pb.IpnsEntry) entry.Value = []byte(val) typ := pb.IpnsEntry_EOL entry.ValidityType = &typ entry.Validity = []byte(u.FormatRFC3339(time.Now().Add(time.Hour * 24))) sig, err := pk.Sign(ipnsEntryDataForSig(entry)) if err != nil { return nil, err } entry.Signature = sig return proto.Marshal(entry) }
// Publish implements Publisher. Accepts a keypair and a value, // and publishes it out to the routing system func (p *ipnsPublisher) Publish(k ci.PrivKey, value string) error { log.Debugf("namesys: Publish %s", value) // validate `value` is a ref (multihash) _, err := mh.FromB58String(value) if err != nil { log.Errorf("hash cast failed: %s", value) return fmt.Errorf("publish value must be str multihash. %v", err) } ctx := context.TODO() data, err := createRoutingEntryData(k, value) if err != nil { log.Error("entry creation failed.") return err } pubkey := k.GetPublic() pkbytes, err := pubkey.Bytes() if err != nil { log.Error("pubkey getbytes failed.") return err } nameb := u.Hash(pkbytes) namekey := u.Key("/pk/" + string(nameb)) log.Debugf("Storing pubkey at: %s", namekey) // Store associated public key timectx, _ := context.WithDeadline(ctx, time.Now().Add(time.Second*4)) err = p.routing.PutValue(timectx, namekey, pkbytes) if err != nil { return err } ipnskey := u.Key("/ipns/" + string(nameb)) log.Debugf("Storing ipns entry at: %s", ipnskey) // Store ipns entry at "/ipns/"+b58(h(pubkey)) timectx, _ = context.WithDeadline(ctx, time.Now().Add(time.Second*4)) err = p.routing.PutValue(timectx, ipnskey, data) if err != nil { return err } return nil }
func publish(n *core.IpfsNode, k crypto.PrivKey, ref string) (*IpnsEntry, error) { pub := nsys.NewRoutingPublisher(n.Routing) err := pub.Publish(k, ref) if err != nil { return nil, err } hash, err := k.GetPublic().Hash() if err != nil { return nil, err } return &IpnsEntry{ Name: u.Key(hash).String(), Value: ref, }, nil }
// WithKeyPair returns a Peer object with given keys. func WithKeyPair(sk ic.PrivKey, pk ic.PubKey) (Peer, error) { if sk == nil && pk == nil { return nil, fmt.Errorf("PeerWithKeyPair nil keys") } pk2 := sk.GetPublic() if pk == nil { pk = pk2 } else if !pk.Equals(pk2) { return nil, fmt.Errorf("key mismatch. pubkey is not privkey's pubkey") } pkid, err := IDFromPubKey(pk) if err != nil { return nil, fmt.Errorf("Failed to hash public key: %v", err) } return &peer{id: pkid, pubKey: pk, privKey: sk}, nil }