2025.01 Vol.2

// TLS #P2p

Transport Layer Security

The little lock icon in the browser doesn’t give me that much confidence. After years of working on browser tech, no matter what the browser promises my initial reaction is always i-don't-believe-you-ron-burgundy.gif. But there is almost certainly a long and storied history to that lock which is probably worth knowing.

In the beginning of the internet, or just nets with no “inter” part yet, everyone was just excited to get some mainframe computers talkin to each other. They weren’t concerned with making the communication ultra secure, why let perfect be the enemy of still super awesome. It wasn’t until the nineties when Netscape wanted to jump start commerce over the internet that some security started to stick.

First there was SSL (Secure Sockets Layer). Now, ideally the internet would just have done a massive protocol upgrade which included some security by default. However, in the early nineties the “world wide web” was just picking up steam and getting to that point took some herculean efforts. Trying to heard all the cats again for a massive underlying protocol change was probably impossible.

Netscape’s strategy was to add security on top the existing TCP/IP protocols in the app layer. As long as the computer on the other end of a socket also understood SSL, everything was cool. SSL essentially took a TCP (Transmission Control Protocol) socket setup by the operating system and then wrapped it with encryption.

The RFC system was developed by internet engineers, but somewhat infamously, SSL didn’t use it. Probably Netscape wanting to be first movers on the secret sauce. But also probably caused the protocol to be crappy. SSL 1.0 was never publicly released due to bugs. 2.0 had several security issues. 3.0, released in 1996, would be the mainstay until finally improved with TLS (Transport Layer Security).

The SSL protocol was attempting to satisfy a lot of the common goals of cryptography schemes providing secure communication over an insecure channel.

  1. Confidentiality // Prevent eavesdropping on sensitive data.
  2. Integrity // Ensure data hasn’t been tampered with during transmission.
  3. Authentication // Verify the identity of communicating parties, particularly the server.
  4. Non-repudiation // Prevent denial of sent messages.

SSL accomplished this with handshakes, ciphers, certificates, and signatures. Which sounds about right, but with so many moving pieces and lack of RFC review, not surprising there were holes. SSL did foresee the need for flexible cipher suites, negotiating a suite in the handshake is part of SSL 3.0.

Still, SSL made it obvious that a better protocol was needed. Luckily, the follow up went through some review. Here’s a timeline of the TLS RFCs for some context.

  1. TLS 1.0: RFC 2246 (January 1999)
  2. TLS 1.1: RFC 4346 (April 2006)
  3. TLS 1.2: RFC 5246 (August 2008)
  4. TLS 1.3: RFC 8446 (August 2018)

TLS had the same general goal as SSL, take a TCP socket and give it some security. The standardization process made it way more robust, if not radically different.

These days TLS is general purpose and can be used by any app which uses TCP/IP. This includes browsers (HTTPS), email clients, and any home rolled app. Many modern languages have built-in support for TLS. And there are operating system level toolkits available like OpenSSL. Even the linux kernel is gaining some native TLS functionality.

So should we just use TLS everywhere? While TLS is modular and configurable, it is still a beast of a protocol. The authentication part in particular. Authentication in TLS is usually accomplished with X.509 certificates. This is complex system involving a hierarchy of certificates. From personal experience, the only way I can wrangle in all the different ways to setup a certificate is to use Smallstep software. And it is still hard to get all devices to play nice since the ecosystem is very centralized. The certificates also take the lion’s share of processing power. Which begs the question, can you use TLS without the authentication?

That is kinda the idea behind bitcoin’s BIP324 custom scheme. The use case doesn’t require authentication, so it removed entirely from the protocol. It also locks in a single cryptography suite, so no handshake negotiations. The lock-ins make it more efficient than an authentication-less TLS equivalent which would still have to deal with all its modularity.

TLS is perhaps slowly tacking towards making authentication less heavy handed. RFC 7250 introduced “raw” public key authentication, which is way more light weight. This is just normal public key stuff without all the certificate structure and fanciness. Raw public keys are supported in TLS 1.3. It hasn’t exactly gained a ton of ground in the past decade, but open source libraries are starting to add support. So while TLS is a robust protocol, it is large burden to support.

ipsec

Could things be better if we add security at a lower part of the stack? That is what IPSec is attempting, but spoiler, it has its own set of tradeoffs.

IPSec adds security at the IP layer. It actually got started around the same time as SSL development in the early nineties, but since it requires those heavy low-level protocol migrations, it unsurprisingly took some more time. It initially had the lofty goal that the next generation of IP protocol (IPv6) would have a required form of “always on” network level security. Instead, IPSec of today is an optional protocol for both IPv4 and IPv6. What went wrong?

IPSec is implemented, at a high level, in the same way as TLS. There are handshakes and negotiations to set up encryption ciphers. What stands out right away to me is that means IP all of sudden needs to manage state. Base IP is made up of datagrams (packets) which contain all their required state to be routed (headers). The sending and receiving processes are not required to hold any state on a packet. Applications like firewalls are simple filters since they can just analyze a packet to make a call. So a state requirement is a big change.

Another challenge is that in practice it is difficult to apply blanket encryption suites across all use cases. Where some use cases are low bandwidth, high value, and would love the highest form of security, others are the exact opposite. And since the IP work is done be the kernel, it is a little more involved for a user to configure. It is more like a system firewall than a per-app knob.

One more thing to note, is that while IP encryption is great for all data, network metadata and side-channel leaks still occur. It is not a silver bullet.

So between the state requirement and the tough flexibility, IPSec is generally used in a hub-and-spoke model like a VPN instead of a mesh model where every connection from a machine is encrypted at the network level.

bip324 and nostr

I mentioned before how BIP324 is a similar scheme meant for private communication over an un-trusted channel. It is hyper-tuned for the bitcoin node use case, but it does mention in the BIP that it could be upgraded with authentication if the need arises. I am not convinced there is a need yet, but, it sure would be cool to add some basic public key authentication. If nostr relays then added some sort of public key identifier…we could drop the heavy weight TLS requirement and just have a lean, bitcoin native, communication scheme.