Class OpenPGPMessageOutputStream

java.lang.Object
java.io.OutputStream
org.bouncycastle.openpgp.api.OpenPGPMessageOutputStream
All Implemented Interfaces:
Closeable, Flushable, AutoCloseable

public class OpenPGPMessageOutputStream extends OutputStream
Implementation of an OutputStream tailored to creating OpenPGP messages. Since not all OpenPGP-related OutputStreams forward close() calls, we need to keep track of nested streams and close them in order. This stream can create OpenPGP messages following the following EBNF (which is a subset of the EBNF defined in RFC9580):
  • OpenPGP Message := ASCII-Armor(Optionally Encrypted Message) | Optionally Encrypted Message
  • Literal Message := LiteralDataPacket
  • Optionally Compressed Message := Literal Message | CompressedDataPacket(Literal Message)
  • Optionally Signed Message := Optionally Compressed Message | OnePassSignaturePacket + Optionally Signed Message + SignaturePacket
  • Optionally Padded Message := Optionally Signed Message | Optionally Signed Message + PaddingPacket
  • Encrypted Message := SEIPDv1(Optionally Padded Message) | SEIPDv2(Optionally Padded Message) | OED(Optionally Padded Message)
  • Optionally Encrypted Message := Optionally Padded Message | Encrypted Message
Therefore, this stream is capable of creating a wide variety of OpenPGP message, from simply LiteralDataPacket-wrapped plaintext over signed messages to encrypted, signed and padded messages. The following considerations lead to why this particular subset was chosen:
  • An encrypted message is not distinguishable from randomness, so it makes no sense to compress it
  • Since signatures also consist of data which is not distinguishable from randomness, it makes no sense to compress them either
  • Padding packets are used to prevent traffic analysis. Since they contain random data, we do not compress them. If a message is encrypted, we want to encrypt the padding packet to prevent an intermediate from stripping it
  • Since (v4) signatures leak some metadata about the message plaintext (the hash and the issuer), for encrypted messages we always place signatures inside the encryption container (sign-then-encrypt)
  • Prefix-signed messages (where a SignaturePacket is prefixed to an OpenPGP message) are inferior to One-Pass-Signed messages, so this stream cannot produce those.
  • Messages using the Cleartext-Signature Framework are "different enough" to deserve their own message generator / stream.