ch6: add snapshot of Paul's changes from #25 (for easier test-reading)

This commit is contained in:
Heiko Schaefer 2023-09-26 13:20:34 +02:00
parent 6d38a9cc1f
commit c72432af4b
No known key found for this signature in database
GPG key ID: 4A849A1904CCBD7D

View file

@ -1,60 +1,90 @@
(signatures_chapter)= (signatures_chapter)=
# Signatures as "statements" # Signatures as "statements"
``` Signatures make up the magic of OpenPGP.
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.
Signatures are the glue that allows for keys, subkeys and identities to be assembled into hierarchical certificates and for messages to gain authenticity.
```{admonition} TODO
:class: warning
- Purpose of a signature - Purpose of a signature
- Meaning of different signature types, nuances of subpackets - Meaning of different signature types, nuances of subpackets
- Can we have a "catalogue" of statements a user might want to make, mapping these to archetypical signatures? - Can we have a "catalogue" of statements a user might want to make, mapping these to archetypical signatures?
- Revocation; Hard vs. Soft - Revocation; Hard vs. Soft
``` ```
## Certifications (third party signatures on keys) ## Terminology
A certification is a machine-readable statement about a (public) key, made by a third party. The term *signature* can have multiple meanings in the context of the OpenPGP specification.
In OpenPGP, certifications are implemented as Cryptographic keys create raw signatures which are byte sequences calculated according to some signature scheme.
[Signature Packets](https://datatracker.ietf.org/doc/html/rfc4880#section-5.2). OpenPGP packs these raw signatures up into OpenPGP signature packets, which carry additional information in the form of signature subpackets.
For the purpose of this document, the term signature will refer to an OpenPGP signature packet (tag 2).
More specifically, certifications in OpenPGP are usually modelled as "third party binding signatures". OpenPGP signatures can be separated into *data signatures* and *certifications*.
A data signature serves the purpose to cryptographically guarantee the authenticity (and implicitly also the integrity) of a message, e.g. an email or a file, while a certification is used to attach metadata or subkeys to a certificate.
Data signatures are always calculated by keys carrying the **S**igning key flag, while certifications require keys carrying the **C**ertify Others key flag (with the exception of so called Primary Key Binding Signatures).
Different types of signatures are distinguished by a signature type code and are calculated in different ways.
Signatures can either be distributed standalone as *detached* signatures, or can be inlined with OpenPGP data, such as an OpenPGP message or a key or certificate.
Typically, certifications in OpenPGP work like this: Alice checks that a key `0x1234...` belongs to Bob, who uses the Data signatures (type 0x00 and 0x01) are created by hashing the message content and calculating a cryptographic signature over the hash.
email address `bob@example.org`. After making sure that the key `0x1234...` and the digital identity `bob@example.org` The result is packed up into an OpenPGP signature packet, which can either be included in the OpenPGP message (TODO: See section about forming messages, cleartext signature framework), or distributed separately as a so called *detached* signature.
are meaningfully linked, she creates a certification stating that the key and the identity are linked. Data signatures are always calculated using a **S**igning key.
Such a certification can serve two purposes: A certification made by a key over components of the same certificate is referred to as a *self-certification*.
A typical use-case for a self-certification is to attach a user ID, such as a name and email address to a certificate.
This is done by calculating the signature over the user ID and the public primary key.
The resulting user ID certification (typically type 0x13, potentially type 0x10-0x12) can then be inserted into the certificate, right after the user ID packet.
1) Alice's OpenPGP software can now reason about Bob's key, and thus show that `0x1234...` is a good key to use for Other examples for self-signatures are binding signatures for subkeys.
interacting with `bob@example.org`. In order to add an OpenPGP subkey to a certificate, a subkey binding signature is calculated over the public primary key, followed by the public subkey.
2) Other parties can observe Alice's certification and derive some amount of confidence in Bob's key from it. The resulting subkey binding signature (type 0x18) can then be inserted into the certificate right after the subkey.
For example, Carol might not easily be able to check if `0x1234...` is Bob's key, but she might consider Alice's If the subkey itself is intended to be used as a **S**igning key, an extra step is required.
certification for Bob's key sufficient evidence. To prevent an attacker from being able to "adopt" a victims signing subkey and then being able to claim to be the origin of signatures in fact made by victim, subkey binding signatures for signing subkeys need to include an embedded "back signature" (formally known as primary key binding signature) made by the signing key itself.
Carol may decide to systematically rely on Alice's certifications. Then we say that Carol uses Alice as a Certifications over user IDs can also be used to certify certificates of third-parties.
"trusted introducer". That is, Carol *delegates* part of her authentication decisions to Alice. If Alice is certain that `Bob Baker <bob@example.com>` controls the key 0xB0B, she can create a user ID certification signature for that identity and send it to Bob.
Bob can then add this signature to his certificate.
TODO: More WoT.
Another important category of signatures are revocations.
A revocation is used to retract the statement formed by a prior signature.
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, or marking user IDs as no longer used.
### Regular certifications ## Signature Subpackets
Are a cryptographic statement that binds a User ID and a Key (via its fingerprint) together. A cryptographic signature alone is often not expressive enough to fulfil certain use-cases.
For this reason, the OpenPGP protocol introduced signature subpackets with rfc4880.
These are well-defined data structures that can be placed as subelements into signature packets, which give additional context and meaning to a signature.
Typical examples are the issuer fingerprint subpacket, which contains the fingerprint of the issuer key, or the key flags subpacket which states, what purpose a component key is intended for.
Have a SignatureType in `GenericCertification, PersonaCertification, CasualCertification, PositiveCertification`. Signature subpackets can reside in two different areas of a signature packet.
Subpackets in the *hashed area* are incorporated in the digest calculation that is done during signature calculation and are therefore covered by the cryptographic signature.
Hashed subpackets are *authenticated*.
If a subpacket is placed in the *unhashed area* instead, it is not included in the signature calculation procedure.
The unhashed area can be used to retroactively add, change or remove subpackets from a signature without invalidating it.
### Trust signatures (using a key as "trusted introducer") Due to the fact that the unhashed area doesn't provide any cryptographic guarantees, it is only intended for advisory packets, or packets that self-authenticate (e.g. issuer key ID / issuer fingerprint subpackets, whose "correctness" can be proven by successfully verifying the signature using the referenced issuer key).
In most cases, signature subpackets are simply added into the hashed area.
A "trust signature" has two additional parameters: a `depth` and a `level`. 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.
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 occurence of a conflicting packet.
#### Alternative model: direct key signatures for pure delegation In some cases, duplicate packets with conflicting content even make sense, e.g. if a signature was made by a version 6 issuer key whose key material was migrated from an older OpenPGP version such as v4.
In this case, the v4 key could be used to validate the v6 signature, but since the fingerprint and key ID calculation scheme was changed between v4 and v6, these identifiers would differ.
Therefore, the signature could contain two sets of issuer fingerprint and isuer key ID subpackets with conflicting, but correct values.
This is useful for using 0xB as a trusted introducer without asserting that 0xB is Bob ```{admonition} TODO
(when a tsig is on a User ID, it is necessarily *also* a vouch about the binding). :class: warning
The logical place to store a tsig that is not also a vouch about a binding is a direct key signature - Key Flags
(however, GnuPG does probably not respect such tsigs). - Preferences
- Embedded Signature (back sig)
The [OpenPGP Web of Trust](https://sequoia-pgp.gitlab.io/sequoia-wot/) spec allows such direct key signatures. - Trust Signatures (amount, depth)
- Direct key signatures
SignatureType is `DirectKey`
In Sequoia, roughly:
```
SignatureBuilder::new(SignatureType::GenericCertification).set_trust_signature(..).sign_direct_key(&mut your_signer, &signee_cert.primary_key())
``` ```