From fb12a4958993a01d7bc8525a43b370c775f96eb4 Mon Sep 17 00:00:00 2001 From: Vlad Date: Tue, 9 Jan 2018 17:22:07 +0200 Subject: [PATCH] whisper: message format changed --- whisper/whisperv6/envelope.go | 8 +--- whisper/whisperv6/message.go | 74 +++---------------------------- whisper/whisperv6/message_test.go | 12 ++--- 3 files changed, 13 insertions(+), 81 deletions(-) diff --git a/whisper/whisperv6/envelope.go b/whisper/whisperv6/envelope.go index 6cbefaef67..d7dac073a6 100644 --- a/whisper/whisperv6/envelope.go +++ b/whisper/whisperv6/envelope.go @@ -198,29 +198,25 @@ 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) { - // The API interface forbids filters doing both symmetric and - // asymmetric encryption. + // The API interface forbids filters doing both symmetric and asymmetric encryption. if watcher.expectsAsymmetricEncryption() && watcher.expectsSymmetricEncryption() { return nil } - var symmetric bool if watcher.expectsAsymmetricEncryption() { msg, _ = e.OpenAsymmetric(watcher.KeyAsym) if msg != nil { - symmetric = false msg.Dst = &watcher.KeyAsym.PublicKey } } else if watcher.expectsSymmetricEncryption() { msg, _ = e.OpenSymmetric(watcher.KeySym) if msg != nil { - symmetric = true msg.SymKeyHash = crypto.Keccak256Hash(watcher.KeySym) } } if msg != nil { - ok := msg.ValidateAndParse(symmetric) + ok := msg.ValidateAndParse() if !ok { return nil } diff --git a/whisper/whisperv6/message.go b/whisper/whisperv6/message.go index 09425f098f..45b33ec557 100644 --- a/whisper/whisperv6/message.go +++ b/whisper/whisperv6/message.go @@ -101,22 +101,13 @@ func NewSentMessage(params *MessageParams) (*sentMessage, error) { // appendPayloadSizeField appends the auxiliary field containing the size of payload func (msg *sentMessage) addPayloadSizeField(payload []byte) { fieldSize := getAuxFieldSize(payload) - field := make([]byte, fieldSize) + field := make([]byte, 4) binary.LittleEndian.PutUint32(field, uint32(len(payload))) + field = field[:fieldSize] msg.Raw = append(msg.Raw, field...) msg.Raw[0] |= byte(fieldSize) } -// getSizeOfLength returns the number of bytes necessary to encode the size of padding -//func getAuxFieldSize(payload []byte) (sz int, err error) { -// sz = intSize(len(b)) // first iteration -// sz = intSize(len(b) + sz) // second iteration -// if sz > 3 { -// err = errors.New("oversized padding parameter") -// } -// return sz, err -//} - // getAuxFieldSize returns the number of bytes necessary to encode the size of payload func getAuxFieldSize(payload []byte) int { s := 1 @@ -144,29 +135,7 @@ func (msg *sentMessage) appendPadding(params *MessageParams) error { rawSize += AESNonceLength } odd := rawSize % padSizeLimit - - //if len(params.Padding) != 0 { - // // padding data was provided by the Dapp, just use it as is - // padSize := len(params.Padding) - // padLengthSize, err := intSize(len(params.Padding)) - // if err != nil { - // return err - // } - // totalPadSize := padSize + padLengthSize - // buf := make([]byte, 8) - // binary.LittleEndian.PutUint32(buf, uint32(totalPadSize)) - // buf = buf[:padLengthSize] - // msg.Raw = append(msg.Raw, buf...) - // msg.Raw = append(msg.Raw, params.Padding...) - // msg.Raw[0] |= byte(padLengthSize) // number of bytes indicating the padding size - //} else if odd != 0 { paddingSize := padSizeLimit - odd - //if totalPadSize > 255 { - // // this algorithm is only valid if padSizeLimit < 256. - // // if padSizeLimit will ever change, please fix the algorithm - // // (please see also ReceivedMessage.extractPadding() function). - // panic("please fix the padding algorithm before releasing new version") - //} pad := make([]byte, paddingSize) _, err := crand.Read(pad) if err != nil { @@ -175,10 +144,7 @@ func (msg *sentMessage) appendPadding(params *MessageParams) error { if !validateSymmetricKey(pad) { return errors.New("failed to generate random padding of size " + strconv.Itoa(paddingSize)) } - //buf[0] = byte(totalPadSize) msg.Raw = append(msg.Raw, pad...) - //msg.Raw[0] |= byte(0x1) // number of bytes indicating the padding size - //} return nil } @@ -195,11 +161,10 @@ func (msg *sentMessage) sign(key *ecdsa.PrivateKey) error { hash := crypto.Keccak256(msg.Raw) signature, err := crypto.Sign(hash, key) if err != nil { - msg.Raw[0] ^= signatureFlag // clear the flag + msg.Raw[0] &= (0xFF ^ signatureFlag) // clear the flag return err } msg.Raw = append(msg.Raw, signature...) - return nil } @@ -297,8 +262,7 @@ func (msg *sentMessage) Wrap(options *MessageParams) (envelope *Envelope, err er // decryptSymmetric decrypts a message with a topic key, using AES-GCM-256. // nonce size should be 12 bytes (see cipher.gcmStandardNonceSize). func (msg *ReceivedMessage) decryptSymmetric(key []byte) error { - // In v6, symmetric messages are expected to contain the 12-byte - // "salt" at the end of the payload. + // symmetric messages are expected to contain the 12-byte nonce at the end of the payload if len(msg.Raw) < AESNonceLength { return errors.New("missing salt or invalid payload in symmetric message") } @@ -335,16 +299,12 @@ func (msg *ReceivedMessage) decryptAsymmetric(key *ecdsa.PrivateKey) error { } // Validate checks the message validity and extracts the fields in case of success. -func (msg *ReceivedMessage) ValidateAndParse(symmetric bool) bool { +func (msg *ReceivedMessage) ValidateAndParse() bool { end := len(msg.Raw) if end < 1 { return false } - if symmetric { - end -= AESNonceLength - } - if isMessageSigned(msg.Raw[0]) { end -= signatureLength if end <= 1 { @@ -371,33 +331,9 @@ func (msg *ReceivedMessage) ValidateAndParse(symmetric bool) bool { beg += payloadSize msg.Padding = msg.Raw[beg:end] - - //padSize, ok := msg.extractPadding(end) - //if !ok { - // return false - //} - //msg.Payload = msg.Raw[1+padSize : end] - return true } -// extractPadding extracts the padding from raw message. -// although we don't support sending messages with padding size -// exceeding 255 bytes, such messages are perfectly valid, and -// can be successfully decrypted. -//func (msg *ReceivedMessage) extractPadding(end int) (int, bool) { -// payloadSize := 0 -// auxFieldSize := int(msg.Raw[0] & auxFieldSizeMask) // number of bytes indicating the size of payload -// if sz != 0 { -// paddingSize = int(bytesToUintLittleEndian(msg.Raw[1 : 1+sz])) -// if paddingSize < sz || paddingSize+1 > end { -// return 0, false -// } -// msg.Padding = msg.Raw[1+sz : 1+paddingSize] -// } -// return paddingSize, true -//} - // Recover retrieves the public key of the message signer. func (msg *ReceivedMessage) SigToPubKey() *ecdsa.PublicKey { defer func() { recover() }() // in case of invalid signature diff --git a/whisper/whisperv6/message_test.go b/whisper/whisperv6/message_test.go index d0305c2e60..81db58dedd 100644 --- a/whisper/whisperv6/message_test.go +++ b/whisper/whisperv6/message_test.go @@ -90,8 +90,8 @@ func singleMessageTest(t *testing.T, symmetric bool) { t.Fatalf("failed to encrypt with seed %d: %s.", seed, err) } - if !decrypted.ValidateAndParse(symmetric) { - t.Fatalf("failed to validate with seed %d.", seed) + if !decrypted.ValidateAndParse() { + t.Fatalf("failed to validate with seed %d, symmetric = %v.", seed, symmetric) } if !bytes.Equal(text, decrypted.Payload) { @@ -427,7 +427,7 @@ func TestPaddingAppendedToSymMessages(t *testing.T) { // payload + flag + aesnonce > 256. Check that the result // is padded on the next 256 boundary. msg := sentMessage{} - msg.Raw = make([]byte, len(params.Payload)+1+AESNonceLength) + msg.Raw = make([]byte, 1+1+len(params.Payload)) err := msg.appendPadding(params) @@ -436,7 +436,7 @@ func TestPaddingAppendedToSymMessages(t *testing.T) { return } - if len(msg.Raw) != 512 { + if len(msg.Raw) != 512-AESNonceLength { t.Errorf("Invalid size %d != 512", len(msg.Raw)) } } @@ -459,7 +459,7 @@ func TestPaddingAppendedToSymMessagesWithSignature(t *testing.T) { // payload + flag + aesnonce > 256. Check that the result // is padded on the next 256 boundary. msg := sentMessage{} - msg.Raw = make([]byte, len(params.Payload)+1+AESNonceLength+signatureLength) + msg.Raw = make([]byte, 1+1+len(params.Payload)) err = msg.appendPadding(params) @@ -468,7 +468,7 @@ func TestPaddingAppendedToSymMessagesWithSignature(t *testing.T) { return } - if len(msg.Raw) != 512 { + if len(msg.Raw) != 512-AESNonceLength-signatureLength { t.Errorf("Invalid size %d != 512", len(msg.Raw)) } }