diff --git a/app/src/androidTest/java/com/kunzisoft/keepass/tests/stream/BinaryAttachmentTest.kt b/app/src/androidTest/java/com/kunzisoft/keepass/tests/stream/BinaryAttachmentTest.kt index cb9d95e42..75b90dcde 100644 --- a/app/src/androidTest/java/com/kunzisoft/keepass/tests/stream/BinaryAttachmentTest.kt +++ b/app/src/androidTest/java/com/kunzisoft/keepass/tests/stream/BinaryAttachmentTest.kt @@ -4,7 +4,7 @@ import android.content.Context import androidx.test.platform.app.InstrumentationRegistry import com.kunzisoft.keepass.database.element.Database import com.kunzisoft.keepass.database.element.database.BinaryAttachment -import com.kunzisoft.keepass.stream.readBytes +import com.kunzisoft.keepass.stream.readAllBytes import com.kunzisoft.keepass.utils.UriUtil import junit.framework.TestCase.assertEquals import org.junit.Test @@ -30,7 +30,7 @@ class BinaryAttachmentTest { private fun saveBinary(asset: String, binaryAttachment: BinaryAttachment) { context.assets.open(asset).use { assetInputStream -> binaryAttachment.getOutputDataStream(loadedKey).use { binaryOutputStream -> - assetInputStream.readBytes(DEFAULT_BUFFER_SIZE) { buffer -> + assetInputStream.readAllBytes(DEFAULT_BUFFER_SIZE) { buffer -> binaryOutputStream.write(buffer) } } diff --git a/app/src/main/java/com/kunzisoft/keepass/database/element/Database.kt b/app/src/main/java/com/kunzisoft/keepass/database/element/Database.kt index 524d44820..e7fe5f12c 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/element/Database.kt +++ b/app/src/main/java/com/kunzisoft/keepass/database/element/Database.kt @@ -346,12 +346,13 @@ class Database { } class LoadedKey(val key: Key, val iv: IvParameterSpec) { - companion object { + const val BINARY_CIPHER = "Blowfish/CBC/PKCS5Padding" + fun generateNewCipherKey(): LoadedKey { - val iv = ByteArray(16) + val iv = ByteArray(8) SecureRandom().nextBytes(iv) - return LoadedKey(KeyGenerator.getInstance("AES").generateKey(), IvParameterSpec(iv)) + return LoadedKey(KeyGenerator.getInstance("Blowfish").generateKey(), IvParameterSpec(iv)) } } } diff --git a/app/src/main/java/com/kunzisoft/keepass/database/element/database/BinaryAttachment.kt b/app/src/main/java/com/kunzisoft/keepass/database/element/database/BinaryAttachment.kt index bd27d722e..e1615b9ca 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/element/database/BinaryAttachment.kt +++ b/app/src/main/java/com/kunzisoft/keepass/database/element/database/BinaryAttachment.kt @@ -22,7 +22,7 @@ package com.kunzisoft.keepass.database.element.database import android.os.Parcel import android.os.Parcelable import com.kunzisoft.keepass.database.element.Database -import com.kunzisoft.keepass.stream.readBytes +import com.kunzisoft.keepass.stream.readAllBytes import java.io.* import java.util.zip.GZIPInputStream import java.util.zip.GZIPOutputStream @@ -39,8 +39,8 @@ class BinaryAttachment : Parcelable { private set var isCorrupted: Boolean = false // Cipher to encrypt temp file - private var cipherEncryption: Cipher = Cipher.getInstance("AES/CFB8/NoPadding") - private var cipherDecryption: Cipher = Cipher.getInstance("AES/CFB8/NoPadding") + private var cipherEncryption: Cipher = Cipher.getInstance(Database.LoadedKey.BINARY_CIPHER) + private var cipherDecryption: Cipher = Cipher.getInstance(Database.LoadedKey.BINARY_CIPHER) fun length(): Long { return dataFile?.length() ?: 0 @@ -115,7 +115,7 @@ class BinaryAttachment : Parcelable { cipherEncryption.init(Cipher.ENCRYPT_MODE, cipherKey.key, cipherKey.iv) GZIPOutputStream(CipherOutputStream(FileOutputStream(fileBinaryCompress), cipherEncryption)).use { outputStream -> getInputDataStream(cipherKey).use { inputStream -> - inputStream.readBytes(bufferSize) { buffer -> + inputStream.readAllBytes(bufferSize) { buffer -> outputStream.write(buffer) } } @@ -140,7 +140,7 @@ class BinaryAttachment : Parcelable { cipherEncryption.init(Cipher.ENCRYPT_MODE, cipherKey.key, cipherKey.iv) CipherOutputStream(FileOutputStream(fileBinaryDecompress), cipherEncryption).use { outputStream -> getUnGzipInputDataStream(cipherKey).use { inputStream -> - inputStream.readBytes(bufferSize) { buffer -> + inputStream.readAllBytes(bufferSize) { buffer -> outputStream.write(buffer) } } diff --git a/app/src/main/java/com/kunzisoft/keepass/database/file/output/DatabaseOutputKDBX.kt b/app/src/main/java/com/kunzisoft/keepass/database/file/output/DatabaseOutputKDBX.kt index 0bd17b722..d775df3fa 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/file/output/DatabaseOutputKDBX.kt +++ b/app/src/main/java/com/kunzisoft/keepass/database/file/output/DatabaseOutputKDBX.kt @@ -156,7 +156,7 @@ class DatabaseOutputKDBX(private val mDatabaseKDBX: DatabaseKDBX, dataOutputStream.writeByte(flag) protectedBinary.getInputDataStream(binaryCipherKey).use { inputStream -> - inputStream.readBytes(BUFFER_SIZE_BYTES) { buffer -> + inputStream.readAllBytes(BUFFER_SIZE_BYTES) { buffer -> dataOutputStream.write(buffer) } } @@ -512,7 +512,7 @@ class DatabaseOutputKDBX(private val mDatabaseKDBX: DatabaseKDBX, val binaryCipherKey = mDatabaseKDBX.loadedCipherKey ?: throw IOException("Unable to retrieve cipher key to write binaries") binary.getInputDataStream(binaryCipherKey).use { inputStream -> - inputStream.readBytes(BUFFER_SIZE_BYTES) { buffer -> + inputStream.readAllBytes(BUFFER_SIZE_BYTES) { buffer -> xml.text(String(Base64.encode(buffer, BASE_64_FLAG))) } } diff --git a/app/src/main/java/com/kunzisoft/keepass/database/file/output/EntryOutputKDB.kt b/app/src/main/java/com/kunzisoft/keepass/database/file/output/EntryOutputKDB.kt index a0a456f4a..ebcfadea1 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/file/output/EntryOutputKDB.kt +++ b/app/src/main/java/com/kunzisoft/keepass/database/file/output/EntryOutputKDB.kt @@ -103,7 +103,7 @@ class EntryOutputKDB { // Write data if (binaryDataLength > 0) { binaryData?.getInputDataStream(binaryCipherKey).use { inputStream -> - inputStream?.readBytes(DatabaseKDB.BUFFER_SIZE_BYTES) { buffer -> + inputStream?.readAllBytes(DatabaseKDB.BUFFER_SIZE_BYTES) { buffer -> mOutputStream.write(buffer) } inputStream?.close() diff --git a/app/src/main/java/com/kunzisoft/keepass/services/AttachmentFileNotificationService.kt b/app/src/main/java/com/kunzisoft/keepass/services/AttachmentFileNotificationService.kt index a4847e319..cc36f8e8f 100644 --- a/app/src/main/java/com/kunzisoft/keepass/services/AttachmentFileNotificationService.kt +++ b/app/src/main/java/com/kunzisoft/keepass/services/AttachmentFileNotificationService.kt @@ -34,7 +34,7 @@ import com.kunzisoft.keepass.database.element.database.BinaryAttachment import com.kunzisoft.keepass.model.AttachmentState import com.kunzisoft.keepass.model.EntryAttachmentState import com.kunzisoft.keepass.model.StreamDirection -import com.kunzisoft.keepass.stream.readBytes +import com.kunzisoft.keepass.stream.readAllBytes import com.kunzisoft.keepass.timeout.TimeoutHelper import com.kunzisoft.keepass.utils.UriUtil import kotlinx.coroutines.* @@ -377,7 +377,7 @@ class AttachmentFileNotificationService: LockNotificationService() { UriUtil.getUriOutputStream(contentResolver, attachmentToUploadUri)?.use { outputStream -> Database.getInstance().loadedCipherKey?.let { binaryCipherKey -> binaryAttachment.getUnGzipInputDataStream(binaryCipherKey).use { inputStream -> - inputStream.readBytes(bufferSize) { buffer -> + inputStream.readAllBytes(bufferSize) { buffer -> outputStream.write(buffer) dataDownloaded += buffer.size try { @@ -403,7 +403,7 @@ class AttachmentFileNotificationService: LockNotificationService() { Database.getInstance().loadedCipherKey?.let { binaryCipherKey -> binaryAttachment.getGzipOutputDataStream(binaryCipherKey).use { outputStream -> BufferedInputStream(inputStream).use { attachmentBufferedInputStream -> - attachmentBufferedInputStream.readBytes(bufferSize) { buffer -> + attachmentBufferedInputStream.readAllBytes(bufferSize) { buffer -> outputStream.write(buffer) dataUploaded += buffer.size try { diff --git a/app/src/main/java/com/kunzisoft/keepass/stream/StreamBytesUtils.kt b/app/src/main/java/com/kunzisoft/keepass/stream/StreamBytesUtils.kt index 4e01ecf3a..4ecfbc777 100644 --- a/app/src/main/java/com/kunzisoft/keepass/stream/StreamBytesUtils.kt +++ b/app/src/main/java/com/kunzisoft/keepass/stream/StreamBytesUtils.kt @@ -30,19 +30,9 @@ import java.util.* * Read all data of stream and invoke [readBytes] each time the buffer is full or no more data to read. */ @Throws(IOException::class) -fun InputStream.readBytes(bufferSize: Int, readBytes: (bytesRead: ByteArray) -> Unit) { - val buffer = ByteArray(bufferSize) - var read = 0 - while (read != -1) { - read = this.read(buffer, 0, buffer.size) - if (read != -1) { - val optimizedBuffer: ByteArray = if (buffer.size == read) { - buffer - } else { - buffer.copyOf(read) - } - readBytes.invoke(optimizedBuffer) - } +fun InputStream.readAllBytes(bufferSize: Int, readBytes: (bytesRead: ByteArray) -> Unit) { + this.buffered(bufferSize).use { bufferedInputStream -> + readBytes.invoke(bufferedInputStream.readBytes()) } }