Summary

  • RFC 2015 used RFC 1847's multipart/signed so a readable MIME body could remain separate from a detached PGP signature, while the signature still covered the body's MIME content headers and encoded bytes.
  • That separation worked only if mail infrastructure stopped silently rewriting the signed first part: CRLF, 7-bit transfer form, Quoted-Printable or Base64 choices, leading From and trailing whitespace all belonged to the evidence boundary.
  • Verification therefore proves a relationship among one byte sequence, one signature and one key. It does not by itself prove real-world identity, intent, delivery, display, time, authorization or outcome.

In the example inside RFC 2015, the important mark is not the armored PGP block. It is the ampersand printed before each line of the first MIME part. The document explains that those marked lines—both content headers and body—are what the signature covers. A reader may see Spanish punctuation and a joke. The verifier sees a precisely ordered byte stream.

That distinction solved an earlier usability failure. Before RFC 2015, PGP/MIME experiments included an application/pgp form that forced software to understand PGP-specific data structures merely to recover the signed message body. RFC 2015 instead adopted the protocol-neutral security multipart framework from RFC 1847. The first part held the signed MIME entity. The second held detached control information labelled application/pgp-signature. A MIME implementation that did not understand PGP could still identify the parts and process other MIME content.

The design did not make the readable body independent of cryptography. It made the boundary visible.

The label was inside the signature

RFC 1847 defined multipart/signed as exactly two parts. The first was the body part over which the signature was made, including its MIME headers; the second carried the verification material. The enclosing protocol parameter identified the second part's media type, while micalg named the message-integrity algorithm so a MIME implementation could calculate while streaming toward the next boundary.

RFC 2015 bound PGP to that frame. For text/plain, the sender first selected the character representation and converted line endings to canonical CRLF. It then applied a Content-Transfer-Encoding. Each encoded line ended in CRLF. MIME content headers were added, also with CRLF endings. Only then was the detached signature calculated over the headers and encoded data.

Including the content headers mattered. If a signature covered only the visible body, an intermediary could change Content-Type or Content-Transfer-Encoding and alter how the same bytes were interpreted without breaking the cryptographic check. The evidence object therefore included both data and the labels that told software what the data meant.

It did not include everything around it. RFC 1847 says the signature applies only to material inside the multipart/signed object, not enclosing message fields or externally referenced bodies. A successful check cannot silently authenticate an outer subject line, a delivery path or a resource that was merely linked.

Seven bits were an evidence rule

RFC 2015 told agents to treat security multiparts as opaque in transit. It immediately explained why that instruction was not enough. A gateway facing a next hop without MIME or 8-bit support might convert content to Quoted-Printable or Base64. That conversion could preserve the characters and make delivery possible, but it changed the first part after the signature had been made.

The sender therefore had to constrain signed material to seven bits. Eight-bit material was to be encoded before signing. RFC 1847 supplied the general reason: an SMTP client could otherwise either convert or return a non-delivery notification, and conversion of a signed object necessarily invalidated the signature. The safe choice was to make the transport-safe representation the signed representation.

RFC 2015's example is unusually concrete. A body line beginning with From was encoded because mail transfer or delivery software often escaped such a line by adding >, a convention inherited from mailbox formats. Trailing spaces were also candidates for encoding because a gateway such as BITNET might modify them. These transformations could leave prose apparently unchanged while changing the hash input.

Local line endings created another gap. Network MIME used CRLF, but a receiving mail agent might store text with a local convention. RFC 3156 later required the verifier to convert line endings back to CRLF. It also clarified the final-line edge: a canonical ending absent from the encoded data must not be invented inside the signature, while an implementation following the OpenPGP convention had to ensure that the signed and transmitted message were identical.

The ordering was the control. Canonicalize the content, apply transfer encoding, add MIME content headers, remove or protect vulnerable whitespace, then sign. Changing the order produced a different evidence object even when the displayed message looked the same.

Encryption-only traffic had more room

RFC 2015 made a deliberate exception for data that was only encrypted. It could contain eight-bit characters and did not have to be reduced to a seven-bit clear representation. RFC 3156 also allowed trailing whitespace without the stripping required for signed material.

This was not a claim that encrypted mail was generically safer. It reflected a different reconstruction problem. With multipart/encrypted, the transmitted second part was opaque OpenPGP data labelled application/octet-stream; the recipient decrypted that object. With a detached signature, the recipient independently held the readable first part and had to hash exactly what the sender hashed. A helpful rewrite of that clear part could therefore destroy verifiability.

Sign-then-encrypt did not escape the rule. RFC 2015 and RFC 3156 kept the seven-bit constraint for signed material even when the signed object was subsequently encrypted. The inner signature would eventually be checked against the recovered inner MIME entity.

The gateway could not promise every property

RFC 2480 turned the operational conflict into an explicit policy problem. A gateway to a non-MIME environment might need to convert MIME labels and flatten a composite object. Yet a security service had to cover the MIME object as a whole, and end-to-end protection could be lost if a gateway verified, decrypted or re-signed on behalf of an endpoint.

Its answer was not one magic conversion. A compliant gateway had to be able to tunnel a security multipart as one unchanged object when MIME capability might exist on the far side. It also had to be able to dismantle multipart/signed for an incapable recipient, knowing that this exposed the content and ruined the signature. In that mode it should retain the signature and add a warning rather than erase the evidence that a signature had travelled with the message. Per-user selection was recommended. Gateway verification or signing was optional and had to be disabled by default because it created a new trust and key-custody surface.

The gateway therefore owned a choice, not a universal truth: preserve end-to-end verifiability, or preserve usability in an environment that could not carry the object. Hiding the choice behind a success badge would lose the most useful record.

What a valid signature did—and did not—say

RFC 3156 updated RFC 2015 for OpenPGP and tightened canonicalization and whitespace rules. Both remain listed as Proposed Standards; the later document updates the earlier one. That chronology describes specifications, not present-day deployment or client support.

Within the specified boundary, successful verification is meaningful. It says that the verifier reproduced the signed MIME entity and that the signature checks under a particular public key. It may support an integrity or authentication decision when a separate trust process establishes what that key represents.

It does not create that surrounding evidence. The check alone does not establish the key holder's civil identity, who composed the text, whether the signer intended the recipient's interpretation, whether a server delivered it, whether a user saw the protected bytes rather than a transformed rendering, when the words were written, whether the signer had organizational authority, or whether a transaction occurred.

A failed check is similarly bounded. It may result from a malicious alteration, but it may also reflect a gateway conversion, whitespace handling, a local newline convention, a construction error, the wrong key or damaged storage. Failure proves that the verifier did not validate the expected cryptographic relation. It does not name the culprit or quantify the consequence.

RFC 2015's lasting contribution was to make that modest boundary operational. Email security began before the cryptographic calculation: it began by deciding which representation intermediaries were no longer allowed to improve.

Sources