From 3e64c3686f2c400d5f914b9498aea9354d3de9bd Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Mon, 8 Jul 2019 12:32:47 +0200 Subject: [PATCH] Use Android's hardware-backed keystore to store backup key This commit also disables the old UI as it does not work with the new key --- app/src/main/AndroidManifest.xml | 7 +-- .../stevesoltys/backup/security/KeyManager.kt | 48 +++++++++++++++++++ .../backup/settings/RecoveryCodeViewModel.kt | 5 +- .../backup/settings/SettingsManager.kt | 2 + .../backup/settings/SettingsViewModel.kt | 3 +- 5 files changed, 55 insertions(+), 10 deletions(-) create mode 100644 app/src/main/java/com/stevesoltys/backup/security/KeyManager.kt diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0bfb69e3..6a987969 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -35,12 +35,7 @@ - - - - - + android:label="@string/app_name"/> = 28) builder.setUnlockedDeviceRequired(true) + return builder.build() + } + +} diff --git a/app/src/main/java/com/stevesoltys/backup/settings/RecoveryCodeViewModel.kt b/app/src/main/java/com/stevesoltys/backup/settings/RecoveryCodeViewModel.kt index 24743d84..b5e1c0a7 100644 --- a/app/src/main/java/com/stevesoltys/backup/settings/RecoveryCodeViewModel.kt +++ b/app/src/main/java/com/stevesoltys/backup/settings/RecoveryCodeViewModel.kt @@ -1,10 +1,10 @@ package com.stevesoltys.backup.settings import android.app.Application -import android.util.ByteStringUtils import androidx.lifecycle.AndroidViewModel import com.stevesoltys.backup.LiveEvent import com.stevesoltys.backup.MutableLiveEvent +import com.stevesoltys.backup.security.KeyManager import io.github.novacrypto.bip39.* import io.github.novacrypto.bip39.Validation.InvalidChecksumException import io.github.novacrypto.bip39.Validation.InvalidWordCountException @@ -46,8 +46,7 @@ class RecoveryCodeViewModel(application: Application) : AndroidViewModel(applica } val mnemonic = input.joinToString(" ") val seed = SeedCalculator(JavaxPBKDF2WithHmacSHA512.INSTANCE).calculateSeed(mnemonic, "") - // TODO use KeyManager to store secret - setBackupPassword(getApplication(), ByteStringUtils.toHexString(seed)) + KeyManager.storeBackupKey(seed) recoveryCodeSaved.setEvent(true) } diff --git a/app/src/main/java/com/stevesoltys/backup/settings/SettingsManager.kt b/app/src/main/java/com/stevesoltys/backup/settings/SettingsManager.kt index 2aa413ec..51ddc5d1 100644 --- a/app/src/main/java/com/stevesoltys/backup/settings/SettingsManager.kt +++ b/app/src/main/java/com/stevesoltys/backup/settings/SettingsManager.kt @@ -25,6 +25,7 @@ fun getBackupFolderUri(context: Context): Uri? { * This is insecure and not supposed to be part of a release, * but rather an intermediate step towards a generated passphrase. */ +@Deprecated("Replaced by KeyManager#storeBackupKey()") fun setBackupPassword(context: Context, password: String) { getDefaultSharedPreferences(context) .edit() @@ -32,6 +33,7 @@ fun setBackupPassword(context: Context, password: String) { .apply() } +@Deprecated("Replaced by KeyManager#getBackupKey()") fun getBackupPassword(context: Context): String? { return getDefaultSharedPreferences(context).getString(PREF_KEY_BACKUP_PASSWORD, null) } diff --git a/app/src/main/java/com/stevesoltys/backup/settings/SettingsViewModel.kt b/app/src/main/java/com/stevesoltys/backup/settings/SettingsViewModel.kt index a49608f9..26bec197 100644 --- a/app/src/main/java/com/stevesoltys/backup/settings/SettingsViewModel.kt +++ b/app/src/main/java/com/stevesoltys/backup/settings/SettingsViewModel.kt @@ -5,12 +5,13 @@ import android.content.Intent import android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION import android.content.Intent.FLAG_GRANT_WRITE_URI_PERMISSION import androidx.lifecycle.AndroidViewModel +import com.stevesoltys.backup.security.KeyManager class SettingsViewModel(application: Application) : AndroidViewModel(application) { private val app = application - fun recoveryCodeIsSet() = getBackupPassword(getApplication()) != null + fun recoveryCodeIsSet() = KeyManager.hasBackupKey() fun locationIsSet() = getBackupFolderUri(getApplication()) != null fun handleChooseFolderResult(result: Intent?) {