diff --git a/channels/send.go b/channels/send.go index 8764a04634b3409bb19cfc9f338206b1547b56c5..26188aa8889483784adb22002bee126114aae903 100644 --- a/channels/send.go +++ b/channels/send.go @@ -10,6 +10,7 @@ package channels import ( "bytes" "crypto/ed25519" + "crypto/hmac" "encoding/base64" "fmt" "time" @@ -60,10 +61,12 @@ const ( // SendAdminReplayTag is the base tag used when generating a debug tag for an // admin replay message. SendAdminReplayTag = "ChAdminReplay" + + // The size of the nonce used in the message ID. + messageNonceSize = 4 ) -// The size of the nonce used in the message ID. -const messageNonceSize = 4 +var emptyChannelID = &id.ID{} // Prints current time without the monotonic clock (m=) for easier reading func dateNow() string { return netTime.Now().Round(0).String() } @@ -93,6 +96,11 @@ func (m *manager) SendGeneric(channelID *id.ID, messageType MessageType, msg []byte, validUntil time.Duration, tracked bool, params cmix.CMIXParams) ( message.ID, rounds.Round, ephemeral.Id, error) { + if hmac.Equal(channelID.Bytes(), emptyChannelID.Bytes()) { + return message.ID{}, rounds.Round{}, ephemeral.Id{}, + errors.New("cannot send to channel id with all 0s") + } + // Reject the send if the user is muted in the channel they are sending to if m.events.mutedUsers.isMuted(channelID, m.me.PubKey) { return message.ID{}, rounds.Round{}, ephemeral.Id{}, @@ -386,6 +394,11 @@ func (m *manager) SendAdminGeneric(channelID *id.ID, messageType MessageType, msg []byte, validUntil time.Duration, tracked bool, params cmix.CMIXParams) ( message.ID, rounds.Round, ephemeral.Id, error) { + if hmac.Equal(channelID.Bytes(), emptyChannelID.Bytes()) { + return message.ID{}, rounds.Round{}, ephemeral.Id{}, + errors.New("cannot send to channel id with all 0s") + } + // Note: We log sends on exit, and append what happened to the message // this cuts down on clutter in the log. log := fmt.Sprintf( diff --git a/channels/send_test.go b/channels/send_test.go index f30bdef8d2fc32c9bd4a3e6b9a0999cee88d2cd3..ccf81e715266c4a9189f1426e648c42791684ec4 100644 --- a/channels/send_test.go +++ b/channels/send_test.go @@ -64,7 +64,9 @@ func Test_manager_SendGeneric(t *testing.T) { }, crng), } - channelID := new(id.ID) + rng := crng.GetStream() + defer rng.Close() + channelID, _ := id.NewRandomID(rng, id.User) messageType := Text msg := []byte("hello world") validUntil := time.Hour @@ -215,7 +217,9 @@ func Test_manager_SendMessage(t *testing.T) { }, crng), } - channelID := new(id.ID) + rng := crng.GetStream() + defer rng.Close() + channelID, _ := id.NewRandomID(rng, id.User) messageType := Text msg := "hello world" validUntil := time.Hour @@ -300,7 +304,9 @@ func Test_manager_SendReply(t *testing.T) { }, crng), } - channelID := new(id.ID) + rng := crng.GetStream() + defer rng.Close() + channelID, _ := id.NewRandomID(rng, id.User) messageType := Text msg := "hello world" validUntil := time.Hour @@ -387,7 +393,9 @@ func Test_manager_SendReaction(t *testing.T) { }, crng), } - channelID := new(id.ID) + rng := crng.GetStream() + defer rng.Close() + channelID, _ := id.NewRandomID(rng, id.User) messageType := Reaction msg := "ðŸ†" params := new(cmix.CMIXParams) diff --git a/dm/send.go b/dm/send.go index acab686c3ec372a3dc5b84ed154dffb1972b4f44..a2cae2a88c11e90ff5a78129635b3eaacd3912a2 100644 --- a/dm/send.go +++ b/dm/send.go @@ -54,6 +54,11 @@ const ( messageNonceSize = 4 ) +var ( + emptyPubKeyBytes = make([]byte, ed25519.PublicKeySize) + emptyPubKey = ed25519.PublicKey(emptyPubKeyBytes) +) + // SendText is used to send a formatted message to another user. func (dc *dmClient) SendText(partnerPubKey *ed25519.PublicKey, partnerToken uint32, @@ -156,6 +161,21 @@ func (dc *dmClient) Send(partnerEdwardsPubKey *ed25519.PublicKey, params cmix.CMIXParams) ( cryptoMessage.ID, rounds.Round, ephemeral.Id, error) { + if partnerToken == 0 { + return cryptoMessage.ID{}, rounds.Round{}, + ephemeral.Id{}, + errors.Errorf("invalid dmToken value: %d", partnerToken) + + } + + if partnerEdwardsPubKey == nil || + partnerEdwardsPubKey.Equal(emptyPubKey) { + return cryptoMessage.ID{}, rounds.Round{}, + ephemeral.Id{}, + errors.Errorf("invalid public key value: %v", + partnerEdwardsPubKey) + } + partnerPubKey := ecdh.Edwards2ECDHNIKEPublicKey(partnerEdwardsPubKey) partnerID := deriveReceptionID(partnerPubKey.Bytes(), partnerToken)