Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document PublicKeyPacket members #1711

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
149 changes: 136 additions & 13 deletions pg/src/main/java/org/bouncycastle/bcpg/PublicKeyPacket.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,77 @@
import java.util.Date;

/**
* basic packet for a PGP public key
* Base class for OpenPGP public (primary) keys.
* The public key packet holds the public parameters of an OpenPGP key pair.
* An OpenPGP certificate (transferable public key) consists of one primary key and optionally multiple subkey packets.
*
* @see <a href="https://www.rfc-editor.org/rfc/rfc4880.html#section-5.5.1.1">
* rfc4880 - Public-Key Packet</a>
* @see <a href="https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-13.html#name-public-key-packet-type-id-6">
* C-R - Public-Key Packet</a>
* @see <a href="https://www.ietf.org/archive/id/draft-koch-librepgp-00.html#name-public-key-packet-tag-6">
* LibrePGP - Public-Key Packet</a>
*/
public class PublicKeyPacket
extends ContainedPacket
implements PublicKeyAlgorithmTags
{
/**
* OpenPGP v3 keys are deprecated.
* They can only be used with RSA.
*
* @see <a href="https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-13.html#name-version-3-public-keys">
* C-R - Version 3 Public Keys</a>
*/
public static final int VERSION_3 = 3;
/**
* OpenPGP v4 keys are (at the time of writing) widely used, but are subject to some attacks.
*
* @see <a href="https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-13.html#name-version-4-public-keys">
* C-R - Version 4 Public Keys</a>
*/
public static final int VERSION_4 = 4;
/**
* OpenPGP v6 keys are newly introduced.
*
* @see <a href="https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-13.html#name-version-6-public-keys">
* C-R - Version 6 Public Keys</a>
*/
public static final int VERSION_6 = 6;

/**
* Non-Standard LibrePGP introduced v5, which is only supported by a subset of vendors.
*/
public static final int LIBREPGP_5 = 5;

private int version;
// Creation time of the key stored as seconds since epoch
private long time;
private int validDays;
private int algorithm;
private BCPGKey key;

/**
* Parse a {@link PublicKeyPacket} from an OpenPGP {@link BCPGInputStream}.
* The packet format is remembered as {@link PacketFormat#LEGACY}.
* @param in packet input stream
* @throws IOException
*/
PublicKeyPacket(
BCPGInputStream in)
throws IOException
{
this(in, false);
}

/**
* Parse a {@link PublicKeyPacket} from an OpenPGP {@link BCPGInputStream}.
* If <pre>newPacketFormat</pre> is true, the packet format is remembered as {@link PacketFormat#CURRENT},
* otherwise as {@link PacketFormat#LEGACY}.
* @param in packet input stream
* @param newPacketFormat new packet format
* @throws IOException
*/
PublicKeyPacket(
BCPGInputStream in,
boolean newPacketFormat)
Expand All @@ -35,21 +84,41 @@ public class PublicKeyPacket
this(PUBLIC_KEY, in, newPacketFormat);
}

/**
* Parse a {@link PublicKeyPacket} or {@link PublicSubkeyPacket} from an OpenPGP {@link BCPGInputStream}.
* If <pre>packetTypeID</pre> is {@link #PUBLIC_KEY}, the packet is a primary key.
* If instead it is {@link #PUBLIC_SUBKEY}, it is a subkey packet.
* The packet format is remembered as {@link PacketFormat#LEGACY}.
* @param packetTypeID packet type ID
* @param in packet input stream
* @throws IOException
*/
PublicKeyPacket(
int keyTag,
int packetTypeID,
BCPGInputStream in)
throws IOException
{
this(keyTag, in, false);
this(packetTypeID, in, false);
}

/**
* Parse a {@link PublicKeyPacket} or {@link PublicSubkeyPacket} from an OpenPGP {@link BCPGInputStream}.
* If <pre>packetTypeID</pre> is {@link #PUBLIC_KEY}, the packet is a primary key.
* If instead it is {@link #PUBLIC_SUBKEY}, it is a subkey packet.
* If <pre>newPacketFormat</pre> is true, the packet format is remembered as {@link PacketFormat#CURRENT},
* otherwise as {@link PacketFormat#LEGACY}.
* @param packetTypeID packet type ID
* @param in packet input stream
* @param newPacketFormat packet format
* @throws IOException
*/
PublicKeyPacket(
int keyTag,
int packetTypeID,
BCPGInputStream in,
boolean newPacketFormat)
throws IOException
{
super(keyTag, newPacketFormat);
super(packetTypeID, newPacketFormat);

version = in.read();
time = ((long)in.read() << 24) | (in.read() << 16) | (in.read() << 8) | in.read();
Expand All @@ -60,7 +129,7 @@ public class PublicKeyPacket
}

algorithm = (byte)in.read();
if (version == VERSION_6)
if (version == VERSION_6 || version == LIBREPGP_5)
{
// TODO: Use keyOctets to be able to parse unknown keys
long keyOctets = ((long)in.read() << 24) | ((long)in.read() << 16) | ((long)in.read() << 8) | in.read();
Expand Down Expand Up @@ -107,11 +176,11 @@ public class PublicKeyPacket
}

/**
* Construct version 4 public key packet.
* Construct version 4 public primary key packet.
*
* @param algorithm
* @param time
* @param key
* @param algorithm public key algorithm id
* @param time creation time
* @param key key object
*/
public PublicKeyPacket(
int algorithm,
Expand All @@ -121,6 +190,13 @@ public PublicKeyPacket(
this(VERSION_4, algorithm, time, key);
}

/**
* Construct an OpenPGP public primary key packet.
* @param version packet version
* @param algorithm public key algorithm id
* @param time creation time
* @param key key object
*/
public PublicKeyPacket(
int version,
int algorithm,
Expand All @@ -130,42 +206,81 @@ public PublicKeyPacket(
this(PUBLIC_KEY, version, algorithm, time, key);
}

PublicKeyPacket(int keyTag, int version, int algorithm, Date time, BCPGKey key)
/**
* Construct an OpenPGP public key packet.
* If <pre>packetTypeID</pre> is {@link #PUBLIC_KEY}, the packet is a primary key.
* If instead it is {@link #PUBLIC_SUBKEY}, it is a subkey packet.
* @param packetTypeID public key packet type ID
* @param version packet version
* @param algorithm public key algorithm id
* @param time creation time
* @param key key object
*/
PublicKeyPacket(int packetTypeID, int version, int algorithm, Date time, BCPGKey key)
{
super(keyTag);
super(packetTypeID);

this.version = version;
this.time = time.getTime() / 1000;
this.algorithm = algorithm;
this.key = key;
}


/**
* Return the packet version.
* @return packet version
*/
public int getVersion()
{
return version;
}

/**
* Return the {@link PublicKeyAlgorithmTags algorithm id} of the public key.
* @return algorithm id
*/
public int getAlgorithm()
{
return algorithm;
}

/**
* Only for v3 keys - The time in days since the keys creation, during which the key is valid.
*
* @return v3 key validity period in days since creation.
* @deprecated v4 and v6 keys instead signal their expiration time via the
* {@link org.bouncycastle.bcpg.sig.KeyExpirationTime} signature subpacket.
*/
@Deprecated
public int getValidDays()
{
return validDays;
}

/**
* Return the keys creation time.
*
* @return creation time of the key
*/
public Date getTime()
{
return new Date(time * 1000);
}

/**
* Return the key object.
* @return key
*/
public BCPGKey getKey()
{
return key;
}

/**
* Return the encoded packet contents without the packet frame.
* @return encoded packet contents
* @throws IOException
*/
public byte[] getEncodedContents()
throws IOException
{
Expand Down Expand Up @@ -200,6 +315,14 @@ public byte[] getEncodedContents()
return bOut.toByteArray();
}

/**
* Encode the packet to the OpenPGP {@link BCPGOutputStream}.
* If the {@link BCPGOutputStream} packet format is set to {@link PacketFormat#ROUNDTRIP}, the result
* of {@link #hasNewPacketFormat()} determines, which packet format is used to encode the packet.
* Otherwise, the {@link BCPGOutputStream} dictates which format to use.
* @param out packet output stream
* @throws IOException
*/
public void encode(
BCPGOutputStream out)
throws IOException
Expand Down