<!--
SPDX-FileCopyrightText: 2023 The "Notes on OpenPGP" project
SPDX-License-Identifier: CC-BY-SA-4.0
-->

(component_signatures_chapter)=
# Signatures on components

This chapter examines OpenPGP signatures associated with certificate components, applying to: 

- component keys, encompassing primary keys and subkeys
- identity components, namely User IDs and User attributes

Signatures on components are used to construct and maintain certificates, and to model the authentication of identities.

This chapter expands on topics introduced in the {ref}`certificates_chapter` chapter.

## Self-signatures vs third-party signatures

Component signatures in OpenPGP are categorized into two distinct types:

- **self-signatures**, which are issued by the certificate holder  using the certificate's primary key
- **third-party signatures**, which are issued by an external entity, not the certificate holder

### Self-signatures

Self-signatures are fundamental in creating and managing OpenPGP certificates. They bind the various components of a certificate into one combined data structure and facilitate the certificate's life-cycle management.

Life-cycle management operations include:

- binding additional components to a certificate
- modifying expiration dates or other metadata of components
- revoking, and thus invalidating, components or existing self-signatures 

Self-signatures are issued by the certificate's owner using the certificate's primary key.
 
```{note}
No [key flag](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-key-flags) is required to issue self-signatures. An OpenPGP primary key can issue self-signatures by default.
```

### Third-party signatures

Third-party signatures are pivotal in OpenPGP for decentralized authentication, forming the basis of the Web of Trust. They encode authentication-related statements about certificates and linked identities, establishing trustworthiness of identity claims.

Third-party signatures are used to make specific statements:

- certifying identity claims
- delegating authentication decisions
- revoking, and thus invalidating, prior third-party signature statements

```{note}
The **certify others** [key flag](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-key-flags) (`0x01`) is required to issue third-party signatures. Typically, only the certificate's primary can hold this key flag.
```

### Distinct functions of self-signatures and third-party signatures

The meaning of an OpenPGP signature depends significantly on its issuer. Self-signatures and third-party signatures, even when of the same [signature type](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-signature-types), serve distinct functions. For example:

- Certifying self-signatures (type IDs `0x10` - `0x13`) bind a User ID to a certificate.
- Third-party signatures of the same type IDs endorse the authenticity of a User ID claimed by the holder of a certificate.

In another instance:

- *When issued as a self-signature*, a [direct key signature](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-direct-key-signature-type-i) sets preferences and advertises features applicable to the entire certificate.
- *When issued by a third party*, especially when it carries a [trust signature](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-trust-signature) subpacket, a similar direct key signature delegates trust to the signed certificate. This may designate the signed certificate as a trust root within the issuer's Web of Trust.

## Self-signatures in certificate formation and management

Self-signatures play a crucial role in forming and managing the structure of OpenPGP certificates. These act as *binding signatures*, joining components and embedding metadata.

Internally, an OpenPGP certificate is essentially a series of packets strung sequentially. When a certificate is stored in a file format known as a [transferable public key](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-transferable-public-keys), packets can be easily added or removed.

To safeguard against unauthorized additions and alterations of components, OpenPGP uses cryptographic signatures. These validate that any additions, such as added subkeys or [identity components](identity_components), were made by the owner of the OpenPGP certificate using its primary key. While anyone can still store unrelated elements to a certificate dataset, OpenPGP implementations will reject them if they lack a valid cryptographic connection with the certificate.

```{note}
Conversely, omissions of packets by third parties can easily occur when handling an OpenPGP certificate dataset. This could pose a challenge, for example, when an attacker deliberately omits revocation packets. Without access to an alternative, complete certificate source, recipients might not detect these omissions.
```

However, there are legitimate instances in which third parties add "unbound" packets (i.e., not signed by the certificate's owner) to a certificate:

- [Third-party certifications](third_party_cert) are often stored within the packet data of the certificate to which they are related. This is a standard practice that provides convenience for users by allowing easy access to all relevant certifications. (See {ref}`cert-flooding` for discussion of a related pitfall.)
- OpenPGP software may locally add [unbound identity data](unbound_user_ids) to a certificate.

(bind_subkey)=
### Binding subkeys to a certificate

Subkeys are linked to OpenPGP certificates via a [subkey binding signature](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#sigtype-subkey-binding) (type ID `0x18`). This signature type indicates the association of the primary key with the subkey.

A subkey binding signature binds a subkey to a primary key, and it embeds metadata into the signature packet. Once generated, the subkey binding signature packet is stored in the certificate directly after the subkey it binds.

Subkeys designated for signing purposes, identified by the *signing* [key flag](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-key-flags), represent a unique category and are handled differently. See {numref}`bind_subkey_sign`.

```{figure} diag/subkey_binding_signature.png
:name: fig-subkey-binding-signature
:alt: Depicts a diagram on white background with the title "Subkey binding signature". At the top left the symbol of a primary component key with certification capability is shown. At the bottom left the symbol of a component key with encryption capability is shown. The primary component key points at the lower component key with a full green arrow line. In the middle of the connection the small symbol of a signature packet is shown. On the right side of the diagram a detailed version of the signature packet can be found in a box with the title "Subkey binding signature". The text reads "Signature over Primary key, Subkey" and the box with "Signature metadata" contains the list "signature creation time", "key expiration time", "key flags" and "issuer fingerprint". The primary component key points at the detailed signature packet with a dotted green arrow line and the text "Primary key creates a subkey binding signature to bind the subkey to the primary key".

Linking an OpenPGP subkey to the primary key with a binding signature
```

Metadata for the subkey, such as the [*key expiration time*](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#key-expiration-subpacket) and capabilities set by [*key flags*](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#key-flags), are included in subpackets within the subkey binding signature packet.

```{note}
The validity of a subkey is intrinsically linked to that of the primary key. An expired primary key renders any associated subkey invalid, regardless of the subkey's own expiration setting.

Legally, a subkey may not have a specified expiry time. In such cases, its expiration aligns implicitly with that of the primary key. Additionally, the creation date of a subkey must always be more recent than that of the primary key.
```

(bind_subkey_sign)=
### Special case: Binding signing subkeys

Binding subkeys that possess the *signing* key flag to a certificate represents a unique scenario. While similar to the binding process of other subkeys, there is an additional, critical requirement: mutual association.

That is, to bind a signing-capable subkey to a primary key, it is insufficient that the "primary key wants to be associated with the subkey." The subkey must explicitly signal that it "wants to be associated with the primary key."

This mutual binding is crucial for security. Without it, an individual (e.g., Alice) could falsely claim a connection to another person's (e.g., Bob's) signing subkey.
As a consequence, Alice could claim to have issued signatures which were in fact issued by Bob.
To prevent such scenarios, where an attacker might wrongfully "adopt" a victim's signing subkey, a dual-layer of signatures is used:

- the [subkey binding signature](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#sigtype-subkey-binding) (type ID `0x18`), which is issued by the certificate's primary key
- the [primary key binding signature](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#sigtype-primary-binding) (type ID `0x19`), created by the subkey itself. This is informally known as an embedded "back signature," because the subkey's signature points back to the primary key.

```{figure} diag/subkey_binding_signatur_for_signing_sk.png
:name: fig-subkey-binding-signature-for-signing-subkeys
:alt: Depicts a diagram on white background with the title "Subkey binding signature for signing subkeys". At the top left the symbol of a primary component key with certification capability is shown. At the bottom left the symbol of a component key with signing capability is shown. The primary component key points at the lower component key with a full green arrow line. In the middle of the connection the small symbol of a signature packet is shown. On the right side of the diagram a detailed version of the signature packet can be found in a box with the title "Subkey binding signature". The text reads "Signature over Primary key, Subkey" and the box with "Signature metadata" in it contains the list "signature creation time", "key expiration time", "key flags" and "issuer fingerprint". Within the signature metadata a box with a green dotted frame extends the list with an inlined signature packet with the title "Embedded Signature; Primary key binding". Its inner text reads "Signature over Primary Key, Signing Subkey". The signature metadata area of this embedded signature holds the list "signature creation time" and "issuer fingerprint". The cryptographic signature symbol overlaps both metadata and general section of the embedded signature. From the signing component key a green dotted arrow line points to the embedded signature in the subkey binding signature with the text "Signing key creates a primary binding signature to associate itself with the primary key" ("primary binding signature" in bold). At the top of the diagram, the primary component key points at the detailed signature packet with a dotted green arrow line and the text "Primary key creates a subkey binding signature to bind the subkey to the primary key".

Linking an OpenPGP signing subkey to the primary key with a binding signature, and an embedded primary key binding signature
```

The back signature signifies the mutuality of the subkey's association with the primary key and is embedded as subpacket data within the subkey binding signature, reinforcing the authenticity of the binding.

(bind_ident)=
### Binding identities to a certificate

Self-signatures also play a vital role in binding identity components, such as User IDs or User Attributes, to an OpenPGP certificate.

To bind the User ID `Alice Adams <alice@example.org>` to her OpenPGP certificate (`AAA1 8CBB 2546 85C5 8358 3205 63FD 37B6  7F33 00F9 FB0E C457 378C D29F 1026 98B3`), Alice would use a certification signature.

There are four types of *certifying self-signature*. According to the specification, the most commonly used type for binding User IDs is the [generic certification](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-generic-certification-of-a-) (type ID `0x10`). Alternatively, types `0x11`, `0x12` or `0x13` might be used. This binding signature must be issued by the primary key.

The certifying self-signature packet – calculated over the primary key, User ID, and metadata of the signature packet – is added to the certificate, directly following the User ID packet.

```{figure} diag/user_id_certification.png
:name: fig-user-id-certification
:alt: Depicts a diagram on white background with the title "User ID binding signature". At the top left the symbol of a primary component key with certification capability is shown. At the bottom left the symbol of a User ID reads "Alice Adams <alice@example.org>". The primary component key points at the User ID with a full green arrow line. In the middle of the connection the small symbol of a signature packet is shown. On the right side of the diagram a detailed version of the signature packet can be found in a box with the title "User ID binding signature". The text reads "Signature over Primary key, User ID" and the box with "Signature metadata" in it contains the list "signature creation time", "key expiration time", "primary User ID flag", "algorithm preferences", "key expiration time (primary key)" and "key flags (primary key)". At the top of the diagram, the primary component key points at the detailed signature packet with a dotted green arrow line and the text "Primary key creates a User ID binding signature to associate the User ID with the primary key".

Linking a User ID to an OpenPGP certificate
```

(primary-metadata)=
### Adding metadata to the primary key/certificate

The signatures that bind subkeys and identity components to a certificate serve dual purposes: linking components to the certificate and adding scoped metadata to components.

Unlike subkeys and User IDs, the primary key of a certificate doesn't require a linking signature since it serves as the central anchor of the certificate.

Metadata can be added to the primary key via two mechanisms:

- direct key signature on the primary key
- *primary User ID* binding signature

The types of metadata typically associated with the primary key through these methods include:

- key expiration
- key flags
- features
- algorithm preference signaling

(direct_key_signature)=
#### Direct key signature

A [*direct key signature*](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-direct-key-signature-type-i) serves as a key mechanism for storing information about the primary key and the entire certificate.

In OpenPGP v6, a direct key signature is the [preferred mechanism](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#section-5.2.3.10-9) for storing algorithm preferences and features.

#### Self-signature binding to primary User ID

In an OpenPGP certificate, one User ID serves as the [*primary* User ID](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-primary-user-id). The metadata in the binding self-signature on this User ID applies to the certificate's primary key.

(self-revocations)=
### Revocation self-signatures: Invalidating certificate components

Revocation self-signatures represent an important class of self-signatures, used primarily to invalidate components or retract prior signature statements.

There are several types of revocation signatures, each serving a specific purpose:

- A [**key revocation signature**](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-key-revocation-signature-ty) (type ID `0x20`) marks a primary key as revoked.
- A [**subkey revocation signature**](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-subkey-revocation-signature) (type ID `0x28`) invalidates the binding of a subkey.
- A [**certification revocation**](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-certification-revocation-si) (type ID `0x30`) invalidates the binding of a User ID or User Attribute.

Common scenarios for using revocations include marking certificates or individual subkeys as unusable (e.g., when the private key has been compromised or replaced) or declaring User IDs as no longer valid.

```{note}
OpenPGP certificates act as append-only data structures in practice. Once elements of a certificate are published, they cannot be removed from key servers or third-party OpenPGP systems. Implementations usually merge all available components and signatures.

Revocations are used to mark components or signatures as invalid.
```

```{admonition} TODO
:class: warning

Research, under what circumstances revocations revoke individual signatures, and when they instead "unbind" components.
```

Note: certification signatures [can be made irrevocable](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-revocable).

#### Hard vs soft revocations

Revocation signatures often include a [*Reason for Revocation* subpacket](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-reason-for-revocation), with a code specifying *why* the revocation was issued. This code determines whether the revocation is considered *soft* or *hard*.

- **Soft revocation**: This is typically used for graceful or planned invalidation of components, such as retiring or updating components. It invalidates the component from the revocation signature's creation time, but earlier uses remain valid. Soft revocations can be reversed with a new self-signature.
- **Hard revocation**: This irrevocably invalidates the component, affecting all past and future uses. It is typically used to signal compromise of secret key material.

```{note}
A revocation signature lacking a *Reason for Revocation* subpacket is interpreted as a hard revocation.
```

(third_party_cert)=
## Authentication and delegation in third-party signatures 

Third-party signatures in OpenPGP primarily encode authentication statements for identities and delegate trust decisions. These signatures can be manually inspected or processed as machine-readable artifacts by OpenPGP software, which evaluates the authenticity of certificates based on user-specified trust roots.

### Certifying identity components

When a signer issues a certifying signature on an identity, it indicates a verified link between the identity and the certificate. That is, the signer vouches for the identity claim.

For example, Alice can vouch that Bob's User ID `Bob Baker <bob@example.com>` is legitimately linked with his certificate `BB28 9FB7 A68D BFA8 C384 CCCD E205 8E02  D9C6 CD2F 3C7C 56AE 7FB5 3D97 1170 BA83`, by creating a certification signature. Bob can then distribute Alice's certifying signature as part of his certificate.

Other users may or may not decide to rely on Alice's statement when questioning the authenticity of Bob's certificate.

### Trust signatures: delegating authentication

OpenPGP uses [*trust signature*](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#trust-signature-subpacket) subpackets to delegate authentication decisions, designating the recipient certificate as a "trusted introducer" (or a trust root) for the user. This includes specifying trust depth (or level) for transitive delegations and quantifying trust with numerical values, indicating the extent of reliance on the introducer's certifications.

Trust signature subpackets are applicable in *third-party* signatures, more specifically:

- identity certification signatures (type ID `0x10` - `0x13`)
- [direct key signatures](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-direct-key-signature-type-i) (type ID `0x1F`)

#### Trust depth/level

The "trust depth" (or level) in OpenPGP signifies the extent of transitive delegation within the authentication process. It determines how far a delegation can be extended from the original trusted introducer to subsequent intermediaries. Essentially, a certificate with a trust depth of more than one acts as a "meta-introducer," facilitating authentication decisions across multiple levels in the network.

A trust depth of 1 means relying on certifications made directly by the trusted introducer. The user's OpenPGP software will accept certifications made directly by the introducer for authenticating identities. 

However, when the trust depth is set higher, it implies a chain of delegation may extend beyond the initial introducer. The user's software will recognize and accept certifications made not only by the primary introducer but also by other intermediaries whom the primary introducer designated as trusted introducers. 

This allows for a more extensive network of trusted certifications, enabling a broader and more interconnected Web of Trust.

```{admonition} VISUAL
:class: warning

Illustrate with diagram(s). Notes for diagrams:

When Alice delegates trust decisions to Trent, designating Trent as a trusted introducer with a *trust depth* of 1, then Alice's OpenPGP implementation will only accept direct certifications by Trent. For example, Trent may have certified that Bob's certificate with the fingerprint `0xB0B` is legitimately connected to Bob's User ID `Bob <bob@example.org>`. If Alice tries to communicate with Bob using his identity `Bob <bob@example.org>`, then Alice's OpenPGP software can automatically determine that the certificate `0xB0B` is appropriate to use.

However, Alice's OpenPGP software wouldn't accept a series of delegations from Trent via Tristan to a certification of Carol's identity (let's imagine that Trent has designated Tristan a trusted introducer). For Alice's OpenPGP software to accept such a path, she needs to designate Trent as a trusted introducer with the `level` set to 2 or more.
```

#### Trust amounts

The "trust amount," with a numerical value ranging from 0 to 255, quantifies the degree of reliance on a delegation.  

A higher value indicates greater degree of reliance. This quantification aids OpenPGP software in determining an aggregate amount of reliance, based on combined certifications from multiple trusted introducers.

```{admonition} VISUAL
:class: warning

Illustrate with diagram(s). Notes for diagrams:

If Alice designates Trent as a trusted introducer at a trust amount of 120, then Alice's OpenPGP software will consider Bob's identity fully authenticated if Trent has certified it.

However, if Alice only assigns a trust amount of 60 (which indicates "partial trust") to Trent, then her software would not consider Bob's identity fully authenticated. Now let's imagine that Alice additionally assigns a trust amount of 60 to Tristan (a second, independent introducer), and Tristan also certified Bob's identity. In this case, Alice's OpenPGP software will consider Bob's identity fully authenticated, based on the combination of both delegations, and the certifications the two trusted introducers issued.
```

#### Limiting delegation scope

When using *trust signature* subpackets, a delegation can be limited to identities that match a [*regular expression*](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#regex-subpacket). 

With this mechanism, for example, it is possible to delegate authentication decisions only for User IDs that match the email domain of an organization.

```{admonition} VISUAL
:class: warning

Illustrate with diagram(s). Notes for diagrams:

For example, Alice could delegate trust decisions only for email addresses in the domain `bob.com` to Bob, if she considers Bob to be a reasonable source of identity certifications for that domain.
```

(wot)=
### Web of Trust: Decentralized trust decisions

The Web of Trust in OpenPGP is a trust model that facilitates authentication decisions through a network of certifications and delegations. It is characterized by a so-called [strong set](https://en.wikipedia.org/wiki/Web_of_trust#Strong_set), which refers to a group of certificates that are robustly interconnected via third-party certifications.

In this model, users independently delegate authentication decisions, choosing whose certification to rely on. This delegation is based on the certificates and third-party signatures available to them, with their OpenPGP software applying the Web of Trust mechanism to discern the reliability of each certificate for an identity.

The OpenPGP RFC doesn't specify exactly how Web of Trust calculations are performed. It only defines the data formats on which these calculations can be performed. See external resources in {numref}`wot-resources`.

### Revoking third-party signatures

To reverse a previously issued third-party signature, the issuer can generate a [*certification revocation signature*](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-certification-revocation-si) (type ID `0x30`). The revocation must be issued by the same key that created the original signature or, in deprecated practice, by a designated [Revocation Key](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-revocation-key). 

## Advanced topics

### Certification recipes

Different signatures in OpenPGP serve various specific purposes. This section provides practical guidance on creating these signatures, illustrating each with concrete examples.

#### Change algorithm preferences

To modify the preferred symmetric, compression, hash, or AEAD algorithms for a key, the key owner needs to issue a direct-key signature (type `0x1F`) on the primary key.

This signature should have the following structure:

| Subpacket                       | Area   | Critical       | Mandatory         | Notes                                              |
|---------------------------------|--------|----------------|-------------------|----------------------------------------------------|
| Signature Creation Time         | Hashed | True           | True              | Current time                                       |
| Issuer Fingerprint              | Hashed | True or False  | Strongly Recommended | The primary key is the issuer                     |
| Key Flags                       | Hashed | True           | False             | Retain key flags from the previous self-signature  |
| Features                        | Hashed | True           | False             | Retain features from the previous self-signature   |
| Key Expiration Time             | Hashed | True           | False             | Retain expiration time from the previous self-signature, if applicable |
| Hash Algorithm Preferences      | Hashed | False          | False             | New preferences                                    |
| Compression Algorithm Preferences | Hashed | False        | False             | New preferences                                    |
| Symmetric Algorithm Preferences | Hashed | False          | False             | New preferences                                    |
| AEAD Algorithm Preferences      | Hashed | False          | False             | New preferences                                    |

#### Change expiration time

To adjust the expiration time of an OpenPGP certificate, a new *DirectKey* signature (type `0x1F`) with a modified Key Expiration Time subpacket must be issued. The structure of this signature is identical to the one outlined in the previous section on changing algorithm preferences.

Additionally, the expiration date can be altered for individual User IDs (detailed below) or separate subkeys (see {numref}`bind_subkey`).

#### Add User ID

To bind a User ID to an OpenPGP certificate a certification signature (type `0x10`-`0x13`) is used which should have the following structure:

| Subpacket               | Area   | Critical       | Mandatory         | Notes                                           |
|-------------------------|--------|----------------|-------------------|-------------------------------------------------|
| Signature Creation Time | Hashed | True           | True              | Current time                                    |
| Issuer Fingerprint      | Hashed | True or False  | Strongly Recommended | The primary key is the issuer                  |
| Primary User ID         | Hashed | True           | False             | Optional                                        |
| Signature Expiration Time | Hashed | True         | False             | Optional                                        |

In addition to these subpackets, self-certifications for User IDs can include others – such as key flags, features, and algorithm preferences – as shown in the previous table. This enables the specification of unique capabilities and preferences for each identity associated with the certificate.

#### Remove or revoke a User ID

Since OpenPGP certificates are often distributed by the means of key servers, new signatures on a certificate are often "merged" into existing copies of the certificate locally by the recipient.

```{admonition} TODO
:class: warning

Link to the "Merging" section in chapter 4, once merged.
```

This integration process means it is practically impossible to directly remove signatures or User IDs from a certificate, as there is no way to communicate the intention of packet deletion to the recipient.

To effectively mark a User ID as invalid, the user can publish a copy of their certificate with a *CertificationRevocation* signature (type `0x30`) attached to the invalidated User ID. This signature signals that the specified User ID is no longer valid or associated with the certificate holder.

The structure of a *CertificationRevocation* is as follows:

| Subpacket               | Area   | Critical       | Mandatory         | Notes                                           |
|-------------------------|--------|----------------|-------------------|-------------------------------------------------|
| Signature Creation Time | Hashed | True           | True              | Current time                                    |
| Issuer Fingerprint      | Hashed | True or False  | Strongly Recommended | The primary key is the issuer                  |
| Reason for Revocation   | Hashed | True           | False             | Determines soft or hard revocation             |

For User ID revocations, the *Reason for Revocation* subpacket is crucial. A value of `0` means no specific reason, leading to a hard revocation, while `32` indicates the User ID is no longer valid, resulting in a soft revocation. Omitting the reason subpacket is also equivalent to a hard revocation.

It is generally advisable to use reason code `32` for revoking User IDs.

(binding_subkeys)=
#### Add a subkey

As part of lifecycle management, the user may need to add a new subkey to their OpenPGP certificate, often for reasons such as upgrading to a subkey with more advanced cryptographic algorithms. The process involves creating a specific signature structure:

| Subpacket                     | Area   | Critical       | Mandatory         | Notes                                               |
|-------------------------------|--------|----------------|-------------------|-----------------------------------------------------|
| Signature Creation Time       | Hashed | True           | True              | Current time                                        |
| Issuer Fingerprint            | Hashed | True or False  | Strongly Recommended | The primary key is the issuer                     |
| Key Flags                     | Hashed | True           | Strongly Recommended | Determine the usage of the key                    |
| Key Expiration Time           | Hashed | True           | False             | Specifies the expiration date of the subkey         |
| Embedded Signature            | Hashed | True           | If Key Flags contains **S** | Signing subkeys require embedded *Primary Key Binding* signature |
| Hash Algorithm Preferences    | Hashed | False          | False             | Per key preferences                                 |
| Compression Algorithm Preferences | Hashed | False      | False             | Per key preferences                                 |
| Symmetric Algorithm Preferences | Hashed | False        | False             | Per key preferences                                 |
| AEAD Algorithm Preferences    | Hashed | False          | False             | Per key preferences                                 |

In addition to these subpackets, users can specify algorithm preferences for each subkey, distinct from those set in the certificate's *DirectKey* signature. 

#### Revoke a subkey

Subkeys, like User IDs, can be individually revoked in OpenPGP. 
This is done by issuing a `SubkeyRevocation` signature (type `0x28`) using the primary key.

The structure of such a signature is straightforward:

| Subpacket               | Area   | Critical       | Mandatory         | Notes                                           |
|-------------------------|--------|----------------|-------------------|-------------------------------------------------|
| Signature Creation Time | Hashed | True           | True              | Current time                                    |
| Issuer Fingerprint      | Hashed | True or False  | Strongly Recommended | The primary key is the issuer                  |
| Reason for Revocation   | Hashed | True           | False             | Determines soft or hard revocation             |


In `SubkeyRevocation` signatures, the [reason for revocation](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-reason-for-revocation) subpacket can only have values in the range of `0-3`. The values `1` (key superseded) and `3` (key retired and no longer used) indicate soft revocations, whereas values `0` (no reason) and `2` (key compromised) indicate hard revocations. 

Note that a value of `32` is not applicable in these signatures.

```{admonition} TODO
:class: warning

Research and explain hardness in the context of subkey revocations. What does a hard subkey revocation express concretely?
```

#### Revoke a certificate

Users may find themselves needing to revoke their entire OpenPGP certificate, rendering it unusable. This could be for various reasons, such as migrating to a new certificate or in response to a compromise of the certificate's secret key material. 

While a soft-revoked certificate can be re-validated at a later time with a new certification, a hard revocation is permanent.

The recommended way to revoke a certificate is by issuing a *KeyRevocation* signature (type `0x20`). Its structure is similar to that of a *CertificationRevocation* signature.

| Subpacket               | Area   | Critical       | Mandatory         | Notes                                           |
|-------------------------|--------|----------------|-------------------|-------------------------------------------------|
| Signature Creation Time | Hashed | True           | True              | Current time                                    |
| Issuer Fingerprint      | Hashed | True or False  | Strongly Recommended | The primary key is the issuer                  |
| Reason for Revocation   | Hashed | True           | False             | Determines soft or hard revocation             |

For *KeyRevocation* signatures, the guidelines regarding the [*Reason for Revocation* subpacket] (https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-reason-for-revocation) are the same as those for *SubkeyRevocation* signatures.

#### Common subpackets in OpenPGP signatures

In OpenPGP, certain subpackets are universally expected across all types of signatures, serving fundamental roles in the signature's structure and verification:

* **Signature Creation Time**: This is a mandatory subpacket in every OpenPGP signature. It contains the timestamp of when the signature was created. For security and integrity, this subpacket must be located in the hashed area of the signature and is recommended to be marked as critical.

* **Issuer Fingerprint**: Essential for signature verification, this subpacket identifies the key (or subkey) that was used to create the signature. OpenPGP v6 signatures should include the Issuer Fingerprint subpacket, containing the 32-byte fingerprint of the key. 

```{note}
The key used as the issuer in the signature might be a subkey of the certificate.
```

This subpacket can be placed in either the hashed or unhashed area due to its self-authenticating nature. However, we recommend including it in the signature's hashed area.

### Managing subpacket conflicts and duplication

In OpenPGP signatures, both the hashed and unhashed areas are composed of lists of subpackets. Inherently, this structure permits the duplication of the same subpacket, which could lead to conflicts. To manage these potential conflicts, the following strategies are used:

- **Precedence of hashed area**: Subpackets within the hashed area of a signature take precedence over those in the unhashed area. This hierarchy helps resolve conflicts when the same subpacket appears in both areas.

- **Handling conflicts within the same area**: Conflicts can still arise within the same area, such as when two subpackets have different expiration dates. In such cases, the [OpenPGP specification](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-notes-on-subpackets) advises that implementations should favor the last occurrence of a conflicting subpacket in the hashed area.

In certain scenarios, having duplicate subpackets with conflicting content is logical and even necessary. For example, consider a signature created by a version 4 issuer key, which was upgraded from an older OpenPGP version (like v3). Since the key ID calculation scheme changed from v3 to v4, the identifiers for the same key would differ between these versions. Therefore, a v4 signature might contain two issuer key ID subpackets, each with different, yet correct values for v3 and v4 keys, respectively. This allows for backward compatibility and ensures the signature can be validated under both key ID calculation schemes.