Skip to content

Commit 0d67f18

Browse files
Merge pull request #1671 from session-foundation/add-blinded-message-decoding
Blinded request message parsing and processing
2 parents e390d11 + e820144 commit 0d67f18

File tree

3 files changed

+115
-9
lines changed

3 files changed

+115
-9
lines changed

app/src/main/java/org/session/libsession/messaging/sending_receiving/MessageParser.kt

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.session.libsession.messaging.sending_receiving
22

3+
import network.loki.messenger.libsession_util.SessionEncrypt
34
import network.loki.messenger.libsession_util.protocol.DecodedEnvelope
45
import network.loki.messenger.libsession_util.protocol.SessionProtocol
56
import org.session.libsession.database.StorageProtocol
@@ -15,11 +16,13 @@ import org.session.libsession.messaging.messages.control.UnsendRequest
1516
import org.session.libsession.messaging.messages.visible.VisibleMessage
1617
import org.session.libsession.messaging.open_groups.OpenGroupApi
1718
import org.session.libsession.snode.SnodeClock
19+
import org.session.libsession.utilities.Address
1820
import org.session.libsession.utilities.ConfigFactoryProtocol
1921
import org.session.libsignal.exceptions.NonRetryableException
2022
import org.session.libsignal.protos.SignalServiceProtos
2123
import org.session.libsignal.utilities.AccountId
2224
import org.session.libsignal.utilities.Base64
25+
import org.session.libsignal.utilities.Hex
2326
import org.session.libsignal.utilities.IdPrefix
2427
import java.util.concurrent.TimeUnit
2528
import javax.inject.Inject
@@ -237,4 +240,39 @@ class MessageParser @Inject constructor(
237240
message.openGroupServerMessageID = msg.id
238241
}
239242
}
243+
244+
fun parseCommunityDirectMessage(
245+
msg: OpenGroupApi.DirectMessage,
246+
communityServerPubKeyHex: String,
247+
currentUserEd25519PrivKey: ByteArray,
248+
currentUserId: AccountId,
249+
currentUserBlindedIDs: List<AccountId>,
250+
): Pair<Message, SignalServiceProtos.Content> {
251+
val (senderId, plaintext) = SessionEncrypt.decryptForBlindedRecipient(
252+
ciphertext = Base64.decode(msg.message),
253+
myEd25519Privkey = currentUserEd25519PrivKey,
254+
openGroupPubkey = Hex.fromStringCondensed(communityServerPubKeyHex),
255+
senderBlindedId = Hex.fromStringCondensed(msg.sender),
256+
recipientBlindId = Hex.fromStringCondensed(msg.recipient),
257+
)
258+
259+
val decoded = SessionProtocol.decodeForCommunity(
260+
payload = plaintext.data,
261+
nowEpochMs = snodeClock.currentTimeMills(),
262+
proBackendPubKey = proBackendKey,
263+
)
264+
265+
val sender = Address.Standard(AccountId(senderId))
266+
267+
return parseMessage(
268+
contentPlaintext = decoded.contentPlainText.data,
269+
relaxSignatureCheck = true,
270+
checkForBlockStatus = false,
271+
isForGroup = false,
272+
currentUserId = currentUserId,
273+
sender = sender.accountId,
274+
messageTimestampMs = (msg.postedAt * 1000),
275+
currentUserBlindedIDs = currentUserBlindedIDs,
276+
)
277+
}
240278
}

app/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageProcessor.kt

Lines changed: 59 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import okio.withLock
1414
import org.session.libsession.database.MessageDataProvider
1515
import org.session.libsession.database.userAuth
1616
import org.session.libsession.messaging.messages.Message
17+
import org.session.libsession.messaging.messages.Message.Companion.senderOrSync
1718
import org.session.libsession.messaging.messages.control.CallMessage
1819
import org.session.libsession.messaging.messages.control.DataExtractionNotification
1920
import org.session.libsession.messaging.messages.control.ExpirationTimerUpdate
@@ -29,6 +30,7 @@ import org.session.libsession.messaging.sending_receiving.notifications.MessageN
2930
import org.session.libsession.messaging.utilities.WebRtcUtils
3031
import org.session.libsession.snode.SnodeAPI
3132
import org.session.libsession.utilities.Address
33+
import org.session.libsession.utilities.Address.Companion.toAddress
3234
import org.session.libsession.utilities.ConfigFactoryProtocol
3335
import org.session.libsession.utilities.GroupUtil.doubleEncodeGroupID
3436
import org.session.libsession.utilities.SSKEnvironment
@@ -76,6 +78,15 @@ class ReceivedMessageProcessor @Inject constructor(
7678
) {
7779
private val threadMutexes = ConcurrentHashMap<Address.Conversable, ReentrantLock>()
7880

81+
private inline fun <T> withThreadLock(
82+
threadAddress: Address.Conversable,
83+
block: () -> T
84+
) {
85+
threadMutexes.getOrPut(threadAddress) { ReentrantLock() }.withLock {
86+
block()
87+
}
88+
}
89+
7990

8091
/**
8192
* Start a message processing session, ensuring that thread updates and notifications are handled
@@ -119,7 +130,7 @@ class ReceivedMessageProcessor @Inject constructor(
119130
threadAddress: Address.Conversable,
120131
message: Message,
121132
proto: SignalServiceProtos.Content,
122-
) = threadMutexes.getOrPut(threadAddress) { ReentrantLock() }.withLock {
133+
) = withThreadLock(threadAddress) {
123134
// The logic to check if the message should be discarded due to being from a hidden contact.
124135
if (threadAddress is Address.Standard &&
125136
message.sentTimestamp != null &&
@@ -130,7 +141,7 @@ class ReceivedMessageProcessor @Inject constructor(
130141
)
131142
) {
132143
log { "Dropping message from hidden contact ${threadAddress.debugString}" }
133-
return@withLock
144+
return@withThreadLock
134145
}
135146

136147
// Get or create thread ID, if we aren't allowed to create it, and it doesn't exist, drop the message
@@ -142,7 +153,7 @@ class ReceivedMessageProcessor @Inject constructor(
142153
.also { id ->
143154
if (id == -1L) {
144155
log { "Dropping message for non-existing thread ${threadAddress.debugString}" }
145-
return@withLock
156+
return@withThreadLock
146157
} else {
147158
context.threadIDs[threadAddress] = id
148159
}
@@ -201,23 +212,64 @@ class ReceivedMessageProcessor @Inject constructor(
201212

202213
fun processCommunityInboxMessage(
203214
context: MessageProcessingContext,
215+
communityServerUrl: String,
216+
communityServerPubKeyHex: String,
204217
message: OpenGroupApi.DirectMessage
205218
) {
206-
//TODO("Waiting for the implementation from libsession_util")
219+
val (message, proto) = messageParser.parseCommunityDirectMessage(
220+
msg = message,
221+
currentUserId = context.currentUserId,
222+
currentUserEd25519PrivKey = context.currentUserEd25519KeyPair.secretKey.data,
223+
currentUserBlindedIDs = context.getCurrentUserBlindedIDsByServer(communityServerUrl),
224+
communityServerPubKeyHex = communityServerPubKeyHex,
225+
)
226+
227+
val threadAddress = message.senderOrSync.toAddress() as Address.Conversable
228+
229+
withThreadLock(threadAddress) {
230+
processSwarmMessage(
231+
context = context,
232+
threadAddress = threadAddress,
233+
message = message,
234+
proto = proto
235+
)
236+
}
207237
}
208238

209239
fun processCommunityOutboxMessage(
210240
context: MessageProcessingContext,
211-
message: OpenGroupApi.DirectMessage
241+
communityServerUrl: String,
242+
communityServerPubKeyHex: String,
243+
msg: OpenGroupApi.DirectMessage
212244
) {
213-
//TODO("Waiting for the implementation from libsession_util")
245+
val (message, proto) = messageParser.parseCommunityDirectMessage(
246+
msg = msg,
247+
currentUserId = context.currentUserId,
248+
currentUserEd25519PrivKey = context.currentUserEd25519KeyPair.secretKey.data,
249+
currentUserBlindedIDs = context.getCurrentUserBlindedIDsByServer(communityServerUrl),
250+
communityServerPubKeyHex = communityServerPubKeyHex,
251+
)
252+
253+
val threadAddress = Address.CommunityBlindedId(
254+
serverUrl = communityServerUrl,
255+
blindedId = Address.Blinded(AccountId(msg.recipient))
256+
)
257+
258+
withThreadLock(threadAddress) {
259+
processSwarmMessage(
260+
context = context,
261+
threadAddress = threadAddress,
262+
message = message,
263+
proto = proto
264+
)
265+
}
214266
}
215267

216268
fun processCommunityMessage(
217269
context: MessageProcessingContext,
218270
threadAddress: Address.Community,
219271
message: OpenGroupApi.Message,
220-
) = threadMutexes.getOrPut(threadAddress) { ReentrantLock() }.withLock {
272+
) = withThreadLock(threadAddress) {
221273
var messageId = messageParser.parseCommunityMessage(
222274
msg = message,
223275
currentUserId = context.currentUserId,

app/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/OpenGroupPoller.kt

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,12 @@ class OpenGroupPoller @AssistedInject constructor(
332332
if (messages.isEmpty()) return
333333
val sorted = messages.sortedBy { it.postedAt }
334334

335+
val serverPubKeyHex = storage.getOpenGroupPublicKey(server)
336+
?: run {
337+
Log.e(TAG, "No community server public key cannot process inbox messages")
338+
return
339+
}
340+
335341
receivedMessageProcessor.startProcessing("CommunityInbox") { ctx ->
336342
for (apiMessage in sorted) {
337343
try {
@@ -340,6 +346,8 @@ class OpenGroupPoller @AssistedInject constructor(
340346
receivedMessageProcessor.processCommunityInboxMessage(
341347
context = ctx,
342348
message = apiMessage,
349+
communityServerUrl = server,
350+
communityServerPubKeyHex = serverPubKeyHex,
343351
)
344352

345353
} catch (e: Exception) {
@@ -358,18 +366,26 @@ class OpenGroupPoller @AssistedInject constructor(
358366
if (messages.isEmpty()) return
359367
val sorted = messages.sortedBy { it.postedAt }
360368

369+
val serverPubKeyHex = storage.getOpenGroupPublicKey(server)
370+
?: run {
371+
Log.e(TAG, "No community server public key cannot process inbox messages")
372+
return
373+
}
374+
361375
receivedMessageProcessor.startProcessing("CommunityOutbox") { ctx ->
362376
for (apiMessage in sorted) {
363377
try {
364378
storage.setLastOutboxMessageId(server, sorted.last().id)
365379

366380
receivedMessageProcessor.processCommunityOutboxMessage(
367381
context = ctx,
368-
message = apiMessage,
382+
msg = apiMessage,
383+
communityServerUrl = server,
384+
communityServerPubKeyHex = serverPubKeyHex,
369385
)
370386

371387
} catch (e: Exception) {
372-
Log.e(TAG, "Error processing inbox message", e)
388+
Log.e(TAG, "Error processing outbox message", e)
373389
}
374390
}
375391
}

0 commit comments

Comments
 (0)