(certificates_chapter)= # Certificates OpenPGP fundamentally hinges on the concept of "OpenPGP certificates," often referred to as "OpenPGP keys." These certificates are complex data structures essential for identity verification, data encryption, and digital signatures. Understanding their structure and functionality is pivotal for effective application of the OpenPGP standard. ## Terminology: Understanding "keys" The term "(cryptographic) keys" is central to grasping the concept of OpenPGP certificates. However, it can refer to different entities, making it a potentially confusing term. Let's clarify those differences. ### Public vs. private keys The term "key," without additional context, can refer to either public or private asymmetric key material. Additionally, symmetric keys may be used in OpenPGP to encrypt private key material, adding a layer of security and complexity. ### Layers of keys in OpenPGP In OpenPGP, the term "key" may refer to three distinct layers, each serving a unique purpose: 1. A (bare) ["cryptographic key"](asymmetric_key_pair) comprises the private and/or public parameters forming a key. For instance, in the case of an RSA private key, the key consists of the exponent `d` along with the prime numbers `p` and `q`. 2. An OpenPGP *component key* includes either an "OpenPGP primary key" or an "OpenPGP subkey." It is a building block of an OpenPGP certificate, consisting of a cryptographic keypair coupled with some invariant metadata, such as key creation time. 3. An "OpenPGP certificate" (or "OpenPGP key") consists of several component keys, identity components, and other elements. These certificates are dynamic, evolving over time as components are added, expire, or are marked as invalid. The following section will delve into the OpenPGP-specific layers (2 and 3) to provide a clearer understanding of their roles within OpenPGP certificates. For detailed insights on structure and handling, refer to our chapters on OpenPGP [certificates](certificates_chapter) and [private keys](private_key_chapter). Additionally, managing certificates, and understanding their authentication and trust models are vital topics. While this document briefly touches upon these aspects, they are integral to working proficiently with OpenPGP. ## Structure of OpenPGP certificates An OpenPGP certificate (or "OpenPGP key") is a collection of an arbitrary number of elements[^packets]: [^packets]: In technical terms, the elements of an OpenPGP certificate are a collection "packets". Each component key and identity component is internally represented as one packet. The other common type of element is "signature" packets, which link the components of a certificate together. - Component OpenPGP keys, - Identity components, - Other metadata (this includes connections between the certificate's components). We sometimes collectively refer to component keys and identity information as "the components of a certificate." ```{figure} diag/OpenPGP_Certificate.png Typical components in an OpenPGP certificate ``` All elements in an OpenPGP certificate are structured around one central component: the *OpenPGP primary key*. The primary key acts as a personal {term}`CA` for the certificate's owner: It can make cryptographic statements about subkeys, identities, expiration, revocation, ... ```{note} OpenPGP certificates are typically long-lived and may be changed (typically by their owner), over time. Components can be added and invalidated, over the lifetime of a certificate ``` ### OpenPGP component keys An OpenPGP certificate usually contains multiple OpenPGP component keys. OpenPGP component keys logically consist of an [asymmetric cryptographic keypair](asymmetric_key_pair) and a creation timestamp. These attributes of a component key cannot be changed after creation (in the case of ECDH keys, two additional parameters are part of a component key's constituting data[^ecdh-paramters]). [^ecdh-paramters]: For [ECDH](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-algorithm-specific-part-for-ecd) component keys, two additional algorithm parameters are part of the component key's constituting and immutable properties. Those parameters define a hash function and a symmetric encryption algorithm. ```{figure} diag/Component_Key.svg An OpenPGP component key ``` Component key representations that include private key material also contain metadata that specifies the password protection scheme for the private key material. However, in this chapter, we're looking at *OpenPGP certificates*, which *don't* contain private key information. Each component key of such a certificate contains only the public part of its cryptographic key data. To read more about private keys in OpenPGP, see {numref}`private_key_chapter`. #### Fingerprint For each OpenPGP component key, an *OpenPGP fingerprint* can be derived from the combination of the public key material and creation timestamp (and ECDH parameters, if applicable). ```{figure} diag/Fingerprint.png Every OpenPGP component key can be named by a fingerprint ``` The fingerprint of our example component OpenPGP key is `AAA1 8CBB 2546 85C5 8358 3205 63FD 37B6 7F33 00F9 FB0E C457 378C D29F 1026 98B3` [^keyid]. [^keyid]: In OpenPGP version 4, the rightmost 64 bit were sometimes used as a shorter identifier, called "Key ID". E.g., an OpenPGP version 4 certificate with the fingerprint `B3D2 7B09 FBA4 1235 2B41 8972 C8B8 6AC4 2455 4239` might be referred to by the 64 bit Key ID `C8B8 6AC4 2455 4239` or styled as `0xC8B86AC424554239`. Historically, even shorter 32 bit identifiers have sometimes been used, like this: `2455 4239`, or `0x24554239`. You may still see such identifiers in very old documents about PGP. However, 32 bit identifiers have [been unfit for purpose for a long time](https://evil32.com/). At some point, 32 bit identifiers were called "short Key ID", while 64 bit identifiers were called "long Key ID". Component keys are used in one of two roles: either as "OpenPGP primary key," or as an "OpenPGP subkey". #### Primary key The "OpenPGP primary key" is a component key that serves a central role in an OpenPGP certificate: - Its fingerprint is used as the unique identifier for the full OpenPGP certificate. - It is used for lifecycle operations, such as adding or invalidating subkeys or identities in a certificate. The validity of the primary key limits its capacity to confer validity to other components. E.g.: The primary key cannot confer an expiration time beyond its own expiration to a subkey. It can also not confer validity to components after it has been revoked. ```{admonition} Terminology :class: note In the RFC, the OpenPGP primary key is also sometimes referred to as "top-level key." It has also sometimes informally been called "master key." ``` #### Subkeys In addition to the primary key, modern OpenPGP certificates usually contain a number of "subkeys" (however, it's not technically necessary for a certificate to contain subkeys). Subkeys have the same structure as the primary key, but they are used in a different role. Subkeys are cryptographically linked with the primary key (more on this in {numref}`binding_subkeys`). ```{figure} diag/Subkeys.png :name: Certificate with Subkeys :alt: Three component keys. The primary key is shown at the top. It can be used for certification. Below it, linked with arrows, are two more component keys, used as subkeys. They are marked as "for encryption" and "for signing", respectively. OpenPGP certificates can contain a number of subkeys ``` #### Key flags: defining which operations a component key can perform Each component key has a set of ["Key Flags"](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#key-flags) that specify which operations that key can perform. The commonly used key flags are: - **C**ertification (issuing third-party certifications) - **S**igning (signing data) - **E**ncryption (encrypting data) - **A**uthentication (commonly used for OpenPGP authentication) By convention, only the primary key is allowed to perform "certification" operations. All other operations can be configured on either the primary key or a subkey. ```{note} It is considered good practice to have separate component keys for each type of operation: to allow only *Certification* operations with the primary key, and to use separate *Signing*, *Encryption* and *Authentication* subkeys (independently: with most algorithms, encryption can't be shared with the other capabilities[^key-flag-sharing]). ``` [^key-flag-sharing]: With ECC algorithms, it's actually not possible to share encryption functionality with the signing-based functionalities, e.g.: ed25519 used for signing; cv25519 used for encryption. #### Component key metadata, including key flags The key flags for a component key are actually not defined *inside* that component key itself. Instead, key flags, together with other metadata about that component key (such as the key expiration time), are stored using mechanisms that join components together as an OpenPGP certificate: - For the primary key, two different mechanisms can be used to define its key flags (as well as other metadata): That configuration can be associated with the [Primary User ID](primary_user_id), or via a [direct key signature](direct_key_signature). - For subkeys, their key flags (and other metadata) are defined with the mechanism that connects the subkey with the certificate (via the primary key). More on that [below](binding_subkeys). (identity_components)= ### Identity components Identity components in an OpenPGP certificate are used by the certificate holder to state that they are known by a certain identifier (like a name, or an email address). #### User IDs An OpenPGP certificate can contain any number of [User IDs](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-user-id-packet-tag-13). Each User ID associates the certificate with an identity. ```{figure} diag/user_id.png OpenPGP certificates can contain any number of User IDs ``` Often, identities in a User ID consist of a UTF-8 encoded string that is composed of a name and an email address. By convention, User IDs typically consist of an [RFC2822](https://www.rfc-editor.org/rfc/rfc2822) *name-addr*. Also see [draft-dkg-openpgp-userid-conventions-00](https://datatracker.ietf.org/doc/draft-dkg-openpgp-userid-conventions/), 25 August 2023. One proposed variant for encoding identities in User ID is to use ["split User IDs"](https://dkg.fifthhorseman.net/blog/2021-dkg-openpgp-transition.html#split-user-ids). (primary_user_id)= #### Primary User ID and its implications One User ID in a certificate has the special property of being the [Primary User ID](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-primary-user-id). User IDs are associated with preference settings (such as preferred encryption algorithms, more on this in {numref}`zooming_in_user_id`). The preferences associated with the Primary User ID are used by default. ```{admonition} TODO :class: warning i think crypto-refresh suggests that the direct key signature should hold the default preferences? we might need to write a more nuanced text here, about how DKS and primary user id interact in v6, and mention the differences to v4? ``` #### User attributes [User attributes](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-user-attribute-packet-tag-1) are similar to User IDs, but less commonly used. The OpenPGP standard currently only defines one format to store in User Attributes: an [image](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-the-image-attribute-subpack), "presumably (but not required to be) that of the key owner". ### Linking the components of an OpenPGP certificate So far we've looked at the components in an OpenPGP certificate, but certificates actually contain another set of elements, which bind the components together, and add metadata to them. Internally, an OpenPGP certificate consists of a sequence of OpenPGP packets. These packets are just stringed 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 add [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 (these linking signatures 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 read this certificate should discard components that don't have a valid cryptographic connection with the certificate. (Conversely, it's easy for a third party to leave out packets when passing on an OpenPGP certificate. An attacker can, for example, choose to omit revocation packets. The recipient of such a partial copy has no way to notice the omission, without access to a different source for the certificate that contains the revocation packet.) Note, though, that there are some cases where third parties legitimately add "unbound" packets to certificates (that is: packets that are not signed by the certificate's owner): - [Third-party certifications](third_party_cert) are traditionally added to the certificate that they make a statement about (this can cause problems in systems that unconditionally accept and include such certifications[^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). (binding_subkeys)= #### Binding subkeys to an OpenPGP certificate Linking a subkey to an OpenPGP certificate is done with a ["Subkey Binding Signature"](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#sigtype-subkey-binding). Such a signature signals that the "primary key wants to be associated with the subkey". The subkey binding signature also adds metadata. ```{figure} diag/subkey_binding.png Linking an OpenPGP subkey to the primary key with a binding signature ``` The [Signature packet](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-signature-packet-tag-2) that binds the subkey to the primary key has the signature type [SubkeyBinding](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-subkey-binding-signature-si). ##### Binding signing subkeys to an OpenPGP certificate Binding subkeys with the "signing" key flag is a special case: When binding a signing 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. ```{figure} diag/subkey_binding_backsig.png Linking an OpenPGP signing subkey to the primary key with a binding signature, and an embedded primary key binding signature ``` This additional "Primary Key Binding" Signature is informally called a "back signature" (because the subkey uses the signature to point "back" to the primary key). #### Binding identities with certifying self-signatures "User ID" identity components are bound to an OpenPGP certificate by issuing a self-signature ("User Attributes" work analogously). For example, the User ID `Alice Adams ` 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 self-signature is created (usually with the signature type [PositiveCertification](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#sigtype-positive-cert)). This signature is issued by the primary key. ```{figure} diag/user_id_certification.png --- --- Linking a User ID to an OpenPGP certificate ``` (direct_key_signature)= #### Direct key signature ```{admonition} TODO explain metadata associated with this signature, and that c-r prefers this over primary user id. ``` ### Revocations ```{admonition} TODO :class: warning This section only contains notes and still needs to be written ``` 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 (third_party_cert)= ## Third party (identity) certifications ```{admonition} TODO :class: warning This section needs writing ``` ## Advanced topics ```{admonition} TODO :class: warning This section only contains notes and still needs to be written ``` ### Certificate management / Evolution of a certificate over time Minimized versions, merging, effective "append only" semantics, ... ### "Naming" a certificate in user-facing contexts - fingerprints and beyond ```{admonition} TODO :class: warning In v4, a 20 byte fingerprint in hex representation was used to name certificates, even in user-facing contexts. For v6, this type of approach is discouraged, but a replacement mechanism is still pending. ``` ### Merging - How to merge two copies of the same certificate? - Canonicalization ### How to generate "minimized" certificate? ### When are certificates valid? - Full certificate: Primary revoked/key expired/binding signature expired, - Subkey: Revoked/key expired/binding signature expired - User ID: revoked, binding expired, ... ### Best practices regarding Key Freshness ```{admonition} TODO :class: warning - Expiry - Subkey rotation Wiktor suggests to check: https://blogs.gentoo.org/mgorny/2018/08/13/openpgp-key-expiration-is-not-a-security-measure/ for important material ``` ### Metadata leak of Social Graph (unbound_user_ids)= ### Adding unbound User IDs to a certificate ```{admonition} TODO :class: warning references/links missing ``` Some OpenPGP subsystems may add User IDs to a certificate, which are not bound to the primary key by the certificate's owner. This can be useful to store local identity information (e.g., Sequoia's public store attaches "pet-names" to certificates, in this way).