mirror of
https://codeberg.org/openpgp/notes.git
synced 2025-09-10 11:49:40 +02:00
Minor edits for clarity (and consistency with other chapters)
This commit is contained in:
parent
058b7b5ebc
commit
09a64ee541
1 changed files with 31 additions and 31 deletions
|
@ -4,45 +4,46 @@ SPDX-License-Identifier: CC-BY-SA-4.0
|
||||||
-->
|
-->
|
||||||
|
|
||||||
(verification_chapter)=
|
(verification_chapter)=
|
||||||
# Verification
|
# Signature verification
|
||||||
|
|
||||||
Signature verification in the OpenPGP protocol is a complex process.
|
Signature verification in the OpenPGP protocol is a complex process.
|
||||||
There are lots of different factors that can influence the validity of a signature, most importantly its expiration date.
|
There are lots of different factors that can influence the validity of a signature, most importantly its expiration date.
|
||||||
A signature can be valid at one point in time and invalid merely a second later.
|
A signature can be valid at one point in time and invalid merely a second later.
|
||||||
Signatures can be invalid due to the absence or presence of other signatures (e.g. revocations).
|
Signatures can be invalid due to the absence or presence of other signatures (e.g. revocations).
|
||||||
Some signatures can be verified standalone, while others require the verification of a chain-like structure of other signatures, mostly on the issuers certificate.
|
Some signatures can be verified standalone, while others require the verification of a chain-like structure of other signatures, mostly within the issuer's certificate.
|
||||||
|
|
||||||
|
|
||||||
## When are signatures valid?
|
## When are signatures valid?
|
||||||
|
|
||||||
As a necessary condition, a valid signature must be cryptographically correct, meaning the signature, as well as the signed information must be intact.
|
As a necessary condition, a valid signature must be [cryptographically correct](sig-verify), meaning the signature, as well as the signed information must be intact.
|
||||||
However, there is a difference between signature *correctness* and *validity*.
|
However, there is a difference between signature *correctness* and *validity*.
|
||||||
A signature might be correct, but still disqualify as a valid signature.
|
A signature might be cryptographically correct, but still not qualify as a *valid* signature.
|
||||||
Put mathematically, the set of valid signatures is a subset of the set of correct signatures.
|
Put mathematically, the set of valid signatures is a subset of the set of correct signatures.
|
||||||
|
|
||||||
The validity of a correct signature is additionally constrained by a number of conditions:
|
The validity of a correct signature is additionally constrained by a number of conditions:
|
||||||
* well-formedness
|
* **Well-formedness**:
|
||||||
Signatures need to be well-formed, meaning they must contain required signature subpackets in the proper subpacket area and must not contain unknown critical subpackets or unknown critical notations.
|
Signatures need to be well-formed, meaning they must contain required signature subpackets in the proper subpacket area and must not contain unknown critical subpackets or unknown critical notations.
|
||||||
Note: This also means, that a signature might be considered valid by one implementation and be rejected by another.
|
Note: This also means that a signature might be considered valid by one implementation and be rejected by another.
|
||||||
Some implementations further apply a policy when verifying signatures, putting constraints on used hash- and key algorithms and key strengths.
|
Some implementations further apply a policy when verifying signatures, putting constraints on accepted hash- and key algorithms and key strengths.
|
||||||
* temporal validity
|
* **Temporal validity**:
|
||||||
Most signatures have a limited validity period, constrained by the signature creation- and expiration time.
|
Most signatures have a limited validity period, constrained by the signature creation- and expiration time.
|
||||||
* qualification
|
* **Qualification**:
|
||||||
Furthermore, some signatures need to be *qualified* by other valid signatures in order to be considered valid.
|
Furthermore, some signatures need to be *qualified* by other valid signatures in order to be considered valid.
|
||||||
This is especially the case with signatures created by dedicated signing subkeys, where, in addition to the signature itself, the subkeys binding signature(s) must be verified.
|
This is especially the case with signatures created by dedicated signing subkeys, where, in addition to the signature itself, the subkeys binding signature(s) must be verified.
|
||||||
* revocation
|
* **Revocation**:
|
||||||
Lastly, signatures can be invalidated by revocations.
|
Lastly, signatures can be invalidated by revocations.
|
||||||
|
|
||||||
### Temporal validity
|
### Temporal validity
|
||||||
|
|
||||||
A signature is valid only for a constrained period of time.
|
A signature is valid only for a constrained period of time:
|
||||||
A lower constraint for the validity period is the creation time of the signature, meaning a signature only becomes valid after its creation timestamp.
|
|
||||||
An upper constraint might be the signatures expiration time.
|
|
||||||
A special case are hard revocation signatures, where the lower constraint is dropped, so hard revocations are valid since the dawn of time.
|
|
||||||
|
|
||||||
When checking a signature for validity, a reference time is defined.
|
- The creation time of the signature acts as a lower bound for the validity. A signature only becomes valid after its creation time. Hard revocation signatures are an exception: they are by definition valid since the dawn of time, and have no lower temporal bound.
|
||||||
For an email that might be the signature creation time itself, or the reception date.
|
|
||||||
For the signature to qualify as valid, it needs to be effective, in other words, the reference time must fall into the period from signature creation to signature expiration.
|
- If present, the signature's expiration time defines an upper bound for its validity.
|
||||||
|
|
||||||
|
When checking a signature for validity, a reference time is used.
|
||||||
|
This can be the current time during validation, or a point in time that relates to the signature that is getting checked.
|
||||||
|
For example, when checking a signature in an email, the reference time might be the signature creation time, or the time of receipt for the email.
|
||||||
|
For the signature to qualify as valid, it needs to be effective. In other words, the reference time must fall into the period between signature creation and signature expiration.
|
||||||
|
|
||||||
The same reference time must be used when verifying additional qualifying signatures.
|
The same reference time must be used when verifying additional qualifying signatures.
|
||||||
|
|
||||||
|
@ -62,8 +63,8 @@ This qualification typically comes via another self-signature on the key itself.
|
||||||
|
|
||||||
Instead, a chain of valid signatures from the signature itself to the primary key of the issuer certificate needs to be established.
|
Instead, a chain of valid signatures from the signature itself to the primary key of the issuer certificate needs to be established.
|
||||||
|
|
||||||
For example, a data signature over an email body may be issued by a subkey only if that subkey is validly bound to the users certificate via a subkey binding signature, and that binding signature needs to contain a key flags subpacket marking the subkey as **S**igning capable.
|
For example, a data signature over an email body may be issued by a subkey only if that subkey is validly bound to the certificate via a subkey binding signature. That binding signature needs to contain a *key flags* subpacket that marks the subkey as *signing* capable.
|
||||||
Similarly, certification signatures over third-party certificates require the issuer key to carry a self-signature qualifying it to **C**ertify other keys.
|
Similarly, certification signatures over third-party certificates require the issuer key to carry a self-signature with the *certification* key flag.
|
||||||
|
|
||||||
Self-qualifying signatures have no such limitations.
|
Self-qualifying signatures have no such limitations.
|
||||||
For example, a certificate consisting only of a primary key and a single key-revocation self-signature contains everything needed to verify the revocation, as key-revocation self-signatures are self-qualifying.
|
For example, a certificate consisting only of a primary key and a single key-revocation self-signature contains everything needed to verify the revocation, as key-revocation self-signatures are self-qualifying.
|
||||||
|
@ -93,8 +94,7 @@ Note: Attribute shadowing should only be used for algorithm preferences, since t
|
||||||
### Signature shadowing
|
### Signature shadowing
|
||||||
|
|
||||||
When inspecting signatures on a component of an OpenPGP certificate, only the newest, effective signature for each function is considered.
|
When inspecting signatures on a component of an OpenPGP certificate, only the newest, effective signature for each function is considered.
|
||||||
In other words; If there are three binding signatures `A, B, C` for a subkey, where `A` was created at `t0`, `B` at `t1` and `C` at `t3` with `t0 < t1 < t2 < t3`, at `t2` an implementation only needs to consider `B`, as `C` is not yet effective.
|
In other words; If there are three binding signatures `A, B, C` for a subkey, where `A` was created at `t0`, `B` at `t1` and `C` at `t3` with `t0 < t1 < t2 < t3`, at `t2` an implementation only needs to consider `B`, as `C` is not yet effective. `A` is shadowed, because it is older than `B`.
|
||||||
`A` is therefore shadowed.
|
|
||||||
|
|
||||||
```{figure} drawio/cert-validity-subkey.png
|
```{figure} drawio/cert-validity-subkey.png
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ When verifying a non-self-qualifying signature, an implementation needs to ident
|
||||||
There might be more than one candidate for such a signature.
|
There might be more than one candidate for such a signature.
|
||||||
|
|
||||||
For example, there might be multiple subkey binding signatures for the same subkey.
|
For example, there might be multiple subkey binding signatures for the same subkey.
|
||||||
In general, for each category of signatures, only that with the latest signature creation time is considered and takes precendence.
|
In general, for each category of signatures, only that with the latest signature creation time is considered and takes precedence.
|
||||||
|
|
||||||
Alternatively, there might be competing qualifying signatures of different types, e.g. a direct key signature and a self-certification signature on a primary User ID.
|
Alternatively, there might be competing qualifying signatures of different types, e.g. a direct key signature and a self-certification signature on a primary User ID.
|
||||||
In this case, depending on how a key is "addressed", different attributes from both candidates "shadow" another.
|
In this case, depending on how a key is "addressed", different attributes from both candidates "shadow" another.
|
||||||
|
@ -138,11 +138,11 @@ TODO: Replace hash algorithm preferences with AEAD preferences for a more realis
|
||||||
For example, the latest direct key signature could list "SHA512, SHA384" as hash algorithm preferences, while the latest self-certification of User ID "Bob" could list "SHA256" only.
|
For example, the latest direct key signature could list "SHA512, SHA384" as hash algorithm preferences, while the latest self-certification of User ID "Bob" could list "SHA256" only.
|
||||||
For yet another User ID "Bobby", the self-signature could list no hash algorithm preferences at all.
|
For yet another User ID "Bobby", the self-signature could list no hash algorithm preferences at all.
|
||||||
If the user wants to compose a signed message using the associated OpenPGP key, they need to figure out, which preferences to use.
|
If the user wants to compose a signed message using the associated OpenPGP key, they need to figure out, which preferences to use.
|
||||||
The specification recommends, that implementations decide which signature takes precendence by the way the certificate is "addressed".
|
The specification recommends, that implementations decide which signature takes precedence by the way the certificate is "addressed".
|
||||||
|
|
||||||
```{figure} drawio/narrow-interpretation.png
|
```{figure} drawio/narrow-interpretation.png
|
||||||
|
|
||||||
Preferrences are sourced from different component signatures, depending on how the key is addressed.
|
Preferences are sourced from signatures on different components, depending on how the key is addressed.
|
||||||
```
|
```
|
||||||
|
|
||||||
If the user wants to write an email as "Bob", it should consider the signature on "Bob", so SHA256 should be used as hash algorithm.
|
If the user wants to write an email as "Bob", it should consider the signature on "Bob", so SHA256 should be used as hash algorithm.
|
||||||
|
@ -151,10 +151,10 @@ However, since this signature does not carry any hash algorithm preferences subp
|
||||||
The same is true, if the certificate is used without any User ID as sender.
|
The same is true, if the certificate is used without any User ID as sender.
|
||||||
|
|
||||||
But it gets more complicated still.
|
But it gets more complicated still.
|
||||||
Algorithm preferences can also "live" on subkey binding signatures, so if the certificate has a dedicated signing subkey, there is yet another signature which could take precendence.
|
Algorithm preferences can also "live" on subkey binding signatures, so if the certificate has a dedicated signing subkey, there is yet another signature which could take precedence.
|
||||||
Preferences from the subkey binding signature take precendence over the direct key signature, but not over self-certifications on the User ID.
|
Preferences from the subkey binding signature take precedence over the direct key signature, but not over self-certifications on the User ID.
|
||||||
|
|
||||||
TODO: Have a table that lists which signatures take precendence in which cases.
|
TODO: Have a table that lists which signatures take precedence in which cases.
|
||||||
|
|
||||||
There can be more than one signature on a component. For example, there could be 3 direct key signatures, e.g. because the user extended the lifespan of their key 2 times already.
|
There can be more than one signature on a component. For example, there could be 3 direct key signatures, e.g. because the user extended the lifespan of their key 2 times already.
|
||||||
In general, for each component, only the newest self-signature is "in effect", and older signatures are "shadowed".
|
In general, for each component, only the newest self-signature is "in effect", and older signatures are "shadowed".
|
||||||
|
@ -164,10 +164,10 @@ TODO: direct key signatures can be revoked, canceling them, meaning an older one
|
||||||
## Complexity of the packet format
|
## Complexity of the packet format
|
||||||
|
|
||||||
Unfortunately, the OpenPGP packet format allows for quite a lot of flexibility when composing certificates.
|
Unfortunately, the OpenPGP packet format allows for quite a lot of flexibility when composing certificates.
|
||||||
User ID packets for example, are not fixed with regards to their position, which means that an attacker (or canonicalizer) can change the order in which User IDs appear in the certificates packet sequence.
|
User ID packets for example, are not fixed in regard to their position, which means that an attacker (or canonicalizer) can change the order in which User IDs appear in the certificates packet sequence.
|
||||||
|
|
||||||
As a concrete example, consider a certificate with multiple User IDs, all marked as primary. Or equaly, a certificate with multiple User IDs of which none is marked as primary.
|
As a concrete example, consider a certificate with multiple User IDs, all marked as primary. Or equally, a certificate with multiple User IDs of which none is marked as primary.
|
||||||
Clients might apply different heuristics to figure out, which User ID actually qualifies as the primary User ID here.
|
Clients might apply different heuristics to figure out, which User ID actually qualifies as the primary User ID here.
|
||||||
|
|
||||||
You might wonder, which signature on the primary key takes precendence in case of multiple signature candidates with conflicting signature subpackets.
|
You might wonder which signature on the primary key takes precedence in case of multiple signature candidates with conflicting signature subpackets.
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue