Regarding `gemini://` over NaCL (replacing TLS)

Ciprian Dorin Craciun ciprian.craciun at gmail.com
Tue Mar 3 12:20:57 GMT 2020


OK, I've been doing some "light reading" about this topic, and this is
what I've found out so far.

(Although I think the change of adopting anything besides TLS is
closer to 0 at this moment, which I would say is a shame...)




#### About "pro-TLS", and "don't roll your own"

[I.e.  This part is a counter argument to my previous emails.  I still
think we can do "simpler", but I do like to be fair, and thus I'm
debating myself...]  :)


Bellow I'll point out three articles, written by three different
people (which after searching the internet seem to be knowledgeable in
this domain, perhaps not Schneier / Bernstein level, but still much
better than the average developer), in a time span of about 10 years.
(The section we are interested in is `client-server application
security`, and not `website security` because the later actually means
"HTTPS security", thus TLS is mandatory, although the former
completely ignores certificates, as in X.509, thus only SSH-like
assumptions.)

* [2018]  https://latacora.micro.blog/2018/04/03/cryptographic-right-answers.html
* [2015]  https://gist.github.com/tqbf/be58d2d39690c3b366ad
* [2009]  http://www.daemonology.net/blog/2009-06-11-cryptographic-right-answers.html


>From [2009] (although I would say it's an incomplete advice as it
doesn't say what to do next):
~~~~
One of the reasons OpenSSL has such a poor track record is that the
SSL protocol itself is highly complex. Certificate chains, revocation
lists, ASN.1, multiple different hashing and encryption schemes...
when you have over a hundred thousand lines of code, it's no wonder
that bugs creep in.
~~~~


>From [2015] (Colin is the author of the [2009] article):
~~~~
What happens when you design your own custom RSA protocol is that 1-18
months afterward, hopefully sooner but often later, you discover that
you made a mistake and your protocol had virtually no security. That
happened to Colin, but a better example is Salt Stack. Salt managed to
deploy e=1 RSA.

[...]

Most of these attacks can be mitigated by hardcoding TLS 1.2+, ECDHE
and AES-GCM. That sounds tricky, and it is, but it's less tricky than
designing your own transport protocol with ECDHE and AES-GCM!

In a custom transport scenario, you don't need to depend on CAs: you
can self-sign a certificate and ship it with your code, just like
Colin suggests you do with RSA keys.

Avoid: designing your own encrypted transport, which is a genuinely
hard engineering problem; using TLS but in a default configuration,
like, with "curl"; using "curl", IPSEC.
~~~~


>From [2018]:
~~~~
In custom protocols, you don’t have to (and shouldn’t) depend on 3rd
party CAs. You don’t even have to use CAs at all (though it’s not hard
to set up your own); you can just use a whitelist of self-signed
certificates — which is approximately what SSH does by default, and
what you’d come up with on your own.

Since you’re doing a custom protocol, you can use the best possible
TLS cipher suites: TLS 1.2+, Curve25519, and ChaPoly. That eliminates
most attacks on TLS. The reason everyone doesn’t do this is that they
need backwards-compatibility, but in custom protocols you don’t need
that.

[...]

Avoid: designing your own encrypted transport, which is a genuinely
hard engineering problem; using TLS but in a default configuration,
like, with “curl”; using “curl”, IPSEC.
~~~~


The takeaway:  if we go with TLS, let's mandate:
* TLS 1.2 with TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
  https://ciphersuite.info/cs/TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
* or, TLS 1.3 with TLS_CHACHA20_POLY1305_SHA256
  https://ciphersuite.info/cs/TLS_CHACHA20_POLY1305_SHA256
* as for certificates only ECDSA, which seem to be available also via
Lets Encrypt;

These options are also suggested by both Mozilla and CloudFlare:
* https://wiki.mozilla.org/Security/Server_Side_TLS
* https://developers.cloudflare.com/ssl/ssl-tls/cipher-suites




#### About the noise protocol

I've glossed over the Noise protocol specification, however before
getting into that I've read the first link bellow:

* https://latacora.micro.blog/factoring-the-noise/
* https://noiseprotocol.org/noise.html  (this is the actual specification);

Basically I think the only Noise protocol instance that pertains to
`gemini://` is the `XX` exchange pattern, citing from the first link
above:
~~~~
XX and XK require an extra round trip before they send over the
initiator’s static key. Flip side: they have the strongest possible
privacy protection for the initiator, whose identity is only sent to
the responder after they’ve been authenticated and forward secrecy has
been established.
~~~~

In fact Alexey Ermishkin together with Trevor Perrin (the original
author of the protocol) have started a project called NoiseSocket,
which basically just focuses on the the `XX` pattern.  (As for
credentials, Trevor Perrin worked for WhatsApp in designing the Noise
protocol, which is still used today.)

* https://github.com/noisesocket/spec
* https://noisesocket.org/post/1/ -- I strongly suggest reading this
document if one is interested in the Noise protocol;

The only disadvantage with Noise (or NoiseSocket) is that given the
frame size is limited to 64K, in case of `gemini://` we need to
implement extra "chunking" for it to work for bodies.  (Alternatively
we can just use it as we do TLS, namely a "stupid pipe that just
applies encryption"...)




####  The part about other alternatives

I've found the following project that also does a "state-of-the-art"
analysis (though granted in 2015):

* https://github.com/auditdrivencrypto/secure-channel
* https://github.com/auditdrivencrypto/secure-channel/blob/master/prior-art.md
* https://github.com/auditdrivencrypto/secure-channel/blob/master/properties.md
* https://github.com/auditdrivencrypto/secure-channel/blob/master/draft.md
* https://github.com/auditdrivencrypto/secure-channel/blob/master/draft2.md

(I don't know his credentials, thus I would assume nothing.)

The "state-of-the-art" is quite "high-level", but it provides a nice
starting point.  The properties document is a good check-list to
analyze any proposal against.  (The only issue, is that he is
interested in building a peer-to-peer network, thus at least the
public key of the server is known in advance.)

The second draft (i.e. `draft2.md` above) is quite interesting,
although as said it does one require to know beforehand the server's
public key.




####  About my previous proposal

I'll have to think harder about it (within my limited cryptographic
expertise), and perhaps submit it to a cryptographers community for
feedback.

At the moment I can see only a minor privacy flaw in it:  the client
discloses its identity (and proof of identity) to any server;  instead
it should first wait for the server to disclose its identity (and
proof of identity) before proceeding.

This issue stems from the fact that the `transport_prepare` function
is "symmetrical" and tries to reduce network round-trips;  instead the
client could first wait for the server verifier and then send its own
(i.e. just a minor change to that function).

Ciprian.


More information about the Gemini mailing list