in mysqlx-connector-python/lib/mysqlx/connection.py [0:0]
def _validate_tls_ciphersuites(settings: Dict[str, Any]) -> None:
"""Validate tls-ciphersuites.
Args:
settings (dict): Settings dictionary.
Raises:
:class:`mysqlx.InterfaceError`: If tls-ciphersuites name is not valid.
"""
tls_ciphersuites = []
if "tls-ciphersuites" not in settings:
return
tls_ciphersuites_settings = settings["tls-ciphersuites"]
if isinstance(tls_ciphersuites_settings, str):
if not (
tls_ciphersuites_settings.startswith("[")
and tls_ciphersuites_settings.endswith("]")
):
raise InterfaceError(
"tls-ciphersuites must be a list, found: "
f"'{tls_ciphersuites_settings}'"
)
tls_css = tls_ciphersuites_settings[1:-1].split(",")
if not tls_css:
raise InterfaceError(
"No valid cipher suite found in the 'tls-ciphersuites' list"
)
for tls_cs in tls_css:
tls_cs = tls_cs.strip().upper()
if tls_cs:
tls_ciphersuites.append(tls_cs)
elif isinstance(tls_ciphersuites_settings, (list, set)):
tls_ciphersuites = [tls_cs for tls_cs in tls_ciphersuites_settings if tls_cs]
else:
raise InterfaceError(
"tls-ciphersuites should be a list with one or more ciphersuites. "
f"Found: '{tls_ciphersuites_settings}'"
)
tls_versions = (
SUPPORTED_TLS_VERSIONS[:]
if settings.get("tls-versions", None) is None
else settings["tls-versions"][:]
)
# A newer TLS version can use a cipher introduced on
# an older version.
tls_versions.sort(reverse=True)
newer_tls_ver = tls_versions[0]
translated_names = []
iani_cipher_suites_names = {}
ossl_cipher_suites_names: List[str] = []
# Old ciphers can work with new TLS versions.
# Find all the ciphers introduced on previous TLS versions
for tls_ver in SUPPORTED_TLS_VERSIONS[
: SUPPORTED_TLS_VERSIONS.index(newer_tls_ver) + 1
]:
iani_cipher_suites_names.update(TLS_CIPHER_SUITES[tls_ver])
ossl_cipher_suites_names.extend(OPENSSL_CS_NAMES[tls_ver])
for name in tls_ciphersuites:
if "-" in name and name in ossl_cipher_suites_names:
translated_names.append(name)
elif name in iani_cipher_suites_names:
translated_name = iani_cipher_suites_names[name]
if translated_name in translated_names:
raise AttributeError(
DUPLICATED_IN_LIST_ERROR.format(
list="tls_ciphersuites", value=translated_name
)
)
translated_names.append(translated_name)
else:
raise InterfaceError(
f"The value '{name}' in cipher suites is not a valid cipher suite"
)
if not translated_names:
raise InterfaceError(
"No valid cipher suite found in the 'tls-ciphersuites' list"
)
# raise an error when using an unacceptable cipher
for cipher_as_ossl in translated_names:
for tls_ver in SUPPORTED_TLS_VERSIONS[
: SUPPORTED_TLS_VERSIONS.index(newer_tls_ver) + 1
]:
if (
cipher_as_ossl
in UNACCEPTABLE_TLS_CIPHERSUITES.get(tls_ver, {}).values()
):
raise NotSupportedError(
f"Cipher {cipher_as_ossl} when used with {tls_ver} is unacceptable."
)
settings["tls-ciphersuites"] = translated_names