Gemini requiring TLS is good, actually

StackSmith recently published "A Call for a Gemini Without TLS," which argues that TLS overcomplicates the Gemini protocol and should be avoided, particularly since the TOFU trust model doesn't add much security. I agree that the practical security benefits of TOFU are limited, but I still think requiring TLS upfront was a good call.

Prior reading:

StackSmith: A Call for a Gemini Without TLS
solderpunk: Why gopher needs crypto

First, while TLS support is not built into the operating system like TCP/IP and DNS are, TLS libraries are readily available and mostly transparent. Adding TLS support to Perez required maybe twenty lines of code (which I borrowed from AV-98 anyway) and didn't add any dependencies (OpenSSL is in Python's standard library). All I had to do was pass a ssl.SSLContext to asyncio.open_connection, and from there implementing the protocol was the exact same as if I had a plaintext socket. Similarly, while you can't telnet directly to a Gemini server, you can openssl s_client to a Gemini server, which is essentially the same.

perez/gemini.py on GitHub

Second, TLS even with an insufficient trust model like TOFU does protect against lazy attackers (for example, coffeeshop Wi-Fi scanning your traffic) and network misconfigurations. A lot of attackers are in fact lazy, as I was reminded by a recent security incident at my workplace. This is especially the case while the profile of Gemini remains low.

Third, requiring TLS at the early stages of the protocol avoids needing to retrofit every client and server with TLS support in the future (as happened with HTTP). Just because Gemini content has relatively low security sensitivity now doesn't mean it will stay that way forever. We can and should iterate on the trust models, but the fact that clients and servers already support TLS certificates makes it easier to start using certificates with more robust trust models in the future.

(James Tomasino suggests using DANE as a trust model)

Fourth, TLS client certificates are a fantastic solution for user authentication. They are easily generated, disposable, not forgeable by the servers you use them on, exactly as cross-site as you want them to be, and capable of being integrated with more robust trust models or being simple opaque session identifiers. Stack offhandedly mentions that "client authentication can likewise be an option using public key cryptography," but implementing that on a standalone basis adds _way_ more risk and complexity to clients and servers than simply using TLS.

With all that being said, having a cleartext version of Gemini is totally reasonable! Some capsules really don't need TLS and there are contexts where not implementing TLS makes experimentation easier. But it needs its own URL scheme and port to avoid collisions with TLS-secured Gemini. I suggest geminict:// (for Gemini cleartext) and 5691 (1965 backwards, which is not assigned by IANA).

leafstorm's gemlog (back to home)