git: 9cab43d1da02 - main - security/py-sslyze: Add py-sslyze 5.0.5
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 29 Jun 2022 16:35:16 UTC
The branch main has been updated by sunpoet: URL: https://cgit.FreeBSD.org/ports/commit/?id=9cab43d1da0201587df86f03b74a1af37e35b09e commit 9cab43d1da0201587df86f03b74a1af37e35b09e Author: Po-Chuan Hsieh <sunpoet@FreeBSD.org> AuthorDate: 2022-06-29 16:26:24 +0000 Commit: Po-Chuan Hsieh <sunpoet@FreeBSD.org> CommitDate: 2022-06-29 16:32:33 +0000 security/py-sslyze: Add py-sslyze 5.0.5 SSLyze is a fast and powerful SSL/TLS scanning tool and Python library. SSLyze can analyze the SSL/TLS configuration of a server by connecting to it, in order to ensure that it uses strong encryption settings (certificate, cipher suites, elliptic curves, etc.), and that it is not vulnerable to known TLS attacks (Heartbleed, ROBOT, OpenSSL CCS injection, etc.). WWW: https://github.com/nabla-c0d3/sslyze --- security/Makefile | 1 + security/py-sslyze/Makefile | 28 ++++ security/py-sslyze/distinfo | 3 + security/py-sslyze/files/patch-openssl | 230 +++++++++++++++++++++++++++++++++ security/py-sslyze/pkg-descr | 8 ++ 5 files changed, 270 insertions(+) diff --git a/security/Makefile b/security/Makefile index 3712d4eb0dfb..3fe2b22adfe7 100644 --- a/security/Makefile +++ b/security/Makefile @@ -974,6 +974,7 @@ SUBDIR += py-spake2 SUBDIR += py-ssh-audit SUBDIR += py-sshpubkeys + SUBDIR += py-sslyze SUBDIR += py-stem SUBDIR += py-stix SUBDIR += py-stix2 diff --git a/security/py-sslyze/Makefile b/security/py-sslyze/Makefile new file mode 100644 index 000000000000..82bc7d3fb1d5 --- /dev/null +++ b/security/py-sslyze/Makefile @@ -0,0 +1,28 @@ +# Created by: Po-Chuan Hsieh <sunpoet@FreeBSD.org> + +PORTNAME= sslyze +PORTVERSION= 5.0.5 +CATEGORIES= security python +MASTER_SITES= CHEESESHOP +PKGNAMEPREFIX= ${PYTHON_PKGNAMEPREFIX} + +MAINTAINER= sunpoet@FreeBSD.org +COMMENT= Fast and powerful SSL/TLS scanning library + +LICENSE= AGPLv3 +LICENSE_FILE= ${WRKSRC}/LICENSE.txt + +RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}cryptography>=2.6<38.0.0:security/py-cryptography@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}nassl>=4.0.1<5.0.0:security/py-nassl@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}pydantic>=1.7<1.10:devel/py-pydantic@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}tls-parser>=2.0.0<3.0.0:security/py-tls-parser@${PY_FLAVOR} + +USES= python:3.7+ +USE_PYTHON= autoplist concurrent distutils + +NO_ARCH= yes + +post-patch: + @${RM} ${WRKSRC}/sslyze/plugins/openssl_cipher_suites/_tls12_workaround.py + +.include <bsd.port.mk> diff --git a/security/py-sslyze/distinfo b/security/py-sslyze/distinfo new file mode 100644 index 000000000000..edc4eb2a6d6f --- /dev/null +++ b/security/py-sslyze/distinfo @@ -0,0 +1,3 @@ +TIMESTAMP = 1656092884 +SHA256 (sslyze-5.0.5.tar.gz) = fea82ad88a030cc0978fb55f632849b3e858e03c5b97fd62459976953d3ef5d5 +SIZE (sslyze-5.0.5.tar.gz) = 985910 diff --git a/security/py-sslyze/files/patch-openssl b/security/py-sslyze/files/patch-openssl new file mode 100644 index 000000000000..747def93d6e0 --- /dev/null +++ b/security/py-sslyze/files/patch-openssl @@ -0,0 +1,230 @@ +--- sslyze/connection_helpers/tls_connection.py.orig 2022-05-14 11:12:33 UTC ++++ sslyze/connection_helpers/tls_connection.py +@@ -2,8 +2,6 @@ import socket + from pathlib import Path + from typing import Optional, TYPE_CHECKING + +-from nassl.legacy_ssl_client import LegacySslClient +- + from sslyze.server_setting import ( + ServerNetworkLocation, + ServerNetworkConfiguration, +@@ -170,7 +168,7 @@ class SslConnection: + ): + raise ValueError("Cannot use modern OpenSSL with SSL 2.0 or 3.0") + +- ssl_client_cls = LegacySslClient if final_should_use_legacy_openssl else SslClient ++ ssl_client_cls = SslClient + + if network_configuration.tls_client_auth_credentials: + # A client certificate and private key were provided +--- sslyze/mozilla_tls_profile/mozilla_config_checker.py.orig 2022-05-14 10:32:13 UTC ++++ sslyze/mozilla_tls_profile/mozilla_config_checker.py +@@ -79,10 +79,6 @@ class ServerScanResultIncomplete(Exception): + + + SCAN_COMMANDS_NEEDED_BY_MOZILLA_CHECKER: Set[ScanCommand] = { +- ScanCommand.SSL_2_0_CIPHER_SUITES, +- ScanCommand.SSL_3_0_CIPHER_SUITES, +- ScanCommand.TLS_1_0_CIPHER_SUITES, +- ScanCommand.TLS_1_1_CIPHER_SUITES, + ScanCommand.TLS_1_2_CIPHER_SUITES, + ScanCommand.TLS_1_3_CIPHER_SUITES, + ScanCommand.HEARTBLEED, +@@ -223,10 +219,6 @@ def _check_tls_versions_and_ciphers( + smallest_ecdh_param_size = 100000 + smallest_dh_param_size = 100000 + for field_name, tls_version_name in [ +- ("ssl_2_0_cipher_suites", "SSLv2"), +- ("ssl_3_0_cipher_suites", "SSLv3"), +- ("tls_1_0_cipher_suites", "TLSv1"), +- ("tls_1_1_cipher_suites", "TLSv1.1"), + ("tls_1_2_cipher_suites", "TLSv1.2"), + ("tls_1_3_cipher_suites", "TLSv1.3"), + ]: +--- sslyze/plugins/compression_plugin.py.orig 2022-05-14 09:12:21 UTC ++++ sslyze/plugins/compression_plugin.py +@@ -1,7 +1,7 @@ + from dataclasses import dataclass + + import pydantic +-from nassl.legacy_ssl_client import LegacySslClient ++from nassl.ssl_client import SslClient + from nassl.ssl_client import ClientCertificateRequested + + from sslyze.json.scan_attempt_json import ScanCommandAttemptAsJson +@@ -89,9 +89,9 @@ def _test_compression_support(server_info: ServerConne + + ssl_connection = server_info.get_preconfigured_tls_connection( + override_tls_version=tls_version_to_use, +- should_use_legacy_openssl=True, # Only the legacy SSL client has methods to check for compression support ++ should_use_legacy_openssl=False, + ) +- if not isinstance(ssl_connection.ssl_client, LegacySslClient): ++ if not isinstance(ssl_connection.ssl_client, SslClient): + raise RuntimeError("Should never happen") + + # Make sure OpenSSL was built with support for compression to avoid false negatives +--- sslyze/plugins/fallback_scsv_plugin.py.orig 2022-05-14 09:12:21 UTC ++++ sslyze/plugins/fallback_scsv_plugin.py +@@ -3,7 +3,6 @@ from typing import List, Optional + + import pydantic + from nassl import _nassl +-from nassl.legacy_ssl_client import LegacySslClient + + from sslyze.json.scan_attempt_json import ScanCommandAttemptAsJson + from sslyze.plugins.plugin_base import ( +--- sslyze/plugins/openssl_cipher_suites/_test_cipher_suite.py.orig 2022-05-14 09:12:21 UTC ++++ sslyze/plugins/openssl_cipher_suites/_test_cipher_suite.py +@@ -2,7 +2,6 @@ from dataclasses import dataclass + from typing import Optional, Union + + from nassl.ephemeral_key_info import EphemeralKeyInfo +-from nassl.legacy_ssl_client import LegacySslClient + from nassl.ssl_client import ClientCertificateRequested, SslClient, BaseSslClient + + from sslyze.errors import ( +@@ -12,7 +11,6 @@ from sslyze.errors import ( + ) + from sslyze.plugins.openssl_cipher_suites.cipher_suites import CipherSuite + from sslyze.server_connectivity import ServerConnectivityInfo, TlsVersionEnum +-from sslyze.plugins.openssl_cipher_suites._tls12_workaround import WorkaroundForTls12ForCipherSuites + + + @dataclass(frozen=True) +@@ -36,15 +34,10 @@ def connect_with_cipher_suite( + server_connectivity_info: ServerConnectivityInfo, tls_version: TlsVersionEnum, cipher_suite: CipherSuite + ) -> Union[CipherSuiteAcceptedByServer, CipherSuiteRejectedByServer]: + """Initiates a SSL handshake with the server using the SSL version and the cipher suite specified.""" +- requires_legacy_openssl = True +- if tls_version == TlsVersionEnum.TLS_1_2: +- # For TLS 1.2, we need to pick the right version of OpenSSL depending on which cipher suite +- requires_legacy_openssl = WorkaroundForTls12ForCipherSuites.requires_legacy_openssl(cipher_suite.openssl_name) +- elif tls_version == TlsVersionEnum.TLS_1_3: +- requires_legacy_openssl = False ++ requires_legacy_openssl = False + + ssl_connection = server_connectivity_info.get_preconfigured_tls_connection( +- override_tls_version=tls_version, should_use_legacy_openssl=requires_legacy_openssl ++ override_tls_version=tls_version, should_use_legacy_openssl=False + ) + _set_cipher_suite_string(tls_version, cipher_suite.openssl_name, ssl_connection.ssl_client) + +--- sslyze/plugins/openssl_cipher_suites/cipher_suites.py.orig 2022-06-25 23:42:22 UTC ++++ sslyze/plugins/openssl_cipher_suites/cipher_suites.py +@@ -3,7 +3,6 @@ from typing import Dict, Set + + from dataclasses import dataclass + +-from nassl.legacy_ssl_client import LegacySslClient + from nassl.ssl_client import OpenSslVersionEnum, SslClient + + from sslyze.server_connectivity import TlsVersionEnum +@@ -571,44 +570,14 @@ _TLS_1_3_CIPHER_SUITES = [ + ] + + +-def _parse_all_cipher_suites_with_legacy_openssl(tls_version: TlsVersionEnum) -> Set[str]: +- ssl_client = LegacySslClient(ssl_version=OpenSslVersionEnum(tls_version.value)) +- # Disable SRP and PSK cipher suites as they need a special setup in the client and are never used +- ssl_client.set_cipher_list("ALL:COMPLEMENTOFALL:-PSK:-SRP") +- return set(ssl_client.get_cipher_list()) +- +- + def _parse_all_cipher_suites() -> Dict[TlsVersionEnum, Set[CipherSuite]]: + tls_version_to_cipher_suites: Dict[TlsVersionEnum, Set[CipherSuite]] = {} + +- for tls_version in [ +- TlsVersionEnum.SSL_2_0, +- TlsVersionEnum.SSL_3_0, +- TlsVersionEnum.TLS_1_0, +- TlsVersionEnum.TLS_1_1, +- ]: +- openssl_cipher_strings = _parse_all_cipher_suites_with_legacy_openssl(tls_version) +- tls_version_to_cipher_suites[tls_version] = set() +- for cipher_suite_openssl_name in openssl_cipher_strings: +- cipher_suite_rfc_name = _OPENSSL_TO_RFC_NAMES_MAPPING[tls_version][cipher_suite_openssl_name] +- tls_version_to_cipher_suites[tls_version].add( +- CipherSuite( +- name=cipher_suite_rfc_name, +- openssl_name=cipher_suite_openssl_name, +- is_anonymous=True if "anon" in cipher_suite_rfc_name else False, +- key_size=_RFC_NAME_TO_KEY_SIZE_MAPPING[cipher_suite_rfc_name], +- ) +- ) +- +- # For TLS 1.2, we have to use both the legacy and modern OpenSSL to cover all cipher suites +- cipher_suites_from_legacy_openssl = _parse_all_cipher_suites_with_legacy_openssl(TlsVersionEnum.TLS_1_2) +- + ssl_client_modern = SslClient(ssl_version=OpenSslVersionEnum(TlsVersionEnum.TLS_1_2.value)) + ssl_client_modern.set_cipher_list("ALL:COMPLEMENTOFALL:-PSK:-SRP") + cipher_suites_from_modern_openssl = set(ssl_client_modern.get_cipher_list()) + +- # Combine the two sets of cipher suites +- openssl_cipher_strings = cipher_suites_from_legacy_openssl.union(cipher_suites_from_modern_openssl) ++ openssl_cipher_strings = cipher_suites_from_modern_openssl + tls_version_to_cipher_suites[TlsVersionEnum.TLS_1_2] = set() + for cipher_suite_openssl_name in openssl_cipher_strings: + # Ignore TLS 1.3 cipher suites +--- sslyze/plugins/scan_commands.py.orig 2022-03-12 09:56:30 UTC ++++ sslyze/plugins/scan_commands.py +@@ -12,12 +12,8 @@ from sslyze.plugins.heartbleed_plugin import Heartblee + from sslyze.plugins.http_headers_plugin import HttpHeadersImplementation + from sslyze.plugins.openssl_ccs_injection_plugin import OpenSslCcsInjectionImplementation + from sslyze.plugins.openssl_cipher_suites.implementation import ( +- Sslv20ScanImplementation, +- Sslv30ScanImplementation, +- Tlsv10ScanImplementation, + Tlsv13ScanImplementation, + Tlsv12ScanImplementation, +- Tlsv11ScanImplementation, + ) + from sslyze.plugins.robot.implementation import RobotImplementation + from sslyze.plugins.session_renegotiation_plugin import SessionRenegotiationImplementation +@@ -60,10 +56,6 @@ class ScanCommandsRepository: + _IMPLEMENTATION_CLASSES: Dict[ScanCommand, Type["ScanCommandImplementation"]] = { + ScanCommand.CERTIFICATE_INFO: CertificateInfoImplementation, + ScanCommand.SESSION_RESUMPTION: SessionResumptionSupportImplementation, +- ScanCommand.SSL_2_0_CIPHER_SUITES: Sslv20ScanImplementation, +- ScanCommand.SSL_3_0_CIPHER_SUITES: Sslv30ScanImplementation, +- ScanCommand.TLS_1_0_CIPHER_SUITES: Tlsv10ScanImplementation, +- ScanCommand.TLS_1_1_CIPHER_SUITES: Tlsv11ScanImplementation, + ScanCommand.TLS_1_2_CIPHER_SUITES: Tlsv12ScanImplementation, + ScanCommand.TLS_1_3_CIPHER_SUITES: Tlsv13ScanImplementation, + ScanCommand.TLS_COMPRESSION: CompressionImplementation, +--- sslyze/plugins/session_renegotiation_plugin.py.orig 2022-05-14 09:12:21 UTC ++++ sslyze/plugins/session_renegotiation_plugin.py +@@ -5,7 +5,7 @@ from typing import List, Optional, Tuple + + import pydantic + from nassl._nassl import OpenSSLError +-from nassl.legacy_ssl_client import LegacySslClient ++from nassl.ssl_client import SslClient + + from sslyze.json.scan_attempt_json import ScanCommandAttemptAsJson + from sslyze.errors import ServerRejectedTlsHandshake +@@ -124,9 +124,9 @@ def _test_secure_renegotiation(server_info: ServerConn + + ssl_connection = server_info.get_preconfigured_tls_connection( + override_tls_version=tls_version_to_use, +- should_use_legacy_openssl=True, # Only the legacy SSL client has methods to check for secure reneg ++ should_use_legacy_openssl=False, + ) +- if not isinstance(ssl_connection.ssl_client, LegacySslClient): ++ if not isinstance(ssl_connection.ssl_client, SslClient): + raise RuntimeError("Should never happen") + + try: +@@ -159,9 +159,9 @@ def _test_client_renegotiation(server_info: ServerConn + + ssl_connection = server_info.get_preconfigured_tls_connection( + override_tls_version=tls_version_to_use, +- should_use_legacy_openssl=True, # Only the legacy SSL client has methods to trigger a reneg ++ should_use_legacy_openssl=False, + ) +- if not isinstance(ssl_connection.ssl_client, LegacySslClient): ++ if not isinstance(ssl_connection.ssl_client, SslClient): + raise RuntimeError("Should never happen") + + try: diff --git a/security/py-sslyze/pkg-descr b/security/py-sslyze/pkg-descr new file mode 100644 index 000000000000..2ae6a7311209 --- /dev/null +++ b/security/py-sslyze/pkg-descr @@ -0,0 +1,8 @@ +SSLyze is a fast and powerful SSL/TLS scanning tool and Python library. + +SSLyze can analyze the SSL/TLS configuration of a server by connecting to it, in +order to ensure that it uses strong encryption settings (certificate, cipher +suites, elliptic curves, etc.), and that it is not vulnerable to known TLS +attacks (Heartbleed, ROBOT, OpenSSL CCS injection, etc.). + +WWW: https://github.com/nabla-c0d3/sslyze