Skip to main content

OpenPGP Message Grammar
draft-gallagher-openpgp-messages-01

Document Type Active Internet-Draft (individual)
Author Andrew Gallagher
Last updated 2026-10-08
RFC stream (None)
Intended RFC status (None)
Formats
Additional resources GitLab Repository
Mailing List Archive
Stream Stream state (No stream defined)
Consensus boilerplate Unknown
RFC Editor Note (None)
IESG IESG state I-D Exists
Telechat date (None)
Responsible AD (None)
Send notices to (None)
draft-gallagher-openpgp-messages-01
openpgp                                                A. Gallagher, Ed.
Internet-Draft                                                PGPKeys.EU
Updates: 9580 (if approved)                               8 October 2026
Intended status: Standards Track                                        
Expires: 11 April 2027

                        OpenPGP Message Grammar
                  draft-gallagher-openpgp-messages-01

Abstract

   This document specifies several updates and clarifications to the
   grammar and semantics of OpenPGP messages.

About This Document

   This note is to be removed before publishing as an RFC.

   The latest revision of this draft can be found at
   https://andrewgdotcom.gitlab.io/openpgp-messages.  Status information
   for this document may be found at https://datatracker.ietf.org/doc/
   draft-gallagher-openpgp-messages/.

   Discussion of this document takes place on the OpenPGP Working Group
   mailing list (mailto:openpgp@ietf.org), which is archived at
   https://mailarchive.ietf.org/arch/browse/openpgp/.  Subscribe at
   https://www.ietf.org/mailman/listinfo/openpgp/.

   Source for this draft and an issue tracker can be found at
   https://gitlab.com/andrewgdotcom/openpgp-messages.

Status of This Memo

   This Internet-Draft is submitted in full conformance with the
   provisions of BCP 78 and BCP 79.

   Internet-Drafts are working documents of the Internet Engineering
   Task Force (IETF).  Note that other groups may also distribute
   working documents as Internet-Drafts.  The list of current Internet-
   Drafts is at https://datatracker.ietf.org/drafts/current/.

   Internet-Drafts are draft documents valid for a maximum of six months
   and may be updated, replaced, or obsoleted by other documents at any
   time.  It is inappropriate to use Internet-Drafts as reference
   material or to cite them other than as "work in progress."

   This Internet-Draft will expire on 11 April 2027.

Gallagher                 Expires 11 April 2027                 [Page 1]
Internet-Draft           OpenPGP Message Grammar            October 2026

Copyright Notice

   Copyright (c) 2026 IETF Trust and the persons identified as the
   document authors.  All rights reserved.

   This document is subject to BCP 78 and the IETF Trust's Legal
   Provisions Relating to IETF Documents (https://trustee.ietf.org/
   license-info) in effect on the date of publication of this document.
   Please review these documents carefully, as they describe your rights
   and restrictions with respect to this document.  Code Components
   extracted from this document must include Revised BSD License text as
   described in Section 4.e of the Trust Legal Provisions and are
   provided without warranty as described in the Revised BSD License.

Table of Contents

   1.  Introduction  . . . . . . . . . . . . . . . . . . . . . . . .   2
   2.  Conventions and Definitions . . . . . . . . . . . . . . . . .   3
   3.  Signed Messages . . . . . . . . . . . . . . . . . . . . . . .   3
     3.1.  Prefix-Signed Message Constraints . . . . . . . . . . . .   4
     3.2.  OPS Message Constraints . . . . . . . . . . . . . . . . .   4
     3.3.  Subject Normalization . . . . . . . . . . . . . . . . . .   5
       3.3.1.  Line Ending Normalization . . . . . . . . . . . . . .   6
     3.4.  Signatures over Signed Messages . . . . . . . . . . . . .   6
   4.  Formal Grammar  . . . . . . . . . . . . . . . . . . . . . . .   6
   5.  Encrypted and Compressed Messages . . . . . . . . . . . . . .   7
   6.  Marker Packet . . . . . . . . . . . . . . . . . . . . . . . .   8
   7.  Security Considerations . . . . . . . . . . . . . . . . . . .   8
   8.  IANA Considerations . . . . . . . . . . . . . . . . . . . . .   8
     8.1.  OpenPGP Packet Types Registry . . . . . . . . . . . . . .   9
   9.  References  . . . . . . . . . . . . . . . . . . . . . . . . .   9
     9.1.  Normative References  . . . . . . . . . . . . . . . . . .   9
     9.2.  Informative References  . . . . . . . . . . . . . . . . .   9
   Appendix A.  Acknowledgments  . . . . . . . . . . . . . . . . . .  10
   Appendix B.  Document History . . . . . . . . . . . . . . . . . .  10
     B.1.  Changes Between draft-gallagher-openpgp-messages-00 and
           draft-gallagher-openpgp-messages-01 . . . . . . . . . . .  10
   Author's Address  . . . . . . . . . . . . . . . . . . . . . . . .  10

1.  Introduction

   OpenPGP messages have a complex grammar and sometimes poorly-
   understood semantics.  This document attempts to address this by:

   *  Expanding on specifications where [RFC9580] does not fully
      describe the existing or expected behaviour of deployed
      implementations.

Gallagher                 Expires 11 April 2027                 [Page 2]
Internet-Draft           OpenPGP Message Grammar            October 2026

   *  Adding clarification where deployed implementations differ in
      their interpretation of [RFC9580] and its predecessors.

   *  Deprecating unused or error-prone features.

   This document does not specify any new wire formats.

2.  Conventions and Definitions

   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
   "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
   "OPTIONAL" in this document are to be interpreted as described in
   BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all
   capitals, as shown here.

3.  Signed Messages

   There are two forms of signed message in OpenPGP.  In a prefix-signed
   message, the Signature packet or packets precede the signed data.  In
   a one-pass signed message, one or more One-Pass Signature packets
   precede the signed data, and the corresponding Signature packet(s)
   follow it.

   The accepted convention is that a prefixed Signature packet signs
   over the next literal packet only, skipping any intervening
   signatures - however this is not explicitly specified in [RFC9580].
   Historically, PGP 2.X treated a prefixed Signature packet as applying
   to the entire following sequence of packets, but this usage is
   deprecated [FINNEY1998].  See Section 3.4 for an alternative
   construction.

   In addition, One-Pass Signature (OPS) nesting semantics are complex,
   and under-specified [SCHAUB2022].  Section 5.4 of [RFC9580] defines
   the nesting octet as:

      A 1-octet number holding a flag showing whether the signature is
      nested.  A zero value indicates that the next packet is another
      One-Pass Signature packet that describes another signature to be
      applied to the same message data.

   The terminology is imprecise, and non-zero "nesting" flags are
   completely unspecified.  One self-consistent interpretation is as
   follows:

   *  A zero nesting octet means that the following OPS and its
      counterpart signature are not signed over by the current OPS.

Gallagher                 Expires 11 April 2027                 [Page 3]
Internet-Draft           OpenPGP Message Grammar            October 2026

      -  This process is recursive if multiple sequential OPS packets
         have a nesting octet of zero.

   *  To add multiple OPS signatures over the same message data, all OPS
      constructions except the innermost one have the nesting octet
      zeroed.

      -  It is not clear what happens if the innermost nesting octet is
         zero but no OPS packet follows.

   The above implies that an OPS with a nonzero nesting octet signs over
   all packets between the OPS packet and its matching signature packet,
   including any further signatures, however it is not clear whether any
   current implementation supports this.

   This is further expanded in [OPENPGPDEVBOOK].

   This still leaves us with an overly complex grammar that resists
   rigorous formalization.  We attempt to improve the formalism below.

3.1.  Prefix-Signed Message Constraints

   Prefixed signatures are deprecated, and their use is hereby
   restricted:

   *  A prefixed Signature packet MUST be followed by one Literal Data
      packet and no other packets except further prefixed Signature
      packets, and Marker packets.

   *  A prefixed Signature packet MUST NOT have a version number greater
      than 4.

   Prefixed signatures SHOULD NOT be generated, but MAY be interpreted.
   A receiving implementation MAY convert a prefixed signature to the
   equivalent OPS signature, by moving the signature after the Literal
   Data packet and prefixing an appropriate OPS packet.

3.2.  OPS Message Constraints

   We constrain OPS structures to a subset of previously-allowed
   configurations:

   *  Prefixed signatures and OPS signatures MUST NOT both be used in
      the same message.

   *  When generating an OPS packet that is followed by another OPS
      packet, the nesting octet SHOULD be set to 0.

Gallagher                 Expires 11 April 2027                 [Page 4]
Internet-Draft           OpenPGP Message Grammar            October 2026

      -  Otherwise, the nesting octet SHOULD be set to 1.

   *  When consuming an OPS packet, the nesting octet MUST be ignored.

   This effectively deprecates the nesting octet, while maintaining
   backwards compatibility with legacy code.

3.3.  Subject Normalization

   The _subject_ of an OpenPGP signature refers to the packet(s) that
   are signed over.  The _type-specific data_ of an OpenPGP signature
   refers to the section of the data stream that is passed to the
   signature's digest function after the optional salt and before the
   trailer.  The type-specific data differs from the subject in that it
   has been normalized, the details of which are dependent on the
   signature type.

   The subject of a signature in the Literal Data or Timestamping
   categories ([I-D.gallagher-openpgp-signatures]) is the Literal Data
   packet that immediately follows one or more prefixed signatures, or
   is enclosed by one or more OPS constructions.  If no Literal Data
   packet is present, the signature is malformed.

   The following normalization steps are applied to the subject of the
   signature to produce the type-specific data:

   *  The framing of the Literal Data packet is discarded, and any
      partial-length packets are concatenated.

   *  The format, filename and timestamp fields are discarded.

   *  If the Signature Type is 0x01, the Literal Data packet body is
      converted to Canonical Text, by converting line endings to CRLF
      and removing any trailing whitespace (Section 3.3.1).

   *  If the Cleartext Signature Framework is being used, dash-escaping
      is also applied (see Section 7.2 of [RFC9580]).

   A One-Pass Signature over a Literal Data packet, a prefixed Signature
   over the same packet, and a detached signature over a file containing
   the body of the same packet are all calculated the same way.  This
   means that they can be losslessly transformed into each other with
   the exception of the Literal Data metadata fields, which an
   application MAY assume contain their recommended default values as
   per Section 5.9 of [RFC9580].

   A signature of Type 0x01 MUST NOT be made over arbitrary binary data,
   only over UTF-8 text.

Gallagher                 Expires 11 April 2027                 [Page 5]
Internet-Draft           OpenPGP Message Grammar            October 2026

3.3.1.  Line Ending Normalization

   When normalizing line endings, only bare linefeeds (an LF control
   character that is not preceded by a CR) are normalized to CRLF.  In
   particular, bare carriage returns MUST NOT be converted to CRLF.

   Instead, carriage returns SHOULD be treated as horizontal whitespace,
   similarly to tab characters.  This means that a carriage return at
   the end of a signed message, if not followed by a linefeed, SHOULD be
   stripped.

3.4.  Signatures over Signed Messages

   It has been previously suggested (for example in [FINNEY1998]) that a
   non-zero nesting octet in a non-innermost OPS packet might be used to
   sign over an already-signed message, including some or all of its
   signatures.  This construction has never been formally specified, and
   such a message SHOULD NOT be created.  A receiving implementation
   that follows the guidance in [ops-message-constraints] will
   automatically invalidate some or all of its signatures.

   To sign over an entire signed message together with its signatures,
   the wire format of the inner message SHOULD first be encapsulated in
   a Literal Data packet.  A Canonical Text signature MUST NOT be made
   over such a nested message, and the Cleartext Signature Framework
   MUST NOT be used.

   Beware that the outer signature(s) will thus be sensitive to the
   inner message's packet framing, i.e. the otherwise inconsequential
   choice of packet header format and partial body lengths.  If the
   inner message is parsed and re-serialized unmodified, but using a
   different framing, the outer signature(s) will no longer validate.

4.  Formal Grammar

   The message grammar in Section 10.3 of [RFC9580] is therefore updated
   to:

   *  Encrypted Session Key:
      Public Key Encrypted Session Key Packet | Symmetric Key Encrypted
      Session Key Packet.

   *  Encrypted Data:
      Symmetrically Encrypted Data Packet | Symmetrically Encrypted and
      Integrity Protected Data Packet.

   *  Encrypted Message:
      (Encrypted Session Key)*, Encrypted Data.

Gallagher                 Expires 11 April 2027                 [Page 6]
Internet-Draft           OpenPGP Message Grammar            October 2026

   *  Prefixed Signed Message:
      (Signature Packet)+, Literal Data Packet.

   *  One-Pass Signed Message:
      (OPS Packet (nest=0)){n>=0}, OPS Packet (nest=1), Literal Data
      Packet, (Signature Packet){n+1}.

   *  Signed Message:
      Prefixed Signed Message | One-Pass Signed Message.

   *  Optionally Signed Message:
      Signed Message | Literal Data Packet.

   *  Unencrypted Message:
      Compressed Data Packet | Optionally Signed Message.

   *  Optionally Padded Unencrypted Message:
      Unencrypted Message, (Padding Packet)*.

   *  OpenPGP Message:
      Encrypted Message | Unencrypted Message.

   In addition to these rules, a Marker packet (Section 5.8 of
   [RFC9580]) can appear anywhere in the sequence.

   In a One-Pass Signed Message, the OPS packets and Signature packets
   SHOULD appear in bracketed pairs, as per Section 5.4 of [RFC9580].
   If a Signature packet does not match its corresponding OPS packet,
   then that particular signature is invalid but the entire packet
   sequence SHOULD NOT be rejected.

5.  Encrypted and Compressed Messages

   [RFC9580] permits an encrypted message to contain another encrypted
   message, and a compressed message to contain another compressed
   message, possibly recursively.  Such messages require potentially
   unbounded resources for negligible added utility, and therefore MUST
   NOT be created.

   In addition, encrypt-then-sign messages are not idiomatic OpenPGP,
   and MUST NOT be generated.

   The guidance in Section 10.3.1 of [RFC9580] is therefore updated to:

   *  Decrypting a version 2 Symmetrically Encrypted and Integrity
      Protected Data packet MUST yield a valid Optionally Padded
      Unencrypted Message.

Gallagher                 Expires 11 April 2027                 [Page 7]
Internet-Draft           OpenPGP Message Grammar            October 2026

   *  Decrypting a version 1 Symmetrically Encrypted and Integrity
      Protected Data packet or -- for historic data -- a Symmetrically
      Encrypted Data packet MUST yield a valid Unencrypted Message.

   *  Decompressing a Compressed Data packet MUST yield a valid
      Optionally Signed Message.

6.  Marker Packet

   Section 5.8 of [RFC9580] defines the Marker Packet as follows:

      The body of the Marker packet consists of:

      -  The three octets 0x50, 0x47, 0x50 (which spell "PGP" in UTF-8).

      Such a packet MUST be ignored when received.

   We update this to also include:

   *  If a receiving implementation encounters a Marker Packet with any
      other contents, it is "a critical packet where the packet type is
      unknown", and the entire sequence MUST be rejected.  See
      Section 4.3 of [RFC9580].

   *  A Marker Packet MAY be added by an application to notify non-
      OpenPGP software that a data stream contains OpenPGP data.  If so,
      the Marker Packet SHOULD be the first packet in the sequence, and
      SHOULD NOT use a Legacy header, so that it can be easily detected.

7.  Security Considerations

   The OPS nesting octet is not signed over and is malleable in
   principle.  An intermediary could swap an outer OPS with its inner
   OPS by also swapping the nesting octets.  The order of OPS nesting
   therefore MUST NOT be considered meaningful.

   In addition, the normalization applied during Literal Data signature
   calculation may result in semantic collisions.  It is possible to
   construct distinct sequences of packets that map to the same sequence
   of octets after Literal Data normalization is applied.  It is not
   known whether such a pair of colliding packet sequences might also
   have different semantics.

8.  IANA Considerations

Gallagher                 Expires 11 April 2027                 [Page 8]
Internet-Draft           OpenPGP Message Grammar            October 2026

8.1.  OpenPGP Packet Types Registry

   IANA is requested to update the following existing entries in the
   registry, to add a reference to this document:

   *  Marker Packet

   *  OPS Packet

9.  References

9.1.  Normative References

   [I-D.gallagher-openpgp-signatures]
              Gallagher, A., "OpenPGP Signatures", Work in Progress,
              Internet-Draft, draft-gallagher-openpgp-signatures-03, 4
              June 2026, <https://datatracker.ietf.org/doc/html/draft-
              gallagher-openpgp-signatures-03>.

   [RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
              Requirement Levels", BCP 14, RFC 2119,
              DOI 10.17487/RFC2119, March 1997,
              <https://www.rfc-editor.org/rfc/rfc2119>.

   [RFC8174]  Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
              2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
              May 2017, <https://www.rfc-editor.org/rfc/rfc8174>.

   [RFC9580]  Wouters, P., Ed., Huigens, D., Winter, J., and Y. Niibe,
              "OpenPGP", RFC 9580, DOI 10.17487/RFC9580, July 2024,
              <https://www.rfc-editor.org/rfc/rfc9580>.

9.2.  Informative References

   [FINNEY1998]
              Finney, H., "Re: More spec-ulations - update", 26 March
              1998, <https://mailarchive.ietf.org/arch/msg/openpgp/
              U4Qg3Z9bj-RDgpwW5nmRNetOZKY/>.

   [OPENPGPDEVBOOK]
              "OpenPGP for Application Developers", 6 May 2024,
              <https://openpgp.dev/book/>.

   [SCHAUB2022]
              Schaub, P., "[openpgp] Proposing a Simplification of
              Message Syntax", 7 October 2022,
              <https://mailarchive.ietf.org/arch/msg/openpgp/
              uepOF6XpSegMO4c59tt9e5H1i4g/>.

Gallagher                 Expires 11 April 2027                 [Page 9]
Internet-Draft           OpenPGP Message Grammar            October 2026

Appendix A.  Acknowledgments

   This document would not have been possible without the extensive work
   of the authors of [OPENPGPDEVBOOK].

   The author would also like to thank Daniel Huigens, Daniel Kahn
   Gillmor, Heiko Schäfer, Neal Walfield, Justus Winter and Paul Schaub
   for additional discussions and suggestions.

Appendix B.  Document History

   Note to RFC Editor: this section should be removed before
   publication.

B.1.  Changes Between draft-gallagher-openpgp-messages-00 and draft-
      gallagher-openpgp-messages-01

   *  Added missing dash-escape step in type-specific data.

   *  Clarified treatment of trailing carriage return characters.

   *  Reworked formal grammar to be more human-readable.

Author's Address

   Andrew Gallagher (editor)
   PGPKeys.EU
   Email: andrewg@andrewg.com

Gallagher                 Expires 11 April 2027                [Page 10]