CGI and client certificate, or do we need a CGI spec

Remco me at rwv.io
Sun Nov 29 16:58:43 GMT 2020


Hi,

I've been working on a gemini server and implemented CGI by skimming
through the CGI/1.1 spec (RFC 3875) and looking through some gemini
server implementations a couple of weeks ago, to figure out what
environment variables to provide.

=> https://git.sr.ht/~rwv/dezhemini/tree/bf5b0ec4/dezhmnsrv.rkt#L253

Currently I'm playing around with client certificates (having learned a
lot more about libopenssl and racket ffi than I bargained for) and was
wondering what environment variables I want to expose to bring that
information into CGI scripts.  So I visited the list of gemini server
software again, browsed some code and found 4 servers supporting both
CGI and client certificates.

Here's what the expose.

# Jetforce

=> https://github.com/michael-lazar/jetforce/blob/d2d1f63f/jetforce/protocol.py#L180

* AUTH_TYPE : "CERTIFICATE".
* REMOTE_USER : client certificate X509 subject common name
* TLS_CLIENT_HASH : certificate fingerprint
* TLS_CLIENT_NOT_BEFORE :  certificate start date
* TLS_CLIENT_NOT_AFTER : certificate end date
* TLS_CLIENT_SERIAL_NUMBER : certificate X509 serial number
* TLS_CLIENT_AUTHORISED : "true" if certificate is validated by server CA store

# GLV-1.12556

=> https://github.com/spc476/GLV-1.12556/blob/13d52b63/Lua/GLV-1/gateway.lua#L156

* AUTH_TYPE : "Certificate"
* REMOTE_USER : client certificate X509 subject common name
* TLS_CLIENT_HASH : certificate fingerprint
* TLS_CLIENT_ISSUER : certificate X509 issuer
* TLS_CLIENT_ISSUER_* : certificate X509 issuer sub fields
* TLS_CLIENT_NOT_AFTER : certificate end date
* TLS_CLIENT_NOT_BEFORE : certificate start date
* TLS_CLIENT_REMAIN : certificate days left
* TLS_CLIENT_SUBJECT : certificate X509 subject
* TLS_CLIENT_SUBJECT_* : certificate X509 subject sub fields

# Gemserv

=> https://git.sr.ht/~int80h/gemserv/tree/ebc22964/src/cgi.rs#L42

* AUTH_TYPE : "Certificate"
* REMOTE_USER : client certificate X509 subject common name
* TLS_CLIENT_HASH : certificate fingerprint

# The Unsinkable Molly Brown

=> https://tildegit.org/solderpunk/molly-brown/src/commit/48f9a206c03c0470e1c132b9667c6daa3583dada/dynamic.go#L151

* TLS_CLIENT_HASH : certificate fingerprint
* TLS_CLIENT_ISSUER : certificate X509 issuer
* TLS_CLIENT_ISSUER_CN : certificate X509 issuer common name
* TLS_CLIENT_SUBJECT : certificate X509 subject
* TLS_CLIENT_SUBJECT_CN : certificate X509 subject common name

Looking at these it's obvious everybody is looking at everybody else to
see how they implemented it and just pick whatever they like, so it
seems I am on the right track.  ;-)  Personally I like this minimal
approach of the latter two and will probably go with no more than:

* REMOTE_USER : client certificate X509 subject common name
* TLS_CLIENT_HASH : certificate fingerprint

Because when writing a CGI scripts these are the only things I would
really need: a way to communicate with the user about their certificate
(REMOTE_USER) and a way to distinguish between offered certificates
(TLS_CLIENT_HASH).  I won't need AUTH_TYPE because if I do get a
TLS_CLIENT_HASH I'll know I can authenticate the user.

But that brings me to the real question here.  Does gemini need a CGI
spec?  Given status code 42 for CGI errors, it kinda committed to
something CGI-ish without actually stating what that is.  The only
server making the effort to implement CGI/1.1 is GLV but, IMHO, that
isn't the kind of simplicity I am here for and it's a bit of a hack to
be honest.

GLV does manage to make CGI scripts more portable, whereas other servers
don't really make the effort.  For instance, some don't provide
PATH_INFO but do provide PATH_TRANSLATED and others provide neither.  I
would like to share my CGI-scripts and have them run anywhere but to
make sharing easier something like a spec would be nice.  What do you
think?

Anyway, back to libopenssl and racket ffi..

Cheers,
Remco


More information about the Gemini mailing list