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:
parent
aeed0e736b
commit
85c0286041
11 changed files with 100 additions and 113 deletions
|
@ -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) }
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.")
|
||||||
|
|
|
@ -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> {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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>> {
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue