Using normal tls certificates with gemini

Alex // nytpu <alex (a) nytpu.com>

Hey everybody,

For my gemini capsule's tls setup, I just used my Let's Encrypt
certificate since I already had it set up for my web site. However,
after reading deeper into server setup with gemini, I discovered that
I'm probably adding a lot of extra request overhead by using a
certificate from a CA instead of self-signed. Now my problem is that if
I change out the certificate, then people that have previously visited
my site may think it is compromised because the certificate changed and
most clients are TOFU. Should I change out the certificate or is it fine
to leave it as is?

As an additional question, if I was writing a more advanced gemini
client, should I validate cert chains if they're availaible or only use
TOFU on the fingerprint and ignore chains entirely? The spec just says
to validate however you want, but what's the community's recommendation?

-- 
Alex // nytpu
alex at nytpu.com
GPG Key: https://www.nytpu.com/files/pubkey.asc
Key fingerprint: 43A5 890C EE85 EA1F 8C88 9492 ECCD C07B 337B 8F5B
https://e-mail.is-not-s.ms/

Link to individual message.

acdw <acdw (a) acdw.net>

On 2020-09-21 (Monday) at 19:04, Alex // nytpu <alex at nytpu.com> wrote:

> Hey everybody,
> 
> For my gemini capsule's tls setup, I just used my Let's Encrypt
> certificate since I already had it set up for my web site. However,
> after reading deeper into server setup with gemini, I discovered that
> I'm probably adding a lot of extra request overhead by using a
> certificate from a CA instead of self-signed. Now my problem is that if
> I change out the certificate, then people that have previously visited
> my site may think it is compromised because the certificate changed and
> most clients are TOFU. Should I change out the certificate or is it fine
> to leave it as is?

IMHO, you're fine as-is. I think I changed out breadpunk.club's cert when 
the Let's Encrypt one for HTTPS updated/changed, but I don't think you 
have to worry about it til then, if even then. There might be  more 
advanced statistics for who has a full cert vs. self-signed around somewhere, though.

> 
> As an additional question, if I was writing a more advanced gemini
> client, should I validate cert chains if they're availaible or only use
> TOFU on the fingerprint and ignore chains entirely? The spec just says
> to validate however you want, but what's the community's recommendation?

Again, IMHO, but I'd just do TOFU validation on the fingerprint ... unless 
you want to maybe be the *most* advanced gemini client out there!

-- 
~ acdw
acdw.net | breadpunk.club/~breadw

Link to individual message.

Drew DeVault <sir (a) cmpwn.com>

On Mon Sep 21, 2020 at 3:04 PM EDT, Alex // nytpu wrote:
> As an additional question, if I was writing a more advanced gemini
> client, should I validate cert chains if they're availaible or only use
> TOFU on the fingerprint and ignore chains entirely? The spec just says
> to validate however you want, but what's the community's recommendation?

Coincidentally, I just finished a TOFU implementation in my client which
I'm relatively satisfied with. To answer your question directly, I chose
to disregard the certificate chain and *always* use TOFU. I don't think
the CA cabal is something Gemini needs to get used to supporting.

In more detail, the TOFU algorithm I decided to use is:

1. On startup, the client loads a list of known hosts from
   ~/.local/share/gmni/known_hosts (adjusted per XDG basedirs as
   appropriate), which is a plaintext file where each line is one host,
   with the following attributes in order, separated by spaces:

   hostname fingerprint-algorithm fingerprint expires

   fingerprint-algorithm is always "SHA-512"; if it's not, this
   known_hosts entry is discarded. The fingerprint is the SHA-512 digest
   of the X509 certificate, and expiry is the Unix timestamp of the
   certificate's notAfter time.
2. Upon receiving a request to validate a certificate:
   A. It confirms that the current time is within [notBefore, notAfter].
      If not, the trust state is INVALID, GOTO 3.
   B. Computes the fingerprint.
   C. Consults the list of known hosts for a matching host. If not
      found, the trust state is UNKNOWN, GOTO 3.
   D. If a matching host is found, and the fingerprint matches, the
      trust state is TRUSTED. GOTO 3.
   E. If a matching host is found, and the fingerprint does not match,
      the trust state is UNTRUSTED. GOTO 3.
3. If the trust state is TRUSTED, proceed with the request.
4. If the trust state is UNKNOWN, display the fingerprint to the user
   and ask them if they want to trust this certificate, now or always.
   If always, another entry is written to known_hosts.
5. If the trust state is INVALID, the user is told about the issue and
   given the option to continue (but not to update known_hosts).
6. If the trust state is UNTRUSTED, the user is told so and the request
   is aborted. The user must manually intervene in the known_hosts file
   to continue.

Code is here:

https://git.sr.ht/~sircmpwn/gmni/commit/02f6af661513683f0c6c1465c5ff1dd8f03a30c9

Link to individual message.

colecmac@protonmail.com <colecmac (a) protonmail.com>

> For my gemini capsule's tls setup, I just used my Let's Encrypt
> certificate since I already had it set up for my web site. However,
> after reading deeper into server setup with gemini, I discovered that
> I'm probably adding a lot of extra request overhead by using a
> certificate from a CA instead of self-signed. Now my problem is that if
> I change out the certificate, then people that have previously visited
> my site may think it is compromised because the certificate changed and
> most clients are TOFU. Should I change out the certificate or is it fine
> to leave it as is?

I had the same problem for my capsule, gemini://makeworld.gq. What I did
was wait until the Let's Encrypt cert expired for a clean transition, and
then created my own small 5-year cert. See my gemlog post for details on
how to generate these:

gemini://makeworld.gq/gemlog/2020-07-06-openssl.gmi

There is also the gemcert tool:
https://tildegit.org/solderpunk/gemcert


> As an additional question, if I was writing a more advanced gemini
> client, should I validate cert chains if they're availaible or only use
> TOFU on the fingerprint and ignore chains entirely? The spec just says
> to validate however you want, but what's the community's recommendation?

Only validate the certificate in the chain that applies to the host you're
visiting, ignore all the others. Most servers do not send chains anyway,
as it adds needless extra bytes. But that does not mean fingerprints shouldn't
be used, you can still take the fingerprint of the last cert in the chain.

Cheers,
makeworld

Link to individual message.

Drew DeVault <sir (a) cmpwn.com>

I think server software should handle certificates for you and clients
should TOFU them. Dealing with certificates is annoying and dumb and the
CAs are a cabal and we don't need any of that noise in our brave new
gemini future.

My server implementation generates 1-year certificates on startup for
any domain its configured to service, and automatically rotates them.
The admin isn't involved in this in any capacity, except to copy+paste
the certificate store if they move between servers.

Link to individual message.

---

Previous Thread: Announcing gmni, a line-mode gemini browser and curl-esque utility program

Next Thread: Genini requests with ncat