From ccf7c4ac1f881087210875b06f7c0639ec3d706b Mon Sep 17 00:00:00 2001 From: Denis Trotsenko Date: Tue, 23 Jan 2024 00:22:21 +0100 Subject: [PATCH] Extract test resources as files --- .../kotpass/database/KeePassDatabaseSpec.kt | 68 ++++++------------ .../database/header/DatabaseHeaderSpec.kt | 18 ++--- .../header/DatabaseInnerHeaderSpec.kt | 11 +-- .../database/header/VariantDictionarySpec.kt | 6 +- .../database/modifiers/CredentialsSpec.kt | 4 +- .../database/modifiers/CustomIconsSpec.kt | 5 +- .../keemobile/kotpass/models/BinariesSpec.kt | 7 +- .../app/keemobile/kotpass/models/EntrySpec.kt | 2 +- .../kotpass/resources/Argon2TestCase.kt | 13 ---- .../kotpass/resources/DatabaseRes.kt | 17 +---- .../kotpass/resources/VariantDictionaryRes.kt | 2 - .../test/resources/groups_and_entries.kdbx | Bin 0 -> 1677 bytes .../test/resources/inner_header_with_binaries | Bin 0 -> 2666 bytes .../{entry => }/invalid_references.kdbx | Bin kotpass/src/test/resources/kdf_params | Bin 0 -> 232 bytes kotpass/src/test/resources/ver3_aes.kdbx | Bin 0 -> 1118 bytes kotpass/src/test/resources/ver4_aes.kdbx | Bin 0 -> 1215 bytes kotpass/src/test/resources/ver4_argon2.kdbx | Bin 0 -> 1245 bytes .../test/resources/ver4_with_binaries.kdbx | Bin 0 -> 3933 bytes 19 files changed, 41 insertions(+), 112 deletions(-) delete mode 100644 kotpass/src/test/kotlin/app/keemobile/kotpass/resources/Argon2TestCase.kt create mode 100644 kotpass/src/test/resources/groups_and_entries.kdbx create mode 100644 kotpass/src/test/resources/inner_header_with_binaries rename kotpass/src/test/resources/{entry => }/invalid_references.kdbx (100%) create mode 100644 kotpass/src/test/resources/kdf_params create mode 100644 kotpass/src/test/resources/ver3_aes.kdbx create mode 100644 kotpass/src/test/resources/ver4_aes.kdbx create mode 100644 kotpass/src/test/resources/ver4_argon2.kdbx create mode 100644 kotpass/src/test/resources/ver4_with_binaries.kdbx diff --git a/kotpass/src/test/kotlin/app/keemobile/kotpass/database/KeePassDatabaseSpec.kt b/kotpass/src/test/kotlin/app/keemobile/kotpass/database/KeePassDatabaseSpec.kt index c4bb758..a950399 100644 --- a/kotpass/src/test/kotlin/app/keemobile/kotpass/database/KeePassDatabaseSpec.kt +++ b/kotpass/src/test/kotlin/app/keemobile/kotpass/database/KeePassDatabaseSpec.kt @@ -15,7 +15,6 @@ import app.keemobile.kotpass.database.modifiers.removeEntry import app.keemobile.kotpass.database.modifiers.removeGroup import app.keemobile.kotpass.database.modifiers.withHistory import app.keemobile.kotpass.database.modifiers.withRecycleBin -import app.keemobile.kotpass.io.decodeBase64ToArray import app.keemobile.kotpass.models.DatabaseElement import app.keemobile.kotpass.models.DeletedObject import app.keemobile.kotpass.models.Entry @@ -46,28 +45,21 @@ class KeePassDatabaseSpec : DescribeSpec({ describe("Database decoder") { it("Reads KeePass 3.x file") { - val database = loadDatabase( - rawData = DatabaseRes.DbVer3Aes, - passphrase = "1" - ) + val database = loadDatabase("ver3_aes.kdbx", "1") + database.content.group.name shouldBe "New" } it("Reads KeePass 4.x file") { - val database = loadDatabase( - rawData = DatabaseRes.DbVer4WithBinaries, - passphrase = "1" - ) + val database = loadDatabase("ver4_with_binaries.kdbx", "1") + database.content.group.name shouldBe "New" } } describe("Database encoder") { it("Writes KeePass 3.x file") { - var database = loadDatabase( - rawData = DatabaseRes.DbVer3Aes, - passphrase = "1" - ) + var database = loadDatabase("ver3_aes.kdbx", "1") val data = ByteArrayOutputStream() .apply { database.encode(this) } .toByteArray() @@ -79,10 +71,7 @@ class KeePassDatabaseSpec : DescribeSpec({ } it("Writes KeePass 4.x file") { - var database = loadDatabase( - rawData = DatabaseRes.DbVer4Argon2, - passphrase = "1" - ) + var database = loadDatabase("ver4_argon2.kdbx", "1") val data = ByteArrayOutputStream() .apply { database.encode(this) } .toByteArray() @@ -96,10 +85,7 @@ class KeePassDatabaseSpec : DescribeSpec({ describe("Database search") { it("Traverse database") { - val database = loadDatabase( - rawData = DatabaseRes.GroupsAndEntries.DbGroupsAndEntries, - passphrase = "1" - ) + val database = loadDatabase("groups_and_entries.kdbx", "1") val result = mutableSetOf() database.traverse { result += it } @@ -166,10 +152,7 @@ class KeePassDatabaseSpec : DescribeSpec({ } it("Finds entries with specific title") { - val database = loadDatabase( - rawData = DatabaseRes.GroupsAndEntries.DbGroupsAndEntries, - passphrase = "1" - ) + val database = loadDatabase("groups_and_entries.kdbx", "1") val entries = database.findEntries { it[BasicField.Title] ?.content @@ -180,10 +163,7 @@ class KeePassDatabaseSpec : DescribeSpec({ } it("Finds entry with specific title") { - val database = loadDatabase( - rawData = DatabaseRes.GroupsAndEntries.DbGroupsAndEntries, - passphrase = "1" - ) + val database = loadDatabase("groups_and_entries.kdbx", "1") val result = database.findEntry { it[BasicField.Title] ?.content @@ -194,10 +174,7 @@ class KeePassDatabaseSpec : DescribeSpec({ } it("Finds group with specific name") { - val database = loadDatabase( - rawData = DatabaseRes.GroupsAndEntries.DbGroupsAndEntries, - passphrase = "1" - ) + val database = loadDatabase("groups_and_entries.kdbx", "1") val result = database.getGroup { it.name == "Group 3" } result shouldNotBe null @@ -208,7 +185,7 @@ class KeePassDatabaseSpec : DescribeSpec({ describe("Database modifiers") { it("Removed Group is moved to recycle bin") { val database = loadDatabase( - rawData = DatabaseRes.GroupsAndEntries.DbGroupsAndEntries, + fileName = "groups_and_entries.kdbx", passphrase = "1" ).withRecycleBin { recycleBinUuid -> moveGroup(DatabaseRes.GroupsAndEntries.Group2, recycleBinUuid) @@ -222,7 +199,7 @@ class KeePassDatabaseSpec : DescribeSpec({ it("Removed Group and it's children UUIDs are added to deleted objects") { val database = loadDatabase( - rawData = DatabaseRes.GroupsAndEntries.DbGroupsAndEntries, + fileName = "groups_and_entries.kdbx", passphrase = "1" ).removeGroup( DatabaseRes.GroupsAndEntries.Group2 @@ -242,7 +219,7 @@ class KeePassDatabaseSpec : DescribeSpec({ it("Group modification") { val (_, group) = loadDatabase( - rawData = DatabaseRes.GroupsAndEntries.DbGroupsAndEntries, + fileName = "groups_and_entries.kdbx", passphrase = "1" ).modifyGroup(DatabaseRes.GroupsAndEntries.Group3) { copy(name = "Hello") @@ -256,7 +233,7 @@ class KeePassDatabaseSpec : DescribeSpec({ it("Groups mass modification") { val label = "Hello" val database = loadDatabase( - rawData = DatabaseRes.GroupsAndEntries.DbGroupsAndEntries, + fileName = "groups_and_entries.kdbx", passphrase = "1" ).modifyGroups { copy(name = label) @@ -272,7 +249,7 @@ class KeePassDatabaseSpec : DescribeSpec({ it("Entries mass modification") { val label = "Hello" val database = loadDatabase( - rawData = DatabaseRes.GroupsAndEntries.DbGroupsAndEntries, + fileName = "groups_and_entries.kdbx", passphrase = "1" ).modifyEntries { copy(overrideUrl = label) @@ -287,7 +264,7 @@ class KeePassDatabaseSpec : DescribeSpec({ it("Entry modification with history") { val (_, entry) = loadDatabase( - rawData = DatabaseRes.GroupsAndEntries.DbGroupsAndEntries, + fileName = "groups_and_entries.kdbx", passphrase = "1" ).modifyEntry(DatabaseRes.GroupsAndEntries.Entry1) { withHistory { @@ -303,7 +280,7 @@ class KeePassDatabaseSpec : DescribeSpec({ it("Removed Entry is moved to recycle bin") { val database = loadDatabase( - rawData = DatabaseRes.GroupsAndEntries.DbGroupsAndEntries, + fileName = "groups_and_entries.kdbx", passphrase = "1" ).withRecycleBin { recycleBinUuid -> moveEntry(DatabaseRes.GroupsAndEntries.Entry1, recycleBinUuid) @@ -317,7 +294,7 @@ class KeePassDatabaseSpec : DescribeSpec({ it("Removed Entry UUID is added to deleted objects") { val database = loadDatabase( - rawData = DatabaseRes.GroupsAndEntries.DbGroupsAndEntries, + fileName = "groups_and_entries.kdbx", passphrase = "1" ).removeEntry( DatabaseRes.GroupsAndEntries.Entry1 @@ -331,10 +308,7 @@ class KeePassDatabaseSpec : DescribeSpec({ } it("Old entries are removed from history when performing cleanup") { - val database = loadDatabase( - rawData = DatabaseRes.GroupsAndEntries.DbGroupsAndEntries, - passphrase = "1" - ) + val database = loadDatabase("groups_and_entries.kdbx", "1") val outdated = Instant .now() .minus(Period.ofDays(database.content.meta.maintenanceHistoryDays + 1)) @@ -359,9 +333,9 @@ class KeePassDatabaseSpec : DescribeSpec({ }) private fun loadDatabase( - rawData: String, + fileName: String, passphrase: String ) = KeePassDatabase.decode( - inputStream = ByteArrayInputStream(rawData.decodeBase64ToArray()), + inputStream = ClassLoader.getSystemResourceAsStream(fileName)!!, credentials = Credentials.from(EncryptedValue.fromString(passphrase)) ) diff --git a/kotpass/src/test/kotlin/app/keemobile/kotpass/database/header/DatabaseHeaderSpec.kt b/kotpass/src/test/kotlin/app/keemobile/kotpass/database/header/DatabaseHeaderSpec.kt index a63a6d9..4f9d48b 100644 --- a/kotpass/src/test/kotlin/app/keemobile/kotpass/database/header/DatabaseHeaderSpec.kt +++ b/kotpass/src/test/kotlin/app/keemobile/kotpass/database/header/DatabaseHeaderSpec.kt @@ -1,38 +1,35 @@ package app.keemobile.kotpass.database.header -import app.keemobile.kotpass.io.decodeBase64ToArray -import app.keemobile.kotpass.resources.DatabaseRes import io.kotest.core.spec.style.DescribeSpec import io.kotest.matchers.shouldBe import io.kotest.matchers.types.shouldBeInstanceOf import okio.Buffer import okio.buffer import okio.source -import java.io.ByteArrayInputStream class DatabaseHeaderSpec : DescribeSpec({ describe("Database header") { it("Properly reads KDF parameters") { - val ver4Argon2 = decodeHeader(DatabaseRes.DbVer4Argon2) + val ver4Argon2 = decodeHeader("ver4_argon2.kdbx") ver4Argon2.signature.base shouldBe Signature.Base ver4Argon2.shouldBeInstanceOf() with(ver4Argon2) { kdfParameters.shouldBeInstanceOf() } - val ver4Aes = decodeHeader(DatabaseRes.DbVer4Aes) + val ver4Aes = decodeHeader("ver4_aes.kdbx") ver4Aes.shouldBeInstanceOf() with(ver4Aes) { kdfParameters.shouldBeInstanceOf() } - val ver3Aes = decodeHeader(DatabaseRes.DbVer3Aes) + val ver3Aes = decodeHeader("ver3_aes.kdbx") ver3Aes.shouldBeInstanceOf() } it("Try to read/write header") { - val ver4Argon2 = decodeHeader(DatabaseRes.DbVer4Argon2).let { header -> + val ver4Argon2 = decodeHeader("ver4_argon2.kdbx").let { header -> val buffer = Buffer() header.writeTo(buffer) buffer.snapshot() @@ -51,7 +48,6 @@ class DatabaseHeaderSpec : DescribeSpec({ } }) -private fun decodeHeader(base64Data: String): DatabaseHeader { - val bytes = base64Data.decodeBase64ToArray() - return DatabaseHeader.readFrom(ByteArrayInputStream(bytes).source().buffer()) -} +private fun decodeHeader(fileName: String) = ClassLoader + .getSystemResourceAsStream(fileName)!! + .use { DatabaseHeader.readFrom(it.source().buffer()) } diff --git a/kotpass/src/test/kotlin/app/keemobile/kotpass/database/header/DatabaseInnerHeaderSpec.kt b/kotpass/src/test/kotlin/app/keemobile/kotpass/database/header/DatabaseInnerHeaderSpec.kt index 40a5cdc..0d8f93d 100644 --- a/kotpass/src/test/kotlin/app/keemobile/kotpass/database/header/DatabaseInnerHeaderSpec.kt +++ b/kotpass/src/test/kotlin/app/keemobile/kotpass/database/header/DatabaseInnerHeaderSpec.kt @@ -1,26 +1,21 @@ package app.keemobile.kotpass.database.header import app.keemobile.kotpass.constants.CrsAlgorithm -import app.keemobile.kotpass.io.decodeBase64ToArray -import app.keemobile.kotpass.resources.DatabaseRes import io.kotest.core.spec.style.DescribeSpec import io.kotest.matchers.shouldBe import okio.Buffer import okio.buffer import okio.source -import java.io.ByteArrayInputStream class DatabaseInnerHeaderSpec : DescribeSpec({ describe("Database inner header") { it("Properly reads and writes data") { val buffer = Buffer() - val data = DatabaseRes.InnerHeaderWithBinaries.decodeBase64ToArray() - val source = ByteArrayInputStream(data) - .source() - .buffer() + var innerHeader = ClassLoader + .getSystemResourceAsStream("inner_header_with_binaries")!! + .use { DatabaseInnerHeader.readFrom(it.source().buffer()) } - var innerHeader = DatabaseInnerHeader.readFrom(source) innerHeader.randomStreamId shouldBe CrsAlgorithm.ChaCha20 innerHeader.binaries.size shouldBe 2 diff --git a/kotpass/src/test/kotlin/app/keemobile/kotpass/database/header/VariantDictionarySpec.kt b/kotpass/src/test/kotlin/app/keemobile/kotpass/database/header/VariantDictionarySpec.kt index f5eee91..15f21f2 100644 --- a/kotpass/src/test/kotlin/app/keemobile/kotpass/database/header/VariantDictionarySpec.kt +++ b/kotpass/src/test/kotlin/app/keemobile/kotpass/database/header/VariantDictionarySpec.kt @@ -1,19 +1,21 @@ package app.keemobile.kotpass.database.header import app.keemobile.kotpass.constants.KdfConst -import app.keemobile.kotpass.io.decodeBase64ToArray import app.keemobile.kotpass.io.decodeHexToArray import app.keemobile.kotpass.resources.VariantDictionaryRes import io.kotest.core.spec.style.DescribeSpec import io.kotest.matchers.shouldBe import io.kotest.matchers.types.shouldBeInstanceOf import okio.ByteString.Companion.toByteString +import java.io.InputStream class VariantDictionarySpec : DescribeSpec({ describe("Variant dictionary") { it("Properly reads and writes data") { - val dictionary = VariantDictionaryRes.KdfParams.decodeBase64ToArray() + val dictionary = ClassLoader + .getSystemResourceAsStream("kdf_params")!! + .use(InputStream::readAllBytes) .toByteString() .let(VariantDictionary::readFrom) .let(VariantDictionary::writeToByteString) diff --git a/kotpass/src/test/kotlin/app/keemobile/kotpass/database/modifiers/CredentialsSpec.kt b/kotpass/src/test/kotlin/app/keemobile/kotpass/database/modifiers/CredentialsSpec.kt index 112a2d9..8dfc024 100644 --- a/kotpass/src/test/kotlin/app/keemobile/kotpass/database/modifiers/CredentialsSpec.kt +++ b/kotpass/src/test/kotlin/app/keemobile/kotpass/database/modifiers/CredentialsSpec.kt @@ -5,8 +5,6 @@ import app.keemobile.kotpass.database.Credentials import app.keemobile.kotpass.database.KeePassDatabase import app.keemobile.kotpass.database.decode import app.keemobile.kotpass.database.encode -import app.keemobile.kotpass.io.decodeBase64ToArray -import app.keemobile.kotpass.resources.DatabaseRes import io.kotest.core.spec.style.DescribeSpec import io.kotest.matchers.shouldBe import java.io.ByteArrayInputStream @@ -21,7 +19,7 @@ class CredentialsSpec : DescribeSpec({ keyData = byteArrayOf(0x4, 0x7, 0x9) ) var database = KeePassDatabase.decode( - ByteArrayInputStream(DatabaseRes.DbVer4Argon2.decodeBase64ToArray()), + ClassLoader.getSystemResourceAsStream("ver4_argon2.kdbx")!!, Credentials.from(EncryptedValue.fromString("1")) ).modifyCredentials { newCredentials diff --git a/kotpass/src/test/kotlin/app/keemobile/kotpass/database/modifiers/CustomIconsSpec.kt b/kotpass/src/test/kotlin/app/keemobile/kotpass/database/modifiers/CustomIconsSpec.kt index 1d0c3c2..c832099 100644 --- a/kotpass/src/test/kotlin/app/keemobile/kotpass/database/modifiers/CustomIconsSpec.kt +++ b/kotpass/src/test/kotlin/app/keemobile/kotpass/database/modifiers/CustomIconsSpec.kt @@ -5,12 +5,9 @@ import app.keemobile.kotpass.database.Credentials import app.keemobile.kotpass.database.KeePassDatabase import app.keemobile.kotpass.database.decode import app.keemobile.kotpass.database.traverse -import app.keemobile.kotpass.io.decodeBase64ToArray import app.keemobile.kotpass.models.CustomIcon -import app.keemobile.kotpass.resources.DatabaseRes import io.kotest.core.spec.style.DescribeSpec import io.kotest.matchers.shouldBe -import java.io.ByteArrayInputStream import java.util.UUID class CustomIconsSpec : DescribeSpec({ @@ -22,7 +19,7 @@ class CustomIconsSpec : DescribeSpec({ uuid to CustomIcon(byteArrayOf(0x1), null, null) ) val database = KeePassDatabase.decode( - ByteArrayInputStream(DatabaseRes.DbVer4Argon2.decodeBase64ToArray()), + ClassLoader.getSystemResourceAsStream("ver4_argon2.kdbx")!!, Credentials.from(EncryptedValue.fromString("1")) ).modifyCustomIcons { customIcons diff --git a/kotpass/src/test/kotlin/app/keemobile/kotpass/models/BinariesSpec.kt b/kotpass/src/test/kotlin/app/keemobile/kotpass/models/BinariesSpec.kt index db82e82..da9ed04 100644 --- a/kotpass/src/test/kotlin/app/keemobile/kotpass/models/BinariesSpec.kt +++ b/kotpass/src/test/kotlin/app/keemobile/kotpass/models/BinariesSpec.kt @@ -9,16 +9,13 @@ import app.keemobile.kotpass.database.modifiers.modifyEntry import app.keemobile.kotpass.database.modifiers.removeUnusedBinaries import app.keemobile.kotpass.extensions.getText import app.keemobile.kotpass.extensions.parseAsXml -import app.keemobile.kotpass.io.decodeBase64ToArray import app.keemobile.kotpass.io.encodeBase64 -import app.keemobile.kotpass.resources.DatabaseRes import app.keemobile.kotpass.xml.marshal import app.keemobile.kotpass.xml.unmarshalBinaries import io.kotest.core.spec.style.DescribeSpec import io.kotest.matchers.shouldBe import okio.buffer import okio.source -import java.io.ByteArrayInputStream import java.util.UUID private const val Contents = "hello kotpass" @@ -61,8 +58,8 @@ class BinariesSpec : DescribeSpec({ it("Removes unused binaries") { val database = KeePassDatabase.decode( - inputStream = ByteArrayInputStream(DatabaseRes.DbVer4WithBinaries.decodeBase64ToArray()), - credentials = Credentials.from(EncryptedValue.fromString("1")) + ClassLoader.getSystemResourceAsStream("ver4_with_binaries.kdbx")!!, + Credentials.from(EncryptedValue.fromString("1")) ).modifyEntry(UUID.fromString("6d9b7812-6d1a-1765-9cd7-c66a93a220e9")) { copy(binaries = listOf()) }.removeUnusedBinaries() diff --git a/kotpass/src/test/kotlin/app/keemobile/kotpass/models/EntrySpec.kt b/kotpass/src/test/kotlin/app/keemobile/kotpass/models/EntrySpec.kt index e38380b..da69148 100644 --- a/kotpass/src/test/kotlin/app/keemobile/kotpass/models/EntrySpec.kt +++ b/kotpass/src/test/kotlin/app/keemobile/kotpass/models/EntrySpec.kt @@ -81,7 +81,7 @@ class EntrySpec : DescribeSpec({ it("Invalid binary references are skipped") { val database = decodeFromResources( - path = "entry/invalid_references.kdbx", + path = "invalid_references.kdbx", credentials = Credentials.from(EncryptedValue.fromString("1")) ) diff --git a/kotpass/src/test/kotlin/app/keemobile/kotpass/resources/Argon2TestCase.kt b/kotpass/src/test/kotlin/app/keemobile/kotpass/resources/Argon2TestCase.kt deleted file mode 100644 index ce51478..0000000 --- a/kotpass/src/test/kotlin/app/keemobile/kotpass/resources/Argon2TestCase.kt +++ /dev/null @@ -1,13 +0,0 @@ -package app.keemobile.kotpass.resources - -import app.keemobile.kotpass.cryptography.Argon2Engine - -internal class Argon2TestCase( - val version: Argon2Engine.Version, - val iterations: Int, - val memory: Int, - val parallelism: Int, - val password: String, - val salt: String, - val output: String -) diff --git a/kotpass/src/test/kotlin/app/keemobile/kotpass/resources/DatabaseRes.kt b/kotpass/src/test/kotlin/app/keemobile/kotpass/resources/DatabaseRes.kt index 1b2b40e..18b3c6a 100644 --- a/kotpass/src/test/kotlin/app/keemobile/kotpass/resources/DatabaseRes.kt +++ b/kotpass/src/test/kotlin/app/keemobile/kotpass/resources/DatabaseRes.kt @@ -1,22 +1,10 @@ -@file:Suppress("ktlint:standard:max-line-length") +@file:Suppress("ktlint:standard:max-line-length", "HasPlatformType") package app.keemobile.kotpass.resources import java.util.UUID internal object DatabaseRes { - const val DbVer4Argon2 = - "A9mimmf7S7UAAAQAAhAAAAAxwfLmv3FDUL5YBSFq/Fr/AwQAAAABAAAABCAAAACcUe6sTzwUKvVJ1JQuWI6yut61mmq3BtbU+IGYbIk9iAcQAAAAfjItHPp6tU4GeGDe7ue9ZQuLAAAAAAFCBQAAACRVVUlEEAAAAO9jbd+MKURLkfeppAPjCgxCAQAAAFMgAAAAc3TvZ7GrIAVWD9C9EMmILKRGRg+eULvvuugNqlBE99cEAQAAAFAEAAAAAQAAAAUBAAAASQgAAAACAAAAAAAAAAUBAAAATQgAAAAAABAAAAAAAAQBAAAAVgQAAAATAAAAAAAEAAAAANCtCvVQB4HJT8I4JUyVkfJ/gRtyhoAOFXcnm0p4CV7H2VCBeBiT24OtPlDqF/l2A/H/e2OCIjOJXJF894p9ezPZv03ZWDJDI73IxoS59qFgwiuV7ERvi0wGlCNTuLkoP+Km9HADAACiwAXkSSI9unVc7xlX4aAQv1T97OrFedJulvMwoc06fKfzEevK36ZWum42hH3JfOQMmyy9FawCt4yMFBdIMYdTNofZgjXPkpT0cw6gd23NKjslD7fypOCHcJl6uBPpf+Q4YLAbFz3D8QiBboPofbcFK78W5A82uGLJ+0Kq6g1aojkZWNFP3O7AD3dwej/OaTnp/FVQ7VuV2fL2fxKz2NJPVwsAHUzWi4KlLT3F4Mk9o+F45HRJA1dmzWKn817EtYMSqAXOWRNT9OmJKscM+GnUyIzDV1J34oxAU88ignav1f68ulU7Q6N98PpEN4XwVqnq7F7xeF1oIpiuTmy7cMBAT2Er60AMF9udwSgq9KzQOnT2z/tg/hLIqkYqEM9dUOynyMV36LMMB2byCix8Tuo1LTP26jzlPU+VzZj3Cjo04cwHE2btH974oz9cyFKn3N5r+ptlMAqg04dOGk0sokO391qYVAnp82oYtw6Va0qqGYcck5TCWLLJ8Ygh1HFtDVS2EiA3yNm5jYkRTvIDTKJGjQ9iRxw4b9BKwjJ+IcRzY2qA30xP40nChH02+jbymfeY9b+NPiQY+JCnbEYbS4oJeABMEjS5Xinm5Pn5XQCY1HNIMtsI7jHq6BjkYrTtLo+vijxFPZ0MYxleIM1tqi+Jq1xx1jl5UqOhr9YoHDldG98IRv38YpxAWXjYWIC74xGzQsgQwL7Nu32RT19O9SWrSKajrVaYaC0aUGwYS41PEOpzM/SjyaG2sHGgB5s/7jP6Sn0pYLaXhh5KiOpjgODnvt2TWzfubuSE/Oxnsm9hRbkJwQo3L+lZZg2ONyzX3O/Uosv6dRbmtYgbAukYkdNnfxIMhPD8hzPl0epSDLA2vId58UFgG+sM43DZbUSfxf/nctWLLQUvCKsOapQEx9hu/ok9RCt0h+XTIWc2mW/uLY4rK09z7dGxkGjOpzCvk9ONoYNT4W/Ry1BC0SDONhgCtV/Spmx76hRrXiwbOOG2FkxCLrzYexi7fbUx1LqodNKj2dq7W3Jg82Hs838ktta+7oR387f1SSNyAVE1j/RJ/fJEpWUeXRR0k2zsFCgyJDc0QVgdLfttXlyiHUeGHV5q4GGTFR7EBZS/niphQ4Cs2JHHH9GZKqReWJpeMGahNP6eZDdFy/rBb3gGNJt6B104EBN5QbpTZc7vgo55ce8GhCmysU8QH2PaRK7Y2gK9m9QAAAAA" - const val DbVer4Aes = - "A9mimmf7S7UAAAQAAhAAAAAxwfLmv3FDUL5YBSFq/Fr/AwQAAAABAAAABCAAAACCdsEJoa+/HI4PlAqhFR+1ZoZ1aU6vtdlxY5jLWTEcogcQAAAAUiN/IXWVctgggk7HpkgJCwtdAAAAAAFCBQAAACRVVUlEEAAAAMnZ85piikRgv3QNCMGKT+pCAQAAAFMgAAAAcvkOGPCC91iXT7+0PHgKSrz1iyw1hClm2lIY0lKQqz0FAQAAAFIIAAAA4JMEAAAAAAAAAAQAAAAA0K0KMpvUzK+vW5N4VgfrjB6WpW5pQta2y8oXrSdnB/fipqvp0zQrRasNKs2n+nJIsG/z5/cID6qCn9SKTXJyCHBB69DvHXbl/IGT/554qluYE8KSxdWBB7aa5iAOcZcOZFNXcAMAAD4h3BpDHx/phFQR4yEvnLaHiXytgubQTRgo5iukAn8/QmMCu5zjvcGap3BoBKghkjHpOMFdEtDum7pHBqbncsIH81bbqFchEKWj+GPnxWjVau1164emKOMVrre+srFVNUKMpDynw+mZ2oNZcRzApKVPGH2nDqx4QAgaOQGcllCBlYjnsCZlZC2tFOuopdRva8fNOWEXgyMcICd9sUV3KBLBn0mk0W2vAoKXe8MwHUfEzVtCAOzP8vFSEnJcqkGmJsZjx2d6SlZkvGqgrwM7p9VLVxCwSkVDKPuFq2qtNSbGZX1iZsZOM0N4VDBQLrlIaNSxLnKnKxnRYl/8dScD4Q7h4MlYBHQX1OLyLlAR/n78Pe201A22KRCHrjh7sqQ/v0Miq3msN8crnvofMky9xuA65k1HAwH8nIfQPDWxaYKhK9CDXifC7JNfrcCw6jxwY3FSP9mm/HKQQjgF3+n3dEhJofWCGh8Z3yrgws/vo2WDHUay5Ia3puR7L2Wmu4+XDnt8EjwqVkkG58x8OcmfHwxgr3ax46rrDfLMts4UWILGaI8I0vcDSZHvQya6ibQ10gIYFP840pgOj5DPtIASfWWj6qpNSmyRZ4aLfRD7xrjlKcKBtOvLT7Or1KO48a8G+Y13DXucsIWCvSBFUiiMKimvh6nLD/5t1Nu0igsBDChP4a/JMhtpVg7dUuH1jQKvDaD6TdJ/PTj5K7oFDhKqyuwIGLpaP8T7k3+luYZgf0jWSNKGTZ37ZEg7yLI9oZ7G0JqV/UrPWiWg7VMoMmCBm9ZM5JBNp4Qdjf3cJWESxEXNtNgVldDSFoTR6kATiJjhS7gk6kWD/1YvjVS2wkVejTWBIk9xSygwmH++CvtibLr+V5TXawprkDuAeGGhfo46OH7gwuK1wvPdmmrykay9f7AZdGOCpeFiZ+jmxiBj+mXmB0Qrz0Pb3SltkH9rOMhV1YBqSHyyuym84HBq/bWoCzc5a0sM9OQ5jMKOK1r5/BxWGx2Ebx/KQhCGW6546Ld6ny99YUhYKG0UMNI3DumC5FXP+bZL0wbGE084hB544zFCR4v83Eqwp5dSTyG0ktfrnGGV8dHG57nKacoB0jORKuCnCV32fW3+GkdwptdZXTXUA9OLIonWpf1nlH5gIHhlwGhg5DaMCVHNjKRFLzbaaHmuwuGNPdzanrBmQFl1DQncq20FXaedD1hYIa8iBeNnfAAAAAA=" - const val DbVer3Aes = - "A9mimmf7S7UBAAMAAhAAMcHy5r9xQ1C+WAUhavxa/wMEAAEAAAAEIADPW/svS+DO+i81CZi5jwPx7vSMZw+kOwtuEJTouxna4wUgAFWzSwWWLFs6rXDhCoNaKdbhKdGvylbOv5+Ncnbw0dqfBggA4JMEAAAAAAAHEAAn+eowy7s6eTvbMQs/ryVLCCAAioXpc+uUeyTeddOZwLffvUunUnML+A/9A38SYZ/rBwQJIAC59LlFQ1RIzJoRZB8dILrJGNmebgtHlT02d5eLs4kkZwoEAAIAAAAABAAA0K0KEBueuGwWZkKS9K32Q2zBN5SmA7S/mYxzv8efJEJtNs1h+s6UxPDDnVHTYzQlYZI1O/mIthq/QkfCaUng2YeFy5DIgNWPsAFn8kdV7hT2UTnf2A/jBoVI5Cr+kz0jeZEQzYiG0UaLWy36zWeSkuFSrtDHWQ7Q1wnx854ifQXCMc0evvFVVSH3JGb2AP1RbhmuYTLiyxN2RSzSH3p3I94ka0gJTA+mV8NuNRRaubK4Ycf5mfFc6ZSoIsb0Y2c4wcN4QusWBNZvfYy3EeV3YNJkT9wzI1HdMSXTwyxm9INL/wFb7AII6Laoym4KFt2fQzGwAUewg1ReLDrZml28K6rOovj3oXopn405Xc+WzrcqzOkxRUdH1HJy7jpLNpdi0bQ7HYDeTmd5CuY5eORMNBgfEWgJXNHZiWqFHsB2/XFf3eH4BUqeNDLrbTbJbnrfT+c3KTjATkT+JiTESqUZwAHJC5eXOoobCsKg8s5gnjklEmaO+qGtNcmuiMlno9wbzX9e3ZUFAJcIXGOWNTKJnNu3qHSw5YA0bKoEGAaRByqpogtwuOguC4qkt0Yru1aYAlXPPW8QOTh+7peiO6XO9qFe++WiPQTZbuiuJdI4plkZ98L1o4OyLRXMr50xX+Td2R7QWCK/gQn7Vkc7uhIOjggLYsp2qOIjougzAgiwxMJouc+a20oy1tWKPXejgRVj9Lt9WI8H0ygMZlkO+wdcCG0jhW+eoWva/ToC+dbAm9CBuYgQvGoPCVVSO8UqVEBozPsOyOWOn3bSxQKOhuztoVUYrGpSkU2w3lLxpbGcHD79X8+ar6lYbWmxADK7/Ppx9LTs4OuMY9awgVCQ9IeewFH4Ort6108D8NHc15UMaKvxnod6to55KewIC9UVga/Fx4Zl/yEiPDh7sOTti+NnOWS0VwKbuaHWPYbsWtMrNBlhEElF6EyT/YZTwE0AMwv9k8ySYVtcqBx7zkNCUKpn67yJNseYZYubm6+KL/jS3XyU6N+RQTBvwSLKej1f/AfJC399dhKHsXRQ2b3hsP7m1yJmbgMQcOk4q2Ocob8rODlZWo3rJr4C+dXVrYCMWsM2XO6nN2/vz/8VDXNerpnQlX43Fc07VTOSWbz370cT9980YAZQLdPJcbN/ENyePUrAxfbAYVJp/dcH04ECSaTINUUe6/x4qjFDXAi2iBFBg9YdBltC6+nxHgS2D2NAUs/96P7g" - const val DbVer4WithBinaries = - "A9mimmf7S7UAAAQAAhAAAAAxwfLmv3FDUL5YBSFq/Fr/AwQAAAABAAAABCAAAACwWqXeJaah8unGdIxhqjbCvXrWcLF6ullsvD8XkoJb9wcQAAAAUjZzu1p2z84s0Intp0fLMQuLAAAAAAFCBQAAACRVVUlEEAAAAO9jbd+MKURLkfeppAPjCgxCAQAAAFMgAAAANlEDHJRwyHFyf9WnPBkx+sL1pvpDFKx01op+mmMS6icEAQAAAFAEAAAAAQAAAAUBAAAASQgAAAACAAAAAAAAAAUBAAAATQgAAAAAABAAAAAAAAQBAAAAVgQAAAATAAAAAAAEAAAAANCtCigDn/ypaXDxDfK4w9d/u4mzP4JsQTSy3JG+wyzEflibuQBgei6SrSk/AmStcEZQNz1bYQuzcvOfuesYS0/2oRJg3BegDJNsx3v+A/dyv/Orm552arKwTCR+5NDS+qD+n+ANAADROoc/WMO6GcErxON9UhjWqoVVUwCe9C13R/MNcyY6MPQjYM352MXSHSHKEFMDSI7UkTNEVTmrXrnmbEcEfKXmRidYnfjtUkTUnFngsSaUCO5c2B3hgMz23ODqw5m3mPS9RoZbDsuFSNrmRoy6wuCn1oDD5DpSTDcDMX7gX6pIZzicRt0MyzcS/koi+9Gd3IIgsuTySJbgzUBQBFm7gnXVKyLKlRl3dlMO0BUpbrPYQhkYsY6MnBR/qb8yfik8hTMh+zjObo6FC4fMZgyIJmCKOloXxbKid+LZYcENDAg5mWWVIj7OmDSyyw8EE6MWtNBQzJBODL/22QgeueuZ7vJTtaTqbID7oI0Mah5hXN6pffo7DPhpKkVjmkaWk8uncCDrrEBa4scoaD9bKLrOOMhUbuvYzKxF64WwimfUPFcCGhSBxSQkptoe5tzZ8hiYa7APt7v6RD1wZ9Yvi2YfXnfok5AChCcr/CBWeMHYSCE1Jo6hghdBrWk7U/0XMJNdg7v5sSmzgkZ9iuNPtHeV+82NjOcsd5QqQ1cvbNPG5gfPzUSqPsAS4ztCXuooo7nV95IOGCQKi9KlUiuxjxxc9MFEC8HcTSK+kxBkNydVSpNLc5YerwaSptGbMmZ4/GsjSjmAqXczhdUtOHE/vbCJseCowYSbu5pAW/uVC9zY26/k6YIv3mnAmsBk034vJEaLuVom+7AF7ij8V+XN0ZpZVoo3dvAf2ndcJ31kjw8f52lXqLG0nxtrG9a5b620iArKoHZxRX3P9NnAT1zAEChMhx14Jn+FjyDCpLiV8xoN2tqjkGRK7xeT7Q4FcMLkDx6J9zSoLl8l062leCNosolYam+saLKokKFp2fnk4fAOpK4clg9wXRvZd909fvspagBErgbHIpIzGX3cT3DemUYtCdsym9Zq4QPpsV+XjfQZl1FbeCJv+2BFqmE2i0ndX1gb4d1pUa75Ro1LDjAWOtPaMKOmkceEXxb/+vYtVnEJRYWF6e7EuddKIUdcnovK2FHuQbuDX2ytq+QovMrAEZoZBepAuu5OLAMEq+WMNBz4znNzkpk3opt2vPzJgpVCzedmYybPjJXbxZtvhbWgM7dg84CHplAJgNtgoK2dJaGdw/KdkYXKIB9mzXJC7qcIhKTzB7tTW68bjTsr2RT2uFvPtJOj9Yghf4qMz3MIkb+E6qAovlb78eTkpjkAm7f7egZohwvanbhY7ez1yz95KWp7HXWvj9Er32dV9e9H/fdGn0lZ4Aou73seYn7pGgSBzO/fbHR8QgjBHROz7rXLVhFudPBPbrah1y2vlXb7ioQ5gfusE5liLE+JHtoAPeu6cQT79GRwIF5rzyN3YnUsU1xHOu0slyAsbhHUuT2WaERTzFMTR0PMsLJICnCzPRMXhq+hPjLX09zHJ0ivsC5ur5sXf9gN0MD7rjjVPW+rcdyMgTOfn5xy4Dfq2dGemoNSgc39FQg1FF1mbsdDc2S8scxMapKc0dxNjr7X4CLyX4RwbsCxc1Y2mlUzFwUtXklr/CV04vTGENmBfiO5f8Bk4RoW4129Frbu3txjBvD3eAY/abIK4nW2g9JGoszJVenFIO5GbpPE785v5WH6ltebk1t1eYeu8LRNIta5cES2WbPOcDf7SuyMvSkZX+pFyxvlKTBtErGSQNGHv6g2CLNRe0wKlK8084tPmpWb85+/4TaXmtDT/hKKRoj3qAoMOQqLJTRzpTb0AMpUQFW6LsT2XUOFgxuCErvnKbq2hMRSFBxGkiuCOoJjvbtD0W+4fNnXYHL6Q/BU4MoKvlnlv/ztFPoMGkWeaUAoCCv4D5wal92qY6tbb+3kL4qPTMLl46lYjN8/9ugv1GUfGfzdPDU1Ysl7NPI/WIZ6iR6r+Cmw/X5R9qaNefQHTc+O2T8W0DzMEGEre5mY2GgfjFHAIA/vWoHmKgP0Ir9imIGuQC31IsHEpbQyRMD5Oxkw1BthFO7nE+QlI1xQa5FJ9BC3JL3u9gLOTfWbl6zGXMigkMfKnETmsfHx7jVXZJg3gOgVlsQyVtBXYkPJQAkb0LhmAVl0ACsceiuhVTWQd5LzaP4ndFiJTD4KOq8xC38Iqe2ia9yG1JhJFSJU5aLY9c3M/T+0QML3PlQwmN92dEMvyi2hWIjVekEvdhAwg7CerYqUtd7vrrkaNNT1NZT+Nf9HaprMlJIeHZwOrTCnuwo/NBfTyuzEZbw8GbaWL0YrTjD8dvAdioifqKCKyBAtxgnsR7M1/6h60mMXswoj9kojcU/DxGa6RlQ5UGQq4Tsb5rcE9yJlpiL+wb5sEm7VXkTeuK5gQ0vrMxJNiprFRWY6OztShShTRVgJfTMZlVjHJ+XnBlxkjs0GNWq+L8326OQ5GW+zVnVAb0Z+9kN7ODK4Tavgqcp9lubYGDrC/oPBX7a72Kk9f11nBCpnKRtj3fldeoZFcbUuXWOHqzCuTtLzXlPu/SX+v3TzBUEzjjncK4TiShAiJuGhMLXrsZ+09tg/WK3dvLOz2xpO+lzUr8am6TjjwVWoH2Wk74MJDGq0BTHF0BPQg2Sty5YNDbhc+j7gsPjm8AhzY2ARaPuhdOpfBjvepuGUtU/DaFUO7m/Id1y4j3aWu1lwaJq6pVZArOCEIJOQCz23fShVtKv55NxMOuDZnIHwheT+o63NBh7JG6uz7XZMVW4ZLzzx/eVSfc/RyYICx48pkRsMkLzRqZ6F2CKjOvudUU/3grPFwyixRJJibsF8gwtEe8tBuYunvRcIhc6YLzt7A0n+KIVd6VmrdJdBYsAfXWcxhsXX0y9QqzS8enzpSwn6361yFqB+35lKAXpaaQYF0jAu7SYoEP133QMP/xdKfdIjzqpmFunRQd/fVmOjj2IWcjffByK2QYAzfBVBEx6KghVJUOJvxw7h4hPcLSKgoyOAK0vv32WOg6MVnWPknwcbnimX+g0deKaiRpTw80k+hP3vgN/2vnqWX+YIxuRmAHEG/E5uEsrS8Grv5b8pQI7nH+ZlFogD6jt4vJPnC0BraHxbwHXF7SjHJ1T4+yVudrCwvNeTkMJvYv4NlZc5U3ZRBDevlSqhufA1lX1CoPzaIcp+dp9FM68esUdr2LPPwnFiNuvNDSv9eR40Id3UZWlB8w3naebQNsjFFtfnjwsnna54be4sASGn6U7eEBtCMKpS6JpzMnFq9rTc2iakg2gVK3TbofXoV5uDS4gJdIdS0lrWbmD3v2voxGCBG1ObFSr0voYxYCBhi3zADlRHAhoDimagW8oRiA/DfRZtKXGPnMPsZxeZVgJX9ilqjt0TwVNVEg1zzkLsKOCkgWo2v4Iipl30HQ0pjSyqsJDtrr96wVncvxV7AoMZE+tDvmDbFzT68LpfzD+J2nAgmYVDbHIDoUrMTpY6/Ow4tfb53gG156CC9htO1pKcY41/kf7bAjwbx4rFpMITewje0CJCBv45rf4q6PNq+uT4VNLgzqZWHuRrQm3FjZlMUZjEkpq2Ah9ImguC9wEnRADevFnlAg4TGBnI+U3JHXOqJZtZihhkdsA6+/2S/VfRKNRFBOg7fn5l8f06hePhExAQEY3izKAlWfTj42i08qrHJ9hM2I3mH1TuXY8NnkxOAsfHq++G4E4TD1hWqQF1N8xN5ecu+i2nESROEinDAXwVrBooK1vVw1XJUUO+YRh6PUIaYwUZQ62PAkSAq0CIWWaBYPp8R8QhPw5xc9A3vsxUR87vpE+LZ/uhO+xY6Bw+nIX+uXQkewqeqTn7+OtHdvp8errDE97KIQ0azQ3onScuaCwIACkzL7rJsog17PoZEqW+JtgGp0PZ9hjJWB5xoWtefkYMKH8U43pnEOiLZR3bwzWZOZDzSJTOMbrgaBFuPwIhAGRMxKXECkIdrCBcWfKisC4RQ+zO4HqNcRpoq6faLkwTs9rdkh1Sym2JXZKNhAPKjtPSz1xII0RVyKzJ2Pvq5tlkzwTCVX5ALzN4KgWSI0XyrASolLcboFZ4DBapxq0qAzv02HFrqzs7qL4HHpd99ageCyi23dRXHwopcg5apeL6/GslXL7iRt852vg9wn00PEuGU4fLibW+QGaQKmYNWn0VuKt895ynvgMzPUlZe5mH2Zw3/u9HLfgOy8jYVIu1SE1HfGmeiouKa6wCqu+3kP61RT1x/g/bYdnhuRYSXMYxt42gdobekNX1jts6tihZ0YfJUuBrZPOExNFTOVNMKWb9QW6gCgeq4N70fKtMUF0ZWt5zUrVhEZlxfd+dJ5dAWbyZHUm3ah0lxmEKNyStOEKtszM1A1UHXAOatr2GnSqipHjoTU6iFR33/Hehms1gu0FvPgUrwoEkmdb2EaV+qLRw4p7qoD4DfJBHzqyYPQRPpHxuqBWxIo0lK6SiiOwn6mwTYmuQ9fXwoI/uBQZd/VBsPz5fmIuSpPn3u/EqoIEkIB/cPjoxYjYMfuPp8Rho8PSnOoq5doDt2/fskiEOMTBJbO825L5Nj4a0J1uX3A4MfBRnQpWR7UG8bnrcYK7sScOHDsVFJ3S8Gc/UuwmJC3/bfn64WlZpCu8VeVGUWWj60Y0Xwz03GGEyIKwX1hEwnI3Th3Y8veZyIkMQKhxxYQdKuV53qa3z3Ak9PASnwTRJLLBYKESIeDJZPxNnP4KEinxSNkmZnEvQmrxN+1yY2B6mUmdw61KIpvPDtbHOvB4UFA5A2KW4n41aIr2Zz13Ay14Uet7dvhcjWWKvA+OFZHqqmoA6DRJW+/QoW1F4vpIVUjttpYydEh7XFAWyIRBYOf5S8cQkTAAAAAA=" - - const val InnerHeaderWithBinaries = - "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" - object GroupsAndEntries { val Group1 = UUID.fromString("c997344c-952b-e02b-06a6-29510ce71a12") val Group2 = UUID.fromString("928f39d5-e1b6-88a9-f4f1-b60b36399186") @@ -25,8 +13,5 @@ internal object DatabaseRes { val Entry1 = UUID.fromString("ba06b36c-c7c8-8f8c-655f-a39dc403c6fa") val Entry2 = UUID.fromString("208e2034-9fc5-c955-5cbf-46d892123316") val Entry3 = UUID.fromString("4e805fdc-8305-7909-2574-d8e2ae2e520a") - - const val DbGroupsAndEntries = - "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" } } diff --git a/kotpass/src/test/kotlin/app/keemobile/kotpass/resources/VariantDictionaryRes.kt b/kotpass/src/test/kotlin/app/keemobile/kotpass/resources/VariantDictionaryRes.kt index b20df1b..15aee3c 100644 --- a/kotpass/src/test/kotlin/app/keemobile/kotpass/resources/VariantDictionaryRes.kt +++ b/kotpass/src/test/kotlin/app/keemobile/kotpass/resources/VariantDictionaryRes.kt @@ -4,6 +4,4 @@ package app.keemobile.kotpass.resources internal object VariantDictionaryRes { const val Uuid = "ef636ddf8c29444b91f7a9a403e30a0c" - const val KdfParams = - "AAFCBQAAACRVVUlEEAAAAO9jbd+MKURLkfeppAPjCgxCAQAAAFMgAAAAc3TvZ7GrIAVWD9C9EMmILKRGRg+eULvvuugNqlBE99cEAQAAAFAEAAAAAQAAAAUBAAAASQgAAAACAAAAAAAAAAUBAAAATQgAAAAAABAAAAAAAAQBAAAAVgQAAAATAAAAAA==AAFCBQAAACRVVUlEEAAAAMnZ85piikRgv3QNCMGKT+pCAQAAAFMgAAAAcvkOGPCC91iXT7+0PHgKSrz1iyw1hClm2lIY0lKQqz0FAQAAAFIIAAAA4JMEAAAAAAAA" } diff --git a/kotpass/src/test/resources/groups_and_entries.kdbx b/kotpass/src/test/resources/groups_and_entries.kdbx new file mode 100644 index 0000000000000000000000000000000000000000..64493262255d1d69c49927f578c4eadee084071e GIT binary patch literal 1677 zcmV;826FiW*`k_f`%AR|00aO65C8xGF~RcYzi~rQzE}kzYW!ON0|Wp70096100bZa z002c8JS_ACn0o>YMt)%-!SV^xNablQ(pfCQ=sH{P-C73_0000}F-yqF3_x9=jSVPm zz|wpRivR!s00BY;0000aRaHqu5C8xG?_+J>j44D*k@u;j1LFz|LID5(08=0U003n^ zc&;)br<#?T)|YyNC#iSt|4*1<;C|n;KUA8XpqvB&0000`1ONa40RR911pxp608I!0 z000005C8xG000F60000<2mk;80ssI2000001OWg509FJ5000vJ0000C0{{R300961 z1ONa44GIkk*}Dy|9*Ac*0d5V)vT`)8n*BTLhu1SOx@lMh+Qqveb^E9EG3yR;%m11E z^67(0(DBZMB@?t0K6WP235bUzr~#Lpzcws;wT>JRZIPPgaH6ZEUR2uE@UcN~Ax(bu z00jU52qF&d8=9sCv=cY1S^&2!05DWAEmc85q?}!4e|K(p>paVBDFc!%LK+J*!9XKVBf-jdlxuhx9V5t)QCz8*)QyQA9V9wfSOOs6V`ohBq-sW`7 zGjHDJmYQh^W+ZfHfvJN=5^g)c*<*6+j>533+0TLW-Pk?%W)Oh$f;<{L$-q>{Vx9C8 zY_sCCHz&K8PJ)DzoH#{*Pq*KVVwg9NK*8wQlCj@0L1Gfj!Bx*UI|EeIr%d!j(jXUy z9M?8dN)tE8ACo~0?lk|nMID@ANw7&ydFTfMB4xgK6wq8?fqx0L(nr5iqh{&Fq0t7{ zkYCuN*FGME16bL)^BOs`B> zQ+3}b^UsW48)kw%B90V_7E)>8oM9H*b;jFHph+L&{*A%(kJP1SagMtk@-e$wG0fJDqkd zR2J<_+;`f6jSBpkc%XXQ`abh)%9=qc)4;ULr9!k}rv2iF7|W^o4?^_jl= zz<{*B@28Nk{jcyyv#|dI5$(F2H?1$Gb0S_Eg(m%dZ(9%=H9&7o$swY9HwdD+VW3^l zVBQ^ky^dwHfJou3oHk{FD7PJ4e!D@5&}la>ZK#h(jaq)9EB?8-;?U&Nb?^R(4L> zknZd37X$~E?V>KK{6V1Y`Dn!Pi1a9x%Jq+gIkz^nbGb%QIM_3Ywe`b{o=BQ8_n6000001TOxz literal 0 HcmV?d00001 diff --git a/kotpass/src/test/resources/inner_header_with_binaries b/kotpass/src/test/resources/inner_header_with_binaries new file mode 100644 index 0000000000000000000000000000000000000000..8eb92a8b8f2eb036ef7017c38bc6ce7392600705 GIT binary patch literal 2666 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 literal 0 HcmV?d00001 diff --git a/kotpass/src/test/resources/entry/invalid_references.kdbx b/kotpass/src/test/resources/invalid_references.kdbx similarity index 100% rename from kotpass/src/test/resources/entry/invalid_references.kdbx rename to kotpass/src/test/resources/invalid_references.kdbx diff --git a/kotpass/src/test/resources/kdf_params b/kotpass/src/test/resources/kdf_params new file mode 100644 index 0000000000000000000000000000000000000000..22de8f07016df33f088f3f81e41464c030735aef GIT binary patch literal 232 zcmZQzbYf*-U{DDS^>h&cGTtZW-tWZMK7HeA1=cYB z3ws4lcIYf|bK{>Eu>1Y47rd(iT)tmt0jUgN0TLhvD~Ryq01`|<3<6*gUyuj`1IQ)@ z2C$AWkPcxmpFu<+0I1$IG-Qe+P=IIde9L7TOWe4>J6!0ISn_X)0#F;P5m1I*f5O9l x4*k;3lHb3bk2fq?eLiB-;RvT`xl0v$RW-RbUkCuHRA^ve;NvuK0BT@h001E>I066w literal 0 HcmV?d00001 diff --git a/kotpass/src/test/resources/ver3_aes.kdbx b/kotpass/src/test/resources/ver3_aes.kdbx new file mode 100644 index 0000000000000000000000000000000000000000..6d2966091f9e2b34045201236d1fa79bc0e94a81 GIT binary patch literal 1118 zcmV-k1flx_*`k_f`%AR}00RI55CAd3^5(yBLr}h01tDtuTK@wC0096100bZa%e(y? zb}4*ACCH9&r9aON{eQk9{zK9wLBxgFm5ujkMlte=9@#Q- zfSh@%j7c0)3?oels}2AJ01XNa3R)3H2UjhSg!t^W$&Go*T6&g5KBznl%62O+*7`fP z9y*>UA=$pke{DE)JePVIjn|nt6(YY$lxNRW2c^>HiTukJEIP#>Z)L=xxPh&n#$S#{ ziX5nmNzvV>cIluz0uU&B1Mr;iIYS`Am4`XB@$AHpR2*6VV=fC+!Y72;ALx+t@0K$= zvFj+c{=d9osR2H)#ek-LOk$iG&0&AD=#^=Pr1Eo;h~q0iW&zamj{{ zE=XgBAXGwwc~Z;JhD7RFpuCpjbvmFGOfZZ2BlYyu3&2=)ddRbNWTc@$AcKDfE*!PT zs#Lv<6%~G`R&gQe^J;m;FQ+s|7CV((@Qp$PP4#xq1&P_u@d>C-Sjeke&S1zD8N^5f zvft*u*&HLn%2H7M@GS zVqfX%2;xg&webH#%OgxhAT{}SB?aJU;DKC5Rx37cbpT+F{-wo>=;Ze^>uC&aE^ln% zZno@F@^#spvy`;RAGZ3nuK=~^_zzNErpUhXFOAT`3#^^y@|1VE4BK4uh*n{98*(i` zE}B1xfeATap^+IyenfeTg6WF!@t6gArK~K#Yh`do>fg_YC3ivgPpD0?7i|-pUk*LBCPc6A#k-}= zplUb;P21u&;R?*nfKlxBklZvtGER5p1_$)7sglLgdhO#3s%o}-Yv2&PT>z-3Wv@V_v=TMYC|E2TNTmAJ6**xYKqk__wT%dC*Z<8%&8?fi!E9LwjJ(m}s z2Iy&%DJ?Tt<800BY;0000aRaHqu5C8xG$=UOoVv0myzjO@io{CHllbW0Yr)QGQ7xctF-Kqh60tm30Kv&sm&kjD5k& zHMZ7Qh>(|TujLXCAf3>$T~Fx7Gow~;|Eo&vg-JgY7goq^N$-$Vv4eoRJnez0066%-pDOV|7BAIZ=Mk6@UaEq?!*6~OzpaZWt7jZ+)d|BW!Gj((OuD- z7%|%m{}c;Hq$m}RLRaVh2NcFMEDHqv-Z= zK1?xthS+b@;pzM^knU~H<3nJ})k08Afk(Wy^!F7fkTz33d24U+w3PgK0oFcrkyWCQ zix|@j@va#o3HesYTH$BSyv+Z3m|DD$RJ0R1IQAkjLVE_nhPM{n7wg+qkv{zc?B=&+ zHYP(5$D?+IByN#10BU>rk-JxRPw=Ylb8u_xFOL%6l=)lELoQ0s9104eW}(XR871cH z`Yo=Lu9Hm0U3vuq0?PSCKkzJamkL&z{LLn4Ejq}aufX_V#Pk|+E1@Chnu$;?ocn$$ z@&GJyc&zmf;>Ng2H62a<4|A#A0Dqca0~5DV2e=b<^DBqM7g`1>(m-k@SpgGh>1H6m zX&*QHkJTi%$8#jXD=h+I7IpNf0lXXk-0Ra_yh%k|&q2K|LUFbCiRL~qdb|&K6Ym9` z6MK|VHX6klrpW0P8Qd%<{1s*m|*#XU7LE*mskunjDqCZRGPC+Y^8Cf3}- zQh?;Ct^Wm;jrLXgUNrs6NhS4EdH>1)MwE d!1q_9>qIcNaaitfS;XmDvfT#eh{yl{006{SDp~*l literal 0 HcmV?d00001 diff --git a/kotpass/src/test/resources/ver4_argon2.kdbx b/kotpass/src/test/resources/ver4_argon2.kdbx new file mode 100644 index 0000000000000000000000000000000000000000..195b183daf7a09ae81ab0beb5d132152fbbff9d3 GIT binary patch literal 1245 zcmV<31S0zb*`k_f`%AR|00aO65C8xGF~RcYzi~rQzE}kzYW!ON0|Wp70096100bZa z005LIMcJ<{8}ph7=>v!Qz`h)qpTjMdgXI)y1C{Fv1Ca+10001|^uqm5)=)yYlW~CT zs(Q-{ivR!s00BY;0000aRaHqu5C8xG?_+J>j44D*k@u;j1LFz|LID5(08=0U001jb zloP!D+Klhs#Yb23eWK&kAv`+g$A}l-u3$@g0!Rb_0000`1ONa40RR911pxp608I!0 z000005C8xG000F60000<2mk;80ssI2000001OWg509FJ5000vJ0000C0{{R300961 z1ONa44GIkk#U5gfY(Ly63I%G9y+LCy;7o#Mk;PmRW4_WhMgYGXhd-GJ@Z*z*Y+JH5m8t_Wtxc`XCNoJT{wc zkLknU0aR@CA5!53f9^_f5p0Po0_R?|oUUaA}w;!=n#w^HB-d_j;qsA2$=%MYwLW5$E?&OSGSn+Ega3$%G>NxpJ+^!5eZe zF=>bOXk@5YZvo?!Q&wx2C%JhnzpAm;K%N!s7+=JLiOw&m+kTJ6qs^cNQBE-9NW?S} z(-X^5Rj!CqzU6R=IUOP4zjfeciTYa3tTqqcr_mk!h#3@y{%d@N&MIaJqI+S1y9M9J z>~}K%G5z}DEMJ3}9fMa$>6_D65l)0CS7V!bm<|=X^%6k3Aw%zSaN;Gnjq--XH=8($ zFph?G1ah1jw%K>Y-lA>l%^{VIB}7>%W|=a}%pvl<cLjCHK-;TnwM!N z^M0ogu03_4euj0w6eYErM!^kVrW;<770#+PuBvkVhk6B-cGRe0atgfmRhu6@Y<*sT z74qwfCpi}!;?$R<9N}}{ z?=pZga2$w!LY_P`#QCZ);tLIvG30hZi=YNt(1kz|i#D549=%%hNnCU_BOwya#984YO)C=mI H00000u5u&+ literal 0 HcmV?d00001 diff --git a/kotpass/src/test/resources/ver4_with_binaries.kdbx b/kotpass/src/test/resources/ver4_with_binaries.kdbx new file mode 100644 index 0000000000000000000000000000000000000000..d2944638a34341936a2e5b10ec11a87fa97e686d GIT binary patch literal 3933 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