From 309509a5022f4669d13a21c1890d9d278db1c65a Mon Sep 17 00:00:00 2001 From: Denis Trotsenko Date: Sat, 4 May 2024 11:50:56 +0200 Subject: [PATCH] Add possibility to provide SecureRandom instance as parameter --- .../kotpass/cryptography/EncryptedValue.kt | 7 +++++-- .../keemobile/kotpass/database/KeePassDatabase.kt | 15 ++++++++++----- .../kotpass/database/header/DatabaseHeader.kt | 10 ++++++++-- .../database/header/DatabaseInnerHeader.kt | 12 +++++------- .../keemobile/kotpass/extensions/SecureRandom.kt | 4 ++-- 5 files changed, 30 insertions(+), 18 deletions(-) diff --git a/kotpass/src/main/kotlin/app/keemobile/kotpass/cryptography/EncryptedValue.kt b/kotpass/src/main/kotlin/app/keemobile/kotpass/cryptography/EncryptedValue.kt index cd2f19e..ae34f75 100644 --- a/kotpass/src/main/kotlin/app/keemobile/kotpass/cryptography/EncryptedValue.kt +++ b/kotpass/src/main/kotlin/app/keemobile/kotpass/cryptography/EncryptedValue.kt @@ -82,9 +82,12 @@ class EncryptedValue( fun fromBase64(base64: String) = fromBinary(base64.decodeBase64ToArray()) - fun fromBinary(bytes: ByteArray): EncryptedValue { + fun fromBinary( + bytes: ByteArray, + random: SecureRandom = SecureRandom() + ): EncryptedValue { val salt = ByteArray(bytes.size) - SecureRandom().nextBytes(salt) + random.nextBytes(salt) for (i in bytes.indices) { bytes[i] = bytes[i] xor salt[i] diff --git a/kotpass/src/main/kotlin/app/keemobile/kotpass/database/KeePassDatabase.kt b/kotpass/src/main/kotlin/app/keemobile/kotpass/database/KeePassDatabase.kt index f7a6299..e570c6b 100644 --- a/kotpass/src/main/kotlin/app/keemobile/kotpass/database/KeePassDatabase.kt +++ b/kotpass/src/main/kotlin/app/keemobile/kotpass/database/KeePassDatabase.kt @@ -10,6 +10,7 @@ import app.keemobile.kotpass.models.DatabaseElement import app.keemobile.kotpass.models.Entry import app.keemobile.kotpass.models.Group import app.keemobile.kotpass.models.Meta +import java.security.SecureRandom import java.util.UUID /** @@ -32,14 +33,16 @@ sealed class KeePassDatabase { * @param rootName Required name of the top group. * @param meta Database metadata. * @param credentials Database credentials. + * @param random optional custom random generator. */ fun create( rootName: String, meta: Meta, - credentials: Credentials + credentials: Credentials, + random: SecureRandom = SecureRandom() ) = Ver3x( credentials = credentials, - header = DatabaseHeader.Ver3x.create(), + header = DatabaseHeader.Ver3x.create(random), content = DatabaseContent( meta = meta, group = Group( @@ -67,14 +70,16 @@ sealed class KeePassDatabase { * @param rootName Required name of the top group. * @param meta Database metadata. * @param credentials Database credentials. + * @param random optional custom random generator. */ fun create( rootName: String, meta: Meta, - credentials: Credentials + credentials: Credentials, + random: SecureRandom = SecureRandom() ) = Ver4x( credentials = credentials, - header = DatabaseHeader.Ver4x.create(), + header = DatabaseHeader.Ver4x.create(random), content = DatabaseContent( meta = meta, group = Group( @@ -85,7 +90,7 @@ sealed class KeePassDatabase { ), deletedObjects = listOf() ), - innerHeader = DatabaseInnerHeader.create() + innerHeader = DatabaseInnerHeader.create(random) ) } } diff --git a/kotpass/src/main/kotlin/app/keemobile/kotpass/database/header/DatabaseHeader.kt b/kotpass/src/main/kotlin/app/keemobile/kotpass/database/header/DatabaseHeader.kt index 70770bb..98d2ff6 100644 --- a/kotpass/src/main/kotlin/app/keemobile/kotpass/database/header/DatabaseHeader.kt +++ b/kotpass/src/main/kotlin/app/keemobile/kotpass/database/header/DatabaseHeader.kt @@ -41,7 +41,10 @@ sealed class DatabaseHeader { val streamStartBytes: ByteString ) : DatabaseHeader() { companion object { - fun create() = with(SecureRandom()) { + /** + * Create an instance of [DatabaseHeader] with the default parameters. + */ + fun create(random: SecureRandom = SecureRandom()) = with(random) { Ver3x( signature = Signature.Default, version = FormatVersion(3, 1), @@ -70,7 +73,10 @@ sealed class DatabaseHeader { val publicCustomData: Map ) : DatabaseHeader() { companion object { - fun create() = with(SecureRandom()) { + /** + * Create an instance of [DatabaseHeader] with the default parameters. + */ + fun create(random: SecureRandom = SecureRandom()) = with(random) { Ver4x( signature = Signature.Default, version = FormatVersion(4, 1), diff --git a/kotpass/src/main/kotlin/app/keemobile/kotpass/database/header/DatabaseInnerHeader.kt b/kotpass/src/main/kotlin/app/keemobile/kotpass/database/header/DatabaseInnerHeader.kt index 3f70ac5..8f0abe7 100644 --- a/kotpass/src/main/kotlin/app/keemobile/kotpass/database/header/DatabaseInnerHeader.kt +++ b/kotpass/src/main/kotlin/app/keemobile/kotpass/database/header/DatabaseInnerHeader.kt @@ -47,13 +47,11 @@ data class DatabaseInnerHeader( } companion object { - fun create() = with(SecureRandom()) { - DatabaseInnerHeader( - randomStreamId = CrsAlgorithm.ChaCha20, - randomStreamKey = nextByteString(64), - binaries = linkedMapOf() - ) - } + fun create(random: SecureRandom = SecureRandom()) = DatabaseInnerHeader( + randomStreamId = CrsAlgorithm.ChaCha20, + randomStreamKey = random.nextByteString(64), + binaries = linkedMapOf() + ) internal fun readFrom(source: BufferedSource): DatabaseInnerHeader { val binaries = linkedMapOf() diff --git a/kotpass/src/main/kotlin/app/keemobile/kotpass/extensions/SecureRandom.kt b/kotpass/src/main/kotlin/app/keemobile/kotpass/extensions/SecureRandom.kt index 5729486..802e8b7 100644 --- a/kotpass/src/main/kotlin/app/keemobile/kotpass/extensions/SecureRandom.kt +++ b/kotpass/src/main/kotlin/app/keemobile/kotpass/extensions/SecureRandom.kt @@ -2,9 +2,9 @@ package app.keemobile.kotpass.extensions import okio.ByteString import okio.ByteString.Companion.toByteString -import java.security.SecureRandom +import java.util.Random -internal fun SecureRandom.nextByteString(length: Int): ByteString { +internal fun Random.nextByteString(length: Int): ByteString { return ByteArray(length) .apply { nextBytes(this) } .toByteString()