Fix issue #127 KDBX binaries

This commit is contained in:
J-Jamet
2019-12-21 21:18:58 +01:00
parent 84fdef8eb6
commit efb9b50f85
3 changed files with 44 additions and 47 deletions

View File

@@ -562,7 +562,7 @@ class DatabaseKDBX : DatabaseVersioned<UUID, UUID, GroupKDBX, EntryKDBX> {
private const val KeyElementName = "Key" private const val KeyElementName = "Key"
private const val KeyDataElementName = "Data" private const val KeyDataElementName = "Data"
const val BASE_64_FLAG = Base64.DEFAULT const val BASE_64_FLAG = Base64.NO_WRAP
const val BUFFER_SIZE_BYTES = 3 * 128 const val BUFFER_SIZE_BYTES = 3 * 128
} }

View File

@@ -961,7 +961,7 @@ class DatabaseInputKDBX(cacheDirectory: File,
// New binary to retrieve // New binary to retrieve
else { else {
var compressed: Boolean? = null var compressed = false
var protected = false var protected = false
if (xpp.attributeCount > 0) { if (xpp.attributeCount > 0) {
@@ -985,12 +985,12 @@ class DatabaseInputKDBX(cacheDirectory: File,
return FileOutputStream(file).use { outputStream -> return FileOutputStream(file).use { outputStream ->
// Force compression in this specific case // Force compression in this specific case
if (mDatabase.compressionAlgorithm == CompressionAlgorithm.GZip if (mDatabase.compressionAlgorithm == CompressionAlgorithm.GZip
&& compressed == false) { && !compressed) {
GZIPOutputStream(outputStream).write(data) GZIPOutputStream(outputStream).write(data)
BinaryAttachment(file, protected, true) BinaryAttachment(file, protected, true)
} else { } else {
outputStream.write(data) outputStream.write(data)
BinaryAttachment(file, protected) BinaryAttachment(file, protected, compressed)
} }
} }
} }

View File

@@ -233,7 +233,7 @@ class DatabaseOutputKDBX(private val mDatabaseKDBX: DatabaseKDBX,
writeUuid(DatabaseKDBXXML.ElemLastTopVisibleGroup, mDatabaseKDBX.lastTopVisibleGroupUUID) writeUuid(DatabaseKDBXXML.ElemLastTopVisibleGroup, mDatabaseKDBX.lastTopVisibleGroupUUID)
// Seem to work properly if always in meta // Seem to work properly if always in meta
// if (header!!.version < DatabaseHeaderKDBX.FILE_VERSION_32_4) if (header!!.version < DatabaseHeaderKDBX.FILE_VERSION_32_4)
writeMetaBinaries() writeMetaBinaries()
writeCustomData(mDatabaseKDBX.customData) writeCustomData(mDatabaseKDBX.customData)
@@ -421,6 +421,43 @@ class DatabaseOutputKDBX(private val mDatabaseKDBX: DatabaseKDBX,
writeObject(name, String(Base64.encode(data, BASE_64_FLAG))) writeObject(name, String(Base64.encode(data, BASE_64_FLAG)))
} }
@Throws(IllegalArgumentException::class, IllegalStateException::class, IOException::class)
private fun writeBinary(binary : BinaryAttachment) {
val binaryLength = binary.length()
if (binaryLength > 0) {
if (binary.isProtected) {
xml.attribute(null, DatabaseKDBXXML.AttrProtected, DatabaseKDBXXML.ValTrue)
binary.getInputDataStream().readBytes(BUFFER_SIZE_BYTES) { buffer ->
val encoded = ByteArray(buffer.size)
randomStream!!.processBytes(buffer, 0, encoded.size, encoded, 0)
val charArray = String(Base64.encode(encoded, BASE_64_FLAG)).toCharArray()
xml.text(charArray, 0, charArray.size)
}
} else {
// Force binary compression from database (compression was harmonized during import)
if (mDatabaseKDBX.compressionAlgorithm === CompressionAlgorithm.GZip) {
xml.attribute(null, DatabaseKDBXXML.AttrCompressed, DatabaseKDBXXML.ValTrue)
}
// Force decompression in this specific case
val binaryInputStream = if (mDatabaseKDBX.compressionAlgorithm == CompressionAlgorithm.None
&& binary.isCompressed == true) {
GZIPInputStream(binary.getInputDataStream())
} else {
binary.getInputDataStream()
}
// Write the XML
binaryInputStream.readBytes(BUFFER_SIZE_BYTES) { buffer ->
val charArray = String(Base64.encode(buffer, BASE_64_FLAG)).toCharArray()
xml.text(charArray, 0, charArray.size)
}
}
}
}
@Throws(IllegalArgumentException::class, IllegalStateException::class, IOException::class) @Throws(IllegalArgumentException::class, IllegalStateException::class, IOException::class)
private fun writeMetaBinaries() { private fun writeMetaBinaries() {
xml.startTag(null, DatabaseKDBXXML.ElemBinaries) xml.startTag(null, DatabaseKDBXXML.ElemBinaries)
@@ -428,29 +465,7 @@ class DatabaseOutputKDBX(private val mDatabaseKDBX: DatabaseKDBX,
mDatabaseKDBX.binaryPool.doForEachBinary { key, binary -> mDatabaseKDBX.binaryPool.doForEachBinary { key, binary ->
xml.startTag(null, DatabaseKDBXXML.ElemBinary) xml.startTag(null, DatabaseKDBXXML.ElemBinary)
xml.attribute(null, DatabaseKDBXXML.AttrId, key.toString()) xml.attribute(null, DatabaseKDBXXML.AttrId, key.toString())
writeBinary(binary)
// Force binary compression from database (compression was harmonized during import)
xml.attribute(null, DatabaseKDBXXML.AttrCompressed,
if (mDatabaseKDBX.compressionAlgorithm === CompressionAlgorithm.GZip) {
DatabaseKDBXXML.ValTrue
} else {
DatabaseKDBXXML.ValFalse
}
)
// Force decompression in this specific case
val binaryInputStream = if (mDatabaseKDBX.compressionAlgorithm == CompressionAlgorithm.None
&& binary.isCompressed == true) {
GZIPInputStream(binary.getInputDataStream())
} else {
binary.getInputDataStream()
}
// Write the XML
binaryInputStream.readBytes(BUFFER_SIZE_BYTES) { buffer ->
val charArray = String(Base64.encode(buffer, BASE_64_FLAG)).toCharArray()
xml.text(charArray, 0, charArray.size)
}
xml.endTag(null, DatabaseKDBXXML.ElemBinary) xml.endTag(null, DatabaseKDBXXML.ElemBinary)
} }
@@ -559,25 +574,7 @@ class DatabaseOutputKDBX(private val mDatabaseKDBX: DatabaseKDBX,
if (ref != null) { if (ref != null) {
xml.attribute(null, DatabaseKDBXXML.AttrRef, ref.toString()) xml.attribute(null, DatabaseKDBXXML.AttrRef, ref.toString())
} else { } else {
val binaryLength = binary.length() writeBinary(binary)
if (binaryLength > 0) {
if (binary.isProtected) {
xml.attribute(null, DatabaseKDBXXML.AttrProtected, DatabaseKDBXXML.ValTrue)
binary.getInputDataStream().readBytes(BUFFER_SIZE_BYTES) { buffer ->
val encoded = ByteArray(buffer.size)
randomStream!!.processBytes(buffer, 0, encoded.size, encoded, 0)
val charArray = String(Base64.encode(encoded, BASE_64_FLAG)).toCharArray()
xml.text(charArray, 0, charArray.size)
}
} else {
binary.getInputDataStream().readBytes(BUFFER_SIZE_BYTES) { buffer ->
val charArray = String(Base64.encode(buffer, BASE_64_FLAG)).toCharArray()
xml.text(charArray, 0, charArray.size)
}
}
}
} }
xml.endTag(null, DatabaseKDBXXML.ElemValue) xml.endTag(null, DatabaseKDBXXML.ElemValue)