From 7cd6579fae659e54ab208ad766a6c8254ff9dace Mon Sep 17 00:00:00 2001 From: Ahmed TAHRI Date: Sun, 26 May 2024 07:58:18 +0200 Subject: [PATCH] improve support --ssl=[...] setting --- extras/profiling/benchmarks.py | 4 ++-- httpie/ssl_.py | 27 ++++++++++++++++++++++++++- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/extras/profiling/benchmarks.py b/extras/profiling/benchmarks.py index 04ea37a203..c262d46977 100644 --- a/extras/profiling/benchmarks.py +++ b/extras/profiling/benchmarks.py @@ -175,11 +175,11 @@ def run(self, context: Context) -> pyperf.Benchmark: for pretty in ['all', 'none']: CommandRunner( 'startup', - f'`http --pretty={pretty} httpbin.local:8888/stream/1000`', + f'`http --pretty={pretty} pie.dev/stream/1000`', [ '--print=HBhb', f'--pretty={pretty}', - 'httpbin.local:8888/stream/1000' + 'pie.dev/stream/1000' ] ) DownloadRunner('download', '`http --download :/big_file.txt` (3GB)', '3G') diff --git a/httpie/ssl_.py b/httpie/ssl_.py index 888be5540d..9dbd27005f 100644 --- a/httpie/ssl_.py +++ b/httpie/ssl_.py @@ -14,7 +14,7 @@ 'tls1': 'PROTOCOL_TLSv1', 'tls1.1': 'PROTOCOL_TLSv1_1', 'tls1.2': 'PROTOCOL_TLSv1_2', - 'tls1.3': 'PROTOCOL_TLSv1_3', + 'tls1.3': 'PROTOCOL_TLS_CLIENT', # CPython does not have a "PROTOCOL_TLSv1_3" constant, so, we'll improvise. } # todo: we'll need to update this in preparation for Python 3.13+ # could be a removal (after a long deprecation about constants @@ -104,6 +104,18 @@ def __init__( self._verify = None if ssl_version or ciphers: + # By default, almost all installed CPython have modern OpenSSL backends + # This actively prevent folks to negotiate "almost" dead TLS protocols + # HTTPie wants to help users when they explicitly expect "old" TLS support + # Common errors for user if not set: + # >- [SSL: NO_CIPHERS_AVAILABLE] no ciphers available + # >- [SSL: LEGACY_SIGALG_DISALLOWED_OR_UNSUPPORTED] legacy sigalg disallowed or unsupported + if ssl_version in {ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1_1} and ciphers is None: + # Please do not raise a "security" concern for that line. + # If the interpreter reach that line, it means that the user willingly set + # an unsafe TLS protocol. + ciphers = "DEFAULT:@SECLEVEL=0" + # Only set the custom context if user supplied one. # Because urllib3-future set his own secure ctx with a set of # ciphers (moz recommended list). thus avoiding excluding QUIC @@ -142,6 +154,19 @@ def _create_ssl_context( ssl_version: str = None, ciphers: str = None, ) -> 'ssl.SSLContext': + # HTTPie will take `ssl.PROTOCOL_TLS_CLIENT` as TLS 1.3 enforced! + # This piece of code is only triggered if user supplied --ssl=tls1.3 + if ssl_version is ssl.PROTOCOL_TLS_CLIENT: + return create_urllib3_context( + ciphers=ciphers, + ssl_minimum_version=ssl.TLSVersion.TLSv1_3, + ssl_maximum_version=ssl.TLSVersion.TLSv1_3, + # Since we are using a custom SSL context, we need to pass this + # here manually, even though it’s also passed to the connection + # in `super().cert_verify()`. + cert_reqs=ssl.CERT_REQUIRED if verify else ssl.CERT_NONE + ) + return create_urllib3_context( ciphers=ciphers, ssl_version=resolve_ssl_version(ssl_version),