When the Spec Is the Only Source of Truth

This post began as a LinkedIn reflection on RFC reading and first-principles thinking. The story went deeper into RFC 2865 RADIUS authentication than a LinkedIn post could hold.


RFC 2865 RADIUS Authentication

The authentication failures were intermittent. Not every packet. Not every user. Just enough to know something was wrong at the byte level.

I was building the wireless firewall gateway from scratch — OpenBSD, ipfilter (Darren Reed’s packet filter, standard on OpenBSD at the time), Apache, PHP. For the authentication backend I found a RADIUS client someone had posted online. Native PHP RADIUS support didn’t exist yet — the first PECL radius extension landed in late 2002, and even then it was an optional add-on, not part of the language. Finding someone’s radius.php and adapting it was the standard approach. The code worked well enough in initial testing. Then the RADIUS server logs started showing malformed packets. Not consistently. Not predictably. Just often enough to be a problem.

I was working inside the OpenBSD ecosystem, which had a culture worth understanding: the project’s documentation was so thorough, and their mailing lists so unforgiving of questions already answered in the man pages, that the community ran a documentation site at rt.fm — a URL that said everything about their philosophy. Ask something already covered in the manual, and you’d get a terse reply pointing you there. RTFM wasn’t a meme in that community. It was policy.

They weren’t wrong.

I already had some background coding sockets in C and C++. Wire formats were familiar territory — you think in terms of bytes, offsets, lengths. What wasn’t familiar was PHP’s byte-level encoding methodology. So I was running two learning curves simultaneously: how do you do in PHP what I already know how to do in C, and where does this implementation diverge from what the protocol actually specifies?

The RFC 2865 RADIUS Password Algorithm

I pulled up RFC 2865, section 5.2. That section describes the User-Password attribute obfuscation algorithm — the mechanism for obscuring a password before it goes on the wire. The RFC lays it out in the usual ASCII art packet diagram, byte positions labeled, algorithm described in plain language. I put the RFC on one side of the screen and the PHP source on the other and started comparing them.

The fix was obvious once I knew what correct looked like. The padding logic wasn’t right. The algorithm requires the password to be padded to a multiple of 16 bytes with null bytes before the XOR chain runs. The implementation didn’t handle that correctly — which is why the failures were intermittent. Passwords that landed cleanly on a 16-byte boundary worked. Others didn’t. The RADIUS server rejected the malformed attribute outright.

My first reaction was honest: how did this get missed? It wasn’t a subtle error. But the author was working in a second language, in a pre-Stack Overflow era, probably without the C background that made the wire-format model intuitive. The RFC wasn’t an obvious tool if you hadn’t already been thinking in terms of bytes and offsets.

That’s the thing about specs. They aren’t a last resort. They’re the primary source — the authoritative description of what correct looks like. Everything else — vendor docs, blog posts, someone’s radius.php — is an interpretation. When the interpretation is wrong and the failure mode is intermittent and nothing else explains it, there’s only one place left to go.

The OpenBSD community already knew this. rt.fm was their way of saying: we wrote it down. Go read it.

The wizards stayed up late because there was no manual. Sometimes there still isn’t. But when the manual exists — and for every protocol that runs on the internet, an RFC exists — that’s the place to start, not the place of last resort.


The BGP prefix leak that took down campus CDN access and the MTU mismatch that held an OSPF adjacency in EXSTART for two weeks are in the same family: production failures that only resolved when I stopped trusting the interpretation and went back to the source. Those stories are here: BGP Prefix Leak, RPKI, and the Cold Email That Confirmed It and 1500 != 1500: MTU, OSPF EXSTART, and a 14-Byte Blind Spot.


What’s the most useful thing an RFC has ever told you that a vendor doc couldn’t?