From a716ac9514577110481434ac2afdc64d97e02375 Mon Sep 17 00:00:00 2001 From: Tad Fisher Date: Sun, 9 Oct 2022 16:11:28 -0700 Subject: Quick and dirty hardware key import --- .../passwordstore/ui/pgp/PGPKeyImportActivity.kt | 37 ++++++++++++++++++---- app/src/main/res/values/strings.xml | 3 ++ 2 files changed, 34 insertions(+), 6 deletions(-) (limited to 'app') 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) { when (result) { is Ok -> { @@ -85,8 +103,8 @@ class PGPKeyImportActivity : AppCompatActivity() { .setCancelable(false) .show() } - is Err -> { - if (result.error is KeyAlreadyExistsException && lastBytes != null) { + is Err -> 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 @@ Select\nGPG Key Select a GPG key to initialize your store with Select key + Pair hardware key Potentially incorrect URL @@ -358,6 +359,8 @@ Create new password or folder Failed to import PGP key An existing key with this ID was found, do you want to replace it? + No secret PGP key + This is a public key. Would you like to pair a hardware security device? Successfully imported PGP key The key ID of the imported key is given below, please review it for correctness:\n%1$s PGP settings -- cgit v1.2.3