<!-- SPDX-FileCopyrightText: 2023 The "Notes on OpenPGP" project SPDX-License-Identifier: CC-BY-SA-4.0 --> (component_signatures_chapter)= # Signatures on components In this chapter, we'll look at OpenPGP signatures that apply to components of certificates. That is, signatures that apply to: - Component keys (primary keys or subkeys) and - Identity components (User IDs or User attributes). Signatures on components are used to construct and maintain certificates, and to model the authentication of identities. This chapter expands on topics we introduced in the {ref}`certificates_chapter` chapter. ## Self-signatures vs third-party signatures There are two fundamentally different flavors of signatures on components: - *Self-signatures*, which are issued by the certificate holder themselves using the primary key of the certificate, and - *third-party signatures*, which are issued by a third party. ### Self-signatures *Self-signatures* on components are a crucial mechanism for forming OpenPGP certificates (by binding the certificate's components into one combined data structure), as well as for life-cycle management of certificates (that is: performing changes to the certificate, over time). Life-cycle management operations on OpenPGP certificates and their components include: - binding additional components to a certificate, - changing the expiration date, or other metadata, of a component, and - invalidating components or existing self-signatures using revocations. Self-signatures are issued by the certificate's owner, using the primary key of the same certificate. ```{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 on components form the basis for OpenPGP's decentralized authentication functionality (also known as the *Web of Trust*). They encode authentication-related statements about certificates and their associated identities. Third-party OpenPGP signatures can be used to make the following types of statements: - Certification of identity claims, - Delegation of authentication decisions, - Invalidating previous third-party signature statements using revocations. ```{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. Only the primary key of a certificate may hold this key flag. ``` ### Self-signatures and third-party signatures convey different meanings The meaning of a signature depends in part on who issued it. A self-signature performs a different function than the same type of signature issued by a third party. For example: - Certifying self-signatures (type IDs `0x10` - `0x13`) are used to bind a User ID to a certificate, while - third-party signatures of the same type IDs indicate that the signer endorses the authenticity of a User ID. Or: - A [direct key signature](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-direct-key-signature-type-i) issued as a self-signature can be used to set preferences and advertise features that apply to the whole certificate, while - a similar [direct key signature](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-direct-key-signature-type-i) issued by a third party delegates trust to the signed certificate, when it carries a [trust signature](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-trust-signature) subpacket. The issuer thereby configures the signed certificate as a trust root in the *Web of Trust*, for themselves. ## Self-signatures: Forming certificates and life-cycle management The components in an OpenPGP certificate are bound together using signatures. These *binding signatures* join the components together, while also adding metadata to them. Internally, an OpenPGP certificate consists of a sequence of OpenPGP packets. These packets are just strung together, one after the other. When a certificate is stored in a file[^tpk], it's easy to remove some of these packets, or add new ones. [^tpk]: When stored in a file, OpenPGP certificates are in a format called [transferable public key](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-transferable-public-keys). However, the owner of a certificate doesn't want a third party to add subkeys or [identity components](identity_components) to their certificate, pretending that the certificate owner put those components there. To prevent malicious addition of components, OpenPGP uses cryptographic signatures. These signatures show that components have been added by the owner of the OpenPGP certificate. They are issued by the primary key of the certificate. So while anyone can still unilaterally store unrelated subkeys and [identity components](identity_components) in an OpenPGP certificate dataset, OpenPGP implementations that load a certificate can (and usually should) discard components that don't have a valid cryptographic connection with the certificate. ```{note} Conversely, it's easy for a third party to leave out packets, while handling an OpenPGP certificate dataset. An attacker can, for example, simply choose to omit revocation packets. The recipient of such a partial copy has no way to notice this omission, without access to a different source for the certificate that contains the revocation packet. ``` Note that there are some cases where third parties legitimately add "unbound" packets (that is: packets that are not signed by the certificate's owner) to a certificate: - [Third-party certifications](third_party_cert) are traditionally stored as part of the packet data of the certificate that they make a statement about (in systems that unconditionally accept and include such certifications, this can cause problems[^flooding]), - OpenPGP software may add [unbound identity data](unbound_user_ids), locally. [^flooding]: Storing third-party identity certifications in the target OpenPGP certificate is convenient for consumers: it is easy to find all relevant certifications in one central location. However, when third parties can unilaterally add certifications, this opens an avenue for denial-of-service attacks by flooding. The SKS network of OpenPGP key servers [allowed and experienced this problem](https://dkg.fifthhorseman.net/blog/openpgp-certificate-flooding.html). (bind_subkey)= ### Binding subkeys to a certificate Subkeys is linked to an OpenPGP certificate using 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 effectively signals that the "primary key wants to be associated with the subkey". A subkey binding signature binds a subkey to a primary key, and adds metadata in the signature packet. Once generated, the subkey binding signature packet is stored in the certificate, directly following the subkey it binds. (Note that subkeys that have the *signing* [key flag](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-key-flags) are a special case, and are handled slightly 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 ``` To specify 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), or the capabilities that are set using [*key flags*](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#key-flags), subpackets are included in the subkey binding signature packet. ```{note} The validity of a subkey is bounded by that of the primary key, meaning that an expired primary key causes the subkey to be invalid, no matter the subkey expiration time. It's legal for a subkey to not have an explicit expiry time. In that case, its expiration date is implicitly the same as the expiration date of the primary key. A subkey cannot be "older" than the primary key. The value of the subkeys creation date MUST be greater than that of the primary key. ``` (bind_subkey_sign)= ### Special case: Binding signing subkeys to a certificate To bind subkeys with the "signing" key flag to a certificate is a special case. For the most part, it works the same as binding other types of subkeys, but there is one additional requirement: To bind a signing-capable subkey to a primary key, it is not sufficient that the "primary key wants to be associated with the subkey." In addition, the subkey must signal that it "wants to be associated with that primary key." Otherwise, Alice could "adopt" Bob's signing subkey and convincingly claim that she made signatures that were in fact issued by Bob. This is to prevent an attack where the attacker "adopts" the victims signing subkey as their own in order to claim ownership over documents which were in fact signed by the victim. In contrast to 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`) is instead created by the subkey (informally also called an embedded "back signature"). ```{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 additional [*primary key binding*](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#sigtype-primary-binding) signature (type 0x19) is informally called a "back signature" (because the subkey uses the signature to point "back" to the primary key). The *primary key binding signature* is "embedded" as subpacket data in the *subkey binding signature* which connects the signing subkey to the primary key. (bind_ident)= ### Binding identities to a certificate Another use-case for a self-signature is to link an identity component (such as a User ID that specifies a name and email address) to a certificate. User ID components are bound to an OpenPGP certificate by issuing a certifying self-signature. "User Attributes" work analogously. For example, the User ID `Alice Adams <alice@example.org>` may be associated with Alice's certificate `AAA1 8CBB 2546 85C5 8358 3205 63FD 37B6 7F33 00F9 FB0E C457 378C D29F 1026 98B3`. Alice can link a User ID to her OpenPGP certificate with a cryptographic signature. To link a User ID, a *certifying self-signature* is created. There are four variant certifying self-signature types. Usually the signature type [positive certification](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#sigtype-positive-cert) (type ID `0x13`) is used to bind User IDs to one's certificate (sometimes, type ID `0x10`, `0x11` or `0x12` may be used instead). This binding signature must be issued by the primary key. The resulting certifying self-signature packet is stored as part of 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 ``` This signature is calculated over the primary key, User ID and the metadata of the signature packet. ### Adding metadata to the primary key The signatures that bind subkeys and identity components to a certificate serve two different purposes: Linking components to the certificate and adding metadata to a component. The primary key in a certificate doesn't need to be linked to the certificate. It acts as the anchor for linking, itself and thus doesn't require being linked. However, there is nevertheless a need to associate metadata with the primary key. There are two mechanisms for adding metadata to the primary key: - Via a direct key signature on the primary key, or - via a "primary User ID" binding signature. Relevant metadata for the primary key that is defined the above mechanisms includes: - Key expiration, - key flags, - 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) is one mechanism to store information about the primary key, and about 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). #### Primary User ID binding self-signature In a 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 primary key of the certificate. ### Revocation self-signatures: Invalidating components of a certificate One important class of self-signatures are revocations. A revocation signature is used to invalidate a component, or retract the statement formed by a prior signature. - 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, while - 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. Typical use-cases for revocations are marking certificates or individual subkeys as unusable (for example, when the private key has been compromised or superseded), or marking User IDs as no longer used. ```{note} OpenPGP certificates act as append-only data structures, in practice. Elements of a certiciate can not be removed from the copies on key servers and the OpenPGP systems of third parties, once published. Implementations usually merge all available components and signatures. Revocations are used as a mechanism to mark components or signatures as invalid. ``` 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 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. ```{note} A revocation signature that has no *reason for revocation* subpacket is interpreted as a hard revocation. ``` (third_party_cert)= ## Third-party signatures: Authentication statements 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. ### Delegating authentication: Trust signatures 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`) #### Trust depth (or "level") 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. ```{admonition} VISUAL :class: warning add diagrams? ``` #### Trust amount 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. ```{admonition} VISUAL :class: warning add diagrams? ``` #### 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. With this mechanism, it is possible to delegate authentication decisions only for User IDs that match the email domain of an organization. **Example** 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. ```{admonition} VISUAL :class: warning add diagrams? ``` ### Decentralized automated trust decisions; or, the "Web of Trust" The OpenPGP, the "Web of Trust" is a trust model that performs authentication decisions on a set of certifications and delegations. 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`. ### Revoking third-party signatures: Undoing previous statements 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`). ## Advanced topics ### Certification Recipes 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: | 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 | Carry over key flags from previous self-signature | | Features | Hashed | True | False | Carry over features from previous self-signature | | Key Expiration Time | Hashed | True | False | Carry over expiration time from previous self-signature, if present | | Hash Alg. Pref. | Hashed | False | False | New preferences | | Comp. Alg. Pref. | Hashed | False | False | New preferences | | Symm. Alg. Pref. | Hashed | False | False | New preferences | | AEAD Alg. Pref. | Hashed | False | False | New preferences | #### Change Expiration Time 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. It is also possible to change the expiration date of individual User IDs (see section below) or separate subkeys (see {numref}`bind_subkey`). #### Add User ID A signature that binds a User ID to a certificate 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 | 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. #### Remove / Revoke 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. 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. This signature signals that the holder of the certificate no longer wants to be associated with that User ID. The structure of a certification revocation 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 | 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. It is recommended to issue User ID revocations using a reason code `32`. (binding_subkeys)= #### Add a Subkey A user might want to add a new subkey to their certificate, for example to replace an old subkey with one that uses a newer cryptographic algorithm. The structure 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 | | 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 `PrimaryKeyBinding` signature | | Hash Alg. Pref. | Hashed | False | False | Per key preferences | | Comp. Alg. Pref. | Hashed | False | False | Per key preferences | | Symm. Alg. Pref. | Hashed | False | False | Per key preferences | | AEAD Alg. Pref. | Hashed | False | False | Per key preferences | Optional algorithm preference subpackets can be used to signal per-subkey preferences that deviate from those set in the certificates `DirectKey` signature. #### Revoke a Subkey Analogous to User IDs, subkeys can be revoked individually. This is done by issuing a `SubkeyRevocation` signature (type 0x28) using the primary key. The structure of such a signature is rather minimal: | 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 | Decides over soft / hard revocation | 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. #### Revoke a Certificate A user might want to revoke their entire certificate, rendering it unusable. 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. The recommended way to revoke a certificate is by issuing a `KeyRevocation` signature (type 0x20). The structure of a key revocation signature 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 | Decides over soft / hard revocation | 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). #### Common Subpackets There are some subpackets that are expected to be included in all types of signatures. * **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. ```{note} The issuer key might be a subkey. ``` 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. ### Potential subpacket conflicts and duplication 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. Therefore, packets in the hashed area take precedence over the unhashed area. However, there may still be conflicts between packets in the same area, e.g., two conflicting expiration dates, etc. 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. Therefore, the signature could contain two issuer key ID subpackets with conflicting, but correct values.