-- Leo's gemini proxy

-- Connecting to gemini.ucant.org:1965...

-- Connected

-- Sending request

-- Meta line: 20 text/gemini

TOFU for carnivores


One of the many subjects of anti-Gemini agitation on the former Gemini mailing list was the subject of TLS, and TOFU. TLS is the encryption layer mandated by the Gemini protocol, and TOFU ("trust on first use") is a policy recommended for how Gemini clients should perform TLS.


At the bottom of this article I set out a URL scheme that mitigates the problems of TLS, including TOFU. I've made a toy implementation of this in Python.


What are TOFU and TCA?


TOFU is the conventional policy for a different encryption layer, called "SSH".


TOFU consists in requiring that successive connections to a server be permitted only if the server can safisfy a client that it possesses a secret of which it demonstrated possession on the very first time a connection was attempted. By analogy, this is like finding that Mrs Holmes lives at such and such an address, going to that address and asking for Mrs Holmes, accepting that the lady who answers the door is Mrs Holmes, and then visiting occasionally in the future and noticing that it's obviously the same individual answering the door, until one day someone *else* answers the door and says that Mrs Holmes has moved house. Now, you don't actually know if the person who has been answering the door as Mrs Holmes really *was* Mrs Holmes, but that may or may not have been relevant for your purposes. Maybe it was actually Mrs Holmes' daughter, but if you were just going there to ask for her to donate cash to your charity, that might not have mattered. On the other hand there are obviously circumstances in which it could matter a great deal.


Now you might have a different scheme, such as requiring the lady at the doorstep to tell you a password, or to show you an identity document that you could cross-check against some trusted source. But none of these schemes is likely to help with the situation where the person at the door is secretly acting under duress. Nonetheless, cross-checking an identity document against some trusted source is a useful alternative policy, and it is much closer to how TLS operates when used with a web browser. The downside is that if Mrs Holmes cannot for some reason present a document certificated by a source you trust, then whatever business you were planning to conduct might no longer take place, therefore the certification authorities gain a chokehold on such business. Certainly some certification authorities were a licence to print money and made some individuals extraordinarily rich.


Trust on first use

Certificate authority


It is argued by some that Gemini should use the "Trust the Certificate Authority" (TCA) scheme rather than "Trust On First Use" (TOFU). There are too many different considerations in the trade-off between those policies to enumerate here.


My point is more about partly mitigating TOFU. Following TOFU instead of TCA only makes a difference to outcomes in a subset of the potential circumstances, as in many cases, both TOFU and TCA will have the same effect, though this may mean equal effectiveness, or equal *in*effectiveness. In particular, TOFU and TCA relate to Gemini and HTTPS servers, not to the individual resources provided through those servers, potentially by distinct human beings, as in the case where one Gemini server serves capsules on behalf of multiple people. TOFU lets your software know that the server you're connecting to seems to be different from the one you connected to previously, and is therefore potentially being "passed off" as the previous server you connected to. TCA lets your software know that the server you're connecting to is or is not the one that was certified by a presumably-reliable certification authority in the recent past. Neither of them tells you whether one or more of that server's own users or documents have somehow been replaced. They operate at a different scale of granularity.


Security for individual documents


TLS lets us obtain the public key of the server responding to our request. This forms the main input to TOFU/TCA decision-making. Now, the context of any request will be a TLS-wrapped communication in some protocol, such as HTTPS or Gemini. There will already have been a TLS handshake, and the client software will have decided on the basis of TOFU/TCA whether to proceed, and will generally issue a request whose parameters are mechanically derived from a URL.


So for example:

https://example.com/files/doc1234.doc

will result in a connection to the server at "example.com", a TLS handshake, during which the certificate presented by the server will be checked according to TCA, and then the web client will issue a TLS-encrypted request for "/files/doc1234.doc". The only way to know whether the certificate is valid is to check it against the data provided in advance on behalf of the Certificate Authority per TCA (or the cached copy, if any, of the certificate if we were following TOFU).


Where the certificate was not previously known to a TOFU-following client, or where it has changed, there is a problem. Now, mostly, this is offloaded onto the user and the user is interrupted, notified and asked to resolve the situation herself/himself/itself.


But we could obviate that if the URL itself contained data adequate to verify the certificate. This makes URLs unreadably long and unwieldy, which would have hindered their adoption in the 1990s, but nowadays it's more likely to be acceptable in some contexts, and URLs are often transferred via cut-and-paste or QR codes.


Technically, URLs that embed server fingerprints are called "YURLs".


YURLs


As there is no principled way to incorporate fingerprint data in Gemini-scheme URLs without effectively extending the specification of Gemini, what I propose instead is a type of URL which uses its own scheme. (URL schemes are the part before the first colon, e.g., "https", "gemini", "mailto", "data". The structure of the part after the colon is determined according to the part before it.) Compliant software encountering one of these non-Gemini URLs would know how to interpret it, and obtain two things:


the expected fingerprint certificate

the requisite information to create a conformant Gemini URL for the document in question, to be requested via the normal, unextended Gemini protocol


Now I think this is best done on a per-document basis. Thomas Leonard ("talex5") has implemented such a thing on top of HTTPS, using the made-up URL scheme "httpsy". This defines a means of validating the server public key and embedding that in a URL, from which an HTTPS request is created. What Leonard also includes is a per-document access token, equivalent to a password. And that needs to be shoved into the URL as well, but once you've got a certificate fingerprint shoehorned into a URL you've already given up on readability and brevity. This token is called a "Swiss number", and is similar to a password; the Titan protocol includes a similar device.


You can have a Swiss number for each document, or for each user. Users can share their Swiss numbers with others: the notion is "knowledge is authorisation". Again, this is similar to the way that anyone who has access to a Google doc can share that access with further parties.


But ultimately, YURLs and Swiss numbers are orthogonal concepts. The key thing from a TLS perspective is the YURL's embedded certificate fingerprint. This secures the system against DNS cache poisoning, compromised Certificate Authorities, and all the various problems with TOFU. TOFU vs TCA is simply irrelevant when the client is using a YURL rather than a plain URL.


talex5 implementation of HTTPSY

Swiss number


Implementation


I propose an experimental URL scheme, "swissyurl+gemini". Any conformant URL would also be a YURL. To reiterate: YURLs are those URLs which include a means of identifying that one is talking to the right server, e.g., by incorporating a certificate fingerprint.


The scheme looks like this:

swissyurl+gemini://sha256:{fingerprint}@{domain}:{port}/{path}!{swiss_number}

for example:

swissyurl+gemini://sha256:a83ddebd605f67f358d43c3f7dd44614cce42c9ce6bbc5e50b78ea5d95d9f068@gemini.ucant.org/restricted/document123.pdf!d2cc435dd66925a7e3fe23fb6d588325

Now if you received this, you could connect to gemini.ucant.org's Gemini service, obtain the public key fingerprint, run it through base32 encoding, and see if "a83ddebd605f67f358d43c3f7dd44614cce42c9ce6bbc5e50b78ea5d95d9f068" popped out. If it didn't, it scarcely matters if your DNS or certificate store were somehow compromised. You'd then make a normal Gemini-protocol request for the following URL:

gemini://gemini.ucant.org/restricted/document123.pdf!d2cc435dd66925a7e3fe23fb6d588325

and the access token would be accepted or rejected by the server (though in practice you would not make two separate TLS connections, to avoid a TOCTOU bug).


Actual Swiss YURL over Gemini client implementation

-- Response ended

-- Page fetched on Thu May 2 19:03:46 2024