forked from cerc-io/plugeth
Added encryption for messages better API for sealing messages
This commit is contained in:
parent
87adff7e18
commit
984c7e6689
@ -16,8 +16,8 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Envelope struct {
|
type Envelope struct {
|
||||||
Expiry int32 // Whisper protocol specifies int32, really should be int64
|
Expiry uint32 // Whisper protocol specifies int32, really should be int64
|
||||||
Ttl int32 // ^^^^^^
|
Ttl uint32 // ^^^^^^
|
||||||
Topics [][]byte
|
Topics [][]byte
|
||||||
Data []byte
|
Data []byte
|
||||||
Nonce uint32
|
Nonce uint32
|
||||||
@ -52,11 +52,11 @@ func (self *Envelope) Hash() Hash {
|
|||||||
func NewEnvelope(ttl time.Duration, topics [][]byte, data *Message) *Envelope {
|
func NewEnvelope(ttl time.Duration, topics [][]byte, data *Message) *Envelope {
|
||||||
exp := time.Now().Add(ttl)
|
exp := time.Now().Add(ttl)
|
||||||
|
|
||||||
return &Envelope{int32(exp.Unix()), int32(ttl.Seconds()), topics, data.Bytes(), 0, Hash{}}
|
return &Envelope{uint32(exp.Unix()), uint32(ttl.Seconds()), topics, data.Bytes(), 0, Hash{}}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Envelope) Seal() {
|
func (self *Envelope) Seal(pow time.Duration) {
|
||||||
self.proveWork(DefaultPow)
|
self.proveWork(pow)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Envelope) proveWork(dura time.Duration) {
|
func (self *Envelope) proveWork(dura time.Duration) {
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
package whisper
|
package whisper
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
)
|
||||||
|
|
||||||
type Message struct {
|
type Message struct {
|
||||||
Flags byte
|
Flags byte
|
||||||
Signature []byte
|
Signature []byte
|
||||||
@ -10,6 +16,49 @@ func NewMessage(payload []byte) *Message {
|
|||||||
return &Message{Flags: 0, Payload: payload}
|
return &Message{Flags: 0, Payload: payload}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *Message) hash() []byte {
|
||||||
|
return crypto.Sha3(append([]byte{self.Flags}, self.Payload...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Message) sign(key []byte) (err error) {
|
||||||
|
self.Flags = 1
|
||||||
|
self.Signature, err = crypto.Sign(self.hash(), key)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Message) Encrypt(from, to []byte) (err error) {
|
||||||
|
err = self.sign(from)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
self.Payload, err = crypto.Encrypt(to, self.Payload)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (self *Message) Bytes() []byte {
|
func (self *Message) Bytes() []byte {
|
||||||
return append([]byte{self.Flags}, append(self.Signature, self.Payload...)...)
|
return append([]byte{self.Flags}, append(self.Signature, self.Payload...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Opts struct {
|
||||||
|
From, To []byte // private(sender), public(receiver) key
|
||||||
|
Ttl time.Duration
|
||||||
|
Topics [][]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Message) Seal(pow time.Duration, opts Opts) (*Envelope, error) {
|
||||||
|
if len(opts.To) > 0 && len(opts.From) > 0 {
|
||||||
|
if err := self.Encrypt(opts.From, opts.To); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
envelope := NewEnvelope(DefaultTtl, opts.Topics, self)
|
||||||
|
envelope.Seal(pow)
|
||||||
|
|
||||||
|
return envelope, nil
|
||||||
|
}
|
||||||
|
@ -2,6 +2,7 @@ package whisper
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@ -35,7 +36,7 @@ const (
|
|||||||
envelopesMsg = 0x01
|
envelopesMsg = 0x01
|
||||||
)
|
)
|
||||||
|
|
||||||
const defaultTtl = 50 * time.Second
|
const DefaultTtl = 50 * time.Second
|
||||||
|
|
||||||
type Whisper struct {
|
type Whisper struct {
|
||||||
pub, sec []byte
|
pub, sec []byte
|
||||||
@ -43,7 +44,7 @@ type Whisper struct {
|
|||||||
|
|
||||||
mmu sync.RWMutex
|
mmu sync.RWMutex
|
||||||
messages map[Hash]*Envelope
|
messages map[Hash]*Envelope
|
||||||
expiry map[int32]*set.SetNonTS
|
expiry map[uint32]*set.SetNonTS
|
||||||
|
|
||||||
quit chan struct{}
|
quit chan struct{}
|
||||||
}
|
}
|
||||||
@ -53,12 +54,18 @@ func New(pub, sec []byte) *Whisper {
|
|||||||
pub: pub,
|
pub: pub,
|
||||||
sec: sec,
|
sec: sec,
|
||||||
messages: make(map[Hash]*Envelope),
|
messages: make(map[Hash]*Envelope),
|
||||||
expiry: make(map[int32]*set.SetNonTS),
|
expiry: make(map[uint32]*set.SetNonTS),
|
||||||
quit: make(chan struct{}),
|
quit: make(chan struct{}),
|
||||||
}
|
}
|
||||||
go whisper.update()
|
go whisper.update()
|
||||||
|
|
||||||
whisper.Send(defaultTtl, nil, NewMessage([]byte("Hello world. This is whisper-go")))
|
msg := NewMessage([]byte(fmt.Sprintf("Hello world. This is whisper-go. Incase you're wondering; the time is %v", time.Now())))
|
||||||
|
envelope, _ := msg.Seal(DefaultPow, Opts{
|
||||||
|
Ttl: DefaultTtl,
|
||||||
|
})
|
||||||
|
if err := whisper.Send(envelope); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
// p2p whisper sub protocol handler
|
// p2p whisper sub protocol handler
|
||||||
whisper.protocol = p2p.Protocol{
|
whisper.protocol = p2p.Protocol{
|
||||||
@ -75,17 +82,14 @@ func (self *Whisper) Stop() {
|
|||||||
close(self.quit)
|
close(self.quit)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Whisper) Send(ttl time.Duration, topics [][]byte, data *Message) {
|
func (self *Whisper) Send(envelope *Envelope) error {
|
||||||
envelope := NewEnvelope(ttl, topics, data)
|
return self.add(envelope)
|
||||||
envelope.Seal()
|
|
||||||
|
|
||||||
self.add(envelope)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Main handler for passing whisper messages to whisper peer objects
|
// Main handler for passing whisper messages to whisper peer objects
|
||||||
func (self *Whisper) msgHandler(peer *p2p.Peer, ws p2p.MsgReadWriter) error {
|
func (self *Whisper) msgHandler(peer *p2p.Peer, ws p2p.MsgReadWriter) error {
|
||||||
wpeer := NewPeer(self, peer, ws)
|
wpeer := NewPeer(self, peer, ws)
|
||||||
// init whisper peer (handshake/status)
|
// initialise whisper peer (handshake/status)
|
||||||
if err := wpeer.init(); err != nil {
|
if err := wpeer.init(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -106,22 +110,37 @@ func (self *Whisper) msgHandler(peer *p2p.Peer, ws p2p.MsgReadWriter) error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
self.add(envelope)
|
if err := self.add(envelope); err != nil {
|
||||||
|
// TODO Punish peer here. Invalid envelope.
|
||||||
|
peer.Infoln(err)
|
||||||
|
}
|
||||||
wpeer.addKnown(envelope)
|
wpeer.addKnown(envelope)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// takes care of adding envelopes to the messages pool. At this moment no sanity checks are being performed.
|
// takes care of adding envelopes to the messages pool. At this moment no sanity checks are being performed.
|
||||||
func (self *Whisper) add(envelope *Envelope) {
|
func (self *Whisper) add(envelope *Envelope) error {
|
||||||
|
if !envelope.valid() {
|
||||||
|
return errors.New("invalid pow for envelope")
|
||||||
|
}
|
||||||
|
|
||||||
self.mmu.Lock()
|
self.mmu.Lock()
|
||||||
defer self.mmu.Unlock()
|
defer self.mmu.Unlock()
|
||||||
|
|
||||||
fmt.Println("add", envelope)
|
hash := envelope.Hash()
|
||||||
self.messages[envelope.Hash()] = envelope
|
self.messages[hash] = envelope
|
||||||
if self.expiry[envelope.Expiry] == nil {
|
if self.expiry[envelope.Expiry] == nil {
|
||||||
self.expiry[envelope.Expiry] = set.NewNonTS()
|
self.expiry[envelope.Expiry] = set.NewNonTS()
|
||||||
}
|
}
|
||||||
self.expiry[envelope.Expiry].Add(envelope.Hash())
|
|
||||||
|
if !self.expiry[envelope.Expiry].Has(hash) {
|
||||||
|
self.expiry[envelope.Expiry].Add(hash)
|
||||||
|
// TODO notify listeners (given that we had any ...)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("add", envelope)
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Whisper) update() {
|
func (self *Whisper) update() {
|
||||||
@ -141,7 +160,7 @@ func (self *Whisper) expire() {
|
|||||||
self.mmu.Lock()
|
self.mmu.Lock()
|
||||||
defer self.mmu.Unlock()
|
defer self.mmu.Unlock()
|
||||||
|
|
||||||
now := int32(time.Now().Unix())
|
now := uint32(time.Now().Unix())
|
||||||
for then, hashSet := range self.expiry {
|
for then, hashSet := range self.expiry {
|
||||||
if then > now {
|
if then > now {
|
||||||
continue
|
continue
|
||||||
|
@ -33,8 +33,7 @@ const (
|
|||||||
MsgGetPeersTy = 0x04
|
MsgGetPeersTy = 0x04
|
||||||
MsgPeersTy = 0x05
|
MsgPeersTy = 0x05
|
||||||
|
|
||||||
MsgStatusTy = 0x10
|
MsgStatusTy = 0x10
|
||||||
//MsgGetTxsTy = 0x11
|
|
||||||
MsgTxTy = 0x12
|
MsgTxTy = 0x12
|
||||||
MsgGetBlockHashesTy = 0x13
|
MsgGetBlockHashesTy = 0x13
|
||||||
MsgBlockHashesTy = 0x14
|
MsgBlockHashesTy = 0x14
|
||||||
|
Loading…
Reference in New Issue
Block a user