org.pgpainless.sop.RevokeKeyImpl.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of pgpainless-sop Show documentation
Show all versions of pgpainless-sop Show documentation
Simple to use OpenPGP API for Java based on Bouncycastle
The newest version!
// SPDX-FileCopyrightText: 2024 Paul Schaub
//
// SPDX-License-Identifier: Apache-2.0
package org.pgpainless.sop
import java.io.IOException
import java.io.InputStream
import java.io.OutputStream
import java.lang.RuntimeException
import org.bouncycastle.openpgp.PGPException
import org.bouncycastle.openpgp.PGPPublicKeyRing
import org.bouncycastle.openpgp.PGPPublicKeyRingCollection
import org.pgpainless.PGPainless
import org.pgpainless.bouncycastle.extensions.openPgpFingerprint
import org.pgpainless.exception.WrongPassphraseException
import org.pgpainless.key.util.KeyRingUtils
import org.pgpainless.key.util.RevocationAttributes
import org.pgpainless.util.ArmoredOutputStreamFactory
import org.pgpainless.util.Passphrase
import sop.Ready
import sop.exception.SOPGPException
import sop.operation.RevokeKey
import sop.util.UTF8Util
class RevokeKeyImpl : RevokeKey {
private val protector = MatchMakingSecretKeyRingProtector()
private var armor = true
override fun keys(keys: InputStream): Ready {
val secretKeyRings =
try {
KeyReader.readSecretKeys(keys, true)
} catch (e: IOException) {
throw SOPGPException.BadData("Cannot decode secret keys.", e)
}
secretKeyRings.forEach { protector.addSecretKey(it) }
val revocationCertificates = mutableListOf()
secretKeyRings.forEach { secretKeys ->
val editor = PGPainless.modifyKeyRing(secretKeys)
try {
val attributes =
RevocationAttributes.createKeyRevocation()
.withReason(RevocationAttributes.Reason.NO_REASON)
.withoutDescription()
if (secretKeys.publicKey.version == 6) {
revocationCertificates.add(
editor.createMinimalRevocationCertificate(protector, attributes))
} else {
val certificate = PGPainless.extractCertificate(secretKeys)
val revocation = editor.createRevocation(protector, attributes)
revocationCertificates.add(
KeyRingUtils.injectCertification(certificate, revocation))
}
} catch (e: WrongPassphraseException) {
throw SOPGPException.KeyIsProtected(
"Missing or wrong passphrase for key ${secretKeys.openPgpFingerprint}", e)
} catch (e: PGPException) {
throw RuntimeException(
"Cannot generate revocation certificate for key ${secretKeys.openPgpFingerprint}",
e)
}
}
return object : Ready() {
override fun writeTo(outputStream: OutputStream) {
val collection = PGPPublicKeyRingCollection(revocationCertificates)
if (armor) {
val armorOut = ArmoredOutputStreamFactory.get(outputStream)
collection.encode(armorOut)
armorOut.close()
} else {
collection.encode(outputStream)
}
}
}
}
override fun noArmor(): RevokeKey = apply { armor = false }
override fun withKeyPassword(password: ByteArray): RevokeKey = apply {
val string =
try {
UTF8Util.decodeUTF8(password)
} catch (e: CharacterCodingException) {
// TODO: Add cause
throw SOPGPException.PasswordNotHumanReadable(
"Cannot UTF8-decode password: ${e.stackTraceToString()}")
}
protector.addPassphrase(Passphrase.fromPassword(string))
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy