Fix group ID handling

pull/286/head
nielsandriesse 4 years ago
parent 317b85561a
commit 9d9affe4f9

@ -209,7 +209,6 @@ import org.thoughtcrime.securesms.util.Dialogs;
import org.thoughtcrime.securesms.util.DynamicLanguage;
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme;
import org.thoughtcrime.securesms.util.ExpirationUtil;
import org.thoughtcrime.securesms.util.GroupUtil;
import org.thoughtcrime.securesms.util.IdentityUtil;
import org.thoughtcrime.securesms.util.MediaUtil;
import org.thoughtcrime.securesms.util.ServiceUtil;
@ -1171,7 +1170,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
String groupPublicKey;
boolean isSSKBasedClosedGroup;
try {
groupPublicKey = HexEncodingKt.toHexString(GroupUtil.getDecodedId(groupRecipient.getAddress().toString()));
groupPublicKey = HexEncodingKt.toHexString(ClosedGroupsProtocol.doubleDecodeGroupID(groupRecipient.getAddress().toString()));
isSSKBasedClosedGroup = DatabaseFactory.getSSKDatabase(this).isSSKBasedClosedGroup(groupPublicKey);
} catch (IOException e) {
groupPublicKey = null;

@ -335,7 +335,7 @@ class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListe
val isClosedGroup = recipient.address.isClosedGroup
// Send a leave group message if this is an active closed group
if (isClosedGroup && DatabaseFactory.getGroupDatabase(this).isActive(recipient.address.toGroupString())) {
val groupPublicKey = GroupUtil.getDecodedId(recipient.address.toString()).toHexString()
val groupPublicKey = ClosedGroupsProtocol.doubleDecodeGroupID(recipient.address.toString()).toHexString()
val isSSKBasedClosedGroup = DatabaseFactory.getSSKDatabase(this).isSSKBasedClosedGroup(groupPublicKey)
if (isSSKBasedClosedGroup) {
ClosedGroupsProtocol.leave(this, groupPublicKey)

@ -27,10 +27,11 @@ import org.whispersystems.signalservice.loki.protocol.closedgroups.SharedSenderK
import org.whispersystems.signalservice.loki.utilities.hexEncodedPrivateKey
import org.whispersystems.signalservice.loki.utilities.hexEncodedPublicKey
import org.whispersystems.signalservice.loki.utilities.toHexString
import java.io.IOException
import java.util.*
object ClosedGroupsProtocol {
val isSharedSenderKeysEnabled = false
val isSharedSenderKeysEnabled = true
public fun createClosedGroup(context: Context, name: String, members: Collection<String>): String {
// Prepare
@ -45,7 +46,7 @@ object ClosedGroupsProtocol {
ClosedGroupSenderKey(Hex.fromStringCondensed(ratchet.chainKey), ratchet.keyIndex, Hex.fromStringCondensed(publicKey))
}
// Create the group
val groupID = GroupUtil.getEncodedId(Hex.fromStringCondensed(groupPublicKey), false)
val groupID = doubleEncodeGroupID(groupPublicKey)
val admins = setOf( userPublicKey )
DatabaseFactory.getGroupDatabase(context).create(groupID, name, LinkedList<Address>(members.map { Address.fromSerialized(it) }),
null, null, LinkedList<Address>(admins.map { Address.fromSerialized(it) }))
@ -74,7 +75,7 @@ object ClosedGroupsProtocol {
// Prepare
val sskDatabase = DatabaseFactory.getSSKDatabase(context)
val groupDB = DatabaseFactory.getGroupDatabase(context)
val groupID = GroupUtil.getEncodedId(Hex.fromStringCondensed(groupPublicKey), false)
val groupID = doubleEncodeGroupID(groupPublicKey)
val group = groupDB.getGroup(groupID).orNull()
if (group == null) {
Log.d("Loki", "Can't add users to nonexistent closed group.")
@ -136,7 +137,7 @@ object ClosedGroupsProtocol {
return
}
val groupDB = DatabaseFactory.getGroupDatabase(context)
val groupID = GroupUtil.getEncodedId(Hex.fromStringCondensed(groupPublicKey), false)
val groupID = doubleEncodeGroupID(groupPublicKey)
val group = groupDB.getGroup(groupID).orNull()
if (group == null) {
Log.d("Loki", "Can't add users to nonexistent closed group.")
@ -241,15 +242,14 @@ object ClosedGroupsProtocol {
sskDatabase.setClosedGroupRatchet(groupPublicKey, senderKey.publicKey.toHexString(), ratchet)
}
// Create the group
val groupID = GroupUtil.getEncodedId(Hex.fromStringCondensed(groupPublicKey), false)
val groupID = doubleEncodeGroupID(groupPublicKey)
DatabaseFactory.getGroupDatabase(context).create(groupID, name, LinkedList<Address>(members.map { Address.fromSerialized(it) }),
null, null, LinkedList<Address>(admins.map { Address.fromSerialized(it) }))
DatabaseFactory.getRecipientDatabase(context).setProfileSharing(Recipient.from(context, Address.fromSerialized(groupID), false), true)
// Add the group to the user's set of public keys to poll for
sskDatabase.setClosedGroupPrivateKey(groupPublicKey, groupPrivateKey.toHexString())
// Notify the user
val threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(Recipient.from(context, Address.fromSerialized(groupID), false))
insertIncomingInfoMessage(context, groupID, GroupContext.Type.UPDATE, SignalServiceGroup.Type.UPDATE, name, members, admins, threadID)
insertIncomingInfoMessage(context, groupID, GroupContext.Type.UPDATE, SignalServiceGroup.Type.UPDATE, name, members, admins)
// Establish sessions if needed
establishSessionsWithMembersIfNeeded(context, members)
}
@ -267,7 +267,7 @@ object ClosedGroupsProtocol {
val members = closedGroupUpdate.membersList.map { it.toByteArray().toHexString() }
val admins = closedGroupUpdate.adminsList.map { it.toByteArray().toHexString() }
val groupDB = DatabaseFactory.getGroupDatabase(context)
val groupID = GroupUtil.getEncodedId(Hex.fromStringCondensed(groupPublicKey), false)
val groupID = doubleEncodeGroupID(groupPublicKey)
val group = groupDB.getGroup(groupID).orNull()
if (group == null) {
Log.d("Loki", "Ignoring closed group info message for nonexistent group.")
@ -312,8 +312,7 @@ object ClosedGroupsProtocol {
// Notify the user
val type0 = if (wasAnyUserRemoved) GroupContext.Type.QUIT else GroupContext.Type.UPDATE
val type1 = if (wasAnyUserRemoved) SignalServiceGroup.Type.QUIT else SignalServiceGroup.Type.UPDATE
val threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(Recipient.from(context, Address.fromSerialized(groupID), false))
insertIncomingInfoMessage(context, groupID, type0, type1, name, members, admins, threadID)
insertIncomingInfoMessage(context, groupID, type0, type1, name, members, admins)
}
public fun handleSenderKeyRequest(context: Context, closedGroupUpdate: SignalServiceProtos.ClosedGroupUpdate, senderPublicKey: String) {
@ -321,7 +320,7 @@ object ClosedGroupsProtocol {
val userPublicKey = TextSecurePreferences.getLocalNumber(context)
val groupPublicKey = closedGroupUpdate.groupPublicKey.toByteArray().toHexString()
val groupDB = DatabaseFactory.getGroupDatabase(context)
val groupID = GroupUtil.getEncodedId(Hex.fromStringCondensed(groupPublicKey), false)
val groupID = doubleEncodeGroupID(groupPublicKey)
val group = groupDB.getGroup(groupID).orNull()
if (group == null) {
Log.d("Loki", "Ignoring closed group sender key request for nonexistent group.")
@ -346,7 +345,7 @@ object ClosedGroupsProtocol {
val sskDatabase = DatabaseFactory.getSSKDatabase(context)
val groupPublicKey = closedGroupUpdate.groupPublicKey.toByteArray().toHexString()
val groupDB = DatabaseFactory.getGroupDatabase(context)
val groupID = GroupUtil.getEncodedId(Hex.fromStringCondensed(groupPublicKey), false)
val groupID = doubleEncodeGroupID(groupPublicKey)
val group = groupDB.getGroup(groupID).orNull()
if (group == null) {
Log.d("Loki", "Ignoring closed group sender key for nonexistent group.")
@ -390,7 +389,7 @@ object ClosedGroupsProtocol {
if (GroupUtil.isOpenGroup(groupID)) {
return listOf( Address.fromSerialized(groupID) )
} else {
val groupPublicKey = GroupUtil.getDecodedId(groupID).toHexString()
val groupPublicKey = doubleDecodeGroupID(groupID).toHexString()
if (DatabaseFactory.getSSKDatabase(context).isSSKBasedClosedGroup(groupPublicKey)) {
return listOf( Address.fromSerialized(groupPublicKey) )
} else {
@ -456,7 +455,7 @@ object ClosedGroupsProtocol {
}
private fun insertIncomingInfoMessage(context: Context, groupID: String, type0: GroupContext.Type, type1: SignalServiceGroup.Type, name: String,
members: Collection<String>, admins: Collection<String>, threadID: Long) {
members: Collection<String>, admins: Collection<String>) {
val groupContextBuilder = GroupContext.newBuilder()
.setId(ByteString.copyFrom(GroupUtil.getDecodedId(groupID)))
.setType(type0)
@ -484,4 +483,18 @@ object ClosedGroupsProtocol {
val infoMessageID = mmsDB.insertMessageOutbox(infoMessage, threadID, false, null)
mmsDB.markAsSent(infoMessageID, true)
}
// NOTE: Signal group ID handling is weird. The ID is double encoded in the database, but not in a `GroupContext`.
@JvmStatic
@Throws(IOException::class)
public fun doubleEncodeGroupID(groupPublicKey: String): String {
return GroupUtil.getEncodedId(GroupUtil.getEncodedId(Hex.fromStringCondensed(groupPublicKey), false).toByteArray(), false)
}
@JvmStatic
@Throws(IOException::class)
public fun doubleDecodeGroupID(groupID: String): ByteArray {
return GroupUtil.getDecodedId(GroupUtil.getDecodedStringId(groupID))
}
}
Loading…
Cancel
Save