mirror of
https://github.com/oxen-io/session-android.git
synced 2025-02-20 06:18:26 +00:00
minor refactor on closed group encryption key pair sending
This commit is contained in:
parent
e85bf7a45d
commit
0e049469aa
@ -315,7 +315,7 @@ private fun MessageReceiver.handleClosedGroupEncryptionKeyPair(message: ClosedGr
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (!group.members.map { it.toString() }.contains(senderPublicKey)) {
|
if (!group.members.map { it.toString() }.contains(senderPublicKey)) {
|
||||||
android.util.Log.d("Loki", "Ignoring closed group encryption key pair from non-member.")
|
Log.d("Loki", "Ignoring closed group encryption key pair from non-member.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Find our wrapper and decrypt it if possible
|
// Find our wrapper and decrypt it if possible
|
||||||
@ -362,6 +362,7 @@ private fun MessageReceiver.handleClosedGroupNameChanged(message: ClosedGroupCon
|
|||||||
private fun MessageReceiver.handleClosedGroupMembersAdded(message: ClosedGroupControlMessage) {
|
private fun MessageReceiver.handleClosedGroupMembersAdded(message: ClosedGroupControlMessage) {
|
||||||
val context = MessagingConfiguration.shared.context
|
val context = MessagingConfiguration.shared.context
|
||||||
val storage = MessagingConfiguration.shared.storage
|
val storage = MessagingConfiguration.shared.storage
|
||||||
|
val userPublicKey = storage.getUserPublicKey()!!
|
||||||
val senderPublicKey = message.sender ?: return
|
val senderPublicKey = message.sender ?: return
|
||||||
val kind = message.kind!! as? ClosedGroupControlMessage.Kind.MembersAdded ?: return
|
val kind = message.kind!! as? ClosedGroupControlMessage.Kind.MembersAdded ?: return
|
||||||
val groupPublicKey = message.groupPublicKey ?: return
|
val groupPublicKey = message.groupPublicKey ?: return
|
||||||
@ -370,9 +371,7 @@ private fun MessageReceiver.handleClosedGroupMembersAdded(message: ClosedGroupCo
|
|||||||
Log.d("Loki", "Ignoring closed group info message for nonexistent group.")
|
Log.d("Loki", "Ignoring closed group info message for nonexistent group.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (!isValidGroupUpdate(group, message.sentTimestamp!!, senderPublicKey)) {
|
if (!isValidGroupUpdate(group, message.sentTimestamp!!, senderPublicKey)) { return }
|
||||||
return
|
|
||||||
}
|
|
||||||
val name = group.title
|
val name = group.title
|
||||||
// Check common group update logic
|
// Check common group update logic
|
||||||
val members = group.members.map { it.serialize() }
|
val members = group.members.map { it.serialize() }
|
||||||
@ -381,11 +380,22 @@ private fun MessageReceiver.handleClosedGroupMembersAdded(message: ClosedGroupCo
|
|||||||
val updateMembers = kind.members.map { it.toByteArray().toHexString() }
|
val updateMembers = kind.members.map { it.toByteArray().toHexString() }
|
||||||
val newMembers = members + updateMembers
|
val newMembers = members + updateMembers
|
||||||
storage.updateMembers(groupID, newMembers.map { Address.fromSerialized(it) })
|
storage.updateMembers(groupID, newMembers.map { Address.fromSerialized(it) })
|
||||||
// Send the latest encryption key pair to the added members if the current user is the admin of the group
|
if (userPublicKey == senderPublicKey) {
|
||||||
val isCurrentUserAdmin = admins.contains(storage.getUserPublicKey()!!)
|
val threadID = storage.getOrCreateThreadIdFor(Address.fromSerialized(groupID))
|
||||||
if (isCurrentUserAdmin) {
|
storage.insertOutgoingInfoMessage(context, groupID, SignalServiceProtos.GroupContext.Type.UPDATE, name, members, admins, threadID, message.sentTimestamp!!)
|
||||||
for (member in updateMembers) {
|
} else {
|
||||||
MessageSender.sendLatestEncryptionKeyPair(member, groupPublicKey)
|
storage.insertIncomingInfoMessage(context, senderPublicKey, groupID, SignalServiceProtos.GroupContext.Type.UPDATE, SignalServiceGroup.Type.UPDATE, name, members, admins, message.sentTimestamp!!)
|
||||||
|
}
|
||||||
|
if (userPublicKey in admins) {
|
||||||
|
// send current encryption key to the latest added members
|
||||||
|
val encryptionKeyPair = pendingKeyPair[groupPublicKey]?.orNull()
|
||||||
|
?: storage.getLatestClosedGroupEncryptionKeyPair(groupPublicKey)
|
||||||
|
if (encryptionKeyPair == null) {
|
||||||
|
android.util.Log.d("Loki", "Couldn't get encryption key pair for closed group.")
|
||||||
|
} else {
|
||||||
|
for (user in updateMembers) {
|
||||||
|
MessageSender.sendEncryptionKeyPair(groupPublicKey, encryptionKeyPair, setOf(user), targetUser = user, force = false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
storage.insertIncomingInfoMessage(context, senderPublicKey, groupID, SignalServiceProtos.GroupContext.Type.UPDATE, SignalServiceGroup.Type.UPDATE, name, members, admins, message.sentTimestamp!!)
|
storage.insertIncomingInfoMessage(context, senderPublicKey, groupID, SignalServiceProtos.GroupContext.Type.UPDATE, SignalServiceGroup.Type.UPDATE, name, members, admins, message.sentTimestamp!!)
|
||||||
@ -491,7 +501,13 @@ private fun MessageReceiver.handleClosedGroupEncryptionKeyPairRequest(message: C
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (!isValidGroupUpdate(group, message.sentTimestamp!!, senderPublicKey)) { return }
|
if (!isValidGroupUpdate(group, message.sentTimestamp!!, senderPublicKey)) { return }
|
||||||
MessageSender.sendLatestEncryptionKeyPair(senderPublicKey, groupPublicKey)
|
val encryptionKeyPair = pendingKeyPair[groupPublicKey]?.orNull()
|
||||||
|
?: storage.getLatestClosedGroupEncryptionKeyPair(groupPublicKey)
|
||||||
|
if (encryptionKeyPair == null) {
|
||||||
|
Log.d("Loki", "Couldn't get encryption key pair for closed group.")
|
||||||
|
} else {
|
||||||
|
MessageSender.sendEncryptionKeyPair(groupPublicKey, encryptionKeyPair, setOf(senderPublicKey), targetUser = senderPublicKey, force = false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isValidGroupUpdate(group: GroupRecord,
|
private fun isValidGroupUpdate(group: GroupRecord,
|
||||||
|
@ -2,7 +2,9 @@
|
|||||||
|
|
||||||
package org.session.libsession.messaging.sending_receiving
|
package org.session.libsession.messaging.sending_receiving
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
import com.google.protobuf.ByteString
|
import com.google.protobuf.ByteString
|
||||||
|
import com.google.protobuf.Message
|
||||||
import nl.komponents.kovenant.Promise
|
import nl.komponents.kovenant.Promise
|
||||||
import nl.komponents.kovenant.deferred
|
import nl.komponents.kovenant.deferred
|
||||||
|
|
||||||
@ -27,7 +29,7 @@ import org.session.libsignal.utilities.logging.Log
|
|||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
|
||||||
private val pendingKeyPair = ConcurrentHashMap<String, Optional<ECKeyPair>>()
|
val pendingKeyPair = ConcurrentHashMap<String, Optional<ECKeyPair>>()
|
||||||
|
|
||||||
fun MessageSender.create(name: String, members: Collection<String>): Promise<String, Exception> {
|
fun MessageSender.create(name: String, members: Collection<String>): Promise<String, Exception> {
|
||||||
val deferred = deferred<String, Exception>()
|
val deferred = deferred<String, Exception>()
|
||||||
@ -247,6 +249,15 @@ fun MessageSender.generateAndSendNewEncryptionKeyPair(groupPublicKey: String, ta
|
|||||||
// make sure we set the pendingKeyPair or wait until it is not null
|
// make sure we set the pendingKeyPair or wait until it is not null
|
||||||
} while (!pendingKeyPair.replace(groupPublicKey,Optional.absent(),Optional.fromNullable(newKeyPair)))
|
} while (!pendingKeyPair.replace(groupPublicKey,Optional.absent(),Optional.fromNullable(newKeyPair)))
|
||||||
// Distribute it
|
// Distribute it
|
||||||
|
sendEncryptionKeyPair(groupPublicKey, newKeyPair, targetMembers)?.success {
|
||||||
|
// Store it * after * having sent out the message to the group
|
||||||
|
storage.addClosedGroupEncryptionKeyPair(newKeyPair, groupPublicKey)
|
||||||
|
pendingKeyPair[groupPublicKey] = Optional.absent()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun MessageSender.sendEncryptionKeyPair(groupPublicKey: String, newKeyPair: ECKeyPair, targetMembers: Collection<String>, targetUser: String? = null, force: Boolean = true): Promise<Unit, Exception>? {
|
||||||
|
val destination = targetUser ?: GroupUtil.doubleEncodeGroupID(groupPublicKey)
|
||||||
val proto = SignalServiceProtos.KeyPair.newBuilder()
|
val proto = SignalServiceProtos.KeyPair.newBuilder()
|
||||||
proto.publicKey = ByteString.copyFrom(newKeyPair.publicKey.serialize().removing05PrefixIfNeeded())
|
proto.publicKey = ByteString.copyFrom(newKeyPair.publicKey.serialize().removing05PrefixIfNeeded())
|
||||||
proto.privateKey = ByteString.copyFrom(newKeyPair.privateKey.serialize())
|
proto.privateKey = ByteString.copyFrom(newKeyPair.privateKey.serialize())
|
||||||
@ -255,14 +266,15 @@ fun MessageSender.generateAndSendNewEncryptionKeyPair(groupPublicKey: String, ta
|
|||||||
val ciphertext = MessageSenderEncryption.encryptWithSessionProtocol(plaintext, publicKey)
|
val ciphertext = MessageSenderEncryption.encryptWithSessionProtocol(plaintext, publicKey)
|
||||||
ClosedGroupControlMessage.KeyPairWrapper(publicKey, ByteString.copyFrom(ciphertext))
|
ClosedGroupControlMessage.KeyPairWrapper(publicKey, ByteString.copyFrom(ciphertext))
|
||||||
}
|
}
|
||||||
val kind = ClosedGroupControlMessage.Kind.EncryptionKeyPair(null, wrappers)
|
val kind = ClosedGroupControlMessage.Kind.EncryptionKeyPair(ByteString.copyFrom(Hex.fromStringCondensed(groupPublicKey)), wrappers)
|
||||||
val sentTime = System.currentTimeMillis()
|
val sentTime = System.currentTimeMillis()
|
||||||
val closedGroupControlMessage = ClosedGroupControlMessage(kind)
|
val closedGroupControlMessage = ClosedGroupControlMessage(kind)
|
||||||
closedGroupControlMessage.sentTimestamp = sentTime
|
closedGroupControlMessage.sentTimestamp = sentTime
|
||||||
sendNonDurably(closedGroupControlMessage, Address.fromSerialized(groupID)).success {
|
return if (force) {
|
||||||
// Store it * after * having sent out the message to the group
|
MessageSender.sendNonDurably(closedGroupControlMessage, Address.fromSerialized(destination))
|
||||||
storage.addClosedGroupEncryptionKeyPair(newKeyPair, groupPublicKey)
|
} else {
|
||||||
pendingKeyPair[groupPublicKey] = Optional.absent()
|
MessageSender.send(closedGroupControlMessage, Address.fromSerialized(destination))
|
||||||
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,34 +293,4 @@ fun MessageSender.requestEncryptionKeyPair(groupPublicKey: String) {
|
|||||||
val closedGroupControlMessage = ClosedGroupControlMessage(ClosedGroupControlMessage.Kind.EncryptionKeyPairRequest())
|
val closedGroupControlMessage = ClosedGroupControlMessage(ClosedGroupControlMessage.Kind.EncryptionKeyPairRequest())
|
||||||
closedGroupControlMessage.sentTimestamp = sentTime
|
closedGroupControlMessage.sentTimestamp = sentTime
|
||||||
send(closedGroupControlMessage, Address.fromSerialized(groupID))
|
send(closedGroupControlMessage, Address.fromSerialized(groupID))
|
||||||
}
|
|
||||||
|
|
||||||
fun MessageSender.sendLatestEncryptionKeyPair(publicKey: String, groupPublicKey: String) {
|
|
||||||
val storage = MessagingConfiguration.shared.storage
|
|
||||||
val groupID = GroupUtil.doubleEncodeGroupID(groupPublicKey)
|
|
||||||
val group = storage.getGroup(groupID) ?: run {
|
|
||||||
Log.d("Loki", "Can't send encryption key pair for nonexistent closed group.")
|
|
||||||
throw Error.NoThread
|
|
||||||
}
|
|
||||||
val members = group.members.map { it.serialize() }
|
|
||||||
if (!members.contains(publicKey)) {
|
|
||||||
Log.d("Loki", "Refusing to send latest encryption key pair to non-member.")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// Get the latest encryption key pair
|
|
||||||
val encryptionKeyPair = pendingKeyPair[groupPublicKey]?.orNull()
|
|
||||||
?: storage.getLatestClosedGroupEncryptionKeyPair(groupPublicKey) ?: return
|
|
||||||
// Send it
|
|
||||||
val proto = SignalServiceProtos.KeyPair.newBuilder()
|
|
||||||
proto.publicKey = ByteString.copyFrom(encryptionKeyPair.publicKey.serialize())
|
|
||||||
proto.privateKey = ByteString.copyFrom(encryptionKeyPair.privateKey.serialize())
|
|
||||||
val plaintext = proto.build().toByteArray()
|
|
||||||
val ciphertext = MessageSenderEncryption.encryptWithSessionProtocol(plaintext, publicKey)
|
|
||||||
Log.d("Loki", "Sending latest encryption key pair to: $publicKey.")
|
|
||||||
val wrapper = ClosedGroupControlMessage.KeyPairWrapper(publicKey, ByteString.copyFrom(ciphertext))
|
|
||||||
val kind = ClosedGroupControlMessage.Kind.EncryptionKeyPair(ByteString.copyFrom(Hex.fromStringCondensed(groupPublicKey)), listOf(wrapper))
|
|
||||||
val sentTime = System.currentTimeMillis()
|
|
||||||
val closedGroupControlMessage = ClosedGroupControlMessage(kind)
|
|
||||||
closedGroupControlMessage.sentTimestamp = sentTime
|
|
||||||
MessageSender.send(closedGroupControlMessage, Address.fromSerialized(publicKey))
|
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user