Client certificate musings
Sean Conner
sean at conman.org
Sun May 24 02:57:14 BST 2020
It was thus said that the Great Thomas Karpiniec once stated:
> Hi!
>
> On Sat, May 23, 2020 at 02:56:38PM +0000, solderpunk wrote:
> > Gemini specs a lot of use for client certificates - partially because
> > they're a nice tool for the job, partially because the design goal of
> > maximising power-to-weight ratio means once you accept the weight of
> > using TLS you'd better implement everything you can using TLS rather
> > than adding yet another pile of concepts.
>
> This was the thing that stood out most on my first read-through of the
> spec! I particularly like the insistence "Transient certificates MUST
> NOT be generated automatically". I wasn't here for the earlier
> discussion but I assume this is to fend off servers making sessions
> purely for tracking purposes by default.
There wasn't much of a discussion.
Okay, a bit of history of this mess, which can be laid at the feet of me
and solderpunk.
In early June of last year, solderpunk starting the design of Gemini and
sometime between the 16th and 21st, he had the initial protocol designed.
On the 21st (19:18:37 -0400 to be exact) I started GLV-1.12556. I already
had a framework for servers written, and a TLS wrapper for Lua, and I wanted
to play around with TLS.
Now, the library I picked for this was LibreSSL, a hard fork of OpenSSL
because of issues. The reason I picked LibreSSL was mainly for its
inclusion of a higher-level library libtls, which makes it easy for an
application writer to use TLS correctly in an application. And if your
client accepts the whole CA mechanism (for both servers and clients) then
yes, it is *very* easy to use [1]. This is further reflected by some of the
functions they defined:
tls_config_insecure_noverifycert()
tls_config_insecure_noverifyname()
tls_config_insecure_noverifytime()
They definitely want to make sure you know that not verifying a
certificate is bad. They also make it easy to use client certificates:
tls_config_verify_client()
tls_config_verify_client_optional()
So with all this, by midnight on the 22nd, I had a minimal Gemini server
written, with client certificate support by the 24th. Since client
certificates weren't a part of the original specification, I thought I would
just go ahead and implement it to show it could be done [2]. To that end, I
set up two end points that were (and still are) protected:
gemini://gemini.conman.org/private/
gemini://gemini.conman.org/conman-labs-private/
I set client certifications optional (else every request would require
them and this would be checked by libtls), and for "/private/" all I require
is that a certificate is sent (I don't even bother looking at it). For
"/conman-labs-private/" I require a certificate I signed to be used (much
like Astrobotany). My intent was to protect certain areas of a Gemini
server with an access control mechanism, and using certificates was (in my
mind) a no brainer.
It was on July 9th that solderpunk decided he liked the idea of a client
certificate for authentication and on August 15th, settled on the idea for
good, and seems to have come to see temporary client certificates as for
some form of "cookie" the client controls by the 19th, because of the
"/private/" area on my server not requiring any particular client
certificate (just *a* client certificate).
And from then, there wasn't much work on it until just recently. I was
surprised and amused that Astrobotany exists, using client certificates as I
envisioned them being used.
> > Right now, AV-98 fills the "Subject" of transient certs with
> > random unique values from Python's `uuid` module, because I seemed
> > to encounter errors sending totally empty certificates to
> > conman.org.
>
> I've seen similar problems before with custom usage of X.509. It would
> be nice to use something smaller than UUID if possible just to keep
> cert size down - provided there is library support as you noted.
I'm not aware of what fields are mandatory either, but certainly using the
string "anon" or "unknown" or "noydb" [3]. Or you know, Noah Body or Abby
Normal.
> I'm not a big fan of using certificate fields for anything meaningful
> - it's a side channel (surrounded by lots of other fields that people
> might be tempted to use) - and it slightly increases the complexity of
> integration between the TLS library and the client/server code.
>
> When a server wants the client to use a non-disposable certificate
> there is an ambiguity. Is it just because they want the user to
> preserve their authentication for more than 24 hours for convenience?
One scenario I envisioned was a Gemini server serving up sensitive
material to known, authenticated users. How that authentication happens is
beyond the scope of the Gemini protocol, but perhaps a companion way (or a
"best practices" way) could be discussed.
> Or is it because the user will permanently lose access to their
> account if they ever lose that key?
Of if they get logged out and forget the password? That can happen now,
so I don't think it's of much concern.
> With this in mind, my current opinion is that there should be no way
> for a server to request a non-disposable certificate.
I disagree. I might want to serve up documents to a select few, and I can
control that by given them a client certificate to use.
-spc
[1] https://github.com/spc476/libtls-examples
[2] I've also played around with client certificates for the web. I
wish they were used more often as they obliviate the need for
"logging" in (has certificate? User is logged in) and "logging out"
(client just stops browsing). It gets difficult when you use
multiple devices, and the UI around generating and using them is ...
let's say it's "technical" and leave it at that.
[3] None of your darned business.
More information about the Gemini
mailing list