whisper/whisperv6: remove Version from the envelope (#15621)
This commit is contained in:
parent
586198ccea
commit
bf62acf033
@ -17,14 +17,16 @@
|
|||||||
package whisperv6
|
package whisperv6
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/sha256"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
"golang.org/x/crypto/pbkdf2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func BenchmarkDeriveKeyMaterial(b *testing.B) {
|
func BenchmarkDeriveKeyMaterial(b *testing.B) {
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
deriveKeyMaterial([]byte("test"), 0)
|
pbkdf2.Key([]byte("test"), nil, 65356, aesKeyLength, sha256.New)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +36,6 @@ import (
|
|||||||
// Envelope represents a clear-text data packet to transmit through the Whisper
|
// Envelope represents a clear-text data packet to transmit through the Whisper
|
||||||
// network. Its contents may or may not be encrypted and signed.
|
// network. Its contents may or may not be encrypted and signed.
|
||||||
type Envelope struct {
|
type Envelope struct {
|
||||||
Version []byte
|
|
||||||
Expiry uint32
|
Expiry uint32
|
||||||
TTL uint32
|
TTL uint32
|
||||||
Topic TopicType
|
Topic TopicType
|
||||||
@ -50,12 +49,12 @@ type Envelope struct {
|
|||||||
|
|
||||||
// size returns the size of envelope as it is sent (i.e. public fields only)
|
// size returns the size of envelope as it is sent (i.e. public fields only)
|
||||||
func (e *Envelope) size() int {
|
func (e *Envelope) size() int {
|
||||||
return EnvelopeHeaderLength + len(e.Version) + len(e.Data)
|
return EnvelopeHeaderLength + len(e.Data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// rlpWithoutNonce returns the RLP encoded envelope contents, except the nonce.
|
// rlpWithoutNonce returns the RLP encoded envelope contents, except the nonce.
|
||||||
func (e *Envelope) rlpWithoutNonce() []byte {
|
func (e *Envelope) rlpWithoutNonce() []byte {
|
||||||
res, _ := rlp.EncodeToBytes([]interface{}{e.Version, e.Expiry, e.TTL, e.Topic, e.Data})
|
res, _ := rlp.EncodeToBytes([]interface{}{e.Expiry, e.TTL, e.Topic, e.Data})
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,7 +62,6 @@ func (e *Envelope) rlpWithoutNonce() []byte {
|
|||||||
// included into an envelope for network forwarding.
|
// included into an envelope for network forwarding.
|
||||||
func NewEnvelope(ttl uint32, topic TopicType, msg *sentMessage) *Envelope {
|
func NewEnvelope(ttl uint32, topic TopicType, msg *sentMessage) *Envelope {
|
||||||
env := Envelope{
|
env := Envelope{
|
||||||
Version: make([]byte, 1),
|
|
||||||
Expiry: uint32(time.Now().Add(time.Second * time.Duration(ttl)).Unix()),
|
Expiry: uint32(time.Now().Add(time.Second * time.Duration(ttl)).Unix()),
|
||||||
TTL: ttl,
|
TTL: ttl,
|
||||||
Topic: topic,
|
Topic: topic,
|
||||||
@ -71,19 +69,9 @@ func NewEnvelope(ttl uint32, topic TopicType, msg *sentMessage) *Envelope {
|
|||||||
Nonce: 0,
|
Nonce: 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
if EnvelopeVersion < 256 {
|
|
||||||
env.Version[0] = byte(EnvelopeVersion)
|
|
||||||
} else {
|
|
||||||
panic("please increase the size of Envelope.Version before releasing this version")
|
|
||||||
}
|
|
||||||
|
|
||||||
return &env
|
return &env
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Envelope) Ver() uint64 {
|
|
||||||
return bytesToUintLittleEndian(e.Version)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Seal closes the envelope by spending the requested amount of time as a proof
|
// Seal closes the envelope by spending the requested amount of time as a proof
|
||||||
// of work on hashing the data.
|
// of work on hashing the data.
|
||||||
func (e *Envelope) Seal(options *MessageParams) error {
|
func (e *Envelope) Seal(options *MessageParams) error {
|
||||||
@ -236,7 +224,6 @@ func (e *Envelope) Open(watcher *Filter) (msg *ReceivedMessage) {
|
|||||||
msg.TTL = e.TTL
|
msg.TTL = e.TTL
|
||||||
msg.Sent = e.Expiry - e.TTL
|
msg.Sent = e.Expiry - e.TTL
|
||||||
msg.EnvelopeHash = e.Hash()
|
msg.EnvelopeHash = e.Hash()
|
||||||
msg.EnvelopeVersion = e.Ver()
|
|
||||||
}
|
}
|
||||||
return msg
|
return msg
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,6 @@ type ReceivedMessage struct {
|
|||||||
|
|
||||||
SymKeyHash common.Hash // The Keccak256Hash of the key, associated with the Topic
|
SymKeyHash common.Hash // The Keccak256Hash of the key, associated with the Topic
|
||||||
EnvelopeHash common.Hash // Message envelope hash to act as a unique id
|
EnvelopeHash common.Hash // Message envelope hash to act as a unique id
|
||||||
EnvelopeVersion uint64
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func isMessageSigned(flags byte) bool {
|
func isMessageSigned(flags byte) bool {
|
||||||
|
@ -367,7 +367,9 @@ func (w *Whisper) AddSymKeyFromPassword(password string) (string, error) {
|
|||||||
return "", fmt.Errorf("failed to generate unique ID")
|
return "", fmt.Errorf("failed to generate unique ID")
|
||||||
}
|
}
|
||||||
|
|
||||||
derived, err := deriveKeyMaterial([]byte(password), EnvelopeVersion)
|
// kdf should run no less than 0.1 seconds on an average computer,
|
||||||
|
// because it's an once in a session experience
|
||||||
|
derived := pbkdf2.Key([]byte(password), nil, 65356, aesKeyLength, sha256.New)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@ -587,10 +589,6 @@ func (wh *Whisper) add(envelope *Envelope) (bool, error) {
|
|||||||
return false, fmt.Errorf("huge messages are not allowed [%x]", envelope.Hash())
|
return false, fmt.Errorf("huge messages are not allowed [%x]", envelope.Hash())
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(envelope.Version) > 4 {
|
|
||||||
return false, fmt.Errorf("oversized version [%x]", envelope.Hash())
|
|
||||||
}
|
|
||||||
|
|
||||||
if envelope.PoW() < wh.MinPow() {
|
if envelope.PoW() < wh.MinPow() {
|
||||||
log.Debug("envelope with low PoW dropped", "PoW", envelope.PoW(), "hash", envelope.Hash().Hex())
|
log.Debug("envelope with low PoW dropped", "PoW", envelope.PoW(), "hash", envelope.Hash().Hex())
|
||||||
return false, nil // drop envelope without error
|
return false, nil // drop envelope without error
|
||||||
@ -628,10 +626,6 @@ func (wh *Whisper) add(envelope *Envelope) (bool, error) {
|
|||||||
|
|
||||||
// postEvent queues the message for further processing.
|
// postEvent queues the message for further processing.
|
||||||
func (w *Whisper) postEvent(envelope *Envelope, isP2P bool) {
|
func (w *Whisper) postEvent(envelope *Envelope, isP2P bool) {
|
||||||
// if the version of incoming message is higher than
|
|
||||||
// currently supported version, we can not decrypt it,
|
|
||||||
// and therefore just ignore this message
|
|
||||||
if envelope.Ver() <= EnvelopeVersion {
|
|
||||||
if isP2P {
|
if isP2P {
|
||||||
w.p2pMsgQueue <- envelope
|
w.p2pMsgQueue <- envelope
|
||||||
} else {
|
} else {
|
||||||
@ -639,7 +633,6 @@ func (w *Whisper) postEvent(envelope *Envelope, isP2P bool) {
|
|||||||
w.messageQueue <- envelope
|
w.messageQueue <- envelope
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// checkOverflow checks if message queue overflow occurs and reports it if necessary.
|
// checkOverflow checks if message queue overflow occurs and reports it if necessary.
|
||||||
func (w *Whisper) checkOverflow() {
|
func (w *Whisper) checkOverflow() {
|
||||||
@ -823,19 +816,6 @@ func BytesToUintBigEndian(b []byte) (res uint64) {
|
|||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
// deriveKeyMaterial derives symmetric key material from the key or password.
|
|
||||||
// pbkdf2 is used for security, in case people use password instead of randomly generated keys.
|
|
||||||
func deriveKeyMaterial(key []byte, version uint64) (derivedKey []byte, err error) {
|
|
||||||
if version == 0 {
|
|
||||||
// kdf should run no less than 0.1 seconds on average compute,
|
|
||||||
// because it's a once in a session experience
|
|
||||||
derivedKey := pbkdf2.Key(key, nil, 65356, aesKeyLength, sha256.New)
|
|
||||||
return derivedKey, nil
|
|
||||||
} else {
|
|
||||||
return nil, unknownVersionError(version)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// GenerateRandomID generates a random string, which is then returned to be used as a key id
|
// GenerateRandomID generates a random string, which is then returned to be used as a key id
|
||||||
func GenerateRandomID() (id string, err error) {
|
func GenerateRandomID() (id string, err error) {
|
||||||
buf := make([]byte, keyIdSize)
|
buf := make([]byte, keyIdSize)
|
||||||
|
@ -19,11 +19,13 @@ package whisperv6
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
|
"crypto/sha256"
|
||||||
mrand "math/rand"
|
mrand "math/rand"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"golang.org/x/crypto/pbkdf2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestWhisperBasic(t *testing.T) {
|
func TestWhisperBasic(t *testing.T) {
|
||||||
@ -79,14 +81,7 @@ func TestWhisperBasic(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var derived []byte
|
var derived []byte
|
||||||
ver := uint64(0xDEADBEEF)
|
derived = pbkdf2.Key([]byte(peerID), nil, 65356, aesKeyLength, sha256.New)
|
||||||
if _, err := deriveKeyMaterial(peerID, ver); err != unknownVersionError(ver) {
|
|
||||||
t.Fatalf("failed deriveKeyMaterial with param = %v: %s.", peerID, err)
|
|
||||||
}
|
|
||||||
derived, err = deriveKeyMaterial(peerID, 0)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed second deriveKeyMaterial with param = %v: %s.", peerID, err)
|
|
||||||
}
|
|
||||||
if !validateSymmetricKey(derived) {
|
if !validateSymmetricKey(derived) {
|
||||||
t.Fatalf("failed validateSymmetricKey with param = %v.", derived)
|
t.Fatalf("failed validateSymmetricKey with param = %v.", derived)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user