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 }