# Advanced material: Signatures on components ## Certification recipes Different {term}`signatures` in OpenPGP serve various specific purposes. This section provides practical guidance on creating these {term}`signatures`, illustrating each with concrete examples. (recipe-algorithm-preferences)= ### Change algorithm preferences To modify the preferred {term}`symmetric`, compression, {term}`hash`, or {term}`AEAD algorithms` for a {term}`key`, the {term}`key owner` needs to issue a {term}`direct key signature` ({term}`type ID` `0x1F`) on the {term}`primary key`. This {term}`signature` should have the following structure: | {term}`Subpacket` | Area | {term}`Critical` | Mandatory | Notes | |---------------------------------------------------------------------------------------------|-----------------------------|------------------------------------------|----------------------|----------------------------------------------------------------------------------------| | {term}`Signature Creation Time` | {term}`Hashed` | True | True | Current time | | {term}`Issuer Fingerprint` | {term}`Hashed` | True or False | Strongly Recommended | The {term}`primary key` is the {term}`issuer` | | {term}`Key Flags` | {term}`Hashed` | True | False | Retain {term}`key flags` from the previous {term}`self-signature` | | {term}`Features` | {term}`Hashed` | True | False | Retain {term}`features` from the previous {term}`self-signature` | | {term}`Key Expiration Time` | {term}`Hashed` | True | False | Retain {term}`expiration time` from the previous {term}`self-signature`, if applicable | | {term}`Hash Algorithm Preferences` | {term}`Hashed` | False | False | New {term}`preferences` | | {term}`Compression Algorithm Preferences` | {term}`Hashed` | False | False | New {term}`preferences` | | {term}`Symmetric Algorithm Preferences` | {term}`Hashed` | False | False | New {term}`preferences` | | {term}`AEAD Algorithm Preferences` | {term}`Hashed` | False | False | New {term}`preferences` | ### Change expiration time To adjust the {term}`expiration time` of an {term}`OpenPGP certificate`, a new *{term}`DirectKey`* {term}`signature` ({term}`type ID` `0x1F`) with a modified {term}`Key Expiration Time subpacket` must be issued. The structure of this {term}`signature` is identical to the one outlined in the previous section on changing {term}`algorithm preferences`. Additionally, the {term}`expiration time` can be altered for individual {term}`User IDs` (detailed below) or separate {term}`subkeys` (see {numref}`bind-subkey`). ### Add User ID To {term}`bind` a {term}`User ID` to an {term}`OpenPGP certificate` a {term}`certification signature` ({term}`type ID` `0x10`-`0x13`) is used which should have the following structure: | {term}`Subpacket` | Area | {term}`Critical` | Mandatory | Notes | |------------------------------------------------------------------------|-----------------------------|------------------------------------------|----------------------|-------------------------------------------------------------------------------------| | {term}`Signature Creation Time` | {term}`Hashed` | True | True | Current time | | {term}`Issuer Fingerprint` | {term}`Hashed` | True or False | Strongly Recommended | The {term}`primary key` is the {term}`issuer` | | {term}`Primary User ID` | {term}`Hashed` | True | False | Optional | | {term}`Signature Expiration Time` | {term}`Hashed` | True | False | Optional | In addition to these {term}`subpackets`, {term}`self-certifications` for {term}`User IDs` can include others – such as {term}`key flags`, {term}`features`, and {term}`algorithm preferences` – as shown in the previous table. This enables the specification of unique capabilities and {term}`preferences` for each {term}`identity` associated with the {term}`certificate`. ### Remove or revoke a User ID Since {term}`OpenPGP certificates` are often distributed by the means of {term}`key servers`, new {term}`signatures` on a {term}`certificate` are often "[merged](certificate-merging)" into existing copies of the {term}`certificate` locally by the recipient. This integration process means it is practically impossible to directly remove {term}`signatures` or {term}`User IDs` from a {term}`certificate`, as there is no way to communicate the intention of {term}`packet` deletion to the recipient. To effectively mark a {term}`User ID` as invalid, the user can publish a copy of their {term}`certificate` with a {term}`Certification Revocation signature` ({term}`type ID` `0x30`) attached to the invalidated {term}`User ID`. This {term}`signature` signals that the specified {term}`User ID` is no longer valid or associated with the {term}`certificate holder`. The structure of a {term}`Certification Revocation signature` is as follows: | {term}`Subpacket` | Area | {term}`Critical` | Mandatory | Notes | |--------------------------------------------------------------------|-----------------------------|------------------------------------------|----------------------|-------------------------------------------------------------------------------------| | {term}`Signature Creation Time` | {term}`Hashed` | True | True | Current time | | {term}`Issuer Fingerprint` | {term}`Hashed` | True or False | Strongly Recommended | The {term}`primary key` is the {term}`issuer` | | {term}`Reason for Revocation` | {term}`Hashed` | True | False | Determines {term}`soft` or {term}`hard revocation` | For {term}`User ID` {term}`revocations`, the *{term}`Reason for Revocation`* {term}`subpacket` is crucial. A value of `0` means no specific reason, leading to a {term}`hard revocation`, while `32` indicates the {term}`User ID` is no longer valid, resulting in a {term}`soft revocation`. Omitting the {term}`reason subpacket` is also equivalent to a {term}`hard revocation`. It is generally advisable to use reason code `32` for revoking {term}`User IDs`. (recipe-binding-subkeys)= ### Add a subkey As part of {term}`life-cycle management`, users may need to add a new {term}`subkey` to their {term}`OpenPGP certificate`, often for reasons such as upgrading to a {term}`subkey` with more advanced cryptographic algorithms. The process involves creating a specific {term}`signature` structure: | {term}`Subpacket` | Area | {term}`Critical` | Mandatory | Notes | |---------------------------------------------------------------------------------------------|-----------------------------|------------------------------------------|-------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | {term}`Signature Creation Time` | {term}`Hashed` | True | True | Current time | | {term}`Issuer Fingerprint` | {term}`Hashed` | True or False | Strongly Recommended | The {term}`primary key` is the {term}`issuer` | | {term}`Key Flags` | {term}`Hashed` | True | Strongly Recommended | Determine the usage of the {term}`key` | | {term}`Key Expiration Time` | {term}`Hashed` | True | False | Specifies the {term}`expiration time` of the {term}`subkey` | | {term}`Embedded Signature` | {term}`Hashed` | True | If {term}`Key Flags` contains **{term}`S`** | {term}`Signing subkeys` require embedded *{term}`Primary Key Binding`* {term}`signature` | | {term}`Hash Algorithm Preferences` | {term}`Hashed` | False | False | Per {term}`key` {term}`preferences` | | {term}`Compression Algorithm Preferences` | {term}`Hashed` | False | False | Per {term}`key` {term}`preferences` | | {term}`Symmetric Algorithm Preferences` | {term}`Hashed` | False | False | Per {term}`key` {term}`preferences` | | {term}`AEAD Algorithm Preferences` | {term}`Hashed` | False | False | Per {term}`key` {term}`preferences` | In addition to these {term}`subpackets`, users can specify {term}`algorithm preferences` for each {term}`subkey`, distinct from those set in the {term}`certificate`'s *{term}`Direct Key`* {term}`signature`. ### Revoke a subkey {term}`Subkeys`, like {term}`User IDs`, can be individually revoked in OpenPGP. This is done by issuing a {term}`Subkey Revocation signature` ({term}`type ID` `0x28`) using the {term}`primary key`. The structure of such a {term}`signature` is straightforward: | {term}`Subpacket` | Area | {term}`Critical` | Mandatory | Notes | |--------------------------------------------------------------------|-----------------------------|------------------------------------------|----------------------|-------------------------------------------------------------------------------------| | {term}`Signature Creation Time` | {term}`Hashed` | True | True | Current time | | {term}`Issuer Fingerprint` | {term}`Hashed` | True or False | Strongly Recommended | The {term}`primary key` is the {term}`issuer` | | {term}`Reason for Revocation` | {term}`Hashed` | True | False | Determines {term}`soft` or {term}`hard revocation` | In {term}`Subkey Revocation signatures`, the [reason for revocation](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-reason-for-revocation) {term}`subpacket` can only have values in the range of `0-3`. The values `1` ({term}`key` superseded) and `3` ({term}`key` retired and no longer used) indicate {term}`soft revocations`, whereas values `0` (no reason) and `2` ({term}`key` compromised) indicate {term}`hard revocations`. Note that a value of `32` is not applicable in these {term}`signatures`. ### Revoke a certificate Users may find themselves needing to revoke their entire {term}`OpenPGP certificate`, rendering it unusable. This could be for various reasons, such as migrating to a new {term}`certificate` or in response to a compromise of the {term}`certificate`'s {term}`secret key material`. While a {term}`soft-revoked` {term}`certificate` can be re-validated at a later time with a new {term}`certification`, a {term}`hard revocation` is permanent. The recommended way to {term}`revoke` a {term}`certificate` is by issuing a {term}`Key Revocation signature` ({term}`type ID` `0x20`). Its structure is similar to that of a {term}`Certification Revocation signature`. | {term}`Subpacket` | Area | {term}`Critical` | Mandatory | Notes | |--------------------------------------------------------------------|-----------------------------|------------------------------------------|----------------------|-------------------------------------------------------------------------------------| | {term}`Signature Creation Time` | {term}`Hashed` | True | True | Current time | | {term}`Issuer Fingerprint` | {term}`Hashed` | True or False | Strongly Recommended | The {term}`primary key` is the {term}`issuer` | | {term}`Reason for Revocation` | {term}`Hashed` | True | False | Determines {term}`soft` or {term}`hard revocation` | For {term}`Key Revocation 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 {term}`Subkey Revocation signatures`. ### Common subpackets in OpenPGP signatures In OpenPGP, certain {term}`subpackets` are universally expected across all types of {term}`signatures`, serving fundamental roles in the {term}`signature`'s structure, {term}`verification` and {term}`validation`: * **{term}`Signature Creation Time`**: This is a mandatory {term}`subpacket` in every {term}`OpenPGP signature`. It contains the timestamp of when the {term}`signature` was created. For security and integrity, this {term}`subpacket` must be located in the {term}`hashed area` of the {term}`signature` and is recommended to be marked as {term}`critical`. * **{term}`Issuer Fingerprint`**: Essential for {term}`signature` {term}`validation`, this {term}`subpacket` identifies the {term}`key` (or {term}`subkey`) that was used to create the {term}`signature`. OpenPGP v6 {term}`signatures` should include the {term}`Issuer Fingerprint subpacket`, containing the 32-byte {term}`fingerprint` of the {term}`key`. ```{note} The {term}`key` used as the {term}`issuer` in the {term}`signature` might be a {term}`subkey` of the {term}`certificate`. ``` These {term}`subpackets` can be placed in either the {term}`hashed` or {term}`unhashed area` due to its self-{term}`authenticating` nature. However, we recommend including them in the {term}`signature`'s {term}`hashed area`. ## Managing subpacket conflicts and duplication In {term}`OpenPGP signatures`, both the {term}`hashed` and {term}`unhashed areas` are composed of lists of {term}`subpackets`. Inherently, this structure permits the duplication of the same {term}`subpacket`, which could lead to conflicts. To manage these potential conflicts, the following strategies are used: - **Precedence of {term}`hashed area`**: {term}`Subpackets` within the {term}`hashed area` of a {term}`signature` take precedence over those in the {term}`unhashed area`. This hierarchy helps resolve conflicts when the same {term}`subpacket` appears in both areas. - **Handling conflicts within the same area**: Conflicts can still arise within the same area, such as when two {term}`subpackets` have different {term}`expiration times`. 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 {term}`implementations` should favor the last occurrence of a conflicting {term}`subpacket` in the {term}`hashed area`. In certain scenarios, having duplicate {term}`subpackets` with conflicting content is logical and even necessary. For example, consider a {term}`signature` created by a version 4 {term}`issuer` {term}`key`, which was upgraded from an older OpenPGP version (like v3). Since the {term}`key ID` calculation scheme changed from v3 to v4, the identifiers for the same {term}`key` would differ between these versions. Therefore, a v4 signature might contain two {term}`issuer key ID subpackets`, each with different, yet correct values for v3 and v4 {term}`keys`, respectively. This allows for backward compatibility and ensures the {term}`signature` can be {term}`validated` under both {term}`key ID` calculation schemes.