Skip to content

Commit

Permalink
Improve HTTPS connection tests
Browse files Browse the repository at this point in the history
  • Loading branch information
amotl committed Mar 19, 2021
1 parent ff4da83 commit bf11e61
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 26 deletions.
69 changes: 46 additions & 23 deletions src/crate/client/doctests/https.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,58 +23,81 @@ with the path to the CA certificate file using the keyword argument
:local:

Examples
--------
========

When switching on verification without a ``ca_cert`` file provided, the
connection will fail because we are using a self-signed server certificate::
All of the following examples will connect to a host using a self-signed
certificate.

>>> verifying_client = HttpClient([crate_host])
>>> verifying_client.server_infos(crate_host)

With certificate verification
-----------------------------

When using a valid CA certificate, the connection will be successful::

>>> client = HttpClient([crate_host], ca_cert=cacert_valid)
>>> client.server_infos(client._get_server())
('https://localhost:65534', 'test', '0.0.0')

When not providing a ``ca_cert`` file, the connection will fail::

>>> client = HttpClient([crate_host])
>>> client.server_infos(crate_host)
Traceback (most recent call last):
...
crate.client.exceptions.ConnectionError: Server not available, ...certificate verify failed...

Also, when providing an invalid ``ca_cert`` an error is raised::
Also, when providing an invalid ``ca_cert``, an error is raised::

>>> verifying_client = HttpClient([crate_host], ca_cert=invalid_ca_cert)
>>> verifying_client.server_infos(crate_host)
>>> client = HttpClient([crate_host], ca_cert=cacert_invalid)
>>> client.server_infos(crate_host)
Traceback (most recent call last):
...
crate.client.exceptions.ConnectionError: Server not available, ...certificate verify failed...

Connecting to a host whose certificate is verified with a valid CA certificate::

>>> verifying_valid_client = HttpClient([crate_host], ca_cert=valid_ca_cert)
>>> verifying_valid_client.server_infos(verifying_valid_client._get_server())
('https://localhost:65534', 'test', '0.0.0')
Without certificate verification
--------------------------------

When turning off certificate verification, calling the server will succeed::
When turning off certificate verification, calling the server will succeed,
even when not providing a valid CA certificate::

>>> non_verifying_client = HttpClient([crate_host], verify_ssl_cert=False)
>>> non_verifying_client.server_infos(crate_host)
>>> client = HttpClient([crate_host], verify_ssl_cert=False)
>>> client.server_infos(crate_host)
('https://localhost:65534', 'test', '0.0.0')

Without verification, calling the server will even work when using an invalid
``ca_cert``::

>>> non_verifying_client = HttpClient([crate_host], verify_ssl_cert=False, ca_cert=invalid_ca_cert)
>>> non_verifying_client.server_infos(crate_host)
>>> client = HttpClient([crate_host], verify_ssl_cert=False, ca_cert=cacert_invalid)
>>> client.server_infos(crate_host)
('https://localhost:65534', 'test', '0.0.0')



Client certificate
------------------

The client supports client certificates.
The CrateDB driver also supports client certificates.

The ``HttpClient`` constructor takes two keyword arguments: ``cert_file`` and
``key_file``. Both should be a string pointing to the path of the client
certificate and key file.
``key_file``. Both should be strings pointing to the path of the client
certificate and key file::

>>> client = HttpClient([crate_host], ca_cert=cacert_valid, cert_file=key_and_cert, key_file=key_and_cert, timeout=10)
>>> client.server_infos(crate_host)
('https://localhost:65534', 'test', '0.0.0')

When using an invalid client certificate, the connection will fail::

>>> client = HttpClient([crate_host], ca_cert=cacert_valid, cert_file=cacert_invalid, key_file=cacert_invalid, timeout=10)
>>> client.server_infos(crate_host)
Traceback (most recent call last):
...
crate.client.exceptions.ConnectionError: Server not available, exception: ...[SSL: ...

This example uses that options, however it fails because the certificate is
invalid::
The connection will also fail when providing an invalid CA certificate::

>>> client = HttpClient([crate_host], cert_file=invalid_ca_cert, key_file=invalid_ca_cert, timeout=10)
>>> client = HttpClient([crate_host], ca_cert=cacert_invalid, cert_file=key_and_cert, key_file=key_and_cert, timeout=10)
>>> client.server_infos(crate_host)
Traceback (most recent call last):
...
Expand Down
12 changes: 9 additions & 3 deletions src/crate/client/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,8 @@ class HttpsTestServerLayer:
HOST = "localhost"
CERT_FILE = os.path.abspath(os.path.join(os.path.dirname(__file__),
"test_https.pem"))
CACERT_FILE = os.path.abspath(os.path.join(os.path.dirname(__file__),
"test_https_ca.pem"))

__name__ = "httpsserver"
__bases__ = tuple()
Expand All @@ -230,6 +232,7 @@ def get_request(self):
keyfile=HttpsTestServerLayer.CERT_FILE,
certfile=HttpsTestServerLayer.CERT_FILE,
cert_reqs=ssl.CERT_OPTIONAL,
ca_certs=HttpsTestServerLayer.CACERT_FILE,
server_side=True)
return socket, client_address

Expand Down Expand Up @@ -271,12 +274,15 @@ def setUpWithHttps(test):
test.globs['crate_host'] = "https://{0}:{1}".format(
HttpsTestServerLayer.HOST, HttpsTestServerLayer.PORT
)
test.globs['invalid_ca_cert'] = os.path.abspath(
os.path.join(os.path.dirname(__file__), "invalid_ca.pem")
test.globs['key_and_cert'] = os.path.abspath(
os.path.join(os.path.dirname(__file__), "test_https.pem")
)
test.globs['valid_ca_cert'] = os.path.abspath(
test.globs['cacert_valid'] = os.path.abspath(
os.path.join(os.path.dirname(__file__), "test_https_ca.pem")
)
test.globs['cacert_invalid'] = os.path.abspath(
os.path.join(os.path.dirname(__file__), "invalid_ca.pem")
)
test.globs['pprint'] = pprint
test.globs['print'] = cprint

Expand Down

0 comments on commit bf11e61

Please sign in to comment.