Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,7 @@ dependencies {
implementation(libs.opencsv)
implementation(libs.androidx.work.runtime.ktx)
implementation(libs.rxbinding)
implementation(libs.retrofit)

if (hasIncludedLibSessionUtilProject) {
implementation(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import kotlinx.coroutines.supervisorScope
import network.loki.messenger.libsession_util.ConfigBase.Companion.PRIORITY_HIDDEN
import network.loki.messenger.libsession_util.ConfigBase.Companion.PRIORITY_VISIBLE
import network.loki.messenger.libsession_util.Namespace
import network.loki.messenger.libsession_util.protocol.SessionProtocol
import network.loki.messenger.libsession_util.util.BlindKeyAPI
import network.loki.messenger.libsession_util.util.ExpiryMode
import nl.komponents.kovenant.Promise
Expand All @@ -28,23 +29,20 @@ import org.session.libsession.messaging.messages.visible.VisibleMessage
import org.session.libsession.messaging.open_groups.OpenGroupApi
import org.session.libsession.messaging.open_groups.OpenGroupApi.Capability
import org.session.libsession.messaging.open_groups.OpenGroupMessage
import org.session.libsession.messaging.utilities.MessageWrapper
import org.session.libsession.snode.SnodeAPI
import org.session.libsession.snode.SnodeAPI.nowWithOffset
import org.session.libsession.snode.SnodeMessage
import org.session.libsession.snode.utilities.asyncPromise
import org.session.libsession.utilities.Address
import org.session.libsession.utilities.SSKEnvironment
import org.session.libsignal.crypto.PushTransportDetails
import org.session.libsignal.protos.SignalServiceProtos
import org.session.libsignal.utilities.AccountId
import org.session.libsignal.utilities.Base64
import org.session.libsignal.utilities.Hex
import org.session.libsignal.utilities.IdPrefix
import org.session.libsignal.utilities.Log
import org.session.libsignal.utilities.defaultRequiresAuth
import org.session.libsignal.utilities.hasNamespaces
import org.session.libsignal.utilities.hexEncodedPublicKey
import java.util.concurrent.TimeUnit
import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview as SignalLinkPreview
import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel as SignalQuote
Expand Down Expand Up @@ -137,54 +135,44 @@ object MessageSender {
// Set the timestamp on the content so it can be verified against envelope timestamp
proto.setSigTimestampMs(message.sentTimestamp!!)

// Serialize the protobuf
val plaintext = PushTransportDetails.getPaddedMessageBody(proto.build().toByteArray())
val plainText = PushTransportDetails.getPaddedMessageBody(proto.build().toByteArray())

// Envelope information
val kind: SignalServiceProtos.Envelope.Type
val senderPublicKey: String
when (destination) {
val wrappedMessage = when (destination) {
is Destination.Contact -> {
kind = SignalServiceProtos.Envelope.Type.SESSION_MESSAGE
senderPublicKey = ""
}
is Destination.LegacyClosedGroup -> {
kind = SignalServiceProtos.Envelope.Type.CLOSED_GROUP_MESSAGE
senderPublicKey = destination.groupPublicKey
}
is Destination.ClosedGroup -> {
kind = SignalServiceProtos.Envelope.Type.CLOSED_GROUP_MESSAGE
senderPublicKey = destination.publicKey
if (isSyncMessage) {
SessionProtocol.encryptFor1o1(
plaintext = plainText,
myEd25519PrivKey = storage.getUserED25519KeyPair()!!.secretKey.data,
timestampMs = message.sentTimestamp!!,
recipientPubKey = AccountId(userPublicKey!!).prefixedBytes,
proRotatingEd25519PrivKey = null,
)
} else {
SessionProtocol.encryptFor1o1(
plaintext = plainText,
myEd25519PrivKey = storage.getUserED25519KeyPair()!!.secretKey.data,
timestampMs = message.sentTimestamp!!,
recipientPubKey = AccountId(destination.publicKey).prefixedBytes,
proRotatingEd25519PrivKey = null,
)
}
}
else -> throw IllegalStateException("Destination should not be open group.")
}

// Encrypt the serialized protobuf
val ciphertext = when (destination) {
is Destination.Contact -> MessageEncrypter.encrypt(plaintext, destination.publicKey)
is Destination.LegacyClosedGroup -> {
val encryptionKeyPair =
MessagingModuleConfiguration.shared.storage.getLatestClosedGroupEncryptionKeyPair(
destination.groupPublicKey
)!!
MessageEncrypter.encrypt(plaintext, encryptionKeyPair.hexEncodedPublicKey)
}
is Destination.ClosedGroup -> {
val envelope = MessageWrapper.createEnvelope(kind, message.sentTimestamp!!, senderPublicKey, proto.build().toByteArray())
configFactory.withGroupConfigs(AccountId(destination.publicKey)) {
it.groupKeys.encrypt(envelope.toByteArray())
}
val groupId = AccountId(destination.publicKey)
SessionProtocol.encryptForGroup(
plaintext = plainText,
myEd25519PrivKey = storage.getUserED25519KeyPair()!!.secretKey.data,
timestampMs = message.sentTimestamp!!,
groupEd25519PublicKey = groupId.prefixedBytes,
groupEd25519PrivateKey = configFactory.withGroupConfigs(groupId) { it.groupKeys.groupEncKey() },
proRotatingEd25519PrivKey = null,
)
}

else -> throw IllegalStateException("Destination should not be open group.")
}
// Wrap the result using envelope information
val wrappedMessage = when (destination) {
is Destination.ClosedGroup -> {
// encrypted bytes from the above closed group encryption and envelope steps
ciphertext
}
else -> MessageWrapper.wrap(kind, message.sentTimestamp!!, senderPublicKey, ciphertext)
}

val base64EncodedData = Base64.encodeBytes(wrappedMessage)
// Send the result
return SnodeMessage(
Expand Down Expand Up @@ -365,8 +353,8 @@ object MessageSender {
if (message !is VisibleMessage || !message.isValid()) {
throw Error.InvalidMessage
}
val messageBody = content.toByteArray()
val plaintext = PushTransportDetails.getPaddedMessageBody(messageBody)

val plaintext = content.toByteArray()
val openGroupMessage = OpenGroupMessage(
sender = message.sender,
sentTimestamp = message.sentTimestamp!!,
Expand All @@ -386,14 +374,17 @@ object MessageSender {
if (message !is VisibleMessage || !message.isValid()) {
throw Error.InvalidMessage
}
val messageBody = content.toByteArray()
val plaintext = PushTransportDetails.getPaddedMessageBody(messageBody)
val ciphertext = MessageEncrypter.encryptBlinded(
plaintext,
destination.blindedPublicKey,
destination.serverPublicKey
val contentBytes = content.toByteArray()
val cipherText = SessionProtocol.encryptForCommunityInbox(
plaintext = contentBytes,
myEd25519PrivKey = userEdKeyPair.secretKey.data,
timestampMs = message.sentTimestamp!!,
recipientPubKey = AccountId(destination.blindedPublicKey).prefixedBytes,
communityServerPubKey = Hex.fromStringCondensed(destination.serverPublicKey),
proRotatingEd25519PrivKey = null
)
val base64EncodedData = Base64.encodeBytes(ciphertext)

val base64EncodedData = Base64.encodeBytes(cipherText)
OpenGroupApi.sendDirectMessage(base64EncodedData, destination.blindedPublicKey, destination.server).success {
message.openGroupServerMessageID = it.id
handleSuccessfulMessageSend(message, destination, openGroupSentTimestamp = TimeUnit.SECONDS.toMillis(it.postedAt))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package org.session.libsession.messaging.sending_receiving

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.ReceiveChannel
import kotlinx.coroutines.launch
import org.session.libsession.utilities.Address
import org.thoughtcrime.securesms.database.ReceivedMessageDatabase
import org.thoughtcrime.securesms.dependencies.ManagerScope
import org.thoughtcrime.securesms.dependencies.OnAppStartupComponent
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class ReceivedMessageManager @Inject constructor(
private val database: ReceivedMessageDatabase,
private val handler: ReceivedMessageHandler,
@param:ManagerScope private val scope: CoroutineScope,
): OnAppStartupComponent {
override fun onPostAppStarted() {
scope.launch {
// database.getSwarmMessagesSorted()
}
}

private fun launchMessageProcessing(
address: Address,
messages: ReceiveChannel<ReceivedMessageDatabase.Message>
) {
scope.launch {
for (msg in messages) {

}
}
}
}
Loading
Loading