github.com/digdeepmining/go-atheios@v1.5.13-0.20180902133602-d5687a2e6f43/whisper/whisperv5/whisper.go (about) 1 // Copyright 2016 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 whisperv5 18 19 import ( 20 "bytes" 21 "crypto/ecdsa" 22 crand "crypto/rand" 23 "crypto/sha256" 24 "fmt" 25 "runtime" 26 "sync" 27 "time" 28 29 "github.com/atheioschain/go-atheios/common" 30 "github.com/atheioschain/go-atheios/crypto" 31 "github.com/atheioschain/go-atheios/logger" 32 "github.com/atheioschain/go-atheios/logger/glog" 33 "github.com/atheioschain/go-atheios/p2p" 34 "golang.org/x/crypto/pbkdf2" 35 set "gopkg.in/fatih/set.v0" 36 ) 37 38 // Whisper represents a dark communication interface through the Ethereum 39 // network, using its very own P2P communication layer. 40 type Whisper struct { 41 protocol p2p.Protocol 42 filters *Filters 43 44 privateKeys map[string]*ecdsa.PrivateKey 45 symKeys map[string][]byte 46 keyMu sync.RWMutex 47 48 envelopes map[common.Hash]*Envelope // Pool of envelopes currently tracked by this node 49 messages map[common.Hash]*ReceivedMessage // Pool of successfully decrypted messages, which are not expired yet 50 expirations map[uint32]*set.SetNonTS // Message expiration pool 51 poolMu sync.RWMutex // Mutex to sync the message and expiration pools 52 53 peers map[*Peer]struct{} // Set of currently active peers 54 peerMu sync.RWMutex // Mutex to sync the active peer set 55 56 mailServer MailServer 57 58 messageQueue chan *Envelope 59 p2pMsgQueue chan *Envelope 60 quit chan struct{} 61 62 overflow bool 63 test bool 64 } 65 66 // New creates a Whisper client ready to communicate through the Ethereum P2P network. 67 // Param s should be passed if you want to implement mail server, otherwise nil. 68 func NewWhisper(server MailServer) *Whisper { 69 whisper := &Whisper{ 70 privateKeys: make(map[string]*ecdsa.PrivateKey), 71 symKeys: make(map[string][]byte), 72 envelopes: make(map[common.Hash]*Envelope), 73 messages: make(map[common.Hash]*ReceivedMessage), 74 expirations: make(map[uint32]*set.SetNonTS), 75 peers: make(map[*Peer]struct{}), 76 mailServer: server, 77 messageQueue: make(chan *Envelope, messageQueueLimit), 78 p2pMsgQueue: make(chan *Envelope, messageQueueLimit), 79 quit: make(chan struct{}), 80 } 81 whisper.filters = NewFilters(whisper) 82 83 // p2p whisper sub protocol handler 84 whisper.protocol = p2p.Protocol{ 85 Name: ProtocolName, 86 Version: uint(ProtocolVersion), 87 Length: NumberOfMessageCodes, 88 Run: whisper.HandlePeer, 89 } 90 91 return whisper 92 } 93 94 // Protocols returns the whisper sub-protocols ran by this particular client. 95 func (w *Whisper) Protocols() []p2p.Protocol { 96 return []p2p.Protocol{w.protocol} 97 } 98 99 // Version returns the whisper sub-protocols version number. 100 func (w *Whisper) Version() uint { 101 return w.protocol.Version 102 } 103 104 func (w *Whisper) getPeer(peerID []byte) (*Peer, error) { 105 w.peerMu.Lock() 106 defer w.peerMu.Unlock() 107 for p := range w.peers { 108 id := p.peer.ID() 109 if bytes.Equal(peerID, id[:]) { 110 return p, nil 111 } 112 } 113 return nil, fmt.Errorf("Could not find peer with ID: %x", peerID) 114 } 115 116 // MarkPeerTrusted marks specific peer trusted, which will allow it 117 // to send historic (expired) messages. 118 func (w *Whisper) MarkPeerTrusted(peerID []byte) error { 119 p, err := w.getPeer(peerID) 120 if err != nil { 121 return err 122 } 123 p.trusted = true 124 return nil 125 } 126 127 func (w *Whisper) RequestHistoricMessages(peerID []byte, envelope *Envelope) error { 128 p, err := w.getPeer(peerID) 129 if err != nil { 130 return err 131 } 132 p.trusted = true 133 return p2p.Send(p.ws, p2pRequestCode, envelope) 134 } 135 136 func (w *Whisper) SendP2PMessage(peerID []byte, envelope *Envelope) error { 137 p, err := w.getPeer(peerID) 138 if err != nil { 139 return err 140 } 141 return p2p.Send(p.ws, p2pCode, envelope) 142 } 143 144 func (w *Whisper) SendP2PDirect(peer *Peer, envelope *Envelope) error { 145 return p2p.Send(peer.ws, p2pCode, envelope) 146 } 147 148 // NewIdentity generates a new cryptographic identity for the client, and injects 149 // it into the known identities for message decryption. 150 func (w *Whisper) NewIdentity() *ecdsa.PrivateKey { 151 key, err := crypto.GenerateKey() 152 if err != nil || !validatePrivateKey(key) { 153 key, err = crypto.GenerateKey() // retry once 154 } 155 if err != nil { 156 panic(err) 157 } 158 if !validatePrivateKey(key) { 159 panic("Failed to generate valid key") 160 } 161 w.keyMu.Lock() 162 defer w.keyMu.Unlock() 163 w.privateKeys[common.ToHex(crypto.FromECDSAPub(&key.PublicKey))] = key 164 return key 165 } 166 167 // DeleteIdentity deletes the specified key if it exists. 168 func (w *Whisper) DeleteIdentity(key string) { 169 w.keyMu.Lock() 170 defer w.keyMu.Unlock() 171 delete(w.privateKeys, key) 172 } 173 174 // HasIdentity checks if the the whisper node is configured with the private key 175 // of the specified public pair. 176 func (w *Whisper) HasIdentity(pubKey string) bool { 177 w.keyMu.RLock() 178 defer w.keyMu.RUnlock() 179 return w.privateKeys[pubKey] != nil 180 } 181 182 // GetIdentity retrieves the private key of the specified public identity. 183 func (w *Whisper) GetIdentity(pubKey string) *ecdsa.PrivateKey { 184 w.keyMu.RLock() 185 defer w.keyMu.RUnlock() 186 return w.privateKeys[pubKey] 187 } 188 189 func (w *Whisper) GenerateSymKey(name string) error { 190 const size = aesKeyLength * 2 191 buf := make([]byte, size) 192 _, err := crand.Read(buf) 193 if err != nil { 194 return err 195 } else if !validateSymmetricKey(buf) { 196 return fmt.Errorf("error in GenerateSymKey: crypto/rand failed to generate random data") 197 } 198 199 key := buf[:aesKeyLength] 200 salt := buf[aesKeyLength:] 201 derived, err := DeriveOneTimeKey(key, salt, EnvelopeVersion) 202 if err != nil { 203 return err 204 } else if !validateSymmetricKey(derived) { 205 return fmt.Errorf("failed to derive valid key") 206 } 207 208 w.keyMu.Lock() 209 defer w.keyMu.Unlock() 210 211 if w.symKeys[name] != nil { 212 return fmt.Errorf("Key with name [%s] already exists", name) 213 } 214 w.symKeys[name] = derived 215 return nil 216 } 217 218 func (w *Whisper) AddSymKey(name string, key []byte) error { 219 if w.HasSymKey(name) { 220 return fmt.Errorf("Key with name [%s] already exists", name) 221 } 222 223 derived, err := deriveKeyMaterial(key, EnvelopeVersion) 224 if err != nil { 225 return err 226 } 227 228 w.keyMu.Lock() 229 defer w.keyMu.Unlock() 230 231 // double check is necessary, because deriveKeyMaterial() is slow 232 if w.symKeys[name] != nil { 233 return fmt.Errorf("Key with name [%s] already exists", name) 234 } 235 w.symKeys[name] = derived 236 return nil 237 } 238 239 func (w *Whisper) HasSymKey(name string) bool { 240 w.keyMu.RLock() 241 defer w.keyMu.RUnlock() 242 return w.symKeys[name] != nil 243 } 244 245 func (w *Whisper) DeleteSymKey(name string) { 246 w.keyMu.Lock() 247 defer w.keyMu.Unlock() 248 delete(w.symKeys, name) 249 } 250 251 func (w *Whisper) GetSymKey(name string) []byte { 252 w.keyMu.RLock() 253 defer w.keyMu.RUnlock() 254 return w.symKeys[name] 255 } 256 257 // Watch installs a new message handler to run in case a matching packet arrives 258 // from the whisper network. 259 func (w *Whisper) Watch(f *Filter) uint32 { 260 return w.filters.Install(f) 261 } 262 263 func (w *Whisper) GetFilter(id uint32) *Filter { 264 return w.filters.Get(id) 265 } 266 267 // Unwatch removes an installed message handler. 268 func (w *Whisper) Unwatch(id uint32) { 269 w.filters.Uninstall(id) 270 } 271 272 // Send injects a message into the whisper send queue, to be distributed in the 273 // network in the coming cycles. 274 func (w *Whisper) Send(envelope *Envelope) error { 275 return w.add(envelope) 276 } 277 278 // Start implements node.Service, starting the background data propagation thread 279 // of the Whisper protocol. 280 func (w *Whisper) Start(*p2p.Server) error { 281 glog.V(logger.Info).Infoln("Whisper started") 282 go w.update() 283 284 numCPU := runtime.NumCPU() 285 for i := 0; i < numCPU; i++ { 286 go w.processQueue() 287 } 288 289 return nil 290 } 291 292 // Stop implements node.Service, stopping the background data propagation thread 293 // of the Whisper protocol. 294 func (w *Whisper) Stop() error { 295 close(w.quit) 296 glog.V(logger.Info).Infoln("Whisper stopped") 297 return nil 298 } 299 300 // handlePeer is called by the underlying P2P layer when the whisper sub-protocol 301 // connection is negotiated. 302 func (wh *Whisper) HandlePeer(peer *p2p.Peer, rw p2p.MsgReadWriter) error { 303 // Create the new peer and start tracking it 304 whisperPeer := newPeer(wh, peer, rw) 305 306 wh.peerMu.Lock() 307 wh.peers[whisperPeer] = struct{}{} 308 wh.peerMu.Unlock() 309 310 defer func() { 311 wh.peerMu.Lock() 312 delete(wh.peers, whisperPeer) 313 wh.peerMu.Unlock() 314 }() 315 316 // Run the peer handshake and state updates 317 if err := whisperPeer.handshake(); err != nil { 318 return err 319 } 320 whisperPeer.start() 321 defer whisperPeer.stop() 322 323 return wh.runMessageLoop(whisperPeer, rw) 324 } 325 326 // runMessageLoop reads and processes inbound messages directly to merge into client-global state. 327 func (wh *Whisper) runMessageLoop(p *Peer, rw p2p.MsgReadWriter) error { 328 for { 329 // fetch the next packet 330 packet, err := rw.ReadMsg() 331 if err != nil { 332 return err 333 } 334 335 switch packet.Code { 336 case statusCode: 337 // this should not happen, but no need to panic; just ignore this message. 338 glog.V(logger.Warn).Infof("%v: unxepected status message received", p.peer) 339 case messagesCode: 340 // decode the contained envelopes 341 var envelopes []*Envelope 342 if err := packet.Decode(&envelopes); err != nil { 343 glog.V(logger.Warn).Infof("%v: failed to decode envelope: [%v], peer will be disconnected", p.peer, err) 344 return fmt.Errorf("garbage received") 345 } 346 // inject all envelopes into the internal pool 347 for _, envelope := range envelopes { 348 if err := wh.add(envelope); err != nil { 349 glog.V(logger.Warn).Infof("%v: bad envelope received: [%v], peer will be disconnected", p.peer, err) 350 return fmt.Errorf("invalid envelope") 351 } 352 p.mark(envelope) 353 } 354 case p2pCode: 355 // peer-to-peer message, sent directly to peer bypassing PoW checks, etc. 356 // this message is not supposed to be forwarded to other peers, and 357 // therefore might not satisfy the PoW, expiry and other requirements. 358 // these messages are only accepted from the trusted peer. 359 if p.trusted { 360 var envelope Envelope 361 if err := packet.Decode(&envelope); err != nil { 362 glog.V(logger.Warn).Infof("%v: failed to decode direct message: [%v], peer will be disconnected", p.peer, err) 363 return fmt.Errorf("garbage received (directMessage)") 364 } 365 wh.postEvent(&envelope, true) 366 } 367 case p2pRequestCode: 368 // Must be processed if mail server is implemented. Otherwise ignore. 369 if wh.mailServer != nil { 370 var request Envelope 371 if err := packet.Decode(&request); err != nil { 372 glog.V(logger.Warn).Infof("%v: failed to decode p2p request message: [%v], peer will be disconnected", p.peer, err) 373 return fmt.Errorf("garbage received (p2p request)") 374 } 375 wh.mailServer.DeliverMail(p, &request) 376 } 377 default: 378 // New message types might be implemented in the future versions of Whisper. 379 // For forward compatibility, just ignore. 380 } 381 382 packet.Discard() 383 } 384 } 385 386 // add inserts a new envelope into the message pool to be distributed within the 387 // whisper network. It also inserts the envelope into the expiration pool at the 388 // appropriate time-stamp. In case of error, connection should be dropped. 389 func (wh *Whisper) add(envelope *Envelope) error { 390 now := uint32(time.Now().Unix()) 391 sent := envelope.Expiry - envelope.TTL 392 393 if sent > now { 394 if sent-SynchAllowance > now { 395 return fmt.Errorf("envelope created in the future [%x]", envelope.Hash()) 396 } else { 397 // recalculate PoW, adjusted for the time difference, plus one second for latency 398 envelope.calculatePoW(sent - now + 1) 399 } 400 } 401 402 if envelope.Expiry < now { 403 if envelope.Expiry+SynchAllowance*2 < now { 404 return fmt.Errorf("very old message") 405 } else { 406 glog.V(logger.Debug).Infof("expired envelope dropped [%x]", envelope.Hash()) 407 return nil // drop envelope without error 408 } 409 } 410 411 if len(envelope.Data) > MaxMessageLength { 412 return fmt.Errorf("huge messages are not allowed [%x]", envelope.Hash()) 413 } 414 415 if len(envelope.Version) > 4 { 416 return fmt.Errorf("oversized version [%x]", envelope.Hash()) 417 } 418 419 if len(envelope.AESNonce) > AESNonceMaxLength { 420 // the standard AES GSM nonce size is 12, 421 // but const gcmStandardNonceSize cannot be accessed directly 422 return fmt.Errorf("oversized AESNonce [%x]", envelope.Hash()) 423 } 424 425 if len(envelope.Salt) > saltLength { 426 return fmt.Errorf("oversized salt [%x]", envelope.Hash()) 427 } 428 429 if envelope.PoW() < MinimumPoW && !wh.test { 430 glog.V(logger.Debug).Infof("envelope with low PoW dropped: %f [%x]", envelope.PoW(), envelope.Hash()) 431 return nil // drop envelope without error 432 } 433 434 hash := envelope.Hash() 435 436 wh.poolMu.Lock() 437 _, alreadyCached := wh.envelopes[hash] 438 if !alreadyCached { 439 wh.envelopes[hash] = envelope 440 if wh.expirations[envelope.Expiry] == nil { 441 wh.expirations[envelope.Expiry] = set.NewNonTS() 442 } 443 if !wh.expirations[envelope.Expiry].Has(hash) { 444 wh.expirations[envelope.Expiry].Add(hash) 445 } 446 } 447 wh.poolMu.Unlock() 448 449 if alreadyCached { 450 glog.V(logger.Detail).Infof("whisper envelope already cached [%x]\n", envelope.Hash()) 451 } else { 452 glog.V(logger.Detail).Infof("cached whisper envelope [%x]: %v\n", envelope.Hash(), envelope) 453 wh.postEvent(envelope, false) // notify the local node about the new message 454 if wh.mailServer != nil { 455 wh.mailServer.Archive(envelope) 456 } 457 } 458 return nil 459 } 460 461 // postEvent queues the message for further processing. 462 func (w *Whisper) postEvent(envelope *Envelope, isP2P bool) { 463 // if the version of incoming message is higher than 464 // currently supported version, we can not decrypt it, 465 // and therefore just ignore this message 466 if envelope.Ver() <= EnvelopeVersion { 467 if isP2P { 468 w.p2pMsgQueue <- envelope 469 } else { 470 w.checkOverflow() 471 w.messageQueue <- envelope 472 } 473 } 474 } 475 476 // checkOverflow checks if message queue overflow occurs and reports it if necessary. 477 func (w *Whisper) checkOverflow() { 478 queueSize := len(w.messageQueue) 479 480 if queueSize == messageQueueLimit { 481 if !w.overflow { 482 w.overflow = true 483 glog.V(logger.Warn).Infoln("message queue overflow") 484 } 485 } else if queueSize <= messageQueueLimit/2 { 486 if w.overflow { 487 w.overflow = false 488 } 489 } 490 } 491 492 // processQueue delivers the messages to the watchers during the lifetime of the whisper node. 493 func (w *Whisper) processQueue() { 494 var e *Envelope 495 for { 496 select { 497 case <-w.quit: 498 return 499 500 case e = <-w.messageQueue: 501 w.filters.NotifyWatchers(e, false) 502 503 case e = <-w.p2pMsgQueue: 504 w.filters.NotifyWatchers(e, true) 505 } 506 } 507 } 508 509 // update loops until the lifetime of the whisper node, updating its internal 510 // state by expiring stale messages from the pool. 511 func (w *Whisper) update() { 512 // Start a ticker to check for expirations 513 expire := time.NewTicker(expirationCycle) 514 515 // Repeat updates until termination is requested 516 for { 517 select { 518 case <-expire.C: 519 w.expire() 520 521 case <-w.quit: 522 return 523 } 524 } 525 } 526 527 // expire iterates over all the expiration timestamps, removing all stale 528 // messages from the pools. 529 func (w *Whisper) expire() { 530 w.poolMu.Lock() 531 defer w.poolMu.Unlock() 532 533 now := uint32(time.Now().Unix()) 534 for then, hashSet := range w.expirations { 535 // Short circuit if a future time 536 if then > now { 537 continue 538 } 539 // Dump all expired messages and remove timestamp 540 hashSet.Each(func(v interface{}) bool { 541 delete(w.envelopes, v.(common.Hash)) 542 delete(w.messages, v.(common.Hash)) 543 return true 544 }) 545 w.expirations[then].Clear() 546 } 547 } 548 549 // envelopes retrieves all the messages currently pooled by the node. 550 func (w *Whisper) Envelopes() []*Envelope { 551 w.poolMu.RLock() 552 defer w.poolMu.RUnlock() 553 554 all := make([]*Envelope, 0, len(w.envelopes)) 555 for _, envelope := range w.envelopes { 556 all = append(all, envelope) 557 } 558 return all 559 } 560 561 // Messages retrieves all the decrypted messages matching a filter id. 562 func (w *Whisper) Messages(id uint32) []*ReceivedMessage { 563 result := make([]*ReceivedMessage, 0) 564 w.poolMu.RLock() 565 defer w.poolMu.RUnlock() 566 567 if filter := w.filters.Get(id); filter != nil { 568 for _, msg := range w.messages { 569 if filter.MatchMessage(msg) { 570 result = append(result, msg) 571 } 572 } 573 } 574 return result 575 } 576 577 func (w *Whisper) addDecryptedMessage(msg *ReceivedMessage) { 578 w.poolMu.Lock() 579 defer w.poolMu.Unlock() 580 581 w.messages[msg.EnvelopeHash] = msg 582 } 583 584 func ValidatePublicKey(k *ecdsa.PublicKey) bool { 585 return k != nil && k.X != nil && k.Y != nil && k.X.Sign() != 0 && k.Y.Sign() != 0 586 } 587 588 func validatePrivateKey(k *ecdsa.PrivateKey) bool { 589 if k == nil || k.D == nil || k.D.Sign() == 0 { 590 return false 591 } 592 return ValidatePublicKey(&k.PublicKey) 593 } 594 595 // validateSymmetricKey returns false if the key contains all zeros 596 func validateSymmetricKey(k []byte) bool { 597 return len(k) > 0 && !containsOnlyZeros(k) 598 } 599 600 func containsOnlyZeros(data []byte) bool { 601 for _, b := range data { 602 if b != 0 { 603 return false 604 } 605 } 606 return true 607 } 608 609 func bytesToIntLittleEndian(b []byte) (res uint64) { 610 mul := uint64(1) 611 for i := 0; i < len(b); i++ { 612 res += uint64(b[i]) * mul 613 mul *= 256 614 } 615 return res 616 } 617 618 func BytesToIntBigEndian(b []byte) (res uint64) { 619 for i := 0; i < len(b); i++ { 620 res *= 256 621 res += uint64(b[i]) 622 } 623 return res 624 } 625 626 // DeriveSymmetricKey derives symmetric key material from the key or password. 627 // pbkdf2 is used for security, in case people use password instead of randomly generated keys. 628 func deriveKeyMaterial(key []byte, version uint64) (derivedKey []byte, err error) { 629 if version == 0 { 630 // kdf should run no less than 0.1 seconds on average compute, 631 // because it's a once in a session experience 632 derivedKey := pbkdf2.Key(key, nil, 65356, aesKeyLength, sha256.New) 633 return derivedKey, nil 634 } else { 635 return nil, unknownVersionError(version) 636 } 637 }