Provide correct version to associated data

This commit is contained in:
Torsten Grote 2021-03-04 17:23:08 -03:00 committed by Chirayu Desai
parent e7a8ad50e8
commit 0aee5cc2aa
4 changed files with 10 additions and 9 deletions

View file

@ -1,7 +1,7 @@
package org.calyxos.backup.storage.crypto
import com.google.crypto.tink.subtle.AesGcmHkdfStreaming
import org.calyxos.backup.storage.backup.Backup
import org.calyxos.backup.storage.backup.Backup.Companion.VERSION
import org.calyxos.backup.storage.crypto.Hkdf.ALGORITHM_HMAC
import org.calyxos.backup.storage.crypto.Hkdf.KEY_SIZE_BYTES
import org.calyxos.backup.storage.toByteArrayFromHex
@ -29,16 +29,16 @@ public object StreamCrypto {
outLengthBytes = KEY_SIZE_BYTES
)
internal fun getAssociatedDataForChunk(chunkId: String): ByteArray =
internal fun getAssociatedDataForChunk(chunkId: String, version: Byte = VERSION): ByteArray =
ByteBuffer.allocate(2 + KEY_SIZE_BYTES)
.put(Backup.VERSION)
.put(version)
.put(TYPE_CHUNK) // type ID for chunks
.put(chunkId.toByteArrayFromHex().apply { check(size == KEY_SIZE_BYTES) })
.array()
internal fun getAssociatedDataForSnapshot(timestamp: Long): ByteArray =
internal fun getAssociatedDataForSnapshot(timestamp: Long, version: Byte = VERSION): ByteArray =
ByteBuffer.allocate(2 + 8)
.put(Backup.VERSION)
.put(version)
.put(TYPE_SNAPSHOT) // type ID for chunks
.put(timestamp.toByteArray())
.array()

View file

@ -16,8 +16,8 @@ internal class SnapshotRetriever(
@Throws(IOException::class, GeneralSecurityException::class)
suspend fun getSnapshot(streamKey: ByteArray, timestamp: Long): BackupSnapshot {
return storagePlugin.getBackupSnapshotInputStream(timestamp).use { inputStream ->
inputStream.readVersion()
val ad = streamCrypto.getAssociatedDataForSnapshot(timestamp)
val version = inputStream.readVersion()
val ad = streamCrypto.getAssociatedDataForSnapshot(timestamp, version.toByte())
streamCrypto.newDecryptingStream(streamKey, inputStream, ad).use { decryptedStream ->
BackupSnapshot.parseFrom(decryptedStream)
}

View file

@ -24,7 +24,7 @@ internal abstract class AbstractChunkRestore(
) {
storagePlugin.getChunkInputStream(chunkId).use { inputStream ->
inputStream.readVersion(version)
val ad = streamCrypto.getAssociatedDataForChunk(chunkId)
val ad = streamCrypto.getAssociatedDataForChunk(chunkId, version.toByte())
streamCrypto.newDecryptingStream(streamKey, inputStream, ad).use { decryptedStream ->
streamReader(decryptedStream)
}

View file

@ -116,7 +116,7 @@ internal class Restore(
}
@Throws(IOException::class, GeneralSecurityException::class)
internal fun InputStream.readVersion(expectedVersion: Int? = null) {
internal fun InputStream.readVersion(expectedVersion: Int? = null): Int {
val version = read()
if (version == -1) throw IOException()
if (expectedVersion != null && version != expectedVersion) {
@ -126,4 +126,5 @@ internal fun InputStream.readVersion(expectedVersion: Int? = null) {
// TODO maybe throw a different exception here and tell the user?
throw IOException()
}
return version
}