> Those headers use comma both to separate challenges and to separate
> parameters within a challenge, which just seems mean-spirited.

Indeed. And while the resulting semantic meaning is unambiguous,
because both lists allow empty elements (well, you shouldn't emit them
but as you note, section 7 says you still need to be able to parse
them), it can be ambiguous for the parser whether an empty element
belongs to the inner list or the outer list. So you'll likely run in
to trouble if trying to use a parser-generator or generic algorithms,
even though the ambiguity is totally inconsequential.

In "Scheme1 realm=foo, , Scheme2 realm=foo", is the empty element an
empty param for the Scheme1 challenge, or an empty challenge between
the Scheme1 and Scheme2 challenges? Answer: It doesn't matter, but
good luck telling your tooling that.

> Other things about HTTP authentication that seem mean, dumb,
> annoying, or all of the above: both the RFC 2069 example response
> and the RFC 7616 SHA-512-256 example response are calculated
> incorrectly;

RFC 2069 (rev 1): Eh, the mistake is noted in the errata.

RFC 2617 (rev 2): Gets it right.

RFC 7616 (rev 3): Indeed. This has been reported as errata (way back
in 2016), but is not "verified". The report claims that the incorrect
values are obtained by naively truncating SHA-512 to 256 bits, rather
than making the other changes (using a different H⁽⁰⁾ value) for it
to be true SHA-512/256; but I haven't checked this to comment on it.

> RFC 7616's userhash field seems to require the server to do
> O(users_in_database) hashes to know what user to operate on;

I'd assume that you'd just store the H(concat(username, ":", realm))
as a column in the database, and select on that. I guess you're still
doing O(users_in_database) hashes, but you'd do a hash when you create
each user, not re-doing all of them for each request.

> RFC 7235's challenge grammar describes a token68 syntax that really
> only is used for the credentials in basic, never a challenge;

Yeah. That's weird.

> RFC 7616 drops backwards compatibility for RFC 2069 even though I
> bought a product this year that still uses RFC 2069-style
> calculations;

You don't mention that RFC 2617 set up a migration path, which RFC
7616 finally "turned off".

1997 (RFC 2069): Here's a formula.

1999 (RFC 2617): Here's a new more secure formula, servers "SHOULD"
set the "qop" parameter to opt-in to it, and clients "SHOULD" respond
in kind. But if qop is unset, then fall back to the old formula.

2015 (RFC 7616): The old formula is gone, you "MUST" set the qop
parameter to select the new formula.

That was a 16 year migration period where both were supported, during
which everyone "SHOULD" have switched to the new way.

> and it's based on old standards that followed "be conservative in
> what you do, be liberal in what you accept from others" so RFC 7230
> section 7 has separate grammars for what lists you must send and
> what lists you must accept, which further complicates parsing the
> nested lists.

You make it sound like they totally changed it; the new list syntax is
a subset of the old syntax, not something different.

Eh, there are already lots of places in the spec where it says "don't
send X... but if you receive X, you should accept+handle it anyway".
This is just one more.