edit ch17

This commit is contained in:
Tammi L. Coles 2023-10-27 09:26:13 +02:00
parent 647b2494f5
commit 3f38d588f5

View file

@ -6,15 +6,15 @@ SPDX-License-Identifier: CC-BY-SA-4.0
(zoom_certificates)=
# Zooming in: Packet structure of certificates and keys
Now that we've established these concepts, and the components that OpenPGP certificates consist of, let's look at the internal details of an example certificate.
Now that we've established the concepts and components that make up OpenPGP certificates , let's look at the internal details of an example certificate.
## A very minimal OpenPGP certificate
First, we'll look at a very minimal version of a "public key" variant of [](alice_priv). That is, an OpenPGP certificate (which doesn't contain private key material).
In this section, we will examine a very minimal version of a "public key" variant of [Alice's OpenPGP key](alice_priv), specifically an OpenPGP certificate that excludes private key material.
In this section, we use the Sequoia-PGP tool `sq` to handle and transform our example OpenPGP key, and to inspect internal OpenPGP packet data.
To achieve this, we will use the Sequoia-PGP tool `sq` to handle and transform our example OpenPGP key, as well as to inspect internal OpenPGP packet data.
Starting from [Alice's OpenPGP "private key"](alice_priv), we first produce the corresponding "public key", or certificate:
Starting from [Alice's OpenPGP private key](alice_priv), we first produce the corresponding public key/certificate using the following command:
```text
$ sq key extract-cert alice.priv > alice.pub
@ -23,13 +23,15 @@ $ sq key extract-cert alice.priv > alice.pub
(split_alice)=
### Splitting the OpenPGP certificate into packets
One way to produce a very minimal version of Alice's certificate is to split the data in `alice.pub` into its component packets, and join only the relevant ones back together into a new variant.
To create a very minimal version of Alice's certificate, we will split the data in `alice.pub` into its component packets and reassemble only the relevant ones back into a new variant.
Execute the following command to achieve this:
```text
$ sq packet split alice.pub
```
With this command, `sq` generates a set of files, each containing an individual OpenPGP packet of the original full certificate in `alice.pub`:
With this command, `sq` generates a set of files, each containing an individual OpenPGP packet extracted from the original full certificate in `alice.pub`:
```text
alice.pub-0--PublicKey
@ -50,22 +52,28 @@ alice.pub-9--Signature
Overview of the packets in Alice's OpenPGP certificate
```
### Joining packets into an OpenPGP certificate
This process allows us to focus on the specific packets within Alice's OpenPGP certificate.
For our first step, we'll use just the first two of the packets of Alice's certificate, and join them together as a very minimal certificate:
### Assembling packets into an OpenPGP certificate
In this step, we'll merge the first two packets of Alice's certificate to create a very minimal certificate:
Execute the following:
```text
$ sq packet join alice.pub-0--PublicKey alice.pub-1--Signature --output alice_minimal.pub
```
This command combines the contents of `alice.pub-0--PublicKey` and `alice.pub-1--Signature` into a single file named `alice_minimal.pub`.
### Inspecting this certificate
This version of Alice's certificate contains just two packets:
- The [*Public-Key packet*](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-public-key-packet-formats) for the primary key, and
- A [*Direct Key Signature*](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#sigtype-direct-key) (a self-signature that binds metadata to the primary key).
- the [*Public-Key packet*](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-public-key-packet-formats) for the primary key, and
- a [*Direct Key Signature*](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#sigtype-direct-key), which is a self-signature that binds metadata to the primary key.
This is the shape of the packets we'll be looking at, in the following two sections:
This is the shape of the packets we'll explore in the subsequent sections:
```{figure} diag/pubcert-minimal.png
:width: 40%
@ -83,9 +91,9 @@ This diagram needs adjustments about
We could show repeat-copies of the individual packet visualization again, below for each packet-related section.
```
In the real world, you won't usually encounter an OpenPGP certificate that is quite this minimal. However, this is technically a valid OpenPGP certificate (and we'll add more components to it, later in this section).
In real-world scenarios, OpenPGP certificates are typically far more complex than this minimal example. However, this is indeed a valid OpenPGP certificate. In the following sections, we will introduce more components to this certificate, increasing its complexity and exploring their details.
In ASCII-armored representation, this very minimal key looks like this:
In ASCII-armored representation, this very minimal key appears as follows:
```text
-----BEGIN PGP PUBLIC KEY BLOCK-----
@ -99,18 +107,20 @@ gAIl6FM5SWuQxg12j0S07ExCOI5NPRDCrSnAV85mAXOzeIGeiVLPQ40oEal3CX/L
-----END PGP PUBLIC KEY BLOCK-----
```
We'll now decode this OpenPGP data, and inspect the two packets in detail.
The output of `sq` is presented as a block of text. We will now decode this OpenPGP data and inspect the two packets it contains.
To inspect the internal structure of the OpenPGP data, we run the Sequoia-PGP tool `sq`, using the `packet dump` subcommand. The output of `sq` is one block of text, but to discuss the content of each packet we'll break the output up into sections here:
To achieve this, we will use the Sequoia-PGP tool `sq` and run the `packet dump` subcommand:
```text
$ sq packet dump --hex alice_minimal.pub
```
This will allow us to gain a detailed understanding of the packet contents.
(public_key)=
### Public-Key packet
The output now starts with a (primary) [Public-Key packet](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-public-key-packet-formats):
The output begins with a (primary) [Public-Key packet](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-public-key-packet-formats):
```text
Public-Key Packet, new CTB, 2 header bytes + 42 bytes
@ -132,23 +142,23 @@ Public-Key Packet, new CTB, 2 header bytes + 42 bytes
00000020 eb e7 42 e2 ab 47 f4 86 b3 ae 65 3e
```
The Public-Key packet consists in large part of the actual cryptographic key data. Let's look at the packet field by field:
The Public-Key packet consists primarily of the cryptographic key data. Let's look at the packet field by field:
- `CTB: 0xc6`[^CTB]: The [packet type ID](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-packet-headers) for this packet. The binary representation of the value `0xc6` is `11000110`. Bits 7 and 6 show that the packet is in *OpenPGP packet format* (as opposed to in *Legacy packet format*). The remaining 6 bits encode the type ID's value: "6". This is the value for a Public-Key packet, as shown in the list of [packet type IDs](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-packet-tags).
- `length: 0x2a`: The remaining length of this packet.
- `CTB: 0xc6`[^CTB]: This is the [packet type ID](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-packet-headers) for this packet. The binary representation of the value `0xc6` is `11000110`. The first two bits show that the packet is in *OpenPGP packet format* (as opposed to in *Legacy packet format*) and the remaining 6 bits encode the type ID value, which is "6." This type ID value corresponds to a Public-Key packet, as listed in the [packet type IDs](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-packet-tags).
The packet type id defines the semantics of the remaining data in the packet. We're looking at a Public-Key packet, which is a kind of [Key Material Packet](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-key-material-packets).
- `length: 0x2a`: This indicates the remaining length of this packet. The packet type ID defines the semantics of the remaining data within the packet. In this case, it is a Public-Key packet, which is a kind of [Key Material Packet](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-key-material-packets).
- `version: 0x06`: The key material is in version 6 format
- `version: 0x06`: The key material is in version 6 format. This means that the next part of the packet adheres to the structure of [Version 6 Public Keys](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-version-6-public-keys).
This means that the next part of the packet follows the structure of [Version 6 Public Keys](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-version-6-public-keys)
- `creation_time: 0x6516eaa6`: This field represents the key's creation time. (See also [Time Fields](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-time-fields)).
- `creation_time: 0x6516eaa6`: "The time that the key was created" (also see [Time Fields](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-time-fields))
- `pk_algo: 0x1b`: "The public-key algorithm ID of this key" (decimal value 27, see the list of [Public-Key Algorithms](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-public-key-algorithms))
- `public_len: 0x00000020`: "Octet count for the following public key material" (in this case, the length of the following `ed25519_public` field)
- `ed25519_public`: [Algorithm-specific representation](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-algorithm-specific-part-for-ed2) of the public key material (the format is based on the value of `pk_algo`), in this case 32 bytes of Ed25519 public key
- `pk_algo: 0x1b`: This corresponds to the key's public-key algorithm ID, which has a decimal value of 27. Refer to the list of [Public-Key Algorithms](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-public-key-algorithms)) for more details.
[^CTB]: Sequoia uses the term CTB (Cipher Type Byte) to refer to the RFC's [packet type ID](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-packet-headers). In previous versions, the RFC called this field "Packet Tag".
- `public_len: 0x00000020`: This section specifies the octet count for the subsequent public key material. In this case, it represents the length of the following `ed25519_public` field.
- `ed25519_public`: This is the [algorithm-specific representation](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-algorithm-specific-part-for-ed2) of the public key material. The format is based on the value of `pk_algo`, which, in this case, is 32 bytes of Ed25519 public key data.
[^CTB]: Sequoia uses the term CTB (Cipher Type Byte) to refer to the RFC's [packet type ID](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-packet-headers). In earlier RFC versions, this field was known as the "Packet Tag."
```{tip}
@ -160,9 +170,9 @@ Note that the *Public-Key packet* contains only the public part of the key.
(zooming_in_dks)=
### Direct Key Signature
The next packet is a [*Direct Key Signature*](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#sigtype-direct-key), which is bound to the primary key (the file `alice.pub-1--Signature` contains this packet).
The next packet in the certificate is a [*Direct Key Signature*](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#sigtype-direct-key), which plays a crucial role in binding specific information to the primary key. This signature is contained within the file `alice.pub-1--Signature`.
This packet "binds the information in the signature subpackets to the key". Each entry under "Signature Packet -> Hashed area" is one signature subpacket, for example, including information about algorithm preferences (*symmetric algorithm preference* and *hash algorithm preferences*).
This packet binds the information within the signature subpackets with the primary key. Each entry under "Signature Packet -> Hashed area" is one signature subpacket, for example, including information about algorithm preferences (*symmetric algorithm preference* and *hash algorithm preferences*).
```text
Signature Packet, new CTB, 2 header bytes + 182 bytes