Subject: Re: [openpgp] Bug#931238: hot armor: please drop "Version: " header

From: Clint Adams <[email-masked]>
Date: Sat, 6 Jul 2019 13:39:41 +0000

On Fri, Jun 28, 2019 at 05:38:36PM -0400, Daniel Kahn Gillmor wrote:
> "hot armor" currently adds a comment line to its enarmored content:
> 
> Version: hot 0.21.3
> 
> Best practices these days omits indicators of what particular OpenPGP
> implementation is in use.   Please do not emit it by default!

Should rfc4880bis deprecate this?

---

From: Heiko Stamer <[email-masked]>
Date: Sat, 6 Jul 2019 15:55:06 +0200

> Should rfc4880bis deprecate this?

There are many other indicators of a particular OpenPGP implementation
(e.g. DKGPG uses four-octet packet lengths). If a somehow uniform
encoding is desired, then IMO a new section "Privacy Considerations"
should be added to rfc4880bis.

--
Heiko

---

From: Marcus Brinkmann <[email-masked]>
Date: Sun, 7 Jul 2019 01:56:19 +0200

That seems almost like a bottomless pit.  Some thoughts (not meant to be
exhaustive):

For messages:

1. The embedded timestamp and filename in a literal data packet.
2. The block sizes for partial data packets, and when they are used.
3. The signature subpackets used and their order (hashed and unhashed).
4. Possibly the details of the compression.
5. The length of the base64 encoding.
6. Potentially the order of signature packets.
7. The value of any quick check bytes (some implementations set them to
invalid values to discourage checking them).

For keys:

1. Again the signature subpackets used and their order.
2. Potentially the details of the user id.
3. Algorithm and other preferences and flags.
4. The cryptographic parameters of public keys (RSA exponent etc)
5. S2K count.
6. Possibly resolution of any timestamps.

On 7/6/19 3:55 PM, Heiko Stamer wrote:
> _______________________________________________
> openpgp mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/openpgp
> 

-- 
Dipl.-Math. Marcus Brinkmann

Lehrstuhl für Netz- und Datensicherheit
Ruhr Universität Bochum
Universitätsstr. 150, Geb. ID 2/461
D-44780 Bochum

Telefon: +49 (0) 234 / 32-25030
http://www.nds.rub.de/chair/people/mbrinkmann

---

From: Daniel Kahn Gillmor <[email-masked]>
Date: Sun, 07 Jul 2019 16:23:19 -0400

On Sun 2019-07-07 01:56:19 +0200, Marcus Brinkmann wrote:
> That seems almost like a bottomless pit.

Totally agreed, fingerprinting surfaces are a drag. Nonetheless, the
people best equipped to enumerate them are the folks with
domain-specific knowledge, like you've done here.

Thanks for starting up a list.  You're basically identifying places
where implementers have a non-obvious choice to make when generating
OpenPGP constructs.  Perhaps the right form for this guidance would be
text that says what reasonable implementations should do.  I'll propose

> 1. The embedded timestamp and filename in a literal data packet.

I'm not sure how these would vary across implementations.  perhaps the
guidance should say "in the absence of a requirement to the contrary,
the timestamp should be set to zero and the filename should be zero
octets in length."

> 2. The block sizes for partial data packets, and when they are used.

Partial data packets SHOULD NOT be generated.  In the event that they
are generated, partial data packets SHOULD have a length represented by
the value 236 (meaning, the packet has a length of 1<<(236&0x1F) == 4096
octets).

> 3. The signature subpackets used and their order (hashed and

Which hashed subpackets to use: i'm not sure about this.  suggestions?

order:

Implementations SHOULD emit signature subpackets in subpacket type
order.  If multiple subpackets of a given type are present, they SHOULD
be ordered based on the binary representation of the
subpacket. (0x01ffff comes before 0x020000, etc).

Implementations SHOULD NOT emit unhashed subpackets without a concrete
reason to do so.

> 4. Possibly the details of the compression.

Implementations SHOULD NOT generate compressed packets.  If they do,
they should prefer Bzip2 over Zlib over ZIP.  (is this right?  what
about per-format compression details?

> 5. The length of the base64 encoding.

I think this means line length.

Implementations SHOULD generate Radix-64 data encoded such that all full
lines have 64 printable characters in them.

> 6. Potentially the order of signature packets.

I'm assuming this is about signature packets over a data, not user ID
certifications or subkey signatures.

If multiple signature packets are attached to a piece of data, they
SHOULD be ordered by their creation date (oldest signature first).  If
multiple signatures share the same creation date, they SHOULD be ordered
by their binary representation.

> invalid values to discourage checking them).

That's news to me, thanks for raising it.  Can you point to
documentation about that?

> 1. Again the signature subpackets used and their order.

Same as above, i think.

> 2. Potentially the details of the user id.

as most of this is entirely user-visible (and user-selected), i'm not
sure how much implementations can do here.  Perhaps we should recommend
using Unicode canonicalization form C for the UTF-8 string though?

> 3. Algorithm and other preferences and flags.

These compatibility markers will invitably leak some information about
the local implementation, as they are needed for interoperability.  We
can provide guidance on the ordering of those preference though.

> 4. The cryptographic parameters of public keys (RSA exponent etc)

The chosen RSA exponent SHOULD be 0x10001.

(suggestions for other parameters for other pubkey algorithms welcome!)

> 5. S2K count.

Modern hardware is fast.  Implementations that emit an S2K packet SHOULD
use Iterated + Salted S2K, and the S2K count SHOULD be 65011712
(single-octet representation 255).

> 6. Possibly resolution of any timestamps.

Isn't the specification's 1-second resolution reasonable?  Do we want to
encourage something different?

One other item for OpenPGP certificates ("keys")"

7. order of certification packets, order of user ids, etc:

I proposed a canonicalized structure for OpenPGP certificates over here:

  https://dev.gnupg.org/T3389

Perhaps this should be a supplementary implementator guidance draft,
distinct from the specifying RFC?  Then we could also update it as new
fingerprinting surface is discovered, without revising the RFC itself.
Anyone interested in starting a draft?

         --dkg

---

From: Daniel Kahn Gillmor <[email-masked]>
Date: Sun, 07 Jul 2019 08:22:44 -0400

> should be added to rfc4880bis.

totally agreed that this should be added, and i encourage you to send
text to the [email-masked] mailing list.

This should not block the removal of the Version: header from the output
of "hot armor", though.

   --dkg

---

From: Peter Gutmann <[email-masked]>
Date: Mon, 8 Jul 2019 01:42:05 +0000

>That seems almost like a bottomless pit.  Some thoughts (not meant to be

Thanks, saved me typing all that.  If it's going to be done as an RFC, it
needs to come with a warning that at best any countermeasures are going to
stop simple-minded fingerprinting, but not anything very advanced.

Also if it's going to be done as an RFC then it should state what threat all
this will be defending against.  "An attacker knowing that you're running out-
of-date software" barely qualifies as a threat - they can just try and attack
you anyway - and I can't see what other purpose it serves.

Peter.

---

From: ilf <[email-masked]>
Date: Mon, 8 Jul 2019 12:48:52 +0200

Peter Gutmann:
> "An attacker knowing that you're running out- of-date software" barely 
> qualifies as a threat - they can just try and attack you anyway - and 
> I can't see what other purpose it serves. 

We had this debate three years ago over on gnupg-devel.

dkg posted a patch - which was merged in upstream GnuPG:

> The version of GnuPG in use is not particularly helpful.  It is not
> cryptographically verifiable, and it doesn't distinguish between
> significant version differences like 2.0.x and 2.1.x.
> Additionally, it leaks metadata that can be used to distinguish users
> from one another, and can potentially be used to target specific
> attacks if there are known behaviors that differ between major
> versions.
> It's probably better to take the more parsimonious approach to
> metadata production by default.

https://lists.gnupg.org/pipermail/gnupg-devel/2016-August/031424.html

These were the original arguments:

> Since "Pervasive Monitoring Is an Attack" [2], let's minimize metadata 
> as much as possible, especially if it's unencrypted *and* not 
> cryptographically verifiable.
> The riseup.net "OpenPGP Best Practices" [3] refer to a gpg.conf [4] 
> which already implements "no-emit-version". I and many other people have 
> been using this with many implementations on many plattforms for a long 
> time, without any problems. So I see no technical reason against the 
> proposal.
> Even RFC 4880 lists no pressing reason for including this by default:
>> The Armor Headers are pairs of strings that can give the user or the 
>> receiving OpenPGP implementation some information about how to decode 
>> or use the message. [5]
> I can't see how "Version: GnuPG v2" tells me or an OpenPGP 
> implementation "how to decode or use the message".
> Let's just drop it.
> 2. https://tools.ietf.org/html/rfc7258
> 3. https://riseup.net/en/security/message-security/openpgp/best-practices
> 4. https://raw.githubusercontent.com/ioerror/duraconf/master/configs/gnupg/gpg.conf
> 5. https://tools.ietf.org/html/rfc4880#page-55

https://lists.gnupg.org/pipermail/gnupg-devel/2016-August/031428.html

After it was merged, a pratical attack was published:

> Werner Koch:
>> You are right, the "Version:" has no technical meaning.
>> I just pushed dkg's patch to master.
> Thanks again for this. Even after the decision, I want to add a 
> real-world example of why this change helps against de-anonymization:
>> Both "French Maid" and Force (operating as "Nob") used the exact same 
>> brand of PGP software, a free brand called GnuPG. There are different 
>> brands of PGP software so it is noteworthy that both Force (operating 
>> as "Nob") and "French Main" used the same brand. Not only did Force 
>> and "French Maid" both use the same brand of PGP software, they also 
>> both used the same outdated version of that software, 1.4.12. Version 
>> 1.4.12 was released on January 2012, and was replaced with a new 
>> version by December 2012, and was one of several versions of GnuPG 
>> software. As such, both "French Maid" and Force (as Nob) were using 
>> the specific, older version of the GnuPG software, and neither of them 
>> replaced it with the other (free) version of GnuPG that came out 
>> thereafter. […]
>> There are also additional similarities between Force's (Nob's) and 
>> "French Maid's" PGP patterns. Both "Nob" and "French Maid" left 
>> certain default settings on their PGP software. For one thing, both 
>> "French Maid" and Force (Nob) left a "tag" that appeared on every 
>> message authored from their PGP key revealing the brand and version of 
>> PGP software they were using. This is akin to, for example, leaving 
>> the phrase "sent from my iPhone" on the bottom of one's emails but 
>> with greater detail: it would be akin to leaving a phrase like "sent 
>> from my iPhone 6 iOS 8.0.1." Leaving this "tag" on typically reveals 
>> that one is dealing with a fairly inexperienced user of PGP, because 
>> someone that regularly uses PGP to communicate would normally have 
>> changed their settings to omit this tag.
> http://www.justice.gov/sites/default/files/opa/press-releases/attachments/2015/03/30/criminal_complaint_forcev2.pdf
> http://www.networkworld.com/article/2904395/microsoft-subnet/mistakes-that-betrayed-anonymity-of-former-dea-agent-and-silk-road-investigator.html

After that, the OpenPGP "Version:" header was dropped across the 
ecosystem:

GnuPG: https://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg.git;a=commit;h=c9387e41db7520d176edd3d6613b85875bdeb32c
GPGTools: https://github.com/GPGTools/MacGPG2/commit/831c2ed77d2ce88134ad4d689414051dc99dc3b3
SKS: https://bitbucket.org/skskeyserver/sks-keyserver/commits/4af75b3526d9

To sum up:

- there is no valid technical reason for it
- there are active attacks which have put people in jail
- it's now ecosystem standard not to generate it

So please:

1. let's drop it by default in other implementations, like hOpenPGP
2. let's edit rfc4880bis to "SHOULD NOT emit a Version: header"

-- 
ilf

If you upload your address book to "the cloud", I don't want to be in it.

---

From: Marcus Brinkmann <[email-masked]>
Date: Wed, 10 Jul 2019 09:41:57 +0200

Hi,

> the timestamp should be set to zero and the filename should be zero

Well, the encoding can be different, filenames can be typical for an
operating system, etc. I'd just zero it all out.

> the value 236 (meaning, the packet has a length of 1<<(236&0x1F) == 4096

Actually, it would be more stable to always use partial data packets
with a fixed chunk size (plus rest).

> Which hashed subpackets to use: i'm not sure about this.  suggestions?

That's a large topic, unfortunately.  Probably requires some research, too.

> subpacket. (0x01ffff comes before 0x020000, etc).

Subpacket length must be canonicalized, too, like packet lengths.  But
there is some trouble here: There are private or experimental subpacket
types, and a generic implementation won't know if the order matters.

> about per-format compression details?

For example, block size. In general, I think there is a lot of
flexibility in choosing the huffman tree and such.  Dunno if that
actually happens in the real world.

> I think this means line length.

Yes, sorry.

> documentation about that?

Unfortunately, I can't find it. It might just have been an idea I read
about somewhere, without implementation, or an obscure niche
implementation. It was an interesting idea, though, so it stuck in my head.

> using Unicode canonicalization form C for the UTF-8 string though?

I agree that user-visibility makes this different from the other items
on this list.

> (suggestions for other parameters for other pubkey algorithms welcome!)

Prime generation and random number generation:

The Million-Key Question—Investigating the Origins of RSA Public Keys
(Petr Švenda, Matúš Nemec, Peter Sekan, Rudolf Kvašňovský, David
Formánek, David Komárek, and Vashek Matyáš, Masaryk University),
25th USENIX Security Symposium

https://www.usenix.org/system/files/conference/usenixsecurity16/sec16_paper_svenda.pdf

> encourage something different?

For example, when creating a new key with multiple subkeys, an
implementation could have the same or different timestamps for them.

> Anyone interested in starting a draft?

Thanks,
Marcus

---

From: ilf <[email-masked]>
Date: Wed, 10 Jul 2019 21:51:44 +0200

> 2. let's edit rfc4880bis to "SHOULD NOT emit a Version: header"

After this mail:

1. LibTMCG dropped it by default: 
http://git.savannah.nongnu.org/cgit/libtmcg.git/commit/?id=2c8a6861ab839cb58b6483a04a7b584423a27811

2. Heiko Stamer submitted a pull request to rfc4880bis: 
https://gitlab.com/openpgp-wg/rfc4880bis/merge_requests/17

I added a comment to slighty improve the wording:

> To minimize metadata, implementations SHOULD NOT emit this key and its 
> corresponding value except for debugging purposes with explicit user 
> consent.

-- 
ilf

---

From: Heiko Stamer <[email-masked]>
Date: Sat, 13 Jul 2019 10:38:14 +0200

> text to the [email-masked] mailing list.

Regarding the fixed encoding of a (sub)packet length I suggest the
following approach (AFAIK it's used by most OpenPGP implementations):

	if (len < 192)
	{
		// one-octet length format
	}
	else if (len < 8384)
	{
		// two-octet length format
	}
	else
	{
		// four-octet length format with 0xFF prefix
	}

Recently, I the length encoding in LibTMCG/DKGPG for subpackets, where
it was previously a four-octet length format with 0xFF prefix.
-- 
Heiko

---

From: Daniel Kahn Gillmor <[email-masked]>
Date: Mon, 22 Jul 2019 09:15:33 -0400

> 		// four-octet length format with 0xFF prefix

This looks reasonable to me, and i agree that it should be part of any
proposed draft aimed at minimizing divergence in generated output across
OpenPGP implementations.

    --dkg