diff --git a/app/libcryfs b/app/libcryfs index 356cf8a..cf822d6 160000 --- a/app/libcryfs +++ b/app/libcryfs @@ -1 +1 @@ -Subproject commit 356cf8a1604776cb2cc4f4ff873936f7b396bd49 +Subproject commit cf822d6a5bb0bb3492ec350d2648f14c859f846f diff --git a/app/src/main/java/sushi/hardcore/droidfs/MainActivity.kt b/app/src/main/java/sushi/hardcore/droidfs/MainActivity.kt index 05f91ca..830abd5 100644 --- a/app/src/main/java/sushi/hardcore/droidfs/MainActivity.kt +++ b/app/src/main/java/sushi/hardcore/droidfs/MainActivity.kt @@ -31,7 +31,7 @@ import sushi.hardcore.droidfs.explorers.ExplorerActivityDrop import sushi.hardcore.droidfs.explorers.ExplorerActivityPick import sushi.hardcore.droidfs.file_operations.FileOperationService import sushi.hardcore.droidfs.filesystems.EncryptedVolume -import sushi.hardcore.droidfs.filesystems.GocryptfsVolume +import sushi.hardcore.droidfs.util.ObjRef import sushi.hardcore.droidfs.util.PathUtils import sushi.hardcore.droidfs.util.WidgetUtil import sushi.hardcore.droidfs.widgets.CustomAlertDialogBuilder @@ -535,7 +535,7 @@ class MainActivity : BaseActivity(), VolumeAdapter.Listener { private fun askForPassword(volume: SavedVolume, position: Int, savePasswordHash: Boolean = false) { val dialogBinding = DialogOpenVolumeBinding.inflate(layoutInflater) - if (!usfFingerprint || fingerprintProtector == null || volume.encryptedHash != null || volume.type == EncryptedVolume.CRYFS_VOLUME_TYPE) { + if (!usfFingerprint || fingerprintProtector == null || volume.encryptedHash != null) { dialogBinding.checkboxSavePassword.visibility = View.GONE } else { dialogBinding.checkboxSavePassword.isChecked = savePasswordHash @@ -564,10 +564,10 @@ class MainActivity : BaseActivity(), VolumeAdapter.Listener { } private fun openVolumeWithPassword(volume: SavedVolume, position: Int, password: ByteArray, savePasswordHash: Boolean) { - val usfFingerprint = sharedPrefs.getBoolean("usf_fingerprint", false) - var returnedHash: ByteArray? = null - if (savePasswordHash && usfFingerprint) { - returnedHash = ByteArray(GocryptfsVolume.KeyLen) + val returnedHash: ObjRef? = if (savePasswordHash) { + ObjRef(null) + } else { + null } object : LoadingTask(this, themeValue, R.string.loading_msg_open) { override suspend fun doTask(): EncryptedVolume? { @@ -594,7 +594,7 @@ class MainActivity : BaseActivity(), VolumeAdapter.Listener { } override fun onPasswordHashDecrypted(hash: ByteArray) {} override fun onPasswordHashSaved() { - Arrays.fill(returnedHash, 0) + Arrays.fill(returnedHash.value!!, 0) volumeAdapter.onVolumeChanged(position) startExplorer(encryptedVolume, volume.shortName) } @@ -604,10 +604,10 @@ class MainActivity : BaseActivity(), VolumeAdapter.Listener { encryptedVolume.close() isClosed = true } - Arrays.fill(returnedHash, 0) + Arrays.fill(returnedHash.value!!, 0) } } - fingerprintProtector.savePasswordHash(volume, returnedHash) + fingerprintProtector.savePasswordHash(volume, returnedHash.value!!) } else { startExplorer(encryptedVolume, volume.shortName) } diff --git a/app/src/main/java/sushi/hardcore/droidfs/add_volume/CreateVolumeFragment.kt b/app/src/main/java/sushi/hardcore/droidfs/add_volume/CreateVolumeFragment.kt index 4c53870..8cc20b6 100644 --- a/app/src/main/java/sushi/hardcore/droidfs/add_volume/CreateVolumeFragment.kt +++ b/app/src/main/java/sushi/hardcore/droidfs/add_volume/CreateVolumeFragment.kt @@ -18,6 +18,7 @@ import sushi.hardcore.droidfs.databinding.FragmentCreateVolumeBinding import sushi.hardcore.droidfs.filesystems.CryfsVolume import sushi.hardcore.droidfs.filesystems.EncryptedVolume import sushi.hardcore.droidfs.filesystems.GocryptfsVolume +import sushi.hardcore.droidfs.util.ObjRef import sushi.hardcore.droidfs.util.WidgetUtil import sushi.hardcore.droidfs.widgets.CustomAlertDialogBuilder import java.io.File @@ -108,12 +109,8 @@ class CreateVolumeFragment: Fragment() { binding.spinnerVolumeType.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { val ciphersArray = if (volumeTypes[position] == resources.getString(R.string.gocryptfs)) { - if (usfFingerprint && fingerprintProtector != null) { - binding.checkboxSavePassword.visibility = View.VISIBLE - } R.array.gocryptfs_encryption_ciphers } else { - binding.checkboxSavePassword.visibility = View.GONE R.array.cryfs_encryption_ciphers } with(encryptionCipherAdapter) { @@ -167,9 +164,11 @@ class CreateVolumeFragment: Fragment() { Arrays.fill(passwordConfirm, 0) } else { Arrays.fill(passwordConfirm, 0) - var returnedHash: ByteArray? = null - if (binding.checkboxSavePassword.isChecked) - returnedHash = ByteArray(GocryptfsVolume.KeyLen) + val returnedHash: ObjRef? = if (binding.checkboxSavePassword.isChecked) { + ObjRef(null) + } else { + null + } object: LoadingTask(requireActivity() as AppCompatActivity, themeValue, R.string.loading_msg_create) { override suspend fun doTask(): SavedVolume? { val volumeFile = File(volumePath) @@ -188,13 +187,16 @@ class CreateVolumeFragment: Fragment() { xchacha, GocryptfsVolume.ScryptDefaultLogN, ConstValues.CREATOR, - returnedHash + returnedHash?.apply { + value = ByteArray(GocryptfsVolume.KeyLen) + }?.value, ), EncryptedVolume.GOCRYPTFS_VOLUME_TYPE) } else { saveVolume(CryfsVolume.create( volumePath, CryfsVolume.getLocalStateDir(activity.filesDir.path), password, + returnedHash, resources.getStringArray(R.array.cryfs_encryption_ciphers)[binding.spinnerCipher.selectedItemPosition] ), EncryptedVolume.CRYFS_VOLUME_TYPE) } @@ -216,21 +218,21 @@ class CreateVolumeFragment: Fragment() { override fun onHashStorageReset() { hashStorageReset = true // retry - it.savePasswordHash(volume, returnedHash) + it.savePasswordHash(volume, returnedHash.value!!) } override fun onPasswordHashDecrypted(hash: ByteArray) {} // shouldn't happen here override fun onPasswordHashSaved() { - Arrays.fill(returnedHash, 0) + Arrays.fill(returnedHash.value!!, 0) onVolumeCreated() } override fun onFailed(pending: Boolean) { if (!pending) { - Arrays.fill(returnedHash, 0) + Arrays.fill(returnedHash.value!!, 0) onVolumeCreated() } } } - it.savePasswordHash(volume, returnedHash) + it.savePasswordHash(volume, returnedHash.value!!) } } else onVolumeCreated() } diff --git a/app/src/main/java/sushi/hardcore/droidfs/file_operations/FileOperationService.kt b/app/src/main/java/sushi/hardcore/droidfs/file_operations/FileOperationService.kt index 22201ed..407e6ea 100644 --- a/app/src/main/java/sushi/hardcore/droidfs/file_operations/FileOperationService.kt +++ b/app/src/main/java/sushi/hardcore/droidfs/file_operations/FileOperationService.kt @@ -18,6 +18,7 @@ import sushi.hardcore.droidfs.ConstValues import sushi.hardcore.droidfs.R import sushi.hardcore.droidfs.explorers.ExplorerElement import sushi.hardcore.droidfs.filesystems.EncryptedVolume +import sushi.hardcore.droidfs.util.ObjRef import sushi.hardcore.droidfs.util.PathUtils import sushi.hardcore.droidfs.util.Wiper import java.io.File @@ -415,8 +416,6 @@ class FileOperationService : Service() { return count } - internal class ObjRef(var value: T) - private fun recursiveCopyVolume( src: DocumentFile, dst: DocumentFile, diff --git a/app/src/main/java/sushi/hardcore/droidfs/filesystems/CryfsVolume.kt b/app/src/main/java/sushi/hardcore/droidfs/filesystems/CryfsVolume.kt index 3b44686..45390d1 100644 --- a/app/src/main/java/sushi/hardcore/droidfs/filesystems/CryfsVolume.kt +++ b/app/src/main/java/sushi/hardcore/droidfs/filesystems/CryfsVolume.kt @@ -3,6 +3,7 @@ package sushi.hardcore.droidfs.filesystems import android.os.Parcel import sushi.hardcore.droidfs.ConstValues import sushi.hardcore.droidfs.explorers.ExplorerElement +import sushi.hardcore.droidfs.util.ObjRef import sushi.hardcore.droidfs.util.PathUtils class CryfsVolume(private val fusePtr: Long): EncryptedVolume() { @@ -16,7 +17,9 @@ class CryfsVolume(private val fusePtr: Long): EncryptedVolume() { private external fun nativeInit( baseDir: String, localStateDir: String, - password: ByteArray, + password: ByteArray?, + givenHash: ByteArray?, + returnedHash: ObjRef?, createBaseDir: Boolean, cipher: String? ): Long @@ -39,8 +42,16 @@ class CryfsVolume(private val fusePtr: Long): EncryptedVolume() { return PathUtils.pathJoin(filesDir, ConstValues.CRYFS_LOCAL_STATE_DIR) } - private fun init(baseDir: String, localStateDir: String, password: ByteArray, createBaseDir: Boolean, cipher: String?): CryfsVolume? { - val fusePtr = nativeInit(baseDir, localStateDir, password, createBaseDir, cipher) + private fun init( + baseDir: String, + localStateDir: String, + password: ByteArray?, + givenHash: ByteArray?, + returnedHash: ObjRef?, + createBaseDir: Boolean, + cipher: String? + ): CryfsVolume? { + val fusePtr = nativeInit(baseDir, localStateDir, password, givenHash, returnedHash, createBaseDir, cipher) return if (fusePtr == 0L) { null } else { @@ -48,12 +59,12 @@ class CryfsVolume(private val fusePtr: Long): EncryptedVolume() { } } - fun create(baseDir: String, localStateDir: String, password: ByteArray, cipher: String?): Boolean { - return init(baseDir, localStateDir, password, true, cipher)?.also { it.close() } != null + fun create(baseDir: String, localStateDir: String, password: ByteArray, returnedHash: ObjRef?, cipher: String?): Boolean { + return init(baseDir, localStateDir, password, null, returnedHash, true, cipher)?.also { it.close() } != null } - fun init(baseDir: String, localStateDir: String, password: ByteArray): CryfsVolume? { - return init(baseDir, localStateDir, password, false, null) + fun init(baseDir: String, localStateDir: String, password: ByteArray?, givenHash: ByteArray?, returnedHash: ObjRef?): CryfsVolume? { + return init(baseDir, localStateDir, password, givenHash, returnedHash, false, null) } } diff --git a/app/src/main/java/sushi/hardcore/droidfs/filesystems/EncryptedVolume.kt b/app/src/main/java/sushi/hardcore/droidfs/filesystems/EncryptedVolume.kt index 9895fef..c1a39f8 100644 --- a/app/src/main/java/sushi/hardcore/droidfs/filesystems/EncryptedVolume.kt +++ b/app/src/main/java/sushi/hardcore/droidfs/filesystems/EncryptedVolume.kt @@ -7,6 +7,7 @@ import android.os.Parcelable import sushi.hardcore.droidfs.ConstValues import sushi.hardcore.droidfs.SavedVolume import sushi.hardcore.droidfs.explorers.ExplorerElement +import sushi.hardcore.droidfs.util.ObjRef import sushi.hardcore.droidfs.util.PathUtils import java.io.File import java.io.FileOutputStream @@ -40,13 +41,26 @@ abstract class EncryptedVolume: Parcelable { } } - fun init(volume: SavedVolume, filesDir: String, password: ByteArray?, givenHash: ByteArray?, returnedHash: ByteArray?): EncryptedVolume? { + fun init( + volume: SavedVolume, + filesDir: String, + password: ByteArray?, + givenHash: ByteArray?, + returnedHash: ObjRef? + ): EncryptedVolume? { return when (volume.type) { GOCRYPTFS_VOLUME_TYPE -> { - GocryptfsVolume.init(volume.getFullPath(filesDir), password, givenHash, returnedHash) + GocryptfsVolume.init( + volume.getFullPath(filesDir), + password, + givenHash, + returnedHash?.apply { + value = ByteArray(GocryptfsVolume.KeyLen) + }?.value + ) } CRYFS_VOLUME_TYPE -> { - CryfsVolume.init(volume.getFullPath(filesDir), CryfsVolume.getLocalStateDir(filesDir), password!!) + CryfsVolume.init(volume.getFullPath(filesDir), CryfsVolume.getLocalStateDir(filesDir), password, givenHash, returnedHash) } else -> throw invalidVolumeType() } diff --git a/app/src/main/java/sushi/hardcore/droidfs/util/ObjRef.kt b/app/src/main/java/sushi/hardcore/droidfs/util/ObjRef.kt new file mode 100644 index 0000000..bb82798 --- /dev/null +++ b/app/src/main/java/sushi/hardcore/droidfs/util/ObjRef.kt @@ -0,0 +1,3 @@ +package sushi.hardcore.droidfs.util + +class ObjRef(var value: T) \ No newline at end of file diff --git a/app/src/main/native/libcryfs.c b/app/src/main/native/libcryfs.c index 134f660..a671519 100644 --- a/app/src/main/native/libcryfs.c +++ b/app/src/main/native/libcryfs.c @@ -5,9 +5,11 @@ JNIEXPORT jlong JNICALL Java_sushi_hardcore_droidfs_filesystems_CryfsVolume_00024Companion_nativeInit(JNIEnv *env, jobject thiz, jstring base_dir, jstring jlocalStateDir, - jbyteArray password, jboolean createBaseDir, + jbyteArray password, jbyteArray givenHash, + jobject returnedHash, + jboolean createBaseDir, jstring cipher) { - return cryfs_init(env, base_dir, jlocalStateDir, password, createBaseDir, cipher); + return cryfs_init(env, base_dir, jlocalStateDir, password, givenHash, returnedHash, createBaseDir, cipher); } JNIEXPORT jlong JNICALL diff --git a/app/src/main/res/layout/dialog_open_volume.xml b/app/src/main/res/layout/dialog_open_volume.xml index 23cbdf7..5ffb30c 100644 --- a/app/src/main/res/layout/dialog_open_volume.xml +++ b/app/src/main/res/layout/dialog_open_volume.xml @@ -17,16 +17,16 @@ - - + + \ No newline at end of file