mirror of
https://github.com/pgpainless/pgpainless.git
synced 2025-09-09 10:19:39 +02:00
Rework ASCII armor API
This commit is contained in:
parent
9856aa43c4
commit
3ccc8601d7
7 changed files with 65 additions and 19 deletions
|
@ -4,8 +4,12 @@
|
|||
|
||||
package org.pgpainless
|
||||
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.OutputStream
|
||||
import java.util.*
|
||||
import org.bouncycastle.bcpg.ArmoredOutputStream
|
||||
import org.bouncycastle.bcpg.BCPGOutputStream
|
||||
import org.bouncycastle.bcpg.PacketFormat
|
||||
import org.bouncycastle.openpgp.PGPKeyRing
|
||||
import org.bouncycastle.openpgp.PGPPublicKeyRing
|
||||
import org.bouncycastle.openpgp.PGPSecretKeyRing
|
||||
|
@ -16,6 +20,7 @@ import org.bouncycastle.openpgp.api.OpenPGPImplementation
|
|||
import org.bouncycastle.openpgp.api.OpenPGPKey
|
||||
import org.bouncycastle.openpgp.api.OpenPGPKeyGenerator
|
||||
import org.bouncycastle.openpgp.api.OpenPGPKeyReader
|
||||
import org.bouncycastle.openpgp.api.OpenPGPSignature
|
||||
import org.bouncycastle.openpgp.api.bc.BcOpenPGPApi
|
||||
import org.pgpainless.algorithm.OpenPGPKeyVersion
|
||||
import org.pgpainless.bouncycastle.PolicyAdapter
|
||||
|
@ -59,6 +64,46 @@ class PGPainless(
|
|||
api = BcOpenPGPApi(implementation)
|
||||
}
|
||||
|
||||
@JvmOverloads
|
||||
fun toAsciiArmor(
|
||||
certOrKey: OpenPGPCertificate,
|
||||
packetFormat: PacketFormat = PacketFormat.ROUNDTRIP
|
||||
): String {
|
||||
val armorBuilder = ArmoredOutputStream.builder().clearHeaders()
|
||||
ArmorUtils.keyToHeader(certOrKey.primaryKey.pgpPublicKey)
|
||||
.getOrDefault(ArmorUtils.HEADER_COMMENT, setOf())
|
||||
.forEach { armorBuilder.addComment(it) }
|
||||
return certOrKey.toAsciiArmoredString(packetFormat, armorBuilder)
|
||||
}
|
||||
|
||||
@JvmOverloads
|
||||
fun toAsciiArmor(
|
||||
signature: OpenPGPSignature,
|
||||
packetFormat: PacketFormat = PacketFormat.ROUNDTRIP
|
||||
): String {
|
||||
val armorBuilder = ArmoredOutputStream.builder().clearHeaders()
|
||||
armorBuilder.addComment(signature.keyIdentifier.toPrettyPrint())
|
||||
return signature.toAsciiArmoredString(packetFormat, armorBuilder)
|
||||
}
|
||||
|
||||
@JvmOverloads
|
||||
fun toAsciiArmor(
|
||||
signature: PGPSignature,
|
||||
packetFormat: PacketFormat = PacketFormat.ROUNDTRIP
|
||||
): String {
|
||||
val armorBuilder = ArmoredOutputStream.builder().clearHeaders()
|
||||
OpenPGPSignature.getMostExpressiveIdentifier(signature.keyIdentifiers)?.let {
|
||||
armorBuilder.addComment(it.toPrettyPrint())
|
||||
}
|
||||
val bOut = ByteArrayOutputStream()
|
||||
val aOut = armorBuilder.build(bOut)
|
||||
val pOut = BCPGOutputStream(aOut, packetFormat)
|
||||
signature.encode(pOut)
|
||||
pOut.close()
|
||||
aOut.close()
|
||||
return bOut.toString()
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a new [OpenPGPKey] from predefined templates.
|
||||
*
|
||||
|
@ -290,10 +335,13 @@ class PGPainless(
|
|||
*/
|
||||
@JvmStatic
|
||||
fun asciiArmor(key: PGPKeyRing): String =
|
||||
if (key is PGPSecretKeyRing) ArmorUtils.toAsciiArmoredString(key)
|
||||
else ArmorUtils.toAsciiArmoredString(key as PGPPublicKeyRing)
|
||||
getInstance().toAsciiArmor(getInstance().toKeyOrCertificate(key))
|
||||
|
||||
@JvmStatic fun asciiArmor(cert: OpenPGPCertificate) = asciiArmor(cert.pgpKeyRing)
|
||||
@JvmStatic
|
||||
@Deprecated(
|
||||
"Call getInstance().toAsciiArmor(cert) instead.",
|
||||
replaceWith = ReplaceWith("getInstance().toAsciiArmor(cert)"))
|
||||
fun asciiArmor(cert: OpenPGPCertificate): String = getInstance().toAsciiArmor(cert)
|
||||
|
||||
/**
|
||||
* Wrap a key of certificate in ASCII armor and write the result into the given
|
||||
|
@ -318,8 +366,10 @@ class PGPainless(
|
|||
* @throws IOException in case of an error during the armoring process
|
||||
*/
|
||||
@JvmStatic
|
||||
@Deprecated("Covert to OpenPGPSignature and call .toAsciiArmoredString() instead.")
|
||||
fun asciiArmor(signature: PGPSignature): String = ArmorUtils.toAsciiArmoredString(signature)
|
||||
@Deprecated(
|
||||
"Call toAsciiArmor(signature) on an instance of PGPainless instead.",
|
||||
replaceWith = ReplaceWith("getInstance().toAsciiArmor(signature)"))
|
||||
fun asciiArmor(signature: PGPSignature): String = getInstance().toAsciiArmor(signature)
|
||||
|
||||
/**
|
||||
* Create an [EncryptionBuilder], which can be used to encrypt and/or sign data using
|
||||
|
|
|
@ -229,7 +229,7 @@ class ArmorUtils {
|
|||
* @return header map
|
||||
*/
|
||||
@JvmStatic
|
||||
private fun keyToHeader(publicKey: PGPPublicKey): Map<String, Set<String>> {
|
||||
fun keyToHeader(publicKey: PGPPublicKey): Map<String, Set<String>> {
|
||||
val headerMap = mutableMapOf<String, MutableSet<String>>()
|
||||
val userIds = KeyRingUtils.getUserIdsIgnoringInvalidUTF8(publicKey)
|
||||
val first: String? = userIds.firstOrNull()
|
||||
|
|
|
@ -113,10 +113,11 @@ public class CanonicalizedDataEncryptionTest {
|
|||
|
||||
@BeforeAll
|
||||
public static void readKeys() throws IOException {
|
||||
secretKeys = PGPainless.getInstance().readKey().parseKey(KEY);
|
||||
PGPainless api = PGPainless.getInstance();
|
||||
secretKeys = api.readKey().parseKey(KEY);
|
||||
publicKeys = secretKeys.toCertificate();
|
||||
// CHECKSTYLE:OFF
|
||||
System.out.println(PGPainless.asciiArmor(secretKeys));
|
||||
System.out.println(api.toAsciiArmor(secretKeys));
|
||||
// CHECKSTYLE:ON
|
||||
}
|
||||
|
||||
|
|
|
@ -599,7 +599,7 @@ class KeyRingReaderTest {
|
|||
public void testReadKeyRingWithArmoredPublicKey() throws IOException {
|
||||
OpenPGPKey secretKeys = api.generateKey().modernKeyRing("Alice <alice@pgpainless.org>");
|
||||
OpenPGPCertificate publicKeys = secretKeys.toCertificate();
|
||||
String armored = PGPainless.asciiArmor(publicKeys);
|
||||
String armored = api.toAsciiArmor(publicKeys);
|
||||
|
||||
PGPKeyRing keyRing = PGPainless.readKeyRing()
|
||||
.keyRing(armored);
|
||||
|
|
|
@ -132,7 +132,7 @@ public class ArmorUtilsTest {
|
|||
@Test
|
||||
public void signatureToAsciiArmoredString() {
|
||||
String SIG = "-----BEGIN PGP SIGNATURE-----\n" +
|
||||
"Version: PGPainless\n" +
|
||||
"Comment: 4F66 5C4D C2C4 660B C642 5E41 5736 E693 1ACF 370C\n" +
|
||||
"\n" +
|
||||
"iHUEARMKAB0WIQRPZlxNwsRmC8ZCXkFXNuaTGs83DAUCYJ/x5gAKCRBXNuaTGs83\n" +
|
||||
"DFRwAP9/4wMvV3WcX59Clo7mkRce6iwW3VBdiN+yMu3tjmHB2wD/RfE28Q1v4+eo\n" +
|
||||
|
|
|
@ -7,7 +7,6 @@ package org.pgpainless.sop
|
|||
import java.io.InputStream
|
||||
import java.io.OutputStream
|
||||
import org.pgpainless.PGPainless
|
||||
import org.pgpainless.util.ArmorUtils
|
||||
import org.pgpainless.util.ArmoredOutputStreamFactory
|
||||
import sop.Ready
|
||||
import sop.operation.ExtractCert
|
||||
|
@ -26,10 +25,8 @@ 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.pgpKeyRing, outputStream)
|
||||
armorOut.write(cert.encoded)
|
||||
armorOut.close()
|
||||
val armored = cert.toAsciiArmoredString()
|
||||
outputStream.write(armored.toByteArray())
|
||||
} else {
|
||||
// for multiple certs, add no info headers to the ASCII armor
|
||||
val armorOut = ArmoredOutputStreamFactory.get(outputStream)
|
||||
|
|
|
@ -18,7 +18,6 @@ import org.pgpainless.key.generation.type.KeyType
|
|||
import org.pgpainless.key.generation.type.eddsa_legacy.EdDSALegacyCurve
|
||||
import org.pgpainless.key.generation.type.rsa.RsaLength
|
||||
import org.pgpainless.key.generation.type.xdh_legacy.XDHLegacySpec
|
||||
import org.pgpainless.util.ArmorUtils
|
||||
import org.pgpainless.util.Passphrase
|
||||
import sop.Profile
|
||||
import sop.Ready
|
||||
|
@ -50,9 +49,8 @@ class GenerateKeyImpl(private val api: PGPainless) : GenerateKey {
|
|||
return object : Ready() {
|
||||
override fun writeTo(outputStream: OutputStream) {
|
||||
if (armor) {
|
||||
val armorOut = ArmorUtils.toAsciiArmoredStream(key.pgpKeyRing, outputStream)
|
||||
key.pgpKeyRing.encode(armorOut)
|
||||
armorOut.close()
|
||||
val armored = key.toAsciiArmoredString()
|
||||
outputStream.write(armored.toByteArray())
|
||||
} else {
|
||||
key.pgpKeyRing.encode(outputStream)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue