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 Jetforce will now accept self-signed and unvalidated client certificates. The
``capath`` and ``cafile`` arguments can still be provided, and will attempt to ``capath`` and ``cafile`` arguments can still be provided, and will attempt to
validate the certificate using of the underlying OpenSSL library. The result 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 variable so that each application can decide how it wants to accept/reject the
connection. connection.

View File

@ -103,12 +103,12 @@ $ openssl req -newkey rsa:2048 -nodes -keyout {hostname}.key \
-nodes -x509 -out {hostname}.crt -subj "/CN={hostname}" -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 Requests that are made with client certificates will include additional
CGI/environment variables with information about the TLS connection. CGI/environment variables with information about the TLS connection.
You can specify a CA for client validation with the ``--tls-cafile`` or ``--tls-capath`` 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 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 this readme, but you can find many helpful tutorials
[online](https://www.makethenmakeinstall.com/2014/05/ssl-client-authentication-step-by-step/). [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_BEFORE | Certificate activation date. | ``2020-04-05T04:18:22Z`` |
| TLS_CLIENT_NOT_AFTER | Certificate expiration date. | ``2021-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_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. 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 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_NOT_AFTER": cert_data["not_after"],
"TLS_CLIENT_SERIAL_NUMBER": cert_data["serial_number"], "TLS_CLIENT_SERIAL_NUMBER": cert_data["serial_number"],
# Grab the value that was stashed during the TLS handshake # 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 return environ

View File

@ -105,12 +105,21 @@ class GeminiCertificateOptions(CertificateOptions):
""" """
Callback used by OpenSSL for client certificate verification. Callback used by OpenSSL for client certificate verification.
preverify_ok returns the verification result that OpenSSL has already preverify_ok will contain the verification result that OpenSSL has
obtained, so return this value to cede control to the underlying determined based on the server's CA trust store.
library. Returning true will always allow client certificates, even if
they are self-signed. 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 return True
def proto_select_callback( def proto_select_callback(