On Wed, Jun 27, 2018 at 1:45 AM, Noam Postavsky <npostavs@gmail.com> wrote:
Eli Zaretskii <eliz@gnu.org> writes:

>> From: Lars Ingebrigtsen <larsi@gnus.org>
>> Date: Tue, 26 Jun 2018 11:27:34 +0200
>> Cc: 31946@debbugs.gnu.org, Jimmy Yuen Ho Wong <wyuenho@gmail.com>
>>
>> We could get in touch with the gnutls maintainer and ask for his input
>> and perhaps ask for API endpoints to allow us to check for these things?
>
> Yes, I think that's the right way for moving forward.

By the way, I've researched this a bit more, it seems like there is no
practical way to detect small subgroups at all, the only solution is to
move to standardized domains (the smallest of which is 2048 bits)
similar to how ECDHE uses standard curves.  This also solves the
composite prime problem, which is likely too expensive to check as well.

https://tools.ietf.org/html/rfc7919:

   Additionally, the DH parameters selected by the server may have a
   known structure that renders them secure against a small subgroup
   attack, but a client receiving an arbitrary p and g has no efficient
   way to verify that the structure of a new group is reasonable for
   use.

According to Dorey et all [1], the RFC you've linked is one of the 4 strategies she
proposed, and the the most feasible in 2016 but still computationally expensive.

Another strategy involves disabling DHE, which she didn't really like as that will be
TLS 1.3's only fallback, but Safari[2], Chrome[3] have since removed them, and Firefox
[4] is on the verge, so I think this option is also viable for Emacs. Just need to pick out the
appripriate DHE ciphers and add a - for everyone of them in the constructed priority string
in `gnutls-boot`.

As to why these browsers are still "failing" the dh-small-subgroup and dh-composite tests,
the negotiated ciphersuite on both Chrome and Firefox is
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, so the effects of small subgroup
attack is basically mitigated (if I understand the papers correctly).

`(setq gnutls-log-level 999)` in Emacs currently doesn't tell me what KX algo was used
, it just tells me AES-256-GCM was negotiated as a cipher. However,

`$ gnutls-cli -V --x509cafile /opt/local/etc/openssl/cert.pem -p 443 dh-small-subgroup.badssl.com`

gives me

- Status: The certificate is trusted.
- Description: (TLS1.2)-(DHE-RSA-2048)-(AES-128-GCM)
- Session ID: ...
- Ephemeral Diffie-Hellman parameters
 - Using prime: 2048 bits
 - Secret key: 507 bits
 - Peer's public key: 2048 bits
 - PKCS#3 format:

-----BEGIN DH PARAMETERS-----
...
-----END DH PARAMETERS-----

- Version: TLS1.2
- Key Exchange: DHE-RSA
- Server Signature: RSA-SHA512
- Cipher: AES-128-GCM
- MAC: AEAD
- Compression: NULL
- Options: safe renegotiation,
- Channel binding 'tls-unique': ...
- Handshake was completed

This is just plain... weird. It's TLS_DHE_RSA_AES_128_GCM_SHA512 with 2048
bit prime, and it's nowhere to be found in browsers' ciphersuites.
Although, TLS_DHE_RSA_AES_128_GCM_SHA256 does still exist on browsers,
and does offer perfect forward secrecy according to SSLLabs[5], but it's fairly low in
their preferences.

So.... this look o...kay if you cut out the signature algorithm? Someone should
doublecheck this.

Alternatively, we can wait for widespread adaption of TLS 1.3 (Cloudflare predicts
50% of TLS connection will be 1.3 by the end of this year[6]), time fixes everything...

Tidbit: The GnuTLS basically ignored a group of Adobe researchers when they
reported to them GnuTLS was susceptible to the small group attack[7]...

[1]: https://eprint.iacr.org/2016/999.pdf
[2]: https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/AAdv838-koo
[3]: https://www.chromestatus.com/feature/5128908798164992
[4]: https://bugzilla.mozilla.org/show_bug.cgi?id=1227519
[5]: https://www.ssllabs.com/ssltest/viewMyClient.html
[6]: https://blog.cloudflare.com/our-predictions-for-2018/
[7]: https://eprint.iacr.org/2016/995.pdf