提交 281d5eaf 作者: Dirk McCormick 提交者: Steven Allen

Update ipns validator

License: MIT
Signed-off-by: 's avatarDirk McCormick <dirkmdev@gmail.com>
上级 8899e986
package namesys
import (
"testing"
"time"
path "github.com/ipfs/go-ipfs/path"
u "gx/ipfs/QmNiJuT8Ja3hMVpBHXv3Q6dwmperaQ6JjLtpMQgMCD7xvx/go-ipfs-util"
proto "gx/ipfs/QmZ4Qi3GaRbjcx28Sme5eMH7RQjGkt8wHxt2a65oLaeFEV/gogo-protobuf/proto"
ci "gx/ipfs/QmaPbCnUMBohSGo3KnxEa2bHqyJVVeEEcwtqJAYxerieBo/go-libp2p-crypto"
record "gx/ipfs/QmbsY8Pr6s3uZsKg7rzBtGDKeCtdoAhNaMTCXBUbvb1eCV/go-libp2p-record"
)
func TestValidation(t *testing.T) {
// Create a record validator
validator := make(record.Validator)
validator["ipns"] = &record.ValidChecker{ValidateIpnsRecord, true}
// Generate a key for signing the records
r := u.NewSeededRand(15) // generate deterministic keypair
priv, pubk, err := ci.GenerateKeyPairWithReader(ci.RSA, 1024, r)
if err != nil {
t.Fatal(err)
}
// Create entry with expiry in one hour
ts := time.Now()
entry, err := CreateRoutingEntryData(priv, path.Path("foo"), 1, ts.Add(time.Hour))
if err != nil {
t.Fatal(err)
}
// Get IPNS record path
pubkb, err := pubk.Bytes()
if err != nil {
t.Fatal(err)
}
pubkh := u.Hash(pubkb).B58String()
ipnsPath := "/ipns/" + pubkh
val, err := proto.Marshal(entry)
if err != nil {
t.Fatal(err)
}
// Create the record
r1, err := record.MakePutRecord(priv, ipnsPath, val, true)
// Validate the record
err = validator.VerifyRecord(r1)
if err != nil {
t.Fatal(err)
}
// Create IPNS record path with a different key
_, pubk2, err := ci.GenerateKeyPairWithReader(ci.RSA, 1024, r)
if err != nil {
t.Fatal(err)
}
pubkb2, err := pubk2.Bytes()
if err != nil {
t.Fatal(err)
}
pubkh2 := u.Hash(pubkb2).B58String()
ipnsWrongPath := "/ipns/" + pubkh2
r2, err := record.MakePutRecord(priv, ipnsWrongPath, val, true)
// Record should fail validation because path doesn't match author
err = validator.VerifyRecord(r2)
if err != ErrInvalidAuthor {
t.Fatal("ValidateIpnsRecord should have returned ErrInvalidAuthor")
}
// Create expired entry
expired, err := CreateRoutingEntryData(priv, path.Path("foo"), 1, ts.Add(-1*time.Hour))
if err != nil {
t.Fatal(err)
}
valExp, err := proto.Marshal(expired)
if err != nil {
t.Fatal(err)
}
// Create record with the expired entry
r3, err := record.MakePutRecord(priv, ipnsPath, valExp, true)
// Record should fail validation because entry is expired
err = validator.VerifyRecord(r3)
if err != ErrExpiredRecord {
t.Fatal("ValidateIpnsRecord should have returned ErrExpiredRecord")
}
}
......@@ -5,6 +5,7 @@ import (
"context"
"errors"
"fmt"
"strings"
"time"
pb "github.com/ipfs/go-ipfs/namesys/pb"
......@@ -31,6 +32,14 @@ var ErrExpiredRecord = errors.New("expired record")
// unknown validity type.
var ErrUnrecognizedValidity = errors.New("unrecognized validity type")
// ErrInvalidAuthor is returned when an IpnsRecord has an
// author that does not match the IPNS path
var ErrInvalidAuthor = errors.New("author does not match path")
// ErrInvalidPath should be returned when an ipns record path
// is not in a valid format
var ErrInvalidPath = errors.New("record path invalid")
const PublishPutValTimeout = time.Minute
const DefaultRecordTTL = 24 * time.Hour
......@@ -295,12 +304,31 @@ func selectRecord(recs []*pb.IpnsEntry, vals [][]byte) (int, error) {
// ValidateIpnsRecord implements ValidatorFunc and verifies that the
// given 'val' is an IpnsEntry and that that entry is valid.
func ValidateIpnsRecord(k string, val []byte) error {
func ValidateIpnsRecord(r *record.ValidationRecord) error {
if r.Namespace != "ipns" {
return ErrInvalidPath
}
entry := new(pb.IpnsEntry)
err := proto.Unmarshal(val, entry)
err := proto.Unmarshal(r.Value, entry)
if err != nil {
return err
}
// Note: The DHT will actually check the signature so we don't
// need to do that here
// Author in key must match author in record
parts := strings.Split(r.Key, "/")
pid, err := peer.IDB58Decode(parts[0])
if err != nil {
return ErrInvalidAuthor
}
if string(pid) != string(r.Author) {
return ErrInvalidAuthor
}
// Check that record has not expired
switch entry.GetValidityType() {
case pb.IpnsEntry_EOL:
t, err := u.ParseRFC3339(string(entry.GetValidity()))
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论