diff --git a/whisper/shhapi/api.go b/whisper/shhapi/api.go index f33ede14e3..74d819e4d7 100644 --- a/whisper/shhapi/api.go +++ b/whisper/shhapi/api.go @@ -156,7 +156,6 @@ func (api *PublicWhisperAPI) NewFilter(args WhisperFilterArgs) (*rpc.HexNumber, filter := whisperv5.Filter{ Src: crypto.ToECDSAPub(args.From), - Dst: crypto.ToECDSAPub(args.To), KeySym: api.whisper.GetSymKey(args.KeyName), PoW: args.PoW, Messages: make(map[common.Hash]*whisperv5.ReceivedMessage), @@ -196,12 +195,13 @@ func (api *PublicWhisperAPI) NewFilter(args WhisperFilterArgs) (*rpc.HexNumber, } if len(args.To) > 0 { - if !whisperv5.ValidatePublicKey(filter.Dst) { + dst := crypto.ToECDSAPub(args.To) + if !whisperv5.ValidatePublicKey(dst) { info := "NewFilter: Invalid 'To' address" glog.V(logger.Error).Infof(info) return nil, errors.New(info) } - filter.KeyAsym = api.whisper.GetIdentity(filter.Dst) + filter.KeyAsym = api.whisper.GetIdentity(dst) if filter.KeyAsym == nil { info := "NewFilter: non-existent identity provided" glog.V(logger.Error).Infof(info) @@ -295,9 +295,6 @@ func (api *PublicWhisperAPI) Post(args PostArgs) error { if params.KeySym == nil && filter.KeySym != nil { params.KeySym = filter.KeySym } - if params.Dst == nil && filter.Dst != nil { - params.Dst = filter.Dst - } if params.Src == nil && filter.Src != nil { params.Src = filter.KeyAsym } diff --git a/whisper/whisperv5/envelope.go b/whisper/whisperv5/envelope.go index dbd1197ac1..426aa38e82 100644 --- a/whisper/whisperv5/envelope.go +++ b/whisper/whisperv5/envelope.go @@ -207,7 +207,7 @@ func (e *Envelope) Open(watcher *Filter) (msg *ReceivedMessage) { if e.isAsymmetric() { msg, _ = e.OpenAsymmetric(watcher.KeyAsym) if msg != nil { - msg.Dst = watcher.Dst + msg.Dst = &watcher.KeyAsym.PublicKey } } else if e.IsSymmetric() { msg, _ = e.OpenSymmetric(watcher.KeySym) diff --git a/whisper/whisperv5/filter.go b/whisper/whisperv5/filter.go index 057e5741a0..3ca1c84472 100644 --- a/whisper/whisperv5/filter.go +++ b/whisper/whisperv5/filter.go @@ -25,7 +25,6 @@ import ( type Filter struct { Src *ecdsa.PublicKey // Sender of the message - Dst *ecdsa.PublicKey // Recipient of the message KeyAsym *ecdsa.PrivateKey // Private Key of recipient KeySym []byte // Key associated with the Topic Topics []TopicType // Topics to filter messages with @@ -142,7 +141,7 @@ func (f *Filter) MatchMessage(msg *ReceivedMessage) bool { if f.expectsAsymmetricEncryption() && msg.isAsymmetricEncryption() { // if Dst match, ignore the topic - return isPubKeyEqual(f.Dst, msg.Dst) + return isPubKeyEqual(&f.KeyAsym.PublicKey, msg.Dst) } else if f.expectsSymmetricEncryption() && msg.isSymmetricEncryption() { // check if that both the key and the topic match if f.SymKeyHash == msg.SymKeyHash { diff --git a/whisper/whisperv5/message_test.go b/whisper/whisperv5/message_test.go index 5e1e5e40a7..3e6fc701cd 100644 --- a/whisper/whisperv5/message_test.go +++ b/whisper/whisperv5/message_test.go @@ -30,16 +30,14 @@ func copyFromBuf(dst []byte, src []byte, beg int) int { return beg + len(dst) } -func generateMessageParams(seed int64) (*MessageParams, error) { - var err error - var p MessageParams - +func generateMessageParams() (*MessageParams, error) { buf := make([]byte, 1024) - _, err = rand.Read(buf) + _, err := rand.Read(buf) if err != nil { return nil, err } + var p MessageParams p.TTL = uint32(rand.Intn(1024)) sz := rand.Intn(400) p.Payload = make([]byte, sz) @@ -62,7 +60,7 @@ func generateMessageParams(seed int64) (*MessageParams, error) { } func singleMessageTest(x *testing.T, seed int64, symmetric bool) { - params, err := generateMessageParams(seed) + params, err := generateMessageParams() if err != nil { x.Errorf("failed generateMessageParams with seed %d: %s.", seed, err) return @@ -149,7 +147,7 @@ func TestMessageWrap(x *testing.T) { rand.Seed(seed) target := 128.0 - params, err := generateMessageParams(seed) + params, err := generateMessageParams() if err != nil { x.Errorf("failed generateMessageParams with seed %d: %s.", seed, err) return @@ -176,7 +174,7 @@ func TestMessageSeal(x *testing.T) { seed := int64(1976726903) rand.Seed(seed) - params, err := generateMessageParams(seed) + params, err := generateMessageParams() if err != nil { x.Errorf("failed generateMessageParams with seed %d: %s.", seed, err) return @@ -227,3 +225,99 @@ func TestMessageSeal(x *testing.T) { return } } + +func TestEnvelopeOpen(x *testing.T) { + seed := time.Now().Unix() + rand.Seed(seed) + var symmetric bool + + for i := 0; i < 256; i++ { + singleEnvelopeOpenTest(x, seed, symmetric) + symmetric = !symmetric + } +} + +func singleEnvelopeOpenTest(x *testing.T, seed int64, symmetric bool) { + params, err := generateMessageParams() + if err != nil { + x.Errorf("failed generateMessageParams with seed %d: %s.", seed, err) + return + } + + key, err := crypto.GenerateKey() + if err != nil { + x.Errorf("failed GenerateKey with seed %d: %s.", seed, err) + return + } + + if !symmetric { + params.KeySym = nil + params.Dst = &key.PublicKey + } + + text := make([]byte, 0, 512) + steg := make([]byte, 0, 512) + raw := make([]byte, 0, 1024) + text = append(text, params.Payload...) + steg = append(steg, params.Padding...) + raw = append(raw, params.Padding...) + + msg := NewSentMessage(params) + env, err := msg.Wrap(params) + if err != nil { + x.Errorf("failed Wrap with seed %d: %s.", seed, err) + return + } + + f := Filter{KeyAsym: key, KeySym: params.KeySym} + decrypted := env.Open(&f) + if decrypted == nil { + x.Errorf("failed to open with seed %d.", seed) + return + } + + if !decrypted.Validate() { + x.Errorf("failed to validate with seed %d.", seed) + return + } + + padsz := len(decrypted.Padding) + if bytes.Compare(steg[:padsz], decrypted.Padding) != 0 { + x.Errorf("failed with seed %d: compare padding.", seed) + return + } + if bytes.Compare(text, decrypted.Payload) != 0 { + x.Errorf("failed with seed %d: compare payload.", seed) + return + } + if !isMessageSigned(decrypted.Raw[0]) { + x.Errorf("failed with seed %d: unsigned.", seed) + return + } + if len(decrypted.Signature) != signatureLength { + x.Errorf("failed with seed %d: signature len %d.", seed, len(decrypted.Signature)) + return + } + if !isPubKeyEqual(decrypted.Src, ¶ms.Src.PublicKey) { + x.Errorf("failed with seed %d: signature mismatch.", seed) + return + } + if decrypted.isAsymmetricEncryption() == symmetric { + x.Errorf("failed with seed %d: asymmetric %v vs. %v.", seed, decrypted.isAsymmetricEncryption(), symmetric) + return + } + if decrypted.isSymmetricEncryption() != symmetric { + x.Errorf("failed with seed %d: symmetric %v vs. %v.", seed, decrypted.isSymmetricEncryption(), symmetric) + return + } + if !symmetric { + if decrypted.Dst == nil { + x.Errorf("failed with seed %d: dst is nil.", seed) + return + } + if !isPubKeyEqual(decrypted.Dst, &key.PublicKey) { + x.Errorf("failed with seed %d: Dst.", seed) + return + } + } +}