// getLocal attempts to retrieve the value from the datastore func (dht *IpfsDHT) getLocal(key key.Key) ([]byte, error) { log.Debug("getLocal %s", key) v, err := dht.datastore.Get(key.DsKey()) if err != nil { return nil, err } log.Debug("found in db") byt, ok := v.([]byte) if !ok { return nil, errors.New("value stored in datastore not []byte") } rec := new(pb.Record) err = proto.Unmarshal(byt, rec) if err != nil { return nil, err } // TODO: 'if paranoid' if u.Debug { err = dht.verifyRecordLocally(rec) if err != nil { log.Debugf("local record verify failed: %s (discarded)", err) return nil, err } } return rec.GetValue(), nil }
func verify(ps peer.Peerstore, r *dhtpb.Record) error { v := make(record.Validator) v["pk"] = record.PublicKeyValidator p := peer.ID(r.GetAuthor()) pk := ps.PubKey(p) if pk == nil { return fmt.Errorf("do not have public key for %s", p) } if err := record.CheckRecordSig(r, pk); err != nil { return err } if err := v.VerifyRecord(r); err != nil { return err } return nil }
func (c *offlineRouting) GetValue(ctx context.Context, key key.Key) ([]byte, error) { v, err := c.datastore.Get(key.DsKey()) if err != nil { return nil, err } byt, ok := v.([]byte) if !ok { return nil, errors.New("value stored in datastore not []byte") } rec := new(pb.Record) err = proto.Unmarshal(byt, rec) if err != nil { return nil, err } return rec.GetValue(), nil }
// VerifyRecord checks a record and ensures it is still valid. // It runs needed validators func (v Validator) VerifyRecord(r *pb.Record) error { // Now, check validity func parts := strings.Split(r.GetKey(), "/") if len(parts) < 3 { log.Infof("Record key does not have validator: %s", key.Key(r.GetKey())) return nil } val, ok := v[parts[1]] if !ok { log.Infof("Unrecognized key prefix: %s", parts[1]) return ErrInvalidRecordType } return val.Func(key.Key(r.GetKey()), r.GetValue()) }
// MakePutRecord creates and signs a dht record for the given key/value pair func MakePutRecord(sk ci.PrivKey, key key.Key, value []byte, sign bool) (*pb.Record, error) { record := new(pb.Record) record.Key = proto.String(string(key)) record.Value = value pkh, err := sk.GetPublic().Hash() if err != nil { return nil, err } record.Author = proto.String(string(pkh)) if sign { blob := RecordBlobForSig(record) sig, err := sk.Sign(blob) if err != nil { return nil, err } record.Signature = sig } return record, nil }
// RecordBlobForSig returns the blob protected by the record signature func RecordBlobForSig(r *pb.Record) []byte { k := []byte(r.GetKey()) v := []byte(r.GetValue()) a := []byte(r.GetAuthor()) return bytes.Join([][]byte{k, v, a}, []byte{}) }