Simpler method

This commit is contained in:
J-Jamet
2021-03-24 11:29:15 +01:00
parent d28a59a2fe
commit 78f707c07c

View File

@@ -155,7 +155,7 @@ class DatabaseInputKDBX(cacheDirectory: File,
val isPlain: InputStream val isPlain: InputStream
if (mDatabase.kdbxVersion.toKotlinLong() < DatabaseHeaderKDBX.FILE_VERSION_32_4.toKotlinLong()) { if (mDatabase.kdbxVersion.toKotlinLong() < DatabaseHeaderKDBX.FILE_VERSION_32_4.toKotlinLong()) {
val decrypted = attachCipherStream(databaseInputStream, cipher) val decrypted = CipherInputStream(databaseInputStream, cipher)
val dataDecrypted = LittleEndianDataInputStream(decrypted) val dataDecrypted = LittleEndianDataInputStream(decrypted)
val storedStartBytes: ByteArray? val storedStartBytes: ByteArray?
try { try {
@@ -192,17 +192,16 @@ class DatabaseInputKDBX(cacheDirectory: File,
val hmIs = HmacBlockInputStream(isData, true, hmacKey) val hmIs = HmacBlockInputStream(isData, true, hmacKey)
isPlain = attachCipherStream(hmIs, cipher) isPlain = CipherInputStream(hmIs, cipher)
} }
val inputStreamXml: InputStream val inputStreamXml: InputStream = when (mDatabase.compressionAlgorithm) {
inputStreamXml = when (mDatabase.compressionAlgorithm) {
CompressionAlgorithm.GZip -> GZIPInputStream(isPlain) CompressionAlgorithm.GZip -> GZIPInputStream(isPlain)
else -> isPlain else -> isPlain
} }
if (mDatabase.kdbxVersion.toKotlinLong() >= DatabaseHeaderKDBX.FILE_VERSION_32_4.toKotlinLong()) { if (mDatabase.kdbxVersion.toKotlinLong() >= DatabaseHeaderKDBX.FILE_VERSION_32_4.toKotlinLong()) {
loadInnerHeader(inputStreamXml, header) readInnerHeader(inputStreamXml, header)
} }
try { try {
@@ -231,66 +230,57 @@ class DatabaseInputKDBX(cacheDirectory: File,
return mDatabase return mDatabase
} }
private fun attachCipherStream(inputStream: InputStream, cipher: Cipher): InputStream {
return CipherInputStream(inputStream, cipher)
}
@Throws(IOException::class) @Throws(IOException::class)
private fun loadInnerHeader(inputStream: InputStream, header: DatabaseHeaderKDBX) { private fun readInnerHeader(inputStream: InputStream,
val lis = LittleEndianDataInputStream(inputStream) header: DatabaseHeaderKDBX) {
while (true) { val dataInputStream = LittleEndianDataInputStream(inputStream)
if (!readInnerHeader(lis, header)) break
}
}
@Throws(IOException::class) var readStream = true
private fun readInnerHeader(dataInputStream: LittleEndianDataInputStream, while (readStream) {
header: DatabaseHeaderKDBX): Boolean { val fieldId = dataInputStream.read().toByte()
val fieldId = dataInputStream.read().toByte()
val size = dataInputStream.readUInt().toKotlinInt() val size = dataInputStream.readUInt().toKotlinInt()
if (size < 0) throw IOException("Corrupted file") if (size < 0) throw IOException("Corrupted file")
var data = ByteArray(0) var data = ByteArray(0)
try { try {
if (size > 0) { if (size > 0) {
if (fieldId != DatabaseHeaderKDBX.PwDbInnerHeaderV4Fields.Binary) { if (fieldId != DatabaseHeaderKDBX.PwDbInnerHeaderV4Fields.Binary) {
data = dataInputStream.readBytes(size) data = dataInputStream.readBytes(size)
}
} }
} catch (e: Exception) {
// OOM only if corrupted file
throw IOException("Corrupted file")
} }
} catch (e: Exception) {
// OOM only if corrupted file
throw IOException("Corrupted file")
}
var result = true readStream = true
when (fieldId) { when (fieldId) {
DatabaseHeaderKDBX.PwDbInnerHeaderV4Fields.EndOfHeader -> { DatabaseHeaderKDBX.PwDbInnerHeaderV4Fields.EndOfHeader -> {
result = false readStream = false
} }
DatabaseHeaderKDBX.PwDbInnerHeaderV4Fields.InnerRandomStreamID -> { DatabaseHeaderKDBX.PwDbInnerHeaderV4Fields.InnerRandomStreamID -> {
header.setRandomStreamID(data) header.setRandomStreamID(data)
} }
DatabaseHeaderKDBX.PwDbInnerHeaderV4Fields.InnerRandomstreamKey -> { DatabaseHeaderKDBX.PwDbInnerHeaderV4Fields.InnerRandomstreamKey -> {
header.innerRandomStreamKey = data header.innerRandomStreamKey = data
} }
DatabaseHeaderKDBX.PwDbInnerHeaderV4Fields.Binary -> { DatabaseHeaderKDBX.PwDbInnerHeaderV4Fields.Binary -> {
// Read in a file // Read in a file
val protectedFlag = dataInputStream.read().toByte() == DatabaseHeaderKDBX.KdbxBinaryFlags.Protected val protectedFlag = dataInputStream.read().toByte() == DatabaseHeaderKDBX.KdbxBinaryFlags.Protected
val byteLength = size - 1 val byteLength = size - 1
// No compression at this level // No compression at this level
val protectedBinary = mDatabase.buildNewAttachment( val protectedBinary = mDatabase.buildNewAttachment(
isRAMSufficient.invoke(byteLength.toLong()), false, protectedFlag) isRAMSufficient.invoke(byteLength.toLong()), false, protectedFlag)
protectedBinary.getOutputDataStream(mDatabase.binaryCache).use { outputStream -> protectedBinary.getOutputDataStream(mDatabase.binaryCache).use { outputStream ->
dataInputStream.readBytes(byteLength) { buffer -> dataInputStream.readBytes(byteLength) { buffer ->
outputStream.write(buffer) outputStream.write(buffer)
}
} }
} }
} }
} }
return result
} }
private enum class KdbContext { private enum class KdbContext {