mirror of
https://codeberg.org/openpgp/notes.git
synced 2025-09-10 11:49:40 +02:00
I removed the "type IDs" here, because these are *packet type* IDs. The only IDs we're using in the text are *signature types*. I believe signature type IDs are the only IDs that application developers sometimes think about in numerical terms.
147 lines
No EOL
10 KiB
Markdown
147 lines
No EOL
10 KiB
Markdown
<!--
|
|
SPDX-FileCopyrightText: 2023 The "Notes on OpenPGP" project
|
|
SPDX-License-Identifier: CC-BY-SA-4.0
|
|
-->
|
|
|
|
(signing_data)=
|
|
# Signatures over data
|
|
|
|
In OpenPGP, a *data signature* guarantees the authenticity and, implicitly, the integrity of certain data. Typical use cases include the authentication of software packages and emails.
|
|
|
|
"Authenticity" in this context means that the data signature was issued by the entity controlling the signing key material. However,
|
|
it does not automatically signal if the expected party indeed controls the signer certificate. OpenPGP does offer mechanisms for *strong authentication*, connecting certificates to specific identities. This verifies that the intended communication partner is indeed associated with the cryptographic identity behind the signature[^sign-auth].
|
|
|
|
[^sign-auth]: Other signing solutions, like [signify](https://flak.tedunangst.com/post/signify), focus on pure signing without strong authentication of the signer's identity.
|
|
|
|
Data signatures can only be issued by component keys with the *signing* [key flag](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-key-flags).
|
|
|
|
Note that data signatures are distinct from {ref}`component_signatures_chapter`, which are used to form and maintain certificates, as well as to certify identities on certificates.
|
|
|
|
(data_signature_types)=
|
|
## Signature types
|
|
|
|
OpenPGP data signatures use one of two [signature types](signature_types):
|
|
|
|
- [**Binary signature**](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#sigtype-binary) (type ID `0x00`): This is the standard signature type for binary data and is typically used for files or data streams. Binary signatures are calculated over the data without any modifications or transformations.
|
|
- [**Text signature**](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-signature-of-a-canonical-te) (type ID `0x01`): Used for textual data, such as email bodies. When calculating a text signature, the data is first normalized by converting line endings into a canonical form (`<CR><LF>`). This mitigates issues caused by platform-specific text encodings, which is important for detached and cleartext signatures where the message file might be re-encoded between signature creation and verification.
|
|
|
|
Data signatures are generated by hashing the message content along with the metadata in the OpenPGP signature packet, and calculating a cryptographic signature over that hash. The resulting cryptographic signature is stored in the signature packet.
|
|
|
|
Data signature packets manifest in three distinct forms, which will be detailed in the subsequent section.
|
|
|
|
## Forms of OpenPGP data signatures
|
|
|
|
OpenPGP data signatures can be applied in three distinct forms[^sign-modes-gpg]:
|
|
|
|
- **Detached**: The OpenPGP signature exists as a separate entity, independent from the signed data.
|
|
- **Inline**: Both the original data and its corresponding OpenPGP signature are encapsulated within an OpenPGP container.
|
|
- **Cleartext signature**: A plaintext message and its OpenPGP signature coexist in a combined text format, preserving the readability of the original message.
|
|
|
|
[^sign-modes-gpg]: These three forms of signature application align with GnuPG's `--detach-sign`, `--sign`, and `--clearsign` command options.
|
|
|
|
### Detached signatures
|
|
|
|
A detached signature is produced by calculating an OpenPGP signature over the data intended for signing. The original data remains unchanged, and the OpenPGP signature is stored as a standalone file. A detached signature file can be distributed alongside or independent of the original data. The authenticity and integrity of the original data file can be verified by using the detached signature file.
|
|
|
|
This signature format is especially useful for signing software releases and other files where it is imperative that the content remains unaltered during the signing process.
|
|
|
|
### Inline signatures
|
|
|
|
An inline signature joins the signed data and its corresponding data signature into a single OpenPGP message.
|
|
|
|
This method is commonly used for signing or encrypting emails. Most email software capable of handling OpenPGP communications typically uses inline signatures.
|
|
|
|
#### Structure
|
|
|
|
An inline-signed OpenPGP message consists of three segments:
|
|
|
|
1. [**One-pass signature packets**](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#one-pass-sig): These one or more packets precede the signed data and enable signature computation in one pass.
|
|
|
|
2. [**Literal data packet**](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#lit): This contains the original data (e.g., the body of a message), without additional interpretation or conversion.
|
|
|
|
3. **Data signature packets**: These contain the cryptographic signature corresponding to the original data.
|
|
|
|
#### Creation
|
|
|
|
To produce an inline signature, the signer processes the entirety of the data by reading from an input file and writing into am output OpenPGP message file. As the data is processed, the signer simultaneously calculates a cryptographic signature. This procedure results in a data signature packet being appended to the output OpenPGP message file, an essential step for efficient signing.
|
|
|
|
For efficient verification, an application must understand how to handle the literal data prior to its reading. This requirement is addressed by the One-Pass Signature packets located at the beginning of inline-signed messages. These packets include essential information such as the fingerprint of the signing key and the hash algorithm used for computing the signature's hash digest. This setup enables the verifier to process the data correctly and efficiently.
|
|
|
|
```{admonition} TODO
|
|
:class: warning
|
|
|
|
Is the signer keyid/fingerprint in the OPS important for the verifier to be able to verify the signature efficiently? Or is it (only?) there to be hashed and signed, along with the literal data?
|
|
```
|
|
|
|
#### Verification
|
|
|
|
Inline-signed messages enable efficient verification in *one pass*, structured as follows:
|
|
|
|
1. **Initiation with One-Pass Signature packets**: These packets begin the verification process. They include the signer's key ID/fingerprint, essential for identifying the appropriate public key for signature validation.
|
|
|
|
2. **Processing the literal data**: This step involves hashing the literal data, preparing it for signature verification.
|
|
|
|
3. **Verifying signature packets**: Located at the end of the message, these packets are checked against the previously calculated hash digest.
|
|
|
|
Important to note, the signer's public key, critical for the final verification step, is not embedded in the message. Verifiers must acquire this key externally (e.g., from a key server) to authenticate the signature successfully.
|
|
|
|
### Cleartext signatures
|
|
|
|
The *Cleartext Signature Framework* (CSF) in OpenPGP accomplishes two primary objectives:
|
|
|
|
- maintaining the message in a human-readable cleartext format, accessible without OpenPGP-specific software
|
|
- incorporating an OpenPGP signature for authentication by users with OpenPGP-compatible software
|
|
|
|
#### Example
|
|
|
|
Below is a detailed example of a {numref}`cleartext` signature:
|
|
|
|
```text
|
|
-----BEGIN PGP SIGNED MESSAGE-----
|
|
Hash: SHA512
|
|
|
|
hello world
|
|
-----BEGIN PGP SIGNATURE-----
|
|
|
|
wpgGARsKAAAAKQWCZT0vBCIhBtB7JOyRoU3SQKwtU+bIqeBUlJpBIi6nOFdu0Zyu
|
|
o9yZAAAAANqgIHAzoRTzu/7Zuxc8Izf4r3/qSCmBfDqWzTXqmVtsSBSHACka3qbN
|
|
eehqu8H6S0UK8V7yHbpVhExu9Hu72jWEzU/B0h9MR5gDhJPoWurx8YfyXBDsRS4y
|
|
r13/eqMN8kfCDw==
|
|
=Ks9w
|
|
-----END PGP SIGNATURE-----
|
|
```
|
|
|
|
This signature is split into two parts: a message ("hello world") and an ASCII-armored OpenPGP signature. The message is immediately comprehensible to a human reader, while the signature block allows for the message's authenticity verification via OpenPGP software.
|
|
|
|
#### Use case
|
|
|
|
Clear text signatures combine two of the benefits of detached and inline-signatures:
|
|
|
|
- They are self-contained, the message and signature can be stored as a single file
|
|
- The message remains human-readable, without requiring additional software tooling
|
|
|
|
This combination can be attractive for processes where signed messages are handled in a partially manual manner, and stored in a system that doesn't have strong support for OpenPGP in that particular workflow[^arch-certifications].
|
|
|
|
[^arch-certifications]: For example, Arch Linux uses a workflow to certify User IDs of new packagers that relies on [cleartext signed statements by established packagers](https://gitlab.archlinux.org/archlinux/archlinux-keyring/-/blob/master/.gitlab/issue_templates/New%20Packager%20Key.md?ref_type=heads&plain=1#L33-46). These signed statements are stored in an issue tracker system, as attachments, for later inspection. In this use case, it is convenient that the message and the signature are stored as one combined file (not as separate ones which would be more tedious to handle manually), and that the message is easy to read. Based on the vouches in these cleartext signed messages, and an [email confirmation by the new packager](https://gitlab.archlinux.org/archlinux/archlinux-keyring/-/wikis/workflows/verify-a-packager-key), main signing key operators issue OpenPGP third-party certifications.
|
|
|
|
#### Text transformations for cleartext signatures
|
|
|
|
In the cleartext signature framework, the message text is normalized by [escaping dashes](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-dash-escaped-text), to prevent parsing problems where message content and armor headers are confused.
|
|
|
|
Additionally, as usual for [text signatures](data_signature_types), the signature is calculated on the text with normalized line endings (`<CR><LF>`).
|
|
|
|
#### Pitfalls
|
|
|
|
While widely used, cleartext signatures are sometimes considered a "legacy method"[^csf-gnupg]. The RFC outlines [pitfalls of cleartext signatures](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-issues-with-the-cleartext-s) and advises that inline and detached signature forms are often preferable.
|
|
|
|
[^csf-gnupg]: https://lists.gnupg.org/pipermail/gnupg-devel/2023-November/035428.html
|
|
|
|
## Advanced topics
|
|
|
|
### Nesting of one-pass signatures
|
|
|
|
```{admonition} TODO
|
|
:class: warning
|
|
|
|
Write
|
|
``` |