mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Better KDBX version implementation (new code)
This commit is contained in:
@@ -43,6 +43,7 @@ import com.kunzisoft.keepass.database.element.node.NodeIdUUID
|
||||
import com.kunzisoft.keepass.database.exception.*
|
||||
import com.kunzisoft.keepass.database.file.DatabaseHeaderKDB
|
||||
import com.kunzisoft.keepass.database.file.DatabaseHeaderKDBX
|
||||
import com.kunzisoft.keepass.database.file.DatabaseHeaderKDBX.Companion.FILE_VERSION_32_4
|
||||
import com.kunzisoft.keepass.database.file.input.DatabaseInputKDB
|
||||
import com.kunzisoft.keepass.database.file.input.DatabaseInputKDBX
|
||||
import com.kunzisoft.keepass.database.file.output.DatabaseOutputKDB
|
||||
@@ -225,7 +226,7 @@ class Database {
|
||||
// Default compression not necessary if stored in header
|
||||
mDatabaseKDBX?.let {
|
||||
return it.compressionAlgorithm == CompressionAlgorithm.GZip
|
||||
&& it.kdbxVersion.toKotlinLong() < DatabaseHeaderKDBX.FILE_VERSION_32_4.toKotlinLong()
|
||||
&& it.kdbxVersion.isBefore(FILE_VERSION_32_4)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -187,7 +187,7 @@ class DatabaseKDBX : DatabaseVersioned<UUID, UUID, GroupKDBX, EntryKDBX> {
|
||||
}
|
||||
CompressionAlgorithm.GZip -> {
|
||||
// Only in databaseV3.1, in databaseV4 the header is zipped during the save
|
||||
if (kdbxVersion.toKotlinLong() < FILE_VERSION_32_4.toKotlinLong()) {
|
||||
if (kdbxVersion.isBefore(FILE_VERSION_32_4)) {
|
||||
compressAllBinaries()
|
||||
}
|
||||
}
|
||||
@@ -195,9 +195,7 @@ class DatabaseKDBX : DatabaseVersioned<UUID, UUID, GroupKDBX, EntryKDBX> {
|
||||
}
|
||||
CompressionAlgorithm.GZip -> {
|
||||
// In databaseV4 the header is zipped during the save, so not necessary here
|
||||
if (kdbxVersion.toKotlinLong() >= FILE_VERSION_32_4.toKotlinLong()) {
|
||||
decompressAllBinaries()
|
||||
} else {
|
||||
if (kdbxVersion.isBefore(FILE_VERSION_32_4)) {
|
||||
when (newCompression) {
|
||||
CompressionAlgorithm.None -> {
|
||||
decompressAllBinaries()
|
||||
@@ -205,6 +203,8 @@ class DatabaseKDBX : DatabaseVersioned<UUID, UUID, GroupKDBX, EntryKDBX> {
|
||||
CompressionAlgorithm.GZip -> {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
decompressAllBinaries()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,7 +167,7 @@ class DatabaseHeaderKDBX(private val databaseV4: DatabaseKDBX) : DatabaseHeader(
|
||||
private fun readHeaderField(dis: InputStream): Boolean {
|
||||
val fieldID = dis.read().toByte()
|
||||
|
||||
val fieldSize: Int = if (version.toKotlinLong() < FILE_VERSION_32_4.toKotlinLong()) {
|
||||
val fieldSize: Int = if (version.isBefore(FILE_VERSION_32_4)) {
|
||||
dis.readBytes2ToUShort()
|
||||
} else {
|
||||
dis.readBytes4ToUInt().toKotlinInt()
|
||||
@@ -194,20 +194,20 @@ class DatabaseHeaderKDBX(private val databaseV4: DatabaseKDBX) : DatabaseHeader(
|
||||
|
||||
PwDbHeaderV4Fields.MasterSeed -> masterSeed = fieldData
|
||||
|
||||
PwDbHeaderV4Fields.TransformSeed -> if (version.toKotlinLong() < FILE_VERSION_32_4.toKotlinLong())
|
||||
PwDbHeaderV4Fields.TransformSeed -> if (version.isBefore(FILE_VERSION_32_4))
|
||||
transformSeed = fieldData
|
||||
|
||||
PwDbHeaderV4Fields.TransformRounds -> if (version.toKotlinLong() < FILE_VERSION_32_4.toKotlinLong())
|
||||
PwDbHeaderV4Fields.TransformRounds -> if (version.isBefore(FILE_VERSION_32_4))
|
||||
setTransformRound(fieldData)
|
||||
|
||||
PwDbHeaderV4Fields.EncryptionIV -> encryptionIV = fieldData
|
||||
|
||||
PwDbHeaderV4Fields.InnerRandomstreamKey -> if (version.toKotlinLong() < FILE_VERSION_32_4.toKotlinLong())
|
||||
PwDbHeaderV4Fields.InnerRandomstreamKey -> if (version.isBefore(FILE_VERSION_32_4))
|
||||
innerRandomStreamKey = fieldData
|
||||
|
||||
PwDbHeaderV4Fields.StreamStartBytes -> streamStartBytes = fieldData
|
||||
|
||||
PwDbHeaderV4Fields.InnerRandomStreamID -> if (version.toKotlinLong() < FILE_VERSION_32_4.toKotlinLong())
|
||||
PwDbHeaderV4Fields.InnerRandomStreamID -> if (version.isBefore(FILE_VERSION_32_4))
|
||||
setRandomStreamID(fieldData)
|
||||
|
||||
PwDbHeaderV4Fields.KdfParameters -> databaseV4.kdfParameters = KdfParameters.deserialize(fieldData)
|
||||
|
||||
@@ -42,6 +42,7 @@ import com.kunzisoft.keepass.database.element.node.NodeKDBXInterface
|
||||
import com.kunzisoft.keepass.database.element.security.ProtectedString
|
||||
import com.kunzisoft.keepass.database.exception.*
|
||||
import com.kunzisoft.keepass.database.file.DatabaseHeaderKDBX
|
||||
import com.kunzisoft.keepass.database.file.DatabaseHeaderKDBX.Companion.FILE_VERSION_32_4
|
||||
import com.kunzisoft.keepass.database.file.DatabaseKDBXXML
|
||||
import com.kunzisoft.keepass.database.file.DateKDBXUtil
|
||||
import com.kunzisoft.keepass.stream.HashedBlockInputStream
|
||||
@@ -158,7 +159,7 @@ class DatabaseInputKDBX(cacheDirectory: File,
|
||||
}
|
||||
|
||||
val plainInputStream: InputStream
|
||||
if (mDatabase.kdbxVersion.toKotlinLong() < DatabaseHeaderKDBX.FILE_VERSION_32_4.toKotlinLong()) {
|
||||
if (mDatabase.kdbxVersion.isBefore(FILE_VERSION_32_4)) {
|
||||
|
||||
val dataDecrypted = CipherInputStream(databaseInputStream, cipher)
|
||||
val storedStartBytes: ByteArray?
|
||||
@@ -207,7 +208,7 @@ class DatabaseInputKDBX(cacheDirectory: File,
|
||||
else -> plainInputStream
|
||||
}
|
||||
|
||||
if (mDatabase.kdbxVersion.toKotlinLong() >= DatabaseHeaderKDBX.FILE_VERSION_32_4.toKotlinLong()) {
|
||||
if (!mDatabase.kdbxVersion.isBefore(FILE_VERSION_32_4)) {
|
||||
readInnerHeader(inputStreamXml, header)
|
||||
}
|
||||
|
||||
@@ -842,7 +843,13 @@ class DatabaseInputKDBX(cacheDirectory: File,
|
||||
val sDate = readString(xpp)
|
||||
var utcDate: Date? = null
|
||||
|
||||
if (mDatabase.kdbxVersion.toKotlinLong() >= DatabaseHeaderKDBX.FILE_VERSION_32_4.toKotlinLong()) {
|
||||
if (mDatabase.kdbxVersion.isBefore(FILE_VERSION_32_4)) {
|
||||
try {
|
||||
utcDate = DatabaseKDBXXML.DateFormatter.parse(sDate)
|
||||
} catch (e: ParseException) {
|
||||
// Catch with null test below
|
||||
}
|
||||
} else {
|
||||
var buf = Base64.decode(sDate, BASE_64_FLAG)
|
||||
if (buf.size != 8) {
|
||||
val buf8 = ByteArray(8)
|
||||
@@ -852,14 +859,6 @@ class DatabaseInputKDBX(cacheDirectory: File,
|
||||
|
||||
val seconds = bytes64ToLong(buf)
|
||||
utcDate = DateKDBXUtil.convertKDBX4Time(seconds)
|
||||
|
||||
} else {
|
||||
|
||||
try {
|
||||
utcDate = DatabaseKDBXXML.DateFormatter.parse(sDate)
|
||||
} catch (e: ParseException) {
|
||||
// Catch with null test below
|
||||
}
|
||||
}
|
||||
|
||||
return utcDate ?: Date(0L)
|
||||
|
||||
@@ -27,6 +27,7 @@ import com.kunzisoft.keepass.database.element.database.DatabaseKDBX
|
||||
import com.kunzisoft.keepass.database.exception.DatabaseOutputException
|
||||
import com.kunzisoft.keepass.database.file.DatabaseHeader
|
||||
import com.kunzisoft.keepass.database.file.DatabaseHeaderKDBX
|
||||
import com.kunzisoft.keepass.database.file.DatabaseHeaderKDBX.Companion.FILE_VERSION_32_4
|
||||
import com.kunzisoft.keepass.stream.MacOutputStream
|
||||
import com.kunzisoft.keepass.utils.*
|
||||
import java.io.ByteArrayOutputStream
|
||||
@@ -75,7 +76,7 @@ constructor(private val databaseKDBX: DatabaseKDBX,
|
||||
writeHeaderField(DatabaseHeaderKDBX.PwDbHeaderV4Fields.CompressionFlags, uIntTo4Bytes(DatabaseHeaderKDBX.getFlagFromCompression(databaseKDBX.compressionAlgorithm)))
|
||||
writeHeaderField(DatabaseHeaderKDBX.PwDbHeaderV4Fields.MasterSeed, header.masterSeed)
|
||||
|
||||
if (header.version.toKotlinLong() < DatabaseHeaderKDBX.FILE_VERSION_32_4.toKotlinLong()) {
|
||||
if (header.version.isBefore(FILE_VERSION_32_4)) {
|
||||
writeHeaderField(DatabaseHeaderKDBX.PwDbHeaderV4Fields.TransformSeed, header.transformSeed)
|
||||
writeHeaderField(DatabaseHeaderKDBX.PwDbHeaderV4Fields.TransformRounds, longTo8Bytes(databaseKDBX.numberKeyEncryptionRounds))
|
||||
} else {
|
||||
@@ -86,7 +87,7 @@ constructor(private val databaseKDBX: DatabaseKDBX,
|
||||
writeHeaderField(DatabaseHeaderKDBX.PwDbHeaderV4Fields.EncryptionIV, header.encryptionIV)
|
||||
}
|
||||
|
||||
if (header.version.toKotlinLong() < DatabaseHeaderKDBX.FILE_VERSION_32_4.toKotlinLong()) {
|
||||
if (header.version.isBefore(FILE_VERSION_32_4)) {
|
||||
writeHeaderField(DatabaseHeaderKDBX.PwDbHeaderV4Fields.InnerRandomstreamKey, header.innerRandomStreamKey)
|
||||
writeHeaderField(DatabaseHeaderKDBX.PwDbHeaderV4Fields.StreamStartBytes, header.streamStartBytes)
|
||||
writeHeaderField(DatabaseHeaderKDBX.PwDbHeaderV4Fields.InnerRandomStreamID, uIntTo4Bytes(header.innerRandomStream!!.id))
|
||||
@@ -120,7 +121,7 @@ constructor(private val databaseKDBX: DatabaseKDBX,
|
||||
|
||||
@Throws(IOException::class)
|
||||
private fun writeHeaderFieldSize(size: Int) {
|
||||
if (header.version.toKotlinLong() < DatabaseHeaderKDBX.FILE_VERSION_32_4.toKotlinLong()) {
|
||||
if (header.version.isBefore(FILE_VERSION_32_4)) {
|
||||
mos.write2BytesUShort(size)
|
||||
} else {
|
||||
mos.write4BytesUInt(UnsignedInt(size))
|
||||
|
||||
@@ -41,6 +41,7 @@ import com.kunzisoft.keepass.database.element.security.ProtectedString
|
||||
import com.kunzisoft.keepass.database.exception.DatabaseOutputException
|
||||
import com.kunzisoft.keepass.database.exception.UnknownKDF
|
||||
import com.kunzisoft.keepass.database.file.DatabaseHeaderKDBX
|
||||
import com.kunzisoft.keepass.database.file.DatabaseHeaderKDBX.Companion.FILE_VERSION_32_4
|
||||
import com.kunzisoft.keepass.database.file.DatabaseKDBXXML
|
||||
import com.kunzisoft.keepass.database.file.DateKDBXUtil
|
||||
import com.kunzisoft.keepass.stream.HashedBlockOutputStream
|
||||
@@ -82,7 +83,7 @@ class DatabaseOutputKDBX(private val mDatabaseKDBX: DatabaseKDBX,
|
||||
|
||||
header = outputHeader(mOutputStream)
|
||||
|
||||
val osPlain: OutputStream = if (header!!.version.toKotlinLong() < DatabaseHeaderKDBX.FILE_VERSION_32_4.toKotlinLong()) {
|
||||
val osPlain: OutputStream = if (header!!.version.isBefore(FILE_VERSION_32_4)) {
|
||||
val cos = attachStreamEncryptor(header!!, mOutputStream)
|
||||
cos.write(header!!.streamStartBytes)
|
||||
|
||||
@@ -101,7 +102,7 @@ class DatabaseOutputKDBX(private val mDatabaseKDBX: DatabaseKDBX,
|
||||
else -> osPlain
|
||||
}
|
||||
|
||||
if (header!!.version.toKotlinLong() >= DatabaseHeaderKDBX.FILE_VERSION_32_4.toKotlinLong()) {
|
||||
if (!header!!.version.isBefore(FILE_VERSION_32_4)) {
|
||||
outputInnerHeader(mDatabaseKDBX, header!!, xmlOutputStream)
|
||||
}
|
||||
|
||||
@@ -266,7 +267,7 @@ class DatabaseOutputKDBX(private val mDatabaseKDBX: DatabaseKDBX,
|
||||
writeUuid(DatabaseKDBXXML.ElemLastTopVisibleGroup, mDatabaseKDBX.lastTopVisibleGroupUUID)
|
||||
|
||||
// Seem to work properly if always in meta
|
||||
if (header!!.version.toKotlinLong() < DatabaseHeaderKDBX.FILE_VERSION_32_4.toKotlinLong())
|
||||
if (header!!.version.isBefore(FILE_VERSION_32_4))
|
||||
writeMetaBinaries()
|
||||
|
||||
writeCustomData(mDatabaseKDBX.customData)
|
||||
@@ -308,7 +309,7 @@ class DatabaseOutputKDBX(private val mDatabaseKDBX: DatabaseKDBX,
|
||||
Log.e(TAG, "Unable to retrieve header", unknownKDF)
|
||||
}
|
||||
|
||||
if (header.version.toKotlinLong() < DatabaseHeaderKDBX.FILE_VERSION_32_4.toKotlinLong()) {
|
||||
if (header.version.isBefore(FILE_VERSION_32_4)) {
|
||||
header.innerRandomStream = CrsAlgorithm.Salsa20
|
||||
header.innerRandomStreamKey = ByteArray(32)
|
||||
} else {
|
||||
@@ -323,7 +324,7 @@ class DatabaseOutputKDBX(private val mDatabaseKDBX: DatabaseKDBX,
|
||||
throw DatabaseOutputException(e)
|
||||
}
|
||||
|
||||
if (header.version.toKotlinLong() < DatabaseHeaderKDBX.FILE_VERSION_32_4.toKotlinLong()) {
|
||||
if (header.version.isBefore(FILE_VERSION_32_4)) {
|
||||
random.nextBytes(header.streamStartBytes)
|
||||
}
|
||||
|
||||
@@ -422,7 +423,7 @@ class DatabaseOutputKDBX(private val mDatabaseKDBX: DatabaseKDBX,
|
||||
|
||||
@Throws(IllegalArgumentException::class, IllegalStateException::class, IOException::class)
|
||||
private fun writeObject(name: String, value: Date) {
|
||||
if (header!!.version.toKotlinLong() < DatabaseHeaderKDBX.FILE_VERSION_32_4.toKotlinLong()) {
|
||||
if (header!!.version.isBefore(FILE_VERSION_32_4)) {
|
||||
writeObject(name, DatabaseKDBXXML.DateFormatter.format(value))
|
||||
} else {
|
||||
val dt = DateTime(value)
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
*/
|
||||
package com.kunzisoft.keepass.utils
|
||||
|
||||
import com.kunzisoft.keepass.database.file.DatabaseHeaderKDBX
|
||||
|
||||
class UnsignedInt(private var unsignedValue: Int) {
|
||||
|
||||
constructor(unsignedValue: UnsignedInt) : this(unsignedValue.toKotlinInt())
|
||||
@@ -44,6 +46,11 @@ class UnsignedInt(private var unsignedValue: Int) {
|
||||
return (unsignedValue and 0xFF).toByte()
|
||||
}
|
||||
|
||||
|
||||
fun isBefore(value: UnsignedInt): Boolean {
|
||||
return toKotlinLong() < value.toKotlinLong()
|
||||
}
|
||||
|
||||
override fun toString():String {
|
||||
return toKotlinLong().toString()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user