@ -7,6 +7,7 @@ import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper
import org.thoughtcrime.securesms.loki.utilities.*
import org.thoughtcrime.securesms.util.Hex
import org.whispersystems.signalservice.loki.protocol.closedgroups.ClosedGroupRatchet
import org.whispersystems.signalservice.loki.protocol.closedgroups.ClosedGroupRatchetCollectionType
import org.whispersystems.signalservice.loki.protocol.closedgroups.ClosedGroupSenderKey
import org.whispersystems.signalservice.loki.protocol.closedgroups.SharedSenderKeysDatabaseProtocol
import org.whispersystems.signalservice.loki.utilities.PublicKeyValidation
@ -17,13 +18,18 @@ class SharedSenderKeysDatabase(context: Context, helper: SQLCipherOpenHelper) :
// Shared
private val closedGroupPublicKey = " closed_group_public_key "
// Ratchets
private val closedGroupRatchetTable = " closed_group_ratchet_table "
private val oldClosedGroupRatchetTable = " old_closed_group_ratchet_table "
private val currentClosedGroupRatchetTable = " closed_group_ratchet_table "
private val senderPublicKey = " sender_public_key "
private val chainKey = " chain_key "
private val keyIndex = " key_index "
private val messageKeys = " message_keys "
@JvmStatic val createClosedGroupRatchetTableCommand
= " CREATE TABLE $closedGroupRatchetTable ( $closedGroupPublicKey STRING, $senderPublicKey STRING, $chainKey STRING, " +
@JvmStatic val createOldClosedGroupRatchetTableCommand
= " CREATE TABLE $oldClosedGroupRatchetTable ( $closedGroupPublicKey STRING, $senderPublicKey STRING, $chainKey STRING, " +
" $keyIndex INTEGER DEFAULT 0, $messageKeys TEXT, PRIMARY KEY ( $closedGroupPublicKey , $senderPublicKey )); "
// Private keys
@JvmStatic val createCurrentClosedGroupRatchetTableCommand
= " CREATE TABLE $currentClosedGroupRatchetTable ( $closedGroupPublicKey STRING, $senderPublicKey STRING, $chainKey STRING, " +
" $keyIndex INTEGER DEFAULT 0, $messageKeys TEXT, PRIMARY KEY ( $closedGroupPublicKey , $senderPublicKey )); "
// Private keys
private val closedGroupPrivateKeyTable = " closed_group_private_key_table "
@ -32,11 +38,18 @@ class SharedSenderKeysDatabase(context: Context, helper: SQLCipherOpenHelper) :
= " CREATE TABLE $closedGroupPrivateKeyTable ( $closedGroupPublicKey STRING PRIMARY KEY, $closedGroupPrivateKey STRING); "
}
private fun getTable ( collection : ClosedGroupRatchetCollectionType ) : String {
return when ( collection ) {
ClosedGroupRatchetCollectionType . Old -> oldClosedGroupRatchetTable
ClosedGroupRatchetCollectionType . Current -> currentClosedGroupRatchetTable
}
}
// region Ratchets & Sender Keys
override fun getClosedGroupRatchet ( groupPublicKey : String , senderPublicKey : String ) : ClosedGroupRatchet ? {
override fun getClosedGroupRatchet ( groupPublicKey : String , senderPublicKey : String , collection : ClosedGroupRatchetCollectionType ): ClosedGroupRatchet ? {
val database = databaseHelper . readableDatabase
val query = " ${Companion.closedGroupPublicKey} = ? AND ${Companion.senderPublicKey} = ? "
return database . get ( closedGroupRatchetTable , query , arrayOf ( groupPublicKey , senderPublicKey ) ) { cursor ->
return database . get ( getTable( collection ) , query , arrayOf ( groupPublicKey , senderPublicKey ) ) { cursor ->
val chainKey = cursor . getString ( Companion . chainKey )
val keyIndex = cursor . getInt ( Companion . keyIndex )
val messageKeys = cursor . getString ( Companion . messageKeys ) . split ( " - " )
@ -44,7 +57,7 @@ class SharedSenderKeysDatabase(context: Context, helper: SQLCipherOpenHelper) :
}
}
override fun setClosedGroupRatchet ( groupPublicKey : String , senderPublicKey : String , ratchet : ClosedGroupRatchet ) {
override fun setClosedGroupRatchet ( groupPublicKey : String , senderPublicKey : String , ratchet : ClosedGroupRatchet , collection : ClosedGroupRatchetCollectionType ) {
val database = databaseHelper . writableDatabase
val values = ContentValues ( )
values . put ( Companion . closedGroupPublicKey , groupPublicKey )
@ -53,23 +66,33 @@ class SharedSenderKeysDatabase(context: Context, helper: SQLCipherOpenHelper) :
values . put ( Companion . keyIndex , ratchet . keyIndex )
values . put ( Companion . messageKeys , ratchet . messageKeys . joinToString ( " - " ) )
val query = " ${Companion.closedGroupPublicKey} = ? AND ${Companion.senderPublicKey} = ? "
database . insertOrUpdate ( closedGroupRatchetTable , values , query , arrayOf ( groupPublicKey , senderPublicKey ) )
database . insertOrUpdate ( getTable( collection ) , values , query , arrayOf ( groupPublicKey , senderPublicKey ) )
}
override fun removeAllClosedGroupRatchets ( groupPublicKey : String ) {
override fun removeAllClosedGroupRatchets ( groupPublicKey : String , collection : ClosedGroupRatchetCollectionType ) {
val database = databaseHelper . writableDatabase
val query = " ${Companion.closedGroupPublicKey} = ? "
database . delete ( closedGroupRatchetTable , query , arrayOf ( groupPublicKey ) )
database . delete ( getTable( collection ) , query , arrayOf ( groupPublicKey ) )
}
override fun getAllClosedGroup SenderKeys( groupPublicKey : String ) : Set < ClosedGroupSenderKey > {
override fun getAllClosedGroup Ratchets( groupPublicKey : String , collection : ClosedGroupRatchetCollectionType ) : Set < Pair < String , ClosedGroupRatchet > > {
val database = databaseHelper . readableDatabase
val query = " ${Companion.closedGroupPublicKey} = ? "
return database . getAll ( closedGroupRatchetTable , query , arrayOf ( groupPublicKey ) ) { cursor ->
return database . getAll ( getTable( collection ) , query , arrayOf ( groupPublicKey ) ) { cursor ->
val chainKey = cursor . getString ( Companion . chainKey )
val keyIndex = cursor . getInt ( Companion . keyIndex )
val messageKeys = cursor . getString ( Companion . messageKeys ) . split ( " - " )
val senderPublicKey = cursor . getString ( Companion . senderPublicKey )
ClosedGroupSenderKey ( Hex . fromStringCondensed ( chainKey ) , keyIndex , Hex . fromStringCondensed ( senderPublicKey ) )
val ratchet = ClosedGroupRatchet ( chainKey , keyIndex , messageKeys )
Pair ( senderPublicKey , ratchet )
} . toSet ( )
}
override fun getAllClosedGroupSenderKeys ( groupPublicKey : String , collection : ClosedGroupRatchetCollectionType ) : Set < ClosedGroupSenderKey > {
return getAllClosedGroupRatchets ( groupPublicKey , collection ) . map { pair ->
val senderPublicKey = pair . first
val ratchet = pair . second
ClosedGroupSenderKey ( Hex . fromStringCondensed ( ratchet . chainKey ) , ratchet . keyIndex , Hex . fromStringCondensed ( senderPublicKey ) )
} . toSet ( )
}
// endregion