github.com/letterj/go-ethereum@v1.8.22-0.20190204142846-520024dfd689/swarm/pss/pss.go (about)

     1  // Copyright 2018 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package pss
    18  
    19  import (
    20  	"bytes"
    21  	"context"
    22  	"crypto/ecdsa"
    23  	"crypto/rand"
    24  	"errors"
    25  	"fmt"
    26  	"hash"
    27  	"sync"
    28  	"time"
    29  
    30  	"github.com/ethereum/go-ethereum/common"
    31  	"github.com/ethereum/go-ethereum/crypto"
    32  	"github.com/ethereum/go-ethereum/metrics"
    33  	"github.com/ethereum/go-ethereum/p2p"
    34  	"github.com/ethereum/go-ethereum/p2p/enode"
    35  	"github.com/ethereum/go-ethereum/p2p/protocols"
    36  	"github.com/ethereum/go-ethereum/rpc"
    37  	"github.com/ethereum/go-ethereum/swarm/log"
    38  	"github.com/ethereum/go-ethereum/swarm/network"
    39  	"github.com/ethereum/go-ethereum/swarm/pot"
    40  	"github.com/ethereum/go-ethereum/swarm/storage"
    41  	whisper "github.com/ethereum/go-ethereum/whisper/whisperv5"
    42  	"golang.org/x/crypto/sha3"
    43  )
    44  
    45  const (
    46  	defaultPaddingByteSize     = 16
    47  	DefaultMsgTTL              = time.Second * 120
    48  	defaultDigestCacheTTL      = time.Second * 10
    49  	defaultSymKeyCacheCapacity = 512
    50  	digestLength               = 32 // byte length of digest used for pss cache (currently same as swarm chunk hash)
    51  	defaultWhisperWorkTime     = 3
    52  	defaultWhisperPoW          = 0.0000000001
    53  	defaultMaxMsgSize          = 1024 * 1024
    54  	defaultCleanInterval       = time.Second * 60 * 10
    55  	defaultOutboxCapacity      = 100000
    56  	pssProtocolName            = "pss"
    57  	pssVersion                 = 2
    58  	hasherCount                = 8
    59  )
    60  
    61  var (
    62  	addressLength = len(pot.Address{})
    63  )
    64  
    65  // cache is used for preventing backwards routing
    66  // will also be instrumental in flood guard mechanism
    67  // and mailbox implementation
    68  type pssCacheEntry struct {
    69  	expiresAt time.Time
    70  }
    71  
    72  // abstraction to enable access to p2p.protocols.Peer.Send
    73  type senderPeer interface {
    74  	Info() *p2p.PeerInfo
    75  	ID() enode.ID
    76  	Address() []byte
    77  	Send(context.Context, interface{}) error
    78  }
    79  
    80  // per-key peer related information
    81  // member `protected` prevents garbage collection of the instance
    82  type pssPeer struct {
    83  	lastSeen  time.Time
    84  	address   PssAddress
    85  	protected bool
    86  }
    87  
    88  // Pss configuration parameters
    89  type PssParams struct {
    90  	MsgTTL              time.Duration
    91  	CacheTTL            time.Duration
    92  	privateKey          *ecdsa.PrivateKey
    93  	SymKeyCacheCapacity int
    94  	AllowRaw            bool // If true, enables sending and receiving messages without builtin pss encryption
    95  }
    96  
    97  // Sane defaults for Pss
    98  func NewPssParams() *PssParams {
    99  	return &PssParams{
   100  		MsgTTL:              DefaultMsgTTL,
   101  		CacheTTL:            defaultDigestCacheTTL,
   102  		SymKeyCacheCapacity: defaultSymKeyCacheCapacity,
   103  	}
   104  }
   105  
   106  func (params *PssParams) WithPrivateKey(privatekey *ecdsa.PrivateKey) *PssParams {
   107  	params.privateKey = privatekey
   108  	return params
   109  }
   110  
   111  // Toplevel pss object, takes care of message sending, receiving, decryption and encryption, message handler dispatchers and message forwarding.
   112  //
   113  // Implements node.Service
   114  type Pss struct {
   115  	*network.Kademlia                   // we can get the Kademlia address from this
   116  	privateKey        *ecdsa.PrivateKey // pss can have it's own independent key
   117  	w                 *whisper.Whisper  // key and encryption backend
   118  	auxAPIs           []rpc.API         // builtins (handshake, test) can add APIs
   119  
   120  	// sending and forwarding
   121  	fwdPool         map[string]*protocols.Peer // keep track of all peers sitting on the pssmsg routing layer
   122  	fwdPoolMu       sync.RWMutex
   123  	fwdCache        map[pssDigest]pssCacheEntry // checksum of unique fields from pssmsg mapped to expiry, cache to determine whether to drop msg
   124  	fwdCacheMu      sync.RWMutex
   125  	cacheTTL        time.Duration // how long to keep messages in fwdCache (not implemented)
   126  	msgTTL          time.Duration
   127  	paddingByteSize int
   128  	capstring       string
   129  	outbox          chan *PssMsg
   130  
   131  	// keys and peers
   132  	pubKeyPool                 map[string]map[Topic]*pssPeer // mapping of hex public keys to peer address by topic.
   133  	pubKeyPoolMu               sync.RWMutex
   134  	symKeyPool                 map[string]map[Topic]*pssPeer // mapping of symkeyids to peer address by topic.
   135  	symKeyPoolMu               sync.RWMutex
   136  	symKeyDecryptCache         []*string // fast lookup of symkeys recently used for decryption; last used is on top of stack
   137  	symKeyDecryptCacheCursor   int       // modular cursor pointing to last used, wraps on symKeyDecryptCache array
   138  	symKeyDecryptCacheCapacity int       // max amount of symkeys to keep.
   139  
   140  	// message handling
   141  	handlers           map[Topic]map[*handler]bool // topic and version based pss payload handlers. See pss.Handle()
   142  	handlersMu         sync.RWMutex
   143  	hashPool           sync.Pool
   144  	topicHandlerCaps   map[Topic]*handlerCaps // caches capabilities of each topic's handlers
   145  	topicHandlerCapsMu sync.RWMutex
   146  
   147  	// process
   148  	quitC chan struct{}
   149  }
   150  
   151  func (p *Pss) String() string {
   152  	return fmt.Sprintf("pss: addr %x, pubkey %v", p.BaseAddr(), common.ToHex(crypto.FromECDSAPub(&p.privateKey.PublicKey)))
   153  }
   154  
   155  // Creates a new Pss instance.
   156  //
   157  // In addition to params, it takes a swarm network Kademlia
   158  // and a FileStore storage for message cache storage.
   159  func NewPss(k *network.Kademlia, params *PssParams) (*Pss, error) {
   160  	if params.privateKey == nil {
   161  		return nil, errors.New("missing private key for pss")
   162  	}
   163  	cap := p2p.Cap{
   164  		Name:    pssProtocolName,
   165  		Version: pssVersion,
   166  	}
   167  	ps := &Pss{
   168  		Kademlia:   k,
   169  		privateKey: params.privateKey,
   170  		w:          whisper.New(&whisper.DefaultConfig),
   171  		quitC:      make(chan struct{}),
   172  
   173  		fwdPool:         make(map[string]*protocols.Peer),
   174  		fwdCache:        make(map[pssDigest]pssCacheEntry),
   175  		cacheTTL:        params.CacheTTL,
   176  		msgTTL:          params.MsgTTL,
   177  		paddingByteSize: defaultPaddingByteSize,
   178  		capstring:       cap.String(),
   179  		outbox:          make(chan *PssMsg, defaultOutboxCapacity),
   180  
   181  		pubKeyPool:                 make(map[string]map[Topic]*pssPeer),
   182  		symKeyPool:                 make(map[string]map[Topic]*pssPeer),
   183  		symKeyDecryptCache:         make([]*string, params.SymKeyCacheCapacity),
   184  		symKeyDecryptCacheCapacity: params.SymKeyCacheCapacity,
   185  
   186  		handlers:         make(map[Topic]map[*handler]bool),
   187  		topicHandlerCaps: make(map[Topic]*handlerCaps),
   188  
   189  		hashPool: sync.Pool{
   190  			New: func() interface{} {
   191  				return sha3.NewLegacyKeccak256()
   192  			},
   193  		},
   194  	}
   195  
   196  	for i := 0; i < hasherCount; i++ {
   197  		hashfunc := storage.MakeHashFunc(storage.DefaultHash)()
   198  		ps.hashPool.Put(hashfunc)
   199  	}
   200  
   201  	return ps, nil
   202  }
   203  
   204  /////////////////////////////////////////////////////////////////////
   205  // SECTION: node.Service interface
   206  /////////////////////////////////////////////////////////////////////
   207  
   208  func (p *Pss) Start(srv *p2p.Server) error {
   209  	go func() {
   210  		ticker := time.NewTicker(defaultCleanInterval)
   211  		cacheTicker := time.NewTicker(p.cacheTTL)
   212  		defer ticker.Stop()
   213  		defer cacheTicker.Stop()
   214  		for {
   215  			select {
   216  			case <-cacheTicker.C:
   217  				p.cleanFwdCache()
   218  			case <-ticker.C:
   219  				p.cleanKeys()
   220  			case <-p.quitC:
   221  				return
   222  			}
   223  		}
   224  	}()
   225  	go func() {
   226  		for {
   227  			select {
   228  			case msg := <-p.outbox:
   229  				err := p.forward(msg)
   230  				if err != nil {
   231  					log.Error(err.Error())
   232  					metrics.GetOrRegisterCounter("pss.forward.err", nil).Inc(1)
   233  				}
   234  			case <-p.quitC:
   235  				return
   236  			}
   237  		}
   238  	}()
   239  	log.Info("Started Pss")
   240  	log.Info("Loaded EC keys", "pubkey", common.ToHex(crypto.FromECDSAPub(p.PublicKey())), "secp256", common.ToHex(crypto.CompressPubkey(p.PublicKey())))
   241  	return nil
   242  }
   243  
   244  func (p *Pss) Stop() error {
   245  	log.Info("Pss shutting down")
   246  	close(p.quitC)
   247  	return nil
   248  }
   249  
   250  var pssSpec = &protocols.Spec{
   251  	Name:       pssProtocolName,
   252  	Version:    pssVersion,
   253  	MaxMsgSize: defaultMaxMsgSize,
   254  	Messages: []interface{}{
   255  		PssMsg{},
   256  	},
   257  }
   258  
   259  func (p *Pss) Protocols() []p2p.Protocol {
   260  	return []p2p.Protocol{
   261  		{
   262  			Name:    pssSpec.Name,
   263  			Version: pssSpec.Version,
   264  			Length:  pssSpec.Length(),
   265  			Run:     p.Run,
   266  		},
   267  	}
   268  }
   269  
   270  func (p *Pss) Run(peer *p2p.Peer, rw p2p.MsgReadWriter) error {
   271  	pp := protocols.NewPeer(peer, rw, pssSpec)
   272  	p.fwdPoolMu.Lock()
   273  	p.fwdPool[peer.Info().ID] = pp
   274  	p.fwdPoolMu.Unlock()
   275  	return pp.Run(p.handlePssMsg)
   276  }
   277  
   278  func (p *Pss) APIs() []rpc.API {
   279  	apis := []rpc.API{
   280  		{
   281  			Namespace: "pss",
   282  			Version:   "1.0",
   283  			Service:   NewAPI(p),
   284  			Public:    true,
   285  		},
   286  	}
   287  	apis = append(apis, p.auxAPIs...)
   288  	return apis
   289  }
   290  
   291  // add API methods to the pss API
   292  // must be run before node is started
   293  func (p *Pss) addAPI(api rpc.API) {
   294  	p.auxAPIs = append(p.auxAPIs, api)
   295  }
   296  
   297  // Returns the swarm Kademlia address of the pss node
   298  func (p *Pss) BaseAddr() []byte {
   299  	return p.Kademlia.BaseAddr()
   300  }
   301  
   302  // Returns the pss node's public key
   303  func (p *Pss) PublicKey() *ecdsa.PublicKey {
   304  	return &p.privateKey.PublicKey
   305  }
   306  
   307  /////////////////////////////////////////////////////////////////////
   308  // SECTION: Message handling
   309  /////////////////////////////////////////////////////////////////////
   310  
   311  func (p *Pss) getTopicHandlerCaps(topic Topic) (hc *handlerCaps, found bool) {
   312  	p.topicHandlerCapsMu.RLock()
   313  	defer p.topicHandlerCapsMu.RUnlock()
   314  	hc, found = p.topicHandlerCaps[topic]
   315  	return
   316  }
   317  
   318  func (p *Pss) setTopicHandlerCaps(topic Topic, hc *handlerCaps) {
   319  	p.topicHandlerCapsMu.Lock()
   320  	defer p.topicHandlerCapsMu.Unlock()
   321  	p.topicHandlerCaps[topic] = hc
   322  }
   323  
   324  // Links a handler function to a Topic
   325  //
   326  // All incoming messages with an envelope Topic matching the
   327  // topic specified will be passed to the given Handler function.
   328  //
   329  // There may be an arbitrary number of handler functions per topic.
   330  //
   331  // Returns a deregister function which needs to be called to
   332  // deregister the handler,
   333  func (p *Pss) Register(topic *Topic, hndlr *handler) func() {
   334  	p.handlersMu.Lock()
   335  	defer p.handlersMu.Unlock()
   336  	handlers := p.handlers[*topic]
   337  	if handlers == nil {
   338  		handlers = make(map[*handler]bool)
   339  		p.handlers[*topic] = handlers
   340  		log.Debug("registered handler", "capabilities", hndlr.caps)
   341  	}
   342  	if hndlr.caps == nil {
   343  		hndlr.caps = &handlerCaps{}
   344  	}
   345  	handlers[hndlr] = true
   346  
   347  	capabilities, ok := p.getTopicHandlerCaps(*topic)
   348  	if !ok {
   349  		capabilities = &handlerCaps{}
   350  		p.setTopicHandlerCaps(*topic, capabilities)
   351  	}
   352  
   353  	if hndlr.caps.raw {
   354  		capabilities.raw = true
   355  	}
   356  	if hndlr.caps.prox {
   357  		capabilities.prox = true
   358  	}
   359  	return func() { p.deregister(topic, hndlr) }
   360  }
   361  
   362  func (p *Pss) deregister(topic *Topic, hndlr *handler) {
   363  	p.handlersMu.Lock()
   364  	defer p.handlersMu.Unlock()
   365  	handlers := p.handlers[*topic]
   366  	if len(handlers) > 1 {
   367  		delete(p.handlers, *topic)
   368  		// topic caps might have changed now that a handler is gone
   369  		caps := &handlerCaps{}
   370  		for h := range handlers {
   371  			if h.caps.raw {
   372  				caps.raw = true
   373  			}
   374  			if h.caps.prox {
   375  				caps.prox = true
   376  			}
   377  		}
   378  		p.setTopicHandlerCaps(*topic, caps)
   379  		return
   380  	}
   381  	delete(handlers, hndlr)
   382  }
   383  
   384  // Filters incoming messages for processing or forwarding.
   385  // Check if address partially matches
   386  // If yes, it CAN be for us, and we process it
   387  // Only passes error to pss protocol handler if payload is not valid pssmsg
   388  func (p *Pss) handlePssMsg(ctx context.Context, msg interface{}) error {
   389  	metrics.GetOrRegisterCounter("pss.handlepssmsg", nil).Inc(1)
   390  	pssmsg, ok := msg.(*PssMsg)
   391  	if !ok {
   392  		return fmt.Errorf("invalid message type. Expected *PssMsg, got %T ", msg)
   393  	}
   394  	log.Trace("handler", "self", label(p.Kademlia.BaseAddr()), "topic", label(pssmsg.Payload.Topic[:]))
   395  	if int64(pssmsg.Expire) < time.Now().Unix() {
   396  		metrics.GetOrRegisterCounter("pss.expire", nil).Inc(1)
   397  		log.Warn("pss filtered expired message", "from", common.ToHex(p.Kademlia.BaseAddr()), "to", common.ToHex(pssmsg.To))
   398  		return nil
   399  	}
   400  	if p.checkFwdCache(pssmsg) {
   401  		log.Trace("pss relay block-cache match (process)", "from", common.ToHex(p.Kademlia.BaseAddr()), "to", (common.ToHex(pssmsg.To)))
   402  		return nil
   403  	}
   404  	p.addFwdCache(pssmsg)
   405  
   406  	psstopic := Topic(pssmsg.Payload.Topic)
   407  
   408  	// raw is simplest handler contingency to check, so check that first
   409  	var isRaw bool
   410  	if pssmsg.isRaw() {
   411  		if capabilities, ok := p.getTopicHandlerCaps(psstopic); ok {
   412  			if !capabilities.raw {
   413  				log.Debug("No handler for raw message", "topic", psstopic)
   414  				return nil
   415  			}
   416  		}
   417  		isRaw = true
   418  	}
   419  
   420  	// check if we can be recipient:
   421  	// - no prox handler on message and partial address matches
   422  	// - prox handler on message and we are in prox regardless of partial address match
   423  	// store this result so we don't calculate again on every handler
   424  	var isProx bool
   425  	if capabilities, ok := p.getTopicHandlerCaps(psstopic); ok {
   426  		isProx = capabilities.prox
   427  	}
   428  	isRecipient := p.isSelfPossibleRecipient(pssmsg, isProx)
   429  	if !isRecipient {
   430  		log.Trace("pss was for someone else :'( ... forwarding", "pss", common.ToHex(p.BaseAddr()), "prox", isProx)
   431  		return p.enqueue(pssmsg)
   432  	}
   433  
   434  	log.Trace("pss for us, yay! ... let's process!", "pss", common.ToHex(p.BaseAddr()), "prox", isProx, "raw", isRaw, "topic", label(pssmsg.Payload.Topic[:]))
   435  	if err := p.process(pssmsg, isRaw, isProx); err != nil {
   436  		qerr := p.enqueue(pssmsg)
   437  		if qerr != nil {
   438  			return fmt.Errorf("process fail: processerr %v, queueerr: %v", err, qerr)
   439  		}
   440  	}
   441  	return nil
   442  }
   443  
   444  // Entry point to processing a message for which the current node can be the intended recipient.
   445  // Attempts symmetric and asymmetric decryption with stored keys.
   446  // Dispatches message to all handlers matching the message topic
   447  func (p *Pss) process(pssmsg *PssMsg, raw bool, prox bool) error {
   448  	metrics.GetOrRegisterCounter("pss.process", nil).Inc(1)
   449  
   450  	var err error
   451  	var recvmsg *whisper.ReceivedMessage
   452  	var payload []byte
   453  	var from PssAddress
   454  	var asymmetric bool
   455  	var keyid string
   456  	var keyFunc func(envelope *whisper.Envelope) (*whisper.ReceivedMessage, string, PssAddress, error)
   457  
   458  	envelope := pssmsg.Payload
   459  	psstopic := Topic(envelope.Topic)
   460  
   461  	if raw {
   462  		payload = pssmsg.Payload.Data
   463  	} else {
   464  		if pssmsg.isSym() {
   465  			keyFunc = p.processSym
   466  		} else {
   467  			asymmetric = true
   468  			keyFunc = p.processAsym
   469  		}
   470  
   471  		recvmsg, keyid, from, err = keyFunc(envelope)
   472  		if err != nil {
   473  			return errors.New("Decryption failed")
   474  		}
   475  		payload = recvmsg.Payload
   476  	}
   477  
   478  	if len(pssmsg.To) < addressLength {
   479  		if err := p.enqueue(pssmsg); err != nil {
   480  			return err
   481  		}
   482  	}
   483  	p.executeHandlers(psstopic, payload, from, raw, prox, asymmetric, keyid)
   484  
   485  	return nil
   486  }
   487  
   488  // copy all registered handlers for respective topic in order to avoid data race or deadlock
   489  func (p *Pss) getHandlers(topic Topic) (ret []*handler) {
   490  	p.handlersMu.RLock()
   491  	defer p.handlersMu.RUnlock()
   492  	for k := range p.handlers[topic] {
   493  		ret = append(ret, k)
   494  	}
   495  	return ret
   496  }
   497  
   498  func (p *Pss) executeHandlers(topic Topic, payload []byte, from PssAddress, raw bool, prox bool, asymmetric bool, keyid string) {
   499  	handlers := p.getHandlers(topic)
   500  	peer := p2p.NewPeer(enode.ID{}, fmt.Sprintf("%x", from), []p2p.Cap{})
   501  	for _, h := range handlers {
   502  		if !h.caps.raw && raw {
   503  			log.Warn("norawhandler")
   504  			continue
   505  		}
   506  		if !h.caps.prox && prox {
   507  			log.Warn("noproxhandler")
   508  			continue
   509  		}
   510  		err := (h.f)(payload, peer, asymmetric, keyid)
   511  		if err != nil {
   512  			log.Warn("Pss handler failed", "err", err)
   513  		}
   514  	}
   515  }
   516  
   517  // will return false if using partial address
   518  func (p *Pss) isSelfRecipient(msg *PssMsg) bool {
   519  	return bytes.Equal(msg.To, p.Kademlia.BaseAddr())
   520  }
   521  
   522  // test match of leftmost bytes in given message to node's Kademlia address
   523  func (p *Pss) isSelfPossibleRecipient(msg *PssMsg, prox bool) bool {
   524  	local := p.Kademlia.BaseAddr()
   525  
   526  	// if a partial address matches we are possible recipient regardless of prox
   527  	// if not and prox is not set, we are surely not
   528  	if bytes.Equal(msg.To, local[:len(msg.To)]) {
   529  
   530  		return true
   531  	} else if !prox {
   532  		return false
   533  	}
   534  
   535  	depth := p.Kademlia.NeighbourhoodDepth()
   536  	po, _ := network.Pof(p.Kademlia.BaseAddr(), msg.To, 0)
   537  	log.Trace("selfpossible", "po", po, "depth", depth)
   538  
   539  	return depth <= po
   540  }
   541  
   542  /////////////////////////////////////////////////////////////////////
   543  // SECTION: Encryption
   544  /////////////////////////////////////////////////////////////////////
   545  
   546  // Links a peer ECDSA public key to a topic
   547  //
   548  // This is required for asymmetric message exchange
   549  // on the given topic
   550  //
   551  // The value in `address` will be used as a routing hint for the
   552  // public key / topic association
   553  func (p *Pss) SetPeerPublicKey(pubkey *ecdsa.PublicKey, topic Topic, address PssAddress) error {
   554  	if err := validateAddress(address); err != nil {
   555  		return err
   556  	}
   557  	pubkeybytes := crypto.FromECDSAPub(pubkey)
   558  	if len(pubkeybytes) == 0 {
   559  		return fmt.Errorf("invalid public key: %v", pubkey)
   560  	}
   561  	pubkeyid := common.ToHex(pubkeybytes)
   562  	psp := &pssPeer{
   563  		address: address,
   564  	}
   565  	p.pubKeyPoolMu.Lock()
   566  	if _, ok := p.pubKeyPool[pubkeyid]; !ok {
   567  		p.pubKeyPool[pubkeyid] = make(map[Topic]*pssPeer)
   568  	}
   569  	p.pubKeyPool[pubkeyid][topic] = psp
   570  	p.pubKeyPoolMu.Unlock()
   571  	log.Trace("added pubkey", "pubkeyid", pubkeyid, "topic", topic, "address", address)
   572  	return nil
   573  }
   574  
   575  // Automatically generate a new symkey for a topic and address hint
   576  func (p *Pss) GenerateSymmetricKey(topic Topic, address PssAddress, addToCache bool) (string, error) {
   577  	keyid, err := p.w.GenerateSymKey()
   578  	if err != nil {
   579  		return "", err
   580  	}
   581  	p.addSymmetricKeyToPool(keyid, topic, address, addToCache, false)
   582  	return keyid, nil
   583  }
   584  
   585  // Links a peer symmetric key (arbitrary byte sequence) to a topic
   586  //
   587  // This is required for symmetrically encrypted message exchange
   588  // on the given topic
   589  //
   590  // The key is stored in the whisper backend.
   591  //
   592  // If addtocache is set to true, the key will be added to the cache of keys
   593  // used to attempt symmetric decryption of incoming messages.
   594  //
   595  // Returns a string id that can be used to retrieve the key bytes
   596  // from the whisper backend (see pss.GetSymmetricKey())
   597  func (p *Pss) SetSymmetricKey(key []byte, topic Topic, address PssAddress, addtocache bool) (string, error) {
   598  	if err := validateAddress(address); err != nil {
   599  		return "", err
   600  	}
   601  	return p.setSymmetricKey(key, topic, address, addtocache, true)
   602  }
   603  
   604  func (p *Pss) setSymmetricKey(key []byte, topic Topic, address PssAddress, addtocache bool, protected bool) (string, error) {
   605  	keyid, err := p.w.AddSymKeyDirect(key)
   606  	if err != nil {
   607  		return "", err
   608  	}
   609  	p.addSymmetricKeyToPool(keyid, topic, address, addtocache, protected)
   610  	return keyid, nil
   611  }
   612  
   613  // adds a symmetric key to the pss key pool, and optionally adds the key
   614  // to the collection of keys used to attempt symmetric decryption of
   615  // incoming messages
   616  func (p *Pss) addSymmetricKeyToPool(keyid string, topic Topic, address PssAddress, addtocache bool, protected bool) {
   617  	psp := &pssPeer{
   618  		address:   address,
   619  		protected: protected,
   620  	}
   621  	p.symKeyPoolMu.Lock()
   622  	if _, ok := p.symKeyPool[keyid]; !ok {
   623  		p.symKeyPool[keyid] = make(map[Topic]*pssPeer)
   624  	}
   625  	p.symKeyPool[keyid][topic] = psp
   626  	p.symKeyPoolMu.Unlock()
   627  	if addtocache {
   628  		p.symKeyDecryptCacheCursor++
   629  		p.symKeyDecryptCache[p.symKeyDecryptCacheCursor%cap(p.symKeyDecryptCache)] = &keyid
   630  	}
   631  	key, _ := p.GetSymmetricKey(keyid)
   632  	log.Trace("added symkey", "symkeyid", keyid, "symkey", common.ToHex(key), "topic", topic, "address", address, "cache", addtocache)
   633  }
   634  
   635  // Returns a symmetric key byte seqyence stored in the whisper backend
   636  // by its unique id
   637  //
   638  // Passes on the error value from the whisper backend
   639  func (p *Pss) GetSymmetricKey(symkeyid string) ([]byte, error) {
   640  	symkey, err := p.w.GetSymKey(symkeyid)
   641  	if err != nil {
   642  		return nil, err
   643  	}
   644  	return symkey, nil
   645  }
   646  
   647  // Returns all recorded topic and address combination for a specific public key
   648  func (p *Pss) GetPublickeyPeers(keyid string) (topic []Topic, address []PssAddress, err error) {
   649  	p.pubKeyPoolMu.RLock()
   650  	defer p.pubKeyPoolMu.RUnlock()
   651  	for t, peer := range p.pubKeyPool[keyid] {
   652  		topic = append(topic, t)
   653  		address = append(address, peer.address)
   654  	}
   655  
   656  	return topic, address, nil
   657  }
   658  
   659  func (p *Pss) getPeerAddress(keyid string, topic Topic) (PssAddress, error) {
   660  	p.pubKeyPoolMu.RLock()
   661  	defer p.pubKeyPoolMu.RUnlock()
   662  	if peers, ok := p.pubKeyPool[keyid]; ok {
   663  		if t, ok := peers[topic]; ok {
   664  			return t.address, nil
   665  		}
   666  	}
   667  	return nil, fmt.Errorf("peer with pubkey %s, topic %x not found", keyid, topic)
   668  }
   669  
   670  // Attempt to decrypt, validate and unpack a
   671  // symmetrically encrypted message
   672  // If successful, returns the unpacked whisper ReceivedMessage struct
   673  // encapsulating the decrypted message, and the whisper backend id
   674  // of the symmetric key used to decrypt the message.
   675  // It fails if decryption of the message fails or if the message is corrupted
   676  func (p *Pss) processSym(envelope *whisper.Envelope) (*whisper.ReceivedMessage, string, PssAddress, error) {
   677  	metrics.GetOrRegisterCounter("pss.process.sym", nil).Inc(1)
   678  
   679  	for i := p.symKeyDecryptCacheCursor; i > p.symKeyDecryptCacheCursor-cap(p.symKeyDecryptCache) && i > 0; i-- {
   680  		symkeyid := p.symKeyDecryptCache[i%cap(p.symKeyDecryptCache)]
   681  		symkey, err := p.w.GetSymKey(*symkeyid)
   682  		if err != nil {
   683  			continue
   684  		}
   685  		recvmsg, err := envelope.OpenSymmetric(symkey)
   686  		if err != nil {
   687  			continue
   688  		}
   689  		if !recvmsg.Validate() {
   690  			return nil, "", nil, fmt.Errorf("symmetrically encrypted message has invalid signature or is corrupt")
   691  		}
   692  		p.symKeyPoolMu.Lock()
   693  		from := p.symKeyPool[*symkeyid][Topic(envelope.Topic)].address
   694  		p.symKeyPoolMu.Unlock()
   695  		p.symKeyDecryptCacheCursor++
   696  		p.symKeyDecryptCache[p.symKeyDecryptCacheCursor%cap(p.symKeyDecryptCache)] = symkeyid
   697  		return recvmsg, *symkeyid, from, nil
   698  	}
   699  	return nil, "", nil, fmt.Errorf("could not decrypt message")
   700  }
   701  
   702  // Attempt to decrypt, validate and unpack an
   703  // asymmetrically encrypted message
   704  // If successful, returns the unpacked whisper ReceivedMessage struct
   705  // encapsulating the decrypted message, and the byte representation of
   706  // the public key used to decrypt the message.
   707  // It fails if decryption of message fails, or if the message is corrupted
   708  func (p *Pss) processAsym(envelope *whisper.Envelope) (*whisper.ReceivedMessage, string, PssAddress, error) {
   709  	metrics.GetOrRegisterCounter("pss.process.asym", nil).Inc(1)
   710  
   711  	recvmsg, err := envelope.OpenAsymmetric(p.privateKey)
   712  	if err != nil {
   713  		return nil, "", nil, fmt.Errorf("could not decrypt message: %s", err)
   714  	}
   715  	// check signature (if signed), strip padding
   716  	if !recvmsg.Validate() {
   717  		return nil, "", nil, fmt.Errorf("invalid message")
   718  	}
   719  	pubkeyid := common.ToHex(crypto.FromECDSAPub(recvmsg.Src))
   720  	var from PssAddress
   721  	p.pubKeyPoolMu.Lock()
   722  	if p.pubKeyPool[pubkeyid][Topic(envelope.Topic)] != nil {
   723  		from = p.pubKeyPool[pubkeyid][Topic(envelope.Topic)].address
   724  	}
   725  	p.pubKeyPoolMu.Unlock()
   726  	return recvmsg, pubkeyid, from, nil
   727  }
   728  
   729  // Symkey garbage collection
   730  // a key is removed if:
   731  // - it is not marked as protected
   732  // - it is not in the incoming decryption cache
   733  func (p *Pss) cleanKeys() (count int) {
   734  	for keyid, peertopics := range p.symKeyPool {
   735  		var expiredtopics []Topic
   736  		for topic, psp := range peertopics {
   737  			if psp.protected {
   738  				continue
   739  			}
   740  
   741  			var match bool
   742  			for i := p.symKeyDecryptCacheCursor; i > p.symKeyDecryptCacheCursor-cap(p.symKeyDecryptCache) && i > 0; i-- {
   743  				cacheid := p.symKeyDecryptCache[i%cap(p.symKeyDecryptCache)]
   744  				if *cacheid == keyid {
   745  					match = true
   746  				}
   747  			}
   748  			if !match {
   749  				expiredtopics = append(expiredtopics, topic)
   750  			}
   751  		}
   752  		for _, topic := range expiredtopics {
   753  			p.symKeyPoolMu.Lock()
   754  			delete(p.symKeyPool[keyid], topic)
   755  			log.Trace("symkey cleanup deletion", "symkeyid", keyid, "topic", topic, "val", p.symKeyPool[keyid])
   756  			p.symKeyPoolMu.Unlock()
   757  			count++
   758  		}
   759  	}
   760  	return
   761  }
   762  
   763  /////////////////////////////////////////////////////////////////////
   764  // SECTION: Message sending
   765  /////////////////////////////////////////////////////////////////////
   766  
   767  func (p *Pss) enqueue(msg *PssMsg) error {
   768  	select {
   769  	case p.outbox <- msg:
   770  		return nil
   771  	default:
   772  	}
   773  
   774  	metrics.GetOrRegisterCounter("pss.enqueue.outbox.full", nil).Inc(1)
   775  	return errors.New("outbox full")
   776  }
   777  
   778  // Send a raw message (any encryption is responsibility of calling client)
   779  //
   780  // Will fail if raw messages are disallowed
   781  func (p *Pss) SendRaw(address PssAddress, topic Topic, msg []byte) error {
   782  	if err := validateAddress(address); err != nil {
   783  		return err
   784  	}
   785  	pssMsgParams := &msgParams{
   786  		raw: true,
   787  	}
   788  	payload := &whisper.Envelope{
   789  		Data:  msg,
   790  		Topic: whisper.TopicType(topic),
   791  	}
   792  	pssMsg := newPssMsg(pssMsgParams)
   793  	pssMsg.To = address
   794  	pssMsg.Expire = uint32(time.Now().Add(p.msgTTL).Unix())
   795  	pssMsg.Payload = payload
   796  	p.addFwdCache(pssMsg)
   797  	err := p.enqueue(pssMsg)
   798  	if err != nil {
   799  		return err
   800  	}
   801  
   802  	// if we have a proxhandler on this topic
   803  	// also deliver message to ourselves
   804  	if capabilities, ok := p.getTopicHandlerCaps(topic); ok {
   805  		if p.isSelfPossibleRecipient(pssMsg, true) && capabilities.prox {
   806  			return p.process(pssMsg, true, true)
   807  		}
   808  	}
   809  	return nil
   810  }
   811  
   812  // Send a message using symmetric encryption
   813  //
   814  // Fails if the key id does not match any of the stored symmetric keys
   815  func (p *Pss) SendSym(symkeyid string, topic Topic, msg []byte) error {
   816  	symkey, err := p.GetSymmetricKey(symkeyid)
   817  	if err != nil {
   818  		return fmt.Errorf("missing valid send symkey %s: %v", symkeyid, err)
   819  	}
   820  	p.symKeyPoolMu.Lock()
   821  	psp, ok := p.symKeyPool[symkeyid][topic]
   822  	p.symKeyPoolMu.Unlock()
   823  	if !ok {
   824  		return fmt.Errorf("invalid topic '%s' for symkey '%s'", topic.String(), symkeyid)
   825  	}
   826  	return p.send(psp.address, topic, msg, false, symkey)
   827  }
   828  
   829  // Send a message using asymmetric encryption
   830  //
   831  // Fails if the key id does not match any in of the stored public keys
   832  func (p *Pss) SendAsym(pubkeyid string, topic Topic, msg []byte) error {
   833  	if _, err := crypto.UnmarshalPubkey(common.FromHex(pubkeyid)); err != nil {
   834  		return fmt.Errorf("Cannot unmarshal pubkey: %x", pubkeyid)
   835  	}
   836  	p.pubKeyPoolMu.Lock()
   837  	psp, ok := p.pubKeyPool[pubkeyid][topic]
   838  	p.pubKeyPoolMu.Unlock()
   839  	if !ok {
   840  		return fmt.Errorf("invalid topic '%s' for pubkey '%s'", topic.String(), pubkeyid)
   841  	}
   842  	return p.send(psp.address, topic, msg, true, common.FromHex(pubkeyid))
   843  }
   844  
   845  // Send is payload agnostic, and will accept any byte slice as payload
   846  // It generates an whisper envelope for the specified recipient and topic,
   847  // and wraps the message payload in it.
   848  // TODO: Implement proper message padding
   849  func (p *Pss) send(to []byte, topic Topic, msg []byte, asymmetric bool, key []byte) error {
   850  	metrics.GetOrRegisterCounter("pss.send", nil).Inc(1)
   851  
   852  	if key == nil || bytes.Equal(key, []byte{}) {
   853  		return fmt.Errorf("Zero length key passed to pss send")
   854  	}
   855  	padding := make([]byte, p.paddingByteSize)
   856  	c, err := rand.Read(padding)
   857  	if err != nil {
   858  		return err
   859  	} else if c < p.paddingByteSize {
   860  		return fmt.Errorf("invalid padding length: %d", c)
   861  	}
   862  	wparams := &whisper.MessageParams{
   863  		TTL:      defaultWhisperTTL,
   864  		Src:      p.privateKey,
   865  		Topic:    whisper.TopicType(topic),
   866  		WorkTime: defaultWhisperWorkTime,
   867  		PoW:      defaultWhisperPoW,
   868  		Payload:  msg,
   869  		Padding:  padding,
   870  	}
   871  	if asymmetric {
   872  		pk, err := crypto.UnmarshalPubkey(key)
   873  		if err != nil {
   874  			return fmt.Errorf("Cannot unmarshal pubkey: %x", key)
   875  		}
   876  		wparams.Dst = pk
   877  	} else {
   878  		wparams.KeySym = key
   879  	}
   880  	// set up outgoing message container, which does encryption and envelope wrapping
   881  	woutmsg, err := whisper.NewSentMessage(wparams)
   882  	if err != nil {
   883  		return fmt.Errorf("failed to generate whisper message encapsulation: %v", err)
   884  	}
   885  	// performs encryption.
   886  	// Does NOT perform / performs negligible PoW due to very low difficulty setting
   887  	// after this the message is ready for sending
   888  	envelope, err := woutmsg.Wrap(wparams)
   889  	if err != nil {
   890  		return fmt.Errorf("failed to perform whisper encryption: %v", err)
   891  	}
   892  	log.Trace("pssmsg whisper done", "env", envelope, "wparams payload", common.ToHex(wparams.Payload), "to", common.ToHex(to), "asym", asymmetric, "key", common.ToHex(key))
   893  
   894  	// prepare for devp2p transport
   895  	pssMsgParams := &msgParams{
   896  		sym: !asymmetric,
   897  	}
   898  	pssMsg := newPssMsg(pssMsgParams)
   899  	pssMsg.To = to
   900  	pssMsg.Expire = uint32(time.Now().Add(p.msgTTL).Unix())
   901  	pssMsg.Payload = envelope
   902  	err = p.enqueue(pssMsg)
   903  	if err != nil {
   904  		return err
   905  	}
   906  	if capabilities, ok := p.getTopicHandlerCaps(topic); ok {
   907  		if p.isSelfPossibleRecipient(pssMsg, true) && capabilities.prox {
   908  			return p.process(pssMsg, true, true)
   909  		}
   910  	}
   911  	return nil
   912  }
   913  
   914  // sendFunc is a helper function that tries to send a message and returns true on success.
   915  // It is set here for usage in production, and optionally overridden in tests.
   916  var sendFunc func(p *Pss, sp *network.Peer, msg *PssMsg) bool = sendMsg
   917  
   918  // tries to send a message, returns true if successful
   919  func sendMsg(p *Pss, sp *network.Peer, msg *PssMsg) bool {
   920  	var isPssEnabled bool
   921  	info := sp.Info()
   922  	for _, capability := range info.Caps {
   923  		if capability == p.capstring {
   924  			isPssEnabled = true
   925  			break
   926  		}
   927  	}
   928  	if !isPssEnabled {
   929  		log.Error("peer doesn't have matching pss capabilities, skipping", "peer", info.Name, "caps", info.Caps)
   930  		return false
   931  	}
   932  
   933  	// get the protocol peer from the forwarding peer cache
   934  	p.fwdPoolMu.RLock()
   935  	pp := p.fwdPool[sp.Info().ID]
   936  	p.fwdPoolMu.RUnlock()
   937  
   938  	err := pp.Send(context.TODO(), msg)
   939  	if err != nil {
   940  		metrics.GetOrRegisterCounter("pss.pp.send.error", nil).Inc(1)
   941  		log.Error(err.Error())
   942  	}
   943  
   944  	return err == nil
   945  }
   946  
   947  // Forwards a pss message to the peer(s) based on recipient address according to the algorithm
   948  // described below. The recipient address can be of any length, and the byte slice will be matched
   949  // to the MSB slice of the peer address of the equivalent length.
   950  //
   951  // If the recipient address (or partial address) is within the neighbourhood depth of the forwarding
   952  // node, then it will be forwarded to all the nearest neighbours of the forwarding node. In case of
   953  // partial address, it should be forwarded to all the peers matching the partial address, if there
   954  // are any; otherwise only to one peer, closest to the recipient address. In any case, if the message
   955  // forwarding fails, the node should try to forward it to the next best peer, until the message is
   956  // successfully forwarded to at least one peer.
   957  func (p *Pss) forward(msg *PssMsg) error {
   958  	metrics.GetOrRegisterCounter("pss.forward", nil).Inc(1)
   959  	sent := 0 // number of successful sends
   960  	to := make([]byte, addressLength)
   961  	copy(to[:len(msg.To)], msg.To)
   962  	neighbourhoodDepth := p.Kademlia.NeighbourhoodDepth()
   963  
   964  	// luminosity is the opposite of darkness. the more bytes are removed from the address, the higher is darkness,
   965  	// but the luminosity is less. here luminosity equals the number of bits given in the destination address.
   966  	luminosityRadius := len(msg.To) * 8
   967  
   968  	// proximity order function matching up to neighbourhoodDepth bits (po <= neighbourhoodDepth)
   969  	pof := pot.DefaultPof(neighbourhoodDepth)
   970  
   971  	// soft threshold for msg broadcast
   972  	broadcastThreshold, _ := pof(to, p.BaseAddr(), 0)
   973  	if broadcastThreshold > luminosityRadius {
   974  		broadcastThreshold = luminosityRadius
   975  	}
   976  
   977  	var onlySendOnce bool // indicates if the message should only be sent to one peer with closest address
   978  
   979  	// if measured from the recipient address as opposed to the base address (see Kademlia.EachConn
   980  	// call below), then peers that fall in the same proximity bin as recipient address will appear
   981  	// [at least] one bit closer, but only if these additional bits are given in the recipient address.
   982  	if broadcastThreshold < luminosityRadius && broadcastThreshold < neighbourhoodDepth {
   983  		broadcastThreshold++
   984  		onlySendOnce = true
   985  	}
   986  
   987  	p.Kademlia.EachConn(to, addressLength*8, func(sp *network.Peer, po int) bool {
   988  		if po < broadcastThreshold && sent > 0 {
   989  			return false // stop iterating
   990  		}
   991  		if sendFunc(p, sp, msg) {
   992  			sent++
   993  			if onlySendOnce {
   994  				return false
   995  			}
   996  			if po == addressLength*8 {
   997  				// stop iterating if successfully sent to the exact recipient (perfect match of full address)
   998  				return false
   999  			}
  1000  		}
  1001  		return true
  1002  	})
  1003  
  1004  	// if we failed to send to anyone, re-insert message in the send-queue
  1005  	if sent == 0 {
  1006  		log.Debug("unable to forward to any peers")
  1007  		if err := p.enqueue(msg); err != nil {
  1008  			metrics.GetOrRegisterCounter("pss.forward.enqueue.error", nil).Inc(1)
  1009  			log.Error(err.Error())
  1010  			return err
  1011  		}
  1012  	}
  1013  
  1014  	// cache the message
  1015  	p.addFwdCache(msg)
  1016  	return nil
  1017  }
  1018  
  1019  /////////////////////////////////////////////////////////////////////
  1020  // SECTION: Caching
  1021  /////////////////////////////////////////////////////////////////////
  1022  
  1023  // cleanFwdCache is used to periodically remove expired entries from the forward cache
  1024  func (p *Pss) cleanFwdCache() {
  1025  	metrics.GetOrRegisterCounter("pss.cleanfwdcache", nil).Inc(1)
  1026  	p.fwdCacheMu.Lock()
  1027  	defer p.fwdCacheMu.Unlock()
  1028  	for k, v := range p.fwdCache {
  1029  		if v.expiresAt.Before(time.Now()) {
  1030  			delete(p.fwdCache, k)
  1031  		}
  1032  	}
  1033  }
  1034  
  1035  func label(b []byte) string {
  1036  	return fmt.Sprintf("%04x", b[:2])
  1037  }
  1038  
  1039  // add a message to the cache
  1040  func (p *Pss) addFwdCache(msg *PssMsg) error {
  1041  	metrics.GetOrRegisterCounter("pss.addfwdcache", nil).Inc(1)
  1042  
  1043  	var entry pssCacheEntry
  1044  	var ok bool
  1045  
  1046  	p.fwdCacheMu.Lock()
  1047  	defer p.fwdCacheMu.Unlock()
  1048  
  1049  	digest := p.digest(msg)
  1050  	if entry, ok = p.fwdCache[digest]; !ok {
  1051  		entry = pssCacheEntry{}
  1052  	}
  1053  	entry.expiresAt = time.Now().Add(p.cacheTTL)
  1054  	p.fwdCache[digest] = entry
  1055  	return nil
  1056  }
  1057  
  1058  // check if message is in the cache
  1059  func (p *Pss) checkFwdCache(msg *PssMsg) bool {
  1060  	p.fwdCacheMu.Lock()
  1061  	defer p.fwdCacheMu.Unlock()
  1062  
  1063  	digest := p.digest(msg)
  1064  	entry, ok := p.fwdCache[digest]
  1065  	if ok {
  1066  		if entry.expiresAt.After(time.Now()) {
  1067  			log.Trace("unexpired cache", "digest", fmt.Sprintf("%x", digest))
  1068  			metrics.GetOrRegisterCounter("pss.checkfwdcache.unexpired", nil).Inc(1)
  1069  			return true
  1070  		}
  1071  		metrics.GetOrRegisterCounter("pss.checkfwdcache.expired", nil).Inc(1)
  1072  	}
  1073  	return false
  1074  }
  1075  
  1076  // Digest of message
  1077  func (p *Pss) digest(msg *PssMsg) pssDigest {
  1078  	return p.digestBytes(msg.serialize())
  1079  }
  1080  
  1081  func (p *Pss) digestBytes(msg []byte) pssDigest {
  1082  	hasher := p.hashPool.Get().(hash.Hash)
  1083  	defer p.hashPool.Put(hasher)
  1084  	hasher.Reset()
  1085  	hasher.Write(msg)
  1086  	digest := pssDigest{}
  1087  	key := hasher.Sum(nil)
  1088  	copy(digest[:], key[:digestLength])
  1089  	return digest
  1090  }
  1091  
  1092  func validateAddress(addr PssAddress) error {
  1093  	if len(addr) > addressLength {
  1094  		return errors.New("address too long")
  1095  	}
  1096  	return nil
  1097  }