|
14 | 14 | 'tls1': 'PROTOCOL_TLSv1',
|
15 | 15 | 'tls1.1': 'PROTOCOL_TLSv1_1',
|
16 | 16 | 'tls1.2': 'PROTOCOL_TLSv1_2',
|
17 |
| - 'tls1.3': 'PROTOCOL_TLSv1_3', |
| 17 | + 'tls1.3': 'PROTOCOL_TLS_CLIENT', # CPython does not have a "PROTOCOL_TLSv1_3" constant, so, we'll improvise. |
18 | 18 | }
|
19 | 19 | # todo: we'll need to update this in preparation for Python 3.13+
|
20 | 20 | # could be a removal (after a long deprecation about constants
|
@@ -104,6 +104,18 @@ def __init__(
|
104 | 104 | self._verify = None
|
105 | 105 |
|
106 | 106 | if ssl_version or ciphers:
|
| 107 | + # By default, almost all installed CPython have modern OpenSSL backends |
| 108 | + # This actively prevent folks to negotiate "almost" dead TLS protocols |
| 109 | + # HTTPie wants to help users when they explicitly expect "old" TLS support |
| 110 | + # Common errors for user if not set: |
| 111 | + # >- [SSL: NO_CIPHERS_AVAILABLE] no ciphers available |
| 112 | + # >- [SSL: LEGACY_SIGALG_DISALLOWED_OR_UNSUPPORTED] legacy sigalg disallowed or unsupported |
| 113 | + if ssl_version in {ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1_1} and ciphers is None: |
| 114 | + # Please do not raise a "security" concern for that line. |
| 115 | + # If the interpreter reach that line, it means that the user willingly set |
| 116 | + # an unsafe TLS protocol. |
| 117 | + ciphers = "DEFAULT:@SECLEVEL=0" |
| 118 | + |
107 | 119 | # Only set the custom context if user supplied one.
|
108 | 120 | # Because urllib3-future set his own secure ctx with a set of
|
109 | 121 | # ciphers (moz recommended list). thus avoiding excluding QUIC
|
@@ -142,6 +154,19 @@ def _create_ssl_context(
|
142 | 154 | ssl_version: str = None,
|
143 | 155 | ciphers: str = None,
|
144 | 156 | ) -> 'ssl.SSLContext':
|
| 157 | + # HTTPie will take `ssl.PROTOCOL_TLS_CLIENT` as TLS 1.3 enforced! |
| 158 | + # This piece of code is only triggered if user supplied --ssl=tls1.3 |
| 159 | + if ssl_version is ssl.PROTOCOL_TLS_CLIENT: |
| 160 | + return create_urllib3_context( |
| 161 | + ciphers=ciphers, |
| 162 | + ssl_minimum_version=ssl.TLSVersion.TLSv1_3, |
| 163 | + ssl_maximum_version=ssl.TLSVersion.TLSv1_3, |
| 164 | + # Since we are using a custom SSL context, we need to pass this |
| 165 | + # here manually, even though it’s also passed to the connection |
| 166 | + # in `super().cert_verify()`. |
| 167 | + cert_reqs=ssl.CERT_REQUIRED if verify else ssl.CERT_NONE |
| 168 | + ) |
| 169 | + |
145 | 170 | return create_urllib3_context(
|
146 | 171 | ciphers=ciphers,
|
147 | 172 | ssl_version=resolve_ssl_version(ssl_version),
|
|
0 commit comments