Skip to content

Commit f4bf48b

Browse files
committed
Add TLS version parameters for start_wsgi_server
This adds the tls_min_version and tls_max_version parameters for the start_wsgi_server (and start_http_server), allowing to restrict the min/max TLS version negotiated for accessing the server. New unit tests under TestWsgiTLS were added, which test the version parameters as well as the rest of TLS capabilities for the start_wsgi_server (TLS on/off, mTLS), since those previously didn't have any test coverage.
1 parent 6133347 commit f4bf48b

7 files changed

Lines changed: 273 additions & 2 deletions

File tree

prometheus_client/exposition.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,8 @@ def _get_ssl_ctx(
196196
cafile: Optional[str] = None,
197197
capath: Optional[str] = None,
198198
client_auth_required: bool = False,
199+
tls_min_version: ssl.TLSVersion = ssl.TLSVersion.MINIMUM_SUPPORTED,
200+
tls_max_version: ssl.TLSVersion = ssl.TLSVersion.MAXIMUM_SUPPORTED
199201
) -> ssl.SSLContext:
200202
"""Load context supports SSL."""
201203
ssl_cxt = ssl.SSLContext(protocol=protocol)
@@ -227,6 +229,9 @@ def _get_ssl_ctx(
227229
raise exc_type(f"Cannot load server certificate file {certfile!r} or "
228230
f"its private key file {keyfile!r}: {msg}")
229231

232+
ssl_cxt.minimum_version = tls_min_version
233+
ssl_cxt.maximum_version = tls_max_version
234+
230235
return ssl_cxt
231236

232237

@@ -240,6 +245,8 @@ def start_wsgi_server(
240245
client_capath: Optional[str] = None,
241246
protocol: int = ssl.PROTOCOL_TLS_SERVER,
242247
client_auth_required: bool = False,
248+
tls_min_version: ssl.TLSVersion = ssl.TLSVersion.MINIMUM_SUPPORTED,
249+
tls_max_version: ssl.TLSVersion = ssl.TLSVersion.MAXIMUM_SUPPORTED
243250
) -> Tuple[WSGIServer, threading.Thread]:
244251
"""Starts a WSGI server for prometheus metrics as a daemon thread."""
245252

@@ -250,7 +257,16 @@ class TmpServer(ThreadingWSGIServer):
250257
app = make_wsgi_app(registry)
251258
httpd = make_server(addr, port, app, TmpServer, handler_class=_SilentHandler)
252259
if certfile and keyfile:
253-
context = _get_ssl_ctx(certfile, keyfile, protocol, client_cafile, client_capath, client_auth_required)
260+
context = _get_ssl_ctx(
261+
certfile,
262+
keyfile,
263+
protocol,
264+
client_cafile,
265+
client_capath,
266+
client_auth_required,
267+
tls_min_version,
268+
tls_max_version
269+
)
254270
httpd.socket = context.wrap_socket(httpd.socket, server_side=True)
255271
t = threading.Thread(target=httpd.serve_forever)
256272
t.daemon = True

tests/certs/client-cert.pem

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIICrzCCAZcCFCVu7nbOAxRNKBYa2cl22rdRCtvfMA0GCSqGSIb3DQEBCwUAMBIx
3+
EDAOBgNVBAMMB1Rlc3QgQ0EwHhcNMjYwNTI2MTQyMTU0WhcNMzYwNTIzMTQyMTU0
4+
WjAWMRQwEgYDVQQDDAt0ZXN0LWNsaWVudDCCASIwDQYJKoZIhvcNAQEBBQADggEP
5+
ADCCAQoCggEBAJM2/f+8BBKjAlSF/9eiuB2444A2g6V007U5shZhBuPC9cNDxGKM
6+
W1WT3QsgvxOdagdaANkpufqHcYixgFhx/v3lSEzlzd3uXyFMOiK7BdiPsctkqlWZ
7+
VGIuUPpWwvJHWS4R5V1nYNCVsgyZB9XGThl7IknQzBK+tkY2GepqPQXyx1/AP7aB
8+
AlTVBx3r7jTWvkrzvAdrcevrjhOOJUbPmgoiiEGSQeZSMvkdLERujvu5Y3wno2Mg
9+
vcHJxCJwZ5y0RakmTzyAZLHke9lMavgt9F5yEA8G/8SnnXy6HrUp6B6I8Z1eLnof
10+
b3mjUwiGxqDwEVBQHfMtOH6uC7ZE6zbNB1cCAwEAATANBgkqhkiG9w0BAQsFAAOC
11+
AQEAJBchyhT2iyg42qi3uUE1NeCcEb/gM82LeihZbDd38ItUdU7TFqk7wEwsUNJk
12+
k1uwNFVlyMGbHD1IvCAS4L8l/9uPaDG4DmLZ42shFRCaABNEFlKtGPa+YNuhFJ5z
13+
DZKaLaJp8BKpvmoH+iPmsoCDlADwWmLgbdeFBGnHRuOnJBSmEEjQFrnz3jKrX6Lk
14+
+IxVX5Rdp9xOKHBJkj99mgseEYZQk2YFFBCzHX7NNl6wBk/usKJoJeaOPhl9eOGK
15+
VaUOfEdO5NuTRf9nPOORzqFtW3ErNjNjPjKN8VppHtXhRO6dWsmzGnmjVChxoZWC
16+
H0rRJtGcab5HWf94laJilCj7Cw==
17+
-----END CERTIFICATE-----

tests/certs/client-key.pem

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
-----BEGIN PRIVATE KEY-----
2+
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCTNv3/vAQSowJU
3+
hf/XorgduOOANoOldNO1ObIWYQbjwvXDQ8RijFtVk90LIL8TnWoHWgDZKbn6h3GI
4+
sYBYcf795UhM5c3d7l8hTDoiuwXYj7HLZKpVmVRiLlD6VsLyR1kuEeVdZ2DQlbIM
5+
mQfVxk4ZeyJJ0MwSvrZGNhnqaj0F8sdfwD+2gQJU1Qcd6+401r5K87wHa3Hr644T
6+
jiVGz5oKIohBkkHmUjL5HSxEbo77uWN8J6NjIL3BycQicGectEWpJk88gGSx5HvZ
7+
TGr4LfRechAPBv/Ep518uh61KegeiPGdXi56H295o1MIhsag8BFQUB3zLTh+rgu2
8+
ROs2zQdXAgMBAAECggEAATafUlJzkCRtelKJFiG+YGmr37HTVPOeY8HVe29noKH0
9+
kkbxNpoPOKiEK7l53wiu8oo7M+RZpucjOEFfnEWtmIchbkIoomR6vpSubVHa+FAl
10+
jYEcvEw2u1ZuuW7Uotg+s8KsVXWVgTKdVJLq/cfpezaeGjtRK0hiH+MF71OFLD2I
11+
UoszlVbTI9FAP+xwuFSJO4xyOirz2VmqgYvQd+qTuuPU2ZjPHFbBUXm6JDpchGJk
12+
WdPp/7qEWKFwDufvgkA5rCFxwsiReQ9HfOS2f4l+7eg2uyjXAClYTt/lYq9PK1Ut
13+
sk/R1Gq5C4S8G0f04Jk8J2bQKS57oRALfaJEps5LUQKBgQDPCPID4w9TnAhWoHtR
14+
L5ps02KLi52sw9F3EVedVX2BjMM/jvRwtzg8I8iaWAE1iL0t8lDQRxbUcgNyWRvi
15+
0/WG/2IESVlciqd4XuITLthj1PDIpIM2iCjQZpZKDqe9bVRPx/AY+UNV1aLSCEbF
16+
xGS+uYoQRGpmiSYnRaQzIzgn0QKBgQC2CDOD1/1sEVFbfsWJTaAM3YjsQ1I5mXFI
17+
HhoWpMKBUogWBXp9dzO4Ae/iRo0QviVUUY2bHlJjCoaQ0FzuiieZIhbOwHG2Qtf3
18+
JzmUaOSMecwsTeM05XHciwY+sWU/Udw7EzDhVpOHPZR31LKeapchUJGnofnOdkcY
19+
zaHEwiuupwKBgQC6I0bD698Zws1UZRC6G1xxv1N4NtxaOewXawYktHoUgaQBftuS
20+
g4gRufJfogPkR74ekx/JQkDqXF9w7WC+/OZgqzdKt0+afia3eEc2DAYNK6QYIKC/
21+
5IcdZz5z8t0o2CTXXeEl8uVxRJQQ1dQbdslFGLdijMBE08XzxQ8t0tpoIQKBgH09
22+
U0QovME3gQQ0SnBXKgDwAp6bCt16RshZfZWKshAL2nlcN5RPCRRWsNa7t56HVGOY
23+
4JaS3BgsS70ivm2YO/pNy+df3FyLzM7M+/6x1F0aB3GL/QCNxDL6q8dCgeh4x88V
24+
OxIuYL4xjg6MFoCL0YMoTa5J8PctxWi5Qc1/0lINAoGASyTZT8emfSDW0+kpqiYw
25+
y+4ftFxqYPAVCf2IWGeQL8TrfkxUiJ7r4Pu5VK9nuYvMR/u4mvnJSG6F1NuJhxzY
26+
4kUnoOnPhITLZjUvNE/xQEuhiJndiehZgSj0JAU6MqGa4pZOxZfqPAfhEF62b5wx
27+
6Wlh7JxQAM+6agEfM3/OS3Y=
28+
-----END PRIVATE KEY-----

tests/certs/server-ca.pem

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIDBTCCAe2gAwIBAgIUMrjGc/qUt+rpFb14OvBFePSMQRIwDQYJKoZIhvcNAQEL
3+
BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAeFw0yNjA1MjYxNDIxNTNaFw0zNjA1MjMx
4+
NDIxNTNaMBIxEDAOBgNVBAMMB1Rlc3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IB
5+
DwAwggEKAoIBAQDFC2wPWOqoFHIYXASjL06yUnG0SlqLqw4oZphdj/q4pbyYPcva
6+
QKI8m4u7Tq/l8JQmbd0sHqGMVYLmACX5ygkppzepz/bVgDeij7RztUgDjJwvUxAC
7+
SEAss0dcE19P57j5ad24xmyV2iP0RK7oXnjapDrH1fhqvIyfybqRxt+50NODRh1t
8+
z471240lDBPOG3ReRZ06dYEpzYaq3PQPatPJnaLGOmsf2NQ8sETTK35vcTMZrXsr
9+
vzrftUCKn4DRyyZ58GE1VpevbVi8z/vHzWBYpRcHTZvfnOz12ijCd2wvnEtTu8TO
10+
+GZS5j84KSF4AI7FlhDMPAS3/dhSLzXgnd4lAgMBAAGjUzBRMB0GA1UdDgQWBBRi
11+
IztvE2ErRLmziv1XxxHCbism8DAfBgNVHSMEGDAWgBRiIztvE2ErRLmziv1XxxHC
12+
bism8DAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAjBA50Oadg
13+
Fx6d/cxzHCEd29BluqxjfzYc4TAeTP4NSQPWKXM7BgIqZbHDS/IAK/Xfd1raVCm5
14+
yv2v4Pe+0fTkezUk5uZjtgZoH5+o4aQL9GdbLO93F4rxzZhpoY92iaXAsoDEntRO
15+
YyDnxLna6csiH4hyvr6Q8Yih/lDysw7DB1jozkFeZtX4ZsVFpsDnYLa5OQjJErpw
16+
9GCM0NEzEW6HlqblsAuBv3DHavUAzfR4obD+Md60BRMxwC5Otl63sS99y81ycs2S
17+
ffW0rLDtgB9hShCXBNeZkGsPrLwBr00nK7bvGaZwOU0Ysuxg+elP3cOXD2UcW7lc
18+
Q+ZBinkQEFpB
19+
-----END CERTIFICATE-----

tests/certs/server-cert.pem

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIDEjCCAfqgAwIBAgIUJW7uds4DFE0oFhrZyXbat1EK294wDQYJKoZIhvcNAQEL
3+
BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAeFw0yNjA1MjYxNDIxNTNaFw0zNjA1MjMx
4+
NDIxNTNaMBQxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQAD
5+
ggEPADCCAQoCggEBAOl3Gnz9y+OHr3MIetuX7a/Bvo/lYkwTnmQpT4YC1ycalM0+
6+
M4wCewrbpn5RoNbH4j+oB6URuiLWlhk3SP9hOwbVbt4rOyCaulAVa5G0B46eqkG6
7+
ZDi9EWkt+L7Zvfwe+MbdG25xmRumkvc6iv8b+/0mM3t5cm3E8BHpwPi6kfoFmFHn
8+
qREDfI4406tBkbSYUkRQL8qZvSWMo5HgIYmgrkKiWuZNV4bNYKHUOyaOqWvgn8En
9+
ZxrlGt2ezHif/SFz+EaYJZkjBDJ5rMbwxl1BAVZKpSubKt5U59zXLkuachZF5sAY
10+
sEd/LoZxF23/qP5y16C4mVzBYO/0z2udNOW9YAcCAwEAAaNeMFwwGgYDVR0RBBMw
11+
EYIJbG9jYWxob3N0hwR/AAABMB0GA1UdDgQWBBSUEOHINPcDxtBsfNF5xSTUSqfF
12+
vDAfBgNVHSMEGDAWgBRiIztvE2ErRLmziv1XxxHCbism8DANBgkqhkiG9w0BAQsF
13+
AAOCAQEALxRf0TSusmJXO9pj5t3Njxc6VS+Ts/MnmE1NTloCCkVMEfYYzqROWHME
14+
LOCg2YSnqX6S6Gwk3zjBSuT7aA4SNQ3lD9HndRYa5k+6/6qunnz5Q/g205GJ97us
15+
HqkvdDjLE7lGmM5pIVjoyeMOWiQ6+EOtMt0CmL0nfqJ0DsDUZHVB7NB+MW20EVmC
16+
XiXr52SuvKHDIms3QFkZWOi+scOKleQnvEVU7VqrQamKNtf8fxxGa3/AvjLLJ1ra
17+
q9eB590eajBDdg50FttYLwyA/yb6cqrfIMfrHRj3R//yE2avtUkrKN6FgCtqgpoa
18+
ZsIk6qEmFQWUTglyLwhk0f6m21FKAA==
19+
-----END CERTIFICATE-----

tests/certs/server-key.pem

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
-----BEGIN PRIVATE KEY-----
2+
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDpdxp8/cvjh69z
3+
CHrbl+2vwb6P5WJME55kKU+GAtcnGpTNPjOMAnsK26Z+UaDWx+I/qAelEboi1pYZ
4+
N0j/YTsG1W7eKzsgmrpQFWuRtAeOnqpBumQ4vRFpLfi+2b38HvjG3RtucZkbppL3
5+
Oor/G/v9JjN7eXJtxPAR6cD4upH6BZhR56kRA3yOONOrQZG0mFJEUC/Kmb0ljKOR
6+
4CGJoK5ColrmTVeGzWCh1Dsmjqlr4J/BJ2ca5Rrdnsx4n/0hc/hGmCWZIwQyeazG
7+
8MZdQQFWSqUrmyreVOfc1y5LmnIWRebAGLBHfy6GcRdt/6j+cteguJlcwWDv9M9r
8+
nTTlvWAHAgMBAAECggEAJ2/ZlxyOGPC+J+naSwbWfTZ2mLsQSDaWLmg2CTaonm/k
9+
i+kCbxeqLjLdZIAoca+RHdyl8fHVJfZmo3rNx2nmvShHkprt4XuRll6P7axiDGrr
10+
6q9wJ490hfZgiuigKZsXvgvyis0ApoWUVNPcT+yru978mlJxDG7UeMoqMTne18NQ
11+
jKw8zTPrcDnSqxdzNs9hGcM/RYDAnNM1jFqnmJpJF9nTMf9gDOYQMJCb7yUZVOj/
12+
ccyc2AjTdp6corXZpSqiYHz4UwfZ0Wvf7BXwBAOxdYnM6qlZXc+RKZJYnlUbSNHZ
13+
IRkIZXsRILAIgpL1fAhMAQodyFMjNU9wQAkva6j49QKBgQD8ohxWR3nKg9KXhSTU
14+
7sv1E5WzUCEAX5gJTSRx9S8lAAotGEByaTO/pWcYtpo+jXukukERhDdnsxR7SJAf
15+
7jOYLUQgqFgZXD/U7vaCNuYoRG0E1MwSqZnVIXOpZW2z6j0PwcbXLJVeLDpDctn1
16+
Ga7VvYiv7/KuvRSQfkSOrH8USwKBgQDsk5lLSOQb7Ke53gfHjeGMU4646JcNDFnD
17+
hWtXQujABwQZmSDWudCvsLWwDr0O0kUDqDcPCEMhbNYo388DwowzHnE35Tzmzo5D
18+
R/YZ+Mh+UuW+e5gLxdmn7Z1xENKft/4ceOkeBBExQumZYYsaNVA7znzotaPSjRfH
19+
J36QHsG1tQKBgQC9NMBaUf/CD4ZaWqpiG1J/gyJ8AEgnGnEojjD8dC/R2zzD10T1
20+
KxtJrhwPozrUHGx8y83Ny6MfNDzjtE3UzDayAzzh5JLOs4tO84WFso4fnFe15ZXN
21+
aF5BBGO2e7N0qrr+oRdFsitQM3mTaGIashiCFghYFDJCcnQDX74CyOgIDwKBgCht
22+
JHHf99LpwtOZJF0uWo9/K9FfNYiuRpyJrQkRTvKZgFLbfugSgp2zJaj7K8Vfmxl/
23+
4kC4WbhZf9MmQ5rR4OFPX2t8ycZrH5ZRsrVHdQNZKRc+yYGhgosWqKPMiyFt8Idv
24+
Be7yJPn1BDQInhuRZq+BnoipmV/+akTG8/Kuvs1NAoGALLN5lPRdZdTvjoiougt9
25+
MxqGfBR9H8PfAo/Eu8Et5Otln3P1Vl3SgeiwDGVb59avfBQ5N4UecTHMp/2jbxOw
26+
w/AzvF9LMLtXKdyqnOeBfP2xgbEZ9chLeoePEYkATpQfgjs7qmzK+mwZin5EyjFa
27+
tqn7AnX5AnDRtPIC10Z05rA=
28+
-----END PRIVATE KEY-----

tests/test_exposition.py

Lines changed: 145 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import gzip
22
from http.server import BaseHTTPRequestHandler, HTTPServer
33
import os
4+
import ssl
45
import threading
56
import time
67
import unittest
8+
import urllib
79

810
import pytest
911

@@ -16,7 +18,7 @@
1618
from prometheus_client.core import GaugeHistogramMetricFamily, Timestamp
1719
from prometheus_client.exposition import (
1820
basic_auth_handler, choose_encoder, default_handler, MetricsHandler,
19-
passthrough_redirect_handler, tls_auth_handler,
21+
passthrough_redirect_handler, start_wsgi_server, tls_auth_handler,
2022
)
2123
import prometheus_client.openmetrics.exposition as openmetrics
2224

@@ -633,6 +635,148 @@ def test_prom_no_version(self):
633635
self.assert_is_prom(exp)
634636

635637

638+
class TestWsgiTLS(unittest.TestCase):
639+
def setUp(self):
640+
self.certs_dir = os.path.join(
641+
os.path.dirname(os.path.realpath(__file__)), 'certs'
642+
)
643+
self.httpd = None
644+
self.t = None
645+
646+
def tearDown(self):
647+
if self.httpd:
648+
self.httpd.shutdown()
649+
self.httpd.server_close()
650+
self.t.join()
651+
652+
def _assert_tls_connection(
653+
self,
654+
server_kwargs,
655+
use_server_tls=True,
656+
client_tls_kwargs=None,
657+
request_tls_version=ssl.TLSVersion.TLSv1_3,
658+
expect_exception=None
659+
):
660+
self.httpd, self.t = start_wsgi_server(port=0, **server_kwargs)
661+
port = self.httpd.server_address[1]
662+
663+
if use_server_tls:
664+
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
665+
ctx.minimum_version = request_tls_version
666+
ctx.maximum_version = request_tls_version
667+
ctx.load_verify_locations(
668+
os.path.join(self.certs_dir, "server-ca.pem")
669+
)
670+
671+
if client_tls_kwargs is not None:
672+
ctx.load_cert_chain(**client_tls_kwargs)
673+
674+
url = f"https://localhost:{port}/metrics"
675+
else:
676+
ctx = None
677+
url = f"http://localhost:{port}/metrics"
678+
679+
if expect_exception is not None:
680+
self.assertRaises(
681+
expect_exception,
682+
urllib.request.urlopen,
683+
url,
684+
context=ctx
685+
)
686+
else:
687+
response = urllib.request.urlopen(url, context=ctx)
688+
self.assertEqual(response.status, 200)
689+
690+
def test_tls_disabled(self):
691+
self._assert_tls_connection(server_kwargs={}, use_server_tls=False)
692+
693+
def test_tls_enabled(self):
694+
server_kwargs = {
695+
"certfile": os.path.join(self.certs_dir, "server-cert.pem"),
696+
"keyfile": os.path.join(self.certs_dir, "server-key.pem"),
697+
}
698+
self._assert_tls_connection(server_kwargs)
699+
700+
def test_tls_untrusted_server_cert_raises(self):
701+
server_kwargs = {
702+
"certfile": os.path.join(self.certs_dir, "cert.pem"),
703+
"keyfile": os.path.join(self.certs_dir, "key.pem"),
704+
}
705+
self._assert_tls_connection(
706+
server_kwargs,
707+
expect_exception=urllib.error.URLError
708+
)
709+
710+
def test_tls_versions_configured_correctly(self):
711+
server_kwargs = {
712+
"certfile": os.path.join(self.certs_dir, "server-cert.pem"),
713+
"keyfile": os.path.join(self.certs_dir, "server-key.pem"),
714+
"tls_min_version": ssl.TLSVersion.TLSv1_2,
715+
"tls_max_version": ssl.TLSVersion.TLSv1_3,
716+
}
717+
self._assert_tls_connection(
718+
server_kwargs,
719+
request_tls_version=ssl.TLSVersion.TLSv1_2
720+
)
721+
722+
def test_tls_using_lower_version_than_min_raises(self):
723+
server_kwargs = {
724+
"certfile": os.path.join(self.certs_dir, "server-cert.pem"),
725+
"keyfile": os.path.join(self.certs_dir, "server-key.pem"),
726+
"tls_min_version": ssl.TLSVersion.TLSv1_3,
727+
}
728+
self._assert_tls_connection(
729+
server_kwargs,
730+
request_tls_version=ssl.TLSVersion.TLSv1_2,
731+
expect_exception=urllib.error.URLError
732+
)
733+
734+
def test_tls_using_higher_version_than_max_raises(self):
735+
server_kwargs = {
736+
"certfile": os.path.join(self.certs_dir, "server-cert.pem"),
737+
"keyfile": os.path.join(self.certs_dir, "server-key.pem"),
738+
"tls_max_version": ssl.TLSVersion.TLSv1_2,
739+
}
740+
self._assert_tls_connection(
741+
server_kwargs,
742+
request_tls_version=ssl.TLSVersion.TLSv1_3,
743+
expect_exception=urllib.error.URLError
744+
)
745+
746+
def test_mtls_enabled(self):
747+
server_kwargs = {
748+
"certfile": os.path.join(self.certs_dir, "server-cert.pem"),
749+
"keyfile": os.path.join(self.certs_dir, "server-key.pem"),
750+
"client_auth_required": True,
751+
"client_cafile": os.path.join(self.certs_dir, "server-ca.pem"),
752+
}
753+
client_tls_kwargs = {
754+
"certfile": os.path.join(self.certs_dir, "client-cert.pem"),
755+
"keyfile": os.path.join(self.certs_dir, "client-key.pem")
756+
}
757+
self._assert_tls_connection(
758+
server_kwargs,
759+
client_tls_kwargs=client_tls_kwargs
760+
)
761+
762+
def test_mtls_untrusted_client_cert_raises(self):
763+
server_kwargs = {
764+
"certfile": os.path.join(self.certs_dir, "server-cert.pem"),
765+
"keyfile": os.path.join(self.certs_dir, "server-key.pem"),
766+
"client_auth_required": True,
767+
"client_cafile": os.path.join(self.certs_dir, "server-cert.pem"),
768+
}
769+
client_tls_kwargs = {
770+
"certfile": os.path.join(self.certs_dir, "cert.pem"),
771+
"keyfile": os.path.join(self.certs_dir, "key.pem")
772+
}
773+
self._assert_tls_connection(
774+
server_kwargs,
775+
client_tls_kwargs=client_tls_kwargs,
776+
expect_exception=ssl.SSLError
777+
)
778+
779+
636780
@pytest.mark.parametrize("scenario", [
637781
{
638782
"name": "empty string",

0 commit comments

Comments
 (0)