add Seq field to envelope signature

This commit is contained in:
Yusef Napora 2020-01-07 13:49:44 -05:00
parent 25c1a5dcd2
commit ce6885c21e
2 changed files with 29 additions and 5 deletions

View File

@ -52,7 +52,8 @@ func MakeEnvelope(privateKey crypto.PrivKey, domain string, payloadType []byte,
return nil, ErrEmptyDomain
}
unsigned, err := makeUnsigned(domain, payloadType, payload)
seq := statelessSeqNo()
unsigned, err := makeUnsigned(domain, payloadType, payload, seq)
if err != nil {
return nil, err
}
@ -67,7 +68,7 @@ func MakeEnvelope(privateKey crypto.PrivKey, domain string, payloadType []byte,
PublicKey: privateKey.GetPublic(),
PayloadType: payloadType,
Payload: payload,
Seq: statelessSeqNo(),
Seq: seq,
signature: sig,
}, nil
}
@ -141,7 +142,7 @@ func (e *SignedEnvelope) Equal(other *SignedEnvelope) bool {
// validate returns true if the envelope signature is valid for the given 'domain',
// or false if it is invalid. May return an error if signature validation fails.
func (e *SignedEnvelope) validate(domain string) error {
unsigned, err := makeUnsigned(domain, e.PayloadType, e.Payload)
unsigned, err := makeUnsigned(domain, e.PayloadType, e.Payload, e.Seq)
if err != nil {
return err
}
@ -160,9 +161,10 @@ func (e *SignedEnvelope) validate(domain string) error {
// makeUnsigned is a helper function that prepares a buffer to sign or verify.
// It returns a byte slice from a pool. The caller MUST return this slice to the
// pool.
func makeUnsigned(domain string, payloadType []byte, payload []byte) ([]byte, error) {
func makeUnsigned(domain string, payloadType []byte, payload []byte, seq uint64) ([]byte, error) {
var (
fields = [][]byte{[]byte(domain), payloadType, payload}
seqBytes = varint.ToUvarint(seq)
fields = [][]byte{[]byte(domain), payloadType, seqBytes, payload}
// fields are prefixed with their length as an unsigned varint. we
// compute the lengths before allocating the sig buffer so we know how

View File

@ -128,6 +128,28 @@ func TestEnvelopeValidateFailsIfContentsAreAltered(t *testing.T) {
test.ExpectError(t, err, "should not be able to open envelope with modified payload")
}
func TestEnvelopeValidateFailsIfSeqIsAltered(t *testing.T) {
var (
payload = []byte("happy hacking")
domain = "libp2p-testing"
payloadType = []byte("/libp2p/testdata")
priv, _, err = test.RandTestKeyPair(crypto.Ed25519, 256)
)
test.AssertNilError(t, err)
envelope, err := MakeEnvelope(priv, domain, payloadType, payload)
test.AssertNilError(t, err)
serialized := alterMessageAndMarshal(t, envelope, func(msg *pb.SignedEnvelope) {
msg.Seq = envelope.Seq + 1
})
// try to open our modified envelope
_, err = ConsumeEnvelope(serialized, domain)
test.ExpectError(t, err, "should not be able to open envelope with modified seq field")
}
// Since we're outside of the crypto package (to avoid import cycles with test package),
// we can't alter the fields in a SignedEnvelope directly. This helper marshals
// the envelope to a protobuf and calls the alterMsg function, which should