Username/password authentication strategy

I see this as the same issue that exists for clients - without a trusted
CA, there's nothing to stop me masquerading as anyone else, other than the
certificate (e.g. fingerprint) pinning, so I believe the process absolutely
needs a (one-time) login prompt to pin the certificate - I can't see a way
to avoid it.

Your question made me think about what would be the minimum steps required
to implement client TOFU with PIN or password verification, and the code
below is my take on what I think has to happen. Note the code is only meant
as a concise way to discuss the process.

So, for example, a request to a private resource, such as: -

gemini://susa.net/cgi-bin/private.sh?articleId=1234

Might be handled something like this: -

$ cat private.sh
#!/bin/bash

# If we have no client certificate, request one.
if [[ "${TLS_CLIENT_HASH}" == "" ]]; then

    echo -ne "60 CLIENT CERTIFICATE REQUIRED\r\n"

elif [[ $(grep "${TLS_CLIENT_HASH}" /tmp/${REMOTE_USER}_sigs) == "" ]]; then

    # We've never seen this user's client hash, so challenge for a PIN
    # (we could store this current URL for onward forwarding)
    echo -ne "30 /cgi-bin/login.sh\r\n"

else

    echo -ne "20 text/gemini\r\n"
    echo "This is the prize inside the protected resource!"
fi

I think a redirect to a login process is unavoidable, because any
originating request might have its own query_string, yet we're going to
need one for the password prompt response. So the login.sh would be our
one-time verification to pin the certificate to a CN based user-id.

$ cat login
#!/bin/bash

# If we have no client certificate, request one.
if [[ "${TLS_CLIENT_HASH}" == "" ]]; then
    echo -ne "60 CLIENT CERTIFICATE REQUIRED\r\n"
    exit
fi

# If the certificate has no CN, then reject it
if [[ "${REMOTE_USER}" == "" ]]; then
    echo -ne "20 text/gemini\r\n"
    echo "Your CN can't be used as a user-id!"
    exit
fi

# We have a client certificate, is it already authorised?
if [[ $(grep "${TLS_CLIENT_HASH}" /tmp/${REMOTE_USER}_sigs) != "" ]]; then
    echo -ne "20 text/gemini\r\n"
    echo "You are already authorised!"
    exit
fi

# We have a certificate and a valid user-id (CN), so either prompt for
# a PIN, or verify PIN if we've been given a QUERY_STRING.

# Grep the remote user's line from the passwd file (format CN:PIN)
PWD_ENTRY=$(grep "^${REMOTE_USER}:" login_passwd)

# Strip the CN value and separator, leaving the PIN
MY_PIN="${PWD_ENTRY#${REMOTE_USER}:}"

# Check for our PIN in the query string (which may be empty)
if [[ "${QUERY_STRING}" == "${MY_PIN}" ]]; then
    echo -ne "20 text/gemini\r\n"
    echo "Your PIN checks out, ${REMOTE_USER}!"
    echo "${TLS_CLIENT_HASH}" >>/tmp/${REMOTE_USER}_sigs
    echo "Your hash has been stored in '/tmp/${REMOTE_USER}_sigs'"
    exit
fi

echo -ne "11 Please enter your PIN, ${REMOTE_USER}\r\n"


On Sun, 19 Jul 2020 at 20:26, Peter Vernigorov <pitr.vern at gmail.com> 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?
>
> Another alternative to implement username/password type authentication
> in Gemini would be the sensitive input status code, but then I would
> have to store a list of certificate fingerprint and username pairs,
> greatly complicating the system.
>
> Given that Gemini protocol strives to be minimal/low-cost for both
> users and client/server devs, has anyone found a simple way to
> implement username/password type authentication systems? To be fair, I
> have attempted to use client short-/long-lived client certificates as
> per recommendation in Gemini protocol specification; however, if
> access to the same "account" from multiple devices and being able to
> survive certificate loss without permanently losing access is my
> account are requirements, this authentication method quickly becomes a
> mess. For example, think about how one would go about getting access
> to their astrobotany plant on a new device. This is why I ended up
> going back to username/password authentication, but having
> difficulties making sure that everything is secure. In need of
> help/suggestions/ideas, thanks.
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.orbitalfox.eu/archives/gemini/attachments/20200720/8bb3
276f/attachment.htm>

---

Previous in thread (3 of 12): 🗣️ Peter Vernigorov (pitr.vern (a) gmail.com)

Next in thread (5 of 12): 🗣️ Peter Vernigorov (pitr.vern (a) gmail.com)

View entire thread.