mirror of
https://github.com/ipfs/kubo.git
synced 2026-03-12 19:57:55 +08:00
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>
135 lines
3.7 KiB
Go
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
|
|
}
|