mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-20 11:08:31 +00:00
Prevent invalid profile keys from being processed for storage service.
This commit is contained in:
@@ -22,10 +22,12 @@ import org.signal.core.util.requireLong
|
|||||||
import org.signal.core.util.requireString
|
import org.signal.core.util.requireString
|
||||||
import org.signal.libsignal.zkgroup.InvalidInputException
|
import org.signal.libsignal.zkgroup.InvalidInputException
|
||||||
import org.signal.libsignal.zkgroup.profiles.ExpiringProfileKeyCredential
|
import org.signal.libsignal.zkgroup.profiles.ExpiringProfileKeyCredential
|
||||||
|
import org.signal.libsignal.zkgroup.profiles.ProfileKey
|
||||||
import org.thoughtcrime.securesms.badges.Badges
|
import org.thoughtcrime.securesms.badges.Badges
|
||||||
import org.thoughtcrime.securesms.badges.models.Badge
|
import org.thoughtcrime.securesms.badges.models.Badge
|
||||||
import org.thoughtcrime.securesms.conversation.colors.AvatarColor
|
import org.thoughtcrime.securesms.conversation.colors.AvatarColor
|
||||||
import org.thoughtcrime.securesms.conversation.colors.ChatColors
|
import org.thoughtcrime.securesms.conversation.colors.ChatColors
|
||||||
|
import org.thoughtcrime.securesms.crypto.ProfileKeyUtil
|
||||||
import org.thoughtcrime.securesms.database.IdentityTable.VerifiedStatus
|
import org.thoughtcrime.securesms.database.IdentityTable.VerifiedStatus
|
||||||
import org.thoughtcrime.securesms.database.RecipientTable.RegisteredState
|
import org.thoughtcrime.securesms.database.RecipientTable.RegisteredState
|
||||||
import org.thoughtcrime.securesms.database.model.DistributionListId
|
import org.thoughtcrime.securesms.database.model.DistributionListId
|
||||||
@@ -47,7 +49,6 @@ import org.thoughtcrime.securesms.wallpaper.ChatWallpaper
|
|||||||
import org.thoughtcrime.securesms.wallpaper.ChatWallpaperFactory
|
import org.thoughtcrime.securesms.wallpaper.ChatWallpaperFactory
|
||||||
import org.whispersystems.signalservice.api.push.ServiceId
|
import org.whispersystems.signalservice.api.push.ServiceId
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.util.Arrays
|
|
||||||
|
|
||||||
object RecipientTableCursorUtil {
|
object RecipientTableCursorUtil {
|
||||||
|
|
||||||
@@ -60,21 +61,19 @@ object RecipientTableCursorUtil {
|
|||||||
fun getRecord(context: Context, cursor: Cursor, idColumnName: String): RecipientRecord {
|
fun getRecord(context: Context, cursor: Cursor, idColumnName: String): RecipientRecord {
|
||||||
val profileKeyString = cursor.requireString(RecipientTable.PROFILE_KEY)
|
val profileKeyString = cursor.requireString(RecipientTable.PROFILE_KEY)
|
||||||
val expiringProfileKeyCredentialString = cursor.requireString(RecipientTable.EXPIRING_PROFILE_KEY_CREDENTIAL)
|
val expiringProfileKeyCredentialString = cursor.requireString(RecipientTable.EXPIRING_PROFILE_KEY_CREDENTIAL)
|
||||||
var profileKey: ByteArray? = null
|
var profileKey: ProfileKey? = null
|
||||||
var expiringProfileKeyCredential: ExpiringProfileKeyCredential? = null
|
var expiringProfileKeyCredential: ExpiringProfileKeyCredential? = null
|
||||||
|
|
||||||
if (profileKeyString != null) {
|
if (profileKeyString != null) {
|
||||||
try {
|
profileKey = ProfileKeyUtil.profileKeyOrNull(profileKeyString)
|
||||||
profileKey = Base64.decode(profileKeyString)
|
|
||||||
} catch (e: IOException) {
|
|
||||||
Log.w(TAG, e)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (expiringProfileKeyCredentialString != null) {
|
if (profileKey == null) {
|
||||||
|
Log.w(TAG, "Profile key present in db but is invalid, ignoring on read")
|
||||||
|
} else if (expiringProfileKeyCredentialString != null) {
|
||||||
try {
|
try {
|
||||||
val columnDataBytes = Base64.decode(expiringProfileKeyCredentialString)
|
val columnDataBytes = Base64.decode(expiringProfileKeyCredentialString)
|
||||||
val columnData = ExpiringProfileKeyCredentialColumnData.ADAPTER.decode(columnDataBytes)
|
val columnData = ExpiringProfileKeyCredentialColumnData.ADAPTER.decode(columnDataBytes)
|
||||||
if (Arrays.equals(columnData.profileKey.toByteArray(), profileKey)) {
|
if (columnData.profileKey.toByteArray().contentEquals(profileKey.serialize())) {
|
||||||
expiringProfileKeyCredential = ExpiringProfileKeyCredential(columnData.expiringProfileKeyCredential.toByteArray())
|
expiringProfileKeyCredential = ExpiringProfileKeyCredential(columnData.expiringProfileKeyCredential.toByteArray())
|
||||||
} else {
|
} else {
|
||||||
Log.i(TAG, "Out of date profile key credential data ignored on read")
|
Log.i(TAG, "Out of date profile key credential data ignored on read")
|
||||||
@@ -135,7 +134,7 @@ object RecipientTableCursorUtil {
|
|||||||
expireMessages = cursor.requireInt(RecipientTable.MESSAGE_EXPIRATION_TIME),
|
expireMessages = cursor.requireInt(RecipientTable.MESSAGE_EXPIRATION_TIME),
|
||||||
expireTimerVersion = cursor.requireInt(RecipientTable.MESSAGE_EXPIRATION_TIME_VERSION),
|
expireTimerVersion = cursor.requireInt(RecipientTable.MESSAGE_EXPIRATION_TIME_VERSION),
|
||||||
registered = RegisteredState.fromId(cursor.requireInt(RecipientTable.REGISTERED)),
|
registered = RegisteredState.fromId(cursor.requireInt(RecipientTable.REGISTERED)),
|
||||||
profileKey = profileKey,
|
profileKey = profileKey?.serialize(),
|
||||||
expiringProfileKeyCredential = expiringProfileKeyCredential,
|
expiringProfileKeyCredential = expiringProfileKeyCredential,
|
||||||
systemProfileName = ProfileName.fromParts(cursor.requireString(RecipientTable.SYSTEM_GIVEN_NAME), cursor.requireString(RecipientTable.SYSTEM_FAMILY_NAME)),
|
systemProfileName = ProfileName.fromParts(cursor.requireString(RecipientTable.SYSTEM_GIVEN_NAME), cursor.requireString(RecipientTable.SYSTEM_FAMILY_NAME)),
|
||||||
systemDisplayName = cursor.requireString(RecipientTable.SYSTEM_JOINED_NAME),
|
systemDisplayName = cursor.requireString(RecipientTable.SYSTEM_JOINED_NAME),
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import org.signal.core.util.isNotEmpty
|
|||||||
import org.signal.core.util.logging.Log
|
import org.signal.core.util.logging.Log
|
||||||
import org.signal.core.util.nullIfBlank
|
import org.signal.core.util.nullIfBlank
|
||||||
import org.signal.core.util.nullIfEmpty
|
import org.signal.core.util.nullIfEmpty
|
||||||
|
import org.thoughtcrime.securesms.crypto.ProfileKeyUtil
|
||||||
import org.thoughtcrime.securesms.database.RecipientTable
|
import org.thoughtcrime.securesms.database.RecipientTable
|
||||||
import org.thoughtcrime.securesms.database.SignalDatabase
|
import org.thoughtcrime.securesms.database.SignalDatabase
|
||||||
import org.thoughtcrime.securesms.database.model.RecipientRecord
|
import org.thoughtcrime.securesms.database.model.RecipientRecord
|
||||||
@@ -215,7 +216,7 @@ class ContactRecordProcessor(
|
|||||||
pni = mergedPni?.toStringWithoutPrefix() ?: ""
|
pni = mergedPni?.toStringWithoutPrefix() ?: ""
|
||||||
givenName = mergedProfileGivenName
|
givenName = mergedProfileGivenName
|
||||||
familyName = mergedProfileFamilyName
|
familyName = mergedProfileFamilyName
|
||||||
profileKey = remote.proto.profileKey.nullIfEmpty() ?: local.proto.profileKey
|
profileKey = remote.proto.profileKey.nullIfEmpty()?.takeIf { ProfileKeyUtil.profileKeyOrNull(it.toByteArray()) != null } ?: local.proto.profileKey
|
||||||
username = remote.proto.username.nullIfBlank() ?: local.proto.username
|
username = remote.proto.username.nullIfBlank() ?: local.proto.username
|
||||||
identityState = mergedIdentityState
|
identityState = mergedIdentityState
|
||||||
identityKey = mergedIdentityKey?.toByteString() ?: ByteString.EMPTY
|
identityKey = mergedIdentityKey?.toByteString() ?: ByteString.EMPTY
|
||||||
|
|||||||
Reference in New Issue
Block a user