Skip to content

Commit 8239129

Browse files
dpetzoldDerrick Petzoldgi0baro
authored
Add TLSv1.2 protocol support (#665)
--------- Co-authored-by: Derrick Petzold <derrick.petzold@collecticevoice.com> Co-authored-by: Giovanni Barillari <giovanni.barillari@sentry.io>
1 parent 955b1ed commit 8239129

16 files changed

Lines changed: 106 additions & 14 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ rustls-pemfile = "2.2"
5353
socket2 = { version = "=0.6", features = ["all"] }
5454
sysinfo = "=0.36"
5555
tikv-jemallocator = { version = "0.6.0", default-features = false, features = ["disable_initial_exec_tls"], optional = true }
56-
tls-listener = { version = "=0.11", features = ["rustls-ring"] }
56+
tls-listener = { version = "=0.11", git = "https://github.com/gi0baro/tls-listener.git", branch = "0.11.x", features = ["rustls-ring", "rustls-tls12"] }
5757
tokio = { version = "1.45", features = ["full"] }
5858
tokio-stream = "0.1"
5959
tokio-tungstenite = "=0.28"

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,13 +268,21 @@ Options:
268268
--ssl-keyfile FILE SSL key file [env var: GRANIAN_SSL_KEYFILE]
269269
--ssl-keyfile-password TEXT SSL key password [env var:
270270
GRANIAN_SSL_KEYFILE_PASSWORD]
271+
--ssl-protocol-min [tls1.2|tls1.3]
272+
Set the minimum supported protocol for SSL
273+
connections. [env var:
274+
GRANIAN_SSL_PROTOCOL_MIN; default: (tls1.3)]
271275
--ssl-ca FILE Root SSL cerificate file for client
272276
verification [env var: GRANIAN_SSL_CA]
273277
--ssl-crl FILE SSL CRL file(s) [env var: GRANIAN_SSL_CRL]
274278
--ssl-client-verify / --no-ssl-client-verify
275279
Verify clients SSL certificates [env var:
276280
GRANIAN_SSL_CLIENT_VERIFY; default:
277281
(disabled)]
282+
--ssl-protocol-version [auto|1.2|1.3]
283+
Override the supported ssl protocol versions
284+
and pin to the one specified. [env var:
285+
GRANIAN_SSL_PROTOCOL_VERSION; default: auto]
278286
--url-path-prefix TEXT URL path prefix the app is mounted on [env
279287
var: GRANIAN_URL_PATH_PREFIX]
280288
--respawn-failed-workers / --no-respawn-failed-workers

granian/_granian.pyi

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ class ASGIWorker:
7272
ssl_enabled: bool,
7373
ssl_cert: Optional[str],
7474
ssl_key: Optional[str],
75+
ssl_key_password: Optional[str],
76+
ssl_protocol_min: str,
7577
ssl_ca: Optional[str],
7678
ssl_crl: List[str],
7779
ssl_client_verify: bool,
@@ -94,6 +96,8 @@ class WSGIWorker:
9496
ssl_enabled: bool,
9597
ssl_cert: Optional[str],
9698
ssl_key: Optional[str],
99+
ssl_key_password: Optional[str],
100+
ssl_protocol_min: str,
97101
ssl_ca: Optional[str],
98102
ssl_crl: List[str],
99103
ssl_client_verify: bool,
@@ -117,6 +121,8 @@ class RSGIWorker:
117121
ssl_enabled: bool,
118122
ssl_cert: Optional[str],
119123
ssl_key: Optional[str],
124+
ssl_key_password: Optional[str],
125+
ssl_protocol_min: str,
120126
ssl_ca: Optional[str],
121127
ssl_crl: List[str],
122128
ssl_client_verify: bool,

granian/_types.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ class WebsocketMessage:
66
data: Union[bytes, str]
77

88

9-
SSLCtx = Tuple[bool, Optional[str], Optional[str], Optional[str], Optional[str], List[str], bool]
9+
SSLCtx = Tuple[bool, Optional[str], Optional[str], Optional[str], str, Optional[str], List[str], bool]

granian/cli.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
import click
88

9-
from .constants import HTTPModes, Interfaces, Loops, RuntimeModes, TaskImpl
9+
from .constants import HTTPModes, Interfaces, Loops, RuntimeModes, SSLProtocols, TaskImpl
1010
from .errors import FatalError
1111
from .http import HTTP1Settings, HTTP2Settings
1212
from .log import LogLevels
@@ -266,6 +266,12 @@ def option(*param_decls: str, cls: Optional[Type[click.Option]] = None, **attrs:
266266
help='SSL key file',
267267
)
268268
@option('--ssl-keyfile-password', help='SSL key password')
269+
@option(
270+
'--ssl-protocol-min',
271+
type=EnumType(SSLProtocols),
272+
default=SSLProtocols.tls13,
273+
help='Set the minimum supported protocol for SSL connections.',
274+
)
269275
@option(
270276
'--ssl-ca',
271277
type=click.Path(exists=True, file_okay=True, dir_okay=False, readable=True, path_type=pathlib.Path),
@@ -442,6 +448,7 @@ def cli(
442448
ssl_certificate: Optional[pathlib.Path],
443449
ssl_keyfile: Optional[pathlib.Path],
444450
ssl_keyfile_password: Optional[str],
451+
ssl_protocol_min: SSLProtocols,
445452
ssl_ca: Optional[pathlib.Path],
446453
ssl_crl: Optional[List[pathlib.Path]],
447454
ssl_client_verify: bool,
@@ -525,6 +532,7 @@ def cli(
525532
ssl_cert=ssl_certificate,
526533
ssl_key=ssl_keyfile,
527534
ssl_key_password=ssl_keyfile_password,
535+
ssl_protocol_min=ssl_protocol_min,
528536
ssl_ca=ssl_ca,
529537
ssl_crl=ssl_crl,
530538
ssl_client_verify=ssl_client_verify,

granian/constants.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,8 @@ class Loops(StrEnum):
3535
class TaskImpl(StrEnum):
3636
asyncio = 'asyncio'
3737
rust = 'rust'
38+
39+
40+
class SSLProtocols(StrEnum):
41+
tls12 = 'tls1.2'
42+
tls13 = 'tls1.3'

granian/server/common.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from .._imports import dotenv, setproctitle, watchfiles
1616
from .._internal import build_env_loader, load_target
1717
from .._signals import set_main_signals
18-
from ..constants import HTTPModes, Interfaces, Loops, RuntimeModes, TaskImpl
18+
from ..constants import HTTPModes, Interfaces, Loops, RuntimeModes, SSLProtocols, TaskImpl
1919
from ..errors import ConfigurationError, PidFileError
2020
from ..http import HTTP1Settings, HTTP2Settings
2121
from ..log import DEFAULT_ACCESSLOG_FMT, LogLevels, configure_logging, logger
@@ -108,6 +108,7 @@ def __init__(
108108
ssl_cert: Optional[Path] = None,
109109
ssl_key: Optional[Path] = None,
110110
ssl_key_password: Optional[str] = None,
111+
ssl_protocol_min: SSLProtocols = SSLProtocols.tls13,
111112
ssl_ca: Optional[Path] = None,
112113
ssl_crl: Optional[List[Path]] = None,
113114
ssl_client_verify: bool = False,
@@ -200,7 +201,9 @@ def __init__(
200201

201202
configure_logging(self.log_level, self.log_config, self.log_enabled)
202203

203-
self.build_ssl_context(ssl_cert, ssl_key, ssl_key_password, ssl_ca, ssl_crl or [], ssl_client_verify)
204+
self.build_ssl_context(
205+
ssl_cert, ssl_key, ssl_key_password, ssl_protocol_min, ssl_ca, ssl_crl or [], ssl_client_verify
206+
)
204207
self._ssp = None
205208
self._shd = None
206209
self._sfd = None
@@ -220,12 +223,13 @@ def build_ssl_context(
220223
cert: Optional[Path],
221224
key: Optional[Path],
222225
password: Optional[str],
226+
proto: SSLProtocols,
223227
ca: Optional[Path],
224228
crl: List[Path],
225229
client_verify: bool,
226230
):
227231
if not (cert and key):
228-
self.ssl_ctx = (False, None, None, None, None, [], False)
232+
self.ssl_ctx = (False, None, None, None, str(proto), None, [], False)
229233
return
230234
# uneeded?
231235
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
@@ -239,6 +243,7 @@ def build_ssl_context(
239243
str(cert.resolve()),
240244
str(key.resolve()),
241245
password,
246+
str(proto),
242247
str(ca.resolve()) if ca else None,
243248
[str(item.resolve()) for item in crl],
244249
client_verify,

granian/server/embed.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
HTTPModes,
2525
Interfaces,
2626
LogLevels,
27+
SSLProtocols,
2728
TaskImpl,
2829
logger,
2930
)
@@ -116,6 +117,7 @@ def __init__(
116117
ssl_cert: Optional[Path] = None,
117118
ssl_key: Optional[Path] = None,
118119
ssl_key_password: Optional[str] = None,
120+
ssl_protocol_min: SSLProtocols = SSLProtocols.tls13,
119121
ssl_ca: Optional[Path] = None,
120122
ssl_crl: Optional[List[Path]] = None,
121123
ssl_client_verify: bool = False,
@@ -150,6 +152,7 @@ def __init__(
150152
ssl_cert=ssl_cert,
151153
ssl_key=ssl_key,
152154
ssl_key_password=ssl_key_password,
155+
ssl_protocol_min=ssl_protocol_min,
153156
ssl_ca=ssl_ca,
154157
ssl_crl=ssl_crl,
155158
ssl_client_verify=ssl_client_verify,

src/asgi/serve.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ impl ASGIWorker {
3333
ssl_cert=None,
3434
ssl_key=None,
3535
ssl_key_password=None,
36+
ssl_protocol_min="1.3",
3637
ssl_ca=None,
3738
ssl_crl=vec![],
3839
ssl_client_verify=false,
@@ -56,6 +57,7 @@ impl ASGIWorker {
5657
ssl_cert: Option<String>,
5758
ssl_key: Option<String>,
5859
ssl_key_password: Option<String>,
60+
ssl_protocol_min: &str,
5961
ssl_ca: Option<String>,
6062
ssl_crl: Vec<String>,
6163
ssl_client_verify: bool,
@@ -78,6 +80,7 @@ impl ASGIWorker {
7880
ssl_cert,
7981
ssl_key,
8082
ssl_key_password,
83+
ssl_protocol_min,
8184
ssl_ca,
8285
ssl_crl,
8386
ssl_client_verify,

0 commit comments

Comments
 (0)