kubo/namesys/ipns_validate_test.go
Steven Allen 118ecb22cd remove new DHT record author check
We're going to just fix this a future commit. *This* change breaks publishing
IPNS records using alternative IPNS keys (because the author signature (peer ID)
differs from the record signature).

We're going to fix it by validating the IPNS signature and ditching the
author/signature fields.

License: MIT
Signed-off-by: Steven Allen <steven@stebalien.com>
2018-01-27 13:45:36 -08:00

135 lines
3.7 KiB
Go

package namesys
import (
"io"
"testing"
"time"
path "github.com/ipfs/go-ipfs/path"
u "gx/ipfs/QmNiJuT8Ja3hMVpBHXv3Q6dwmperaQ6JjLtpMQgMCD7xvx/go-ipfs-util"
proto "gx/ipfs/QmZ4Qi3GaRbjcx28Sme5eMH7RQjGkt8wHxt2a65oLaeFEV/gogo-protobuf/proto"
peer "gx/ipfs/Qma7H6RW8wRrfZpNSXwxYGcd1E149s42FpWNpDNieSVrnU/go-libp2p-peer"
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{Func: ValidateIpnsRecord, Sign: true}
// Generate a key for signing the records
r := u.NewSeededRand(15) // generate deterministic keypair
priv, ipnsPath := genKeys(t, r)
// 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)
}
val, err := proto.Marshal(entry)
if err != nil {
t.Fatal(err)
}
// Create the record
rec, err := record.MakePutRecord(priv, ipnsPath, val, true)
if err != nil {
t.Fatal(err)
}
// Validate the record
err = validator.VerifyRecord(rec)
if err != nil {
t.Fatal(err)
}
/* TODO(#4613)
// Create IPNS record path with a different private key
_, ipnsWrongAuthor := genKeys(t, r)
wrongAuthorRec, err := record.MakePutRecord(priv, ipnsWrongAuthor, val, true)
if err != nil {
t.Fatal(err)
}
// Record should fail validation because path doesn't match author
err = validator.VerifyRecord(wrongAuthorRec)
if err != ErrInvalidAuthor {
t.Fatal("ValidateIpnsRecord should have returned ErrInvalidAuthor")
}
// Create IPNS record path with extra path components after author
extraPath := ipnsPath + "/some/path"
extraPathRec, err := record.MakePutRecord(priv, extraPath, val, true)
if err != nil {
t.Fatal(err)
}
// Record should fail validation because path has extra components after author
err = validator.VerifyRecord(extraPathRec)
if err != ErrInvalidAuthor {
t.Fatal("ValidateIpnsRecord should have returned ErrInvalidAuthor")
}
// Create unsigned IPNS record
unsignedRec, err := record.MakePutRecord(priv, ipnsPath, val, false)
if err != nil {
t.Fatal(err)
}
// Record should fail validation because IPNS records require signature
err = validator.VerifyRecord(unsignedRec)
if err != ErrInvalidAuthor {
t.Fatal("ValidateIpnsRecord should have returned ErrInvalidAuthor")
}
// Create unsigned IPNS record with no author
unsignedRecNoAuthor, err := record.MakePutRecord(priv, ipnsPath, val, false)
if err != nil {
t.Fatal(err)
}
noAuth := ""
unsignedRecNoAuthor.Author = &noAuth
// Record should fail validation because IPNS records require author
err = validator.VerifyRecord(unsignedRecNoAuthor)
if err != ErrInvalidAuthor {
t.Fatal("ValidateIpnsRecord should have returned ErrInvalidAuthor")
}
*/
// Create expired entry
expiredEntry, err := CreateRoutingEntryData(priv, path.Path("foo"), 1, ts.Add(-1*time.Hour))
if err != nil {
t.Fatal(err)
}
valExp, err := proto.Marshal(expiredEntry)
if err != nil {
t.Fatal(err)
}
// Create record with the expired entry
expiredRec, err := record.MakePutRecord(priv, ipnsPath, valExp, true)
// Record should fail validation because entry is expired
err = validator.VerifyRecord(expiredRec)
if err != ErrExpiredRecord {
t.Fatal("ValidateIpnsRecord should have returned ErrExpiredRecord")
}
}
func genKeys(t *testing.T, r io.Reader) (ci.PrivKey, string) {
priv, _, err := ci.GenerateKeyPairWithReader(ci.RSA, 1024, r)
if err != nil {
t.Fatal(err)
}
id, err := peer.IDFromPrivateKey(priv)
if err != nil {
t.Fatal(err)
}
_, ipnsKey := IpnsKeysForID(id)
return priv, ipnsKey
}