View Source OpenPGP.Packet.BodyChunk (OpenPGP v0.6.2)
Packet data is represented as a list of body chunks. Each body chunk includes chunk length header information and chunk data.
Most of the packets will have only one body chunk. Only packets with Partial Body Length expected to have more than one body chunk.
The OpenPGP.Util.concat_body/1
can be applied to a packet body or a
list of body chunks to concatenate chunks into a binary to be further
interpreted.
RFC4880
4.2.1. Old Format Packet Lengths
The meaning of the length-type in old format packets is:
0 - The packet has a one-octet length. The header is 2 octets long.
1 - The packet has a two-octet length. The header is 3 octets long.
2 - The packet has a four-octet length. The header is 5 octets long.
3 - The packet is of indeterminate length. The header is 1 octet
long, and the implementation must determine how long the packet
is. If the packet is in a file, this means that the packet
extends until the end of the file. In general, an implementation
SHOULD NOT use indeterminate-length packets except where the end
of the data will be clear from the context, and even then it is
better to use a definite length, or a new format header. The new
format headers described below have a mechanism for precisely
encoding data of indeterminate length.
4.2.2. New Format Packet Lengths
New format packets have four possible ways of encoding length:
A one-octet Body Length header encodes packet lengths of up to 191 octets.
A two-octet Body Length header encodes packet lengths of 192 to 8383 octets.
A five-octet Body Length header encodes packet lengths of up to 4,294,967,295 (0xFFFFFFFF) octets in length. (This actually encodes a four-octet scalar number.)
When the length of the packet body is not known in advance by the issuer, Partial Body Length headers encode a packet of indeterminate length, effectively making it a stream.
4.2.2.1. One-Octet Lengths
A one-octet Body Length header encodes a length of 0 to 191 octets. This type of length header is recognized because the one octet value is less than 192. The body length is equal to:
bodyLen = 1st_octet;
4.2.2.2. Two-Octet Lengths
A two-octet Body Length header encodes a length of 192 to 8383 octets. It is recognized because its first octet is in the range 192 to 223. The body length is equal to:
bodyLen = ((1st_octet - 192) << 8) + (2nd_octet) + 192
4.2.2.3. Five-Octet Lengths
A five-octet Body Length header consists of a single octet holding the value 255, followed by a four-octet scalar. The body length is equal to:
bodyLen = (2nd_octet << 24) | (3rd_octet << 16) |
(4th_octet << 8) | 5th_octet
This basic set of one, two, and five-octet lengths is also used internally to some packets.
4.2.2.4. Partial Body Lengths
A Partial Body Length header is one octet long and encodes the length of only part of the data packet. This length is a power of 2, from 1 to 1,073,741,824 (2 to the 30th power). It is recognized by its one octet value that is greater than or equal to 224, and less than 255. The Partial Body Length is equal to:
partialBodyLen = 1 << (1st_octet & 0x1F);
Each Partial Body Length header is followed by a portion of the packet body data. The Partial Body Length header specifies this portion's length. Another length header (one octet, two-octet, five-octet, or partial) follows that portion. The last length header in the packet MUST NOT be a Partial Body Length header. Partial Body Length headers may only be used for the non-final parts of the packet.
Note also that the last Body Length header can be a zero-length header.
An implementation MAY use Partial Body Lengths for data packets, be they literal, compressed, or encrypted. The first partial length MUST be at least 512 octets long. Partial Body Lengths MUST NOT be used for any other packet types.
Summary
Functions
Decode body chunk given input binary and packet tag. Return structured body chunk and remaining binary. Expect input to start with Body Length header octets.
Types
@type chunk_length() :: {:fixed | :partial | :indeterminate, non_neg_integer()}
Chunk length in octets (bytes). Payload size.
@type header_length() :: non_neg_integer()
The packet has a N-octet length header.
@type t() :: %OpenPGP.Packet.BodyChunk{ chunk_length: chunk_length(), data: binary(), header_length: header_length() }
Functions
@spec decode(input :: binary(), OpenPGP.Packet.PacketTag.t()) :: {t(), rest :: binary()}
Decode body chunk given input binary and packet tag. Return structured body chunk and remaining binary. Expect input to start with Body Length header octets.
Example:
iex> alias OpenPGP.Packet.{BodyChunk, PacketTag}
iex> BodyChunk.decode(<<5, "Hello", " world!">>, %PacketTag{format: :old, length_type: {0, "one-octet"}})
{%BodyChunk{data: "Hello", header_length: 1, chunk_length: {:fixed, 5}}, " world!"}