Rollback readBytes method and default buffer to fix argon2 database

This commit is contained in:
J-Jamet
2021-02-09 14:15:18 +01:00
parent 309380bdd5
commit 3f6a9c3af5
7 changed files with 39 additions and 26 deletions

View File

@@ -281,7 +281,5 @@ class DatabaseKDB : DatabaseVersioned<Int, UUID, GroupKDB, EntryKDB>() {
const val BACKUP_FOLDER_TITLE = "Backup" const val BACKUP_FOLDER_TITLE = "Backup"
private const val BACKUP_FOLDER_UNDEFINED_ID = -1 private const val BACKUP_FOLDER_UNDEFINED_ID = -1
const val BUFFER_SIZE_BYTES = 3 * 128
} }
} }

View File

@@ -216,7 +216,7 @@ class DatabaseKDBX : DatabaseVersioned<UUID, UUID, GroupKDBX, EntryKDBX> {
val cipherKey = loadedCipherKey val cipherKey = loadedCipherKey
?: throw IOException("Unable to retrieve cipher key to compress binaries") ?: throw IOException("Unable to retrieve cipher key to compress binaries")
// To compress, create a new binary with file // To compress, create a new binary with file
binary.compress(cipherKey, BUFFER_SIZE_BYTES) binary.compress(cipherKey)
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG, "Unable to compress $binary", e) Log.e(TAG, "Unable to compress $binary", e)
} }
@@ -228,7 +228,7 @@ class DatabaseKDBX : DatabaseVersioned<UUID, UUID, GroupKDBX, EntryKDBX> {
try { try {
val cipherKey = loadedCipherKey val cipherKey = loadedCipherKey
?: throw IOException("Unable to retrieve cipher key to decompress binaries") ?: throw IOException("Unable to retrieve cipher key to decompress binaries")
binary.decompress(cipherKey, BUFFER_SIZE_BYTES) binary.decompress(cipherKey)
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG, "Unable to decompress $binary", e) Log.e(TAG, "Unable to decompress $binary", e)
} }
@@ -713,7 +713,5 @@ class DatabaseKDBX : DatabaseVersioned<UUID, UUID, GroupKDBX, EntryKDBX> {
private const val XML_ATTRIBUTE_DATA_HASH = "Hash" private const val XML_ATTRIBUTE_DATA_HASH = "Hash"
const val BASE_64_FLAG = Base64.NO_WRAP const val BASE_64_FLAG = Base64.NO_WRAP
const val BUFFER_SIZE_BYTES = 3 * 128
} }
} }

View File

@@ -332,7 +332,9 @@ class DatabaseInputKDB(cacheDirectory: File)
val cipherKey = mDatabase.loadedCipherKey val cipherKey = mDatabase.loadedCipherKey
?: throw IOException("Unable to retrieve cipher key to load binaries") ?: throw IOException("Unable to retrieve cipher key to load binaries")
BufferedOutputStream(binaryAttachment.getOutputDataStream(cipherKey)).use { outputStream -> BufferedOutputStream(binaryAttachment.getOutputDataStream(cipherKey)).use { outputStream ->
cipherInputStream.copyPartTo(outputStream, fieldSize) cipherInputStream.readBytes(fieldSize) { buffer ->
outputStream.write(buffer)
}
} }
} }
} }

View File

@@ -33,7 +33,6 @@ import com.kunzisoft.keepass.database.element.database.BinaryAttachment
import com.kunzisoft.keepass.database.element.database.CompressionAlgorithm import com.kunzisoft.keepass.database.element.database.CompressionAlgorithm
import com.kunzisoft.keepass.database.element.database.DatabaseKDBX import com.kunzisoft.keepass.database.element.database.DatabaseKDBX
import com.kunzisoft.keepass.database.element.database.DatabaseKDBX.Companion.BASE_64_FLAG import com.kunzisoft.keepass.database.element.database.DatabaseKDBX.Companion.BASE_64_FLAG
import com.kunzisoft.keepass.database.element.database.DatabaseKDBX.Companion.BUFFER_SIZE_BYTES
import com.kunzisoft.keepass.database.element.database.DatabaseVersioned import com.kunzisoft.keepass.database.element.database.DatabaseVersioned
import com.kunzisoft.keepass.database.element.entry.EntryKDBX import com.kunzisoft.keepass.database.element.entry.EntryKDBX
import com.kunzisoft.keepass.database.element.group.GroupKDBX import com.kunzisoft.keepass.database.element.group.GroupKDBX
@@ -303,7 +302,9 @@ class DatabaseInputKDBX(cacheDirectory: File)
val cipherKey = mDatabase.loadedCipherKey val cipherKey = mDatabase.loadedCipherKey
?: throw IOException("Unable to retrieve cipher key to load binaries") ?: throw IOException("Unable to retrieve cipher key to load binaries")
protectedBinary.getOutputDataStream(cipherKey).use { outputStream -> protectedBinary.getOutputDataStream(cipherKey).use { outputStream ->
dataInputStream.copyPartTo(outputStream, byteLength) dataInputStream.readBytes(byteLength) { buffer ->
outputStream.write(buffer)
}
} }
} }
} }

View File

@@ -32,7 +32,6 @@ import com.kunzisoft.keepass.database.element.DeletedObject
import com.kunzisoft.keepass.database.element.database.CompressionAlgorithm import com.kunzisoft.keepass.database.element.database.CompressionAlgorithm
import com.kunzisoft.keepass.database.element.database.DatabaseKDBX import com.kunzisoft.keepass.database.element.database.DatabaseKDBX
import com.kunzisoft.keepass.database.element.database.DatabaseKDBX.Companion.BASE_64_FLAG import com.kunzisoft.keepass.database.element.database.DatabaseKDBX.Companion.BASE_64_FLAG
import com.kunzisoft.keepass.database.element.database.DatabaseKDBX.Companion.BUFFER_SIZE_BYTES
import com.kunzisoft.keepass.database.element.entry.AutoType import com.kunzisoft.keepass.database.element.entry.AutoType
import com.kunzisoft.keepass.database.element.entry.EntryKDBX import com.kunzisoft.keepass.database.element.entry.EntryKDBX
import com.kunzisoft.keepass.database.element.group.GroupKDBX import com.kunzisoft.keepass.database.element.group.GroupKDBX
@@ -473,7 +472,7 @@ class DatabaseOutputKDBX(private val mDatabaseKDBX: DatabaseKDBX,
if (binary.isProtected) { if (binary.isProtected) {
xml.attribute(null, DatabaseKDBXXML.AttrProtected, DatabaseKDBXXML.ValTrue) xml.attribute(null, DatabaseKDBXXML.AttrProtected, DatabaseKDBXXML.ValTrue)
binary.getInputDataStream().use { inputStream -> binary.getInputDataStream().use { inputStream ->
inputStream.readBytes(BUFFER_SIZE_BYTES) { buffer -> inputStream.readBytes { buffer ->
val encoded = ByteArray(buffer.size) val encoded = ByteArray(buffer.size)
randomStream!!.processBytes(buffer, 0, encoded.size, encoded, 0) randomStream!!.processBytes(buffer, 0, encoded.size, encoded, 0)
xml.text(String(Base64.encode(encoded, BASE_64_FLAG))) xml.text(String(Base64.encode(encoded, BASE_64_FLAG)))
@@ -482,7 +481,7 @@ class DatabaseOutputKDBX(private val mDatabaseKDBX: DatabaseKDBX,
} else { } else {
// Write the XML // Write the XML
binary.getInputDataStream().use { inputStream -> binary.getInputDataStream().use { inputStream ->
inputStream.readBytes(BUFFER_SIZE_BYTES) { buffer -> inputStream.readBytes { buffer ->
xml.text(String(Base64.encode(buffer, BASE_64_FLAG))) xml.text(String(Base64.encode(buffer, BASE_64_FLAG)))
} }
} }
@@ -510,7 +509,7 @@ class DatabaseOutputKDBX(private val mDatabaseKDBX: DatabaseKDBX,
val binaryCipherKey = mDatabaseKDBX.loadedCipherKey val binaryCipherKey = mDatabaseKDBX.loadedCipherKey
?: throw IOException("Unable to retrieve cipher key to write binaries") ?: throw IOException("Unable to retrieve cipher key to write binaries")
binary.getInputDataStream(binaryCipherKey).use { inputStream -> binary.getInputDataStream(binaryCipherKey).use { inputStream ->
inputStream.readAllBytes(BUFFER_SIZE_BYTES) { buffer -> inputStream.readAllBytes { buffer ->
xml.text(String(Base64.encode(buffer, BASE_64_FLAG))) xml.text(String(Base64.encode(buffer, BASE_64_FLAG)))
} }
} }

View File

@@ -20,7 +20,6 @@
package com.kunzisoft.keepass.database.file.output package com.kunzisoft.keepass.database.file.output
import com.kunzisoft.keepass.database.element.Database import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.database.element.database.DatabaseKDB
import com.kunzisoft.keepass.database.element.entry.EntryKDB import com.kunzisoft.keepass.database.element.entry.EntryKDB
import com.kunzisoft.keepass.database.exception.DatabaseOutputException import com.kunzisoft.keepass.database.exception.DatabaseOutputException
import com.kunzisoft.keepass.stream.* import com.kunzisoft.keepass.stream.*
@@ -103,7 +102,7 @@ class EntryOutputKDB {
// Write data // Write data
if (binaryDataLength > 0) { if (binaryDataLength > 0) {
binaryData?.getInputDataStream(binaryCipherKey).use { inputStream -> binaryData?.getInputDataStream(binaryCipherKey).use { inputStream ->
inputStream?.readAllBytes(DatabaseKDB.BUFFER_SIZE_BYTES) { buffer -> inputStream?.readAllBytes { buffer ->
mOutputStream.write(buffer) mOutputStream.write(buffer)
} }
inputStream?.close() inputStream?.close()

View File

@@ -24,14 +24,14 @@ import com.kunzisoft.keepass.utils.StringDatabaseKDBUtils.bytesToString
import com.kunzisoft.keepass.utils.UnsignedInt import com.kunzisoft.keepass.utils.UnsignedInt
import java.io.IOException import java.io.IOException
import java.io.InputStream import java.io.InputStream
import java.io.OutputStream
import java.util.* import java.util.*
/** /**
* Read all data of stream and invoke [readBytes] each time the buffer is full or no more data to read. * Read all data of stream and invoke [readBytes] each time the buffer is full or no more data to read.
*/ */
@Throws(IOException::class) @Throws(IOException::class)
fun InputStream.readAllBytes(bufferSize: Int, readBytes: (bytesRead: ByteArray) -> Unit) { fun InputStream.readAllBytes(bufferSize: Int = DEFAULT_BUFFER_SIZE,
readBytes: (bytesRead: ByteArray) -> Unit) {
val buffer = ByteArray(bufferSize) val buffer = ByteArray(bufferSize)
var read = 0 var read = 0
while (read != -1) { while (read != -1) {
@@ -48,17 +48,33 @@ fun InputStream.readAllBytes(bufferSize: Int, readBytes: (bytesRead: ByteArray)
} }
/** /**
* Read number of bytes defined by [length] and copy the content in [outputStream] * Read number of bytes defined by [length] and invoke [readBytes] each time the buffer is full or no more data to read.
*/ */
@Throws(IOException::class) @Throws(IOException::class)
fun InputStream.copyPartTo(outputStream: OutputStream, length: Int, bufferSize: Int = DEFAULT_BUFFER_SIZE) { fun InputStream.readBytes(length: Int, bufferSize: Int = DEFAULT_BUFFER_SIZE,
var bytesCopied: Long = 0 readBytes: (bytesRead: ByteArray) -> Unit) {
val buffer = ByteArray(bufferSize) var bufferLength = bufferSize
var bytesRead = read(buffer) var buffer = ByteArray(bufferLength)
while (bytesRead >= 0 && bytesCopied <= length) {
outputStream.write(buffer, 0, bytesRead) var offset = 0
bytesCopied += bytesRead var read = 0
bytesRead = read(buffer) while (offset < length && read != -1) {
// To reduce the buffer for the last bytes reads
if (length - offset < bufferLength) {
bufferLength = length - offset
buffer = ByteArray(bufferLength)
}
read = this.read(buffer, 0, bufferLength)
// To get only the bytes read
val optimizedBuffer: ByteArray = if (read >= 0 && buffer.size > read) {
buffer.copyOf(read)
} else {
buffer
}
readBytes.invoke(optimizedBuffer)
offset += read
} }
} }