fix: Separate Main credential, remove ContentProvider from Database

This commit is contained in:
J-Jamet 2023-05-14 15:33:39 +02:00
parent 7db0c4f7d3
commit 6742a8893c
25 changed files with 339 additions and 279 deletions

View file

@ -19,9 +19,7 @@
*/
package com.kunzisoft.keepass.database.element
import android.content.ContentResolver
import android.graphics.Color
import android.net.Uri
import android.util.Log
import com.kunzisoft.androidclearchroma.ChromaUtil
import com.kunzisoft.keepass.database.crypto.EncryptionAlgorithm
@ -56,8 +54,6 @@ import com.kunzisoft.keepass.database.search.SearchParameters
import com.kunzisoft.keepass.hardware.HardwareKey
import com.kunzisoft.keepass.tasks.ProgressTaskUpdater
import com.kunzisoft.keepass.utils.*
import com.kunzisoft.keepass.utils.UriHelper.getUriInputStream
import com.kunzisoft.keepass.utils.UriHelper.getUriOutputStream
import java.io.*
import java.util.*
@ -68,9 +64,6 @@ open class Database {
private var mDatabaseKDB: DatabaseKDB? = null
private var mDatabaseKDBX: DatabaseKDBX? = null
var fileUri: Uri? = null
private set
private var mSearchHelper: SearchHelper = SearchHelper()
var isReadOnly = false
@ -548,22 +541,19 @@ open class Database {
}
fun createData(
databaseUri: Uri,
databaseName: String,
rootName: String,
templateGroupName: String?
) {
setDatabaseKDBX(DatabaseKDBX(databaseName, rootName, templateGroupName))
this.fileUri = databaseUri
// Set Database state
this.dataModifiedSinceLastLoading = false
}
@Throws(DatabaseInputException::class)
fun loadData(
contentResolver: ContentResolver,
databaseUri: Uri,
mainCredential: MainCredential,
databaseStream: InputStream,
masterCredential: MasterCredential,
challengeResponseRetriever: (HardwareKey, ByteArray?) -> ByteArray,
readOnly: Boolean,
cacheDirectory: File,
@ -571,16 +561,12 @@ open class Database {
fixDuplicateUUID: Boolean,
progressTaskUpdater: ProgressTaskUpdater?
) {
// Save database URI
this.fileUri = databaseUri
// Check if the file is writable
this.isReadOnly = readOnly
try {
// Read database stream for the first time
readDatabaseStream(contentResolver, databaseUri,
readDatabaseStream(databaseStream,
{ databaseInputStream ->
val databaseKDB = DatabaseKDB().apply {
binaryCache.cacheDirectory = cacheDirectory
@ -591,9 +577,8 @@ open class Database {
progressTaskUpdater
) {
databaseKDB.deriveMasterKey(
contentResolver,
mainCredential
)
masterCredential
)
}
setDatabaseKDB(databaseKDB)
},
@ -607,8 +592,7 @@ open class Database {
openDatabase(databaseInputStream,
progressTaskUpdater) {
databaseKDBX.deriveMasterKey(
contentResolver,
mainCredential,
masterCredential,
challengeResponseRetriever
)
}
@ -633,9 +617,8 @@ open class Database {
@Throws(DatabaseInputException::class)
fun mergeData(
contentResolver: ContentResolver,
databaseToMergeUri: Uri?,
databaseToMergeMainCredential: MainCredential?,
databaseToMergeStream: InputStream,
databaseToMergeMasterCredential: MasterCredential?,
databaseToMergeChallengeResponseRetriever: (HardwareKey, ByteArray?) -> ByteArray,
isRAMSufficient: (memoryWanted: Long) -> Boolean,
progressTaskUpdater: ProgressTaskUpdater?
@ -647,71 +630,58 @@ open class Database {
// New database instance to get new changes
val databaseToMerge = Database()
databaseToMerge.fileUri = databaseToMergeUri ?: this.fileUri
try {
val databaseUri = databaseToMerge.fileUri
if (databaseUri != null) {
readDatabaseStream(contentResolver, databaseUri,
{ databaseInputStream ->
val databaseToMergeKDB = DatabaseKDB()
DatabaseInputKDB(databaseToMergeKDB)
.openDatabase(databaseInputStream, progressTaskUpdater) {
if (databaseToMergeMainCredential != null) {
databaseToMergeKDB.deriveMasterKey(
contentResolver,
databaseToMergeMainCredential
)
} else {
this@Database.mDatabaseKDB?.let { thisDatabaseKDB ->
databaseToMergeKDB.copyMasterKeyFrom(thisDatabaseKDB)
}
}
}
databaseToMerge.setDatabaseKDB(databaseToMergeKDB)
},
{ databaseInputStream ->
val databaseToMergeKDBX = DatabaseKDBX()
DatabaseInputKDBX(databaseToMergeKDBX).apply {
setMethodToCheckIfRAMIsSufficient(isRAMSufficient)
openDatabase(databaseInputStream, progressTaskUpdater) {
if (databaseToMergeMainCredential != null) {
databaseToMergeKDBX.deriveMasterKey(
contentResolver,
databaseToMergeMainCredential,
databaseToMergeChallengeResponseRetriever
)
} else {
this@Database.mDatabaseKDBX?.let { thisDatabaseKDBX ->
databaseToMergeKDBX.copyMasterKeyFrom(thisDatabaseKDBX)
}
readDatabaseStream(databaseToMergeStream,
{ databaseInputStream ->
val databaseToMergeKDB = DatabaseKDB()
DatabaseInputKDB(databaseToMergeKDB)
.openDatabase(databaseInputStream, progressTaskUpdater) {
if (databaseToMergeMasterCredential != null) {
databaseToMergeKDB.deriveMasterKey(
databaseToMergeMasterCredential
)
} else {
this@Database.mDatabaseKDB?.let { thisDatabaseKDB ->
databaseToMergeKDB.copyMasterKeyFrom(thisDatabaseKDB)
}
}
}
databaseToMerge.setDatabaseKDBX(databaseToMergeKDBX)
}
)
loaded = true
mDatabaseKDBX?.let { currentDatabaseKDBX ->
val databaseMerger = DatabaseKDBXMerger(currentDatabaseKDBX).apply {
this.isRAMSufficient = isRAMSufficient
}
databaseToMerge.mDatabaseKDB?.let { databaseKDBToMerge ->
databaseMerger.merge(databaseKDBToMerge)
if (databaseToMergeUri != null) {
this.dataModifiedSinceLastLoading = true
}
}
databaseToMerge.mDatabaseKDBX?.let { databaseKDBXToMerge ->
databaseMerger.merge(databaseKDBXToMerge)
if (databaseToMergeUri != null) {
this.dataModifiedSinceLastLoading = true
databaseToMerge.setDatabaseKDB(databaseToMergeKDB)
},
{ databaseInputStream ->
val databaseToMergeKDBX = DatabaseKDBX()
DatabaseInputKDBX(databaseToMergeKDBX).apply {
setMethodToCheckIfRAMIsSufficient(isRAMSufficient)
openDatabase(databaseInputStream, progressTaskUpdater) {
if (databaseToMergeMasterCredential != null) {
databaseToMergeKDBX.deriveMasterKey(
databaseToMergeMasterCredential,
databaseToMergeChallengeResponseRetriever
)
} else {
this@Database.mDatabaseKDBX?.let { thisDatabaseKDBX ->
databaseToMergeKDBX.copyMasterKeyFrom(thisDatabaseKDBX)
}
}
}
}
databaseToMerge.setDatabaseKDBX(databaseToMergeKDBX)
}
)
loaded = true
mDatabaseKDBX?.let { currentDatabaseKDBX ->
val databaseMerger = DatabaseKDBXMerger(currentDatabaseKDBX).apply {
this.isRAMSufficient = isRAMSufficient
}
databaseToMerge.mDatabaseKDB?.let { databaseKDBToMerge ->
databaseMerger.merge(databaseKDBToMerge)
this.dataModifiedSinceLastLoading = true
}
databaseToMerge.mDatabaseKDBX?.let { databaseKDBXToMerge ->
databaseMerger.merge(databaseKDBXToMerge)
this.dataModifiedSinceLastLoading = true
}
} else {
throw UnknownDatabaseLocationException()
}
} catch (e: Exception) {
Log.e(TAG, "Unable to merge the database")
@ -725,49 +695,43 @@ open class Database {
@Throws(DatabaseInputException::class)
fun reloadData(
contentResolver: ContentResolver,
databaseStream: InputStream,
isRAMSufficient: (memoryWanted: Long) -> Boolean,
progressTaskUpdater: ProgressTaskUpdater?
) {
// Retrieve the stream from the old database URI
try {
val oldDatabaseUri = fileUri
if (oldDatabaseUri != null) {
readDatabaseStream(contentResolver, oldDatabaseUri,
{ databaseInputStream ->
val databaseKDB = DatabaseKDB()
mDatabaseKDB?.let {
databaseKDB.binaryCache = it.binaryCache
}
DatabaseInputKDB(databaseKDB)
.openDatabase(databaseInputStream, progressTaskUpdater) {
this@Database.mDatabaseKDB?.let { thisDatabaseKDB ->
databaseKDB.copyMasterKeyFrom(thisDatabaseKDB)
}
}
setDatabaseKDB(databaseKDB)
},
{ databaseInputStream ->
val databaseKDBX = DatabaseKDBX()
mDatabaseKDBX?.let {
databaseKDBX.binaryCache = it.binaryCache
}
DatabaseInputKDBX(databaseKDBX).apply {
setMethodToCheckIfRAMIsSufficient(isRAMSufficient)
openDatabase(databaseInputStream, progressTaskUpdater) {
this@Database.mDatabaseKDBX?.let { thisDatabaseKDBX ->
databaseKDBX.copyMasterKeyFrom(thisDatabaseKDBX)
}
}
}
setDatabaseKDBX(databaseKDBX)
// Retrieve the stream from the old database
readDatabaseStream(databaseStream,
{ databaseInputStream ->
val databaseKDB = DatabaseKDB()
mDatabaseKDB?.let {
databaseKDB.binaryCache = it.binaryCache
}
)
loaded = true
} else {
throw UnknownDatabaseLocationException()
}
DatabaseInputKDB(databaseKDB)
.openDatabase(databaseInputStream, progressTaskUpdater) {
this@Database.mDatabaseKDB?.let { thisDatabaseKDB ->
databaseKDB.copyMasterKeyFrom(thisDatabaseKDB)
}
}
setDatabaseKDB(databaseKDB)
},
{ databaseInputStream ->
val databaseKDBX = DatabaseKDBX()
mDatabaseKDBX?.let {
databaseKDBX.binaryCache = it.binaryCache
}
DatabaseInputKDBX(databaseKDBX).apply {
setMethodToCheckIfRAMIsSufficient(isRAMSufficient)
openDatabase(databaseInputStream, progressTaskUpdater) {
this@Database.mDatabaseKDBX?.let { thisDatabaseKDBX ->
databaseKDBX.copyMasterKeyFrom(thisDatabaseKDBX)
}
}
}
setDatabaseKDBX(databaseKDBX)
}
)
loaded = true
} catch (e: Exception) {
Log.e(TAG, "Unable to reload the database")
if (e is DatabaseException)
@ -780,16 +744,12 @@ open class Database {
@Throws(Exception::class)
private fun readDatabaseStream(
contentResolver: ContentResolver,
databaseUri: Uri,
databaseStream: InputStream,
openDatabaseKDB: (InputStream) -> Unit,
openDatabaseKDBX: (InputStream) -> Unit
) {
try {
// Load Data, pass Uris as InputStreams
val databaseStream = contentResolver.getUriInputStream(databaseUri)
?: throw UnknownDatabaseLocationException()
// Load Data by InputStream
BufferedInputStream(databaseStream).use { databaseInputStream ->
// We'll end up reading 8 bytes to identify the header. Might as well use two extra.
@ -822,63 +782,54 @@ open class Database {
@Throws(DatabaseOutputException::class)
fun saveData(
contentResolver: ContentResolver,
cacheDir: File,
databaseCopyUri: Uri?,
mainCredential: MainCredential?,
cacheFile: File,
databaseOutputStream: OutputStream?,
isNewLocation: Boolean,
masterCredential: MasterCredential?,
challengeResponseRetriever: (HardwareKey, ByteArray?) -> ByteArray
) {
val saveUri = databaseCopyUri ?: this.fileUri
// Build temp database file to avoid file corruption if error
val cacheFile = File(cacheDir, saveUri.hashCode().toString())
try {
if (saveUri != null) {
// Save in a temp memory to avoid exception
cacheFile.outputStream().use { outputStream ->
mDatabaseKDB?.let { databaseKDB ->
DatabaseOutputKDB(databaseKDB).apply {
writeDatabase(outputStream) {
if (mainCredential != null) {
databaseKDB.deriveMasterKey(
contentResolver,
mainCredential
)
} else {
// No master key change
}
}
}
}
?: mDatabaseKDBX?.let { databaseKDBX ->
DatabaseOutputKDBX(databaseKDBX).apply {
writeDatabase(outputStream) {
if (mainCredential != null) {
// Build new master key from MainCredential
databaseKDBX.deriveMasterKey(
contentResolver,
mainCredential,
challengeResponseRetriever
)
} else {
// Reuse composite key parts
databaseKDBX.deriveCompositeKey(
challengeResponseRetriever
)
}
// Save in a temp memory to avoid exception
cacheFile.outputStream().use { outputStream ->
mDatabaseKDB?.let { databaseKDB ->
DatabaseOutputKDB(databaseKDB).apply {
writeDatabase(outputStream) {
if (masterCredential != null) {
databaseKDB.deriveMasterKey(
masterCredential
)
} else {
// No master key change
}
}
}
}
// Copy from the cache to the final stream
contentResolver.getUriOutputStream(saveUri)?.use { outputStream ->
cacheFile.inputStream().use { inputStream ->
inputStream.readAllBytes { buffer ->
outputStream.write(buffer)
?: mDatabaseKDBX?.let { databaseKDBX ->
DatabaseOutputKDBX(databaseKDBX).apply {
writeDatabase(outputStream) {
if (masterCredential != null) {
// Build new master key from MainCredential
databaseKDBX.deriveMasterKey(
masterCredential,
challengeResponseRetriever
)
} else {
// Reuse composite key parts
databaseKDBX.deriveCompositeKey(
challengeResponseRetriever
)
}
}
}
}
} else {
throw UnknownDatabaseLocationException()
}
// Copy from the cache to the final stream
databaseOutputStream?.use { outputStream ->
cacheFile.inputStream().use { inputStream ->
inputStream.readAllBytes { buffer ->
outputStream.write(buffer)
}
}
}
} catch (e: Exception) {
Log.e(TAG, "Unable to save database", e)
@ -892,7 +843,7 @@ open class Database {
} catch (e: Exception) {
Log.e(TAG, "Cache file $cacheFile cannot be deleted", e)
}
if (databaseCopyUri == null) {
if (isNewLocation) {
this.dataModifiedSinceLastLoading = false
}
}
@ -1010,11 +961,10 @@ open class Database {
}
}
fun clearAndClose(filesDirectory: File? = null) {
open fun clearAndClose(filesDirectory: File? = null) {
clearIndexesAndBinaries(filesDirectory)
this.mDatabaseKDB = null
this.mDatabaseKDBX = null
this.fileUri = null
this.loaded = false
}
@ -1029,11 +979,11 @@ open class Database {
}
}
fun validatePasswordEncoding(mainCredential: MainCredential): Boolean {
val password = mainCredential.password
val containsKeyFile = mainCredential.keyFileUri != null
return mDatabaseKDB?.validatePasswordEncoding(password, containsKeyFile)
?: mDatabaseKDBX?.validatePasswordEncoding(password, containsKeyFile)
fun isValidCredential(masterCredential: MasterCredential): Boolean {
val password = masterCredential.password
val containsKeyFile = masterCredential.keyFileData != null
return mDatabaseKDB?.isValidCredential(password, containsKeyFile)
?: mDatabaseKDBX?.isValidCredential(password, containsKeyFile)
?: false
}

View file

@ -18,8 +18,6 @@
*/
package com.kunzisoft.keepass.database.element
import android.content.ContentResolver
import android.net.Uri
import android.os.Parcel
import android.os.Parcelable
import android.util.Base64
@ -29,8 +27,9 @@ import com.kunzisoft.keepass.database.element.database.DatabaseKDBX
import com.kunzisoft.keepass.hardware.HardwareKey
import com.kunzisoft.keepass.utils.StringUtil.removeSpaceChars
import com.kunzisoft.keepass.utils.StringUtil.toHexString
import com.kunzisoft.keepass.utils.UriHelper.getUriInputStream
import com.kunzisoft.keepass.utils.readByteArrayCompat
import com.kunzisoft.keepass.utils.readEnum
import com.kunzisoft.keepass.utils.writeByteArrayCompat
import com.kunzisoft.keepass.utils.writeEnum
import org.apache.commons.codec.binary.Hex
import org.w3c.dom.Node
@ -43,19 +42,19 @@ import javax.xml.XMLConstants
import javax.xml.parsers.DocumentBuilderFactory
import javax.xml.parsers.ParserConfigurationException
data class MainCredential(var password: String? = null,
var keyFileUri: Uri? = null,
var hardwareKey: HardwareKey? = null): Parcelable {
data class MasterCredential(var password: String? = null,
var keyFileData: ByteArray? = null,
var hardwareKey: HardwareKey? = null): Parcelable {
constructor(parcel: Parcel) : this() {
password = parcel.readString()
keyFileUri = parcel.readParcelable(Uri::class.java.classLoader)
keyFileData = parcel.readByteArrayCompat()
hardwareKey = parcel.readEnum<HardwareKey>()
}
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeString(password)
parcel.writeParcelable(keyFileUri, flags)
parcel.writeByteArrayCompat(keyFileData)
parcel.writeEnum(hardwareKey)
}
@ -67,10 +66,10 @@ data class MainCredential(var password: String? = null,
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as MainCredential
other as MasterCredential
if (password != other.password) return false
if (keyFileUri != other.keyFileUri) return false
if (!keyFileData.contentEquals(other.keyFileData)) return false
if (hardwareKey != other.hardwareKey) return false
return true
@ -78,21 +77,21 @@ data class MainCredential(var password: String? = null,
override fun hashCode(): Int {
var result = password?.hashCode() ?: 0
result = 31 * result + (keyFileUri?.hashCode() ?: 0)
result = 31 * result + (keyFileData?.hashCode() ?: 0)
result = 31 * result + (hardwareKey?.hashCode() ?: 0)
return result
}
companion object CREATOR : Parcelable.Creator<MainCredential> {
override fun createFromParcel(parcel: Parcel): MainCredential {
return MainCredential(parcel)
companion object CREATOR : Parcelable.Creator<MasterCredential> {
override fun createFromParcel(parcel: Parcel): MasterCredential {
return MasterCredential(parcel)
}
override fun newArray(size: Int): Array<MainCredential?> {
override fun newArray(size: Int): Array<MasterCredential?> {
return arrayOfNulls(size)
}
private val TAG = MainCredential::class.java.simpleName
private val TAG = MasterCredential::class.java.simpleName
@Throws(IOException::class)
fun retrievePasswordKey(key: String,
@ -107,17 +106,14 @@ data class MainCredential(var password: String? = null,
}
@Throws(IOException::class)
fun retrieveFileKey(contentResolver: ContentResolver,
keyFileUri: Uri?,
allowXML: Boolean): ByteArray {
if (keyFileUri == null)
throw IOException("Keyfile URI is null")
val keyData = getKeyFileData(contentResolver, keyFileUri)
?: throw IOException("No data retrieved")
fun retrieveKeyFileDecodedKey(
keyFileData: ByteArray,
allowXML: Boolean
): ByteArray {
try {
// Check XML key file
val xmlKeyByteArray = if (allowXML)
loadXmlKeyFile(ByteArrayInputStream(keyData))
loadXmlKeyFile(ByteArrayInputStream(keyFileData))
else
null
if (xmlKeyByteArray != null) {
@ -125,16 +121,16 @@ data class MainCredential(var password: String? = null,
}
// Check 32 bytes key file
when (keyData.size) {
32 -> return keyData
when (keyFileData.size) {
32 -> return keyFileData
64 -> try {
return Hex.decodeHex(String(keyData).toCharArray())
return Hex.decodeHex(String(keyFileData).toCharArray())
} catch (ignoredException: Exception) {
// Key is not base 64, treat it as binary data
}
}
// Hash file as binary data
return HashManager.hashSha256(keyData)
return HashManager.hashSha256(keyFileData)
} catch (e: Exception) {
throw IOException("Unable to load the keyfile.", e)
}
@ -145,15 +141,6 @@ data class MainCredential(var password: String? = null,
return HashManager.hashSha256(keyData)
}
@Throws(Exception::class)
private fun getKeyFileData(contentResolver: ContentResolver,
keyFileUri: Uri): ByteArray? {
contentResolver.getUriInputStream(keyFileUri)?.use { keyFileInputStream ->
return keyFileInputStream.readBytes()
}
return null
}
private fun loadXmlKeyFile(keyInputStream: InputStream): ByteArray? {
try {
val documentBuilderFactory = DocumentBuilderFactory.newInstance()

View file

@ -19,13 +19,12 @@
package com.kunzisoft.keepass.database.element.database
import android.content.ContentResolver
import com.kunzisoft.encrypt.HashManager
import com.kunzisoft.encrypt.aes.AESTransformer
import com.kunzisoft.keepass.database.crypto.EncryptionAlgorithm
import com.kunzisoft.keepass.database.crypto.kdf.KdfEngine
import com.kunzisoft.keepass.database.crypto.kdf.KdfFactory
import com.kunzisoft.keepass.database.element.MainCredential
import com.kunzisoft.keepass.database.element.MasterCredential
import com.kunzisoft.keepass.database.element.binary.BinaryData
import com.kunzisoft.keepass.database.element.entry.EntryKDB
import com.kunzisoft.keepass.database.element.group.GroupKDB
@ -129,25 +128,23 @@ class DatabaseKDB : DatabaseVersioned<Int, UUID, GroupKDB, EntryKDB>() {
}
fun deriveMasterKey(
contentResolver: ContentResolver,
mainCredential: MainCredential
masterCredential: MasterCredential
) {
// Exception when no password
if (mainCredential.hardwareKey != null)
if (masterCredential.hardwareKey != null)
throw HardwareKeyDatabaseException()
if (mainCredential.password == null && mainCredential.keyFileUri == null)
if (masterCredential.password == null && masterCredential.keyFileData == null)
throw EmptyKeyDatabaseException()
// Retrieve plain data
val password = mainCredential.password
val keyFileUri = mainCredential.keyFileUri
val passwordBytes = if (password != null) MainCredential.retrievePasswordKey(
val password = masterCredential.password
val keyFileData = masterCredential.keyFileData
val passwordBytes = if (password != null) MasterCredential.retrievePasswordKey(
password,
passwordEncoding
) else null
val keyFileBytes = if (keyFileUri != null) MainCredential.retrieveFileKey(
contentResolver,
keyFileUri,
val keyFileBytes = if (keyFileData != null) MasterCredential.retrieveKeyFileDecodedKey(
keyFileData,
false
) else null

View file

@ -19,7 +19,6 @@
*/
package com.kunzisoft.keepass.database.element.database
import android.content.ContentResolver
import android.util.Base64
import android.util.Log
import com.kunzisoft.encrypt.HashManager
@ -226,24 +225,22 @@ class DatabaseKDBX : DatabaseVersioned<UUID, UUID, GroupKDBX, EntryKDBX> {
}
fun deriveMasterKey(
contentResolver: ContentResolver,
mainCredential: MainCredential,
masterCredential: MasterCredential,
challengeResponseRetriever: (HardwareKey, ByteArray?) -> ByteArray,
) {
// Retrieve each plain credential
val password = mainCredential.password
val keyFileUri = mainCredential.keyFileUri
val hardwareKey = mainCredential.hardwareKey
val passwordBytes = if (password != null) MainCredential.retrievePasswordKey(
val password = masterCredential.password
val keyFileData = masterCredential.keyFileData
val hardwareKey = masterCredential.hardwareKey
val passwordBytes = if (password != null) MasterCredential.retrievePasswordKey(
password,
passwordEncoding
) else null
val keyFileBytes = if (keyFileUri != null) MainCredential.retrieveFileKey(
contentResolver,
keyFileUri,
val keyFileBytes = if (keyFileData != null) MasterCredential.retrieveKeyFileDecodedKey(
keyFileData,
true
) else null
val hardwareKeyBytes = if (hardwareKey != null) MainCredential.retrieveHardwareKey(
val hardwareKeyBytes = if (hardwareKey != null) MasterCredential.retrieveHardwareKey(
challengeResponseRetriever.invoke(hardwareKey, transformSeed)
) else null
@ -272,7 +269,7 @@ class DatabaseKDBX : DatabaseVersioned<UUID, UUID, GroupKDBX, EntryKDBX> {
keyFileBytes
)
} else {
val hardwareKeyBytes = MainCredential.retrieveHardwareKey(
val hardwareKeyBytes = MasterCredential.retrieveHardwareKey(
challengeResponseRetriever.invoke(hardwareKey, transformSeed)
)
this.masterKey = composedKeyToMasterKey(
@ -873,10 +870,10 @@ class DatabaseKDBX : DatabaseVersioned<UUID, UUID, GroupKDBX, EntryKDBX> {
}
}
override fun validatePasswordEncoding(password: String?, containsKeyFile: Boolean): Boolean {
override fun isValidCredential(password: String?, containsKeyFile: Boolean): Boolean {
if (password == null)
return true
return super.validatePasswordEncoding(password, containsKeyFile)
return super.isValidCredential(password, containsKeyFile)
}
override fun clearIndexes() {

View file

@ -93,7 +93,7 @@ abstract class DatabaseVersioned<
return null
}
open fun validatePasswordEncoding(password: String?, containsKeyFile: Boolean): Boolean {
open fun isValidCredential(password: String?, containsKeyFile: Boolean): Boolean {
if (password == null && !containsKeyFile)
return false