From e1201d92e156b2d102bd8b6b98cad0e95638421c9db05d8a0ceb5548ea96c9ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mark=C3=A9ta=20Machov=C3=A1?= Date: Tue, 8 Apr 2025 07:58:18 +0000 Subject: [PATCH] - Fix dependencies gh#IdentityPython/pysaml2#984 OBS-URL: https://build.opensuse.org/package/show/devel:languages:python/python-pysaml2?expand=0&rev=80 --- .gitattributes | 23 ++ .gitignore | 1 + python-pysaml2.changes | 474 +++++++++++++++++++++++++++++++++++++++++ python-pysaml2.spec | 120 +++++++++++ use-cryptography.patch | 342 +++++++++++++++++++++++++++++ v7.4.2.tar.gz | 3 + v7.5.0.tar.gz | 3 + v7.5.2.tar.gz | 3 + 8 files changed, 969 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 python-pysaml2.changes create mode 100644 python-pysaml2.spec create mode 100644 use-cryptography.patch create mode 100644 v7.4.2.tar.gz create mode 100644 v7.5.0.tar.gz create mode 100644 v7.5.2.tar.gz diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..9b03811 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,23 @@ +## Default LFS +*.7z filter=lfs diff=lfs merge=lfs -text +*.bsp filter=lfs diff=lfs merge=lfs -text +*.bz2 filter=lfs diff=lfs merge=lfs -text +*.gem filter=lfs diff=lfs merge=lfs -text +*.gz filter=lfs diff=lfs merge=lfs -text +*.jar filter=lfs diff=lfs merge=lfs -text +*.lz filter=lfs diff=lfs merge=lfs -text +*.lzma filter=lfs diff=lfs merge=lfs -text +*.obscpio filter=lfs diff=lfs merge=lfs -text +*.oxt filter=lfs diff=lfs merge=lfs -text +*.pdf filter=lfs diff=lfs merge=lfs -text +*.png filter=lfs diff=lfs merge=lfs -text +*.rpm filter=lfs diff=lfs merge=lfs -text +*.tbz filter=lfs diff=lfs merge=lfs -text +*.tbz2 filter=lfs diff=lfs merge=lfs -text +*.tgz filter=lfs diff=lfs merge=lfs -text +*.ttf filter=lfs diff=lfs merge=lfs -text +*.txz filter=lfs diff=lfs merge=lfs -text +*.whl filter=lfs diff=lfs merge=lfs -text +*.xz filter=lfs diff=lfs merge=lfs -text +*.zip filter=lfs diff=lfs merge=lfs -text +*.zst filter=lfs diff=lfs merge=lfs -text diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..57affb6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.osc diff --git a/python-pysaml2.changes b/python-pysaml2.changes new file mode 100644 index 0000000..27e582a --- /dev/null +++ b/python-pysaml2.changes @@ -0,0 +1,474 @@ +------------------------------------------------------------------- +Tue Apr 8 07:29:45 UTC 2025 - Ben Greiner + +- Fix dependencies gh#IdentityPython/pysaml2#984 + +------------------------------------------------------------------- +Fri Feb 28 04:15:23 UTC 2025 - Nico Krapp + +- Update to 7.5.2 + * Include the XSD of the XML Encryption Syntax and Processing + Version 1.1 to the schema validator +- Update to 7.5.1 + * deps: restrict pyOpenSSL up to v24.2.1 until it is replaced + * deps: update dependncies for the lockfile and examples +- add use-cryptography.patch to fix tests + +------------------------------------------------------------------- +Tue Oct 29 08:15:43 UTC 2024 - Dirk Müller + +- update to 7.5.0: + * Fix missing requested attributes from the ACS + * Add support for errorURL to be exposed in metadata for IdP + * Update logged message when the signature validation on the + assertion fails + * Replace imp with importlib + * deps: restrict xmlschema version + * deps: remove utility from packaging + * examples: update code and README to align with latest code + * docs: update readme with info about xmlsec1 compatibility + +------------------------------------------------------------------- +Mon Jan 29 13:54:33 UTC 2024 - Petr Gajdos + +- update to 7.4.2: + * Add support for xmlsec1 1.3.x + * Use the set crypto_backend when creating the entity metadata + * ## 7.4.1 (2023-02-24) + * Fix subject-id requirements processing + * ## 7.4.0 (2023-02-14) + * Ensure the ID of each Signature element is unique when + signing an encrypted assertion + * Bump Python to 3.9 + * dev: Add mypy configuration and type stubs + * tests: move tox.ini config into pyproject.toml + * docs: Update release instructions + * ## 7.3.0 (2023-02-14) + * During metadata generation, render extensions both for + EntityDescriptor and IdPSSODescriptor + * Fix compatibility with certain SAML implementation that + inflate messasges on the POST binding + * Update the SWAMID entity category requirements + * Fix check for NameID when it originates from an encrypted + asssertion + * Add support for pymongo `>=3.5` and `<5` + * Update README with supported specifications + * Remove dependency on the six package + * Cleanup unused imports and pythonisms for Python versions + older than 3.6 + * Convert README to markdown + * Introduce flake8 to check for issues + * Use black and isort to manage formatting and imports + * Use poetry to manage the project dependencies, packaging and + versions + * Fix whitespace typos on the eIDAS schemas + * Try different logout bindings on the saml2.client level + * Add the mailLocalAddress attribute as part of the saml and + shib uri name format bundles + * Add the isMemberOf attribute as part of the basic attribute + format bundle +- drop upstreamed pymongo-4-support.patch + +------------------------------------------------------------------- +Sun Jun 11 13:23:30 UTC 2023 - ecsos + +- Add %{?sle15_python_module_pythons} + +------------------------------------------------------------------- +Tue Nov 15 14:23:13 UTC 2022 - Rolf Krahl + +- Fix dependencies according to upstream setup.cfg + +------------------------------------------------------------------- +Thu Oct 6 21:56:41 UTC 2022 - Yogalakshmi Arunachalam + +- version update to 7.2.1 (2022-08-23) + * Accept and forward sign and digest alg information when creating a metadata string + * Fix tests to comply with latest xmlschema + +- version update to 7.2.0 (2022-08-10) + * Add schemas for eIDAS extensions, elements and attributes + * Add the voPerson v2 attributes mappings; see reference + * Add the registration_info_typ method on saml2.mdstore.MetadataStore to get the registration information from an EntityDescriptor services + * Allow exceptions to convey the SAML StatusCode in an error response + * Fix typo on method name under saml2.mdstore.MetadataStore; from sbibmd_scopes to shibmd_scopes + * Add partial support for xs:date AttributeValue type + * Fallback to xs:string as the type of the AttributeValue text node + * Fallback to the authn context class declaration to set the authn context class reference + * Αdd configuration option http_client_timeout to set a timeout on the HTTP calls by the httpbase module + * Load certificates using cryptography and support certificate chains + * Remove deprecated cryptography backend param + * Fix assertion policy filter: Fallback to match a known attribute or return its name + * examples: Allow multiple attributes to be returned by the idp + * tests: Minor cleanups + * docs: Reference python2 compatible fork + * misc: add pepy badges on the README file + +------------------------------------------------------------------- +Thu Jul 28 06:04:01 UTC 2022 - Steve Kowalik + +- Add patch pymongo-4-support.patch: + * Support pymongo >= 4 + +------------------------------------------------------------------- +Thu Apr 7 08:37:47 UTC 2022 - pgajdos@suse.com + +- version update to 7.1.2 + ## 7.1.2 (2022-03-04) + - fix assertion policy filter to try to resolve the local_name using the friendly name if it failed with the name_format + - reload metadata in-place to avoid memory leak + - tests: Restrict pymongo to v3 + - docs: highlight installation command + ## 7.1.1 (2022-02-22) + - Process and verify the metadata signature for EntitiesDescriptor and EntityDescriptor + - Fix client to be able to retry creating an AuthnRequest with a different binding + - Allow requested_authn_context to be an object + - AttributeValues are optional; allow Attributes to not have values + - Update SWAMID entity category to support https://myacademicid.org/entity-categories/esi + - Fix signing for requests with the SOAP binding + - tests: new test case for signed SOAP LogoutRequests + - docs: document the metadata node_name option for the remote source + - examples: align with latest updates + - deps: declare setuptools as a requirement for processing the package version + - build: add python 3.9 and 3.10 to classifiers + - misc: linter fixes + ## 7.1.0 (2021-11-16) + - Fix signature verification for the redirect binding for AuthnRequest and + LogoutRequest. + - Include encryption KeyName in encrypted assertions. + - Add "reason" field in invalid signature errors due to invalid document format. + - New SP configuration option requested_authn_context to set the preferred + RequestedAuthnContext class reference. + - Add support for metadata refresh by adding a metadata_reload method into saml2.Entity. + This method is to be externally invoked, and to receive the same metadata + configuration as what was passed under the metadata key to saml2.Config. The method + loads a new metadata configuration and swaps it in (replacing the references across + several objects that hold a metadata reference). + - Fix SessionIndex resolution during logout. + - Fix AuthnResponse::get_subject to be able to decrypt a NameID with the given keys. + - Refactor AuthnResponse::authn_info to consider DeclRef equivalent to ClassRef. + - Ensure creation of multiple ePTIDs is handled correctly. + - Improve signature checks by ensuring the Object element is absent, enforcing allowed + transform aglorithms, enforcing allowed canonicalization methods and requiring the + enveloped-signature transform to be present. + - mdstore: Make unknown metadata extensions available through the internal metadata. + - mdstore: Fix the exception handler of the InMemoryMetaData object. + - mdstore: Fix the serialization of the MetadataStore object. + - examples: Fix code to catter changes in interfaces. + - examples: Update certificates to avoid SSL KEY TO SMALL errors. + - docs: Significant improvement on the configuration options documentation. + - docs: Fix typos. +- python-mock is not required for build + +------------------------------------------------------------------- +Fri Jul 2 20:25:49 UTC 2021 - Michael Ströder + +- removed obsolete 0001-Always-use-base64.encodebytes-base64.encodestring-ha.patch +- Update to 7.0.1: + * 7.0.1 (2021-05-20) + - Preserve order of response bindings on IdP-initiated logout + - Fix use of expected binding on SP logout + * 7.0.0 (2021-05-18) + - **BREAKING** Replace encryption method rsa-1_5 with rsa-oaep-mgf1p + - Add documentation next to the code + * 6.5.2 (2021-05-18) + - Add shibmd_scopes metadata extractor + - Allow the Issuer element on a Response to be missing + - Respect the preferred_binding configuration for the single_logout_service + - Fix logout signature flags for redirect, post and soap requests + - Respect the logout_requests_signed configuration option + - Fix crash when applying policy on RequestedAttribute without a friendlyName + - Correctly validate IssueInstant + - Correctly handle AudienceRestriction elements with no value + - Raise InvalidAssertion exception when assertion requirements are not met + - Raise SAMLError on failure to parse a metadata file + - Raise StatusInvalidAuthnResponseStatement when the AuthnStatement is not valid + - Handle all forms of ACS endpoint specifications + - tests: Always use base64.encodebytes; base64.encodestring has been dropped + - build: Set minimum version needed for xmlschema + - docs: Update Travis CI badge from travis-ci.org to travis-ci.com + - examples: Fix example code + +------------------------------------------------------------------- +Mon Apr 26 12:55:01 UTC 2021 - Dirk Müller + +- add 0001-Always-use-base64.encodebytes-base64.encodestring-ha.patch + +------------------------------------------------------------------- +Mon Jan 25 15:06:45 UTC 2021 - Dirk Müller + +- update requires + +------------------------------------------------------------------- +Wed Jan 20 23:41:54 UTC 2021 - Michael Ströder + +- Update to 6.5.1: + * Fix the parser to take into account both the xs and xsd namespace prefixes + +------------------------------------------------------------------- +Wed Jan 20 20:12:26 UTC 2021 - Michael Ströder + +- Update to 6.5.0 - Security release + * Fix processing of invalid SAML XML documents - CVE-2021-21238 + * Fix unspecified xmlsec1 key-type preference - CVE-2021-21239 + * Add more tests regarding XSW attacks + * Add XML Schemas for SAML2 and common extensions + * Fix the XML parser to not break on ePTID AttributeValues + * Fix the initialization value of the return_addrs property of the StatusResponse object + * Fix SWAMID entity-category policy regarding eduPersonTargetedID + * data: use importlib to load package data (backwards compatibility through the importlib_resources package) + * docs: improve the documentation for the signing_algorithm and digest_algorithm options + * examples: fix the logging configuration of the example-IdP + * tests: allow tests to pass on 32bit systems by properly choosing dates in test XML documents + * tests: improvements on the generation of response and assertion objects + * tests: expand tests on python-3.9 and python-3.10-dev +- added new build dependencies: + * python3-importlib-resources + * python3-xmlschema + * update-alternatives +- removed obsolete avoid-too-large-dates.patch +- replaced %python3_alternative by %python_alternative + +------------------------------------------------------------------- +Wed Jan 6 10:49:48 UTC 2021 - Matej Cepl + +- Add avoid-too-large-dates.patch to avoid test failures on i586 + (Y38K bug; gh#IdentityPython/pysaml2#759) + +------------------------------------------------------------------- +Mon Jan 4 21:25:04 UTC 2021 - Matej Cepl + +- Skip test test_filter_ava_registration_authority_1 + (gh#IdentityPython/pysaml2#759). + +------------------------------------------------------------------- +Sun Dec 20 10:04:41 UTC 2020 - Dirk Müller + +- update to 6.3.1: + - Fix extraction of RegistrationInfo when no information is available + - Fix http_info struct to include status-code + - Allow to specify policy configurations based on the registration authority. + - Add new configuration option `logout_responses_signed` to sign logout responses. + - When available and appropriate return the ResponseLocation along with the Location + attribute. + - Always use base64.encodebytes; base64.encodestring has been dropped. + - Examples: fix IdP example that was outputing debug statements on stdout that became + part of its metadata. + - CI/CD: Use Ubuntu bionic as the host to run the CI/CD process. + - CI/CD: Pre-releases are now available on [test.pypi.org][pypi.test.pysaml2]. Each + commit/merge on the master branch autotically creates a new pre-release. To install a + prelease, run: + - Fix the generated xsd:ID format for EncryptedData and EncryptedKey elements + - Set the default value for the NameFormat attribute to unspecified when parsing + - Support arbitrary entity attributes + - Replace all asserts with proper checks + - Allow request signing in artifact2message + - Support logging configuration through the python logger + - Fix wrong identifiers for ecdsa algos + - Fix automatic inversion of attribute map files + - Factor out common codepaths in attribute_converter + - Remove uneeded exception logging + - Docs: Update configuration options documentation + - Examples: Support both str and bytes in SAML requests on the example idp + - Examples: Update to key generation to 2048 bits + +------------------------------------------------------------------- +Sat Jul 11 18:07:25 UTC 2020 - Michael Ströder + +- update to 6.1.0: + * Fix signed logout requests flag + * Differentiate between metadata NameIDFormat and AuthnRequest NameIDPolicy Format + - Users using `name_id_format` to set the `` attribute now + need to use the new configuration option `name_id_policy_format`. + * Fix documentation formatting + * Fix generation of signed metadata + * Add attribute mappings used by SwedenConnect (DIGG, INERA and PKIX specifications) + * Update SWAMID entity category + * Document the `additional_cert_files` configuration option + +------------------------------------------------------------------- +Fri Jul 10 12:29:12 UTC 2020 - Dirk Mueller + +- update to 5.3.0: + - Fix check for nameid_format set to the string "None" in the configuration + - Fix presence of empty eIDAS RequestedAttributes element on AuthnRequest + - Refactor create_authn_request method to be easier to reason about + - Fix NameIDPolicy checks for allowed Format and allowCreate values + +------------------------------------------------------------------- +Sun Jun 14 08:57:41 UTC 2020 - Dirk Mueller + +- update to 5.1.0: + - support eIDAS RequestedAttributes per AuthnRequest + - fix xmlsec1 --id-attr configuration option value + - do not remove existing disco URL query params + - load attribute maps in predictable order + - better error message when AudienceRestriction does not validate + - always use base64.encodebytes instead of base64.encodestring + - update the eIDAS attribute mapping for legal person + - fix py_compile warnings + - fix pylint errors and warnings + - various small fixes + - add Python3.8 as supported + - tests: fix validity dates + - docs: document default value for 'want_response_signed' + +------------------------------------------------------------------- +Tue May 5 12:50:42 UTC 2020 - Matej Cepl + +- Don't use %python3_only command, but properly use alternatives. +- Skip failing tests on i586 (gh#IdentityPython/pysaml2#682) + +------------------------------------------------------------------- +Sat Mar 14 15:57:25 UTC 2020 - Dirk Mueller + +- update to 5.0.0: + - Fix XML Signature Wrapping (XSW) vulnerabilities - CVE-2020-5390 + - Add freshness period feature for MetaDataMDX + - Fix bug in duration calculation in time_util library + - Fix ipv6 validation to accommodate for addresses with brackets + - Fix xmlsec temporary files deletions + - Add method to get supported algorithms from metadata + - Add mdstore method to extract assurance certifications + - Add mdstore method to extract contact_person data + - Add attribute mappings from the Swiss eduPerson Schema + - Make AESCipher and Fernet interfaces compatible + - Remove deprecated saml2.aes module + - Remove deprecated saml2.extensions.ui module + - Replace deprecated mongodb operations + - Rename ToOld error to TooOld + - Fix pytest warnings + - Mock tests that need a network connection + - Start dropping python2 support + - Add mdstore methods to extract mdui uiinfo elements + - Add attribute mapping for umbrellaID attributes + - Fix logic error in pick_binding method for Entity class + - Validate the audience of assertions regardless of a response being unsolicited + - Fix PKCS_9 saml_url prefix + - docs: Fix warnings from docs generation + - docs: Update release instructions regarding branch releases + - docs: Fix list formatting on IdP example page + - docs: Update pysaml2 options doc with `name_id_format_allow_create` + - misc: fix various typos + +------------------------------------------------------------------- +Tue Jan 7 11:37:57 UTC 2020 - Tomáš Chvátal + +- Use python dbm dependency instead of legacy gdbm + +------------------------------------------------------------------- +Mon Jul 22 14:57:53 UTC 2019 - Tomáš Chvátal + +- Update to 4.8.0: + * Refactor the way ForceAuthn is set: check for "true" and "1" + * Allow to set NameQualifier and SPNameQualifier attributes for ePTID + * Parse assertions with Holder-of-Key profile + * Add created_at timestamps to all mongodb documents + * Look for existing persistent id's before creating new ones + * Do not add AllowCreate property for default transient NameID + * Enable entity category import from module search path + * Add SAML subject identifier attributes to saml2_uri attributemap + * Fix deprecation warning regarding the cgi module - use the html module when available + * Misc minor improvements + * tests: Be compatible with latest pytest + * tests: Make tests pass after 2024 + * tests: Add py37 as a test target + * docs: Correct instructions to run tests + * docs: Fix misc typos + +------------------------------------------------------------------- +Wed Jun 5 09:39:57 UTC 2019 - Marketa Calabkova + +- Update to 4.7.0 + * Add support for MDQ signature verification + * Raise XmlsecError if xmlsec1 operations do not succeed + * Handle non standard response error status codes correctly + * Remove the python-future dependency and only use six + +------------------------------------------------------------------- +Fri Dec 7 10:43:13 UTC 2018 - Tomáš Chvátal + +- Update to 4.6.5: + * Many many changes everywhere, see CHANGELOG.md for details +- Use github tarball to include license/tests + +------------------------------------------------------------------- +Tue Dec 4 12:52:47 UTC 2018 - Matej Cepl + +- Remove superfluous devel dependency for noarch package + +------------------------------------------------------------------- +Wed Oct 10 06:08:56 UTC 2018 - Dirk Mueller + +- cleanup filelist + +------------------------------------------------------------------- +Tue Oct 9 15:50:52 UTC 2018 - Colleen Murphy + +- Replace python-pycryptodomex dep with python-cryptography + - Dependency was swapped in afdf5b4 + +------------------------------------------------------------------- +Wed Nov 29 08:25:34 UTC 2017 - okurz@suse.com + +- Add missing runtime dependency on 'defusedxml' +- Add obsolete suse_version special handling + +------------------------------------------------------------------- +Mon Oct 30 22:27:36 UTC 2017 - michael@stroeder.com + +- update to 4.5.0 + +------------------------------------------------------------------- +Mon Jun 19 08:57:42 UTC 2017 - okurz@suse.com + +- Convert to singlespec + +------------------------------------------------------------------- +Tue Nov 22 15:18:26 UTC 2016 - dmueller@suse.com + +- fix requires + +------------------------------------------------------------------- +Thu Nov 17 14:42:09 UTC 2016 - michael@stroeder.com + +- update to 4.4.0 +- added LICENSE.txt to docs + +------------------------------------------------------------------- +Fri Feb 26 13:14:29 UTC 2016 - tbechtold@suse.com + +- Require python-python-dateutil. package was renamed + +------------------------------------------------------------------- +Tue Oct 13 21:31:03 UTC 2015 - dmueller@suse.com + +- add pycrypto/pyOpenSSL dependency + +------------------------------------------------------------------- +Tue Sep 1 07:17:52 UTC 2015 - tbechtold@suse.com + +- Move python-repoze.who from Recommends to Requires. It's needed. + +------------------------------------------------------------------- +Thu Jul 30 19:30:53 UTC 2015 - tbechtold@suse.com + +- Add missing Requires + +------------------------------------------------------------------- +Thu Jul 16 15:40:39 UTC 2015 - seife+obs@b1-systems.com + +- fix build on non-SUSE distributions whose rpm does not know + "Recommends" + +------------------------------------------------------------------- +Wed Jun 10 08:48:46 UTC 2015 - dmueller@suse.com + +- update to 2.4.0: + * A couple of security fixes plus maintenance updates. + +------------------------------------------------------------------- +Tue Oct 15 07:41:04 UTC 2013 - speilicke@suse.com + +- Initial version + diff --git a/python-pysaml2.spec b/python-pysaml2.spec new file mode 100644 index 0000000..46bf9d3 --- /dev/null +++ b/python-pysaml2.spec @@ -0,0 +1,120 @@ +# +# spec file for package python-pysaml2 +# +# Copyright (c) 2025 SUSE LLC +# +# All modifications and additions to the file contributed by third parties +# remain the property of their copyright owners, unless otherwise agreed +# upon. The license for this file, and modifications and additions to the +# file, is the same license as for the pristine package itself (unless the +# license for the pristine package is not an Open Source License, in which +# case the license is the MIT License). An "Open Source License" is a +# license that conforms to the Open Source Definition (Version 1.9) +# published by the Open Source Initiative. + +# Please submit bugfixes or comments via https://bugs.opensuse.org/ +# + + +%global modname pysaml2 +%{?sle15_python_module_pythons} +Name: python-pysaml2 +Version: 7.5.2 +Release: 0 +Summary: Python implementation of SAML Version 2 to be used in a WSGI environment +License: Apache-2.0 +URL: https://github.com/IdentityPython/pysaml2 +Source: https://github.com/IdentityPython/pysaml2/archive/v%{version}.tar.gz +# PATCH-FIX-UPSTREAM use-cryptography.patch https://github.com/IdentityPython/pysaml2/issues/879 +Patch0: use-cryptography.patch +BuildRequires: %{python_module Paste} +BuildRequires: %{python_module base >= 3.9} +BuildRequires: %{python_module cryptography >= 40.0} +BuildRequires: %{python_module dbm} +BuildRequires: %{python_module defusedxml} +BuildRequires: %{python_module pip} +BuildRequires: %{python_module poetry-core} +BuildRequires: %{python_module pymongo >= 3.5} +BuildRequires: %{python_module pytest} +BuildRequires: %{python_module python-dateutil} +BuildRequires: %{python_module pytz} +BuildRequires: %{python_module requests >= 1.0.0} +BuildRequires: %{python_module responses} +BuildRequires: %{python_module xmlschema >= 2} +BuildRequires: %{python_module zope.interface} +BuildRequires: fdupes +# This is needed as xmlsec itself does not pull any backend by default +# Will be fixed in future xmlsec releases +BuildRequires: libxmlsec1-openssl1 +BuildRequires: python-rpm-macros +BuildRequires: update-alternatives +BuildRequires: xmlsec1 +Requires: python-Paste +Requires: python-cryptography >= 3.1 +Requires: python-defusedxml +Requires: python-pyOpenSSL +Requires: python-pymongo >= 3.5 +Requires: python-python-dateutil +Requires: python-pytz +Requires: python-requests >= 1.0.0 +Requires: python-xmlschema >= 1.2.1 +Requires: python-zope.interface +Requires(post): update-alternatives +Requires(postun): update-alternatives +# We need to have arch build to make ifarch condition below working +# BuildArch: noarch +%python_subpackages + +%description +PySAML2 is a pure python implementation of SAML2. +It contains all necessary pieces for building a +SAML2 service provider or an identity provider. + +%prep +%autosetup -p1 -n %{modname}-%{version} + +# delete shebang of files not in executable path +find src/ -name '*.py' -print0 | xargs -0 sed -i '1s/#!.*$//' +# remove tests that poll internet +rm -f tests/test_30_mdstore*.py + +%build +%pyproject_wheel + +%install +%pyproject_install +for exec in make_metadata parse_xsd2 mdexport merge_metadata ; do +%python_clone -a %{buildroot}%{_bindir}/$exec +done +%python_expand rm -r %{buildroot}%{$python_sitelib}/saml2test +%python_expand %fdupes %{buildroot}%{$python_sitelib} + +%check +# https://github.com/IdentityPython/pysaml2/issues/858 +sed -i 's:import mock:from unittest import mock:' tests/test_41_response.py +sed -i 's:mock.mock:unittest.mock:' tests/test_52_default_sign_alg.py +# Excluded tests for i586 gh#IdentityPython/pysaml2#682 and gh#IdentityPython/pysaml2#759 +# Exclude broken namespace test (https://github.com/IdentityPython/pysaml2/issues/921) +%ifarch %{ix86} +%pytest -k "not (test_namespace_processing or test_assertion_consumer_service or test_swamid_sp or test_swamid_idp or test_other_response or test_mta or test_unknown_subject or test_filter_ava_registration_authority_1)" tests +%else +%pytest -k "not test_namespace_processing" tests +%endif + +%post +%python_install_alternative make_metadata parse_xsd2 mdexport merge_metadata + +%postun +%python_uninstall_alternative make_metadata parse_xsd2 mdexport merge_metadata + +%files %{python_files} +%license LICENSE +%doc README.md CHANGELOG.md +%python_alternative %{_bindir}/make_metadata +%python_alternative %{_bindir}/parse_xsd2 +%python_alternative %{_bindir}/mdexport +%python_alternative %{_bindir}/merge_metadata +%{python_sitelib}/saml2 +%{python_sitelib}/pysaml2-%{version}.dist-info + +%changelog diff --git a/use-cryptography.patch b/use-cryptography.patch new file mode 100644 index 0000000..d6fac74 --- /dev/null +++ b/use-cryptography.patch @@ -0,0 +1,342 @@ +From 930a652a240c8cd1489429a7d70cf5fa7ef1606a Mon Sep 17 00:00:00 2001 +From: Patrick Rauscher +Date: Wed, 12 Feb 2025 23:29:34 +0100 +Subject: [PATCH] replace pyopenssl with cryptography + +--- + pyproject.toml | 3 +- + src/saml2/cert.py | 178 ++++++++++++++++++++++++-------------------- + src/saml2/sigver.py | 12 +-- + 3 files changed, 105 insertions(+), 88 deletions(-) + +diff --git a/pyproject.toml b/pyproject.toml +index 985692043..8a7cd9185 100644 +--- a/pyproject.toml ++++ b/pyproject.toml +@@ -37,12 +37,11 @@ parse_xsd2 = "saml2.tools.parse_xsd2:main" + + [tool.poetry.dependencies] + python = "^3.9" +-cryptography = ">=3.1" ++cryptography = ">=40.0" + defusedxml = "*" + importlib-metadata = {version = ">=1.7.0", python = "<3.8"} + importlib-resources = {python = "<3.9", version = "*"} + paste = {optional = true, version = "*"} +-pyopenssl = "<24.3.0" + python-dateutil = "*" + pytz = "*" + "repoze.who" = {optional = true, version = "*"} +diff --git a/src/saml2/cert.py b/src/saml2/cert.py +index c5f626601..1759b9b24 100644 +--- a/src/saml2/cert.py ++++ b/src/saml2/cert.py +@@ -5,7 +5,11 @@ + from os import remove + from os.path import join + +-from OpenSSL import crypto ++from cryptography import x509 ++from cryptography.exceptions import InvalidSignature ++from cryptography.hazmat.primitives import hashes, serialization ++from cryptography.hazmat.primitives.asymmetric import rsa ++from cryptography.x509.oid import NameOID + import dateutil.parser + import pytz + +@@ -36,7 +40,6 @@ def create_certificate( + valid_to=315360000, + sn=1, + key_length=1024, +- hash_alg="sha256", + write_to_file=False, + cert_dir="", + cipher_passphrase=None, +@@ -87,8 +90,6 @@ def create_certificate( + is 1. + :param key_length: Length of the key to be generated. Defaults + to 1024. +- :param hash_alg: Hash algorithm to use for the key. Default +- is sha256. + :param write_to_file: True if you want to write the certificate + to a file. The method will then return + a tuple with path to certificate file and +@@ -131,49 +132,68 @@ def create_certificate( + k_f = join(cert_dir, key_file) + + # create a key pair +- k = crypto.PKey() +- k.generate_key(crypto.TYPE_RSA, key_length) ++ k = rsa.generate_private_key( ++ public_exponent=65537, ++ key_size=key_length, ++ ) + + # create a self-signed cert +- cert = crypto.X509() ++ builder = x509.CertificateBuilder() + + if request: +- cert = crypto.X509Req() ++ builder = x509.CertificateSigningRequestBuilder() + + if len(cert_info["country_code"]) != 2: + raise WrongInput("Country code must be two letters!") +- cert.get_subject().C = cert_info["country_code"] +- cert.get_subject().ST = cert_info["state"] +- cert.get_subject().L = cert_info["city"] +- cert.get_subject().O = cert_info["organization"] # noqa: E741 +- cert.get_subject().OU = cert_info["organization_unit"] +- cert.get_subject().CN = cn ++ subject_name = x509.Name([ ++ x509.NameAttribute(NameOID.COUNTRY_NAME, ++ cert_info["country_code"]), ++ x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, ++ cert_info["state"]), ++ x509.NameAttribute(NameOID.LOCALITY_NAME, ++ cert_info["city"]), ++ x509.NameAttribute(NameOID.ORGANIZATION_NAME, ++ cert_info["organization"]), ++ x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, ++ cert_info["organization_unit"]), ++ x509.NameAttribute(NameOID.COMMON_NAME, cn), ++ ]) ++ builder = builder.subject_name(subject_name) + if not request: +- cert.set_serial_number(sn) +- cert.gmtime_adj_notBefore(valid_from) # Valid before present time +- cert.gmtime_adj_notAfter(valid_to) # 3 650 days +- cert.set_issuer(cert.get_subject()) +- cert.set_pubkey(k) +- cert.sign(k, hash_alg) ++ now = datetime.datetime.now(datetime.UTC) ++ builder = builder.serial_number( ++ sn, ++ ).not_valid_before( ++ now + datetime.timedelta(seconds=valid_from), ++ ).not_valid_after( ++ now + datetime.timedelta(seconds=valid_to), ++ ).issuer_name( ++ subject_name, ++ ).public_key( ++ k.public_key(), ++ ) ++ cert = builder.sign(k, hashes.SHA256()) + + try: +- if request: +- tmp_cert = crypto.dump_certificate_request(crypto.FILETYPE_PEM, cert) +- else: +- tmp_cert = crypto.dump_certificate(crypto.FILETYPE_PEM, cert) +- tmp_key = None ++ tmp_cert = cert.public_bytes(serialization.Encoding.PEM) ++ key_encryption = None + if cipher_passphrase is not None: + passphrase = cipher_passphrase["passphrase"] + if isinstance(cipher_passphrase["passphrase"], str): + passphrase = passphrase.encode("utf-8") +- tmp_key = crypto.dump_privatekey(crypto.FILETYPE_PEM, k, cipher_passphrase["cipher"], passphrase) ++ key_encryption = serialization.BestAvailableEncryption(passphrase) + else: +- tmp_key = crypto.dump_privatekey(crypto.FILETYPE_PEM, k) ++ key_encryption = serialization.NoEncryption() ++ tmp_key = k.private_bytes( ++ encoding=serialization.Encoding.PEM, ++ format=serialization.PrivateFormat.TraditionalOpenSSL, ++ encryption_algorithm=key_encryption, ++ ) + if write_to_file: +- with open(c_f, "w") as fc: +- fc.write(tmp_cert.decode("utf-8")) +- with open(k_f, "w") as fk: +- fk.write(tmp_key.decode("utf-8")) ++ with open(c_f, "wb") as fc: ++ fc.write(tmp_cert) ++ with open(k_f, "wb") as fk: ++ fk.write(tmp_key) + return c_f, k_f + return tmp_cert, tmp_key + except Exception as ex: +@@ -198,7 +218,6 @@ def create_cert_signed_certificate( + sign_cert_str, + sign_key_str, + request_cert_str, +- hash_alg="sha256", + valid_from=0, + valid_to=315360000, + sn=1, +@@ -222,8 +241,6 @@ def create_cert_signed_certificate( + the requested certificate. If you only have + a file use the method read_str_from_file + to get a string representation. +- :param hash_alg: Hash algorithm to use for the key. Default +- is sha256. + :param valid_from: When the certificate starts to be valid. + Amount of seconds from when the + certificate is generated. +@@ -237,27 +254,29 @@ def create_cert_signed_certificate( + :return: String representation of the signed + certificate. + """ +- ca_cert = crypto.load_certificate(crypto.FILETYPE_PEM, sign_cert_str) +- ca_key = None +- if passphrase is not None: +- ca_key = crypto.load_privatekey(crypto.FILETYPE_PEM, sign_key_str, passphrase) +- else: +- ca_key = crypto.load_privatekey(crypto.FILETYPE_PEM, sign_key_str) +- req_cert = crypto.load_certificate_request(crypto.FILETYPE_PEM, request_cert_str) +- +- cert = crypto.X509() +- cert.set_subject(req_cert.get_subject()) +- cert.set_serial_number(sn) +- cert.gmtime_adj_notBefore(valid_from) +- cert.gmtime_adj_notAfter(valid_to) +- cert.set_issuer(ca_cert.get_subject()) +- cert.set_pubkey(req_cert.get_pubkey()) +- cert.sign(ca_key, hash_alg) +- +- cert_dump = crypto.dump_certificate(crypto.FILETYPE_PEM, cert) +- if isinstance(cert_dump, str): +- return cert_dump +- return cert_dump.decode("utf-8") ++ if isinstance(sign_cert_str, str): ++ sign_cert_str = sign_cert_str.encode("utf-8") ++ ca_cert = x509.load_pem_x509_certificate(sign_cert_str) ++ ca_key = serialization.load_pem_private_key( ++ sign_key_str, password=passphrase) ++ req_cert = x509.load_pem_x509_csr(request_cert_str) ++ ++ now = datetime.datetime.now(datetime.UTC) ++ cert = x509.CertificateBuilder().subject_name( ++ req_cert.subject, ++ ).serial_number( ++ sn, ++ ).not_valid_before( ++ now + datetime.timedelta(seconds=valid_from), ++ ).not_valid_after( ++ now + datetime.timedelta(seconds=valid_to), ++ ).issuer_name( ++ ca_cert.subject, ++ ).public_key( ++ req_cert.public_key(), ++ ).sign(ca_key, hashes.SHA256()) ++ ++ return cert.public_bytes(serialization.Encoding.PEM).decode("utf-8") + + def verify_chain(self, cert_chain_str_list, cert_str): + """ +@@ -276,13 +295,6 @@ def verify_chain(self, cert_chain_str_list, cert_str): + cert_str = tmp_cert_str + return (True, "Signed certificate is valid and correctly signed by CA " "certificate.") + +- def certificate_not_valid_yet(self, cert): +- starts_to_be_valid = dateutil.parser.parse(cert.get_notBefore()) +- now = pytz.UTC.localize(datetime.datetime.utcnow()) +- if starts_to_be_valid < now: +- return False +- return True +- + def verify(self, signing_cert_str, cert_str): + """ + Verifies if a certificate is valid and signed by a given certificate. +@@ -303,34 +315,34 @@ def verify(self, signing_cert_str, cert_str): + Message = Why the validation failed. + """ + try: +- ca_cert = crypto.load_certificate(crypto.FILETYPE_PEM, signing_cert_str) +- cert = crypto.load_certificate(crypto.FILETYPE_PEM, cert_str) +- +- if self.certificate_not_valid_yet(ca_cert): ++ if isinstance(signing_cert_str, str): ++ signing_cert_str = signing_cert_str.encode("utf-8") ++ if isinstance(cert_str, str): ++ cert_str = cert_str.encode("utf-8") ++ ca_cert = x509.load_pem_x509_certificate(signing_cert_str) ++ cert = x509.load_pem_x509_certificate(cert_str) ++ now = datetime.datetime.now(datetime.UTC) ++ ++ if ca_cert.not_valid_before_utc >= now: + return False, "CA certificate is not valid yet." + +- if ca_cert.has_expired() == 1: ++ if ca_cert.not_valid_after_utc < now: + return False, "CA certificate is expired." + +- if cert.has_expired() == 1: ++ if cert.not_valid_after_utc < now: + return False, "The signed certificate is expired." + +- if self.certificate_not_valid_yet(cert): ++ if cert.not_valid_before_utc >= now: + return False, "The signed certificate is not valid yet." + +- if ca_cert.get_subject().CN == cert.get_subject().CN: ++ if ca_cert.subject.get_attributes_for_oid(NameOID.COMMON_NAME) == \ ++ cert.subject.get_attributes_for_oid(NameOID.COMMON_NAME): + return False, ("CN may not be equal for CA certificate and the " "signed certificate.") + +- cert_algorithm = cert.get_signature_algorithm() +- cert_algorithm = cert_algorithm.decode("ascii") +- cert_str = cert_str.encode("ascii") +- +- cert_crypto = saml2.cryptography.pki.load_pem_x509_certificate(cert_str) +- + try: +- crypto.verify(ca_cert, cert_crypto.signature, cert_crypto.tbs_certificate_bytes, cert_algorithm) ++ cert.verify_directly_issued_by(ca_cert) + return True, "Signed certificate is valid and correctly signed by CA certificate." +- except crypto.Error as e: ++ except (ValueError, TypeError, InvalidSignature) as e: + return False, f"Certificate is incorrectly signed: {str(e)}" + except Exception as e: + return False, f"Certificate is not valid for an unknown reason. {str(e)}" +@@ -352,8 +364,14 @@ def read_cert_from_file(cert_file, cert_type="pem"): + data = fp.read() + + try: +- cert = saml2.cryptography.pki.load_x509_certificate(data, cert_type) +- pem_data = saml2.cryptography.pki.get_public_bytes_from_cert(cert) ++ cert = None ++ if cert_type == "pem": ++ cert = x509.load_pem_x509_certificate(data) ++ elif cert_type == "der": ++ cert = x509.load_der_x509_certificate(data) ++ else: ++ raise ValueError(f"cert-type {cert_type} not supported") ++ pem_data = cert.public_bytes(serialization.Encoding.PEM).decode("utf-8") + except Exception as e: + raise CertificateError(e) + +diff --git a/src/saml2/sigver.py b/src/saml2/sigver.py +index f3af1ec99..98d11b1d1 100644 +--- a/src/saml2/sigver.py ++++ b/src/saml2/sigver.py +@@ -28,7 +28,7 @@ + + from urllib import parse + +-from OpenSSL import crypto ++from cryptography import x509 + import pytz + + from saml2 import ExtensionElement +@@ -383,14 +383,14 @@ def active_cert(key): + """ + try: + cert_str = pem_format(key) +- cert = crypto.load_certificate(crypto.FILETYPE_PEM, cert_str) ++ cert = x509.load_pem_x509_certificate(cert_str) + except AttributeError: + return False + +- now = pytz.UTC.localize(datetime.datetime.utcnow()) +- valid_from = dateutil.parser.parse(cert.get_notBefore()) +- valid_to = dateutil.parser.parse(cert.get_notAfter()) +- active = not cert.has_expired() and valid_from <= now < valid_to ++ now = datetime.datetime.now(datetime.UTC) ++ valid_from = cert.not_valid_before_utc ++ valid_to = cert.not_valid_after_utc ++ active = valid_from <= now < valid_to + return active + + diff --git a/v7.4.2.tar.gz b/v7.4.2.tar.gz new file mode 100644 index 0000000..de20456 --- /dev/null +++ b/v7.4.2.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dfeaa53854467cdcdae1b0fb2c76a3610f8b179dca8176757d245db7fa7ad806 +size 6059879 diff --git a/v7.5.0.tar.gz b/v7.5.0.tar.gz new file mode 100644 index 0000000..6511322 --- /dev/null +++ b/v7.5.0.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2b93b50b768711e5ffc96c0b5630c1e50b3160335e267ed902d3a535385e9418 +size 6065861 diff --git a/v7.5.2.tar.gz b/v7.5.2.tar.gz new file mode 100644 index 0000000..6dad2e5 --- /dev/null +++ b/v7.5.2.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f0bed0419258f6c8540b9d3eace7815206c337f61c91fb253b53e39eafa707a4 +size 6070199