diff --git a/whisper/whisperv6/envelope.go b/whisper/whisperv6/envelope.go index 26d2c2af12..e7ef36a24b 100644 --- a/whisper/whisperv6/envelope.go +++ b/whisper/whisperv6/envelope.go @@ -208,17 +208,18 @@ func (e *Envelope) OpenSymmetric(key []byte) (msg *ReceivedMessage, err error) { // Open tries to decrypt an envelope, and populates the message fields in case of success. func (e *Envelope) Open(watcher *Filter) (msg *ReceivedMessage) { - // if the filter has some asymmetric key provided, it will - // attempt to open it asymmetrically. If this fails, then - // attempt to open it symmetrically. + // The API interface forbids filters doing both symmetric and + // asymmetric encryption. + if watcher.expectsAsymmetricEncryption() && watcher.expectsSymmetricEncryption() { + return nil + } + if watcher.expectsAsymmetricEncryption() { msg, _ = e.OpenAsymmetric(watcher.KeyAsym) if msg != nil { msg.Dst = &watcher.KeyAsym.PublicKey } - } - - if msg == nil && watcher.expectsSymmetricEncryption() { + } else if watcher.expectsSymmetricEncryption() { msg, _ = e.OpenSymmetric(watcher.KeySym) if msg != nil { msg.SymKeyHash = crypto.Keccak256Hash(watcher.KeySym) diff --git a/whisper/whisperv6/envelope_test.go b/whisper/whisperv6/envelope_test.go new file mode 100644 index 0000000000..b0b8c9dbed --- /dev/null +++ b/whisper/whisperv6/envelope_test.go @@ -0,0 +1,64 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Contains the tests associated with the Whisper protocol Envelope object. + +package whisperv6 + +import ( + mrand "math/rand" + "testing" + + "github.com/ethereum/go-ethereum/crypto" +) + +func TestEnvelopeOpenAcceptsOnlyOneKeyTypeInFilter(t *testing.T) { + symKey := make([]byte, aesKeyLength) + mrand.Read(symKey) + + asymKey, err := crypto.GenerateKey() + if err != nil { + t.Fatalf("failed GenerateKey with seed %d: %s.", seed, err) + } + + params := MessageParams{ + PoW: 0.01, + WorkTime: 1, + TTL: uint32(mrand.Intn(1024)), + Payload: make([]byte, 50), + KeySym: symKey, + Dst: nil, + } + + mrand.Read(params.Payload) + + msg, err := NewSentMessage(¶ms) + if err != nil { + t.Fatalf("failed to create new message with seed %d: %s.", seed, err) + } + + e, err := msg.Wrap(¶ms) + if err != nil { + t.Fatalf("Failed to Wrap the message in an envelope with seed %d: %s", seed, err) + } + + f := Filter{KeySym: symKey, KeyAsym: asymKey} + + decrypted := e.Open(&f) + if decrypted != nil { + t.Fatalf("Managed to decrypt a message with an invalid filter, seed %d", seed) + } +} \ No newline at end of file diff --git a/whisper/whisperv6/filter.go b/whisper/whisperv6/filter.go index 2786f97a09..2f52dd6b98 100644 --- a/whisper/whisperv6/filter.go +++ b/whisper/whisperv6/filter.go @@ -53,6 +53,10 @@ func NewFilters(w *Whisper) *Filters { } func (fs *Filters) Install(watcher *Filter) (string, error) { + if watcher.KeySym != nil && watcher.KeyAsym != nil { + return "", fmt.Errorf("filters must choose between symmetric and asymmetric keys") + } + if watcher.Messages == nil { watcher.Messages = make(map[common.Hash]*ReceivedMessage) } diff --git a/whisper/whisperv6/filter_test.go b/whisper/whisperv6/filter_test.go index 652efc12e8..ff6c302c10 100644 --- a/whisper/whisperv6/filter_test.go +++ b/whisper/whisperv6/filter_test.go @@ -229,6 +229,36 @@ func TestInstallIdenticalFilters(t *testing.T) { } } +func TestInstallFilterWithSymAndAsymKeys(t *testing.T) { + InitSingleTest() + + w := New(&Config{}) + filters := NewFilters(w) + filter1, _ := generateFilter(t, true) + + asymKey, err := crypto.GenerateKey() + if err != nil { + t.Fatalf("Unable to create asymetric keys", err) + } + + // Copy the first filter since some of its fields + // are randomly gnerated. + filter := &Filter{ + KeySym: filter1.KeySym, + KeyAsym: asymKey, + Topics: filter1.Topics, + PoW: filter1.PoW, + AllowP2P: filter1.AllowP2P, + Messages: make(map[common.Hash]*ReceivedMessage), + } + + _, err = filters.Install(filter) + + if err == nil { + t.Fatalf("Error detecting that a filter had both an asymmetric and symmetric key, with seed %d", seed) + } +} + func TestComparePubKey(t *testing.T) { InitSingleTest() diff --git a/whisper/whisperv6/message_test.go b/whisper/whisperv6/message_test.go index f4c16b256f..281a852d67 100644 --- a/whisper/whisperv6/message_test.go +++ b/whisper/whisperv6/message_test.go @@ -240,7 +240,12 @@ func singleEnvelopeOpenTest(t *testing.T, symmetric bool) { t.Fatalf("failed Wrap with seed %d: %s.", seed, err) } - f := Filter{KeyAsym: key, KeySym: params.KeySym} + var f Filter + if symmetric { + f = Filter{KeySym: params.KeySym} + } else { + f = Filter{KeyAsym: key} + } decrypted := env.Open(&f) if decrypted == nil { t.Fatalf("failed to open with seed %d.", seed)