From 424aee5fb352e0f9e856cf2a01ffd98606bce430 Mon Sep 17 00:00:00 2001 From: Ryan ZHAO Date: Mon, 15 Mar 2021 15:43:05 +1100 Subject: [PATCH] fix possible serialising crash & refactor --- .../loki/protocol/MultiDeviceProtocol.kt | 4 +-- .../messaging/messages/Destination.kt | 23 ++++--------- .../control/ClosedGroupControlMessage.kt | 32 +++++++++++++------ .../messages/control/ConfigurationMessage.kt | 31 +++++++----------- .../MessageReceiverHandler.kt | 4 +-- 5 files changed, 43 insertions(+), 51 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/MultiDeviceProtocol.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/MultiDeviceProtocol.kt index 81e137171a..69dfc70126 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/MultiDeviceProtocol.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/MultiDeviceProtocol.kt @@ -79,8 +79,8 @@ object MultiDeviceProtocol { closedGroupUpdate.publicKey = ByteString.copyFrom(Hex.fromStringCondensed(closedGroup.publicKey)) closedGroupUpdate.name = closedGroup.name val encryptionKeyPair = SignalServiceProtos.KeyPair.newBuilder() - encryptionKeyPair.publicKey = ByteString.copyFrom(closedGroup.encryptionKeyPair.publicKey.serialize().removing05PrefixIfNeeded()) - encryptionKeyPair.privateKey = ByteString.copyFrom(closedGroup.encryptionKeyPair.privateKey.serialize()) + encryptionKeyPair.publicKey = ByteString.copyFrom(closedGroup.encryptionKeyPair!!.publicKey.serialize().removing05PrefixIfNeeded()) + encryptionKeyPair.privateKey = ByteString.copyFrom(closedGroup.encryptionKeyPair!!.privateKey.serialize()) closedGroupUpdate.encryptionKeyPair = encryptionKeyPair.build() closedGroupUpdate.addAllMembers(closedGroup.members.map { ByteString.copyFrom(Hex.fromStringCondensed(it)) }) closedGroupUpdate.addAllAdmins(closedGroup.admins.map { ByteString.copyFrom(Hex.fromStringCondensed(it)) }) diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/Destination.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/Destination.kt index 47e48de38d..ef389b08b0 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/Destination.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/Destination.kt @@ -7,25 +7,14 @@ import org.session.libsignal.service.loki.utilities.toHexString sealed class Destination { - class Contact() : Destination() { - var publicKey: String = "" - internal constructor(publicKey: String): this() { - this.publicKey = publicKey - } + class Contact(var publicKey: String) : Destination() { + internal constructor(): this("") } - class ClosedGroup() : Destination() { - var groupPublicKey: String = "" - internal constructor(groupPublicKey: String): this() { - this.groupPublicKey = groupPublicKey - } + class ClosedGroup(var groupPublicKey: String) : Destination() { + internal constructor(): this("") } - class OpenGroup() : Destination() { - var channel: Long = 0 - var server: String = "" - internal constructor(channel: Long, server: String): this() { - this.channel = channel - this.server = server - } + class OpenGroup(var channel: Long, var server: String) : Destination() { + internal constructor(): this(0, "") } companion object { diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/control/ClosedGroupControlMessage.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/control/ClosedGroupControlMessage.kt index bad3ad566f..ea483fa41f 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/control/ClosedGroupControlMessage.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/control/ClosedGroupControlMessage.kt @@ -30,16 +30,28 @@ class ClosedGroupControlMessage() : ControlMessage() { // Kind enum sealed class Kind { - class New(val publicKey: ByteString, val name: String, val encryptionKeyPair: ECKeyPair, val members: List, val admins: List) : Kind() + class New(var publicKey: ByteString, var name: String, var encryptionKeyPair: ECKeyPair?, var members: List, var admins: List) : Kind() { + internal constructor(): this(ByteString.EMPTY, "", null, listOf(), listOf()) + } /// - Note: Deprecated in favor of more explicit group updates. - class Update(val name: String, val members: List) : Kind() + class Update(var name: String, var members: List) : Kind() { + internal constructor(): this("", listOf()) + } /// An encryption key pair encrypted for each member individually. /// /// - Note: `publicKey` is only set when an encryption key pair is sent in a one-to-one context (i.e. not in a group). - class EncryptionKeyPair(val publicKey: ByteString?, val wrappers: Collection) : Kind() - class NameChange(val name: String) : Kind() - class MembersAdded(val members: List) : Kind() - class MembersRemoved( val members: List) : Kind() + class EncryptionKeyPair(var publicKey: ByteString?, var wrappers: Collection) : Kind() { + internal constructor(): this(null, listOf()) + } + class NameChange(var name: String) : Kind() { + internal constructor(): this("") + } + class MembersAdded(var members: List) : Kind() { + internal constructor(): this(listOf()) + } + class MembersRemoved(var members: List) : Kind() { + internal constructor(): this(listOf()) + } class MemberLeft : Kind() class EncryptionKeyPairRequest: Kind() @@ -118,8 +130,8 @@ class ClosedGroupControlMessage() : ControlMessage() { val kind = kind ?: return false return when(kind) { is Kind.New -> { - !kind.publicKey.isEmpty && kind.name.isNotEmpty() && kind.encryptionKeyPair.publicKey != null - && kind.encryptionKeyPair.privateKey != null && kind.members.isNotEmpty() && kind.admins.isNotEmpty() + !kind.publicKey.isEmpty && kind.name.isNotEmpty() && kind.encryptionKeyPair!!.publicKey != null + && kind.encryptionKeyPair!!.privateKey != null && kind.members.isNotEmpty() && kind.admins.isNotEmpty() } is Kind.Update -> kind.name.isNotEmpty() is Kind.EncryptionKeyPair -> true @@ -145,8 +157,8 @@ class ClosedGroupControlMessage() : ControlMessage() { closedGroupControlMessage.publicKey = kind.publicKey closedGroupControlMessage.name = kind.name val encryptionKeyPair = SignalServiceProtos.KeyPair.newBuilder() - encryptionKeyPair.publicKey = ByteString.copyFrom(kind.encryptionKeyPair.publicKey.serialize().removing05PrefixIfNeeded()) - encryptionKeyPair.privateKey = ByteString.copyFrom(kind.encryptionKeyPair.privateKey.serialize()) + encryptionKeyPair.publicKey = ByteString.copyFrom(kind.encryptionKeyPair!!.publicKey.serialize().removing05PrefixIfNeeded()) + encryptionKeyPair.privateKey = ByteString.copyFrom(kind.encryptionKeyPair!!.privateKey.serialize()) closedGroupControlMessage.encryptionKeyPair = encryptionKeyPair.build() closedGroupControlMessage.addAllMembers(kind.members) closedGroupControlMessage.addAllAdmins(kind.admins) diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/control/ConfigurationMessage.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/control/ConfigurationMessage.kt index e33ab11b3a..fe06cc6c01 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/control/ConfigurationMessage.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/control/ConfigurationMessage.kt @@ -14,11 +14,13 @@ import org.session.libsignal.service.loki.utilities.removing05PrefixIfNeeded import org.session.libsignal.service.loki.utilities.toHexString import org.session.libsignal.utilities.Hex -class ConfigurationMessage(): ControlMessage() { +class ConfigurationMessage(var closedGroups: List, var openGroups: List, var contacts: List, var displayName: String, var profilePicture: String?, var profileKey: ByteArray): ControlMessage() { - class ClosedGroup(val publicKey: String, val name: String, val encryptionKeyPair: ECKeyPair, val members: List, val admins: List) { + class ClosedGroup(var publicKey: String, var name: String, var encryptionKeyPair: ECKeyPair?, var members: List, var admins: List) { val isValid: Boolean get() = members.isNotEmpty() && admins.isNotEmpty() + internal constructor(): this("", "", null, listOf(), listOf()) + override fun toString(): String { return name } @@ -42,8 +44,8 @@ class ConfigurationMessage(): ControlMessage() { result.publicKey = ByteString.copyFrom(Hex.fromStringCondensed(publicKey)) result.name = name val encryptionKeyPairAsProto = SignalServiceProtos.KeyPair.newBuilder() - encryptionKeyPairAsProto.publicKey = ByteString.copyFrom(encryptionKeyPair.publicKey.serialize().removing05PrefixIfNeeded()) - encryptionKeyPairAsProto.privateKey = ByteString.copyFrom(encryptionKeyPair.privateKey.serialize()) + encryptionKeyPairAsProto.publicKey = ByteString.copyFrom(encryptionKeyPair!!.publicKey.serialize().removing05PrefixIfNeeded()) + encryptionKeyPairAsProto.privateKey = ByteString.copyFrom(encryptionKeyPair!!.privateKey.serialize()) result.encryptionKeyPair = encryptionKeyPairAsProto.build() result.addAllMembers(members.map { ByteString.copyFrom(Hex.fromStringCondensed(it)) }) result.addAllAdmins(admins.map { ByteString.copyFrom(Hex.fromStringCondensed(it)) }) @@ -51,7 +53,10 @@ class ConfigurationMessage(): ControlMessage() { } } - class Contact(val publicKey: String, val name: String, val profilePicture: String?, val profileKey: ByteArray?) { + class Contact(var publicKey: String, var name: String, var profilePicture: String?, var profileKey: ByteArray?) { + + internal constructor(): this("", "", null, null) + companion object { fun fromProto(proto: SignalServiceProtos.ConfigurationMessage.Contact): Contact? { if (!proto.hasName() || !proto.hasProfileKey()) return null @@ -85,13 +90,6 @@ class ConfigurationMessage(): ControlMessage() { override val ttl: Long = 4 * 24 * 60 * 60 * 1000 override val isSelfSendValid: Boolean = true - var closedGroups: List = listOf() - var openGroups: List = listOf() - var contacts: List = listOf() - var displayName: String = "" - var profilePicture: String? = null - var profileKey: ByteArray = byteArrayOf() - companion object { fun getCurrent(contacts: List): ConfigurationMessage? { @@ -135,14 +133,7 @@ class ConfigurationMessage(): ControlMessage() { } } - internal constructor(closedGroups: List, openGroups: List, contacts: List, displayName: String, profilePicture: String?, profileKey: ByteArray): this() { - this.closedGroups = closedGroups - this.openGroups = openGroups - this.contacts = contacts - this.displayName = displayName - this.profilePicture = profilePicture - this.profileKey = profileKey - } + internal constructor(): this(listOf(), listOf(), listOf(), "", null, byteArrayOf()) override fun toProto(): SignalServiceProtos.Content? { val configurationProto = SignalServiceProtos.ConfigurationMessage.newBuilder() diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageReceiverHandler.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageReceiverHandler.kt index 114b0ba326..c1bfee205f 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageReceiverHandler.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageReceiverHandler.kt @@ -110,7 +110,7 @@ private fun MessageReceiver.handleConfigurationMessage(message: ConfigurationMes val allClosedGroupPublicKeys = storage.getAllClosedGroupPublicKeys() for (closeGroup in message.closedGroups) { if (allClosedGroupPublicKeys.contains(closeGroup.publicKey)) continue - handleNewClosedGroup(message.sender!!, message.sentTimestamp!!, closeGroup.publicKey, closeGroup.name, closeGroup.encryptionKeyPair, closeGroup.members, closeGroup.admins, message.sentTimestamp!!) + handleNewClosedGroup(message.sender!!, message.sentTimestamp!!, closeGroup.publicKey, closeGroup.name, closeGroup.encryptionKeyPair!!, closeGroup.members, closeGroup.admins, message.sentTimestamp!!) } val allOpenGroups = storage.getAllOpenGroups().map { it.value.server } for (openGroup in message.openGroups) { @@ -222,7 +222,7 @@ private fun MessageReceiver.handleNewClosedGroup(message: ClosedGroupControlMess val groupPublicKey = kind.publicKey.toByteArray().toHexString() val members = kind.members.map { it.toByteArray().toHexString() } val admins = kind.admins.map { it.toByteArray().toHexString() } - handleNewClosedGroup(message.sender!!, message.sentTimestamp!!, groupPublicKey, kind.name, kind.encryptionKeyPair, members, admins, message.sentTimestamp!!) + handleNewClosedGroup(message.sender!!, message.sentTimestamp!!, groupPublicKey, kind.name, kind.encryptionKeyPair!!, members, admins, message.sentTimestamp!!) } // Parameter @sender:String is just for inserting incoming info message