aboutsummaryrefslogtreecommitdiff
path: root/crypto-pgpainless/src/main/kotlin
diff options
context:
space:
mode:
authorHarsh Shandilya <me@msfjarvis.dev>2022-07-17 15:37:54 +0530
committerHarsh Shandilya <me@msfjarvis.dev>2022-07-17 22:38:27 +0530
commitb9f4da71ea057df11c9da4ba41ce2e1836de2d51 (patch)
treee38e27946589e49d612f882e199a186a7118166a /crypto-pgpainless/src/main/kotlin
parent236c2719fa8496a6c3b3ecc2c75d86a798a2d617 (diff)
crypto-pgpainless: allow updating existing keys automatically for specific cases
Diffstat (limited to 'crypto-pgpainless/src/main/kotlin')
-rw-r--r--crypto-pgpainless/src/main/kotlin/app/passwordstore/crypto/PGPKeyManager.kt20
1 files changed, 19 insertions, 1 deletions
diff --git a/crypto-pgpainless/src/main/kotlin/app/passwordstore/crypto/PGPKeyManager.kt b/crypto-pgpainless/src/main/kotlin/app/passwordstore/crypto/PGPKeyManager.kt
index a80b5dcb..b834164d 100644
--- a/crypto-pgpainless/src/main/kotlin/app/passwordstore/crypto/PGPKeyManager.kt
+++ b/crypto-pgpainless/src/main/kotlin/app/passwordstore/crypto/PGPKeyManager.kt
@@ -21,6 +21,9 @@ import java.io.File
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.withContext
+import org.bouncycastle.openpgp.PGPPublicKeyRing
+import org.bouncycastle.openpgp.PGPSecretKeyRing
+import org.pgpainless.PGPainless
import org.pgpainless.util.selection.userid.SelectUserId
public class PGPKeyManager
@@ -36,9 +39,24 @@ constructor(
withContext(dispatcher) {
runSuspendCatching {
if (!keyDirExists()) throw KeyDirectoryUnavailableException
- if (tryParseKeyring(key) == null) throw InvalidKeyException
+ val incomingKeyRing = tryParseKeyring(key) ?: throw InvalidKeyException
val keyFile = File(keyDir, "${tryGetId(key)}.$KEY_EXTENSION")
if (keyFile.exists()) {
+ val existingKeyBytes = keyFile.readBytes()
+ val existingKeyRing =
+ tryParseKeyring(PGPKey(existingKeyBytes)) ?: throw InvalidKeyException
+ when {
+ existingKeyRing is PGPPublicKeyRing && incomingKeyRing is PGPSecretKeyRing -> {
+ keyFile.writeBytes(key.contents)
+ return@runSuspendCatching key
+ }
+ existingKeyRing is PGPPublicKeyRing && incomingKeyRing is PGPPublicKeyRing -> {
+ val updatedPublicKey = PGPainless.mergeCertificate(existingKeyRing, incomingKeyRing)
+ val keyBytes = PGPainless.asciiArmor(updatedPublicKey).encodeToByteArray()
+ keyFile.writeBytes(keyBytes)
+ return@runSuspendCatching key
+ }
+ }
// Check for replace flag first and if it is false, throw an error
if (!replace)
throw KeyAlreadyExistsException(