Verify digest for backupv2 local media restore.

This commit is contained in:
Cody Henthorne 2024-09-05 15:49:05 -04:00
parent 6112ee9bd3
commit 929942de9d
4 changed files with 14 additions and 12 deletions

View file

@ -23,7 +23,6 @@ import java.io.IOException
import java.io.InputStream
import java.io.OutputStream
import java.util.Collections
import kotlin.random.Random
typealias ArchiveResult = org.signal.core.util.Result<Unit, LocalArchiver.FailureCause>
@ -70,10 +69,9 @@ object LocalArchiver {
}
source()?.use { sourceStream ->
val iv = Random.nextBytes(16) // todo [local-backup] but really do an iv from table
val iv = attachment.remoteIv
val combinedKey = Base64.decode(attachment.remoteKey)
var destination: OutputStream? = filesFileSystem.fileOutputStream(mediaName)
val destination: OutputStream? = filesFileSystem.fileOutputStream(mediaName)
if (destination == null) {
Log.w(TAG, "Unable to create output file for attachment")

View file

@ -478,7 +478,7 @@ class AttachmentTable(
return readableDatabase
.select(*PROJECTION)
.from(TABLE_NAME)
.where("$REMOTE_KEY IS NOT NULL AND $REMOTE_DIGEST IS NOT NULL AND $DATA_FILE IS NOT NULL")
.where("$REMOTE_KEY IS NOT NULL AND $REMOTE_DIGEST IS NOT NULL AND $REMOTE_IV IS NOT NULL AND $DATA_FILE IS NOT NULL")
.orderBy("$ID DESC")
.run()
.readToList {
@ -487,7 +487,8 @@ class AttachmentTable(
random = it.requireNonNullBlob(DATA_RANDOM),
size = it.requireLong(DATA_SIZE),
remoteDigest = it.requireBlob(REMOTE_DIGEST)!!,
remoteKey = it.requireBlob(REMOTE_KEY)!!
remoteKey = it.requireBlob(REMOTE_KEY)!!,
remoteIv = it.requireBlob(REMOTE_IV)!!
)
}
}
@ -2550,7 +2551,8 @@ class AttachmentTable(
val random: ByteArray,
val size: Long,
val remoteDigest: ByteArray,
val remoteKey: ByteArray
val remoteKey: ByteArray,
val remoteIv: ByteArray
)
class LocalRestorableAttachment(

View file

@ -6,6 +6,7 @@ package org.thoughtcrime.securesms.jobs
import android.net.Uri
import org.signal.core.util.Base64
import org.signal.core.util.StreamUtil
import org.signal.core.util.androidx.DocumentFileInfo
import org.signal.core.util.logging.Log
import org.signal.core.util.withinTransaction
@ -145,9 +146,10 @@ class RestoreLocalAttachmentJob private constructor(
val streamSupplier = StreamSupplier { ArchiveFileSystem.openInputStream(context, restoreUri) ?: throw IOException("Unable to open stream") }
try {
// TODO [local-backup] actually verify mac and save iv
AttachmentCipherInputStream.createForAttachment(streamSupplier, size, attachment.size, combinedKey, null, null, 0, true).use { input ->
SignalDatabase.attachments.finalizeAttachmentAfterDownload(attachment.mmsId, attachment.attachmentId, input, null)
val iv = ByteArray(16)
streamSupplier.openStream().use { StreamUtil.readFully(it, iv) }
AttachmentCipherInputStream.createForAttachment(streamSupplier, size, attachment.size, combinedKey, attachment.remoteDigest, null, 0, false).use { input ->
SignalDatabase.attachments.finalizeAttachmentAfterDownload(attachment.mmsId, attachment.attachmentId, input, iv)
}
} catch (e: InvalidMessageException) {
Log.w(TAG, "Experienced an InvalidMessageException while trying to read attachment.", e)

View file

@ -1,7 +1,7 @@
package org.signal.spinner
import android.database.Cursor
import android.util.Base64
import org.signal.core.util.Base64
object DefaultColumnTransformer : ColumnTransformer {
override fun matches(tableName: String?, columnName: String): Boolean {
@ -11,7 +11,7 @@ object DefaultColumnTransformer : ColumnTransformer {
override fun transform(tableName: String?, columnName: String, cursor: Cursor): String? {
val index = cursor.getColumnIndex(columnName)
return when (cursor.getType(index)) {
Cursor.FIELD_TYPE_BLOB -> Base64.encodeToString(cursor.getBlob(index), 0)
Cursor.FIELD_TYPE_BLOB -> Base64.encodeWithPadding(cursor.getBlob(index))
else -> cursor.getString(index)
}
}