Signatures are a fundamental mechanism within OpenPGP. They provide the syntax for forming and interpreting comprehensive statements about certificates and their components, as well as for ensuring the integrity and authenticity of data.
Without signatures, keys would remain unassociated with any certificate or owner. Signatures are crucial for binding component keys and identity components into hierarchical certificates and for establishing the authenticity of messages.
- **Cryptographic signature**: a sequence of bytes created by cryptographic keys, calculated according to a signature scheme.
- **OpenPGP signature packets**: Defined in the [OpenPGP standard](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-signature-packet-type-id-2), these packets combine a raw cryptographic signature along with a *type* designation and additional metadata.
The OpenPGP standard defines a set of [Signature types](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-signature-types), each identified by a numerical *signature type ID*. Signature types define the purpose of a signature and how it should be interpreted.
- **Signatures over data**: These signatures are denoted by type IDs `0x00` for binary documents and `0x01` for canonical text documents. The signer uses these signatures to claim ownership, assert creation, or certify the immutability of the document.
- **Signatures on components**: These are signatures that are associated with component keys or identity components of a certificate.
Signatures on components are a complex topic, and we discuss them in depth in {ref}`component_signatures_chapter`. They are grouped based on two criteria:
- **Packets being signed**: Typically one or more packets, though sometimes none, depending on the context. These are the packets to which the signature statement pertains.
- **Data within the signature packet**: This includes information that specifies the intent of the signature.
Verifying an OpenPGP signature packet is similar to its creation, with some crucial differences that facilitate the verification by entities other than the signer.
- **Access to public key**: Unlike the creation process, which is exclusive to the signer, verification can be performed by anyone who has access to the public key of the signer.
- **Use of signature verification mechanism**:
After calculating the hash digest from the input data, a signature verification mechanism is employed. This mechanism uses the hash digest, the cryptographic signature from the signature packet, and the public key of the signer. Its purpose is to ascertain the cryptographic validity of the signature.
In the OpenPGP protocol, signature subpackets enhance the expressiveness of a signature beyond what is conveyed by just the bare cryptographic signature and the signature type ID. These subpackets, introduced in [RFC 2440](https://datatracker.ietf.org/doc/html/rfc2440), are essential for embedding additional metadata within signature packets.
Signature subpackets serve as sub-elements within signature packets, providing extra context and meaning to a signature.
They are formatted as key-value pairs, where the keys are defined as [subpacket type IDs](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-signature-subpacket-types-r) by the RFC. The RFC also provides the format and interpretation of the values.
- The [*issuer fingerprint*](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#issuer-fingerprint-subpacket) subpacket encodes the fingerprint of the component key that issued the signature.
- The [*key flags*](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-key-flags) subpacket defines the capabilities are assigned to a component key within a certificate.
Signature subpackets within OpenPGP can reside in one of two distinct areas of a signature packet, each serving a different purpose and providing varying levels of security.
- **Hashed area**: Hashed subpackets are included in the hash digest of the signature and are thus covered by its cryptographic signature. They reliably express the signer's intent.
- **Unhashed area**: Unhashed subpackets, conversely, are not included in the hash digest for the signature. They are thus not protected against tampering and can be used to retroactively add, change, or remove metadata in a signature packet without affecting its validity. They are primarily used for advisory purposes or in scenarios where the integrity of the subpacket content can be self-authenticated. An example is the issuer fingerprint subpacket, which can be validated through successful signature verification using the referenced issuer key.
The majority of signature subpackets are stored in the hashed area.
For detailed information and specifications, refer to [Hashed vs. Unhashed Subpackets](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-hashed-vs-unhashed-subpacke) in the OpenPGP RFC.
In the OpenPGP protocol, each signature subpacket can be marked with a *criticality flag*. This flag plays a pivotal role in the interpretation and validation of the signature. When set, it instructs any receiving implementation encountering an unrecognized subpacket type to treat this as a significant error and to invalidate the signature.
This mechanism accounts for different OpenPGP implementations that may support only certain subsets of the standard. Moreover, it anticipates the evolution of the standard, including the addition of new subpacket types.
Consider a scenario where an implementation does not recognize a subpacket indicating signature expiration. Without understanding this concept, the implementation might erroneously accept an already expired signature. By marking the expiration date subpacket as critical, the creator of the signature ensures that any recipient who cannot process this subpacket will reject the signature as invalid.
For specific guidelines on which subpackets should be marked as critical, refer to the RFC sections [5.2.3.11](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-signature-creation-time) to [5.2.3.36](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-intended-recipient-fingerpr).
[Notations](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#notation-data) are a signature subpacket type that can be used to effectively extend the otherwise limited set of signature subpacket types with user-defined notations. An issuer can use notations to add name-value data to an OpenPGP signature.
Notation names are UTF-8 encoded strings. They may reside in the "user namespace," which means a notation *tag* (in UTF-8 string format) followed by a DNS domain name.
#### Use of notations by Keyoxide
Notations have, for example, been used for the popular decentralized identity verification service [Keyoxide](https://keyoxide.org/). Keyoxide uses notations in the `ariadne.id` namespace. See the [Keyoxide documentation](https://docs.keyoxide.org/wiki/ariadne-identity/) for more details.
investigate, discuss: GnuPG uses preference packets for the User ID that was addressed while sequoia completely omits User ID preferences and either uses Direct Key Sigs or (I think) primary User ID.
C-R 5.2. says: An implementation MUST generate a version 6 signature when signing with a version 6 key. An implementation MUST generate a version 4 signature when signing with a version 4 key.