💾 Archived View for rawtext.club › ~sloum › geminilist › 000987.gmi captured on 2020-09-24 at 02:11:57. Gemini links have been rewritten to link to archived content

View Raw

More Information

-=-=-=-=-=-=-

<-- back to the mailing list

Client certificate musings

solderpunk solderpunk at SDF.ORG

Sat May 23 15:56:38 BST 2020

- - - - - - - - - - - - - - - - - - - 

Howdy,

It's time to start thinking hard about client certificates.

A super quick introduction for the unaware: everyone is (hopefully!)familiar with the idea that when you make a TLS connection to a server,the server provides a certificate (basically a public key plus somemetadata, signed - directly or via a chain - by a trusted third party).This is supposed to convince you that you've connected to who you thinkyou have. What some may not know is that TLS allows clients to send acertificate to the server as well. This never (or almost never) happenson the web, where clients typically authenticate using a username andpassword inside a cookie-powered session.

I first learned about client certificates in the murky, distant pastwhen the "semantic web" was a hot topic, in the context of thedecentralised "Friend Of a Friend" social network idea. You can readabout FOAF+SSL at https://www.w3.org/wiki/Foaf+ssl.

Gemini specs a lot of use for client certificates - partially becausethey're a nice tool for the job, partially because the design goal ofmaximising power-to-weight ratio means once you accept the weight ofusing TLS you'd better implement everything you can using TLS ratherthan adding yet another pile of concepts.

The current rough spec fairly clearly outlines two usage scenarios forclient certificates.

One is where you want to restrict access to some Gemini resource to alimited set of clients, e.g. you want to be able to check a webcam atyour home via Gemini from your office while at work, or via your phone,but you don't want to open up access to the whole world. So, yougenerate a self-signed certificate on your office computer or yourphone, and manually add its fingerprint to a whitelist on your homeserver, and nobody else is allowed in. This is entirely analogous tothe way many of you are probably familiar with of logging into a serverover ssh using a private key. It works the same way and has the samepros/cons (e.g. can't be brute forced, is limited to devices with theright keys installed).

This is pretty explicitly supported in Gemini via status code 62 torequest such a certificate and 63 to reject one not on the whitelist.It is actually implemented at gemini://gemini.conman.org/, if you wantto play around with this.

I'm not sure there's much more to consider for this scenario. Becausein a whitelisting scenario the server and client are typically bothunder some degree of control by the same person, people can handleexpiry/renewal however they want and the spec should stay silent onthis.

The second scenario involves transient client certificates. These arebasically an alternative to cookie-powered sessions in HTTP(S). Aclient generates a self-signed certificate and uses it for somerequests so that the server can recognise consecutive requests as comingfrom the same location, and use the certificate fingerprint as a key ina database to maintain state between requests. This allows, e.g. usinga long series of status code 10 responses to basically "fill out aform", e.g. in signing a guest book there could be separate prompts fora name, email address or URL, plus guest book comment. You couldactually build fairly extensive command-line applications using thisparadigm (they'd suck in a graphical browser that kept popping up inputwindows, but in something like AV-98 the experience would be a lotsmoother).

Anyway, the appeal of using client certificates for sessions is that:

Compared to cookies they are more secure and put the client in control.

Gemini allows for transient sessions using the 61 and 21 status codes.61 requests the start of a session, which clients can always refuse todo. 21 allows servers to signal the termination of a session andclients should immediately and permanently delete the correspondingkeypair upon receiving it.

Until very recently, I don't think any of this was implemented anywhere.AV-98 now recognises these codes and reacts appropriately. I tested itwith a purpose-built dummy server which does nothing but send thesecodes. I am hoping we can soon start to explore this mechanism more,but there are some things to discuss:

There is a third scenario, which the spec does not explicitly discuss atall, but which is actually the most widely used scenario in Geminispaceso far, which is the main reason that I want to kick off a discussionabout this and change the spec if required. It's the idea of persistentidentity (basically, a "user account") at a server which is not underthe client's control. The persistent part differentiates this scenariofrom the clearly defined transient certificates, and the lack ofcombined control differentiates it from the previously discussedssh-style whitelist scenario. This is exactly the scenario which holdswith the astrobotany.mozz.us application.

Astrobotany currently requires users to generate a CSR for theircertificate, which is submitted to mozz.us over HTTPS, which signswhatever it sees. This is cumbersome for the user, and doesn't actuallyachieve anything because the signing is done unconditionally. Everybodyinvolved agrees this should be done differently. The reason it turnedout like it has is because of the extreme lack of detail in the cert onanything to do with client certificates, but with this particularscenario in particular.

Right now, the spec describes status code 62 (originally intended forwhitelisting scenarios) with "This resource is protected and a clientcertificate which the server accepts as valid must be used - adisposable key/cert generated on the fly in response to this status isnot appropriate as the server will do something like compare thecertificate fingerprint against a white-list of allowed certificates".This *could* be relaxed a bit to make it clear that the client *can* trygenerating a cert in response to the status, but that the server may notaccept it. This would allow e.g. astrobotany to send a 62 to a newuser, for the user to generate a non-disposable self-signed cert andsend it back, and for astrobotany to immediatley accept the cert andconnect its fingerprint to a user ID in its database. This is basicallythe smallest possible change to the spec which permits a much morestreamlined version of the way astrobotany currently works. AV-98 isready right now to work with applications using this paradigm.

But, I don't know if it makes more sense to introduce new 6x codes toexplicitly separate this scenario from the whitelisted cert scenario.If we don't do this, clients may waste time prompting their users togenerate a cert to send to a server which is never going to accept it,which may confused users.

We could change 62 to specify that the META should be a plain-languagemessage to users, which could disambiguate the scenario. Somethingelse to consider here is that astrobotany uses the Common Name part ofthe certificate for the username. I like this idea a lot, butdifferent applications may want different or additional userinformation, and using META to convey this information could work well.

There is also the open question of how to handle renewal of this kind ofcertificate, which people might have need of for years and years.Applications which a user authenticates to this way could request theuser to provide an email address (which could be validated in the usualwebbish way of sending a gemini:// URL with a unique token in it).Then, once the initial sign-up cert is due to expire soon, the app couldemail the user a URL with a unique token in it which they should accessusing a new cert, whereupon the new cert's fingerprint should be tied tothe account. But I'm wary of blindly copying ideas from the web. Thisapproach doesn't allow a long term account without associating an emailaddress, and that sucks from a privacy perspective.

A similar workflow could happen inside the app if somebody "signs in"close to the expiry date of their cert, which would not require an emailaddress. But this doesn't work if you happen not to log in for severalmonths on either side of the expiry date.

Users could sign their new certificate with their old certificate toprove continuity, but to some extent this defeats the purpose ofexpiring certs in the first place, which is to limit the impact ofprivate key compromise.

Of course, for very low-stakes applications like Astrobotany - and,realistically, *all* Gemini applications are likely to be verylow-stakes for the foreseeable future - users could also just "sign up"with very long-lived certificates. The CA/Browser Forum disallows certsthat live longer than two years currently, and will apparently soon dropthe limit to one year, but there's no reason we need to listen to them,especially not in the context of client certificates.

There are probably plenty of relevant things I have not mentioned yet.Feel free to mention them!

For anybody thinking "Holy heck, this sounds complicated, why are weputting this in Gemini?" and/or "I sure don't want to write all the codeto do this in my client": Client certificates weren't dreamed up forGemini, they are a pre-existing part of TLS. Even if the Gemini specdidn't say a word about them, people could build applications using themfor authentication without violating the Gemini spec in anyway. Becausethey're very handy things, their eventual use in conjunction with Geminiis likely inevitable. Thus, my thinking is that we might as wellstandardise on how to use them with Gemini to provide for easierinteroperability and streamlined user experiences. Also, they aretotally unnecessary for public content like gemlogs, and a client whichdoes not implement them at all (which is currently the vast majority ofclients) is likely to remain extremely usable for the majority of peopleand the majority of purposes. In fact, to some extent the existence ofpopular clients which *don't* handle client certificates would provide auseful protective measure against people hiding content behind certs(which, I realise, also facilitate nasty things like "pay walls")without a good reason.

Cheers,Solderpunk