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.
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 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 and verification.
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. Only the certificate's primary holds this key flag.
The meaning of an OpenPGP signature depends significantly on its issuer. Self-signatures and third-party signatures, even when of the same type, serve distinct functions. For example:
- *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 designates the signed certificate as a trust root within the issuer's *Web of Trust*.
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, OpenPGP uses cryptographic signatures. These validate that any additions, such as 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 subkeys and identity components to a certificate dataset, OpenPGP implementations typically reject components lacking a valid cryptographic connection with the certificate.
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 instances – legitimate and malicious – 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. However, in systems that unconditionally accept these certifications, it can lead to unintended consequences. Specifically, this approach has been exploited to cause denial-of-service attacks through [certificate flooding](https://dkg.fifthhorseman.net/blog/openpgp-certificate-flooding.html), a problem notably experienced by the SKS network of OpenPGP servers.
- OpenPGP software may locally append [unbound identity data](unbound_user_ids) 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`.
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.
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.
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. 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.
The back signature signifies the mutuality of the subkey's association with the primary key and is embedded within the subkey binding signature, reinforcing the authenticity of the binding.
Take for instance, the User ID `Alice Adams <alice@example.org>`. To link this User ID to her OpenPGP certificate (e.g., `AAA1 8CBB 2546 85C5 8358 3205 63FD 37B6 7F33 00F9 FB0E C457 378C D29F 1026 98B3`), Alice would use a cryptographic signature.
There are four types of *certifying self-signature*. The most commonly used type for binding User IDs is the [positive certification](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#sigtype-positive-cert) (type ID `0x13`). Alternatively, types `0x10`, `0x11` or `0x12` 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 then appended to the certificate, directly following the User ID packet.
The signatures that bind subkeys and identity components to a certificate serve dual purposes: linking components to the certificate and adding metadata to components.
Unlike these components, the primary key of a certificate doesn't require a linking signature since it serves as the central anchor of the certificate. However, associating metadata with the primary key is still essential, as it generally applies to the entire certificate.
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).
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.
Revocation self-signatures represent an important class of self-signatures, used primarily to invalidate components or retract prior signature statements.
- 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`) revokes a prior subkey binding signature.
- A [**certification revocation**](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-certification-revocation-si) (type ID `0x30`) revokes a certification signature.
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.
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.
A revocation signature can contain a subpacket indicating the [*reason for revocation*](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-reason-for-revocation). The value of this subpacket contains a code that specifies why the revocation was issued. This code determines whether the revocation is considered a *soft revocation* or a *hard revocation*:
- A *soft revocation* is typically used for graceful or planned invalidation. Soft revocation of a component invalidates it from the revocation signature's creation time onwards. Uses of the component before the revocation time remain intact. Soft revocations can be reverted by re-validating the invalidated component with a new self-signature.
- A *hard revocation*, by contrast, invalidates the component retroactively, rendering all past and future uses invalid. Hard revocation of a component cannot be undone by re-validating the component.
Soft revocations are typically used when a certificate, subkey or User ID is retired or superseded gracefully, while hard revocations are typically used to signal compromise of secret key material.
Signatures on components by third parties mainly encode authentication of identities and delegations of trust decisions.
Third party signatures can be inspected and reasoned about manually by humans. More powerfully, though, they can also be used as machine-readable artifacts, by OpenPGP software, which can reason about the authenticity of certificates on behalf of its users, based on trust roots that the user has specified.
### Certifying identity components
By issuing a certifying signature on an identity, the signer expresses that he has verified that the identity and the certificate are meaningfully linked. The signer vouches for the connection between the certificate and the identity.
If Alice is certain that the identity `Bob Baker <bob@example.com>` controls the certificate `0xB0B`, she can create a certification signature that binds Bob's User ID and Bob's certificate. Bob will usually distribute this certifying signature from Alice as part of his certificate.
Effectively, this is a way for Alice to broadcast the statement "I, Alice, have checked that `Bob Baker <bob@example.com>` controls the certificate `0xB0B`." Other users may or may not decide to rely on this statement by Alice.
The OpenPGP standard specifies primitives to delegate authentication decisions to certificates. The standard uses the (somewhat confusing) term "trust" for this mechanism. Delegating authentication decisions to a certificate, using a [*trust signature*](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#trust-signature-subpacket) subpacket, makes the target certificate a "trusted introducer."
A "trusted introducer" acts as a trust root for the user.
[*Trust signature*](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#trust-signature-subpacket) subpackets can be used in two types of signatures:
- On an identity certification signature (type ID `0x10` - `0x13`), or on a
- [*direct key signature*](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-direct-key-signature-type-i) (type ID `0x1F`)
OpenPGP's delegation mechanism allows specifying transitive delegation of trust: delegating authentication decisions across more than one hop. The standard refers to certificates as a "meta-introducer," when a "trust signature" subpacket defines it as a trusted introducer with a depth (or "level") of two or more.
A trust signature subpacket with means that the target certificate may delegate to a second, intermediate, introducer, which in turn has issued a certification signature for an identity.
**Examples**
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.
A trust signature can quantify the degree to which the issuer wants to rely on a delegation. This "trust amount" has a numerical value between 0 and 255.
A trust amount of 120 indicates "complete trust," which means that a certification by that trusted introducer is considered sufficient to consider authentications by that introducer as sufficient.
**Examples**
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 the scope of delegations with regular expressions
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), for example, to limit the email address in a User ID to a specific domain name.
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.
The OpenPGP, the "Web of Trust" is a trust model that performs authentication decisions on a set of certifications and delegations[^strong-set].
[^strong-set]: In the context of the Web of Trust, the so-called [strong set](https://en.wikipedia.org/wiki/Web_of_trust#Strong_set) refers to a set of certificates that are strongly linked amongst each other via third-party certifications.
The OpenPGP "Web of Trust" model assumes that every user makes their own choice about who they delegate authentication decisions to. Based on the available certificates and third-party signatures, the user's OpenPGP software uses the Web of Trust mechanism to determine which certificates are considered reliable for an identity.
The OpenPGP RFC doesn't specify how exactly Web of Trust calculations are performed. It only defines the data formats that these calculations can be performed on. See external resources in {numref}`wot-resources`.
The issuer of a third-party signature can undo such a signature by issuing a [*certification revocation signature*](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-certification-revocation-si) (type ID `0x30`).
As mentioned above, different signatures are used for different purposes.
In this section, we will try to give guidance on how to create certain signatures by example.
#### Change Algorithm Preferences
In order to change what symmetric, compression, hash or AEAD algorithms are preferred by the key owner, they can issue a direct-key signature (type 0x1F) on the primary key.
This signature should have the following structure:
The recommended way to change the expiration time of a certificate is by issuing a new `DirectKey` signature (type 0x1F) with an adjusted Key Expiration Time subpacket.
The structure of such a signature is the same as in the section above.
Self-certifications over User IDs can optionally carry the same subpackets as listed in the previous table (key flags, features, algorithm preferences).
This way, separate capabilities can be assigned to different identities.
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.
This means, that it is not really possible to remove signatures / User IDs from a certificate, as there is no way to communicate the intention of packet deletion to the recipient.
So to 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.
| 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 | Decides over soft / hard revocation |
For User ID revocations, the value of the reason subpacket can either be `0` (no reason specified) or `32`, signaling that the User ID is no longer valid.
The latter would result in a soft revocation, while a reason code of `0` is considered a hard revocation.
Omitting the reason packet altogether is also equivalent to a hard revocation.
Optional algorithm preference subpackets can be used to signal per-subkey preferences that deviate from those set in the certificates `DirectKey` signature.
In `SubkeyRevocation` signatures, the [reason subpacket](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-reason-for-revocation) cannot have value `32`, but instead may be from the range of `0-3`.
Values `1` (key superseded) and `3` (key retired and no longer used) are soft reasons, while `0` (no reason) and `2` (key compromised) are considered hard.
Depending on the circumstances, they might either want to revoke it softly, e.g. in case of migration to a new certificate, or they want to issue a hard revocation, e.g. in case of secret key material compromise. A soft-revoked certificate can be re-validated at a later point in time, by issuing a new certification, while a hard revocation is typically permanent.
For `KeyRevocation` signatures, the same constraints as for `SubkeyRevocation` signatures apply to the [reason subpacket](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-reason-for-revocation).
* **Signature Creation Time**: Every OpenPGP signature MUST contain a Signature Creation Time subpacket (2) containing the timestamp at which the signature was made. This packet MUST be present in the hashed area of the signature and SHOULD be marked as critical.
* **Issuer Fingerprint**: To be able to verify a signature, the verifier needs to know which (sub-)key was used to issue the signature in the first place. Therefore, every OpenPGP v6 signature SHOULD contain an Issuer Fingerprint subpacket (33) containing the 32 byte fingerprint of the particular component key that was used to create the signature.
Since the issuer fingerprint subpacket is self-authenticating, it can either be included as a hashed or unhashed subpacket, but the authors of this book recommend to place it in the hashed area of the signature.
Since the hashed and unhashed areas of a signature are just lists of subpackets, in principle they allow duplicates of the same subpacket, which might lead to conflicts.
The [specification recommends](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-notes-on-subpackets) that implementations favor the last occurrence of a conflicting packet in the hashed area (that is, the last entry for that subpacket type in the sequence of subpackets in the hashed area).
In some cases, duplicate packets with conflicting content even make sense, e.g., if a signature was made by a version 4 issuer key whose key material was migrated from an older OpenPGP version such as v3.
In this case, either the v3 or v4 key could be used to validate the v4 signature, but since the key ID calculation scheme was changed between v3 and v4, these identifiers would differ.