github.com/status-im/status-go@v1.1.0/protocol/common/message_sender.go (about) 1 package common 2 3 import ( 4 "context" 5 "crypto/ecdsa" 6 "database/sql" 7 "math/rand" 8 "sync" 9 "time" 10 11 "github.com/golang/protobuf/proto" 12 "github.com/pkg/errors" 13 datasyncnode "github.com/status-im/mvds/node" 14 datasyncproto "github.com/status-im/mvds/protobuf" 15 "github.com/status-im/mvds/state" 16 "go.uber.org/zap" 17 18 "github.com/status-im/status-go/eth-node/crypto" 19 "github.com/status-im/status-go/eth-node/types" 20 "github.com/status-im/status-go/protocol/datasync" 21 datasyncpeer "github.com/status-im/status-go/protocol/datasync/peer" 22 "github.com/status-im/status-go/protocol/encryption" 23 "github.com/status-im/status-go/protocol/encryption/sharedsecret" 24 "github.com/status-im/status-go/protocol/protobuf" 25 "github.com/status-im/status-go/protocol/transport" 26 v1protocol "github.com/status-im/status-go/protocol/v1" 27 ) 28 29 // Whisper message properties. 30 const ( 31 whisperTTL = 15 32 whisperDefaultPoW = 0.002 33 // whisperLargeSizePoW is the PoWTarget for larger payload sizes 34 whisperLargeSizePoW = 0.000002 35 // largeSizeInBytes is when should we be using a lower POW. 36 // Roughly this is 50KB 37 largeSizeInBytes = 50000 38 whisperPoWTime = 5 39 maxMessageSenderEphemeralKeys = 3 40 ) 41 42 // RekeyCompatibility indicates whether we should be sending 43 // keys in 1-to-1 messages as well as in the newer format 44 var RekeyCompatibility = true 45 46 // SentMessage reprent a message that has been passed to the transport layer 47 type SentMessage struct { 48 PublicKey *ecdsa.PublicKey 49 Spec *encryption.ProtocolMessageSpec 50 MessageIDs [][]byte 51 } 52 53 type MessageEventType uint32 54 55 const ( 56 MessageScheduled = iota + 1 57 MessageSent 58 ) 59 60 type MessageEvent struct { 61 Recipient *ecdsa.PublicKey 62 Type MessageEventType 63 SentMessage *SentMessage 64 RawMessage *RawMessage 65 } 66 67 type MessageSender struct { 68 identity *ecdsa.PrivateKey 69 datasync *datasync.DataSync 70 database *sql.DB 71 protocol *encryption.Protocol 72 transport *transport.Transport 73 logger *zap.Logger 74 persistence *RawMessagesPersistence 75 76 datasyncEnabled bool 77 78 // ephemeralKeys is a map that contains the ephemeral keys of the client, used 79 // to decrypt messages 80 ephemeralKeys map[string]*ecdsa.PrivateKey 81 ephemeralKeysMutex sync.Mutex 82 83 // messageEventsSubscriptions contains all the subscriptions for message events 84 messageEventsSubscriptions []chan<- *MessageEvent 85 messageEventsSubscriptionsMutex sync.Mutex 86 87 featureFlags FeatureFlags 88 89 // handleSharedSecrets is a callback that is called every time a new shared secret is negotiated 90 handleSharedSecrets func([]*sharedsecret.Secret) error 91 } 92 93 func NewMessageSender( 94 identity *ecdsa.PrivateKey, 95 database *sql.DB, 96 enc *encryption.Protocol, 97 transport *transport.Transport, 98 logger *zap.Logger, 99 features FeatureFlags, 100 ) (*MessageSender, error) { 101 p := &MessageSender{ 102 identity: identity, 103 datasyncEnabled: features.Datasync, 104 protocol: enc, 105 database: database, 106 persistence: NewRawMessagesPersistence(database), 107 transport: transport, 108 logger: logger, 109 ephemeralKeys: make(map[string]*ecdsa.PrivateKey), 110 featureFlags: features, 111 } 112 113 return p, nil 114 } 115 116 func (s *MessageSender) Stop() { 117 s.messageEventsSubscriptionsMutex.Lock() 118 defer s.messageEventsSubscriptionsMutex.Unlock() 119 120 for _, c := range s.messageEventsSubscriptions { 121 close(c) 122 } 123 s.messageEventsSubscriptions = nil 124 s.StopDatasync() 125 } 126 127 func (s *MessageSender) SetHandleSharedSecrets(handler func([]*sharedsecret.Secret) error) { 128 s.handleSharedSecrets = handler 129 } 130 131 func (s *MessageSender) StartDatasync(statusChangeEvent chan datasyncnode.PeerStatusChangeEvent, handler func(peer state.PeerID, payload *datasyncproto.Payload) error) error { 132 if !s.datasyncEnabled { 133 return nil 134 } 135 136 dataSyncTransport := datasync.NewNodeTransport() 137 dataSyncNode, err := datasyncnode.NewPersistentNode( 138 s.database, 139 dataSyncTransport, 140 datasyncpeer.PublicKeyToPeerID(s.identity.PublicKey), 141 datasyncnode.BATCH, 142 datasync.CalculateSendTime, 143 statusChangeEvent, 144 s.logger, 145 ) 146 if err != nil { 147 return err 148 } 149 150 s.datasync = datasync.New(dataSyncNode, dataSyncTransport, true, s.logger) 151 152 s.datasync.Init(handler, s.logger) 153 s.datasync.Start(datasync.DatasyncTicker) 154 155 return nil 156 } 157 158 // SendPrivate takes encoded data, encrypts it and sends through the wire. 159 func (s *MessageSender) SendPrivate( 160 ctx context.Context, 161 recipient *ecdsa.PublicKey, 162 rawMessage *RawMessage, 163 ) ([]byte, error) { 164 s.logger.Debug( 165 "sending a private message", 166 zap.String("public-key", types.EncodeHex(crypto.FromECDSAPub(recipient))), 167 zap.String("site", "SendPrivate"), 168 ) 169 // Currently we don't support sending through datasync and setting custom waku fields, 170 // as the datasync interface is not rich enough to propagate that information, so we 171 // would have to add some complexity to handle this. 172 if rawMessage.ResendType == ResendTypeDataSync && (rawMessage.Sender != nil || rawMessage.SkipEncryptionLayer || rawMessage.SendOnPersonalTopic) { 173 return nil, errors.New("setting identity, skip-encryption or personal topic and datasync not supported") 174 } 175 176 // Set sender identity if not specified 177 if rawMessage.Sender == nil { 178 rawMessage.Sender = s.identity 179 } 180 181 return s.sendPrivate(ctx, recipient, rawMessage) 182 } 183 184 // SendCommunityMessage takes encoded data, encrypts it and sends through the wire 185 // using the community topic and their key 186 func (s *MessageSender) SendCommunityMessage( 187 ctx context.Context, 188 rawMessage *RawMessage, 189 ) ([]byte, error) { 190 s.logger.Debug( 191 "sending a community message", 192 zap.String("communityId", types.EncodeHex(rawMessage.CommunityID)), 193 zap.String("site", "SendCommunityMessage"), 194 ) 195 rawMessage.Sender = s.identity 196 197 return s.sendCommunity(ctx, rawMessage) 198 } 199 200 // SendPubsubTopicKey sends the protected topic key for a community to a list of recipients 201 func (s *MessageSender) SendPubsubTopicKey( 202 ctx context.Context, 203 rawMessage *RawMessage, 204 ) ([]byte, error) { 205 s.logger.Debug( 206 "sending the protected topic key for a community", 207 zap.String("communityId", types.EncodeHex(rawMessage.CommunityID)), 208 zap.String("site", "SendPubsubTopicKey"), 209 ) 210 rawMessage.Sender = s.identity 211 messageID, err := s.getMessageID(rawMessage) 212 if err != nil { 213 return nil, err 214 } 215 216 if err = s.setMessageID(messageID, rawMessage); err != nil { 217 return nil, err 218 } 219 220 // Notify before dispatching, otherwise the dispatch subscription might happen 221 // earlier than the scheduled 222 s.notifyOnScheduledMessage(nil, rawMessage) 223 224 // Send to each recipients 225 for _, recipient := range rawMessage.Recipients { 226 _, err = s.sendPrivate(ctx, recipient, rawMessage) 227 if err != nil { 228 return nil, errors.Wrap(err, "failed to send message") 229 } 230 } 231 return messageID, nil 232 233 } 234 235 // SendGroup takes encoded data, encrypts it and sends through the wire, 236 // always return the messageID 237 func (s *MessageSender) SendGroup( 238 ctx context.Context, 239 recipients []*ecdsa.PublicKey, 240 rawMessage RawMessage, 241 ) ([]byte, error) { 242 s.logger.Debug( 243 "sending a private group message", 244 zap.String("site", "SendGroup"), 245 ) 246 // Set sender if not specified 247 if rawMessage.Sender == nil { 248 rawMessage.Sender = s.identity 249 } 250 251 // Calculate messageID first and set on raw message 252 messageID, err := s.getMessageID(&rawMessage) 253 if err != nil { 254 return nil, err 255 } 256 257 if err = s.setMessageID(messageID, &rawMessage); err != nil { 258 return nil, err 259 } 260 261 // We call it only once, and we nil the function after so it doesn't get called again 262 if rawMessage.BeforeDispatch != nil { 263 if err := rawMessage.BeforeDispatch(&rawMessage); err != nil { 264 return nil, err 265 } 266 } 267 268 // Send to each recipients 269 for _, recipient := range recipients { 270 _, err = s.sendPrivate(ctx, recipient, &rawMessage) 271 if err != nil { 272 return nil, errors.Wrap(err, "failed to send message") 273 } 274 } 275 return messageID, nil 276 } 277 278 func (s *MessageSender) getMessageID(rawMessage *RawMessage) (types.HexBytes, error) { 279 wrappedMessage, err := s.wrapMessageV1(rawMessage) 280 if err != nil { 281 return nil, errors.Wrap(err, "failed to wrap message") 282 } 283 284 messageID := v1protocol.MessageID(&rawMessage.Sender.PublicKey, wrappedMessage) 285 return messageID, nil 286 } 287 288 func (s *MessageSender) ValidateRawMessage(rawMessage *RawMessage) error { 289 id, err := s.getMessageID(rawMessage) 290 if err != nil { 291 return err 292 } 293 messageID := types.EncodeHex(id) 294 295 return s.validateMessageID(messageID, rawMessage) 296 297 } 298 299 func (s *MessageSender) validateMessageID(messageID string, rawMessage *RawMessage) error { 300 if len(rawMessage.ID) > 0 && rawMessage.ID != messageID { 301 s.logger.Error("failed to validate message ID, RawMessage content was modified", 302 zap.String("prevID", rawMessage.ID), 303 zap.String("newID", messageID), 304 zap.Any("contentType", rawMessage.MessageType)) 305 return ErrModifiedRawMessage 306 } 307 return nil 308 } 309 310 func (s *MessageSender) setMessageID(messageID types.HexBytes, rawMessage *RawMessage) error { 311 msgID := types.EncodeHex(messageID) 312 313 if err := s.validateMessageID(msgID, rawMessage); err != nil { 314 return err 315 } 316 317 rawMessage.ID = msgID 318 return nil 319 } 320 321 func ShouldCommunityMessageBeEncrypted(msgType protobuf.ApplicationMetadataMessage_Type) bool { 322 return msgType == protobuf.ApplicationMetadataMessage_CHAT_MESSAGE || 323 msgType == protobuf.ApplicationMetadataMessage_EDIT_MESSAGE || 324 msgType == protobuf.ApplicationMetadataMessage_DELETE_MESSAGE || 325 msgType == protobuf.ApplicationMetadataMessage_PIN_MESSAGE || 326 msgType == protobuf.ApplicationMetadataMessage_EMOJI_REACTION 327 } 328 329 // sendCommunity sends a message that's to be sent in a community 330 // If it's a chat message, it will go to the respective topic derived by the 331 // chat id, if it's not a chat message, it will go to the community topic. 332 func (s *MessageSender) sendCommunity( 333 ctx context.Context, 334 rawMessage *RawMessage, 335 ) ([]byte, error) { 336 s.logger.Debug("sending community message", zap.String("recipient", types.EncodeHex(crypto.FromECDSAPub(&rawMessage.Sender.PublicKey)))) 337 338 // Set sender 339 if rawMessage.Sender == nil { 340 rawMessage.Sender = s.identity 341 } 342 343 messageID, err := s.getMessageID(rawMessage) 344 if err != nil { 345 return nil, err 346 } 347 348 if err = s.setMessageID(messageID, rawMessage); err != nil { 349 return nil, err 350 } 351 352 if rawMessage.BeforeDispatch != nil { 353 if err := rawMessage.BeforeDispatch(rawMessage); err != nil { 354 return nil, err 355 } 356 } 357 // Notify before dispatching, otherwise the dispatch subscription might happen 358 // earlier than the scheduled 359 s.notifyOnScheduledMessage(nil, rawMessage) 360 361 var hashes [][]byte 362 var newMessages []*types.NewMessage 363 364 forceRekey := rawMessage.CommunityKeyExMsgType == KeyExMsgRekey 365 366 // Check if it's a key exchange message. In this case we send it 367 // to all the recipients 368 if rawMessage.CommunityKeyExMsgType != KeyExMsgNone { 369 // If rekeycompatibility is on, we always 370 // want to execute below, otherwise we execute 371 // only when we want to fill up old keys to a given user 372 if RekeyCompatibility || !forceRekey { 373 keyExMessageSpecs, err := s.protocol.GetKeyExMessageSpecs(rawMessage.HashRatchetGroupID, s.identity, rawMessage.Recipients, forceRekey) 374 if err != nil { 375 return nil, err 376 } 377 378 for i, spec := range keyExMessageSpecs { 379 recipient := rawMessage.Recipients[i] 380 _, _, err = s.sendMessageSpec(ctx, recipient, spec, [][]byte{messageID}) 381 if err != nil { 382 return nil, err 383 } 384 } 385 } 386 } 387 388 wrappedMessage, err := s.wrapMessageV1(rawMessage) 389 if err != nil { 390 return nil, err 391 } 392 393 // If it's a chat message, we send it on the community chat topic 394 if ShouldCommunityMessageBeEncrypted(rawMessage.MessageType) { 395 messageSpec, err := s.protocol.BuildHashRatchetMessage(rawMessage.HashRatchetGroupID, wrappedMessage) 396 if err != nil { 397 return nil, err 398 } 399 400 payload, err := proto.Marshal(messageSpec.Message) 401 if err != nil { 402 return nil, errors.Wrap(err, "failed to marshal") 403 } 404 hashes, newMessages, err = s.dispatchCommunityChatMessage(ctx, rawMessage, payload, forceRekey) 405 if err != nil { 406 return nil, err 407 } 408 409 sentMessage := &SentMessage{ 410 Spec: messageSpec, 411 MessageIDs: [][]byte{messageID}, 412 } 413 414 s.notifyOnSentMessage(sentMessage) 415 416 } else { 417 418 pubkey, err := crypto.DecompressPubkey(rawMessage.CommunityID) 419 if err != nil { 420 return nil, errors.Wrap(err, "failed to decompress pubkey") 421 } 422 hashes, newMessages, err = s.dispatchCommunityMessage(ctx, pubkey, wrappedMessage, rawMessage.PubsubTopic, forceRekey, rawMessage) 423 if err != nil { 424 s.logger.Error("failed to send a community message", zap.Error(err)) 425 return nil, errors.Wrap(err, "failed to send a message spec") 426 } 427 } 428 429 s.logger.Debug("sent-message: community ", 430 zap.Strings("recipient", PubkeysToHex(rawMessage.Recipients)), 431 zap.String("messageID", messageID.String()), 432 zap.String("messageType", "community"), 433 zap.Any("contentType", rawMessage.MessageType), 434 zap.Strings("hashes", types.EncodeHexes(hashes))) 435 s.transport.Track(messageID, hashes, newMessages) 436 437 return messageID, nil 438 } 439 440 // sendPrivate sends data to the recipient identifying with a given public key. 441 func (s *MessageSender) sendPrivate( 442 ctx context.Context, 443 recipient *ecdsa.PublicKey, 444 rawMessage *RawMessage, 445 ) ([]byte, error) { 446 s.logger.Debug("sending private message", zap.String("recipient", types.EncodeHex(crypto.FromECDSAPub(recipient)))) 447 448 var wrappedMessage []byte 449 var err error 450 if rawMessage.SkipApplicationWrap { 451 wrappedMessage = rawMessage.Payload 452 } else { 453 wrappedMessage, err = s.wrapMessageV1(rawMessage) 454 if err != nil { 455 return nil, errors.Wrap(err, "failed to wrap message") 456 } 457 } 458 459 messageID := v1protocol.MessageID(&rawMessage.Sender.PublicKey, wrappedMessage) 460 461 if err = s.setMessageID(messageID, rawMessage); err != nil { 462 return nil, err 463 } 464 465 if rawMessage.BeforeDispatch != nil { 466 if err := rawMessage.BeforeDispatch(rawMessage); err != nil { 467 return nil, err 468 } 469 } 470 471 // Notify before dispatching, otherwise the dispatch subscription might happen 472 // earlier than the scheduled 473 s.notifyOnScheduledMessage(recipient, rawMessage) 474 475 if s.datasync != nil && s.featureFlags.Datasync && rawMessage.ResendType == ResendTypeDataSync { 476 // No need to call transport tracking. 477 // It is done in a data sync dispatch step. 478 datasyncID, err := s.addToDataSync(recipient, wrappedMessage) 479 if err != nil { 480 return nil, errors.Wrap(err, "failed to send message with datasync") 481 } 482 // We don't need to receive confirmations from our own devices 483 if !IsPubKeyEqual(recipient, &s.identity.PublicKey) { 484 confirmation := &RawMessageConfirmation{ 485 DataSyncID: datasyncID, 486 MessageID: messageID, 487 PublicKey: crypto.CompressPubkey(recipient), 488 } 489 490 err = s.persistence.InsertPendingConfirmation(confirmation) 491 if err != nil { 492 return nil, err 493 } 494 } 495 } else if rawMessage.SkipEncryptionLayer { 496 497 messageBytes := wrappedMessage 498 if rawMessage.CommunityKeyExMsgType == KeyExMsgReuse { 499 groupID := rawMessage.HashRatchetGroupID 500 501 ratchets, err := s.protocol.GetKeysForGroup(groupID) 502 if err != nil { 503 return nil, err 504 } 505 506 message, err := s.protocol.BuildHashRatchetKeyExchangeMessageWithPayload(s.identity, recipient, groupID, ratchets, wrappedMessage) 507 if err != nil { 508 return nil, err 509 } 510 511 messageBytes, err = proto.Marshal(message.Message) 512 if err != nil { 513 return nil, err 514 } 515 } 516 517 // When SkipProtocolLayer is set we don't pass the message to the encryption layer 518 hashes, newMessages, err := s.sendPrivateRawMessage(ctx, rawMessage, recipient, messageBytes) 519 if err != nil { 520 s.logger.Error("failed to send a private message", zap.Error(err)) 521 return nil, errors.Wrap(err, "failed to send a message spec") 522 } 523 524 s.logger.Debug("sent-message: private skipProtocolLayer", 525 zap.String("recipient", PubkeyToHex(recipient)), 526 zap.String("messageID", messageID.String()), 527 zap.String("messageType", "private"), 528 zap.Any("contentType", rawMessage.MessageType), 529 zap.Strings("hashes", types.EncodeHexes(hashes))) 530 s.transport.Track(messageID, hashes, newMessages) 531 532 } else { 533 messageSpec, err := s.protocol.BuildEncryptedMessage(rawMessage.Sender, recipient, wrappedMessage) 534 if err != nil { 535 return nil, errors.Wrap(err, "failed to encrypt message") 536 } 537 538 hashes, newMessages, err := s.sendMessageSpec(ctx, recipient, messageSpec, [][]byte{messageID}) 539 if err != nil { 540 s.logger.Error("failed to send a private message", zap.Error(err)) 541 return nil, errors.Wrap(err, "failed to send a message spec") 542 } 543 544 s.logger.Debug("sent-message: private without datasync", 545 zap.String("recipient", PubkeyToHex(recipient)), 546 zap.String("messageID", messageID.String()), 547 zap.Any("contentType", rawMessage.MessageType), 548 zap.String("messageType", "private"), 549 zap.Strings("hashes", types.EncodeHexes(hashes))) 550 s.transport.Track(messageID, hashes, newMessages) 551 } 552 553 return messageID, nil 554 } 555 556 // sendPairInstallation sends data to the recipients, using DH 557 func (s *MessageSender) SendPairInstallation( 558 ctx context.Context, 559 recipient *ecdsa.PublicKey, 560 rawMessage RawMessage, 561 ) ([]byte, error) { 562 s.logger.Debug("sending private message", zap.String("recipient", types.EncodeHex(crypto.FromECDSAPub(recipient)))) 563 564 wrappedMessage, err := s.wrapMessageV1(&rawMessage) 565 if err != nil { 566 return nil, errors.Wrap(err, "failed to wrap message") 567 } 568 569 messageSpec, err := s.protocol.BuildDHMessage(s.identity, recipient, wrappedMessage) 570 if err != nil { 571 return nil, errors.Wrap(err, "failed to encrypt message") 572 } 573 574 messageID := v1protocol.MessageID(&s.identity.PublicKey, wrappedMessage) 575 576 hashes, newMessages, err := s.sendMessageSpec(ctx, recipient, messageSpec, [][]byte{messageID}) 577 if err != nil { 578 return nil, errors.Wrap(err, "failed to send a message spec") 579 } 580 581 s.transport.Track(messageID, hashes, newMessages) 582 583 return messageID, nil 584 } 585 586 func (s *MessageSender) encodeMembershipUpdate( 587 message v1protocol.MembershipUpdateMessage, 588 chatEntity ChatEntity, 589 ) ([]byte, error) { 590 591 if chatEntity != nil { 592 chatEntityProtobuf := chatEntity.GetProtobuf() 593 switch chatEntityProtobuf := chatEntityProtobuf.(type) { 594 case *protobuf.ChatMessage: 595 message.Message = chatEntityProtobuf 596 case *protobuf.EmojiReaction: 597 message.EmojiReaction = chatEntityProtobuf 598 599 } 600 } 601 602 encodedMessage, err := v1protocol.EncodeMembershipUpdateMessage(message) 603 if err != nil { 604 return nil, errors.Wrap(err, "failed to encode membership update message") 605 } 606 607 return encodedMessage, nil 608 } 609 610 // EncodeMembershipUpdate takes a group and an optional chat message and returns the protobuf representation to be sent on the wire. 611 // All the events in a group are encoded and added to the payload 612 func (s *MessageSender) EncodeMembershipUpdate( 613 group *v1protocol.Group, 614 chatEntity ChatEntity, 615 ) ([]byte, error) { 616 message := v1protocol.MembershipUpdateMessage{ 617 ChatID: group.ChatID(), 618 Events: group.Events(), 619 } 620 621 return s.encodeMembershipUpdate(message, chatEntity) 622 } 623 624 // EncodeAbridgedMembershipUpdate takes a group and an optional chat message and returns the protobuf representation to be sent on the wire. 625 // Only the events relevant to the current group are encoded 626 func (s *MessageSender) EncodeAbridgedMembershipUpdate( 627 group *v1protocol.Group, 628 chatEntity ChatEntity, 629 ) ([]byte, error) { 630 message := v1protocol.MembershipUpdateMessage{ 631 ChatID: group.ChatID(), 632 Events: group.AbridgedEvents(), 633 } 634 return s.encodeMembershipUpdate(message, chatEntity) 635 } 636 637 func (s *MessageSender) dispatchCommunityChatMessage(ctx context.Context, rawMessage *RawMessage, wrappedMessage []byte, rekey bool) ([][]byte, []*types.NewMessage, error) { 638 payload := wrappedMessage 639 var err error 640 if rekey && len(rawMessage.HashRatchetGroupID) != 0 { 641 642 var ratchet *encryption.HashRatchetKeyCompatibility 643 // We have just rekeyed, pull the latest 644 if RekeyCompatibility { 645 ratchet, err = s.protocol.GetCurrentKeyForGroup(rawMessage.HashRatchetGroupID) 646 if err != nil { 647 return nil, nil, err 648 } 649 650 } 651 // We send the message over the community topic 652 spec, err := s.protocol.BuildHashRatchetReKeyGroupMessage(s.identity, rawMessage.Recipients, rawMessage.HashRatchetGroupID, wrappedMessage, ratchet) 653 if err != nil { 654 return nil, nil, err 655 } 656 payload, err = proto.Marshal(spec.Message) 657 if err != nil { 658 return nil, nil, err 659 } 660 } 661 662 newMessage := &types.NewMessage{ 663 TTL: whisperTTL, 664 Payload: payload, 665 PowTarget: calculatePoW(payload), 666 PowTime: whisperPoWTime, 667 PubsubTopic: rawMessage.PubsubTopic, 668 } 669 670 if rawMessage.BeforeDispatch != nil { 671 if err := rawMessage.BeforeDispatch(rawMessage); err != nil { 672 return nil, nil, err 673 } 674 } 675 676 // notify before dispatching 677 s.notifyOnScheduledMessage(nil, rawMessage) 678 679 newMessages, err := s.segmentMessage(newMessage) 680 if err != nil { 681 return nil, nil, err 682 } 683 684 hashes := make([][]byte, 0, len(newMessages)) 685 for _, newMessage := range newMessages { 686 hash, err := s.transport.SendPublic(ctx, newMessage, rawMessage.LocalChatID) 687 if err != nil { 688 return nil, nil, err 689 } 690 hashes = append(hashes, hash) 691 } 692 693 return hashes, newMessages, nil 694 } 695 696 // SendPublic takes encoded data, encrypts it and sends through the wire. 697 func (s *MessageSender) SendPublic( 698 ctx context.Context, 699 chatName string, 700 rawMessage RawMessage, 701 ) ([]byte, error) { 702 // Set sender 703 if rawMessage.Sender == nil { 704 rawMessage.Sender = s.identity 705 } 706 707 var wrappedMessage []byte 708 var err error 709 if rawMessage.SkipApplicationWrap { 710 wrappedMessage = rawMessage.Payload 711 } else { 712 wrappedMessage, err = s.wrapMessageV1(&rawMessage) 713 if err != nil { 714 return nil, errors.Wrap(err, "failed to wrap message") 715 } 716 } 717 718 var newMessage *types.NewMessage 719 720 messageSpec, err := s.protocol.BuildPublicMessage(s.identity, wrappedMessage) 721 if err != nil { 722 s.logger.Error("failed to send a public message", zap.Error(err)) 723 return nil, errors.Wrap(err, "failed to wrap a public message in the encryption layer") 724 } 725 726 if len(rawMessage.HashRatchetGroupID) != 0 { 727 728 var ratchet *encryption.HashRatchetKeyCompatibility 729 var err error 730 // We have just rekeyed, pull the latest 731 ratchet, err = s.protocol.GetCurrentKeyForGroup(rawMessage.HashRatchetGroupID) 732 if err != nil { 733 return nil, err 734 } 735 736 keyID, err := ratchet.GetKeyID() 737 if err != nil { 738 return nil, err 739 } 740 s.logger.Debug("adding key id to message", zap.String("keyid", types.Bytes2Hex(keyID))) 741 // We send the message over the community topic 742 spec, err := s.protocol.BuildHashRatchetReKeyGroupMessage(s.identity, rawMessage.Recipients, rawMessage.HashRatchetGroupID, wrappedMessage, ratchet) 743 if err != nil { 744 return nil, err 745 } 746 newMessage, err = MessageSpecToWhisper(spec) 747 if err != nil { 748 return nil, err 749 } 750 751 } else if !rawMessage.SkipEncryptionLayer { 752 newMessage, err = MessageSpecToWhisper(messageSpec) 753 if err != nil { 754 return nil, err 755 } 756 } else { 757 newMessage = &types.NewMessage{ 758 TTL: whisperTTL, 759 Payload: wrappedMessage, 760 PowTarget: calculatePoW(wrappedMessage), 761 PowTime: whisperPoWTime, 762 } 763 } 764 765 newMessage.Ephemeral = rawMessage.Ephemeral 766 newMessage.PubsubTopic = rawMessage.PubsubTopic 767 newMessage.Priority = rawMessage.Priority 768 769 messageID := v1protocol.MessageID(&rawMessage.Sender.PublicKey, wrappedMessage) 770 771 if err = s.setMessageID(messageID, &rawMessage); err != nil { 772 return nil, err 773 } 774 775 if rawMessage.BeforeDispatch != nil { 776 if err := rawMessage.BeforeDispatch(&rawMessage); err != nil { 777 return nil, err 778 } 779 } 780 781 // notify before dispatching 782 s.notifyOnScheduledMessage(nil, &rawMessage) 783 784 newMessages, err := s.segmentMessage(newMessage) 785 if err != nil { 786 return nil, err 787 } 788 789 hashes := make([][]byte, 0, len(newMessages)) 790 for _, newMessage := range newMessages { 791 hash, err := s.transport.SendPublic(ctx, newMessage, chatName) 792 if err != nil { 793 return nil, err 794 } 795 hashes = append(hashes, hash) 796 } 797 798 sentMessage := &SentMessage{ 799 Spec: messageSpec, 800 MessageIDs: [][]byte{messageID}, 801 } 802 803 s.notifyOnSentMessage(sentMessage) 804 805 s.logger.Debug("sent-message: public message", 806 zap.Strings("recipient", PubkeysToHex(rawMessage.Recipients)), 807 zap.String("messageID", messageID.String()), 808 zap.Any("contentType", rawMessage.MessageType), 809 zap.String("messageType", "public"), 810 zap.Strings("hashes", types.EncodeHexes(hashes))) 811 s.transport.Track(messageID, hashes, newMessages) 812 813 return messageID, nil 814 } 815 816 // unwrapDatasyncMessage tries to unwrap message as datasync one and in case of success 817 // returns cloned messages with replaced payloads 818 func (s *MessageSender) unwrapDatasyncMessage(m *v1protocol.StatusMessage, response *handleMessageResponse) error { 819 820 datasyncMessage, err := s.datasync.Unwrap( 821 m.SigPubKey(), 822 m.EncryptionLayer.Payload, 823 ) 824 if err != nil { 825 return err 826 } 827 828 response.DatasyncSender = m.SigPubKey() 829 response.DatasyncAcks = append(response.DatasyncAcks, datasyncMessage.Acks...) 830 response.DatasyncRequests = append(response.DatasyncRequests, datasyncMessage.Requests...) 831 for _, o := range datasyncMessage.GroupOffers { 832 for _, mID := range o.MessageIds { 833 response.DatasyncOffers = append(response.DatasyncOffers, DatasyncOffer{GroupID: o.GroupId, MessageID: mID}) 834 } 835 } 836 837 for _, ds := range datasyncMessage.Messages { 838 message, err := m.Clone() 839 if err != nil { 840 return err 841 } 842 message.EncryptionLayer.Payload = ds.Body 843 response.DatasyncMessages = append(response.DatasyncMessages, message) 844 845 } 846 return nil 847 } 848 849 // HandleMessages expects a whisper message as input, and it will go through 850 // a series of transformations until the message is parsed into an application 851 // layer message, or in case of Raw methods, the processing stops at the layer 852 // before. 853 // It returns an error only if the processing of required steps failed. 854 func (s *MessageSender) HandleMessages(wakuMessage *types.Message) (*HandleMessageResponse, error) { 855 logger := s.logger.With(zap.String("site", "HandleMessages")) 856 hlogger := logger.With(zap.String("hash", types.HexBytes(wakuMessage.Hash).String())) 857 858 response, err := s.handleMessage(wakuMessage) 859 if err != nil { 860 // Hash ratchet with a group id not found yet, save the message for future processing 861 if err == encryption.ErrHashRatchetGroupIDNotFound && len(response.Message.EncryptionLayer.HashRatchetInfo) == 1 { 862 info := response.Message.EncryptionLayer.HashRatchetInfo[0] 863 return nil, s.persistence.SaveHashRatchetMessage(info.GroupID, info.KeyID, wakuMessage) 864 } 865 866 // The current message segment has been successfully retrieved. 867 // However, the collection of segments is not yet complete. 868 if err == ErrMessageSegmentsIncomplete { 869 return nil, nil 870 } 871 872 return nil, err 873 } 874 875 // Process queued hash ratchet messages 876 for _, hashRatchetInfo := range response.Message.EncryptionLayer.HashRatchetInfo { 877 messages, err := s.persistence.GetHashRatchetMessages(hashRatchetInfo.KeyID) 878 if err != nil { 879 return nil, err 880 } 881 882 var processedIds [][]byte 883 for _, message := range messages { 884 hlogger.Info("handling out of order encrypted messages", zap.String("hash", types.Bytes2Hex(message.Hash))) 885 r, err := s.handleMessage(message) 886 if err != nil { 887 hlogger.Debug("failed to handle hash ratchet message", zap.Error(err)) 888 continue 889 } 890 response.DatasyncMessages = append(response.toPublicResponse().StatusMessages, r.Messages()...) 891 response.DatasyncAcks = append(response.DatasyncAcks, r.DatasyncAcks...) 892 893 processedIds = append(processedIds, message.Hash) 894 } 895 896 err = s.persistence.DeleteHashRatchetMessages(processedIds) 897 if err != nil { 898 s.logger.Warn("failed to delete hash ratchet messages", zap.Error(err)) 899 return nil, err 900 } 901 } 902 903 return response.toPublicResponse(), nil 904 } 905 906 type DatasyncOffer struct { 907 GroupID []byte 908 MessageID []byte 909 } 910 911 type HandleMessageResponse struct { 912 Hash []byte 913 StatusMessages []*v1protocol.StatusMessage 914 DatasyncSender *ecdsa.PublicKey 915 DatasyncAcks [][]byte 916 DatasyncOffers []DatasyncOffer 917 DatasyncRequests [][]byte 918 } 919 920 func (h *handleMessageResponse) toPublicResponse() *HandleMessageResponse { 921 return &HandleMessageResponse{ 922 Hash: h.Hash, 923 StatusMessages: h.Messages(), 924 DatasyncSender: h.DatasyncSender, 925 DatasyncAcks: h.DatasyncAcks, 926 DatasyncOffers: h.DatasyncOffers, 927 DatasyncRequests: h.DatasyncRequests, 928 } 929 } 930 931 type handleMessageResponse struct { 932 Hash []byte 933 Message *v1protocol.StatusMessage 934 DatasyncMessages []*v1protocol.StatusMessage 935 DatasyncSender *ecdsa.PublicKey 936 DatasyncAcks [][]byte 937 DatasyncOffers []DatasyncOffer 938 DatasyncRequests [][]byte 939 } 940 941 func (h *handleMessageResponse) Messages() []*v1protocol.StatusMessage { 942 if len(h.DatasyncMessages) > 0 { 943 return h.DatasyncMessages 944 } 945 return []*v1protocol.StatusMessage{h.Message} 946 } 947 948 func (s *MessageSender) handleMessage(wakuMessage *types.Message) (*handleMessageResponse, error) { 949 logger := s.logger.With(zap.String("site", "handleMessage")) 950 hlogger := logger.With(zap.String("hash", types.EncodeHex(wakuMessage.Hash))) 951 952 message := &v1protocol.StatusMessage{} 953 954 response := &handleMessageResponse{ 955 Hash: wakuMessage.Hash, 956 Message: message, 957 DatasyncMessages: []*v1protocol.StatusMessage{}, 958 DatasyncAcks: [][]byte{}, 959 } 960 961 err := message.HandleTransportLayer(wakuMessage) 962 if err != nil { 963 hlogger.Error("failed to handle transport layer message", zap.Error(err)) 964 return nil, err 965 } 966 967 err = s.handleSegmentationLayerV2(message) 968 if err != nil { 969 hlogger.Debug("failed to handle segmentation layer message", zap.Error(err)) 970 971 // Segments not completed yet, stop processing 972 if err == ErrMessageSegmentsIncomplete { 973 return nil, err 974 } 975 // Segments already completed, stop processing 976 if err == ErrMessageSegmentsAlreadyCompleted { 977 return nil, err 978 } 979 } 980 981 err = s.handleEncryptionLayer(context.Background(), message) 982 if err != nil { 983 hlogger.Debug("failed to handle an encryption message", zap.Error(err)) 984 985 // Hash ratchet with a group id not found yet, stop processing 986 if err == encryption.ErrHashRatchetGroupIDNotFound { 987 return response, err 988 } 989 } 990 991 if s.datasync != nil && s.datasyncEnabled { 992 err := s.unwrapDatasyncMessage(message, response) 993 if err != nil { 994 hlogger.Debug("failed to handle datasync message", zap.Error(err)) 995 } 996 } 997 998 for _, msg := range response.Messages() { 999 err := msg.HandleApplicationLayer() 1000 if err != nil { 1001 hlogger.Error("failed to handle application metadata layer message", zap.Error(err)) 1002 } 1003 } 1004 1005 return response, nil 1006 } 1007 1008 // fetchDecryptionKey returns the private key associated with this public key, and returns true if it's an ephemeral key 1009 func (s *MessageSender) fetchDecryptionKey(destination *ecdsa.PublicKey) (*ecdsa.PrivateKey, bool) { 1010 destinationID := types.EncodeHex(crypto.FromECDSAPub(destination)) 1011 1012 s.ephemeralKeysMutex.Lock() 1013 decryptionKey, ok := s.ephemeralKeys[destinationID] 1014 s.ephemeralKeysMutex.Unlock() 1015 1016 // the key is not there, fallback on identity 1017 if !ok { 1018 return s.identity, false 1019 } 1020 return decryptionKey, true 1021 } 1022 1023 func (s *MessageSender) handleEncryptionLayer(ctx context.Context, message *v1protocol.StatusMessage) error { 1024 logger := s.logger.With(zap.String("site", "handleEncryptionLayer")) 1025 publicKey := message.SigPubKey() 1026 1027 // if it's an ephemeral key, we don't negotiate a topic 1028 decryptionKey, skipNegotiation := s.fetchDecryptionKey(message.TransportLayer.Dst) 1029 1030 err := message.HandleEncryptionLayer(decryptionKey, publicKey, s.protocol, skipNegotiation) 1031 1032 // if it's an ephemeral key, we don't have to handle a device not found error 1033 if err == encryption.ErrDeviceNotFound && !skipNegotiation { 1034 if err := s.handleErrDeviceNotFound(ctx, publicKey); err != nil { 1035 logger.Error("failed to handle ErrDeviceNotFound", zap.Error(err)) 1036 } 1037 } 1038 if err != nil { 1039 logger.Error("failed to handle an encrypted message", zap.Error(err)) 1040 return err 1041 } 1042 1043 return nil 1044 } 1045 1046 func (s *MessageSender) handleErrDeviceNotFound(ctx context.Context, publicKey *ecdsa.PublicKey) error { 1047 now := time.Now().Unix() 1048 advertise, err := s.protocol.ShouldAdvertiseBundle(publicKey, now) 1049 if err != nil { 1050 return err 1051 } 1052 if !advertise { 1053 return nil 1054 } 1055 1056 messageSpec, err := s.protocol.BuildBundleAdvertiseMessage(s.identity, publicKey) 1057 if err != nil { 1058 return err 1059 } 1060 1061 ctx, cancel := context.WithTimeout(ctx, time.Second) 1062 defer cancel() 1063 // We don't pass an array of messageIDs as no action needs to be taken 1064 // when sending a bundle 1065 _, _, err = s.sendMessageSpec(ctx, publicKey, messageSpec, nil) 1066 if err != nil { 1067 return err 1068 } 1069 1070 s.protocol.ConfirmBundleAdvertisement(publicKey, now) 1071 1072 return nil 1073 } 1074 1075 func (s *MessageSender) wrapMessageV1(rawMessage *RawMessage) ([]byte, error) { 1076 wrappedMessage, err := v1protocol.WrapMessageV1(rawMessage.Payload, rawMessage.MessageType, rawMessage.Sender) 1077 if err != nil { 1078 return nil, errors.Wrap(err, "failed to wrap message") 1079 } 1080 return wrappedMessage, nil 1081 } 1082 1083 func (s *MessageSender) addToDataSync(publicKey *ecdsa.PublicKey, message []byte) ([]byte, error) { 1084 groupID := datasync.ToOneToOneGroupID(&s.identity.PublicKey, publicKey) 1085 peerID := datasyncpeer.PublicKeyToPeerID(*publicKey) 1086 exist, err := s.datasync.IsPeerInGroup(groupID, peerID) 1087 if err != nil { 1088 return nil, errors.Wrap(err, "failed to check if peer is in group") 1089 } 1090 if !exist { 1091 if err := s.datasync.AddPeer(groupID, peerID); err != nil { 1092 return nil, errors.Wrap(err, "failed to add peer") 1093 } 1094 } 1095 id, err := s.datasync.AppendMessage(groupID, message) 1096 if err != nil { 1097 return nil, errors.Wrap(err, "failed to append message to datasync") 1098 } 1099 1100 return id[:], nil 1101 } 1102 1103 // sendPrivateRawMessage sends a message not wrapped in an encryption layer 1104 func (s *MessageSender) sendPrivateRawMessage(ctx context.Context, rawMessage *RawMessage, publicKey *ecdsa.PublicKey, payload []byte) ([][]byte, []*types.NewMessage, error) { 1105 newMessage := &types.NewMessage{ 1106 TTL: whisperTTL, 1107 Payload: payload, 1108 PowTarget: calculatePoW(payload), 1109 PowTime: whisperPoWTime, 1110 PubsubTopic: rawMessage.PubsubTopic, 1111 } 1112 1113 newMessages, err := s.segmentMessage(newMessage) 1114 if err != nil { 1115 return nil, nil, err 1116 } 1117 1118 hashes := make([][]byte, 0, len(newMessages)) 1119 var hash []byte 1120 for _, newMessage := range newMessages { 1121 if rawMessage.SendOnPersonalTopic { 1122 hash, err = s.transport.SendPrivateOnPersonalTopic(ctx, newMessage, publicKey) 1123 } else { 1124 hash, err = s.transport.SendPrivateWithPartitioned(ctx, newMessage, publicKey) 1125 } 1126 if err != nil { 1127 return nil, nil, err 1128 } 1129 hashes = append(hashes, hash) 1130 } 1131 1132 return hashes, newMessages, nil 1133 } 1134 1135 // sendCommunityMessage sends a message not wrapped in an encryption layer 1136 // to a community 1137 func (s *MessageSender) dispatchCommunityMessage(ctx context.Context, publicKey *ecdsa.PublicKey, wrappedMessage []byte, pubsubTopic string, rekey bool, rawMessage *RawMessage) ([][]byte, []*types.NewMessage, error) { 1138 payload := wrappedMessage 1139 if rekey && len(rawMessage.HashRatchetGroupID) != 0 { 1140 1141 var ratchet *encryption.HashRatchetKeyCompatibility 1142 var err error 1143 // We have just rekeyed, pull the latest 1144 if RekeyCompatibility { 1145 ratchet, err = s.protocol.GetCurrentKeyForGroup(rawMessage.HashRatchetGroupID) 1146 if err != nil { 1147 return nil, nil, err 1148 } 1149 1150 } 1151 keyID, err := ratchet.GetKeyID() 1152 if err != nil { 1153 return nil, nil, err 1154 } 1155 s.logger.Debug("adding key id to message", zap.String("keyid", types.Bytes2Hex(keyID))) 1156 // We send the message over the community topic 1157 spec, err := s.protocol.BuildHashRatchetReKeyGroupMessage(s.identity, rawMessage.Recipients, rawMessage.HashRatchetGroupID, wrappedMessage, ratchet) 1158 if err != nil { 1159 return nil, nil, err 1160 } 1161 payload, err = proto.Marshal(spec.Message) 1162 if err != nil { 1163 return nil, nil, err 1164 } 1165 } 1166 1167 newMessage := &types.NewMessage{ 1168 TTL: whisperTTL, 1169 Payload: payload, 1170 PowTarget: calculatePoW(payload), 1171 PowTime: whisperPoWTime, 1172 PubsubTopic: pubsubTopic, 1173 } 1174 1175 newMessages, err := s.segmentMessage(newMessage) 1176 if err != nil { 1177 return nil, nil, err 1178 } 1179 1180 hashes := make([][]byte, 0, len(newMessages)) 1181 for _, newMessage := range newMessages { 1182 hash, err := s.transport.SendCommunityMessage(ctx, newMessage, publicKey) 1183 if err != nil { 1184 return nil, nil, err 1185 } 1186 hashes = append(hashes, hash) 1187 } 1188 1189 return hashes, newMessages, nil 1190 } 1191 1192 func (s *MessageSender) SendMessageSpec(ctx context.Context, publicKey *ecdsa.PublicKey, messageSpec *encryption.ProtocolMessageSpec, messageIDs [][]byte) ([][]byte, []*types.NewMessage, error) { 1193 return s.sendMessageSpec(ctx, publicKey, messageSpec, messageIDs) 1194 } 1195 1196 // sendMessageSpec analyses the spec properties and selects a proper transport method. 1197 func (s *MessageSender) sendMessageSpec(ctx context.Context, publicKey *ecdsa.PublicKey, messageSpec *encryption.ProtocolMessageSpec, messageIDs [][]byte) ([][]byte, []*types.NewMessage, error) { 1198 logger := s.logger.With(zap.String("site", "sendMessageSpec")) 1199 1200 newMessage, err := MessageSpecToWhisper(messageSpec) 1201 if err != nil { 1202 return nil, nil, err 1203 } 1204 1205 newMessages, err := s.segmentMessage(newMessage) 1206 if err != nil { 1207 return nil, nil, err 1208 } 1209 1210 hashes := make([][]byte, 0, len(newMessages)) 1211 var hash []byte 1212 for _, newMessage := range newMessages { 1213 // The shared secret needs to be handle before we send a message 1214 // otherwise the topic might not be set up before we receive a message 1215 if messageSpec.SharedSecret != nil && s.handleSharedSecrets != nil { 1216 err := s.handleSharedSecrets([]*sharedsecret.Secret{messageSpec.SharedSecret}) 1217 if err != nil { 1218 return nil, nil, err 1219 } 1220 1221 } 1222 // process shared secret 1223 if messageSpec.AgreedSecret { 1224 logger.Debug("sending using shared secret") 1225 hash, err = s.transport.SendPrivateWithSharedSecret(ctx, newMessage, publicKey, messageSpec.SharedSecret.Key) 1226 } else { 1227 logger.Debug("sending partitioned topic") 1228 hash, err = s.transport.SendPrivateWithPartitioned(ctx, newMessage, publicKey) 1229 } 1230 if err != nil { 1231 return nil, nil, err 1232 } 1233 hashes = append(hashes, hash) 1234 } 1235 1236 sentMessage := &SentMessage{ 1237 PublicKey: publicKey, 1238 Spec: messageSpec, 1239 MessageIDs: messageIDs, 1240 } 1241 1242 s.notifyOnSentMessage(sentMessage) 1243 1244 return hashes, newMessages, nil 1245 } 1246 1247 func (s *MessageSender) SubscribeToMessageEvents() <-chan *MessageEvent { 1248 c := make(chan *MessageEvent, 100) 1249 s.messageEventsSubscriptions = append(s.messageEventsSubscriptions, c) 1250 return c 1251 } 1252 1253 func (s *MessageSender) notifyOnSentMessage(sentMessage *SentMessage) { 1254 event := &MessageEvent{ 1255 Type: MessageSent, 1256 SentMessage: sentMessage, 1257 } 1258 1259 s.messageEventsSubscriptionsMutex.Lock() 1260 defer s.messageEventsSubscriptionsMutex.Unlock() 1261 1262 // Publish on channels, drop if buffer is full 1263 for _, c := range s.messageEventsSubscriptions { 1264 select { 1265 case c <- event: 1266 default: 1267 s.logger.Warn("message events subscription channel full when publishing sent event, dropping message") 1268 } 1269 } 1270 1271 } 1272 1273 func (s *MessageSender) notifyOnScheduledMessage(recipient *ecdsa.PublicKey, message *RawMessage) { 1274 event := &MessageEvent{ 1275 Recipient: recipient, 1276 Type: MessageScheduled, 1277 RawMessage: message, 1278 } 1279 1280 s.messageEventsSubscriptionsMutex.Lock() 1281 defer s.messageEventsSubscriptionsMutex.Unlock() 1282 1283 // Publish on channels, drop if buffer is full 1284 for _, c := range s.messageEventsSubscriptions { 1285 select { 1286 case c <- event: 1287 default: 1288 s.logger.Warn("message events subscription channel full when publishing scheduled event, dropping message") 1289 } 1290 } 1291 } 1292 1293 func (s *MessageSender) JoinPublic(id string) (*transport.Filter, error) { 1294 return s.transport.JoinPublic(id) 1295 } 1296 1297 func (s *MessageSender) getRandomEphemeralKey() *ecdsa.PrivateKey { 1298 k := rand.Intn(len(s.ephemeralKeys)) //nolint: gosec 1299 for _, key := range s.ephemeralKeys { 1300 if k == 0 { 1301 return key 1302 } 1303 k-- 1304 } 1305 return nil 1306 } 1307 1308 func (s *MessageSender) GetEphemeralKey() (*ecdsa.PrivateKey, error) { 1309 s.ephemeralKeysMutex.Lock() 1310 if len(s.ephemeralKeys) >= maxMessageSenderEphemeralKeys { 1311 s.ephemeralKeysMutex.Unlock() 1312 return s.getRandomEphemeralKey(), nil 1313 } 1314 privateKey, err := crypto.GenerateKey() 1315 if err != nil { 1316 s.ephemeralKeysMutex.Unlock() 1317 return nil, err 1318 } 1319 1320 s.ephemeralKeys[types.EncodeHex(crypto.FromECDSAPub(&privateKey.PublicKey))] = privateKey 1321 s.ephemeralKeysMutex.Unlock() 1322 _, err = s.transport.LoadKeyFilters(privateKey) 1323 if err != nil { 1324 return nil, err 1325 } 1326 1327 return privateKey, nil 1328 } 1329 1330 func MessageSpecToWhisper(spec *encryption.ProtocolMessageSpec) (*types.NewMessage, error) { 1331 var newMessage *types.NewMessage 1332 1333 payload, err := proto.Marshal(spec.Message) 1334 if err != nil { 1335 return newMessage, err 1336 } 1337 1338 newMessage = &types.NewMessage{ 1339 TTL: whisperTTL, 1340 Payload: payload, 1341 PowTarget: calculatePoW(payload), 1342 PowTime: whisperPoWTime, 1343 } 1344 return newMessage, nil 1345 } 1346 1347 // calculatePoW returns the PoWTarget to be used. 1348 // We check the size and arbitrarily set it to a lower PoW if the packet is 1349 // greater than 50KB. We do this as the defaultPoW is too high for clients to send 1350 // large messages. 1351 func calculatePoW(payload []byte) float64 { 1352 if len(payload) > largeSizeInBytes { 1353 return whisperLargeSizePoW 1354 } 1355 return whisperDefaultPoW 1356 } 1357 1358 func (s *MessageSender) StopDatasync() { 1359 if s.datasync != nil { 1360 s.datasync.Stop() 1361 } 1362 } 1363 1364 // GetCurrentKeyForGroup returns the latest key timestampID belonging to a key group 1365 func (s *MessageSender) GetCurrentKeyForGroup(groupID []byte) (*encryption.HashRatchetKeyCompatibility, error) { 1366 return s.protocol.GetCurrentKeyForGroup(groupID) 1367 } 1368 1369 // GetKeyIDsForGroup returns a slice of key IDs belonging to a given group ID 1370 func (s *MessageSender) GetKeysForGroup(groupID []byte) ([]*encryption.HashRatchetKeyCompatibility, error) { 1371 return s.protocol.GetKeysForGroup(groupID) 1372 } 1373 1374 func (s *MessageSender) CleanupHashRatchetEncryptedMessages() error { 1375 monthAgo := time.Now().AddDate(0, -1, 0).Unix() 1376 1377 err := s.persistence.DeleteHashRatchetMessagesOlderThan(monthAgo) 1378 if err != nil { 1379 return err 1380 } 1381 1382 return nil 1383 }