mirror of
https://codeberg.org/openpgp/notes.git
synced 2024-11-27 01:52:06 +01:00
ch8: edits for clarity and flow
This commit is contained in:
parent
06da358f99
commit
2346c346c2
1 changed files with 65 additions and 54 deletions
|
@ -6,70 +6,87 @@ SPDX-License-Identifier: CC-BY-SA-4.0
|
|||
(component_signatures_chapter)=
|
||||
# Signatures on components
|
||||
|
||||
In this chapter, we'll look into OpenPGP signatures that apply to components of certificates. That is, signatures that apply to:
|
||||
In this chapter, we'll look at OpenPGP signatures that apply to components of certificates. That is, signatures that apply to:
|
||||
|
||||
- Component keys (primary keys or subkeys) and
|
||||
- Identity components (User IDs or User attributes).
|
||||
|
||||
This chapter adds detail to material we discussed in the {ref}`certificates_chapter` chapter.
|
||||
Signatures on components are used to construct and maintain certificates, and to model the authentication of identities.
|
||||
|
||||
## Two flavors of signatures on components: first party vs third party
|
||||
This chapter expands on topics we introduced in the {ref}`certificates_chapter` chapter.
|
||||
|
||||
Signatures on components are a crucial mechanism for forming OpenPGP certificates, as well as for life-cycle management of certificates, when issued by the certificate holder.
|
||||
## Self-signatures vs third-party signatures
|
||||
|
||||
Separately, signatures on components can serve as a building block for OpenPGP's decentralized authentication functionality. Signatures for this functionality are issued by third parties.
|
||||
There are two fundamentally different flavors of signatures on components:
|
||||
|
||||
### Self-signatures: Forming certificates and life-cycle management
|
||||
- *Self-signatures*, which are issued by the certificate holder themselves using the primary key of the certificate, and
|
||||
- *third-party signatures*, which are issued by a third party.
|
||||
|
||||
*Self-signatures* are issued by the certificate's owner, using the primary key of the same certificate.
|
||||
### Self-signatures
|
||||
|
||||
Signatures on components are also a central mechanism for life-cycle management of OpenPGP certificates and their components. This includes defining or changing expiration dates, or issuing revocations, for certificates or their components.
|
||||
*Self-signatures* on components are a crucial mechanism for forming OpenPGP certificates (by binding the certificate's components into one combined data structure), as well as for life-cycle management of certificates (that is: performing changes to the certificate, over time).
|
||||
|
||||
Life-cycle management operations on OpenPGP certificates and their components include:
|
||||
|
||||
- binding additional components to a certificate,
|
||||
- changing the expiration date, or other metadata, of a component, and
|
||||
- invalidating components or existing self-signatures using revocations.
|
||||
|
||||
Self-signatures are issued by the certificate's owner, using the primary key of the same certificate.
|
||||
|
||||
```{note}
|
||||
The **certify others** [key flag](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-key-flags) (`0x01`) is not required in order to issue certifying self-signatures. This key flag is only necessary to issue valid third-party certifications.
|
||||
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 certifications: Encoding authentication
|
||||
### Third-party signatures
|
||||
|
||||
Mechanisms for decentralized authentication of identities are one of OpenPGP’s core strengths: Signatures on components by third parties can be used for the authentication of identities.
|
||||
Third-party signatures on components form the basis for OpenPGP's decentralized authentication functionality (also known as the *Web of Trust*). They encode authentication-related statements about certificates and their associated identities.
|
||||
|
||||
Using OpenPGP signatures, identity claims can be certified by third parties. Similarly, authentication decisions can be delegated using signatures.
|
||||
Third-party OpenPGP signatures can be used to make the following types of statements:
|
||||
|
||||
### Meaning differs between self- and third-party signatures
|
||||
- Certification of identity claims,
|
||||
- Delegation of authentication decisions,
|
||||
- Invalidating previous third-party signature statements using revocations.
|
||||
|
||||
```{note}
|
||||
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 primary key of a certificate may hold this key flag.
|
||||
```
|
||||
|
||||
### Self-signatures and third-party signatures convey different meanings
|
||||
|
||||
The meaning of a signature depends in part on who issued it. A self-signature performs a different function than the same type of signature issued by a third party.
|
||||
|
||||
For example:
|
||||
|
||||
- A [direct key signature](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-direct-key-signature-type-i) issued as a self-signature can be used to set preferences and advertise features that apply to the whole certificate, while
|
||||
- A similar [direct key signature](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-direct-key-signature-type-i) issued by a third party, which carries a [trust signature](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-trust-signature) subpacket, acts as a statement by the issuer that they delegate trust to the signed certificate (the issuer thereby uses the remote certificate as a trust root in the *Web of Trust*).
|
||||
- Certifying self-signatures (type IDs `0x10` - `0x13`) are used to bind a User ID to a certificate, while
|
||||
- third-party signatures of the same type IDs indicate that the signer endorses the authenticity of a User ID.
|
||||
|
||||
Or:
|
||||
|
||||
- Certifying self-signatures (type IDs `0x10` - `0x13`) are used to bind a User ID to a certificate, while
|
||||
- the same signature type IDs issued by a third party are statements by the signer that they endorse the authenticity of the signed User ID to some degree.
|
||||
- A [direct key signature](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-direct-key-signature-type-i) issued as a self-signature can be used to set preferences and advertise features that apply to the whole certificate, while
|
||||
- a similar [direct key signature](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-direct-key-signature-type-i) issued by a third party delegates trust to the signed certificate, when it carries a [trust signature](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-trust-signature) subpacket. The issuer thereby configures the signed certificate as a trust root in the *Web of Trust*, for themselves.
|
||||
|
||||
## Self-signatures: Linking the components of a certificate
|
||||
## Self-signatures: Forming certificates and life-cycle management
|
||||
|
||||
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.
|
||||
The components in an OpenPGP certificate are bound together using signatures. These *binding signatures* join the components together, while also adding 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.
|
||||
Internally, an OpenPGP certificate consists of a sequence of OpenPGP packets. These packets are just strung 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 [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).
|
||||
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. They 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.
|
||||
So while anyone can still unilaterally store unrelated subkeys and [identity components](identity_components) in an OpenPGP certificate dataset, OpenPGP implementations that load a certificate can (and usually should) discard components that don't have a valid cryptographic connection with the certificate.
|
||||
|
||||
```{note}
|
||||
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.
|
||||
Conversely, it's easy for a third party to leave out packets, while handling an OpenPGP certificate dataset. An attacker can, for example, simply choose to omit revocation packets. The recipient of such a partial copy has no way to notice this 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):
|
||||
Note that there are some cases where third parties legitimately add "unbound" packets (that is: packets that are not signed by the certificate's owner) to a certificate:
|
||||
|
||||
- [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]),
|
||||
- [Third-party certifications](third_party_cert) are traditionally stored as part of the packet data of the certificate that they make a statement about (in systems that unconditionally accept and include such certifications, this can cause problems[^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).
|
||||
|
@ -77,21 +94,21 @@ Note, though, that there are some cases where third parties legitimately add "un
|
|||
(bind_subkey)=
|
||||
### Binding subkeys to a certificate
|
||||
|
||||
A subkey is linked to an OpenPGP certificate using a [subkey binding signature](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#sigtype-subkey-binding) (type ID 0x18). This signature type effectively signals that the "primary key wants to be associated with the subkey".
|
||||
Subkeys is linked to an OpenPGP certificate using a [subkey binding signature](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#sigtype-subkey-binding) (type ID `0x18`). This signature type effectively signals that the "primary key wants to be associated with the subkey".
|
||||
|
||||
A subkey binding signature binds the public primary key and the public subkey, and additionally metadata in the signature packet. Once generated, the subkey binding signature packet is stored in the certificate right after the subkey.
|
||||
A subkey binding signature binds a subkey to a primary key, and adds metadata in the signature packet. Once generated, the subkey binding signature packet is stored in the certificate, directly following the subkey it binds.
|
||||
|
||||
(Note that subkeys that have the *signing* [key flag](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-key-flags) are a special case, see {numref}`bind_subkey_sign`.)
|
||||
(Note that subkeys that have the *signing* [key flag](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-key-flags) are a special case, and are handled slightly differently. See {numref}`bind_subkey_sign`.)
|
||||
|
||||
```{figure} diag/subkey_binding_signature.png
|
||||
|
||||
Linking an OpenPGP subkey to the primary key with a binding signature
|
||||
```
|
||||
|
||||
In order to specify an expiration time for the subkey, a key expiration time subpacket can be included in the subkey binding signature packet.
|
||||
To specify metadata for the subkey, such as the [*key expiration time*](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#key-expiration-subpacket), or the capabilities that are set using [*key flags*](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#key-flags), subpackets are included in the subkey binding signature packet.
|
||||
|
||||
```{note}
|
||||
The validity of a subkey is bounded by that of the primary key, meaning an expired primary key causes the subkey to be invalidated, no matter the subkey expiration time.
|
||||
The validity of a subkey is bounded by that of the primary key, meaning that an expired primary key causes the subkey to be invalid, no matter the subkey expiration time.
|
||||
|
||||
It's legal for a subkey to not have an explicit expiry time. In that case, its expiration date is implicitly the same as the expiration date of the primary key.
|
||||
|
||||
|
@ -101,42 +118,41 @@ A subkey cannot be "older" than the primary key. The value of the subkeys creati
|
|||
(bind_subkey_sign)=
|
||||
### Special case: Binding signing subkeys to a certificate
|
||||
|
||||
To bind subkeys with the "signing" key flag to a certificate is a special case. For the most part, it works the same as binding other types of subkeys, but there is an additional requirement:
|
||||
To bind subkeys with the "signing" key flag to a certificate is a special case. For the most part, it works the same as binding other types of subkeys, but there is one additional requirement:
|
||||
|
||||
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."
|
||||
To bind a signing-capable 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.
|
||||
This is to prevent an attack where the attacker "adopts" the victims signing subkey as their own in order to claim ownership over documents which were in fact signed by the victim.
|
||||
In contrast to the [subkey binding signature](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#sigtype-subkey-binding) (type ID 0x18), which is issued by the certificate's primary key, the [primary key binding signature](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#sigtype-primary-binding) (type ID 0x19) is instead created by the subkey (informally also called an embedded "back signature").
|
||||
In contrast to the [subkey binding signature](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#sigtype-subkey-binding) (type ID `0x18`), which is issued by the certificate's primary key, the [primary key binding signature](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#sigtype-primary-binding) (type ID `0x19`) is instead created by the subkey (informally also called an embedded "back signature").
|
||||
|
||||
```{figure} diag/subkey_binding_signatur_for_signing_sk.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) is an embedded `PrimaryKeyBinding` "back signature" (type 0x19).
|
||||
The additional [*primary key binding*](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#sigtype-primary-binding) signature (type 0x19) is informally called a "back signature" (because the subkey uses the signature to point "back" to the primary key).
|
||||
|
||||
The *primary key binding signature* is "embedded" as subpacket data in the *subkey binding signature* that connects the signing subkey to the primary key.
|
||||
The *primary key binding signature* is "embedded" as subpacket data in the *subkey binding signature* which connects the signing subkey to the primary key.
|
||||
|
||||
### Binding identities to a certificate
|
||||
|
||||
Another use-case for a self-signature is to link an identity component (such as a User ID that specifies a name and email address) to a certificate.
|
||||
|
||||
User ID components are bound to an OpenPGP certificate by issuing a self-signature ("User Attributes" work analogously).
|
||||
User ID components are bound to an OpenPGP certificate by issuing a certifying self-signature. "User Attributes" work analogously.
|
||||
|
||||
For example, the User ID `Alice Adams <alice@example.org>` 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 "certifying self-signature" is created (usually with the signature type [positive certification](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#sigtype-positive-cert) (type ID 0x13, or sometimes with type ID 0x10, 0x11 or 0x12)). This signature is issued by the primary key.
|
||||
Alice can link a User ID to her OpenPGP certificate with a cryptographic signature. To link a User ID, a *certifying self-signature* is created. There are four variant certifying self-signature types. Usually the signature type [positive certification](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#sigtype-positive-cert) (type ID `0x13`) is used to bind User IDs to one's certificate (sometimes, type ID `0x10`, `0x11` or `0x12` may be used instead). This binding signature must be issued by the primary key.
|
||||
|
||||
The resulting certification is stored as part of the certificate, right after the User ID packet.
|
||||
The resulting certifying self-signature packet is stored as part of the certificate, directly following the User ID packet.
|
||||
|
||||
```{figure} diag/user_id_certification.png
|
||||
---
|
||||
---
|
||||
|
||||
Linking a User ID to an OpenPGP certificate
|
||||
```
|
||||
|
||||
This signature is calculated over the primary key and User ID.
|
||||
This signature is calculated over the primary key, User ID and the metadata of the signature packet.
|
||||
|
||||
|
||||
### Adding metadata to the primary key
|
||||
|
@ -175,7 +191,12 @@ A revocation signature is used to retract the statement formed by a prior signat
|
|||
A subkey revocation signature revokes a prior subkey binding signature, while a certification revocation revokes a certification signature.
|
||||
Typical use-cases for revocations are marking certificates or individual subkeys as unusable (for example, when the private key has been compromised or superseded), or marking User IDs as no longer used.
|
||||
|
||||
A revocation signature can either be hard or soft. A soft revocation of a certificate invalidates it from the revocation signature's creation time onwards. This means signatures issued before the revocation remain intact. A hard revocation, by contrast, invalidates the certificate retroactively, rendering all issued signatures invalid, regardless of creation time. Soft revocations are typically used whenever a key or User ID is retired or superseded gracefully, while hard revocations can, for example, signal compromise of secret key material.
|
||||
A revocation signature can either be *hard* or *soft*:
|
||||
|
||||
- A soft revocation of a certificate invalidates it from the revocation signature's creation time onwards. This means signatures issued before the revocation remain intact.
|
||||
- A hard revocation, by contrast, invalidates the certificate retroactively, rendering all issued signatures invalid, regardless of creation time.
|
||||
|
||||
Soft revocations are typically used whenever a key or User ID is retired or superseded gracefully, while hard revocations can, for example, signal compromise of secret key material.
|
||||
|
||||
```{note}
|
||||
OpenPGP certificates act as append-only data structures, in practice. Elements of a certiciate can not be removed from the copies on key servers and the OpenPGP systems of third parties, once published. Implementations usually merge all available components and signatures.
|
||||
|
@ -199,7 +220,7 @@ A missing revocation reason subpacket is equivalent with a hard revocation reaso
|
|||
```
|
||||
|
||||
(third_party_cert)=
|
||||
## Third-party certifications: Making statements about other people's certificates and identities
|
||||
## Third-party certifications: Encoding authentication statements
|
||||
|
||||
```{admonition} TODO
|
||||
:class: warning
|
||||
|
@ -362,13 +383,3 @@ The [specification recommends](https://www.ietf.org/archive/id/draft-ietf-openpg
|
|||
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.
|
||||
|
||||
```{admonition} TODO
|
||||
:class: warning
|
||||
|
||||
- Key Flags
|
||||
- Preferences
|
||||
- Embedded Signature (back sig)
|
||||
- Trust Signatures (amount, depth)
|
||||
- Direct key signatures
|
||||
```
|
||||
|
|
Loading…
Reference in a new issue