💾 Archived View for geminiprotocol.net › history › phlog › inputs-and-client-certs.gmi captured on 2024-05-12 at 15:19:30. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2023-09-08)

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

Inputs and client certs

(originally posted in Gopherspace on 2019-07-25)

With the link syntax finally established, the next biggest priority in my mind is to stabilise the status codes, because this is currently the only other significant place where the existing implementations vary and I think it's important to unify the current tiny Geminiverse ASAP. I've already written something about status codes, and I have much more developed thoughts on that to share soon. But to put that discussion into full context, I wanted to quickly present a few other ideas. Both of these will be fleshed out more fully later.

Previous post "Status codes" (2019-06-27)

The first is the idea of queries, or user inputs, or whatever we want to call them. Essentially, an equivalent of gopher's item type 7. When you use a gopher client to follow a link with item type 7, the client will prompt you for up to 256 characters of input. It will then connect to the relevant server, and instead of sending just the path followed by a CRLF as per a standard Gopher request, it will send the path, then a tab, then your input followed by a CRLF. This is how serarch engines like Veronica accept search terms, and the same functionality is also sometimes used for things like guestbooks. It's nice functionality to have and I want something similar in Gemini.

There are basically two questions here. The short and boring and probably pretty easy one is how do we add user input to the request format? Right now I see no problem with simply copying Gopher's tab separation approach, but let me know if you think this has severe shortcomings. More substantially, is given that we do not have item types, how should a Geminimap convey that a particular link is to a resource which accepts an input?

The best idea I've come up with so far on this front is to dedicate a status code to this issue. The status code would indicate that the server is requesting user input, and the line of text that comes after the code would be a prompt to present the user. The client should present the prompt, get the user's response, then make a new request to the same resource with the response included. This does mean that "doing a Gemini search" becomes a two-request action, which is a shame, but since the user has to read the prompt and type their input in between the two queries, the time wasted on setting up / tearing down the connections should still be a small proportion of the total time involved (and I'm hoping that one day TLS session resumption is well-supported enough that connections become cheaper than they are today). The bonus of this approach is that the server gets to specify a custom prompt for each resource which accepts input, which is not possible in gopher. This might seem like a small thing, but I'll come back to it later and reveal its true power. But first...

The other idea is authentication using client TLS certificates. This idea is actually already implemented in the Conman server, and interest has already been expressed in possibly adding it to Germinal. I endorse this idea very strongly and I plan for it to be the only implementation of authentication in Gemini, i.e. there will be no password-based authentication comparable to HTTP's. Why?

Firstly, because we're aiming for maximum power-to-weight ratio. The weight of TLS is already in the protocol, so we should try to extract maximum power from it. Anything which can be achieved using TLS should be achieved using it, rather than adding more weight with extra parts of the protocol.

Secondly, because using client certificates is slightly more complicated than using passwords, which means people won't deploy authentication lightly. This might seem like an odd consideration. It's motivated by the thought-provoking article "Avoiding the gravity hole of webbiness in gopher"[2] by enkiv2, written in response to my early ponderings which eventually spawned the Gemini project. You should definitely read this article if you're interested in this whole discussion - the final four paragraphs are the most important, IMHO. enkiv2 opines that one of the immediate negative consequence of the introduction of HTTPS was the proliferation of "registration gating" on the web. This honestly isn't something I'd thought about before but I definitely understand the sentiment. A Geminispace where the majority of content is totally publicly accessible, like gopherspace, sounds like a good thing. Making private Geminispace possible but not straightforward discourages forcing people to authenticate themselves for no good reason, while still catering to people who want to do things like serve content only for their own use.

Finally, because client certs can also be used to function as a superior version of cookies! By remembering the fingerprint of a client certificate, a server can recognise that a given connection is coming from the same client as a previous one. That might sound like a very bad thing, just like cookies are a very bad thing, but client certs differ from cookies in very important ways. They aren't given to the client by the server like cookies are, but the client has to generate them itself before even connecting to the server - they are fundamentally opt-in. Even better, once a client deletes a key/cert pair, it is gone for good - the server remembers only the fingerprint, which is insufficient to recreate the pair. Client certs allow clients to voluntarily and very visibly (generating a new key/cert pair takes some time and will briefly spike your CPU usage) enter into a temporary session of state-persistence with a given server, which the client is guaranteed to be able to permanently end whenever it wants to, whether the server likes it or not. This functionality is somewhat similar to the Session-ID header idea that gcupc proposed in their excellent response to enkiv2's article[3], which talks about a possible "lynx web" - yet more required reading.

Now, back to the "true power" of the input prompt status code: within one of these "client-certificate sessions", a server can respond to successive requests from the same client for a resource which wants a user input with different prompts each time. This can be used to do things like simulate a HTML form with multiple text fields, by asking for the fields one at a time. Or it can be used to play very simple text-based adventure games! It's basically a minimalist remote REPL interface and should allow some interesting server-side applications to be built on Gemini. I'm fairly excited about this - not because I have lots of such applications that I really want to make, but rather because it's a very nice emergent property of the protocol. This sort of application was not in my mind whatsoever when I started designing Gemini, it just turned out to be possible using a combination of two features which were included for entirely unrelated reasons. Stuff like that is neat!

My next post will give my latest thoughts on the status code system, and my current ideas are largely based around making these two features work. That's why I wanted to provide some context by describing them first. Feedback on these two ideas, even before the status code post comes up, are of course welcome.

[1] gopher://zaibatsu.circumlunar.space:70/0/~solderpunk/gemini/status-codes.txt

[2] gopher://fuckup.solutions:70/1/enkiv2/avoiding-the-gravity-hole-of-webbiness-in-gopher

[3] https://jfm.carcosa.net/blog/computing/gopher-and-the-lynx-web/