diff --git a/crypto-42.patch b/crypto-42.patch new file mode 100644 index 0000000..6e0e080 --- /dev/null +++ b/crypto-42.patch @@ -0,0 +1,47 @@ +Index: PyKMIP-0.10.0/kmip/services/server/crypto/engine.py +=================================================================== +--- PyKMIP-0.10.0.orig/kmip/services/server/crypto/engine.py ++++ PyKMIP-0.10.0/kmip/services/server/crypto/engine.py +@@ -588,10 +588,10 @@ class CryptographyEngine(api.Cryptograph + backend = default_backend() + + try: +- public_key = backend.load_der_public_key(encryption_key) ++ public_key = serialization.load_der_public_key(encryption_key) + except Exception: + try: +- public_key = backend.load_pem_public_key(encryption_key) ++ public_key = serialization.load_pem_public_key(encryption_key) + except Exception: + raise exceptions.CryptographicFailure( + "The public key bytes could not be loaded." +@@ -935,14 +935,14 @@ class CryptographyEngine(api.Cryptograph + params["unsafe_skip_rsa_key_validation"] = False + + try: +- private_key = backend.load_der_private_key( ++ private_key = serialization.load_der_private_key( + decryption_key, + None, + **params, + ) + except Exception: + try: +- private_key = backend.load_pem_private_key( ++ private_key = serialization.load_pem_private_key( + decryption_key, + None, + **params, +@@ -1500,10 +1500,10 @@ class CryptographyEngine(api.Cryptograph + ) + + try: +- public_key = backend.load_der_public_key(signing_key) ++ public_key = serialization.load_der_public_key(signing_key) + except Exception: + try: +- public_key = backend.load_pem_public_key(signing_key) ++ public_key = serialization.load_pem_public_key(signing_key) + except Exception: + raise exceptions.CryptographicFailure( + "The signing key bytes could not be loaded." diff --git a/no-ssl-wrap-socket.patch b/no-ssl-wrap-socket.patch new file mode 100644 index 0000000..5b37460 --- /dev/null +++ b/no-ssl-wrap-socket.patch @@ -0,0 +1,101 @@ +From 433ab3ef43241155ee64196574daae2f41feac4e Mon Sep 17 00:00:00 2001 +From: Steven Silvester +Date: Wed, 4 Oct 2023 09:59:43 -0500 +Subject: [PATCH 01/11] Add python 3.12 support + +--- + .github/workflows/tox.yml | 3 ++- + kmip/services/kmip_client.py | 19 +++++++------- + kmip/services/server/server.py | 25 ++++++++++--------- + .../tests/unit/services/server/test_server.py | 4 +-- + 4 files changed, 27 insertions(+), 24 deletions(-) + +Index: PyKMIP-0.10.0/kmip/services/kmip_client.py +=================================================================== +--- PyKMIP-0.10.0.orig/kmip/services/kmip_client.py ++++ PyKMIP-0.10.0/kmip/services/kmip_client.py +@@ -285,13 +285,15 @@ class KMIPProxy(object): + six.reraise(*last_error) + + def _create_socket(self, sock): +- self.socket = ssl.wrap_socket( ++ context = ssl.SSLContext(protocol=self.ssl_version) ++ context.load_verify_locations(capath=self.ca_certs) ++ context.check_hostname = False ++ context.verify_mode = self.cert_reqs ++ if self.certfile: ++ context.load_cert_chain(self.certfile, self.keyfile) ++ self.socket = context.wrap_socket( + sock, +- keyfile=self.keyfile, +- certfile=self.certfile, +- cert_reqs=self.cert_reqs, +- ssl_version=self.ssl_version, +- ca_certs=self.ca_certs, ++ server_side=False, + do_handshake_on_connect=self.do_handshake_on_connect, + suppress_ragged_eofs=self.suppress_ragged_eofs) + self.socket.settimeout(self.timeout) +Index: PyKMIP-0.10.0/kmip/services/server/server.py +=================================================================== +--- PyKMIP-0.10.0.orig/kmip/services/server/server.py ++++ PyKMIP-0.10.0/kmip/services/server/server.py +@@ -287,17 +287,22 @@ class KmipServer(object): + for cipher in auth_suite_ciphers: + self._logger.debug(cipher) + +- self._socket = ssl.wrap_socket( ++ capath = self.config.settings.get('ca_path') ++ context = ssl.SSLContext(protocol=self.auth_suite.protocol) ++ if capath is not None: ++ context.load_verify_locations(capath=capath) ++ context.verify_mode = ssl.CERT_REQUIRED ++ context.set_ciphers(self.auth_suite.ciphers) ++ certfile = self.config.settings.get('certificate_path') ++ if certfile: ++ keyfile = self.config.settings.get('key_path') ++ context.load_cert_chain(certfile, keyfile=keyfile) ++ ++ self._socket = context.wrap_socket( + self._socket, +- keyfile=self.config.settings.get('key_path'), +- certfile=self.config.settings.get('certificate_path'), + server_side=True, +- cert_reqs=ssl.CERT_REQUIRED, +- ssl_version=self.auth_suite.protocol, +- ca_certs=self.config.settings.get('ca_path'), + do_handshake_on_connect=False, +- suppress_ragged_eofs=True, +- ciphers=self.auth_suite.ciphers ++ suppress_ragged_eofs=True + ) + + try: +Index: PyKMIP-0.10.0/kmip/tests/unit/services/server/test_server.py +=================================================================== +--- PyKMIP-0.10.0.orig/kmip/tests/unit/services/server/test_server.py ++++ PyKMIP-0.10.0/kmip/tests/unit/services/server/test_server.py +@@ -210,9 +210,9 @@ class TestKmipServer(testtools.TestCase) + # Test that in ideal cases no errors are generated and the right + # log messages are. + with mock.patch('socket.socket') as socket_mock: +- with mock.patch('ssl.wrap_socket') as ssl_mock: ++ with mock.patch('ssl.SSLContext') as ssl_mock: + socket_mock.return_value = a_mock +- ssl_mock.return_value = b_mock ++ ssl_mock.return_value.wrap_socket.return_value = b_mock + + manager_mock.assert_not_called() + monitor_mock.assert_not_called() +@@ -271,9 +271,9 @@ class TestKmipServer(testtools.TestCase) + + # Test that a NetworkingError is generated if the socket bind fails. + with mock.patch('socket.socket') as socket_mock: +- with mock.patch('ssl.wrap_socket') as ssl_mock: ++ with mock.patch('ssl.SSLContext') as ssl_mock: + socket_mock.return_value = a_mock +- ssl_mock.return_value = b_mock ++ ssl_mock.return_value.wrap_socket.return_value = b_mock + + test_exception = Exception() + b_mock.bind.side_effect = test_exception diff --git a/python-PyKMIP.changes b/python-PyKMIP.changes index dad636a..a5b367b 100644 --- a/python-PyKMIP.changes +++ b/python-PyKMIP.changes @@ -1,3 +1,13 @@ +------------------------------------------------------------------- +Thu Mar 28 03:58:37 UTC 2024 - Steve Kowalik + +- Clean up Python 2 leftovers. +- Add patch crypto-42.patch: + * Use cryptography.hazmat.primitives.serialization to load private keys. +- Add patch no-ssl-wrap-socket.patch: + * Do not use removed in Python 3.12 function, ssl.wrap_socket. +- Switch to pyproject macros. + ------------------------------------------------------------------- Fri Sep 8 06:13:02 UTC 2023 - Daniel Garcia diff --git a/python-PyKMIP.spec b/python-PyKMIP.spec index 769a1f2..2b11401 100644 --- a/python-PyKMIP.spec +++ b/python-PyKMIP.spec @@ -1,7 +1,7 @@ # # spec file for package python-PyKMIP # -# Copyright (c) 2023 SUSE LLC +# Copyright (c) 2024 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -16,13 +16,11 @@ # -%bcond_without python2 Name: python-PyKMIP Version: 0.10.0 Release: 0 Summary: KMIP v11 library License: Apache-2.0 -Group: Development/Languages/Python URL: https://github.com/OpenKMIP/PyKMIP Source: https://files.pythonhosted.org/packages/source/P/PyKMIP/PyKMIP-%{version}.tar.gz # PATCH-FIX-UPSTREAM fix-tests-SQLAlchemy-140.patch gh#OpenKMIP/PyKMIP#656 mcepl@suse.com @@ -30,18 +28,24 @@ Source: https://files.pythonhosted.org/packages/source/P/PyKMIP/PyKMIP-% Patch0: fix-tests-SQLAlchemy-140.patch # https://github.com/OpenKMIP/PyKMIP/issues/668 Patch1: python-PyKMIP-no-mock.patch -# PATCH-FIX-OPENSUSE crypto-39.patch gh#OpenKMIP/PyKMIP#689 +# PATCH-FIX-UPSTREAM crypto-39.patch gh#OpenKMIP/PyKMIP#689 Patch2: crypto-39.patch # PATCH-FIX-UPSTREAM fix_test_mac_with_cryptographic_failure.patch gh#OpenKMIP/PyKMIP#702 Patch3: fix_test_mac_with_cryptographic_failure.patch +# PATCH-FIX-OPENSUSE Use cryptography.hazmat.primitives.serialization for loading private keys. +Patch4: crypto-42.patch +# PATCH-FIX-UPSTREAM Based on gh#OpenKMIP/PyKMIP#707, including some changes suggested +Patch5: no-ssl-wrap-socket.patch BuildRequires: %{python_module SQLAlchemy} BuildRequires: %{python_module cryptography} BuildRequires: %{python_module devel} +BuildRequires: %{python_module pip} BuildRequires: %{python_module pytest} BuildRequires: %{python_module requests} BuildRequires: %{python_module setuptools} BuildRequires: %{python_module six} BuildRequires: %{python_module testtools} +BuildRequires: %{python_module wheel} BuildRequires: fdupes BuildRequires: python-rpm-macros Requires: python-SQLAlchemy @@ -49,14 +53,8 @@ Requires: python-cryptography Requires: python-requests Requires: python-six Requires(post): update-alternatives -Requires(postun):update-alternatives +Requires(postun): update-alternatives BuildArch: noarch -%if %{with python2} -BuildRequires: python-enum34 -%endif -%ifpython2 -Requires: python-enum34 -%endif %python_subpackages %description @@ -69,12 +67,14 @@ Standards`_ (OASIS). PyKMIP supports a subset of features in versions %prep %autosetup -p1 -n PyKMIP-%{version} +# Not needed, we use Python 3.4+ only +sed -i '/"enum-compat",/d' setup.py %build -%python_build +%pyproject_wheel %install -%python_install +%pyproject_install %python_clone -a %{buildroot}%{_bindir}/pykmip-server %python_expand %fdupes %{buildroot}%{$python_sitelib} @@ -91,7 +91,7 @@ Standards`_ (OASIS). PyKMIP supports a subset of features in versions %license LICENSE.txt %doc README.rst %{python_sitelib}/kmip -%{python_sitelib}/PyKMIP-%{version}*-info +%{python_sitelib}/PyKMIP-%{version}.dist-info %python_alternative %{_bindir}/pykmip-server %changelog