1
0
Fork 0
mirror of https://codeberg.org/openpgp/notes.git synced 2025-03-16 22:23:12 +01:00
openpgp-notes/book/source/08-signing_components.md
2023-11-23 17:39:31 +01:00

30 KiB
Raw Blame History

(component_signatures_chapter)=

Signatures on components

This chapter examines OpenPGP signatures associated with certificate components, applying to:

  • component keys, encompassing primary keys and subkeys
  • identity components, namely User IDs and User attributes

Signatures on components are used to construct and maintain certificates, and to model the authentication of identities.

This chapter expands on topics introduced in the {ref}certificates_chapter chapter.

Self-signatures vs third-party signatures

Component signatures in OpenPGP are categorized into two distinct types:

  • self-signatures, which are issued by the certificate holder using the certificate's primary key
  • third-party signatures, which are issued by an external entity, not the certificate holder

Self-signatures

Self-signatures are fundamental in creating and managing OpenPGP certificates. They bind the various components of a certificate into one combined data structure and facilitate the certificate's life-cycle management.

Life-cycle management operations include:

  • binding additional components to a certificate
  • modifying expiration dates or other metadata of components
  • revoking, and thus invalidating, components or existing self-signatures

Self-signatures are issued by the certificate's owner using the certificate's primary key.

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 are pivotal in OpenPGP for decentralized authentication, forming the basis of the Web of Trust. They encode authentication-related statements about certificates and linked identities, establishing trustworthiness and verification.

Third-party signatures are used to make specific statements:

  • certifying identity claims
  • delegating authentication decisions
  • revoking, and thus invalidating, prior third-party signature statements
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 certificate's primary holds this key flag.

Distinct functions of self-signatures and third-party signatures

The meaning of an OpenPGP signature depends significantly on its issuer. Self-signatures and third-party signatures, even when of the same type, serve distinct functions. For example:

  • Certifying self-signatures (type IDs 0x10 - 0x13) bind a User ID to a certificate.
  • Third-party signatures of the same type IDs endorses the authenticity of a User ID.

In another instance:

  • When issued as a self-signature, a direct key signature sets preferences and advertises features applicable to the entire certificate.
  • When issued by a third party, especially when it carries a trust signature subpacket, a similar direct key signature delegates trust to the signed certificate. This designates the signed certificate as a trust root within the issuer's Web of Trust.

Self-signatures in certificate formation and management

Self-signatures play a crucial role in forming and managing the structure of OpenPGP certificates. These act as binding signatures, joining components and embedding metadata.

Internally, an OpenPGP certificate is essentially a series of packets strung sequentially. When a certificate is stored in a file format known as a transferable public key, packets can be easily added or removed.

To safeguard against unauthorized additions, OpenPGP uses cryptographic signatures. These validate that any additions, such as subkeys or identity components, were made by the owner of the OpenPGP certificate using its primary key. While anyone can still store unrelated subkeys and identity components to a certificate dataset, OpenPGP implementations typically reject components lacking a valid cryptographic connection with the certificate.

Conversely, omissions of packets by third parties can easily occur when handling an OpenPGP certificate dataset. This could pose a challenge, for example, when an attacker deliberately omits revocation packets. Without access to an alternative, complete certificate source, recipients might not detect these omissions.

However, there are instances legitimate and malicious in which third parties add "unbound" packets (i.e., not signed by the certificate's owner) to a certificate:

  • Third-party certifications are often stored within the packet data of the certificate to which they are related.This is a standard practice that provides convenience for users by allowing easy access to all relevant certifications. However, in systems that unconditionally accept these certifications, it can lead to unintended consequences. Specifically, this approach has been exploited to cause denial-of-service attacks through certificate flooding, a problem notably experienced by the SKS network of OpenPGP servers.
  • OpenPGP software may locally append unbound identity data to a certificate.

(bind_subkey)=

Binding subkeys to a certificate

Subkeys are linked to OpenPGP certificates via a subkey binding signature (type ID 0x18). This signature type indicates the association of the primary key with the subkey.

A subkey binding signature binds a subkey to a primary key, and it embeds metadata into the signature packet. Once generated, the subkey binding signature packet is stored in the certificate directly after the subkey it binds.

Subkeys designated for signing purposes, identified by the signing key flag, represent a unique category and are handled differently. See {numref}bind_subkey_sign.


Linking an OpenPGP subkey to the primary key with a binding signature

Metadata for the subkey, such as the key expiration time and capabilities set by key flags, are included in subpackets within the subkey binding signature packet.

The validity of a subkey is intrinsically linked to that of the primary key. An expired primary key renders any associated subkey invalid, regardless of the subkeys own expiration setting.

Legally, a subkey may not have a specified expiry time. In such cases, its expiration aligns implicitly with that of the primary key. Additionally, the creation date of a subkey must always be more recent than that of the primary key.

(bind_subkey_sign)=

Special case: Binding signing subkeys

Binding subkeys that possess the signing key flag to a certificate represents a unique scenario. While similar to the binding process of other subkeys, there is an additional, critical requirement: mutual association.

That is, to bind a signing-capable subkey to a primary key, it is insufficient that the "primary key wants to be associated with the subkey." The subkey must explicitly signal that it "wants to be associated with the primary key."

This mutual binding is crucial for security. Without it, an individual (e.g., Alice) could falsely claim a connection to another persons (e.g., Bob's) signing subkey. To prevent such scenarios, where an attacker might wrongfully "adopt" a victim's signing subkey, a dual-layer of signatures is used:

  • the subkey binding signature (type ID 0x18), which is issued by the certificate's primary key
  • the primary key binding signature (type ID 0x19), created by the subkey itself. This is informally known as an embedded "back signature," because the subkey's signature points back 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 back signature signifies the mutuality of the subkey's association with the primary key and is embedded within the subkey binding signature, reinforcing the authenticity of the binding.

(bind_ident)=

Binding identities to a certificate

Self-signatures also play a vital role in binding identity components, such as User IDs or User Attributes, to an OpenPGP certificate.

Take for instance, the User ID Alice Adams <alice@example.org>. To link this User ID to her OpenPGP certificate (e.g., AAA1 8CBB 2546 85C5 8358 3205 63FD 37B6 7F33 00F9 FB0E C457 378C D29F 1026 98B3), Alice would use a cryptographic signature.

There are four types of certifying self-signature. The most commonly used type for binding User IDs is the positive certification (type ID 0x13). Alternatively, types 0x10, 0x11 or 0x12 might be used. This binding signature must be issued by the primary key.

The certifying self-signature packet calculated over the primary key, User ID, and metadata of the signature packet is then appended to the certificate, directly following the User ID packet.


Linking a User ID to an OpenPGP certificate

(primary-metadata)=

Adding metadata to the primary key/certificate

The signatures that bind subkeys and identity components to a certificate serve dual purposes: linking components to the certificate and adding metadata to components.

Unlike these components, the primary key of a certificate doesn't require a linking signature since it serves as the central anchor of the certificate. However, associating metadata with the primary key is still essential, as it generally applies to the entire certificate.

Metadata can be added to the primary key via two mechanisms:

  • direct key signature on the primary key
  • primary User ID binding signature

The types of metadata typically associated with the primary key through these methods include:

  • key expiration
  • key flags
  • algorithm preference signaling

(direct_key_signature)=

Direct key signature

A direct key signature serves as a key mechanism for storing information about the primary key and the entire certificate.

In OpenPGP v6, a direct key signature is the preferred mechanism.

Self-signature binding to primary User ID

In an OpenPGP certificate, one User ID serves as the primary User ID. The metadata in the binding self-signature on this User ID applies to the certificate's primary key.

Revocation self-signatures: Invalidating certificate components

Revocation self-signatures represent an important class of self-signatures, used primarily to invalidate components or retract prior signature statements.

There are several types of revocation signatures, each serving a specific purpose:

Common scenarios for using revocations include marking certificates or individual subkeys as unusable (e.g., when the private key has been compromised or replaced) or declaring User IDs as no longer valid.

OpenPGP certificates act as append-only data structures in practice. Once elements of a certificate are published, they cannot be removed from key servers or third-party OpenPGP systems. Implementations usually merge all available components and signatures.

Revocations are used to mark components or signatures as invalid.

Note: certification signatures can be made irrevocable.

Hard vs soft revocations

Revocation signatures often include a reason for revocation subpacket, with a code specifying why the revocation was issued. This code determines whether the revocation is considered soft or hard.

  • Soft revocation: This is typically used for graceful or planned invalidation of components, such as retiring or updating components. It invalidates the component from the revocation signature's creation time, but earlier uses remain valid. Soft revocations can be reversed with a new self-signature.
  • Hard revocation: This irrevocably invalidates the component, affecting all past and future uses. It is typically used to signal compromise of secret key material.
A revocation signature lacking a *reason for revocation* subpacket is interpreted as a hard revocation.

(third_party_cert)=

Authentication and delegation in third-party signatures

Third-party signatures in OpenPGP primarily encode authentication statements for identities and delegate trust decisions. These signatures can be manually inspected or processed as machine-readable artifacts by OpenPGP software, which evaluates the authenticity of certificates based on user-specified trust roots.

Certifying identity components

When a signer issues a certifying signature on an identity, it indicates a verified link between the identity and the certificate.That is, the signer vouches for the connection.

For example, Alice can certify Bob's User ID Bob Baker <bob@example.com> with his certificate 0xB0B, by creating a certification signature that binds Bob's User ID and Bob's certificate. Bob then distributes Alice's certifying signature as part of his certificate.

Other users may or may not decide to rely on Alice's statement.

Trust signatures: delegating authentication

OpenPGP uses trust signature subpackets to delegate authentication decisions, transforming the recipient certificate into a "trusted introducer" (or a trust root) for the user. This includes specifying trust depth (or level) for transitive delegations and quantifying trust with numerical values, indicating the extent of reliance on the introducer's certifications.

Trust signature subpackets are applicable in:

Trust depth/level

The trust depth (or level) in OpenPGP signifies the extent of transitive delegation within the authentication process. It determines how far the trust can be extended from the original trusted introducer to subsequent intermediaries. Essentially, a certificate with a designated trust depth acts as a "meta-introducer," facilitating authentication decisions across multiple levels in the network.

For example, a trust depth of 1 means there is direct trust in the certifications made by the trusted introducer. In this case, the user's OpenPGP software will accept certifications made directly by the introducer for authenticating identities.

However, when the trust depth is set higher, it implies a chain of trust extending beyond the initial introducer. The user's software will recognize and accept certifications made not only by the primary introducer but also by other intermediaries whom the primary introducer trusts.

This allows for a more extensive network of trusted certifications, enabling a broader and more interconnected Web of Trust.

:class: warning

Heiko, I found the example confusing. So more text is here AND I recommend adding a visual to illustrate it, using your former example. 

Trust amounts

The trust amount, with a numerical value ranging from 0 to 255, quantifies the degree of trust in a delegation.

A higher value indicates greater trust, such as 120 for complete trust, while lower values suggest partial trust. This quantification aids OpenPGP software in determining the authentication level based on combined trust from multiple trusted introducers.

:class: warning

add diagrams? @heiko -- yes, using the examples that I removed

Limiting delegation scope

When using trust signature subpackets, a delegation can be limited to identities that match a regular expression.

With this mechanism, for example, it is possible to delegate authentication decisions only for User IDs that match the email domain of an organization.

:class: warning

add diagrams?

(wot)=

Web of Trust: Decentralized trust decisions

The Web of Trust in OpenPGP is a trust model that facilitates authentication decisions through a network of certifications and delegations.[^strong-set] It is characterized by a so-called strong set, which refers to a group of certificates that are robustly interconnected via third-party certifications.

In this model, users independently delegate authentication decisions, choosing whom to trust among various certificate issuers. This delegation is based on the certificates and third-party signatures available to them, with their OpenPGP software applying the Web of Trust mechanism to discern the reliability of each certificate for an identity.

The OpenPGP RFC doesn't specify exactly how Web of Trust calculations are performed. It only defines the data formats on which these calculations can be performed. See external resources in {numref}wot-resources.

Revoking third-party signatures

To reverse a previously issued third-party signature, the issuer can generate a certification revocation signature (type ID 0x30). The revocation must be issued by the same key that created the original signature or, in deprecated practice, by a designated Revocation Key.

Advanced topics

Certification recipes

Different signatures in OpenPGP serve various specific purposes. This section provides practical guidance on creating these signatures, illustrating each with concrete examples.

Change algorithm preferences

To modify the preferred symmetric, compression, hash, or AEAD algorithms for a key, the key owner needs to 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 Should be the current time
Issuer Fingerprint Hashed True or False Strongly Recommended Identifies the primary key as the issuer
Key Flags Hashed True False Retain key flags from the previous self-signature
Features Hashed True False Retain features from the previous self-signature
Key Expiration Time Hashed True False If applicable, use expiration time from the previous self-signature
Hash Algorithm Preferences Hashed False False New preferences
Compression Algorithm Preferences Hashed False False New preferences
Symmetric Algorithm Preferences Hashed False False New preferences
AEAD Algorithm Preferences Hashed False False New preferences

Change expiration time

To adjust the expiration time of an OpenPGP certificate, issue a new DirectKey signature (type 0x1F) with a modified Key Expiration Time subpacket. The structure of this signature is identical to the one outlined in the previous section on changing algorithm preferences.

Additionally, the expiration date can be altered for individual User IDs (detailed below) or separate subkeys (see {numref}bind_subkey).

Add User ID

To bind a User ID to an OpenPGP certificate, the 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 Identifies the primary key as the issuer
Primary User ID Hashed True False Optional
Signature Expiration Time Hashed True False Optional

In addition to these subpackets, self-certifications for User IDs can include others such as key flags, features, and algorithm preferences as shown in the previous table. This enables the specification of unique capabilities and preferences for each identity associated with the certificate.

Remove or revoke a 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 integration process means it is practically impossible to directly remove signatures or User IDs from a certificate, as there is no way to communicate the intention of packet deletion to the recipient.

To effectively 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 specified User ID is no longer valid or associated with the certificate holder.

The structure of a certification revocation is as follows:

Subpacket Area Critical Mandatory Notes
Signature Creation Time Hashed True True Should be the current time
Issuer Fingerprint Hashed True or False Strongly Recommended Indicates the primary key as the issuer
Reason for Revocation Hashed True False Determines the nature of the revocation

For User ID revocations, the Reason for Revocation subpacket is crucial. A value of 0 means no specific reason, leading to a hard revocation, while 32 indicates the User ID is no longer valid, resulting in a soft revocation. Omitting the reason subpacket is also equivalent to a hard revocation.

It is generally advisable to use reason code 32 for revoking User IDs.

(binding_subkeys)=

Add a subkey

Users may need to add a new subkey to their OpenPGP certificate, often for reasons such as upgrading to a subkey with more advanced cryptographic algorithms. The process involves creating a specific signature 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 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 Primary Key Binding signature
Hash Algorithm Preferences Hashed False False Per key preferences
Compression Algorithm Preferences Hashed False False Per key preferences
Symmetric Algorithm Preferences Hashed False False Per key preferences
AEAD Algorithm Preferences Hashed False False Per key preferences

In addition to these subpackets, users can specify algorithm preferences for each subkey, distinct from those set in the certificate's 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 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.

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.

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