Skip to content

Commit 700157d

Browse files
committed
Improve HTTPS connection tests
1 parent 715c66d commit 700157d

File tree

7 files changed

+155
-31
lines changed

7 files changed

+155
-31
lines changed

src/crate/client/doctests/https.txt

+47-24
Original file line numberDiff line numberDiff line change
@@ -23,59 +23,82 @@ with the path to the CA certificate file using the keyword argument
2323
:local:
2424

2525
Examples
26-
--------
26+
========
2727

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

31-
>>> verifying_client = HttpClient([crate_host])
32-
>>> verifying_client.server_infos(crate_host)
31+
32+
With certificate verification
33+
-----------------------------
34+
35+
When using a valid CA certificate, the connection will be successful::
36+
37+
>>> client = HttpClient([crate_host], ca_cert=cacert_valid)
38+
>>> client.server_infos(client._get_server())
39+
('https://localhost:65534', 'test', '0.0.0')
40+
41+
When not providing a ``ca_cert`` file, the connection will fail::
42+
43+
>>> client = HttpClient([crate_host])
44+
>>> client.server_infos(crate_host)
3345
Traceback (most recent call last):
3446
...
3547
crate.client.exceptions.ConnectionError: Server not available, ...certificate verify failed...
3648

37-
Also, when providing an invalid ``ca_cert`` an error is raised::
49+
Also, when providing an invalid ``ca_cert``, an error is raised::
3850

39-
>>> verifying_client = HttpClient([crate_host], ca_cert=invalid_ca_cert)
40-
>>> verifying_client.server_infos(crate_host)
51+
>>> client = HttpClient([crate_host], ca_cert=cacert_invalid)
52+
>>> client.server_infos(crate_host)
4153
Traceback (most recent call last):
4254
...
4355
crate.client.exceptions.ConnectionError: Server not available, ...certificate verify failed...
4456

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

47-
>>> verifying_valid_client = HttpClient([crate_host], ca_cert=valid_ca_cert)
48-
>>> verifying_valid_client.server_infos(verifying_valid_client._get_server())
49-
('https://localhost:65534', 'test', '0.0.0')
58+
Without certificate verification
59+
--------------------------------
5060

51-
When turning off certificate verification, calling the server will succeed::
61+
When turning off certificate verification, calling the server will succeed,
62+
even when not providing a valid CA certificate::
5263

53-
>>> non_verifying_client = HttpClient([crate_host], verify_ssl_cert=False)
54-
>>> non_verifying_client.server_infos(crate_host)
64+
>>> client = HttpClient([crate_host], verify_ssl_cert=False)
65+
>>> client.server_infos(crate_host)
5566
('https://localhost:65534', 'test', '0.0.0')
5667

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

60-
>>> non_verifying_client = HttpClient([crate_host], verify_ssl_cert=False, ca_cert=invalid_ca_cert)
61-
>>> non_verifying_client.server_infos(crate_host)
71+
>>> client = HttpClient([crate_host], verify_ssl_cert=False, ca_cert=cacert_invalid)
72+
>>> client.server_infos(crate_host)
6273
('https://localhost:65534', 'test', '0.0.0')
6374

6475

76+
6577
Client certificate
6678
------------------
6779

68-
The client supports client certificates.
80+
The CrateDB driver also supports client certificates.
6981

7082
The ``HttpClient`` constructor takes two keyword arguments: ``cert_file`` and
71-
``key_file``. Both should be a string pointing to the path of the client
72-
certificate and key file.
83+
``key_file``. Both should be strings pointing to the path of the client
84+
certificate and key file::
85+
86+
>>> client = HttpClient([crate_host], ca_cert=cacert_valid, cert_file=clientcert_valid, key_file=clientcert_valid)
87+
>>> client.server_infos(crate_host)
88+
('https://localhost:65534', 'test', '0.0.0')
89+
90+
When using an invalid client certificate, the connection will fail::
91+
92+
>>> client = HttpClient([crate_host], ca_cert=cacert_valid, cert_file=clientcert_invalid, key_file=clientcert_invalid)
93+
>>> client.server_infos(crate_host)
94+
Traceback (most recent call last):
95+
...
96+
crate.client.exceptions.ConnectionError: Server not available, exception: HTTPSConnectionPool...
7397

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

77-
>>> client = HttpClient([crate_host], cert_file=invalid_ca_cert, key_file=invalid_ca_cert, timeout=10)
100+
>>> client = HttpClient([crate_host], ca_cert=cacert_invalid, cert_file=clientcert_valid, key_file=clientcert_valid)
78101
>>> client.server_infos(crate_host)
79102
Traceback (most recent call last):
80103
...
81-
crate.client.exceptions.ConnectionError: Server not available, exception: ...[SSL: ...
104+
crate.client.exceptions.ConnectionError: Server not available, exception: HTTPSConnectionPool...
+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
-----BEGIN RSA PRIVATE KEY-----
2+
MIIEowIBAAKCAQEAwLzVfL66Z6GiuVVZsDMSuLQS8fnW402U0cNLJNp2resdswfC
3+
y7t8X9KXi49nBCxn4RsNkWLQacdSxYhz5HTyuHny8id0Tb+05AY3yDvWIm7R+gXy
4+
2tScqplcqotKCGLmPavQk1+H3ChderRVb7jTyphSx1n4bsdVSkbseajevz1afy07
5+
D8kj/nhkGml7msZOrffjmxqgXLlC2tEuCnO7TA/KOn2uGLxoIivac7AqkRdnYB5j
6+
3qVX2M6ftL8xAM2myNRuV+Ugj1XkvVE94/5Ihm1lKDqlwWh0dSzY0NnHwJh1ej98
7+
V1er+bdbXOKEG6Pjjbk6xNHK0EtqonlUfgVX2QIDAQABAoIBADtygw6k7W3FZyFu
8+
9+jm9+FMeYN1Ihid90bzy5ukXnKqUFDGFgks3OHZXLDJHGcnIytFYtvy9IGL3zXa
9+
LpTKlYrc4lhaXv8UIEEswcva2ONp9w39A7kHVwMvpmtb5wvLJWTkN8Mc9hSrxplw
10+
QeHhykF01iNy1rOke+QbGBk2Qu4M/1fRBUHcf+AWLamc3I6hE3Wy5GDZM3AGFVeW
11+
jQB3E6EbPrvBfc8XVPoOwYbNnZYgF7H66Iya7IN0QjozKzE5RiX3dQXRnEIwIgcw
12+
sJ3Nv8S8LgTIlumPMsvQHSRvVovT1/3V6uEsIrAUMVcXjv+Yuwp8z/Ux42deoToO
13+
LR025vkCgYEA5y/6v3h0v4FpHHdsZQBJJdsaDyrFqdjpWO0VF2npH/ByITPNyZwy
14+
whFSmXGTBFiIWQaleF00cwMNq0xxXDXRP2I/14TbM3DMXXznnCZoA4yROaoBd21Q
15+
Ymo8N049DAVK3/AfFjFI1i7T7jAcrtVYX4kvU/3O8yP7WLCQnbPffKcCgYEA1Wxs
16+
F7UyEznJBToLRTcaRiUUdqYcUt/JqmHlEC5BjpB939nGpLneulYz6WAlWdg8nMx7
17+
zP2Iyk+ND0aSz0qjWuxSi0IZLF5JCbrRiKIgMO9F7yWw3T+gdmiezmLecxlExZ42
18+
rfFI6o9AuG+0taY+nXu2oHbL0gJA6nLKWudgl38CgYBeYW0Jq+BlqixCLdL3rNUv
19+
+jG6TWjivSYOYsOAioFcw6mkOmTh0L28EpxY/k/Zr1cCmT8GU26tIWr8KroAvgvN
20+
x4turdNbPcqAxBQ94EQIZuOG2gu9OMhfVSV+Ipezh5mYsIvQYJBuuDFXBRdAnOJ2
21+
JihHLs/E3USoYXS4nQ048wKBgA74ZPigwBtzITOZp7K6M8CZ1z6fVjtF8UpfRYcG
22+
B5ktb3blOrbRRttBMrD7CoOr1EyXV1PAsPin7dgVdjTOInk9PGkCQOvIzUy+avYv
23+
kRx9nCUzOp26WdIUcpc9ficKrbVC7Mj0tM2nML3/L+jR+XBofh3xV0iq2czYMnN/
24+
6VmXAoGBAIUvnXaG5NXMBy2bs5j7NaHfizo5VM/4WIA6iB+dbuf6RcH18hG/C7Mf
25+
RkOhVoTaQAS8FLg+0tMHKcxGMk8bcJcCKoFqD2+cOyyiPpaFXNpTg+VlHrtnH7s6
26+
FCbwlfmb7RbpPI+iCYDtJQpoPvTeuC58mZTHvE5OQWchh32VuwzM
27+
-----END RSA PRIVATE KEY-----
28+
-----BEGIN CERTIFICATE-----
29+
MIIC1DCCAj0CFGQC3tYjJ8bEqpzh37LH6gi+om8zMA0GCSqGSIb3DQEBCwUAMIGI
30+
MQswCQYDVQQGEwJERTEPMA0GA1UECAwGQmVybGluMQ8wDQYDVQQHDAZCZXJsaW4x
31+
IjAgBgNVBAoMGUNyw4PCpHRlIFRlY2hub2xvZ2llIEdtYkgxEzARBgNVBAMMCmxv
32+
Y2FsaG9yc3QxHjAcBgkqhkiG9w0BCQEWD25vYm9keUBjcmF0ZS5pbzAeFw0yMTAz
33+
MTkxODU0NTlaFw0yMjAzMTQxODU0NTlaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQI
34+
DApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQw
35+
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDAvNV8vrpnoaK5VVmwMxK4
36+
tBLx+dbjTZTRw0sk2nat6x2zB8LLu3xf0peLj2cELGfhGw2RYtBpx1LFiHPkdPK4
37+
efLyJ3RNv7TkBjfIO9YibtH6BfLa1JyqmVyqi0oIYuY9q9CTX4fcKF16tFVvuNPK
38+
mFLHWfhux1VKRux5qN6/PVp/LTsPySP+eGQaaXuaxk6t9+ObGqBcuULa0S4Kc7tM
39+
D8o6fa4YvGgiK9pzsCqRF2dgHmPepVfYzp+0vzEAzabI1G5X5SCPVeS9UT3j/kiG
40+
bWUoOqXBaHR1LNjQ2cfAmHV6P3xXV6v5t1tc4oQbo+ONuTrE0crQS2qieVR+BVfZ
41+
AgMBAAEwDQYJKoZIhvcNAQELBQADgYEAFE+prZkMryCFqjELJWFPXfcxGIQmMP6U
42+
mMCb1eny60s0mHu1TasqjxaoBN/1/PPi9ZGpWZfoI4UK/Xt+F6iFT2ehQvErXVop
43+
cSAbGFSDH+ST6Qv5mE0Fzc1EPBa+x0qWzNeBBxUcQ89LH5cfX9HmuIFiErv9qr/K
44+
ROJOkC6+AjU=
45+
-----END CERTIFICATE-----

src/crate/client/pki/client_valid.pem

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
-----BEGIN RSA PRIVATE KEY-----
2+
MIIEogIBAAKCAQEApEAgWEX1bWJWj5rCj0+BjbeaZdhzmNno43rYmwBBW+1U4BuD
3+
bOuumnyfut3nns3e6mWcVvyc4F36a5CJt7b6YSxUi2k1fgrs08mzbOQaQ/dkiY+X
4+
wdsMcb9Vdc+VHTK9dYwKQIbsTkWZ9zMPzZ0da8ilXGM8oHRyBZDrpRb4c18fWJpp
5+
UMAmnStkm6FyWNEOug/FXFU4HduD/59z91SRpWaJX8HnbZcAOcMbXFomQ23rPPxi
6+
Ld/rX86KwxPjTlZK3c3r7/eIN0iY/GqxZ+3Vx0W2I093Qai3XyAiSd1/HkJS19qP
7+
f442evV03h+Y0zEVaPQ3+fxqvVc5aCzaQFl7jQIDAQABAoIBAALv8qQhfCYcoBep
8+
WNlfPp3eLrCrkkWlf/ixdbYv5vtR3zayx0LnZBP3LpQU69N3MwlWD9muYs/QXm4W
9+
A6B5cTjTph9oHkDGyT1wWfkUizOz9ORQ4RHibPKLzWdx8uS2x5SWkIhe4VL1A6/c
10+
BehTavdGe06Pp8Hm0zMuSEiHhKHrhjpCLHyoWfUQV4wDdTQqGUtCm+vw9X//d4tr
11+
rD7VtOj7EWxWekHAHBBuSutnydUgnYANdqmH23gz0ixQT0XFigO/pMZfjyQQImQp
12+
yT+RpgUtM4KJQoGTEOcVloLfGrO9s/iJwhL9jcAypMA/VP1LXqp0tbYVgMwzTV9Y
13+
EYtEYLECgYEAz+IAEPnGGPiL6wHwqXTZViszq4lL+BtNJGFRlSD0HfQsm1L7pIcO
14+
f45Jy5f+cAQGRw2gbjal14107rQU9QoTiDUPyrs2wIItoEg+2IO7ujScqhQKpBwY
15+
FMPfqTFp2yoRU4jOTj/1W16Vv6mIab8/AZGOjUC4djOUQBK3efCHBscCgYEAykS2
16+
lAIK9N6o89fxLJO83PUbL/vom4qlMK4zu1dCzRk0KZe3tw41GlOWSUey0EJddNu1
17+
WmkiRLypeRSRzlushvcD6bicoHj6G5ZtEWMgSUNSZhw03sJ9vvgyJR43ApFfXg4D
18+
0h9ZyUD75YCWCj6t75694Ei6JteAOkjpYxP9RwsCgYACd8JccTqizUCL96ftuw9h
19+
cH3aiXS3a0uNJQKc7Jk5Sc7FwURvfZL0fLHvksxYdBPHAChpZoiteGZs9wJQrl/w
20+
/ABF/db2jhUQlAr68wVlfn5lnntJ23OFu5WKIqYJDgTKoxMf5q54+TR54/9Ukgqj
21+
cCDrGFuYO6CE6jP3ZJ2VvQKBgF+rfIgpJzGHF3aujt48yrngHQnnJrBbNaL+4m0b
22+
6vbDkw6ROk4VJDzdiFoE1aj3muio+vBWheTpL2ebuRNX/RShRXKI5VxpnDLsRY5R
23+
ynWcqB6v/LnYWE25a05vKinGxMrh6iC6v2cXm42D8nPKDc8m0DyDabjxeS8YSXuZ
24+
etTdAoGAH2keFYo3TPu1p7kgRXyJHeRFk4/n8N/jN+ChPZcOn9aZxBeOjwOAUTnu
25+
QJsTv6mrzPlsUMVOhOnA9M3TebfgOhCbb7MJMT+e04mUgiACLwPMA7RVWyoVrivP
26+
BD67yEKxqxKs5wh7kGIoUUsGaLLRCzRkrlIvBbUWcEh/sSEDEzA=
27+
-----END RSA PRIVATE KEY-----
28+
-----BEGIN CERTIFICATE-----
29+
MIIDJTCCAg0CFHFIksYWdXAiW8NROML2/iBbu/PrMA0GCSqGSIb3DQEBCwUAMFkx
30+
CzAJBgNVBAYTAkFUMRMwEQYDVQQIDApWb3JhcmxiZXJnMREwDwYDVQQHDAhEb3Ju
31+
YmlybjEOMAwGA1UECgwFQ3JhdGUxEjAQBgNVBAMMCWxvY2FsaG9zdDAeFw0yMTAz
32+
MTkxOTE1MzhaFw0yMjAzMTQxOTE1MzhaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQI
33+
DApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQw
34+
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCkQCBYRfVtYlaPmsKPT4GN
35+
t5pl2HOY2ejjetibAEFb7VTgG4Ns666afJ+63eeezd7qZZxW/JzgXfprkIm3tvph
36+
LFSLaTV+CuzTybNs5BpD92SJj5fB2wxxv1V1z5UdMr11jApAhuxORZn3Mw/NnR1r
37+
yKVcYzygdHIFkOulFvhzXx9YmmlQwCadK2SboXJY0Q66D8VcVTgd24P/n3P3VJGl
38+
ZolfwedtlwA5wxtcWiZDbes8/GIt3+tfzorDE+NOVkrdzevv94g3SJj8arFn7dXH
39+
RbYjT3dBqLdfICJJ3X8eQlLX2o9/jjZ69XTeH5jTMRVo9Df5/Gq9VzloLNpAWXuN
40+
AgMBAAEwDQYJKoZIhvcNAQELBQADggEBAGQFf8I2V+wbWpTItkVMq9Mipb5b3z7w
41+
aCpxyG2dB9MTKQ4wbrJ29q15g7GZjg9pmIzptJej9Vj7nYXuskeqeunMgwJUJ/QU
42+
SUewx5MUYjl2cRtsAHXyQvqoV/FWwRqQGhqKGb3/dzULAgNYntIcXu+QNzOIA/q9
43+
/Q4quG/SRcorKQM5RDbBpf8Lqan9csLNuL+u5T4BCYtqd7EaeHBMhQ30cP502Hn4
44+
U0oYmnqvP2KNtvAPKhqKMWodd2MfyW87ifU7eugZFFY11y8HqvP5V3P0QxoxiBlB
45+
XU6nnhHW88hel0gxFDZ51fbnVp6SP/hyjyt/deNaJzZfHFIPDqPXjLs=
46+
-----END CERTIFICATE-----

src/crate/client/tests.py

+17-7
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,9 @@ class HttpsTestServerLayer(object):
211211
PORT = 65534
212212
HOST = "localhost"
213213
CERT_FILE = os.path.abspath(os.path.join(os.path.dirname(__file__),
214-
"test_https.pem"))
214+
"pki/server_valid.pem"))
215+
CACERT_FILE = os.path.abspath(os.path.join(os.path.dirname(__file__),
216+
"pki/cacert_valid.pem"))
215217

216218
__name__ = "httpsserver"
217219
__bases__ = tuple()
@@ -223,6 +225,7 @@ def get_request(self):
223225
keyfile=HttpsTestServerLayer.CERT_FILE,
224226
certfile=HttpsTestServerLayer.CERT_FILE,
225227
cert_reqs=ssl.CERT_OPTIONAL,
228+
ca_certs=HttpsTestServerLayer.CACERT_FILE,
226229
server_side=True)
227230
return socket, client_address
228231

@@ -264,15 +267,22 @@ def setUpWithHttps(test):
264267
test.globs['crate_host'] = "https://{0}:{1}".format(
265268
HttpsTestServerLayer.HOST, HttpsTestServerLayer.PORT
266269
)
267-
test.globs['invalid_ca_cert'] = os.path.abspath(
268-
os.path.join(os.path.dirname(__file__), "invalid_ca.pem")
269-
)
270-
test.globs['valid_ca_cert'] = os.path.abspath(
271-
os.path.join(os.path.dirname(__file__), "test_https_ca.pem")
272-
)
273270
test.globs['pprint'] = pprint
274271
test.globs['print'] = cprint
275272

273+
test.globs['cacert_valid'] = os.path.abspath(
274+
os.path.join(os.path.dirname(__file__), "pki/cacert_valid.pem")
275+
)
276+
test.globs['cacert_invalid'] = os.path.abspath(
277+
os.path.join(os.path.dirname(__file__), "pki/cacert_invalid.pem")
278+
)
279+
test.globs['clientcert_valid'] = os.path.abspath(
280+
os.path.join(os.path.dirname(__file__), "pki/client_valid.pem")
281+
)
282+
test.globs['clientcert_invalid'] = os.path.abspath(
283+
os.path.join(os.path.dirname(__file__), "pki/client_invalid.pem")
284+
)
285+
276286

277287
def _try_execute(cursor, stmt):
278288
try:

0 commit comments

Comments
 (0)