Username/password authentication strategy
Peter Vernigorov
pitr.vern at gmail.com
Sun Jul 19 22:27:18 BST 2020
Thanks for the reply Alex. My understanding is that your blog post
talks about how to get the server to request that the client sends the
certificate, and you are right that many Gemini servers don’t usually
do that. When writing Gig framework - https://github.com/pitr/gig -
and having the same issue, I noticed that most Go-based Gemini servers
out there don’t do this but a quick search showed that it’s just a
matter of one line change to get it working properly:
&tls.Config{
MinVersion: tls.VersionTLS12,
ClientAuth: tls.RequestClientCert // <-- this line, default is NoClientCert
}
Anyhow, when the client DOES send the certificate, it seems to do it
in plain text. See this excerpt from TLS handshaking:
...
- The server sends its ServerKeyExchange message (depending on the
selected cipher suite, this may be omitted by the server).
...
- The client responds with a Certificate message, which contains the
client's certificate.
...
- The client now sends a ChangeCipherSpec record, essentially telling
the server, "Everything I tell you from now on will be authenticated
(and encrypted if encryption was negotiated)."
...
Notice how the certificate is sent before client starts encrypting
messages. This means that the CN (and other) fields are also in plain
view and therefore cannot contain secret information.
On Sun, Jul 19, 2020 at 10:03 PM Alex Schroeder <alex at gnu.org> wrote:
>
> On Sun, 2020-07-19 at 21:26 +0200, Peter Vernigorov wrote:
> > I am trying to implement a simple authentication for my Gemini site,
> > and was planning to use a client certificate CN field to pass
> > username:password pair to server. However, upon reading closely about
> > the TLS handshake -
> > https://en.wikipedia.org/wiki/Transport_Layer_Security#TLS_handshake
> > -
> > it seems that the client (just like the server) certificate is sent
> > before the ChangeCipherSpec record, i.e. insecure. That means to me
> > that the CN field would be passed before the TLS session is started
> > and therefore not suitable as an authentication medium. Is that
> > correct?
>
> Well, my experience is that you tell the server that you want to verify
> peer certificates (which is typically off for servers); then the client
> sends you a server that won't validate if you do nothing else: you have
> to overwrite the default validation code and return True for
> everything. Then your code gets the client certificate and now you can
> do the real validation in your app instead of on the TLS layer.
>
> Here's a long blog post:
> https://alexschroeder.ch/wiki/2020-07-13_Client_Certificates_and_IO%3a%3aSocket%3a%3aSSL_(Perl)
>
> Here's where I tell my server that I want to verify peers (client
> certificates) and that I will provide my own verification code:
> https://alexschroeder.ch/cgit/gemini-wiki/tree/gemini-wiki#n758
>
> Here's the verification code for the TLS library which accepts
> anything:
> https://alexschroeder.ch/cgit/gemini-wiki/tree/gemini-wiki#n775
>
> Here's some example code that does actual validation, requests a client
> certificate if none is available, etc:
> https://alexschroeder.ch/cgit/gemini-wiki/about/#client-certificates
>
> Good luck!
>
> And yes, I'm using more traditional access tokens for my wiki per
> default.
>
More information about the Gemini
mailing list