Fix verify_callback behavior, change "verified" to "authorised" to conform with the wording in the gemini specification.

This commit is contained in:
Michael Lazar 2020-05-30 14:39:31 -04:00
parent 4202e69ff4
commit 8deb372ca0
4 changed files with 19 additions and 10 deletions

View File

@ -54,7 +54,7 @@ Check out the updated examples in the *examples/* directory for more details.
Jetforce will now accept self-signed and unvalidated client certificates. The
``capath`` and ``cafile`` arguments can still be provided, and will attempt to
validate the certificate using of the underlying OpenSSL library. The result
of this validation will be saved in the ``TLS_CLIENT_VERIFIED`` environment
of this validation will be saved in the ``TLS_CLIENT_AUTHORISED`` environment
variable so that each application can decide how it wants to accept/reject the
connection.

View File

@ -103,12 +103,12 @@ $ openssl req -newkey rsa:2048 -nodes -keyout {hostname}.key \
-nodes -x509 -out {hostname}.crt -subj "/CN={hostname}"
```
Jetforce also supports TLS client certificates (both self-signed and CA verified).
Jetforce also supports TLS client certificates (both self-signed and CA authorised).
Requests that are made with client certificates will include additional
CGI/environment variables with information about the TLS connection.
You can specify a CA for client validation with the ``--tls-cafile`` or ``--tls-capath``
flags. Connections validated by the CA will have the ``TLS_CLIENT_VERIFIED`` environment
flags. Connections validated by the CA will have the ``TLS_CLIENT_AUTHORISED`` environment
variable set to True. Instructions on how to generate CA's are outside of the scope of
this readme, but you can find many helpful tutorials
[online](https://www.makethenmakeinstall.com/2014/05/ssl-client-authentication-step-by-step/).
@ -159,7 +159,7 @@ Additional CGI variables will also be included when the connection uses a TLS cl
| TLS_CLIENT_NOT_BEFORE | Certificate activation date. | ``2020-04-05T04:18:22Z`` |
| TLS_CLIENT_NOT_AFTER | Certificate expiration date. | ``2021-04-05T04:18:22Z`` |
| TLS_CLIENT_SERIAL_NUMBER | Certificate serial number. | ``73629018972631`` |
| TLS_CLIENT_VERIFIED | Was the certificate verified by OpenSSL? | ``0`` (not verified) / ``1`` (verified) |
| TLS_CLIENT_AUTHORISED | Was the certificate verified by the server's CA? | ``0`` (not authorised) / ``1`` (authorised) |
The CGI script must then write the gemini response to the *stdout* stream.
This includes the status code and meta string on the first line, and the

View File

@ -162,7 +162,7 @@ class GeminiProtocol(LineOnlyReceiver):
"TLS_CLIENT_NOT_AFTER": cert_data["not_after"],
"TLS_CLIENT_SERIAL_NUMBER": cert_data["serial_number"],
# Grab the value that was stashed during the TLS handshake
"TLS_CLIENT_VERIFIED": getattr(conn, "verified", False),
"TLS_CLIENT_AUTHORISED": getattr(conn, "authorised", False),
}
)
return environ

View File

@ -105,12 +105,21 @@ class GeminiCertificateOptions(CertificateOptions):
"""
Callback used by OpenSSL for client certificate verification.
preverify_ok returns the verification result that OpenSSL has already
obtained, so return this value to cede control to the underlying
library. Returning true will always allow client certificates, even if
they are self-signed.
preverify_ok will contain the verification result that OpenSSL has
determined based on the server's CA trust store.
Return preverify_ok to cede control to the underlying library.
Return True to allow unverified, self-signed client certificates.
This callback may be invoked multiple times during the TLS handshake.
If at any point OpenSSL returns a preverify_ok value of zero, we should
mark the certificate as not trusted.
"""
conn.verified = preverify_ok
if not hasattr(conn, "authorised"):
conn.authorised = preverify_ok
else:
conn.authorised *= preverify_ok
return True
def proto_select_callback(