diff --git a/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/ChangeKeyPasswordImpl.kt b/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/ChangeKeyPasswordImpl.kt index a63d73ed..f8b66896 100644 --- a/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/ChangeKeyPasswordImpl.kt +++ b/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/ChangeKeyPasswordImpl.kt @@ -10,7 +10,6 @@ import java.io.OutputStream import org.bouncycastle.openpgp.PGPException import org.bouncycastle.openpgp.PGPSecretKeyRingCollection import org.pgpainless.PGPainless -import org.pgpainless.bouncycastle.extensions.openPgpFingerprint import org.pgpainless.exception.MissingPassphraseException import org.pgpainless.key.protection.SecretKeyRingProtector import org.pgpainless.key.util.KeyRingUtils @@ -29,30 +28,30 @@ class ChangeKeyPasswordImpl(private val api: PGPainless) : ChangeKeyPassword { override fun keys(keys: InputStream): Ready { val newProtector = SecretKeyRingProtector.unlockAnyKeyWith(newPassphrase) - val secretKeysCollection = + val secretKeys = try { - KeyReader.readSecretKeys(keys, true) + KeyReader(api).readSecretKeys(keys, true) } catch (e: IOException) { throw SOPGPException.BadData(e) } val updatedSecretKeys = - secretKeysCollection - .map { secretKeys -> - oldProtector.addSecretKey(secretKeys) + secretKeys + .map { + oldProtector.addSecretKey(it) try { return@map KeyRingUtils.changePassphrase( - null, secretKeys, oldProtector, newProtector) + null, it.pgpSecretKeyRing, oldProtector, newProtector) } catch (e: MissingPassphraseException) { throw SOPGPException.KeyIsProtected( - "Cannot unlock key ${secretKeys.openPgpFingerprint}", e) + "Cannot unlock key ${it.keyIdentifier}", e) } catch (e: PGPException) { if (e.message?.contains("Exception decrypting key") == true) { throw SOPGPException.KeyIsProtected( - "Cannot unlock key ${secretKeys.openPgpFingerprint}", e) + "Cannot unlock key ${it.keyIdentifier}", e) } throw RuntimeException( - "Cannot change passphrase of key ${secretKeys.openPgpFingerprint}", e) + "Cannot change passphrase of key ${it.keyIdentifier}", e) } } .let { PGPSecretKeyRingCollection(it) } diff --git a/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/DecryptImpl.kt b/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/DecryptImpl.kt index 26c372a5..fad50c5b 100644 --- a/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/DecryptImpl.kt +++ b/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/DecryptImpl.kt @@ -92,11 +92,11 @@ class DecryptImpl(private val api: PGPainless) : Decrypt { } override fun verifyWithCert(cert: InputStream): Decrypt = apply { - KeyReader.readPublicKeys(cert, true).let { consumerOptions.addVerificationCerts(it) } + consumerOptions.addVerificationCerts(KeyReader(api).readPublicKeys(cert, true)) } override fun withKey(key: InputStream): Decrypt = apply { - KeyReader.readSecretKeys(key, true).forEach { + KeyReader(api).readSecretKeys(key, true).forEach { protector.addSecretKey(it) consumerOptions.addDecryptionKey(it, protector) } diff --git a/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/DetachedSignImpl.kt b/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/DetachedSignImpl.kt index a7271740..26548c89 100644 --- a/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/DetachedSignImpl.kt +++ b/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/DetachedSignImpl.kt @@ -7,14 +7,13 @@ package org.pgpainless.sop import java.io.InputStream import java.io.OutputStream import org.bouncycastle.openpgp.PGPException -import org.bouncycastle.openpgp.PGPSecretKeyRing import org.bouncycastle.openpgp.PGPSignature +import org.bouncycastle.openpgp.api.OpenPGPKey import org.bouncycastle.util.io.Streams import org.pgpainless.PGPainless import org.pgpainless.algorithm.CompressionAlgorithm import org.pgpainless.algorithm.DocumentSignatureType import org.pgpainless.algorithm.HashAlgorithm -import org.pgpainless.bouncycastle.extensions.openPgpFingerprint import org.pgpainless.encryption_signing.ProducerOptions import org.pgpainless.encryption_signing.SigningOptions import org.pgpainless.exception.KeyException.MissingSecretKeyException @@ -34,7 +33,7 @@ class DetachedSignImpl(private val api: PGPainless) : DetachedSign { private val signingOptions = SigningOptions.get(api) private val protector = MatchMakingSecretKeyRingProtector() - private val signingKeys = mutableListOf<PGPSecretKeyRing>() + private val signingKeys = mutableListOf<OpenPGPKey>() private var armor = true private var mode = SignAs.binary @@ -44,13 +43,13 @@ class DetachedSignImpl(private val api: PGPainless) : DetachedSign { try { signingOptions.addDetachedSignature(protector, it, modeToSigType(mode)) } catch (e: UnacceptableSigningKeyException) { - throw SOPGPException.KeyCannotSign("Key ${it.openPgpFingerprint} cannot sign.", e) + throw SOPGPException.KeyCannotSign("Key ${it.keyIdentifier} cannot sign.", e) } catch (e: MissingSecretKeyException) { throw SOPGPException.KeyCannotSign( - "Key ${it.openPgpFingerprint} cannot sign. Missing secret key.", e) + "Key ${it.keyIdentifier} cannot sign. Missing secret key.", e) } catch (e: PGPException) { throw SOPGPException.KeyIsProtected( - "Key ${it.openPgpFingerprint} cannot be unlocked.", e) + "Key ${it.keyIdentifier} cannot be unlocked.", e) } } @@ -93,8 +92,8 @@ class DetachedSignImpl(private val api: PGPainless) : DetachedSign { } override fun key(key: InputStream): DetachedSign = apply { - KeyReader.readSecretKeys(key, true).forEach { - val info = api.inspect(api.toKey(it)) + KeyReader(api).readSecretKeys(key, true).forEach { + val info = api.inspect(it) if (!info.isUsableForSigning) { throw SOPGPException.KeyCannotSign( "Key ${info.fingerprint} does not have valid, signing capable subkeys.") diff --git a/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/DetachedVerifyImpl.kt b/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/DetachedVerifyImpl.kt index c73d30ac..1a252bfa 100644 --- a/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/DetachedVerifyImpl.kt +++ b/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/DetachedVerifyImpl.kt @@ -23,7 +23,7 @@ class DetachedVerifyImpl(private val api: PGPainless) : DetachedVerify { private val options = ConsumerOptions.get(api).forceNonOpenPgpData() override fun cert(cert: InputStream): DetachedVerify = apply { - options.addVerificationCerts(KeyReader.readPublicKeys(cert, true)) + options.addVerificationCerts(KeyReader(api).readPublicKeys(cert, true)) } override fun data(data: InputStream): List<Verification> { diff --git a/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/EncryptImpl.kt b/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/EncryptImpl.kt index a0534f56..556a9490 100644 --- a/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/EncryptImpl.kt +++ b/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/EncryptImpl.kt @@ -8,12 +8,11 @@ import java.io.IOException import java.io.InputStream import java.io.OutputStream import org.bouncycastle.openpgp.PGPException -import org.bouncycastle.openpgp.PGPSecretKeyRing +import org.bouncycastle.openpgp.api.OpenPGPKey import org.bouncycastle.util.io.Streams import org.pgpainless.PGPainless import org.pgpainless.algorithm.DocumentSignatureType import org.pgpainless.algorithm.StreamEncoding -import org.pgpainless.bouncycastle.extensions.openPgpFingerprint import org.pgpainless.encryption_signing.EncryptionOptions import org.pgpainless.encryption_signing.ProducerOptions import org.pgpainless.encryption_signing.SigningOptions @@ -40,7 +39,7 @@ class EncryptImpl(private val api: PGPainless) : Encrypt { private val encryptionOptions = EncryptionOptions.get(api) private var signingOptions: SigningOptions? = null - private val signingKeys = mutableListOf<PGPSecretKeyRing>() + private val signingKeys = mutableListOf<OpenPGPKey>() private val protector = MatchMakingSecretKeyRingProtector() private var profile = RFC4880_PROFILE.name @@ -69,9 +68,9 @@ class EncryptImpl(private val api: PGPainless) : Encrypt { try { signingOptions!!.addInlineSignature(protector, it, modeToSignatureType(mode)) } catch (e: UnacceptableSigningKeyException) { - throw SOPGPException.KeyCannotSign("Key ${it.openPgpFingerprint} cannot sign", e) + throw SOPGPException.KeyCannotSign("Key ${it.keyIdentifier} cannot sign", e) } catch (e: WrongPassphraseException) { - throw SOPGPException.KeyIsProtected("Cannot unlock key ${it.openPgpFingerprint}", e) + throw SOPGPException.KeyIsProtected("Cannot unlock key ${it.keyIdentifier}", e) } catch (e: PGPException) { throw SOPGPException.BadData(e) } @@ -105,14 +104,14 @@ class EncryptImpl(private val api: PGPainless) : Encrypt { } val signingKey = - KeyReader.readSecretKeys(key, true).singleOrNull() + KeyReader(api).readSecretKeys(key, true).singleOrNull() ?: throw SOPGPException.BadData( AssertionError( "Exactly one secret key at a time expected. Got zero or multiple instead.")) - val info = api.inspect(api.toKey(signingKey)) + val info = api.inspect(signingKey) if (info.signingSubkeys.isEmpty()) { - throw SOPGPException.KeyCannotSign("Key ${info.fingerprint} cannot sign.") + throw SOPGPException.KeyCannotSign("Key ${info.keyIdentifier} cannot sign.") } protector.addSecretKey(signingKey) @@ -121,7 +120,7 @@ class EncryptImpl(private val api: PGPainless) : Encrypt { override fun withCert(cert: InputStream): Encrypt = apply { try { - encryptionOptions.addRecipients(KeyReader.readPublicKeys(cert, true)) + KeyReader(api).readPublicKeys(cert, true).forEach { encryptionOptions.addRecipient(it) } } catch (e: UnacceptableEncryptionKeyException) { throw SOPGPException.CertCannotEncrypt(e.message ?: "Cert cannot encrypt", e) } catch (e: IOException) { diff --git a/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/ExtractCertImpl.kt b/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/ExtractCertImpl.kt index 426d5787..3a5993b4 100644 --- a/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/ExtractCertImpl.kt +++ b/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/ExtractCertImpl.kt @@ -18,8 +18,7 @@ class ExtractCertImpl(private val api: PGPainless) : ExtractCert { private var armor = true override fun key(keyInputStream: InputStream): Ready { - val certs = - KeyReader.readSecretKeys(keyInputStream, true).map { PGPainless.extractCertificate(it) } + val certs = KeyReader(api).readSecretKeys(keyInputStream, true).map { it.toCertificate() } return object : Ready() { override fun writeTo(outputStream: OutputStream) { @@ -27,17 +26,18 @@ class ExtractCertImpl(private val api: PGPainless) : ExtractCert { if (certs.size == 1) { val cert = certs[0] // This way we have a nice armor header with fingerprint and user-ids - val armorOut = ArmorUtils.toAsciiArmoredStream(cert, outputStream) - cert.encode(armorOut) + val armorOut = + ArmorUtils.toAsciiArmoredStream(cert.pgpKeyRing, outputStream) + armorOut.write(cert.encoded) armorOut.close() } else { // for multiple certs, add no info headers to the ASCII armor val armorOut = ArmoredOutputStreamFactory.get(outputStream) - certs.forEach { it.encode(armorOut) } + certs.forEach { armorOut.write(it.encoded) } armorOut.close() } } else { - certs.forEach { it.encode(outputStream) } + certs.forEach { outputStream.write(it.encoded) } } } } diff --git a/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/InlineSignImpl.kt b/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/InlineSignImpl.kt index 7f9cd0eb..c12c9b1e 100644 --- a/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/InlineSignImpl.kt +++ b/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/InlineSignImpl.kt @@ -8,13 +8,12 @@ import java.io.InputStream import java.io.OutputStream import java.lang.RuntimeException import org.bouncycastle.openpgp.PGPException -import org.bouncycastle.openpgp.PGPSecretKeyRing +import org.bouncycastle.openpgp.api.OpenPGPKey import org.bouncycastle.util.io.Streams import org.pgpainless.PGPainless import org.pgpainless.algorithm.CompressionAlgorithm import org.pgpainless.algorithm.DocumentSignatureType import org.pgpainless.algorithm.StreamEncoding -import org.pgpainless.bouncycastle.extensions.openPgpFingerprint import org.pgpainless.encryption_signing.ProducerOptions import org.pgpainless.encryption_signing.SigningOptions import org.pgpainless.exception.KeyException.MissingSecretKeyException @@ -31,7 +30,7 @@ class InlineSignImpl(private val api: PGPainless) : InlineSign { private val signingOptions = SigningOptions.get(api) private val protector = MatchMakingSecretKeyRingProtector() - private val signingKeys = mutableListOf<PGPSecretKeyRing>() + private val signingKeys = mutableListOf<OpenPGPKey>() private var armor = true private var mode = InlineSignAs.binary @@ -45,14 +44,14 @@ class InlineSignImpl(private val api: PGPainless) : InlineSign { signingOptions.addInlineSignature(protector, key, modeToSigType(mode)) } } catch (e: UnacceptableSigningKeyException) { - throw SOPGPException.KeyCannotSign("Key ${key.openPgpFingerprint} cannot sign.", e) + throw SOPGPException.KeyCannotSign("Key ${key.keyIdentifier} cannot sign.", e) } catch (e: MissingSecretKeyException) { throw SOPGPException.KeyCannotSign( - "Key ${key.openPgpFingerprint} does not have the secret signing key component available.", + "Key ${key.keyIdentifier} does not have the secret signing key component available.", e) } catch (e: PGPException) { throw SOPGPException.KeyIsProtected( - "Key ${key.openPgpFingerprint} cannot be unlocked.", e) + "Key ${key.keyIdentifier} cannot be unlocked.", e) } } @@ -97,11 +96,11 @@ class InlineSignImpl(private val api: PGPainless) : InlineSign { } override fun key(key: InputStream): InlineSign = apply { - KeyReader.readSecretKeys(key, true).forEach { - val info = api.inspect(api.toKey(it)) + KeyReader(api).readSecretKeys(key, true).forEach { + val info = api.inspect(it) if (!info.isUsableForSigning) { throw SOPGPException.KeyCannotSign( - "Key ${info.fingerprint} does not have valid, signing capable subkeys.") + "Key ${info.keyIdentifier} does not have valid, signing capable subkeys.") } protector.addSecretKey(it) signingKeys.add(it) diff --git a/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/InlineVerifyImpl.kt b/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/InlineVerifyImpl.kt index bfc3dd37..332c1445 100644 --- a/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/InlineVerifyImpl.kt +++ b/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/InlineVerifyImpl.kt @@ -24,7 +24,7 @@ class InlineVerifyImpl(private val api: PGPainless) : InlineVerify { private val options = ConsumerOptions.get(api) override fun cert(cert: InputStream): InlineVerify = apply { - options.addVerificationCerts(KeyReader.readPublicKeys(cert, true)) + options.addVerificationCerts(KeyReader(api).readPublicKeys(cert, true)) } override fun data(data: InputStream): ReadyWithResult<List<Verification>> { diff --git a/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/KeyReader.kt b/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/KeyReader.kt index 2ce608ca..2ea36137 100644 --- a/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/KeyReader.kt +++ b/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/KeyReader.kt @@ -7,71 +7,63 @@ package org.pgpainless.sop import java.io.IOException import java.io.InputStream import org.bouncycastle.openpgp.PGPException -import org.bouncycastle.openpgp.PGPPublicKeyRingCollection import org.bouncycastle.openpgp.PGPRuntimeOperationException -import org.bouncycastle.openpgp.PGPSecretKeyRingCollection +import org.bouncycastle.openpgp.api.OpenPGPCertificate +import org.bouncycastle.openpgp.api.OpenPGPKey import org.pgpainless.PGPainless import sop.exception.SOPGPException /** Reader for OpenPGP keys and certificates with error matching according to the SOP spec. */ -class KeyReader { +class KeyReader(val api: PGPainless = PGPainless.getInstance()) { - companion object { - @JvmStatic - fun readSecretKeys( - keyInputStream: InputStream, - requireContent: Boolean - ): PGPSecretKeyRingCollection { - val keys = - try { - PGPainless.readKeyRing().secretKeyRingCollection(keyInputStream) - } catch (e: IOException) { - if (e.message == null) { - throw e - } - if (e.message!!.startsWith("unknown object in stream:") || - e.message!!.startsWith("invalid header encountered")) { - throw SOPGPException.BadData(e) - } + fun readSecretKeys(keyInputStream: InputStream, requireContent: Boolean): List<OpenPGPKey> { + val keys = + try { + api.readKey().parseKeys(keyInputStream) + } catch (e: IOException) { + if (e.message == null) { throw e } - if (requireContent && keys.none()) { - throw SOPGPException.BadData(PGPException("No key data found.")) - } - - return keys - } - - @JvmStatic - fun readPublicKeys( - certIn: InputStream, - requireContent: Boolean - ): PGPPublicKeyRingCollection { - val certs = - try { - PGPainless.readKeyRing().keyRingCollection(certIn, true) - } catch (e: IOException) { - if (e.message == null) { - throw e - } - if (e.message!!.startsWith("unknown object in stream:") || - e.message!!.startsWith("invalid header encountered")) { - throw SOPGPException.BadData(e) - } - throw e - } catch (e: PGPRuntimeOperationException) { + if (e.message!!.startsWith("unknown object in stream:") || + e.message!!.startsWith("invalid header encountered") || + e.message!!.startsWith("Encountered unexpected packet:")) { throw SOPGPException.BadData(e) } - - if (certs.pgpSecretKeyRingCollection.any()) { - throw SOPGPException.BadData( - "Secret key components encountered, while certificates were expected.") + throw e } - - if (requireContent && certs.pgpPublicKeyRingCollection.none()) { - throw SOPGPException.BadData(PGPException("No cert data found.")) - } - return certs.pgpPublicKeyRingCollection + if (requireContent && keys.none()) { + throw SOPGPException.BadData(PGPException("No key data found.")) } + + return keys + } + + fun readPublicKeys(certIn: InputStream, requireContent: Boolean): List<OpenPGPCertificate> { + val certs = + try { + api.readKey().parseKeysOrCertificates(certIn) + } catch (e: IOException) { + if (e.message == null) { + throw e + } + if (e.message!!.startsWith("unknown object in stream:") || + e.message!!.startsWith("invalid header encountered")) { + throw SOPGPException.BadData(e) + } + throw e + } catch (e: PGPRuntimeOperationException) { + throw SOPGPException.BadData(e) + } + + if (certs.any { it.isSecretKey }) { + throw SOPGPException.BadData( + "Secret key components encountered, while certificates were expected.") + } + + if (requireContent && certs.isEmpty()) { + throw SOPGPException.BadData("No certificate data found.") + } + + return certs } } diff --git a/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/MatchMakingSecretKeyRingProtector.kt b/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/MatchMakingSecretKeyRingProtector.kt index d4a4cb7e..21ed794b 100644 --- a/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/MatchMakingSecretKeyRingProtector.kt +++ b/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/MatchMakingSecretKeyRingProtector.kt @@ -39,7 +39,7 @@ class MatchMakingSecretKeyRingProtector : SecretKeyRingProtector { keys.forEach { key -> for (subkey in key) { - if (protector.hasPassphrase(subkey.keyID)) { + if (protector.hasPassphrase(subkey.keyIdentifier)) { continue } @@ -50,6 +50,8 @@ class MatchMakingSecretKeyRingProtector : SecretKeyRingProtector { } } + fun addSecretKey(key: OpenPGPKey) = addSecretKey(key.pgpSecretKeyRing) + fun addSecretKey(key: PGPSecretKeyRing) = apply { if (!keys.add(key)) { return@apply diff --git a/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/RevokeKeyImpl.kt b/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/RevokeKeyImpl.kt index 67dd36a2..40b5103f 100644 --- a/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/RevokeKeyImpl.kt +++ b/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/RevokeKeyImpl.kt @@ -12,7 +12,6 @@ import org.bouncycastle.openpgp.PGPException import org.bouncycastle.openpgp.PGPPublicKeyRingCollection import org.bouncycastle.openpgp.api.OpenPGPCertificate import org.pgpainless.PGPainless -import org.pgpainless.bouncycastle.extensions.openPgpFingerprint import org.pgpainless.bouncycastle.extensions.toOpenPGPCertificate import org.pgpainless.exception.WrongPassphraseException import org.pgpainless.key.util.KeyRingUtils @@ -30,29 +29,28 @@ class RevokeKeyImpl(private val api: PGPainless) : RevokeKey { private var armor = true override fun keys(keys: InputStream): Ready { - val secretKeyRings = + val secretKeys = try { - KeyReader.readSecretKeys(keys, true) + KeyReader(api).readSecretKeys(keys, true) } catch (e: IOException) { throw SOPGPException.BadData("Cannot decode secret keys.", e) } - secretKeyRings.forEach { protector.addSecretKey(it) } + secretKeys.forEach { protector.addSecretKey(it) } val revocationCertificates = mutableListOf<OpenPGPCertificate>() - secretKeyRings.forEach { secretKeys -> - val openPGPKey = api.toKey(secretKeys) - val editor = api.modify(openPGPKey) + secretKeys.forEach { + val editor = api.modify(it) try { val attributes = RevocationAttributes.createKeyRevocation() .withReason(RevocationAttributes.Reason.NO_REASON) .withoutDescription() - if (openPGPKey.primaryKey.version == 6) { + if (it.primaryKey.version == 6) { revocationCertificates.add( editor.createMinimalRevocationCertificate(protector, attributes)) } else { - val certificate = openPGPKey.toCertificate() + val certificate = it.toCertificate() val revocation = editor.createRevocation(protector, attributes) revocationCertificates.add( KeyRingUtils.injectCertification( @@ -61,11 +59,10 @@ class RevokeKeyImpl(private val api: PGPainless) : RevokeKey { } } catch (e: WrongPassphraseException) { throw SOPGPException.KeyIsProtected( - "Missing or wrong passphrase for key ${secretKeys.openPgpFingerprint}", e) + "Missing or wrong passphrase for key ${it.keyIdentifier}", e) } catch (e: PGPException) { throw RuntimeException( - "Cannot generate revocation certificate for key ${secretKeys.openPgpFingerprint}", - e) + "Cannot generate revocation certificate for key ${it.keyIdentifier}", e) } }