fix(Desktop): Use correct SqlCipher parameters to create an encrypted database
This commit is contained in:
parent
866da87caf
commit
8b9fc0d3fc
|
@ -167,7 +167,11 @@ kotlin {
|
||||||
implementation(libs.google.zxing.javase)
|
implementation(libs.google.zxing.javase)
|
||||||
implementation(libs.harawata.appdirs)
|
implementation(libs.harawata.appdirs)
|
||||||
implementation(libs.commons.lang3)
|
implementation(libs.commons.lang3)
|
||||||
api(libs.cash.sqldelight.sqlite.driver)
|
val sqldelight = libs.cash.sqldelight.sqlite.driver.get()
|
||||||
|
.let { "${it.module}:${it.versionConstraint.requiredVersion}" }
|
||||||
|
api(sqldelight) {
|
||||||
|
exclude(group = "org.xerial")
|
||||||
|
}
|
||||||
api(libs.kamel.image)
|
api(libs.kamel.image)
|
||||||
api(libs.mayakapps.window.styler)
|
api(libs.mayakapps.window.styler)
|
||||||
api(libs.wunderbox.nativefiledialog)
|
api(libs.wunderbox.nativefiledialog)
|
||||||
|
|
|
@ -9,9 +9,11 @@ import com.artemchep.keyguard.common.io.bind
|
||||||
import com.artemchep.keyguard.common.io.ioEffect
|
import com.artemchep.keyguard.common.io.ioEffect
|
||||||
import com.artemchep.keyguard.common.model.MasterKey
|
import com.artemchep.keyguard.common.model.MasterKey
|
||||||
import com.artemchep.keyguard.data.Database
|
import com.artemchep.keyguard.data.Database
|
||||||
import io.ktor.util.hex
|
import io.ktor.util.*
|
||||||
|
import org.sqlite.mc.SQLiteMCSqlCipherConfig
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.Properties
|
import java.sql.DriverManager
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
class SqlManagerFile(
|
class SqlManagerFile(
|
||||||
private val fileIo: IO<File>,
|
private val fileIo: IO<File>,
|
||||||
|
@ -21,9 +23,40 @@ class SqlManagerFile(
|
||||||
databaseFactory: (SqlDriver) -> Database,
|
databaseFactory: (SqlDriver) -> Database,
|
||||||
vararg callbacks: AfterVersion,
|
vararg callbacks: AfterVersion,
|
||||||
): IO<SqlHelper> = ioEffect {
|
): IO<SqlHelper> = ioEffect {
|
||||||
|
val file = fileIo
|
||||||
|
.bind()
|
||||||
|
try {
|
||||||
|
createSqlHelper(
|
||||||
|
file = file,
|
||||||
|
masterKey = masterKey,
|
||||||
|
databaseFactory = databaseFactory,
|
||||||
|
callbacks = callbacks,
|
||||||
|
)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
println(e.message)
|
||||||
|
if ("is not a database" in e.message.orEmpty()) {
|
||||||
|
file.delete()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try again
|
||||||
|
createSqlHelper(
|
||||||
|
file = file,
|
||||||
|
masterKey = masterKey,
|
||||||
|
databaseFactory = databaseFactory,
|
||||||
|
callbacks = callbacks,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun createSqlHelper(
|
||||||
|
file: File,
|
||||||
|
masterKey: MasterKey,
|
||||||
|
databaseFactory: (SqlDriver) -> Database,
|
||||||
|
vararg callbacks: AfterVersion,
|
||||||
|
): SqlHelper {
|
||||||
val driver: SqlDriver = createSqlDriver(
|
val driver: SqlDriver = createSqlDriver(
|
||||||
file = fileIo
|
file = file,
|
||||||
.bind(),
|
|
||||||
key = masterKey.byteArray,
|
key = masterKey.byteArray,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -48,7 +81,7 @@ class SqlManagerFile(
|
||||||
}
|
}
|
||||||
|
|
||||||
val database = databaseFactory(driver)
|
val database = databaseFactory(driver)
|
||||||
object : SqlHelper {
|
return object : SqlHelper {
|
||||||
override val driver: SqlDriver get() = driver
|
override val driver: SqlDriver get() = driver
|
||||||
|
|
||||||
override val database: Database get() = database
|
override val database: Database get() = database
|
||||||
|
@ -64,8 +97,7 @@ class SqlManagerFile(
|
||||||
driver.execute(
|
driver.execute(
|
||||||
identifier = null,
|
identifier = null,
|
||||||
sql = """
|
sql = """
|
||||||
PRAGMA key = "x'$hex";
|
PRAGMA rekey = "x'$hex'";
|
||||||
PRAGMA rekey = "x'$hex";
|
|
||||||
""".trimIndent(),
|
""".trimIndent(),
|
||||||
parameters = 0,
|
parameters = 0,
|
||||||
binders = null,
|
binders = null,
|
||||||
|
@ -78,13 +110,22 @@ class SqlManagerFile(
|
||||||
file: File,
|
file: File,
|
||||||
key: ByteArray,
|
key: ByteArray,
|
||||||
): SqlDriver {
|
): SqlDriver {
|
||||||
val hex = hex(key)
|
val drivers = DriverManager.getDrivers().toList()
|
||||||
|
require(drivers.size == 1) {
|
||||||
|
"There should be only one SQL driver, currently " +
|
||||||
|
drivers.joinToString { it::class.java.canonicalName } +
|
||||||
|
" are present."
|
||||||
|
}
|
||||||
|
|
||||||
|
val sqlCipherProps = SQLiteMCSqlCipherConfig.getDefault()
|
||||||
|
.withRawUnsaltedKey(key)
|
||||||
|
.build()
|
||||||
|
.toProperties()
|
||||||
val url = "jdbc:sqlite:file:${file.absolutePath}"
|
val url = "jdbc:sqlite:file:${file.absolutePath}"
|
||||||
return JdbcSqliteDriver(
|
return JdbcSqliteDriver(
|
||||||
url = url,
|
url = url,
|
||||||
properties = Properties().apply {
|
properties = Properties().apply {
|
||||||
put("cipher", "sqlcipher")
|
putAll(sqlCipherProps)
|
||||||
put("hexkey", hex)
|
|
||||||
put("foreign_keys", "true")
|
put("foreign_keys", "true")
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue