From 7dceb98670fb9168876ae268f365d086e1e594fe Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Tue, 7 Sep 2021 16:09:42 +0200 Subject: [PATCH] Add test for decrypting and reading version 0 metadata --- .../metadata/MetadataReadWriteTest.kt | 69 +++++++++++++++++++ .../seedvault/metadata/MetadataV0ReadTest.kt | 67 ++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 app/src/test/java/com/stevesoltys/seedvault/metadata/MetadataReadWriteTest.kt create mode 100644 app/src/test/java/com/stevesoltys/seedvault/metadata/MetadataV0ReadTest.kt diff --git a/app/src/test/java/com/stevesoltys/seedvault/metadata/MetadataReadWriteTest.kt b/app/src/test/java/com/stevesoltys/seedvault/metadata/MetadataReadWriteTest.kt new file mode 100644 index 00000000..1930ac1e --- /dev/null +++ b/app/src/test/java/com/stevesoltys/seedvault/metadata/MetadataReadWriteTest.kt @@ -0,0 +1,69 @@ +package com.stevesoltys.seedvault.metadata + +import com.stevesoltys.seedvault.crypto.CipherFactoryImpl +import com.stevesoltys.seedvault.crypto.CryptoImpl +import com.stevesoltys.seedvault.crypto.KEY_SIZE_BYTES +import com.stevesoltys.seedvault.crypto.KeyManagerTestImpl +import com.stevesoltys.seedvault.getRandomString +import com.stevesoltys.seedvault.header.HeaderReaderImpl +import com.stevesoltys.seedvault.header.HeaderWriterImpl +import com.stevesoltys.seedvault.header.VERSION +import com.stevesoltys.seedvault.metadata.PackageState.APK_AND_DATA +import com.stevesoltys.seedvault.metadata.PackageState.WAS_STOPPED +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.TestInstance +import org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS +import java.io.ByteArrayInputStream +import java.io.ByteArrayOutputStream +import javax.crypto.spec.SecretKeySpec +import kotlin.random.Random + +@TestInstance(PER_CLASS) +internal class MetadataReadWriteTest { + + private val secretKey = SecretKeySpec( + "This is a legacy backup key 1234".toByteArray(), 0, KEY_SIZE_BYTES, "AES" + ) + private val keyManager = KeyManagerTestImpl(secretKey) + private val cipherFactory = CipherFactoryImpl(keyManager) + private val headerWriter = HeaderWriterImpl() + private val headerReader = HeaderReaderImpl() + private val cryptoImpl = CryptoImpl(cipherFactory, headerWriter, headerReader) + + private val writer = MetadataWriterImpl(cryptoImpl) + private val reader = MetadataReaderImpl(cryptoImpl) + + private val packages = HashMap().apply { + put(getRandomString(), PackageMetadata(Random.nextLong(), APK_AND_DATA)) + put(getRandomString(), PackageMetadata(Random.nextLong(), WAS_STOPPED)) + } + + @Test + fun `written metadata matches read metadata`() { + val metadata = getMetadata(packages) + val outputStream = ByteArrayOutputStream() + + writer.write(metadata, outputStream) + + val inputStream = ByteArrayInputStream(outputStream.toByteArray()) + + + assertEquals(metadata, reader.readMetadata(inputStream, metadata.token)) + } + + private fun getMetadata( + packageMetadata: HashMap = HashMap() + ): BackupMetadata { + return BackupMetadata( + version = VERSION, + token = Random.nextLong(), + time = Random.nextLong(), + androidVersion = Random.nextInt(), + androidIncremental = getRandomString(), + deviceName = getRandomString(), + packageMetadataMap = packageMetadata + ) + } + +} diff --git a/app/src/test/java/com/stevesoltys/seedvault/metadata/MetadataV0ReadTest.kt b/app/src/test/java/com/stevesoltys/seedvault/metadata/MetadataV0ReadTest.kt new file mode 100644 index 00000000..b4d1fb99 --- /dev/null +++ b/app/src/test/java/com/stevesoltys/seedvault/metadata/MetadataV0ReadTest.kt @@ -0,0 +1,67 @@ +package com.stevesoltys.seedvault.metadata + +import com.stevesoltys.seedvault.crypto.CipherFactoryImpl +import com.stevesoltys.seedvault.crypto.CryptoImpl +import com.stevesoltys.seedvault.crypto.KEY_SIZE_BYTES +import com.stevesoltys.seedvault.crypto.KeyManagerTestImpl +import com.stevesoltys.seedvault.header.HeaderReaderImpl +import com.stevesoltys.seedvault.header.HeaderWriterImpl +import com.stevesoltys.seedvault.header.VERSION +import com.stevesoltys.seedvault.metadata.PackageState.APK_AND_DATA +import com.stevesoltys.seedvault.metadata.PackageState.WAS_STOPPED +import com.stevesoltys.seedvault.toByteArrayFromHex +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.TestInstance +import org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS +import java.io.ByteArrayInputStream +import javax.crypto.spec.SecretKeySpec + +/** + * Tests that we can still decrypt and read version 0 metadata. + */ +@TestInstance(PER_CLASS) +internal class MetadataV0ReadTest { + + private val secretKey = SecretKeySpec( + "This is a legacy backup key 1234".toByteArray(), 0, KEY_SIZE_BYTES, "AES" + ) + private val keyManager = KeyManagerTestImpl(secretKey) + private val cipherFactory = CipherFactoryImpl(keyManager) + private val headerWriter = HeaderWriterImpl() + private val headerReader = HeaderReaderImpl() + private val cryptoImpl = CryptoImpl(cipherFactory, headerWriter, headerReader) + + private val reader = MetadataReaderImpl(cryptoImpl) + + private val packages = HashMap().apply { + put("org.example", PackageMetadata(23L, APK_AND_DATA)) + put("net.example", PackageMetadata(42L, WAS_STOPPED)) + } + + @Test + fun `written metadata matches read metadata`() { + val metadata = getMetadata(packages) + val encryptedMetadata = ("0000C61EB78225EDD5CBCC4CA693486451C7CF8CAE" + + "D7BCD7B390262EEC4C4ADF721FB35D0D3EFB33ABAFDFA5634DFA361F523183A82ED284330360B9BEA1AC" + + "C323EC05DE1C841AD9B57D76F812494FA9A9BBE9FD01DCC878852A4171DFD456BC13EAC70BA973FF7BC1" + + "75CA84F0324FB35F7AD32CAD5451494B6DE45473519037FCBA50F4DE1CF424552ED813DC782425837B96" + + "F580B01534FE9C9969E0434796F4599B28A533956E180ABD2823E1822DF9E344EEF8BDE06307815332FE" + + "19E757B7133EE3853A7C8157F2ECDE82C0AC1D0A9B187573").toByteArrayFromHex() + val inputStream = ByteArrayInputStream(encryptedMetadata) + assertEquals(metadata, reader.readMetadata(inputStream, metadata.token)) + } + + private fun getMetadata( + packageMetadata: HashMap = HashMap() + ) = BackupMetadata( + version = VERSION, + token = 1337L, + time = 2342L, + androidVersion = 30, + androidIncremental = "sdfqefpojlfj", + deviceName = "foo bar", + packageMetadataMap = packageMetadata + ) + +}