Skip to content

Commit

Permalink
OpenPGP Packets: Remember packetTagFormat to allow round-tripping pac…
Browse files Browse the repository at this point in the history
…kets unmodified
  • Loading branch information
vanitasvitae committed May 7, 2024
1 parent d7ffa8b commit 06ef4f6
Show file tree
Hide file tree
Showing 29 changed files with 692 additions and 98 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,16 @@ public class AEADEncDataPacket
private final byte[] iv;

public AEADEncDataPacket(BCPGInputStream in)
throws IOException
{
this(in, false);
}

public AEADEncDataPacket(BCPGInputStream in,
boolean newPacketFormat)
throws IOException
{
super(in, AEAD_ENC_DATA);
super(in, AEAD_ENC_DATA, newPacketFormat);

version = (byte)in.read();
if (version != VERSION_1)
Expand Down
44 changes: 22 additions & 22 deletions pg/src/main/java/org/bouncycastle/bcpg/BCPGInputStream.java
Original file line number Diff line number Diff line change
Expand Up @@ -264,52 +264,52 @@ else if (l == 255)
switch (tag)
{
case RESERVED:
return new ReservedPacket(objStream);
return new ReservedPacket(objStream, newPacket);
case PUBLIC_KEY_ENC_SESSION:
return new PublicKeyEncSessionPacket(objStream);
return new PublicKeyEncSessionPacket(objStream, newPacket);
case SIGNATURE:
return new SignaturePacket(objStream);
return new SignaturePacket(objStream, newPacket);
case SYMMETRIC_KEY_ENC_SESSION:
return new SymmetricKeyEncSessionPacket(objStream);
return new SymmetricKeyEncSessionPacket(objStream, newPacket);
case ONE_PASS_SIGNATURE:
return new OnePassSignaturePacket(objStream);
return new OnePassSignaturePacket(objStream, newPacket);
case SECRET_KEY:
return new SecretKeyPacket(objStream);
return new SecretKeyPacket(objStream, newPacket);
case PUBLIC_KEY:
return new PublicKeyPacket(objStream);
return new PublicKeyPacket(objStream, newPacket);
case SECRET_SUBKEY:
return new SecretSubkeyPacket(objStream);
return new SecretSubkeyPacket(objStream, newPacket);
case COMPRESSED_DATA:
return new CompressedDataPacket(objStream);
return new CompressedDataPacket(objStream, newPacket);
case SYMMETRIC_KEY_ENC:
return new SymmetricEncDataPacket(objStream);
return new SymmetricEncDataPacket(objStream, newPacket);
case MARKER:
return new MarkerPacket(objStream);
return new MarkerPacket(objStream, newPacket);
case LITERAL_DATA:
return new LiteralDataPacket(objStream);
return new LiteralDataPacket(objStream, newPacket);
case TRUST:
return new TrustPacket(objStream);
return new TrustPacket(objStream, newPacket);
case USER_ID:
return new UserIDPacket(objStream);
return new UserIDPacket(objStream, newPacket);
case USER_ATTRIBUTE:
return new UserAttributePacket(objStream);
return new UserAttributePacket(objStream, newPacket);
case PUBLIC_SUBKEY:
return new PublicSubkeyPacket(objStream);
return new PublicSubkeyPacket(objStream, newPacket);
case SYM_ENC_INTEGRITY_PRO:
return new SymmetricEncIntegrityPacket(objStream);
return new SymmetricEncIntegrityPacket(objStream, newPacket);
case MOD_DETECTION_CODE:
return new ModDetectionCodePacket(objStream);
return new ModDetectionCodePacket(objStream, newPacket);
case AEAD_ENC_DATA:
return new AEADEncDataPacket(objStream);
return new AEADEncDataPacket(objStream, newPacket);
case PADDING:
return new PaddingPacket(objStream);
return new PaddingPacket(objStream, newPacket);
case EXPERIMENTAL_1:
case EXPERIMENTAL_2:
case EXPERIMENTAL_3:
case EXPERIMENTAL_4:
return new ExperimentalPacket(tag, objStream);
return new ExperimentalPacket(tag, objStream, newPacket);
default:
return new UnknownPacket(tag, objStream);
return new UnknownPacket(tag, objStream, newPacket);
}
}

Expand Down
66 changes: 61 additions & 5 deletions pg/src/main/java/org/bouncycastle/bcpg/BCPGOutputStream.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public static BCPGOutputStream wrap(OutputStream out)
}

OutputStream out;
private boolean useOldFormat;
private PacketFormat packetFormat;
private byte[] partialBuffer;
private int partialBufferLength;
private int partialPower;
Expand All @@ -46,11 +46,11 @@ public static BCPGOutputStream wrap(OutputStream out)
public BCPGOutputStream(
OutputStream out)
{
this(out, false);
this(out, PacketFormat.ROUNDTRIP);
}

/**
* Base constructor specifying whether or not to use packets in the new format
* Base constructor specifying whether to use packets in the new format
* wherever possible.
*
* @param out output stream to write encoded data to.
Expand All @@ -59,9 +59,16 @@ public BCPGOutputStream(
public BCPGOutputStream(
OutputStream out,
boolean newFormatOnly)
{
this(out, newFormatOnly ? PacketFormat.CURRENT : PacketFormat.ROUNDTRIP);
}

public BCPGOutputStream(
OutputStream out,
PacketFormat packetFormat)
{
this.out = out;
this.useOldFormat = !newFormatOnly;
this.packetFormat = packetFormat;
}

/**
Expand All @@ -75,6 +82,7 @@ public BCPGOutputStream(
throws IOException
{
this.out = out;
this.packetFormat = PacketFormat.LEGACY;
this.writeHeader(tag, true, true, 0);
}

Expand All @@ -95,6 +103,7 @@ public BCPGOutputStream(
throws IOException
{
this.out = out;
this.packetFormat = oldFormat ? PacketFormat.LEGACY : PacketFormat.CURRENT;

if (length > 0xFFFFFFFFL)
{
Expand Down Expand Up @@ -122,6 +131,7 @@ public BCPGOutputStream(
throws IOException
{
this.out = out;
this.packetFormat = PacketFormat.CURRENT;

this.writeHeader(tag, false, false, length);
}
Expand All @@ -141,6 +151,7 @@ public BCPGOutputStream(
throws IOException
{
this.out = out;
this.packetFormat = PacketFormat.CURRENT;
this.writeHeader(tag, false, true, 0);

this.partialBuffer = buffer;
Expand Down Expand Up @@ -316,22 +327,66 @@ public void write(
}
}

/**
* Write a packet to the stream.
* @param p packet
* @throws IOException
*/
public void writePacket(
ContainedPacket p)
throws IOException
{
p.encode(this);
}

/**
* Write a packet to the stream.
* The packet will use the old encoding format if {@link #packetFormat} is {@link PacketFormat#LEGACY}, otherwise
* it will be encoded using the new packet format.
* @param tag packet tag
* @param body packet body
* @throws IOException
*/
void writePacket(
int tag,
byte[] body)
throws IOException
{
this.writeHeader(tag, useOldFormat, false, body.length);
this.writeHeader(tag, packetFormat == PacketFormat.LEGACY, false, body.length);
this.write(body);
}

/**
* Write a packet.
* The packet format will be chosen primarily based on {@link #packetFormat}.
* If {@link #packetFormat} is {@link PacketFormat#CURRENT}, the packet will be encoded using the new format.
* If it is {@link PacketFormat#LEGACY}, the packet will use old encoding format.
* If it is {@link PacketFormat#ROUNDTRIP}, then the format will be determined by objectPrefersNewPacketFormat.
*
* @param objectPrefersNewPacketFormat whether the packet prefers to be encoded using the new packet format
* @param tag packet tag
* @param body packet body
* @throws IOException
*/
void writePacket(
boolean objectPrefersNewPacketFormat,
int tag,
byte[] body)
throws IOException
{
boolean oldPacketFormat = packetFormat == PacketFormat.LEGACY ||
(packetFormat == PacketFormat.ROUNDTRIP && !objectPrefersNewPacketFormat);
this.writeHeader(tag, oldPacketFormat, false, body.length);
this.write(body);
}

/**
* Write a packet, forcing the packet format to be either old or new.
* @param tag packet tag
* @param body packet body
* @param oldFormat if true, old format is forced, else force new format
* @throws IOException
*/
void writePacket(
int tag,
byte[] body,
Expand Down Expand Up @@ -379,4 +434,5 @@ public void close()
out.flush();
out.close();
}

}
12 changes: 10 additions & 2 deletions pg/src/main/java/org/bouncycastle/bcpg/CompressedDataPacket.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,18 @@ public class CompressedDataPacket
int algorithm;

CompressedDataPacket(
BCPGInputStream in)
BCPGInputStream in)
throws IOException
{
this(in, false);
}

CompressedDataPacket(
BCPGInputStream in,
boolean newPacketFormat)
throws IOException
{
super(in, COMPRESSED_DATA);
super(in, COMPRESSED_DATA, newPacketFormat);

algorithm = in.read();
}
Expand Down
21 changes: 15 additions & 6 deletions pg/src/main/java/org/bouncycastle/bcpg/ContainedPacket.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,30 @@ public abstract class ContainedPacket
extends Packet
implements Encodable
{

ContainedPacket(int packetTag)
{
super(packetTag);
this(packetTag, false);
}

ContainedPacket(int packetTag, boolean newPacketFormat)
{
super(packetTag, newPacketFormat);
}

public byte[] getEncoded()
throws IOException
{
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
BCPGOutputStream pOut = new BCPGOutputStream(bOut);

pOut.writePacket(this);
return getEncoded(PacketFormat.ROUNDTRIP);
}

public byte[] getEncoded(PacketFormat format)
throws IOException
{
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
BCPGOutputStream pOut = new BCPGOutputStream(bOut, format);
pOut.writePacket(this);
pOut.close();

return bOut.toByteArray();
}

Expand Down
22 changes: 18 additions & 4 deletions pg/src/main/java/org/bouncycastle/bcpg/ExperimentalPacket.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,32 @@ public class ExperimentalPacket
extends ContainedPacket implements PublicKeyAlgorithmTags
{
private byte[] contents;


/**
*
* @param in
* @throws IOException
*/
ExperimentalPacket(
int tag,
BCPGInputStream in)
throws IOException
{
this(tag, in, false);
}

/**
*
* @param in
* @throws IOException
*/
ExperimentalPacket(
int tag,
BCPGInputStream in)
BCPGInputStream in,
boolean newPacketFormat)
throws IOException
{
super(tag);
super(tag, newPacketFormat);

this.contents = in.readAll();
}
Expand All @@ -44,6 +58,6 @@ public void encode(
BCPGOutputStream out)
throws IOException
{
out.writePacket(getPacketTag(), contents);
out.writePacket(hasNewPacketFormat(), getPacketTag(), contents);
}
}
11 changes: 9 additions & 2 deletions pg/src/main/java/org/bouncycastle/bcpg/InputStreamPacket.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,15 @@ public InputStreamPacket(
BCPGInputStream in,
int packetTag)
{
super(packetTag);

this(in, packetTag, false);
}

InputStreamPacket(
BCPGInputStream in,
int packetTag,
boolean newPacketFormat)
{
super(packetTag, newPacketFormat);
this.in = in;
}

Expand Down
12 changes: 10 additions & 2 deletions pg/src/main/java/org/bouncycastle/bcpg/LiteralDataPacket.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,18 @@ public class LiteralDataPacket
long modDate;

LiteralDataPacket(
BCPGInputStream in)
BCPGInputStream in)
throws IOException
{
this(in, false);
}

LiteralDataPacket(
BCPGInputStream in,
boolean newPacketFormat)
throws IOException
{
super(in, LITERAL_DATA);
super(in, LITERAL_DATA, newPacketFormat);

format = in.read();
int l = in.read();
Expand Down
Loading

0 comments on commit 06ef4f6

Please sign in to comment.