openpgp-notes/book/source/04-certificates.md
2023-10-22 13:10:10 +02:00

16 KiB

(certificates_chapter)=

Certificates

OpenPGP fundamentally hinges on the concept of "OpenPGP certificates," also known as "OpenPGP keys." These certificates are complex data structures essential for identity verification, data encryption, and digital signatures. Understanding their structure and function is pivotal to effectively applying 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" 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 a discussion of private key material in OpenPGP, see the chapter {ref}private_key_chapter. Bindings that connect the components of a certificate are discussed in our chapter {ref}certifications_chapter. For much more detail on the internal (packet) structure of certificates and keys refer to our chapter {ref}zoom_certificates. 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 elements1:

  • Component keys
  • Identity components
  • Additional metadata, including connections between the certificate's components

This documentation collectively refers to component keys and identity information as "the components of a certificate."


Typical components in an OpenPGP certificate

Every element in an OpenPGP certificate revolves around a central component: the OpenPGP primary key. The primary key acts as a personal CA (Certification Authority) for the certificate's owner, enabling cryptographic statements regarding subkeys, identities, expiration, revocation, and more.

OpenPGP certificates tend to have a long lifespan, with the potential for modifications (typically by their owner) over time. Components may be added or invalidated throughout a certificate's lifetime.

Component keys

An OpenPGP certificate usually contains multiple component keys. Component keys serve in one of two roles: either as an "OpenPGP primary key" or as an "OpenPGP subkey."

OpenPGP component keys logically consist of an asymmetric cryptographic keypair and a creation timestamp. Once created, these attributes of a component key remain fixed (for ECDH keys, two additional parameters are part of a component key's constitutive data2).


An OpenPGP component key

In OpenPGP, component keys containing private key material include metadata that specifies the password protection scheme. However, this chapter focuses on OpenPGP certificates. The component keys of these certificates contain only the public part of its cryptographic key data. For information on private keys in OpenPGP, see {numref}private_key_chapter.

Fingerprint

Each OpenPGP component key allows for the generation of an OpenPGP fingerprint . This fingerprint is produced based on the public key material, the creation timestamp, and, when relevant, the ECDH parameters.


Every OpenPGP component key is identifiable by a unique fingerprint.

The fingerprint of our example OpenPGP component key is C0A5 8384 A438 E5A1 4F73 7124 26A4 D45D BAEE F4A3 9E6B 30B0 9D55 13F9 78AC CA943.

Component keys are used in one of two roles: either as "OpenPGP primary key" or as an "OpenPGP subkey."

The OpenPGP primary key is a distinct component key that serves a central role in an OpenPGP certificate:

  • Its fingerprint acts as the unique identifier for the entire OpenPGP certificate.
  • It facilitates lifecycle operations, such as adding or invalidating subkeys or identities within a certificate.
:class: note

In the RFC, the OpenPGP primary key is occasionally referred to as "top-level key." Informally, it has also been termed the "master key."

Subkeys

Modern OpenPGP certificates often include several subkeys in addition to the primary key, although these subkeys are optional.

While subkeys have the same structural attributes as the primary key, they fulfill different roles. Subkeys are cryptographically linked with the primary key, a relationship further discussed in {numref}binding_subkeys.

:name: Certificate with subkeys
:alt: Diagram depicting three component keys. The primary key is positioned at the top, designated for certification. Below it, connected by arrows, are two subkeys labeled as "for encryption" and "for signing," respectively.

OpenPGP certificates can contain multiple subkeys.

Defining operational capabilities with key flags

Each component key has a set of "key flags" that delineate the operations a key can perform.

Commonly used key flags include:

  • Certification: enables issuing third-party certifications
  • Signing: allows the key to sign data
  • Encryption: allows the key to encrypt data
  • Authentication: primarily used for OpenPGP authentication

In line with best practices, distinct component keys should handle specific operations. The primary key should be reserved solely for certification, while separate subkeys should be used for signing, encryption, and authentication. Notably, in many algorithms, encryption capability is exclusive and cannot overlap with other operations[^key-flag-sharing]).

Component key metadata, including key flags

The key flags for a component key are not stored within the component key directly.

Instead, key flags, along with other metadata about that component key, such as the key expiration time, are stored using mechanisms that group components into an OpenPGP certificate:

  • For the primary key, its key flags and other metadata can be defined in two ways: they can be linked with the Primary User ID or through a direct key signature.
  • For subkeys, the key flags and other metadata are set using the mechanism that ties the subkey to the certificate, specifically through the primary key. Further details on binding subkeys are below.

(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 in OpenPGP certificates

OpenPGP certificates can contain multiple User IDs. Each User ID associates the certificate with an identity.


OpenPGP certificates can contain any number of User IDs
This image could be visually improved! The new image should have an alt tag

A typical User ID identity is a UTF-8-encoded string composed of a name and an email address. By convention, User IDs align with the format described in RFC2822 as a name-addr.

For further conventions on User IDs, refer to the document draft-dkg-openpgp-userid-conventions-00, dated 25 August 2023.

One proposed variant for encoding identities in User ID is to use "split User IDs".

Heiko, please clarify what the value is of this proposal or remove it. 

(primary_user_id)=

Implimations of the Primary User ID

Within a certificate, a specific User ID is desginated as the Primary User ID.

Each User ID carries associated preference settings, such as preferred encryption algorithms, which is detailed in {numref}zooming_in_user_id). The preferences associated with the Primary User ID take precedence by default.

: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 in OpenPGP

While user attributes are similar to User IDs, they are less commonly used.

Currently, the OpenPGP standard prescribes only one format for storing user attributes: an image. Typically, this image represents the key owner, but it is not required.

Linking the components

To form an OpenPGP certificate, individual components are interconnected by the certificate holder using their OpenPGP software. Within OpenPGP, this process is termed "binding," as in "a subkey is bound to the primary key." These bindings are realized using cryptographic signatures. An in-depth discussion of this topic can be found in {ref}certifications_chapter).

In very abstract terms, the primary key of a certificate acts as a root of trust or "certification authority." It is responsible for:

  • issuing signatures that express the certificate holder's intent to use specific subkeys or identity components;
  • conducting other lifecycle operations, including setting expiration dates and marking components as invalidated or "revoked."

By binding components using digital signatures, recipients of an OpenPGP certificate need only validate the authenticity of the primary key to use for their communication partner. Traditionally, this is done by manually verifying the fingerprint of the primary key. Once the validity of the primary key is confirmed, the validity of the remaining components can be automatically assessed by the user's OpenPGP software. Generally, components are valid parts of a certificate if there is a statement signed by the certificate's primary key endorsing this validity.

Revocations

:class: warning

This section needs to be written

Third-party (identity) certifications

:class: warning

This section needs to be written

Third-party identity certifications have historically played a pivotal role in the OpenPGP ecosystem.

Security considerations

While a convenience for consumers, indiscriminately accepting and integrating third-party identity certifications comes with significant risks.

Without any restrictions in place, malicious entities can flood a certificate with excessive certifications. Called "certificate flooding," this form of digital vandalism grossly expands the certificate size, making the certificate cumbersome and impractical for users.

It also opens the door to potential denial-of-service attacks, rendering the certificate non-functional or significantly impeding its operation.

The popular SKS keyserver network experienced certificate flooding firsthand, causing it to shut down operations in 2019.

Improved mechanisms in OpenPGP v6

:class: warning

This section needs to be written

Advanced topics

: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

: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

: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 about the primary key: In Direct Key Signature vs. in Primary User ID, in v4 and v6

:class: warning

write

Metadata leak of Social Graph

(unbound_user_ids)=

Adding unbound User IDs to a certificate

: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).


  1. In technical terms, the elements of an OpenPGP certificate are a collection of "packets." Each component key and identity component is internally represented as a packet. Another common type of packet is the "signature" packet, which connect the components of a certificate. ↩︎

  2. For ECDH component keys, two additional algorithm parameters are integral to the component key's constitutive and immutable properties. Those parameters specify a hash function and a symmetric encryption algorithm. ↩︎

  3. In OpenPGP version 4, the rightmost 64 bits were sometimes used as a shorter identifier, called "Key ID." For example, an OpenPGP version 4 certificate with the fingerprint B3D2 7B09 FBA4 1235 2B41 8972 C8B8 6AC4 2455 4239 might be referenced by the 64-bit Key ID C8B8 6AC4 2455 4239 or formatted as 0xC8B86AC424554239.
    Historically, even shorter 32-bit identifiers were used, like this: 2455 4239, or 0x24554239. Such identifiers still appear in very old documents about PGP. However, 32-bit identifiers have been long deemed unfit for purpose. At one point, 32-bit identifiers were called "short Key ID," while 64-bit identifiers were referred to as "long Key ID." ↩︎