Edits for clarity; normalize "inline signed".

Inline signed: without dash, to correspond with "one-pass signed". C-R seems inconsistent about this styling.
This commit is contained in:
Heiko Schaefer 2023-12-26 17:15:31 +01:00
parent 7b4031dc0a
commit 59832e220b
No known key found for this signature in database
GPG Key ID: DAE9A9050FCCF1EB
1 changed files with 30 additions and 24 deletions

View File

@ -8,11 +8,11 @@ SPDX-License-Identifier: CC-BY-SA-4.0
(adv-inline-signature)=
## Internals of inline signed messages
Inline-signed messages are one of the forms of [OpenPGP data signatures](forms-of-data-signatures). An {term}`inline-signed message <inline signature>` joins the signed data and its corresponding {term}`data signature` into a single {term}`OpenPGP message`.
Inline signed messages are one of the forms of [OpenPGP data signatures](forms-of-data-signatures). An {term}`inline signed message <inline signature>` joins the signed data and its corresponding {term}`data signature` into a single {term}`OpenPGP message`.
OpenPGP defines two variant forms of inline-signed messages:
OpenPGP defines two variant forms of inline signed messages:
1. **{term}`One-pass signed messages<One-pass signed Message>`** This is the commonly used format for inline-signed messages. A signer can produce and a verifier can verify this format in one pass.
1. **{term}`One-pass signed messages<One-pass signed Message>`** This is the commonly used format for inline signed messages. A signer can produce and a verifier can verify this format in one pass.
2. **{term}`Prefixed signed messages<Prefixed signed Message>`** This format predates[^inline-signature-formats] {term}`one-pass signed messages<One-pass signed Message>` and is conceptually slightly simpler. However, it has no strong benefits and is now rarely used.
[^inline-signature-formats]: One-pass signing was first specified in RFC 2440. The format was not supported in PGP 2.6.x.
@ -28,7 +28,7 @@ A {term}`one-pass signed<One-pass signed Message>` {term}`OpenPGP message` consi
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 {term}`packets<Packet>` precede the signed data and enable {term}`signature<OpenPGP Signature Packet>` computation (both creation and verification) in a single pass.
2. [**{term}`OpenPGP message`**](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), which is signed without additional interpretation or conversion. Internally, a signed [message](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-openpgp-messages) consists of one or more OpenPGP packets. The message that gets signed could, for example, consist of a {term}`Literal Data Packet`, or a {term}`Compressed Data Packet`.
2. [**{term}`OpenPGP message`**](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), which is signed without additional interpretation or conversion. Internally, a signed [message](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-openpgp-messages) consists of one or more OpenPGP packets. The message that gets signed will typically consist of either a {term}`Literal Data Packet`, or a {term}`Compressed Data Packet`.
3. **{term}`Data signature packets<OpenPGP Signature Packet>`**: These contain the {term}`cryptographic signature` corresponding to the original data.
@ -42,40 +42,46 @@ The structure of a one-pass signed message.
```{note}
Despite its name, a {term}`one-pass signature packet` is not a type of {term}`signature packet<OpenPGP Signature Packet>`.
Instead, it's a type of auxiliary packet that can be used in conjunction with {term}`signature packets<OpenPGP Signature Packet>`. Its use allows storing the {term}`signature packets<OpenPGP Signature Packet>` after the message body.
Instead, it's a type of auxiliary packet that can be used in conjunction with {term}`signature packets<OpenPGP Signature Packet>`, to enable efficient generation and checking of inline signed messages.
The structure of a {term}`one-pass signature packet` closely mirrors an {term}`OpenPGP signature packet`. However, it does not contain a cryptographic signature.
```
#### The function of the one-pass signature packet
To understand the purpose of this packet, consider that without it, the position of signature packets within an inline signed OpenPGP message constitutes a trade-off for efficient data processing. In particular when signed data is large and exceeds available memory in size.
The purpose of this packet is efficient handling of inline signed messages in *stream processing* mode. This is particularly important when the signed message is large and exceeds available memory in size.
The producer of a signed OpenPGP message wants to streamline the signature calculation process in such a way that allows to emit a copy of the signed data while calculating the cryptographic signature. On the signer's side, the signature packet is therefore easy to store after the signed data.
Without this packet, the position of signature packets within an inline signed OpenPGP message constitutes a trade-off:
The verifier, on the other hand, needs some information from the signature packet in order to perform the signature verification process. In particular, the verifier needs to know which hash algorithm was used to calculate the signature, in order to perform the same hashing operation on the message data.
- The producer of a signed OpenPGP message wants to streamline the signature calculation process in such a way that allows to emit a copy of the signed data while calculating the cryptographic signature. On the signer's side, the signature packet is therefore easy to store after the signed data.
- The verifier, on the other hand, needs some information from the signature packet to perform the signature verification process. In particular, the verifier needs to know which hash algorithm was used to calculate the signature, to perform the same hashing operation on the message data.
As a consequence, without a {term}`one-pass signature packet`, either:
- the producer would need to process the signed data twice:
- once to calculate the signature, and
- a second time to emit the signed data (the result is a prefixed signed message), or
- the verifier would need to process the OpenPGP message twice:
- once to read the signature packets at the end in order to determine the hash algorithm, and
- The producer would need to process the input data twice:
- once to calculate the cryptographic signature, and
- a second time to emit the signed data (this format result is a [](prefixed-signature)), or
- The verifier would need to process the OpenPGP message twice:
- once to read the signature packets at the end to determine the hash algorithm, and
- a second time to process the body of the message, and calculate the hash verifying the signature.
The one-pass signature packet solves this issue, by allowing both the creation and verification of a signed message in a single pass. It effectively contains a copy of the data in a signature packet, but without the cryptographic signature data.
The one-pass signature packet solves this issue by allowing both the *creation* and *verification* of a signed message in a single pass. The one-pass signature packet effectively contains an advance copy of the data in the signature packet, but without the cryptographic signature data.
The signer can easily emit this metadata before processing the full message, and for the verifier, this metadata enables processing of the message body. Both signer and verifier can efficiently generate or check a one-pass signed message.
The signer can easily emit the metadata in the one-pass signature packet before processing the full message. For the verifier, availability of this metadata at the start of the signed message enables processing of the message body.
Even in stream processing mode, signers can efficiently generate one-pass signed messages, and verifiers can efficiently check them.
#### Creation
To produce a {term}`one-pass inline signature<One-pass signed Message>`, the {term}`signer` decides on a hash algorithm and emits a {term}`one-pass signature packet<One-pass Signature Packet>` into the destination {term}`OpenPGP message`. This contains essential information such as the {term}`fingerprint<OpenPGP Fingerprint>` of the {term}`signing key<OpenPGP Component Key>` and the {term}`hash<Hash Digest>` algorithm used for computing the {term}`signature<OpenPGP Signature Packet>`'s {term}`hash digest`. The signer then processes the entirety of the signed message, emitting it as a series of one or more {term}`packets<Packet>` into the message as well. Once the data is processed, the {term}`signer` calculates a {term}`cryptographic signature` using the calculated hash value. Lastly, the result is emitted as a {term}`data signature packet` to the output message, and the whole packet sequence can be efficiently stored or transmitted.
For efficient {term}`verification`, an application must understand how to handle the {term}`OpenPGP message` prior to reading from it. This requirement is addressed by the {term}`one-pass signature packets<One-pass Signature Packet>` located at the beginning of {term}`inline-signed<Inline Signature>` messages. This setup enables the verifier to process the data correctly and efficiently in a single pass.
For efficient {term}`verification`, an application must understand how to handle the {term}`OpenPGP message` prior to reading from it. This requirement is addressed by the {term}`one-pass signature packets<One-pass Signature Packet>` located at the beginning of {term}`inline signed<Inline Signature>` messages. This setup enables the verifier to process the data correctly and efficiently in a single pass.
Strictly speaking, knowing just the hash algorithm would be sufficient to begin the verification process. However, having efficient access to the signer's fingerprint or key ID upfront allows OpenPGP software to fetch the signer's certificate(s) before processing the entirety of the - potentially large - signed data. This may, for example, involve downloading the certificate from a keyserver. In case fetching the signer's certificate(s) fails, or requires additional input from the user, it is better to signal the user about this before processing the data.
#### Verification
{term}`Inline-signed<Inline Signature>` messages enable efficient {term}`verification` in *one pass*, structured as follows:
{term}`Inline signed<Inline Signature>` messages enable efficient {term}`verification` in *one pass*, structured as follows:
1. **Initiation with {term}`one-pass signature packets<One-pass Signature Packet>`**: These {term}`packets<Packet>` begin the {term}`verification` process. They include the {term}`signer`'s {term}`key ID`/{term}`fingerprint<OpenPGP Fingerprint>`, essential for identifying the appropriate {term}`public key<OpenPGP Certificate>` for signature {term}`validation`.
@ -87,24 +93,24 @@ Important to note, the {term}`signer`'s {term}`public key<OpenPGP Certificate>`,
#### Nesting of one-pass signatures
Signing a message using the one-pass mechanism involves prepending a *one-pass signature* (OPS) packet to the message and appending the corresponding signature, sandwiching the signed content.
A {term}`one-pass signed message` can contain multiple signatures.
An OpenPGP message can contain multiple signatures added that way.
There are two subtly different use cases for this:
- Multiple signers can issue cryptographic signatures that can be stored in one shared (and thus space-efficient) inline signed message. In this case, each signer makes a cryptographic statement about just the signed message. The individual signatures are independent of each other.
- Alternatively, a later signer can sign not just the input message, but also include a previous signature in their signature. In this case, the second signer notarizes the previous signer's signature combined with the signed message.
```{note}
One-pass signatures are nested, meaning the outermost one-pass signature packet corresponds to the outermost signature packet.
One-pass signatures are nested. The outermost one-pass signature packet corresponds to the outermost signature packet.
```
When a message is signed, the signature is always calculated over the contents of the literal data packet, not the literal data packet itself.
This means that if a message, which is compressed using a compressed data packet is wrapped using a one-pass signature, the signature is still being calculated over the plaintext inside the literal data packet.
There is one exception, though.
```{note}
Of course there is.
```
The OPS packet has a "nested" flag[^nested-flag], which can either be `1` or `0`.
If this flag is set to `0`, it indicates that further OPSs will follow this packet, which are calculated over the same plaintext data as this OPS is. A value of `1` indicates, that either no further OPS packets will follow (this OPS is the last), or that this OPS is calculated over the the usual plaintext data, but wrapped inside any OPS+Signature combinations that follow this OPS.
If this flag is set to `0`, it indicates that further OPSs will follow this packet, which are calculated over the same plaintext data as this OPS is. A value of `1` indicates, that either no further OPS packets will follow (this OPS is the last), or that this OPS is calculated over the usual plaintext data, but wrapped inside any OPS+Signature combinations that follow this OPS.
[^nested-flag]: See [description of the nested flag](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#section-5.4-3.8.1).