mirror of
https://codeberg.org/openpgp/notes.git
synced 2024-11-27 01:52:06 +01:00
restructure
This commit is contained in:
parent
1b95fa95a3
commit
19ac66ee5c
1 changed files with 98 additions and 65 deletions
|
@ -5,33 +5,19 @@ SPDX-License-Identifier: CC-BY-SA-4.0
|
||||||
|
|
||||||
(certifications_chapter)=
|
(certifications_chapter)=
|
||||||
|
|
||||||
# Certification signatures
|
# Signatures on components
|
||||||
|
|
||||||
Signatures make up the magic of OpenPGP.
|
Signatures make up the magic of OpenPGP.
|
||||||
They act as the syntax that allows forming and interpreting complex statements about data and identities.
|
They act as the syntax that allows forming and interpreting complex statements about data and identities.
|
||||||
Without signatures there would only be loose keys, impossible to associate with their owner.
|
Without signatures there would only be loose keys, impossible to associate with their owner.
|
||||||
Signatures are the glue that allows for keys, subkeys and identities to be assembled into hierarchical certificates and for messages to gain authenticity.
|
Signatures are the glue that allows for components (keys, subkeys and identities) to be assembled into hierarchical certificates and for messages to gain authenticity.
|
||||||
|
|
||||||
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.
|
In this chapter, we'll discuss signatures that apply to component keys and identity components. In {ref}`signing_data`, we discuss the other class of signatures, which makes statements about data.
|
||||||
|
|
||||||
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.
|
In this chapter, one important distinction is between:
|
||||||
|
|
||||||
[^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).
|
- Self-signatures, where the owner of a certificate uses signatures internal to their certificate and
|
||||||
|
- Third-party signatures, where a third party issues statements about components of a certificate.
|
||||||
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).
|
|
||||||
|
|
||||||
## Terminology
|
## Terminology
|
||||||
|
|
||||||
|
@ -129,6 +115,82 @@ Sections 5.2.3.11 - 5.2.3.36 give guidance on which subpackets are usually marke
|
||||||
explain metadata associated with this signature, and that c-r prefers this over primary user id.
|
explain metadata associated with this signature, and that c-r prefers this over primary user id.
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Self-signatures
|
||||||
|
|
||||||
|
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 to a 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_signature.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).
|
||||||
|
|
||||||
|
|
||||||
|
In order to specify an expiration time for the subkey, a key expiration time subpacket can be included. Note, that the validity of the 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.
|
||||||
|
|
||||||
|
Note, that a subkey cannot be "older" than the primary key. The value of the subkeys creation date MUST be greater than that of the primary key.
|
||||||
|
|
||||||
|
#### Binding signing subkeys
|
||||||
|
|
||||||
|
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.
|
||||||
|
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.
|
||||||
|
Contrary to the `SubkeyBinding` signature, which is issued by the certificates primary key, the `PrimaryKeyBinding` signature is instead created by the subkey.
|
||||||
|
|
||||||
|
```{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) is an embedded `PrimaryKeyBinding` "back signature" (type 0x19).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Certifying identities
|
||||||
|
|
||||||
|
"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 <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 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
|
||||||
|
```
|
||||||
|
|
||||||
|
This signature is calculated over the primary key and User ID.
|
||||||
|
|
||||||
### Revocations
|
### Revocations
|
||||||
|
|
||||||
|
@ -151,6 +213,14 @@ Contrary, a hard revocation cannot be re-validated. Furthermore, a hard-revoked
|
||||||
|
|
||||||
A missing revocation reason subpacket is equivalent with a hard revocation reason.
|
A missing revocation reason subpacket is equivalent with a hard revocation reason.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Third-party signatures
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
## Advanced
|
||||||
|
|
||||||
### Certification Recipes
|
### Certification Recipes
|
||||||
|
|
||||||
As mentioned above, different signatures are used for different purposes.
|
As mentioned above, different signatures are used for different purposes.
|
||||||
|
@ -174,26 +244,14 @@ This signature should have the following structure:
|
||||||
| AEAD Alg. Pref. | Hashed | False | False | New preferences |
|
| AEAD Alg. Pref. | Hashed | False | False | New preferences |
|
||||||
|
|
||||||
#### Change Expiration Time
|
#### Change Expiration Time
|
||||||
|
|
||||||
The recommended way to change the expiration time of a certificate is by issuing a new `DirectKey` signature (type 0x1F) with an adjusted Key Expiration Time subpacket.
|
The recommended way to change the expiration time of a certificate is by issuing a new `DirectKey` signature (type 0x1F) with an adjusted Key Expiration Time subpacket.
|
||||||
The structure of such a signature is the same as in the section above.
|
The structure of such a signature is the same as in the section above.
|
||||||
It is also possible to change the expiration date of individual User IDs (see section below) or separate subkeys (see [section X](#add_subkey)).
|
It is also possible to change the expiration date of individual User IDs (see section below) or separate subkeys (see [section X](#add_subkey)).
|
||||||
|
|
||||||
#### Add User ID
|
#### Add User ID
|
||||||
|
|
||||||
"User ID" identity components are bound to an OpenPGP certificate by issuing a self-signature ("User Attributes" work analogously).
|
A signature that binds a User ID to a certificate should have the following structure:
|
||||||
|
|
||||||
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 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
|
|
||||||
```
|
|
||||||
|
|
||||||
This signature is calculated over the primary key and User ID.
|
|
||||||
The signature should have the following structure:
|
|
||||||
|
|
||||||
| Subpacket | Area | Critical | Mandatory | Notes |
|
| Subpacket | Area | Critical | Mandatory | Notes |
|
||||||
|-----------|------|----------|-----------|-------|
|
|-----------|------|----------|-----------|-------|
|
||||||
|
@ -206,6 +264,7 @@ Self-certifications over User IDs can optionally carry the same subpackets as li
|
||||||
This way, separate capabilities can be assigned to different identities.
|
This way, separate capabilities can be assigned to different identities.
|
||||||
|
|
||||||
#### Remove / Revoke User ID
|
#### Remove / Revoke 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.
|
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 means, that it is not really possible to remove signatures / User IDs from a certificate, as there is no way to communicate the intention of packet deletion to the recipient.
|
This means, that it is not really possible to remove signatures / User IDs from a certificate, as there is no way to communicate the intention of packet deletion to the recipient.
|
||||||
|
|
||||||
|
@ -227,20 +286,11 @@ It is recommended to issue User ID certifications using a reason code `32` and t
|
||||||
|
|
||||||
(binding_subkeys)=
|
(binding_subkeys)=
|
||||||
#### Add a Subkey
|
#### Add a Subkey
|
||||||
|
|
||||||
For the purpose of key freshness, a user might want to add a new subkey to their certificate.
|
For the purpose of key freshness, a user might want to add a new subkey to their 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.
|
The structure is as follows:
|
||||||
|
|
||||||
```{figure} diag/subkey_binding_signature.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).
|
|
||||||
|
|
||||||
The structure is as follows:
|
|
||||||
|
|
||||||
| Subpacket | Area | Critical | Mandatory | Notes |
|
| Subpacket | Area | Critical | Mandatory | Notes |
|
||||||
|-----------|------|----------|-----------|-------|
|
|-----------|------|----------|-----------|-------|
|
||||||
|
@ -256,26 +306,8 @@ The [Signature packet](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto
|
||||||
|
|
||||||
Optional algorithm preference subpackets can be used to signal per-subkey preferences that deviate from those set in the certificates `DirectKey` signature.
|
Optional algorithm preference subpackets can be used to signal per-subkey preferences that deviate from those set in the certificates `DirectKey` signature.
|
||||||
|
|
||||||
In order to specify an expiration time for the subkey, a key expiration time subpacket can be included. Note, that the validity of the 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.
|
|
||||||
|
|
||||||
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.
|
|
||||||
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.
|
|
||||||
Contrary to the `SubkeyBinding` signature, which is issued by the certificates primary key, the `PrimaryKeyBinding` signature is instead created by the subkey.
|
|
||||||
|
|
||||||
```{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) is an embedded `PrimaryKeyBinding` "back signature" (type 0x19).
|
|
||||||
|
|
||||||
Note, that a subkey cannot be "older" than the primary key. The value of the subkeys creation date MUST be greater than that of the primary key.
|
|
||||||
|
|
||||||
#### Revoke a Subkey
|
#### Revoke a Subkey
|
||||||
|
|
||||||
Analogous to User IDs, subkeys can be revoked individually.
|
Analogous to User IDs, subkeys can be revoked individually.
|
||||||
This is done by issuing a `SubkeyRevocation` signature (type 0x28) using the primary key.
|
This is done by issuing a `SubkeyRevocation` signature (type 0x28) using the primary key.
|
||||||
The structure of such a signature is rather minimal:
|
The structure of such a signature is rather minimal:
|
||||||
|
@ -290,6 +322,7 @@ In `SubkeyRevocation` signatures, the reason subpacket cannot have value `32`, b
|
||||||
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.
|
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
|
#### Revoke a Certificate
|
||||||
|
|
||||||
A user might want to revoke their whole certificate, rendering it unusable.
|
A user might want to revoke their whole 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.
|
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.
|
||||||
|
|
||||||
|
@ -318,7 +351,7 @@ 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.
|
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 conflicts and duplication
|
### 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.
|
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 precendence over the unhashed area.
|
Therefore, packets in the hashed area take precendence over the unhashed area.
|
||||||
|
|
Loading…
Reference in a new issue