1
0
Fork 0
mirror of https://github.com/pgpainless/pgpainless.git synced 2025-09-09 10:19:39 +02:00

Remove usage of deprecated methods in SOP implementations

This commit is contained in:
Paul Schaub 2025-03-28 16:02:36 +01:00
parent aeed0e736b
commit 85c0286041
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
11 changed files with 100 additions and 113 deletions

View file

@ -10,7 +10,6 @@ import java.io.OutputStream
import org.bouncycastle.openpgp.PGPException import org.bouncycastle.openpgp.PGPException
import org.bouncycastle.openpgp.PGPSecretKeyRingCollection import org.bouncycastle.openpgp.PGPSecretKeyRingCollection
import org.pgpainless.PGPainless import org.pgpainless.PGPainless
import org.pgpainless.bouncycastle.extensions.openPgpFingerprint
import org.pgpainless.exception.MissingPassphraseException import org.pgpainless.exception.MissingPassphraseException
import org.pgpainless.key.protection.SecretKeyRingProtector import org.pgpainless.key.protection.SecretKeyRingProtector
import org.pgpainless.key.util.KeyRingUtils import org.pgpainless.key.util.KeyRingUtils
@ -29,30 +28,30 @@ class ChangeKeyPasswordImpl(private val api: PGPainless) : ChangeKeyPassword {
override fun keys(keys: InputStream): Ready { override fun keys(keys: InputStream): Ready {
val newProtector = SecretKeyRingProtector.unlockAnyKeyWith(newPassphrase) val newProtector = SecretKeyRingProtector.unlockAnyKeyWith(newPassphrase)
val secretKeysCollection = val secretKeys =
try { try {
KeyReader.readSecretKeys(keys, true) KeyReader(api).readSecretKeys(keys, true)
} catch (e: IOException) { } catch (e: IOException) {
throw SOPGPException.BadData(e) throw SOPGPException.BadData(e)
} }
val updatedSecretKeys = val updatedSecretKeys =
secretKeysCollection secretKeys
.map { secretKeys -> .map {
oldProtector.addSecretKey(secretKeys) oldProtector.addSecretKey(it)
try { try {
return@map KeyRingUtils.changePassphrase( return@map KeyRingUtils.changePassphrase(
null, secretKeys, oldProtector, newProtector) null, it.pgpSecretKeyRing, oldProtector, newProtector)
} catch (e: MissingPassphraseException) { } catch (e: MissingPassphraseException) {
throw SOPGPException.KeyIsProtected( throw SOPGPException.KeyIsProtected(
"Cannot unlock key ${secretKeys.openPgpFingerprint}", e) "Cannot unlock key ${it.keyIdentifier}", e)
} catch (e: PGPException) { } catch (e: PGPException) {
if (e.message?.contains("Exception decrypting key") == true) { if (e.message?.contains("Exception decrypting key") == true) {
throw SOPGPException.KeyIsProtected( throw SOPGPException.KeyIsProtected(
"Cannot unlock key ${secretKeys.openPgpFingerprint}", e) "Cannot unlock key ${it.keyIdentifier}", e)
} }
throw RuntimeException( throw RuntimeException(
"Cannot change passphrase of key ${secretKeys.openPgpFingerprint}", e) "Cannot change passphrase of key ${it.keyIdentifier}", e)
} }
} }
.let { PGPSecretKeyRingCollection(it) } .let { PGPSecretKeyRingCollection(it) }

View file

@ -92,11 +92,11 @@ class DecryptImpl(private val api: PGPainless) : Decrypt {
} }
override fun verifyWithCert(cert: InputStream): Decrypt = apply { 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 { override fun withKey(key: InputStream): Decrypt = apply {
KeyReader.readSecretKeys(key, true).forEach { KeyReader(api).readSecretKeys(key, true).forEach {
protector.addSecretKey(it) protector.addSecretKey(it)
consumerOptions.addDecryptionKey(it, protector) consumerOptions.addDecryptionKey(it, protector)
} }

View file

@ -7,14 +7,13 @@ package org.pgpainless.sop
import java.io.InputStream import java.io.InputStream
import java.io.OutputStream import java.io.OutputStream
import org.bouncycastle.openpgp.PGPException import org.bouncycastle.openpgp.PGPException
import org.bouncycastle.openpgp.PGPSecretKeyRing
import org.bouncycastle.openpgp.PGPSignature import org.bouncycastle.openpgp.PGPSignature
import org.bouncycastle.openpgp.api.OpenPGPKey
import org.bouncycastle.util.io.Streams import org.bouncycastle.util.io.Streams
import org.pgpainless.PGPainless import org.pgpainless.PGPainless
import org.pgpainless.algorithm.CompressionAlgorithm import org.pgpainless.algorithm.CompressionAlgorithm
import org.pgpainless.algorithm.DocumentSignatureType import org.pgpainless.algorithm.DocumentSignatureType
import org.pgpainless.algorithm.HashAlgorithm import org.pgpainless.algorithm.HashAlgorithm
import org.pgpainless.bouncycastle.extensions.openPgpFingerprint
import org.pgpainless.encryption_signing.ProducerOptions import org.pgpainless.encryption_signing.ProducerOptions
import org.pgpainless.encryption_signing.SigningOptions import org.pgpainless.encryption_signing.SigningOptions
import org.pgpainless.exception.KeyException.MissingSecretKeyException 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 signingOptions = SigningOptions.get(api)
private val protector = MatchMakingSecretKeyRingProtector() private val protector = MatchMakingSecretKeyRingProtector()
private val signingKeys = mutableListOf<PGPSecretKeyRing>() private val signingKeys = mutableListOf<OpenPGPKey>()
private var armor = true private var armor = true
private var mode = SignAs.binary private var mode = SignAs.binary
@ -44,13 +43,13 @@ class DetachedSignImpl(private val api: PGPainless) : DetachedSign {
try { try {
signingOptions.addDetachedSignature(protector, it, modeToSigType(mode)) signingOptions.addDetachedSignature(protector, it, modeToSigType(mode))
} catch (e: UnacceptableSigningKeyException) { } catch (e: UnacceptableSigningKeyException) {
throw SOPGPException.KeyCannotSign("Key ${it.openPgpFingerprint} cannot sign.", e) throw SOPGPException.KeyCannotSign("Key ${it.keyIdentifier} cannot sign.", e)
} catch (e: MissingSecretKeyException) { } catch (e: MissingSecretKeyException) {
throw SOPGPException.KeyCannotSign( throw SOPGPException.KeyCannotSign(
"Key ${it.openPgpFingerprint} cannot sign. Missing secret key.", e) "Key ${it.keyIdentifier} cannot sign. Missing secret key.", e)
} catch (e: PGPException) { } catch (e: PGPException) {
throw SOPGPException.KeyIsProtected( 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 { override fun key(key: InputStream): DetachedSign = apply {
KeyReader.readSecretKeys(key, true).forEach { KeyReader(api).readSecretKeys(key, true).forEach {
val info = api.inspect(api.toKey(it)) val info = api.inspect(it)
if (!info.isUsableForSigning) { if (!info.isUsableForSigning) {
throw SOPGPException.KeyCannotSign( throw SOPGPException.KeyCannotSign(
"Key ${info.fingerprint} does not have valid, signing capable subkeys.") "Key ${info.fingerprint} does not have valid, signing capable subkeys.")

View file

@ -23,7 +23,7 @@ class DetachedVerifyImpl(private val api: PGPainless) : DetachedVerify {
private val options = ConsumerOptions.get(api).forceNonOpenPgpData() private val options = ConsumerOptions.get(api).forceNonOpenPgpData()
override fun cert(cert: InputStream): DetachedVerify = apply { 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> { override fun data(data: InputStream): List<Verification> {

View file

@ -8,12 +8,11 @@ import java.io.IOException
import java.io.InputStream import java.io.InputStream
import java.io.OutputStream import java.io.OutputStream
import org.bouncycastle.openpgp.PGPException import org.bouncycastle.openpgp.PGPException
import org.bouncycastle.openpgp.PGPSecretKeyRing import org.bouncycastle.openpgp.api.OpenPGPKey
import org.bouncycastle.util.io.Streams import org.bouncycastle.util.io.Streams
import org.pgpainless.PGPainless import org.pgpainless.PGPainless
import org.pgpainless.algorithm.DocumentSignatureType import org.pgpainless.algorithm.DocumentSignatureType
import org.pgpainless.algorithm.StreamEncoding import org.pgpainless.algorithm.StreamEncoding
import org.pgpainless.bouncycastle.extensions.openPgpFingerprint
import org.pgpainless.encryption_signing.EncryptionOptions import org.pgpainless.encryption_signing.EncryptionOptions
import org.pgpainless.encryption_signing.ProducerOptions import org.pgpainless.encryption_signing.ProducerOptions
import org.pgpainless.encryption_signing.SigningOptions import org.pgpainless.encryption_signing.SigningOptions
@ -40,7 +39,7 @@ class EncryptImpl(private val api: PGPainless) : Encrypt {
private val encryptionOptions = EncryptionOptions.get(api) private val encryptionOptions = EncryptionOptions.get(api)
private var signingOptions: SigningOptions? = null private var signingOptions: SigningOptions? = null
private val signingKeys = mutableListOf<PGPSecretKeyRing>() private val signingKeys = mutableListOf<OpenPGPKey>()
private val protector = MatchMakingSecretKeyRingProtector() private val protector = MatchMakingSecretKeyRingProtector()
private var profile = RFC4880_PROFILE.name private var profile = RFC4880_PROFILE.name
@ -69,9 +68,9 @@ class EncryptImpl(private val api: PGPainless) : Encrypt {
try { try {
signingOptions!!.addInlineSignature(protector, it, modeToSignatureType(mode)) signingOptions!!.addInlineSignature(protector, it, modeToSignatureType(mode))
} catch (e: UnacceptableSigningKeyException) { } catch (e: UnacceptableSigningKeyException) {
throw SOPGPException.KeyCannotSign("Key ${it.openPgpFingerprint} cannot sign", e) throw SOPGPException.KeyCannotSign("Key ${it.keyIdentifier} cannot sign", e)
} catch (e: WrongPassphraseException) { } catch (e: WrongPassphraseException) {
throw SOPGPException.KeyIsProtected("Cannot unlock key ${it.openPgpFingerprint}", e) throw SOPGPException.KeyIsProtected("Cannot unlock key ${it.keyIdentifier}", e)
} catch (e: PGPException) { } catch (e: PGPException) {
throw SOPGPException.BadData(e) throw SOPGPException.BadData(e)
} }
@ -105,14 +104,14 @@ class EncryptImpl(private val api: PGPainless) : Encrypt {
} }
val signingKey = val signingKey =
KeyReader.readSecretKeys(key, true).singleOrNull() KeyReader(api).readSecretKeys(key, true).singleOrNull()
?: throw SOPGPException.BadData( ?: throw SOPGPException.BadData(
AssertionError( AssertionError(
"Exactly one secret key at a time expected. Got zero or multiple instead.")) "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()) { if (info.signingSubkeys.isEmpty()) {
throw SOPGPException.KeyCannotSign("Key ${info.fingerprint} cannot sign.") throw SOPGPException.KeyCannotSign("Key ${info.keyIdentifier} cannot sign.")
} }
protector.addSecretKey(signingKey) protector.addSecretKey(signingKey)
@ -121,7 +120,7 @@ class EncryptImpl(private val api: PGPainless) : Encrypt {
override fun withCert(cert: InputStream): Encrypt = apply { override fun withCert(cert: InputStream): Encrypt = apply {
try { try {
encryptionOptions.addRecipients(KeyReader.readPublicKeys(cert, true)) KeyReader(api).readPublicKeys(cert, true).forEach { encryptionOptions.addRecipient(it) }
} catch (e: UnacceptableEncryptionKeyException) { } catch (e: UnacceptableEncryptionKeyException) {
throw SOPGPException.CertCannotEncrypt(e.message ?: "Cert cannot encrypt", e) throw SOPGPException.CertCannotEncrypt(e.message ?: "Cert cannot encrypt", e)
} catch (e: IOException) { } catch (e: IOException) {

View file

@ -18,8 +18,7 @@ class ExtractCertImpl(private val api: PGPainless) : ExtractCert {
private var armor = true private var armor = true
override fun key(keyInputStream: InputStream): Ready { override fun key(keyInputStream: InputStream): Ready {
val certs = val certs = KeyReader(api).readSecretKeys(keyInputStream, true).map { it.toCertificate() }
KeyReader.readSecretKeys(keyInputStream, true).map { PGPainless.extractCertificate(it) }
return object : Ready() { return object : Ready() {
override fun writeTo(outputStream: OutputStream) { override fun writeTo(outputStream: OutputStream) {
@ -27,17 +26,18 @@ class ExtractCertImpl(private val api: PGPainless) : ExtractCert {
if (certs.size == 1) { if (certs.size == 1) {
val cert = certs[0] val cert = certs[0]
// This way we have a nice armor header with fingerprint and user-ids // This way we have a nice armor header with fingerprint and user-ids
val armorOut = ArmorUtils.toAsciiArmoredStream(cert, outputStream) val armorOut =
cert.encode(armorOut) ArmorUtils.toAsciiArmoredStream(cert.pgpKeyRing, outputStream)
armorOut.write(cert.encoded)
armorOut.close() armorOut.close()
} else { } else {
// for multiple certs, add no info headers to the ASCII armor // for multiple certs, add no info headers to the ASCII armor
val armorOut = ArmoredOutputStreamFactory.get(outputStream) val armorOut = ArmoredOutputStreamFactory.get(outputStream)
certs.forEach { it.encode(armorOut) } certs.forEach { armorOut.write(it.encoded) }
armorOut.close() armorOut.close()
} }
} else { } else {
certs.forEach { it.encode(outputStream) } certs.forEach { outputStream.write(it.encoded) }
} }
} }
} }

View file

@ -8,13 +8,12 @@ import java.io.InputStream
import java.io.OutputStream import java.io.OutputStream
import java.lang.RuntimeException import java.lang.RuntimeException
import org.bouncycastle.openpgp.PGPException import org.bouncycastle.openpgp.PGPException
import org.bouncycastle.openpgp.PGPSecretKeyRing import org.bouncycastle.openpgp.api.OpenPGPKey
import org.bouncycastle.util.io.Streams import org.bouncycastle.util.io.Streams
import org.pgpainless.PGPainless import org.pgpainless.PGPainless
import org.pgpainless.algorithm.CompressionAlgorithm import org.pgpainless.algorithm.CompressionAlgorithm
import org.pgpainless.algorithm.DocumentSignatureType import org.pgpainless.algorithm.DocumentSignatureType
import org.pgpainless.algorithm.StreamEncoding import org.pgpainless.algorithm.StreamEncoding
import org.pgpainless.bouncycastle.extensions.openPgpFingerprint
import org.pgpainless.encryption_signing.ProducerOptions import org.pgpainless.encryption_signing.ProducerOptions
import org.pgpainless.encryption_signing.SigningOptions import org.pgpainless.encryption_signing.SigningOptions
import org.pgpainless.exception.KeyException.MissingSecretKeyException 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 signingOptions = SigningOptions.get(api)
private val protector = MatchMakingSecretKeyRingProtector() private val protector = MatchMakingSecretKeyRingProtector()
private val signingKeys = mutableListOf<PGPSecretKeyRing>() private val signingKeys = mutableListOf<OpenPGPKey>()
private var armor = true private var armor = true
private var mode = InlineSignAs.binary private var mode = InlineSignAs.binary
@ -45,14 +44,14 @@ class InlineSignImpl(private val api: PGPainless) : InlineSign {
signingOptions.addInlineSignature(protector, key, modeToSigType(mode)) signingOptions.addInlineSignature(protector, key, modeToSigType(mode))
} }
} catch (e: UnacceptableSigningKeyException) { } catch (e: UnacceptableSigningKeyException) {
throw SOPGPException.KeyCannotSign("Key ${key.openPgpFingerprint} cannot sign.", e) throw SOPGPException.KeyCannotSign("Key ${key.keyIdentifier} cannot sign.", e)
} catch (e: MissingSecretKeyException) { } catch (e: MissingSecretKeyException) {
throw SOPGPException.KeyCannotSign( 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) e)
} catch (e: PGPException) { } catch (e: PGPException) {
throw SOPGPException.KeyIsProtected( 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 { override fun key(key: InputStream): InlineSign = apply {
KeyReader.readSecretKeys(key, true).forEach { KeyReader(api).readSecretKeys(key, true).forEach {
val info = api.inspect(api.toKey(it)) val info = api.inspect(it)
if (!info.isUsableForSigning) { if (!info.isUsableForSigning) {
throw SOPGPException.KeyCannotSign( 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) protector.addSecretKey(it)
signingKeys.add(it) signingKeys.add(it)

View file

@ -24,7 +24,7 @@ class InlineVerifyImpl(private val api: PGPainless) : InlineVerify {
private val options = ConsumerOptions.get(api) private val options = ConsumerOptions.get(api)
override fun cert(cert: InputStream): InlineVerify = apply { 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>> { override fun data(data: InputStream): ReadyWithResult<List<Verification>> {

View file

@ -7,71 +7,63 @@ package org.pgpainless.sop
import java.io.IOException import java.io.IOException
import java.io.InputStream import java.io.InputStream
import org.bouncycastle.openpgp.PGPException import org.bouncycastle.openpgp.PGPException
import org.bouncycastle.openpgp.PGPPublicKeyRingCollection
import org.bouncycastle.openpgp.PGPRuntimeOperationException 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 org.pgpainless.PGPainless
import sop.exception.SOPGPException import sop.exception.SOPGPException
/** Reader for OpenPGP keys and certificates with error matching according to the SOP spec. */ /** 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 { fun readSecretKeys(keyInputStream: InputStream, requireContent: Boolean): List<OpenPGPKey> {
@JvmStatic val keys =
fun readSecretKeys( try {
keyInputStream: InputStream, api.readKey().parseKeys(keyInputStream)
requireContent: Boolean } catch (e: IOException) {
): PGPSecretKeyRingCollection { if (e.message == null) {
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)
}
throw e throw e
} }
if (requireContent && keys.none()) { if (e.message!!.startsWith("unknown object in stream:") ||
throw SOPGPException.BadData(PGPException("No key data found.")) e.message!!.startsWith("invalid header encountered") ||
} e.message!!.startsWith("Encountered unexpected packet:")) {
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) {
throw SOPGPException.BadData(e) throw SOPGPException.BadData(e)
} }
throw e
if (certs.pgpSecretKeyRingCollection.any()) {
throw SOPGPException.BadData(
"Secret key components encountered, while certificates were expected.")
} }
if (requireContent && keys.none()) {
if (requireContent && certs.pgpPublicKeyRingCollection.none()) { throw SOPGPException.BadData(PGPException("No key data found."))
throw SOPGPException.BadData(PGPException("No cert data found."))
}
return certs.pgpPublicKeyRingCollection
} }
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
} }
} }

View file

@ -39,7 +39,7 @@ class MatchMakingSecretKeyRingProtector : SecretKeyRingProtector {
keys.forEach { key -> keys.forEach { key ->
for (subkey in key) { for (subkey in key) {
if (protector.hasPassphrase(subkey.keyID)) { if (protector.hasPassphrase(subkey.keyIdentifier)) {
continue continue
} }
@ -50,6 +50,8 @@ class MatchMakingSecretKeyRingProtector : SecretKeyRingProtector {
} }
} }
fun addSecretKey(key: OpenPGPKey) = addSecretKey(key.pgpSecretKeyRing)
fun addSecretKey(key: PGPSecretKeyRing) = apply { fun addSecretKey(key: PGPSecretKeyRing) = apply {
if (!keys.add(key)) { if (!keys.add(key)) {
return@apply return@apply

View file

@ -12,7 +12,6 @@ import org.bouncycastle.openpgp.PGPException
import org.bouncycastle.openpgp.PGPPublicKeyRingCollection import org.bouncycastle.openpgp.PGPPublicKeyRingCollection
import org.bouncycastle.openpgp.api.OpenPGPCertificate import org.bouncycastle.openpgp.api.OpenPGPCertificate
import org.pgpainless.PGPainless import org.pgpainless.PGPainless
import org.pgpainless.bouncycastle.extensions.openPgpFingerprint
import org.pgpainless.bouncycastle.extensions.toOpenPGPCertificate import org.pgpainless.bouncycastle.extensions.toOpenPGPCertificate
import org.pgpainless.exception.WrongPassphraseException import org.pgpainless.exception.WrongPassphraseException
import org.pgpainless.key.util.KeyRingUtils import org.pgpainless.key.util.KeyRingUtils
@ -30,29 +29,28 @@ class RevokeKeyImpl(private val api: PGPainless) : RevokeKey {
private var armor = true private var armor = true
override fun keys(keys: InputStream): Ready { override fun keys(keys: InputStream): Ready {
val secretKeyRings = val secretKeys =
try { try {
KeyReader.readSecretKeys(keys, true) KeyReader(api).readSecretKeys(keys, true)
} catch (e: IOException) { } catch (e: IOException) {
throw SOPGPException.BadData("Cannot decode secret keys.", e) throw SOPGPException.BadData("Cannot decode secret keys.", e)
} }
secretKeyRings.forEach { protector.addSecretKey(it) } secretKeys.forEach { protector.addSecretKey(it) }
val revocationCertificates = mutableListOf<OpenPGPCertificate>() val revocationCertificates = mutableListOf<OpenPGPCertificate>()
secretKeyRings.forEach { secretKeys -> secretKeys.forEach {
val openPGPKey = api.toKey(secretKeys) val editor = api.modify(it)
val editor = api.modify(openPGPKey)
try { try {
val attributes = val attributes =
RevocationAttributes.createKeyRevocation() RevocationAttributes.createKeyRevocation()
.withReason(RevocationAttributes.Reason.NO_REASON) .withReason(RevocationAttributes.Reason.NO_REASON)
.withoutDescription() .withoutDescription()
if (openPGPKey.primaryKey.version == 6) { if (it.primaryKey.version == 6) {
revocationCertificates.add( revocationCertificates.add(
editor.createMinimalRevocationCertificate(protector, attributes)) editor.createMinimalRevocationCertificate(protector, attributes))
} else { } else {
val certificate = openPGPKey.toCertificate() val certificate = it.toCertificate()
val revocation = editor.createRevocation(protector, attributes) val revocation = editor.createRevocation(protector, attributes)
revocationCertificates.add( revocationCertificates.add(
KeyRingUtils.injectCertification( KeyRingUtils.injectCertification(
@ -61,11 +59,10 @@ class RevokeKeyImpl(private val api: PGPainless) : RevokeKey {
} }
} catch (e: WrongPassphraseException) { } catch (e: WrongPassphraseException) {
throw SOPGPException.KeyIsProtected( throw SOPGPException.KeyIsProtected(
"Missing or wrong passphrase for key ${secretKeys.openPgpFingerprint}", e) "Missing or wrong passphrase for key ${it.keyIdentifier}", e)
} catch (e: PGPException) { } catch (e: PGPException) {
throw RuntimeException( throw RuntimeException(
"Cannot generate revocation certificate for key ${secretKeys.openPgpFingerprint}", "Cannot generate revocation certificate for key ${it.keyIdentifier}", e)
e)
} }
} }