<!--
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 signatures over data are distinct from {ref}`component_signatures_chapter`, which are used to attach metadata or subkeys to a certificate.

## Signature types

OpenPGP data signatures use one of two [signature types](signature_types):

- **Binary signature** (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** (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 particularly important for detached 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 signature packet, and calculating a cryptographic signature over that hash. The resulting cryptographic signature is stored in an OpenPGP signature packet.

Data signature packets manifest in three distinct forms, which will be detailed in the subsequent section.

## Forms of OpenPGP data signatures

OpenPGP signatures over data can be used in three different forms[^sign-modes-gpg]:

- *Detached*: The signature is a standalone artifact, separate from the signed data.
- *Inline*: The original data and the signature over data are enclosed within an OpenPGP container.
- *Cleartext signature*: A plaintext message and a signature over this message are stored in a combined text-format, maintaining the original message's readability.

[^sign-modes-gpg]: These three signature forms correspond with GnuPG's `--detach-sign`, `--sign` and `--clear-sign` modes.

### Detached signatures

A detached signature is produced by calculating an OpenPGP signature over the signed data. The original data is left as is, while the OpenPGP signature is stored as a standalone file. A detached signature can be distributed alongside or independent of the original data. The authenticity and integrity of the original data file can be verified using the detached signature file.

This signature format is especially useful for signing software releases and other files that must not be modified by the signing process.

### Inline signatures

An inline signature joins the signed data and a signature over this data into one combined OpenPGP message.

This method is usually used with signed and/or encrypted emails. Most software that supports OpenPGP for encrypted and/or signed messages uses inline-signatures.

#### Structure

An inline-signed OpenPGP message consists of three segments:

- One or more [One-Pass Signature packets](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#one-pass-sig),
- the original data, wrapped in a [Literal Data packet](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#lit),
- the corresponding Data Signature packets.

#### 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. The signer calculates a cryptographic signature over the course of this process. Therefore, an efficient signer can only emit the resulting data signature packet at the end of this process, and thus store it at the end of the data stream.

On the other hand, an efficient verifying application needs to know how to process the literal data before reading it. This is the purpose of the so-called One-Pass Signature packets in the first segment of inline-signed messages. One-Pass Signature packets contain the fingerprint of the signing key, as well as the hash algorithm used to calculate the hash digest for the signature.

```{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

This structure allows verifying applications to verify inline-signed messages in *one pass*:

- The One-Pass Signature packets initiate the verification process,
- the literal data can then be processed (which means: it gets hashed),
- the signature packets at the end of the message can be verified against the hash digest that the previous step calculated.

Note that the final step of verifying the cryptographic signature requires access to the signer's public key material. This public key material is not included in the signed message. The verifier must obtain the signer's public key data out-of-band (e.g. by obtaining the signer's certificate from a key server).

### Cleartext signatures

The *Cleartext Signature Framework* (CSF) is an OpenPGP mechanism that combines two goals:

- It leaves the message in clear text format, so that it can be viewed directly by a human in a program that knows nothing about OpenPGP.
- At the same time, it adds an OpenPGP signature that allows verification of that message by users whose software supports OpenPGP.

#### Example

In {numref}`cleartext` we inspect an example of a cleartext signature in detail. Let's have a brief look at this example, here, to get a sense of what a cleartext signature looks like:

```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-----
```

A cleartext signature consists of two blocks. These blocks contain the message and a signature, respectively. In this case, the message consists of the text `hello world`.

Notice that the message in the first block is readable by a human reader, without requiring additional software tools, as long as the reader knows where to look, and which elements to ignore.

The second block contains an ASCII-armored OpenPGP signature for the message. Using this signature, OpenPGP software can verify the authenticity of the message.

#### Use-cases

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

```{admonition} TODO
:class: warning

explain text transformations for cleartext signatures (LF->CRLF and additional escaping)
```

#### Pitfalls

Cleartext signatures are popular and have useful applications.

At the same time, they are considered a "legacy method"[^csf-gnupg] by some.

[^csf-gnupg]: https://lists.gnupg.org/pipermail/gnupg-devel/2023-November/035428.html

The RFC points out a number of specific [pitfalls of cleartext signatures](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-issues-with-the-cleartext-s), and how to avoid them. It advises that in many cases, the inline and detached signature forms are preferable.

## Advanced topics

### Nesting of one-pass signatures

```{admonition} TODO
:class: warning

Write
```