alex at gnu.org
Fri Jul 17 10:24:42 BST 2020
People on the #gemini IRC channel and on Mastodon might have seen me
struggle with client certificates on the server side and it occured to
me that I didn't post my solution to the list so here it is.
Background: I'm using Perl, with a library that uses OpenSSL bindings
in the background, so as you dig deeper, you soon end up reading the
In the TOFU world, the default OpenSSL setup doesn't quite work. The
default is that clients don't send their client certificates to the
server unless the server asks for them during the handshake. In the
OpenSSL world, the server can be told to do this by telling it to
verify the client certificate. When you do that, the server will then
reject the connection because the client certificate is self-signed. In
order to force the server to still accept it, you need to provide your
own verification callback which simply returns 1 for all certificates
in the chain of certificates the client presents you with.
"SSL_set_verify() sets the verification flags for ssl to be mode and
specifies the verify_callback function to be used. If no callback
function shall be specified, the NULL pointer can be used for
verify_callback. In this case last verify_callback set specifically for
this ssl remains."
Keywords to look for in your SSL or TLS library's documentation are
"peer verification", "verification mode", "verification callback", etc.
Once you have all that, then you can get the fingerprint of the client
cert on the server side and compare it to the list of fingerprints you
know (if you're trying to only allow some people access), or save the
combination of fingerprint and common name in your database if you want
to create an account (like astrobotany does), or send a 60 code back if
there is no certificate, or a 61 code if the fingerprint doesn't match
anything in your database, or a 62 if you decide to do further tests
such as checking the validity start date or the expiry date of the
Hope that helps somebody
More information about the Gemini