Generate default ciphers using approach from #1501

This commit is contained in:
Jakub Roztocil 2023-05-19 22:26:33 +02:00
parent 8e56e9fc64
commit fcd3f7ece6
3 changed files with 16 additions and 45 deletions

View File

@ -20,7 +20,7 @@ from httpie.output.formatters.colors import (AUTO_STYLE, DEFAULT_STYLE, BUNDLED_
get_available_styles) get_available_styles)
from httpie.plugins.builtin import BuiltinAuthPlugin from httpie.plugins.builtin import BuiltinAuthPlugin
from httpie.plugins.registry import plugin_manager from httpie.plugins.registry import plugin_manager
from httpie.ssl_ import AVAILABLE_SSL_VERSION_ARG_MAPPING, DEFAULT_SSL_CIPHERS from httpie.ssl_ import AVAILABLE_SSL_VERSION_ARG_MAPPING, DEFAULT_SSL_CIPHERS_STRING
options = ParserSpec( options = ParserSpec(
'http', 'http',
@ -832,9 +832,9 @@ ssl.add_argument(
help=f""" help=f"""
A string in the OpenSSL cipher list format. By default, the following A string in the OpenSSL cipher list format. By default, the following
is used: ciphers are used on your system:
{DEFAULT_SSL_CIPHERS} {DEFAULT_SSL_CIPHERS_STRING}
""", """,
) )

View File

@ -8,46 +8,7 @@ from urllib3.util.ssl_ import (
resolve_ssl_version, resolve_ssl_version,
) )
# We used to import default SSL ciphers via `SSL_CIPHERS` from `urllib3` but its been removed,
# so weve copied the original list here.
# Our issue: <https://github.com/httpie/httpie/issues/1499>
# Removal commit: <https://github.com/urllib3/urllib3/commit/e5eac0c>
DEFAULT_SSL_CIPHERS = ":".join([
# <urllib3>
# A secure default.
# Sources for more information on TLS ciphers:
#
# - https://wiki.mozilla.org/Security/Server_Side_TLS
# - https://www.ssllabs.com/projects/best-practices/index.html
# - https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
#
# The general intent is:
# - prefer cipher suites that offer perfect forward secrecy (DHE/ECDHE),
# - prefer ECDHE over DHE for better performance,
# - prefer any AES-GCM and ChaCha20 over any AES-CBC for better performance and
# security,
# - prefer AES-GCM over ChaCha20 because hardware-accelerated AES is common,
# - disable NULL authentication, MD5 MACs, DSS, and other
# insecure ciphers for security reasons.
# - NOTE: TLS 1.3 cipher suites are managed through a different interface
# not exposed by CPython (yet!) and are enabled by default if they're available.
"ECDHE+AESGCM",
"ECDHE+CHACHA20",
"DHE+AESGCM",
"DHE+CHACHA20",
"ECDH+AESGCM",
"DH+AESGCM",
"ECDH+AES",
"DH+AES",
"RSA+AESGCM",
"RSA+AES",
"!aNULL",
"!eNULL",
"!MD5",
"!DSS",
"!AESCCM",
# </urllib3>
])
SSL_VERSION_ARG_MAPPING = { SSL_VERSION_ARG_MAPPING = {
'ssl2.3': 'PROTOCOL_SSLv23', 'ssl2.3': 'PROTOCOL_SSLv23',
'ssl3': 'PROTOCOL_SSLv3', 'ssl3': 'PROTOCOL_SSLv3',
@ -119,6 +80,10 @@ class HTTPieHTTPSAdapter(HTTPAdapter):
cert_reqs=ssl.CERT_REQUIRED if verify else ssl.CERT_NONE cert_reqs=ssl.CERT_REQUIRED if verify else ssl.CERT_NONE
) )
@classmethod
def get_default_ciphers_names(cls):
return [cipher['name'] for cipher in cls._create_ssl_context(verify=False).get_ciphers()]
def _is_key_file_encrypted(key_file): def _is_key_file_encrypted(key_file):
"""Detects if a key file is encrypted or not. """Detects if a key file is encrypted or not.
@ -132,3 +97,9 @@ def _is_key_file_encrypted(key_file):
return True return True
return False return False
# We used to import the default set of TLS ciphers from urllib3, but they removed it.
# Instead, now urllib3 uses the list of ciphers configured by the system.
# <https://github.com/httpie/httpie/pull/1501>
DEFAULT_SSL_CIPHERS_STRING = ':'.join(HTTPieHTTPSAdapter.get_default_ciphers_names())

View File

@ -7,7 +7,7 @@ import urllib3
from unittest import mock from unittest import mock
from httpie.ssl_ import AVAILABLE_SSL_VERSION_ARG_MAPPING, DEFAULT_SSL_CIPHERS from httpie.ssl_ import AVAILABLE_SSL_VERSION_ARG_MAPPING, DEFAULT_SSL_CIPHERS_STRING
from httpie.status import ExitStatus from httpie.status import ExitStatus
from .utils import HTTP_OK, TESTS_ROOT, IS_PYOPENSSL, http from .utils import HTTP_OK, TESTS_ROOT, IS_PYOPENSSL, http
@ -146,7 +146,7 @@ def test_ciphers(httpbin_secure):
r = http( r = http(
httpbin_secure.url + '/get', httpbin_secure.url + '/get',
'--ciphers', '--ciphers',
DEFAULT_SSL_CIPHERS, DEFAULT_SSL_CIPHERS_STRING,
) )
assert HTTP_OK in r assert HTTP_OK in r