blob: fc3f889ae3fd85bac512b98b0de5476db111603c (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
# Virebent fork of gmnisrv
This is a fork of [gmnisrv](https://git.sr.ht/~sircmpwn/gmnisrv), a small
Gemini server, with three patches that let it serve **CA-signed certificates
(e.g. Let's Encrypt)** instead of being limited to self-signed TOFU certs.
## Why
Upstream gmnisrv reads only the leaf certificate from the cert file
(`PEM_read_X509`) and never sends the intermediate chain, so clients cannot
build a path to a trusted root — CA validation always fails and you are stuck
with TOFU. agate has the same limitation by design. This fork makes a Gemini
capsule verifiable with a normal Let's Encrypt certificate.
## Patches
1. **Full certificate chain** — `tls_host_init` now reads every certificate in
the PEM (leaf + intermediates) into a `STACK_OF(X509)`, and `tls_set_host`
sends it with `SSL_set1_chain`. (`src/tls.c`, `include/config.h`)
2. **TLS 1.3 only** — minimum protocol bumped from TLS 1.2 to TLS 1.3.
(`src/tls.c`)
3. **Handshake buffer overflow fix** — the handshake flush staged the whole
TLS output into a fixed 4 KB buffer. A full CA chain (~5 KB) overflowed it
and aborted the process on an `assert` — a crash loop on any public port hit
by scanners. The flush now drains the write BIO through a local buffer in a
loop, like the response path already does. (`src/server.c`)
## Build
```
./configure
# OpenSSL 3.x emits deprecation warnings for the EC self-signed generator;
# allow them through:
echo 'CFLAGS += -Wno-error=deprecated-declarations' >> .build/config.mk
make gmnisrv
```
Put the Let's Encrypt `fullchain.pem` as `<store>/<hostname>.crt` and
`privkey.pem` as `<store>/<hostname>.key`, and refresh them from a certbot
deploy hook on renewal.
|