diff options
author | Tad Fisher <tadfisher@gmail.com> | 2022-10-09 16:11:28 -0700 |
---|---|---|
committer | Tad Fisher <tadfisher@gmail.com> | 2022-10-09 16:17:25 -0700 |
commit | a716ac9514577110481434ac2afdc64d97e02375 (patch) | |
tree | 92c310139cef2032d2c9b809648e92f50e24d10f /app | |
parent | 75040136ae5ca6108335975430b411f8a560d0ba (diff) |
Quick and dirty hardware key import
Diffstat (limited to 'app')
-rw-r--r-- | app/src/main/java/app/passwordstore/ui/pgp/PGPKeyImportActivity.kt | 37 | ||||
-rw-r--r-- | app/src/main/res/values/strings.xml | 3 |
2 files changed, 34 insertions, 6 deletions
diff --git a/app/src/main/java/app/passwordstore/ui/pgp/PGPKeyImportActivity.kt b/app/src/main/java/app/passwordstore/ui/pgp/PGPKeyImportActivity.kt index 4c9060f7..b3edb1a9 100644 --- a/app/src/main/java/app/passwordstore/ui/pgp/PGPKeyImportActivity.kt +++ b/app/src/main/java/app/passwordstore/ui/pgp/PGPKeyImportActivity.kt @@ -7,20 +7,26 @@ package app.passwordstore.ui.pgp import android.os.Bundle +import androidx.activity.ComponentActivity import androidx.activity.result.contract.ActivityResultContracts.OpenDocument import androidx.appcompat.app.AppCompatActivity +import androidx.lifecycle.lifecycleScope import app.passwordstore.R +import app.passwordstore.crypto.HWSecurityDeviceHandler import app.passwordstore.crypto.KeyUtils.tryGetId import app.passwordstore.crypto.PGPKey import app.passwordstore.crypto.PGPKeyManager import app.passwordstore.crypto.errors.KeyAlreadyExistsException +import app.passwordstore.crypto.errors.NoSecretKeyException import com.github.michaelbull.result.Err import com.github.michaelbull.result.Ok import com.github.michaelbull.result.Result +import com.github.michaelbull.result.getOrThrow import com.github.michaelbull.result.runCatching import com.google.android.material.dialog.MaterialAlertDialogBuilder import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject +import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking @AndroidEntryPoint @@ -32,9 +38,10 @@ class PGPKeyImportActivity : AppCompatActivity() { */ private var lastBytes: ByteArray? = null @Inject lateinit var keyManager: PGPKeyManager + @Inject lateinit var deviceHandler: HWSecurityDeviceHandler private val pgpKeyImportAction = - registerForActivityResult(OpenDocument()) { uri -> + (this as ComponentActivity).registerForActivityResult(OpenDocument()) { uri -> runCatching { if (uri == null) { return@runCatching null @@ -50,6 +57,7 @@ class PGPKeyImportActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + pgpKeyImportAction.launch(arrayOf("*/*")) } @@ -68,6 +76,16 @@ class PGPKeyImportActivity : AppCompatActivity() { return key } + private fun pairDevice(bytes: ByteArray) { + lifecycleScope.launch { + val result = keyManager.addKey( + deviceHandler.pairWithPublicKey(PGPKey(bytes)).getOrThrow(), + replace = true + ) + handleImportResult(result) + } + } + private fun handleImportResult(result: Result<PGPKey?, Throwable>) { when (result) { is Ok<PGPKey?> -> { @@ -85,8 +103,8 @@ class PGPKeyImportActivity : AppCompatActivity() { .setCancelable(false) .show() } - is Err<Throwable> -> { - if (result.error is KeyAlreadyExistsException && lastBytes != null) { + is Err<Throwable> -> when { + result.error is KeyAlreadyExistsException && lastBytes != null -> MaterialAlertDialogBuilder(this) .setTitle(getString(R.string.pgp_key_import_failed)) .setMessage(getString(R.string.pgp_key_import_failed_replace_message)) @@ -96,14 +114,21 @@ class PGPKeyImportActivity : AppCompatActivity() { .setNegativeButton(R.string.dialog_no) { _, _ -> finish() } .setCancelable(false) .show() - } else { + result.error is NoSecretKeyException && lastBytes != null -> + MaterialAlertDialogBuilder(this) + .setTitle(R.string.pgp_key_import_failed_no_secret) + .setMessage(R.string.pgp_key_import_failed_no_secret_message) + .setPositiveButton(R.string.dialog_yes) { _, _ -> pairDevice(lastBytes!!) } + .setNegativeButton(R.string.dialog_no) { _, _ -> finish() } + .setCancelable(false) + .show() + else -> MaterialAlertDialogBuilder(this) .setTitle(getString(R.string.pgp_key_import_failed)) - .setMessage(result.error.message) + .setMessage(result.error.message + "\n" + result.error.stackTraceToString()) .setPositiveButton(android.R.string.ok) { _, _ -> finish() } .setCancelable(false) .show() - } } } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9997f6aa..63f47f27 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -332,6 +332,7 @@ <string name="select_gpg_key_title">Select\nGPG Key</string> <string name="select_gpg_key_message">Select a GPG key to initialize your store with</string> <string name="gpg_key_select">Select key</string> + <string name="pair_hardware_key">Pair hardware key</string> <!-- SSH port validation --> <string name="ssh_scheme_needed_title">Potentially incorrect URL</string> @@ -358,6 +359,8 @@ <string name="password_list_fab_content_description">Create new password or folder</string> <string name="pgp_key_import_failed">Failed to import PGP key</string> <string name="pgp_key_import_failed_replace_message">An existing key with this ID was found, do you want to replace it?</string> + <string name="pgp_key_import_failed_no_secret">No secret PGP key</string> + <string name="pgp_key_import_failed_no_secret_message">This is a public key. Would you like to pair a hardware security device?</string> <string name="pgp_key_import_succeeded">Successfully imported PGP key</string> <string name="pgp_key_import_succeeded_message">The key ID of the imported key is given below, please review it for correctness:\n%1$s</string> <string name="pref_category_pgp_title">PGP settings</string> |