Subject: Re: [openpgp] "OpenPGP Simple"

From: Peter Gutmann <[email-masked]>
Date: Wed, 18 Mar 2015 03:55:41 +0000

David Shaw <[email-masked]> writes:

>What if the encoding was really simple - something like 4 bytes always, and
>the leftmost bit would mean "partial".  So any packet 2^31 or less could be
>encoded in one piece, but we could still do partial for those situations that
>needed it.  We could have any number of partial lengths, but it would always
>end with a non-partial final length.

That's kind of ugly because now you're stuffing metadata into the length
field.  A better approach is the one used in BER indefinite-length encodings,
you have a flag at the start saying "lengths are indefinite", then a series of
partial lengths followed by an end-of-contents value, tag 0 and length 0.  In
other words it's something like:

  |len|  data  |len|  data  |len|  data  |0|

So once you hit a partial length of zero you know you're done.

Peter.

---

From: Werner Koch <[email-masked]>
Date: Wed, 18 Mar 2015 10:01:58 +0100

> So once you hit a partial length of zero you know you're done.

That would indeed make the code easier and is what my pre-OpenPGP
implementation did.  However we need to support the current huffman like
length encoding anyway and thus any easier method benefits only the
sender's implementation.

I am in favor of simplifying the packet header.  The question is how to
encode such a new method.  The obvious choice is to use bit 7 of the CTB
which is currently always set.  Using new packet numbers would also be
possible but that would extend the already weird encoding.

Salam-Shalom,

   Werner

ps.

Here is a description of the pre-OpenPGP partial length format:

  In the old packet header format CTB bits 1 and 0 encode "packet-length
  length" which these values: the following table:

      0 - 1-byte packet-length field
      1 - 2-byte packet-length field
      2 - 4-byte packet-length field
      3 - no packet length supplied, unknown packet length

  As indicated in this table, depending on the packet-length length
  bits, the remaining 1, 2, 4, or 0 bytes of the packet structure field
  are a "packet-length field".  The packet-length field is a whole
  number field.  The value of the packet-length field is defined to be
  the value of the whole number field.

  A value of 3 is currently used in one place: on compressed data.  That
  is, a compressed data block currently looks like <A3 01 . .  .>, where
  <A3>, binary 10 1000 11, is an indefinite-length packet. The proper
  interpretation is "until the end of the enclosing structure", although
  it should never appear outermost (where the enclosing structure is a
  file).

  [Old GPG extension:]

  A value of 3 for other packets enables a special length encoding,
  which is used in case, where the length of the following packet can
  not be determined prior to writing the packet; especially this will be
  used if large amounts of data are processed in filter mode.

  It works like this: After the CTB (with a length field of 3) a marker
  field is used, which gives the length of the following datablock.
  This is a simple 2 byte field (MSB first) containing the amount of
  data following this field, not including this length field. After this
  datablock another length field follows, which gives the size of the
  next datablock.  A value of 0 indicates the end of the packet. The
  maximum size of a data block is limited to 65534, thereby reserving a
  value of 0xffff for future extensions. These length markers must be
  inserted into the data stream just before writing the data out.

  This 2 byte field is large enough, because the application must buffer
  this amount of data to prepend the length marker before writing it out.
  Data block sizes larger than about 32k doesn't make any sense. Note
  that this may also be used for compressed data streams, but we must use
  another packet version to tell the application that it can not assume,
  that this is the last packet.

-- 
Die Gedanken sind frei.  Ausnahmen regelt ein Bundesgesetz.