# 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.
