github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/whisper/whisperv6/message.go (about)

     1  
     2  //此源码被清华学神尹成大魔王专业翻译分析并修改
     3  //尹成QQ77025077
     4  //尹成微信18510341407
     5  //尹成所在QQ群721929980
     6  //尹成邮箱 yinc13@mails.tsinghua.edu.cn
     7  //尹成毕业于清华大学,微软区块链领域全球最有价值专家
     8  //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620
     9  //
    10  //
    11  //
    12  //
    13  //
    14  //
    15  //
    16  //
    17  //
    18  //
    19  //
    20  //
    21  //
    22  //
    23  //
    24  
    25  //
    26  
    27  package whisperv6
    28  
    29  import (
    30  	"crypto/aes"
    31  	"crypto/cipher"
    32  	"crypto/ecdsa"
    33  	crand "crypto/rand"
    34  	"encoding/binary"
    35  	"errors"
    36  	mrand "math/rand"
    37  	"strconv"
    38  
    39  	"github.com/ethereum/go-ethereum/common"
    40  	"github.com/ethereum/go-ethereum/crypto"
    41  	"github.com/ethereum/go-ethereum/crypto/ecies"
    42  	"github.com/ethereum/go-ethereum/log"
    43  )
    44  
    45  //
    46  //
    47  type MessageParams struct {
    48  	TTL      uint32
    49  	Src      *ecdsa.PrivateKey
    50  	Dst      *ecdsa.PublicKey
    51  	KeySym   []byte
    52  	Topic    TopicType
    53  	WorkTime uint32
    54  	PoW      float64
    55  	Payload  []byte
    56  	Padding  []byte
    57  }
    58  
    59  //
    60  //
    61  //
    62  type sentMessage struct {
    63  	Raw []byte
    64  }
    65  
    66  //
    67  //
    68  type ReceivedMessage struct {
    69  	Raw []byte
    70  
    71  	Payload   []byte
    72  	Padding   []byte
    73  	Signature []byte
    74  	Salt      []byte
    75  
    76  PoW   float64          //
    77  Sent  uint32           //
    78  TTL   uint32           //
    79  Src   *ecdsa.PublicKey //
    80  Dst   *ecdsa.PublicKey //
    81  	Topic TopicType
    82  
    83  SymKeyHash   common.Hash //
    84  EnvelopeHash common.Hash //
    85  }
    86  
    87  func isMessageSigned(flags byte) bool {
    88  	return (flags & signatureFlag) != 0
    89  }
    90  
    91  func (msg *ReceivedMessage) isSymmetricEncryption() bool {
    92  	return msg.SymKeyHash != common.Hash{}
    93  }
    94  
    95  func (msg *ReceivedMessage) isAsymmetricEncryption() bool {
    96  	return msg.Dst != nil
    97  }
    98  
    99  //
   100  func NewSentMessage(params *MessageParams) (*sentMessage, error) {
   101  	const payloadSizeFieldMaxSize = 4
   102  	msg := sentMessage{}
   103  	msg.Raw = make([]byte, 1,
   104  		flagsLength+payloadSizeFieldMaxSize+len(params.Payload)+len(params.Padding)+signatureLength+padSizeLimit)
   105  msg.Raw[0] = 0 //
   106  	msg.addPayloadSizeField(params.Payload)
   107  	msg.Raw = append(msg.Raw, params.Payload...)
   108  	err := msg.appendPadding(params)
   109  	return &msg, err
   110  }
   111  
   112  //
   113  func (msg *sentMessage) addPayloadSizeField(payload []byte) {
   114  	fieldSize := getSizeOfPayloadSizeField(payload)
   115  	field := make([]byte, 4)
   116  	binary.LittleEndian.PutUint32(field, uint32(len(payload)))
   117  	field = field[:fieldSize]
   118  	msg.Raw = append(msg.Raw, field...)
   119  	msg.Raw[0] |= byte(fieldSize)
   120  }
   121  
   122  //
   123  func getSizeOfPayloadSizeField(payload []byte) int {
   124  	s := 1
   125  	for i := len(payload); i >= 256; i /= 256 {
   126  		s++
   127  	}
   128  	return s
   129  }
   130  
   131  //
   132  //
   133  func (msg *sentMessage) appendPadding(params *MessageParams) error {
   134  	if len(params.Padding) != 0 {
   135  //
   136  		msg.Raw = append(msg.Raw, params.Padding...)
   137  		return nil
   138  	}
   139  
   140  	rawSize := flagsLength + getSizeOfPayloadSizeField(params.Payload) + len(params.Payload)
   141  	if params.Src != nil {
   142  		rawSize += signatureLength
   143  	}
   144  	odd := rawSize % padSizeLimit
   145  	paddingSize := padSizeLimit - odd
   146  	pad := make([]byte, paddingSize)
   147  	_, err := crand.Read(pad)
   148  	if err != nil {
   149  		return err
   150  	}
   151  	if !validateDataIntegrity(pad, paddingSize) {
   152  		return errors.New("failed to generate random padding of size " + strconv.Itoa(paddingSize))
   153  	}
   154  	msg.Raw = append(msg.Raw, pad...)
   155  	return nil
   156  }
   157  
   158  //
   159  //
   160  func (msg *sentMessage) sign(key *ecdsa.PrivateKey) error {
   161  	if isMessageSigned(msg.Raw[0]) {
   162  //
   163  		log.Error("failed to sign the message: already signed")
   164  		return nil
   165  	}
   166  
   167  msg.Raw[0] |= signatureFlag //
   168  	hash := crypto.Keccak256(msg.Raw)
   169  	signature, err := crypto.Sign(hash, key)
   170  	if err != nil {
   171  msg.Raw[0] &= (0xFF ^ signatureFlag) //
   172  		return err
   173  	}
   174  	msg.Raw = append(msg.Raw, signature...)
   175  	return nil
   176  }
   177  
   178  //
   179  func (msg *sentMessage) encryptAsymmetric(key *ecdsa.PublicKey) error {
   180  	if !ValidatePublicKey(key) {
   181  		return errors.New("invalid public key provided for asymmetric encryption")
   182  	}
   183  	encrypted, err := ecies.Encrypt(crand.Reader, ecies.ImportECDSAPublic(key), msg.Raw, nil, nil)
   184  	if err == nil {
   185  		msg.Raw = encrypted
   186  	}
   187  	return err
   188  }
   189  
   190  //
   191  //
   192  func (msg *sentMessage) encryptSymmetric(key []byte) (err error) {
   193  	if !validateDataIntegrity(key, aesKeyLength) {
   194  		return errors.New("invalid key provided for symmetric encryption, size: " + strconv.Itoa(len(key)))
   195  	}
   196  	block, err := aes.NewCipher(key)
   197  	if err != nil {
   198  		return err
   199  	}
   200  	aesgcm, err := cipher.NewGCM(block)
   201  	if err != nil {
   202  		return err
   203  	}
   204  salt, err := generateSecureRandomData(aesNonceLength) //
   205  	if err != nil {
   206  		return err
   207  	}
   208  	encrypted := aesgcm.Seal(nil, salt, msg.Raw, nil)
   209  	msg.Raw = append(encrypted, salt...)
   210  	return nil
   211  }
   212  
   213  //
   214  //
   215  //
   216  //
   217  //
   218  func generateSecureRandomData(length int) ([]byte, error) {
   219  	x := make([]byte, length)
   220  	y := make([]byte, length)
   221  	res := make([]byte, length)
   222  
   223  	_, err := crand.Read(x)
   224  	if err != nil {
   225  		return nil, err
   226  	} else if !validateDataIntegrity(x, length) {
   227  		return nil, errors.New("crypto/rand failed to generate secure random data")
   228  	}
   229  	_, err = mrand.Read(y)
   230  	if err != nil {
   231  		return nil, err
   232  	} else if !validateDataIntegrity(y, length) {
   233  		return nil, errors.New("math/rand failed to generate secure random data")
   234  	}
   235  	for i := 0; i < length; i++ {
   236  		res[i] = x[i] ^ y[i]
   237  	}
   238  	if !validateDataIntegrity(res, length) {
   239  		return nil, errors.New("failed to generate secure random data")
   240  	}
   241  	return res, nil
   242  }
   243  
   244  //
   245  func (msg *sentMessage) Wrap(options *MessageParams) (envelope *Envelope, err error) {
   246  	if options.TTL == 0 {
   247  		options.TTL = DefaultTTL
   248  	}
   249  	if options.Src != nil {
   250  		if err = msg.sign(options.Src); err != nil {
   251  			return nil, err
   252  		}
   253  	}
   254  	if options.Dst != nil {
   255  		err = msg.encryptAsymmetric(options.Dst)
   256  	} else if options.KeySym != nil {
   257  		err = msg.encryptSymmetric(options.KeySym)
   258  	} else {
   259  		err = errors.New("unable to encrypt the message: neither symmetric nor assymmetric key provided")
   260  	}
   261  	if err != nil {
   262  		return nil, err
   263  	}
   264  
   265  	envelope = NewEnvelope(options.TTL, options.Topic, msg)
   266  	if err = envelope.Seal(options); err != nil {
   267  		return nil, err
   268  	}
   269  	return envelope, nil
   270  }
   271  
   272  //
   273  //
   274  func (msg *ReceivedMessage) decryptSymmetric(key []byte) error {
   275  //
   276  	if len(msg.Raw) < aesNonceLength {
   277  		return errors.New("missing salt or invalid payload in symmetric message")
   278  	}
   279  	salt := msg.Raw[len(msg.Raw)-aesNonceLength:]
   280  
   281  	block, err := aes.NewCipher(key)
   282  	if err != nil {
   283  		return err
   284  	}
   285  	aesgcm, err := cipher.NewGCM(block)
   286  	if err != nil {
   287  		return err
   288  	}
   289  	decrypted, err := aesgcm.Open(nil, salt, msg.Raw[:len(msg.Raw)-aesNonceLength], nil)
   290  	if err != nil {
   291  		return err
   292  	}
   293  	msg.Raw = decrypted
   294  	msg.Salt = salt
   295  	return nil
   296  }
   297  
   298  //
   299  func (msg *ReceivedMessage) decryptAsymmetric(key *ecdsa.PrivateKey) error {
   300  	decrypted, err := ecies.ImportECDSA(key).Decrypt(msg.Raw, nil, nil)
   301  	if err == nil {
   302  		msg.Raw = decrypted
   303  	}
   304  	return err
   305  }
   306  
   307  //
   308  func (msg *ReceivedMessage) ValidateAndParse() bool {
   309  	end := len(msg.Raw)
   310  	if end < 1 {
   311  		return false
   312  	}
   313  
   314  	if isMessageSigned(msg.Raw[0]) {
   315  		end -= signatureLength
   316  		if end <= 1 {
   317  			return false
   318  		}
   319  		msg.Signature = msg.Raw[end : end+signatureLength]
   320  		msg.Src = msg.SigToPubKey()
   321  		if msg.Src == nil {
   322  			return false
   323  		}
   324  	}
   325  
   326  	beg := 1
   327  	payloadSize := 0
   328  sizeOfPayloadSizeField := int(msg.Raw[0] & SizeMask) //
   329  	if sizeOfPayloadSizeField != 0 {
   330  		payloadSize = int(bytesToUintLittleEndian(msg.Raw[beg : beg+sizeOfPayloadSizeField]))
   331  		if payloadSize+1 > end {
   332  			return false
   333  		}
   334  		beg += sizeOfPayloadSizeField
   335  		msg.Payload = msg.Raw[beg : beg+payloadSize]
   336  	}
   337  
   338  	beg += payloadSize
   339  	msg.Padding = msg.Raw[beg:end]
   340  	return true
   341  }
   342  
   343  //
   344  //
   345  func (msg *ReceivedMessage) SigToPubKey() *ecdsa.PublicKey {
   346  defer func() { recover() }() //
   347  
   348  	pub, err := crypto.SigToPub(msg.hash(), msg.Signature)
   349  	if err != nil {
   350  		log.Error("failed to recover public key from signature", "err", err)
   351  		return nil
   352  	}
   353  	return pub
   354  }
   355  
   356  //
   357  func (msg *ReceivedMessage) hash() []byte {
   358  	if isMessageSigned(msg.Raw[0]) {
   359  		sz := len(msg.Raw) - signatureLength
   360  		return crypto.Keccak256(msg.Raw[:sz])
   361  	}
   362  	return crypto.Keccak256(msg.Raw)
   363  }