././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1661028173.9695654 xmlsec-1.3.13/0000755000175100001710000000000014300243516012467 5ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/.pre-commit-config.yaml0000644000175100001710000000273414300243501016750 0ustar00runnerdocker# See https://pre-commit.com for more information # See https://pre-commit.com/hooks.html for more hooks exclude: ".*.diff" # exclude patches repos: - repo: https://github.com/psf/black rev: 22.6.0 hooks: - id: black types: [] files: ^.*.pyi?$ exclude: ^doc/ - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.3.0 hooks: - id: no-commit-to-branch - id: trailing-whitespace - id: end-of-file-fixer - id: check-yaml - id: check-added-large-files - id: check-ast - id: check-merge-conflict - id: check-json - id: detect-private-key - id: mixed-line-ending - id: pretty-format-json args: [--autofix] - repo: https://github.com/PyCQA/flake8 rev: 5.0.4 hooks: - id: flake8 exclude: ^setup.py$ additional_dependencies: [flake8-docstrings, flake8-bugbear, flake8-logging-format, flake8-builtins, flake8-eradicate, flake8-fixme, pep8-naming, flake8-pep3101, flake8-annotations-complexity,flake8-pyi] - repo: https://github.com/PyCQA/isort rev: 5.10.1 hooks: - id: isort - repo: https://github.com/pre-commit/mirrors-mypy rev: v0.971 hooks: - id: mypy exclude: (setup.py|tests/.*.py|doc/.*) types: [] files: ^.*.pyi?$ additional_dependencies: [lxml-stubs,types-docutils] - repo: https://github.com/pre-commit/pygrep-hooks rev: v1.9.0 hooks: - id: rst-backticks ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/.readthedocs.yaml0000644000175100001710000000032214300243501015705 0ustar00runnerdockerversion: 2 build: os: ubuntu-20.04 tools: python: '3.9' sphinx: configuration: doc/source/conf.py python: install: - method: pip path: . - requirements: doc/source/requirements.txt ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/LICENSE0000644000175100001710000000206614300243501013472 0ustar00runnerdockerThe MIT License (MIT) Copyright (c) 2014 Ryan Leckey Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/MANIFEST.in0000644000175100001710000000046314300243501014222 0ustar00runnerdockerrecursive-include src * recursive-include tests * prune */__pycache__ prune .github prune doc exclude .appveyor.yml exclude .editorconfig exclude .travis.yml exclude .gitattributes exclude .gitignore exclude requirements-test.txt exclude requirements.txt exclude xmlsec_extra.py exclude xmlsec_setupinfo.py ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1661028173.9695654 xmlsec-1.3.13/PKG-INFO0000644000175100001710000001544714300243516013577 0ustar00runnerdockerMetadata-Version: 2.1 Name: xmlsec Version: 1.3.13 Summary: Python bindings for the XML Security Library Home-page: https://github.com/mehcode/python-xmlsec Author: Bulat Gaifullin Author-email: support@mehcode.com Maintainer: Oleg Hoefling Maintainer-email: oleg.hoefling@gmail.com License: MIT Project-URL: Documentation, https://xmlsec.readthedocs.io Project-URL: Source, https://github.com/mehcode/python-xmlsec Project-URL: Changelog, https://github.com/mehcode/python-xmlsec/releases Keywords: xmlsec Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: Intended Audience :: System Administrators Classifier: License :: OSI Approved :: MIT License Classifier: Operating System :: OS Independent Classifier: Programming Language :: C Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Topic :: Text Processing :: Markup :: XML Classifier: Typing :: Typed Requires-Python: >=3.5 License-File: LICENSE python-xmlsec ============= .. image:: https://img.shields.io/pypi/v/xmlsec.svg?logo=python&logoColor=white :target: https://pypi.python.org/pypi/xmlsec .. image:: https://img.shields.io/travis/com/mehcode/python-xmlsec/master.svg?logo=travis&logoColor=white&label=Travis%20CI :target: https://travis-ci.org/mehcode/python-xmlsec .. image:: https://img.shields.io/appveyor/ci/hoefling/xmlsec/master.svg?logo=appveyor&logoColor=white&label=AppVeyor :target: https://ci.appveyor.com/project/hoefling/xmlsec .. image:: https://github.com/mehcode/python-xmlsec/workflows/manylinux2010/badge.svg :target: https://github.com/mehcode/python-xmlsec/actions?query=workflow%3A%22manylinux2010%22 .. image:: https://github.com/mehcode/python-xmlsec/workflows/MacOS/badge.svg :target: https://github.com/mehcode/python-xmlsec/actions?query=workflow%3A%22MacOS%22 .. image:: https://github.com/mehcode/python-xmlsec/workflows/linuxbrew/badge.svg :target: https://github.com/mehcode/python-xmlsec/actions?query=workflow%3A%22linuxbrew%22 .. image:: https://codecov.io/gh/mehcode/python-xmlsec/branch/master/graph/badge.svg :target: https://codecov.io/gh/mehcode/python-xmlsec .. image:: https://img.shields.io/readthedocs/xmlsec/latest?logo=read-the-docs :target: https://xmlsec.readthedocs.io/en/latest/?badge=latest :alt: Documentation Status Python bindings for the `XML Security Library `_. Documentation ************* A documentation for ``xmlsec`` can be found at `xmlsec.readthedocs.io `_. Usage ***** Check the `examples `_ section in the documentation to see various examples of signing and verifying using the library. Requirements ************ - ``libxml2 >= 2.9.1`` - ``libxmlsec1 >= 1.2.18`` Install ******* ``xmlsec`` is available on PyPI: .. code-block:: bash pip install xmlsec Depending on your OS, you may need to install the required native libraries first: Linux (Debian) ^^^^^^^^^^^^^^ .. code-block:: bash apt-get install pkg-config libxml2-dev libxmlsec1-dev libxmlsec1-openssl Note: There is no required version of LibXML2 for Ubuntu Precise, so you need to download and install it manually. .. code-block:: bash wget http://xmlsoft.org/sources/libxml2-2.9.1.tar.gz tar -xvf libxml2-2.9.1.tar.gz cd libxml2-2.9.1 ./configure && make && make install Linux (CentOS) ^^^^^^^^^^^^^^ .. code-block:: bash yum install libxml2-devel xmlsec1-devel xmlsec1-openssl-devel libtool-ltdl-devel Linux (Fedora) ^^^^^^^^^^^^^^ .. code-block:: bash dnf install libxml2-devel xmlsec1-devel xmlsec1-openssl-devel libtool-ltdl-devel Mac ^^^ .. code-block:: bash brew install libxml2 libxmlsec1 pkg-config Alpine ^^^^^^ .. code-block:: bash apk add build-base libressl libffi-dev libressl-dev libxslt-dev libxml2-dev xmlsec-dev xmlsec Troubleshooting *************** Mac ^^^ If you get any fatal errors about missing ``.h`` files, update your ``C_INCLUDE_PATH`` environment variable to include the appropriate files from the ``libxml2`` and ``libxmlsec1`` libraries. Windows ^^^^^^^ Starting with 1.3.7, prebuilt wheels are available for Windows, so running ``pip install xmlsec`` should suffice. If you want to build from source: #. Configure build environment, see `wiki.python.org `_ for more details. #. Install from source dist: .. code-block:: bash pip install xmlsec --no-binary=xmlsec Building from source ******************** #. Clone the ``xmlsec`` source code repository to your local computer. .. code-block:: bash git clone https://github.com/mehcode/python-xmlsec.git #. Change into the ``python-xmlsec`` root directory. .. code-block:: bash cd /path/to/xmlsec #. Install the project and all its dependencies using ``pip``. .. code-block:: bash pip install . Contributing ************ Setting up your environment ^^^^^^^^^^^^^^^^^^^^^^^^^^^ #. Follow steps 1 and 2 of the `manual installation instructions <#building-from-source>`_. #. Initialize a virtual environment to develop in. This is done so as to ensure every contributor is working with close-to-identicial versions of packages. .. code-block:: bash mkvirtualenv xmlsec The ``mkvirtualenv`` command is available from ``virtualenvwrapper`` package which can be installed by following `link `_. #. Activate the created virtual environment: .. code-block:: bash workon xmlsec #. Install ``xmlsec`` in development mode with testing enabled. This will download all dependencies required for running the unit tests. .. code-block:: bash pip install -r requirements-test.txt pip install -e "." Running the test suite ^^^^^^^^^^^^^^^^^^^^^^ #. `Set up your environment <#setting-up-your-environment>`_. #. Run the unit tests. .. code-block:: bash pytest tests #. Tests configuration Env variable ``PYXMLSEC_TEST_ITERATIONS`` specifies number of test iterations to detect memory leaks. Reporting an issue ^^^^^^^^^^^^^^^^^^ Please attach the output of following information: * version of ``xmlsec`` * version of ``libxmlsec1`` * version of ``libxml2`` * output from the command .. code-block:: bash pkg-config --cflags xmlsec1 License ******* Unless otherwise noted, all files contained within this project are licensed under the MIT opensource license. See the included ``LICENSE`` file or visit `opensource.org `_ for more information. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/README.rst0000644000175100001710000001313714300243501014155 0ustar00runnerdockerpython-xmlsec ============= .. image:: https://img.shields.io/pypi/v/xmlsec.svg?logo=python&logoColor=white :target: https://pypi.python.org/pypi/xmlsec .. image:: https://img.shields.io/travis/com/mehcode/python-xmlsec/master.svg?logo=travis&logoColor=white&label=Travis%20CI :target: https://travis-ci.org/mehcode/python-xmlsec .. image:: https://img.shields.io/appveyor/ci/hoefling/xmlsec/master.svg?logo=appveyor&logoColor=white&label=AppVeyor :target: https://ci.appveyor.com/project/hoefling/xmlsec .. image:: https://github.com/mehcode/python-xmlsec/workflows/manylinux2010/badge.svg :target: https://github.com/mehcode/python-xmlsec/actions?query=workflow%3A%22manylinux2010%22 .. image:: https://github.com/mehcode/python-xmlsec/workflows/MacOS/badge.svg :target: https://github.com/mehcode/python-xmlsec/actions?query=workflow%3A%22MacOS%22 .. image:: https://github.com/mehcode/python-xmlsec/workflows/linuxbrew/badge.svg :target: https://github.com/mehcode/python-xmlsec/actions?query=workflow%3A%22linuxbrew%22 .. image:: https://codecov.io/gh/mehcode/python-xmlsec/branch/master/graph/badge.svg :target: https://codecov.io/gh/mehcode/python-xmlsec .. image:: https://img.shields.io/readthedocs/xmlsec/latest?logo=read-the-docs :target: https://xmlsec.readthedocs.io/en/latest/?badge=latest :alt: Documentation Status Python bindings for the `XML Security Library `_. Documentation ************* A documentation for ``xmlsec`` can be found at `xmlsec.readthedocs.io `_. Usage ***** Check the `examples `_ section in the documentation to see various examples of signing and verifying using the library. Requirements ************ - ``libxml2 >= 2.9.1`` - ``libxmlsec1 >= 1.2.18`` Install ******* ``xmlsec`` is available on PyPI: .. code-block:: bash pip install xmlsec Depending on your OS, you may need to install the required native libraries first: Linux (Debian) ^^^^^^^^^^^^^^ .. code-block:: bash apt-get install pkg-config libxml2-dev libxmlsec1-dev libxmlsec1-openssl Note: There is no required version of LibXML2 for Ubuntu Precise, so you need to download and install it manually. .. code-block:: bash wget http://xmlsoft.org/sources/libxml2-2.9.1.tar.gz tar -xvf libxml2-2.9.1.tar.gz cd libxml2-2.9.1 ./configure && make && make install Linux (CentOS) ^^^^^^^^^^^^^^ .. code-block:: bash yum install libxml2-devel xmlsec1-devel xmlsec1-openssl-devel libtool-ltdl-devel Linux (Fedora) ^^^^^^^^^^^^^^ .. code-block:: bash dnf install libxml2-devel xmlsec1-devel xmlsec1-openssl-devel libtool-ltdl-devel Mac ^^^ .. code-block:: bash brew install libxml2 libxmlsec1 pkg-config Alpine ^^^^^^ .. code-block:: bash apk add build-base libressl libffi-dev libressl-dev libxslt-dev libxml2-dev xmlsec-dev xmlsec Troubleshooting *************** Mac ^^^ If you get any fatal errors about missing ``.h`` files, update your ``C_INCLUDE_PATH`` environment variable to include the appropriate files from the ``libxml2`` and ``libxmlsec1`` libraries. Windows ^^^^^^^ Starting with 1.3.7, prebuilt wheels are available for Windows, so running ``pip install xmlsec`` should suffice. If you want to build from source: #. Configure build environment, see `wiki.python.org `_ for more details. #. Install from source dist: .. code-block:: bash pip install xmlsec --no-binary=xmlsec Building from source ******************** #. Clone the ``xmlsec`` source code repository to your local computer. .. code-block:: bash git clone https://github.com/mehcode/python-xmlsec.git #. Change into the ``python-xmlsec`` root directory. .. code-block:: bash cd /path/to/xmlsec #. Install the project and all its dependencies using ``pip``. .. code-block:: bash pip install . Contributing ************ Setting up your environment ^^^^^^^^^^^^^^^^^^^^^^^^^^^ #. Follow steps 1 and 2 of the `manual installation instructions <#building-from-source>`_. #. Initialize a virtual environment to develop in. This is done so as to ensure every contributor is working with close-to-identicial versions of packages. .. code-block:: bash mkvirtualenv xmlsec The ``mkvirtualenv`` command is available from ``virtualenvwrapper`` package which can be installed by following `link `_. #. Activate the created virtual environment: .. code-block:: bash workon xmlsec #. Install ``xmlsec`` in development mode with testing enabled. This will download all dependencies required for running the unit tests. .. code-block:: bash pip install -r requirements-test.txt pip install -e "." Running the test suite ^^^^^^^^^^^^^^^^^^^^^^ #. `Set up your environment <#setting-up-your-environment>`_. #. Run the unit tests. .. code-block:: bash pytest tests #. Tests configuration Env variable ``PYXMLSEC_TEST_ITERATIONS`` specifies number of test iterations to detect memory leaks. Reporting an issue ^^^^^^^^^^^^^^^^^^ Please attach the output of following information: * version of ``xmlsec`` * version of ``libxmlsec1`` * version of ``libxml2`` * output from the command .. code-block:: bash pkg-config --cflags xmlsec1 License ******* Unless otherwise noted, all files contained within this project are licensed under the MIT opensource license. See the included ``LICENSE`` file or visit `opensource.org `_ for more information. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/pyproject.toml0000644000175100001710000000210214300243501015370 0ustar00runnerdocker[tool.mypy] files = ['src'] ignore_missing_imports = false warn_unused_configs = true disallow_subclassing_any = true disallow_any_generics = true disallow_untyped_calls = true disallow_untyped_defs = true disallow_incomplete_defs = true check_untyped_defs = true disallow_untyped_decorators = true disallow_any_unimported = true strict_optional = true no_implicit_optional = true warn_redundant_casts = true warn_unused_ignores = true warn_return_any = true warn_no_return = true no_implicit_reexport = true show_error_codes = true [tool.black] line_length = 130 skip-string-normalization = true target_version = ['py39'] include = '\.pyi?$' exclude = ''' ( /( \.eggs # exclude a few common directories in the | \.git # root of the project | \.mypy_cache | \.tox | build | dist )/ ) ''' [tool.isort] profile = 'black' known_first_party = ['xmlsec'] known_third_party = ['lxml', 'pytest', '_pytest', 'hypothesis'] [build-system] requires = ['setuptools>=42', 'wheel', 'setuptools_scm[toml]>=3.4', "pkgconfig>=1.5.1", "lxml>=3.8, !=4.7.0"] ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1661028173.9695654 xmlsec-1.3.13/setup.cfg0000644000175100001710000000102314300243516014304 0ustar00runnerdocker[metadata] description_file = README.rst [bdist_rpm] release = 1 build_requires = pkg-config xmlsec1-devel libxml2-devel xmlsec1-openssl-devel group = Development/Libraries requires = xmlsec1 xmlsec1-openssl [build_sphinx] source-dir = doc/source build-dir = doc/build all_files = 1 [upload_docs] upload_dir = doc/build/html [flake8] per-file-ignores = *.pyi: E301, E302, E305, E501, E701, F401, F822 exclude = .venv*,.git,*_pb2.pyi,build,dist,libs,.eggs,.direnv* max-line-length = 130 [egg_info] tag_build = tag_date = 0 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/setup.py0000644000175100001710000005330114300243501014175 0ustar00runnerdockerimport contextlib import html.parser import io import json import multiprocessing import os import re import subprocess import sys import tarfile import zipfile from distutils import log from distutils.errors import DistutilsError from distutils.version import StrictVersion as Version from pathlib import Path from urllib.request import urlcleanup, urljoin, urlopen, urlretrieve from setuptools import Extension, setup from setuptools.command.build_ext import build_ext as build_ext_orig class HrefCollector(html.parser.HTMLParser): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.hrefs = [] def handle_starttag(self, tag, attrs): if tag == 'a': for name, value in attrs: if name == 'href': self.hrefs.append(value) def latest_release_from_html(url, matcher): with contextlib.closing(urlopen(url)) as r: charset = r.headers.get_content_charset() or 'utf-8' content = r.read().decode(charset) collector = HrefCollector() collector.feed(content) hrefs = collector.hrefs def comp(text): try: return Version(matcher.match(text).groupdict()['version']) except (AttributeError, ValueError): return Version('0.0') latest = max(hrefs, key=comp) return '{}/{}'.format(url, latest) def latest_release_from_gnome_org_cache(url, lib_name): cache_url = '{}/cache.json'.format(url) with contextlib.closing(urlopen(cache_url)) as r: cache = json.load(r) latest_version = cache[2][lib_name][-1] latest_source = cache[1][lib_name][latest_version]['tar.xz'] return '{}/{}'.format(url, latest_source) def latest_zlib_release(): return latest_release_from_html('https://zlib.net/fossils', re.compile('zlib-(?P.*).tar.gz')) def latest_libiconv_release(): return latest_release_from_html('https://ftp.gnu.org/pub/gnu/libiconv', re.compile('libiconv-(?P.*).tar.gz')) def latest_libxml2_release(): return latest_release_from_gnome_org_cache('https://download.gnome.org/sources/libxml2', 'libxml2') def latest_libxslt_release(): return latest_release_from_gnome_org_cache('https://download.gnome.org/sources/libxslt', 'libxslt') def latest_xmlsec_release(): return latest_release_from_html('https://www.aleksey.com/xmlsec/download/', re.compile('xmlsec1-(?P.*).tar.gz')) class build_ext(build_ext_orig): def info(self, message): self.announce(message, level=log.INFO) def run(self): ext = self.ext_map['xmlsec'] self.debug = os.environ.get('PYXMLSEC_ENABLE_DEBUG', False) self.static = os.environ.get('PYXMLSEC_STATIC_DEPS', False) if self.static or sys.platform == 'win32': self.info('starting static build on {}'.format(sys.platform)) buildroot = Path('build', 'tmp') self.prefix_dir = buildroot / 'prefix' self.prefix_dir.mkdir(parents=True, exist_ok=True) self.prefix_dir = self.prefix_dir.absolute() self.build_libs_dir = buildroot / 'libs' self.build_libs_dir.mkdir(exist_ok=True) self.libs_dir = Path(os.environ.get('PYXMLSEC_LIBS_DIR', 'libs')) self.libs_dir.mkdir(exist_ok=True) self.info('{:20} {}'.format('Lib sources in:', self.libs_dir.absolute())) if sys.platform == 'win32': self.prepare_static_build_win() elif 'linux' in sys.platform: self.prepare_static_build_linux() else: import pkgconfig try: config = pkgconfig.parse('xmlsec1') except EnvironmentError: raise DistutilsError('Unable to invoke pkg-config.') except pkgconfig.PackageNotFoundError: raise DistutilsError('xmlsec1 is not installed or not in path.') if config is None or not config.get('libraries'): raise DistutilsError('Bad or incomplete result returned from pkg-config.') ext.define_macros.extend(config['define_macros']) ext.include_dirs.extend(config['include_dirs']) ext.library_dirs.extend(config['library_dirs']) ext.libraries.extend(config['libraries']) import lxml ext.include_dirs.extend(lxml.get_include()) ext.define_macros.extend( [('MODULE_NAME', self.distribution.metadata.name), ('MODULE_VERSION', self.distribution.metadata.version)] ) # escape the XMLSEC_CRYPTO macro value, see mehcode/python-xmlsec#141 for (key, value) in ext.define_macros: if key == 'XMLSEC_CRYPTO' and not (value.startswith('"') and value.endswith('"')): ext.define_macros.remove((key, value)) ext.define_macros.append((key, '"{0}"'.format(value))) break if sys.platform == 'win32': ext.extra_compile_args.append('/Zi') else: ext.extra_compile_args.extend( [ '-g', '-std=c99', '-fPIC', '-fno-strict-aliasing', '-Wno-error=declaration-after-statement', '-Werror=implicit-function-declaration', ] ) if self.debug: ext.extra_compile_args.append('-Wall') ext.extra_compile_args.append('-O0') ext.define_macros.append(('PYXMLSEC_ENABLE_DEBUG', '1')) else: ext.extra_compile_args.append('-Os') super(build_ext, self).run() def prepare_static_build_win(self): release_url = 'https://github.com/bgaifullin/libxml2-win-binaries/releases/download/v2018.08/' if sys.maxsize > 2147483647: suffix = 'win64' else: suffix = 'win32' libs = [ 'libxml2-2.9.4.{}.zip'.format(suffix), 'libxslt-1.1.29.{}.zip'.format(suffix), 'zlib-1.2.8.{}.zip'.format(suffix), 'iconv-1.14.{}.zip'.format(suffix), 'openssl-1.0.1.{}.zip'.format(suffix), 'xmlsec-1.2.24.{}.zip'.format(suffix), ] for libfile in libs: url = urljoin(release_url, libfile) destfile = self.libs_dir / libfile if destfile.is_file(): self.info('Using local copy of "{}"'.format(url)) else: self.info('Retrieving "{}" to "{}"'.format(url, destfile)) urlcleanup() # work around FTP bug 27973 in Py2.7.12+ urlretrieve(url, str(destfile)) for p in self.libs_dir.glob('*.zip'): with zipfile.ZipFile(str(p)) as f: destdir = self.build_libs_dir f.extractall(path=str(destdir)) ext = self.ext_map['xmlsec'] ext.define_macros = [ ('XMLSEC_CRYPTO', '\\"openssl\\"'), ('__XMLSEC_FUNCTION__', '__FUNCTION__'), ('XMLSEC_NO_GOST', '1'), ('XMLSEC_NO_XKMS', '1'), ('XMLSEC_NO_CRYPTO_DYNAMIC_LOADING', '1'), ('XMLSEC_CRYPTO_OPENSSL', '1'), ('UNICODE', '1'), ('_UNICODE', '1'), ('LIBXML_ICONV_ENABLED', 1), ('LIBXML_STATIC', '1'), ('LIBXSLT_STATIC', '1'), ('XMLSEC_STATIC', '1'), ('inline', '__inline'), ] ext.libraries = [ 'libxmlsec_a', 'libxmlsec-openssl_a', 'libeay32', 'iconv_a', 'libxslt_a', 'libexslt_a', 'libxml2_a', 'zlib', 'WS2_32', 'Advapi32', 'User32', 'Gdi32', 'Crypt32', ] ext.library_dirs = [str(p.absolute()) for p in self.build_libs_dir.rglob('lib')] includes = [p for p in self.build_libs_dir.rglob('include') if p.is_dir()] includes.append(next(p / 'xmlsec' for p in includes if (p / 'xmlsec').is_dir())) ext.include_dirs = [str(p.absolute()) for p in includes] def prepare_static_build_linux(self): self.openssl_version = os.environ.get('PYXMLSEC_OPENSSL_VERSION', '1.1.1q') self.libiconv_version = os.environ.get('PYXMLSEC_LIBICONV_VERSION') self.libxml2_version = os.environ.get('PYXMLSEC_LIBXML2_VERSION') self.libxslt_version = os.environ.get('PYXMLSEC_LIBXSLT_VERSION') self.zlib_version = os.environ.get('PYXMLSEC_ZLIB_VERSION') self.xmlsec1_version = os.environ.get('PYXMLSEC_XMLSEC1_VERSION') # fetch openssl openssl_tar = next(self.libs_dir.glob('openssl*.tar.gz'), None) if openssl_tar is None: self.info('{:10}: {}'.format('OpenSSL', 'source tar not found, downloading ...')) openssl_tar = self.libs_dir / 'openssl.tar.gz' self.info('{:10}: {} {}'.format('OpenSSL', 'version', self.openssl_version)) urlretrieve('https://www.openssl.org/source/openssl-{}.tar.gz'.format(self.openssl_version), str(openssl_tar)) # fetch zlib zlib_tar = next(self.libs_dir.glob('zlib*.tar.gz'), None) if zlib_tar is None: self.info('{:10}: {}'.format('zlib', 'source not found, downloading ...')) zlib_tar = self.libs_dir / 'zlib.tar.gz' if self.zlib_version is None: url = latest_zlib_release() self.info('{:10}: {}'.format('zlib', 'PYXMLSEC_ZLIB_VERSION unset, downloading latest from {}'.format(url))) else: url = 'https://zlib.net/fossils/zlib-{}.tar.gz'.format(self.zlib_version) self.info( '{:10}: {}'.format('zlib', 'PYXMLSEC_ZLIB_VERSION={}, downloading from {}'.format(self.zlib_version, url)) ) urlretrieve(url, str(zlib_tar)) # fetch libiconv libiconv_tar = next(self.libs_dir.glob('libiconv*.tar.gz'), None) if libiconv_tar is None: self.info('{:10}: {}'.format('libiconv', 'source not found, downloading ...')) libiconv_tar = self.libs_dir / 'libiconv.tar.gz' if self.libiconv_version is None: url = latest_libiconv_release() self.info('{:10}: {}'.format('zlib', 'PYXMLSEC_LIBICONV_VERSION unset, downloading latest from {}'.format(url))) else: url = 'https://ftp.gnu.org/pub/gnu/libiconv/libiconv-{}.tar.gz'.format(self.libiconv_version) self.info( '{:10}: {}'.format( 'zlib', 'PYXMLSEC_LIBICONV_VERSION={}, downloading from {}'.format(self.libiconv_version, url) ) ) urlretrieve(url, str(libiconv_tar)) # fetch libxml2 libxml2_tar = next(self.libs_dir.glob('libxml2*.tar.xz'), None) if libxml2_tar is None: self.info('{:10}: {}'.format('libxml2', 'source tar not found, downloading ...')) if self.libxml2_version is None: url = latest_libxml2_release() self.info('{:10}: {}'.format('libxml2', 'PYXMLSEC_LIBXML2_VERSION unset, downloading latest from {}'.format(url))) else: version_prefix, _ = self.libxml2_version.rsplit('.', 1) url = 'https://download.gnome.org/sources/libxml2/{}/libxml2-{}.tar.xz'.format( version_prefix, self.libxml2_version ) self.info( '{:10}: {}'.format( 'libxml2', 'PYXMLSEC_LIBXML2_VERSION={}, downloading from {}'.format(self.libxml2_version, url) ) ) libxml2_tar = self.libs_dir / 'libxml2.tar.xz' urlretrieve(url, str(libxml2_tar)) # fetch libxslt libxslt_tar = next(self.libs_dir.glob('libxslt*.tar.gz'), None) if libxslt_tar is None: self.info('{:10}: {}'.format('libxslt', 'source tar not found, downloading ...')) if self.libxslt_version is None: url = latest_libxslt_release() self.info('{:10}: {}'.format('libxslt', 'PYXMLSEC_LIBXSLT_VERSION unset, downloading latest from {}'.format(url))) else: version_prefix, _ = self.libxslt_version.rsplit('.', 1) url = 'https://download.gnome.org/sources/libxslt/{}/libxslt-{}.tar.xz'.format( version_prefix, self.libxslt_version ) self.info( '{:10}: {}'.format( 'libxslt', 'PYXMLSEC_LIBXSLT_VERSION={}, downloading from {}'.format(self.libxslt_version, url) ) ) libxslt_tar = self.libs_dir / 'libxslt.tar.gz' urlretrieve(url, str(libxslt_tar)) # fetch xmlsec1 xmlsec1_tar = next(self.libs_dir.glob('xmlsec1*.tar.gz'), None) if xmlsec1_tar is None: self.info('{:10}: {}'.format('xmlsec1', 'source tar not found, downloading ...')) if self.xmlsec1_version is None: url = latest_xmlsec_release() self.info('{:10}: {}'.format('xmlsec1', 'PYXMLSEC_XMLSEC1_VERSION unset, downloading latest from {}'.format(url))) else: url = 'https://www.aleksey.com/xmlsec/download/xmlsec1-{}.tar.gz'.format(self.xmlsec1_version) self.info( '{:10}: {}'.format( 'xmlsec1', 'PYXMLSEC_XMLSEC1_VERSION={}, downloading from {}'.format(self.xmlsec1_version, url) ) ) xmlsec1_tar = self.libs_dir / 'xmlsec1.tar.gz' urlretrieve(url, str(xmlsec1_tar)) for file in (openssl_tar, zlib_tar, libiconv_tar, libxml2_tar, libxslt_tar, xmlsec1_tar): self.info('Unpacking {}'.format(file.name)) try: with tarfile.open(str(file)) as tar: tar.extractall(path=str(self.build_libs_dir)) except EOFError: raise DistutilsError('Bad {} downloaded; remove it and try again.'.format(file.name)) prefix_arg = '--prefix={}'.format(self.prefix_dir) cflags = ['-fPIC'] env = os.environ.copy() if 'CFLAGS' in env: env['CFLAGS'].append(' '.join(cflags)) else: env['CFLAGS'] = ' '.join(cflags) self.info('Building OpenSSL') openssl_dir = next(self.build_libs_dir.glob('openssl-*')) subprocess.check_output(['./config', prefix_arg, 'no-shared', '-fPIC'], cwd=str(openssl_dir), env=env) subprocess.check_output(['make', '-j{}'.format(multiprocessing.cpu_count() + 1)], cwd=str(openssl_dir), env=env) subprocess.check_output( ['make', '-j{}'.format(multiprocessing.cpu_count() + 1), 'install_sw'], cwd=str(openssl_dir), env=env ) self.info('Building zlib') zlib_dir = next(self.build_libs_dir.glob('zlib-*')) subprocess.check_output(['./configure', prefix_arg], cwd=str(zlib_dir), env=env) subprocess.check_output(['make', '-j{}'.format(multiprocessing.cpu_count() + 1)], cwd=str(zlib_dir), env=env) subprocess.check_output(['make', '-j{}'.format(multiprocessing.cpu_count() + 1), 'install'], cwd=str(zlib_dir), env=env) self.info('Building libiconv') libiconv_dir = next(self.build_libs_dir.glob('libiconv-*')) subprocess.check_output( ['./configure', prefix_arg, '--disable-dependency-tracking', '--disable-shared'], cwd=str(libiconv_dir), env=env ) subprocess.check_output(['make', '-j{}'.format(multiprocessing.cpu_count() + 1)], cwd=str(libiconv_dir), env=env) subprocess.check_output( ['make', '-j{}'.format(multiprocessing.cpu_count() + 1), 'install'], cwd=str(libiconv_dir), env=env ) self.info('Building LibXML2') libxml2_dir = next(self.build_libs_dir.glob('libxml2-*')) subprocess.check_output( [ './configure', prefix_arg, '--disable-dependency-tracking', '--disable-shared', '--enable-rebuild-docs=no', '--without-lzma', '--without-python', '--with-iconv={}'.format(self.prefix_dir), '--with-zlib={}'.format(self.prefix_dir), ], cwd=str(libxml2_dir), env=env, ) subprocess.check_output(['make', '-j{}'.format(multiprocessing.cpu_count() + 1)], cwd=str(libxml2_dir), env=env) subprocess.check_output( ['make', '-j{}'.format(multiprocessing.cpu_count() + 1), 'install'], cwd=str(libxml2_dir), env=env ) self.info('Building libxslt') libxslt_dir = next(self.build_libs_dir.glob('libxslt-*')) subprocess.check_output( [ './configure', prefix_arg, '--disable-dependency-tracking', '--disable-shared', '--without-python', '--without-crypto', '--with-libxml-prefix={}'.format(self.prefix_dir), ], cwd=str(libxslt_dir), env=env, ) subprocess.check_output(['make', '-j{}'.format(multiprocessing.cpu_count() + 1)], cwd=str(libxslt_dir), env=env) subprocess.check_output( ['make', '-j{}'.format(multiprocessing.cpu_count() + 1), 'install'], cwd=str(libxslt_dir), env=env ) self.info('Building xmlsec1') if 'LDFLAGS' in env: env['LDFLAGS'].append(' -lpthread') else: env['LDFLAGS'] = '-lpthread' xmlsec1_dir = next(self.build_libs_dir.glob('xmlsec1-*')) subprocess.check_output( [ './configure', prefix_arg, '--disable-shared', '--disable-gost', '--disable-crypto-dl', '--enable-static=yes', '--enable-shared=no', '--enable-static-linking=yes', '--with-default-crypto=openssl', '--with-openssl={}'.format(self.prefix_dir), '--with-libxml={}'.format(self.prefix_dir), '--with-libxslt={}'.format(self.prefix_dir), ], cwd=str(xmlsec1_dir), env=env, ) subprocess.check_output( ['make', '-j{}'.format(multiprocessing.cpu_count() + 1)] + ['-I{}'.format(str(self.prefix_dir / 'include')), '-I{}'.format(str(self.prefix_dir / 'include' / 'libxml'))], cwd=str(xmlsec1_dir), env=env, ) subprocess.check_output( ['make', '-j{}'.format(multiprocessing.cpu_count() + 1), 'install'], cwd=str(xmlsec1_dir), env=env ) ext = self.ext_map['xmlsec'] ext.define_macros = [ ('__XMLSEC_FUNCTION__', '__func__'), ('XMLSEC_NO_SIZE_T', None), ('XMLSEC_NO_GOST', '1'), ('XMLSEC_NO_GOST2012', '1'), ('XMLSEC_NO_XKMS', '1'), ('XMLSEC_CRYPTO', '\\"openssl\\"'), ('XMLSEC_NO_CRYPTO_DYNAMIC_LOADING', '1'), ('XMLSEC_CRYPTO_OPENSSL', '1'), ('LIBXML_ICONV_ENABLED', 1), ('LIBXML_STATIC', '1'), ('LIBXSLT_STATIC', '1'), ('XMLSEC_STATIC', '1'), ('inline', '__inline'), ('UNICODE', '1'), ('_UNICODE', '1'), ] ext.include_dirs.append(str(self.prefix_dir / 'include')) ext.include_dirs.extend([str(p.absolute()) for p in (self.prefix_dir / 'include').iterdir() if p.is_dir()]) ext.library_dirs = [] ext.libraries = ['m', 'rt'] extra_objects = [ 'libxmlsec1.a', 'libxslt.a', 'libxml2.a', 'libz.a', 'libxmlsec1-openssl.a', 'libcrypto.a', 'libiconv.a', 'libxmlsec1.a', ] ext.extra_objects = [str(self.prefix_dir / 'lib' / o) for o in extra_objects] src_root = Path(__file__).parent / 'src' sources = [str(p.absolute()) for p in src_root.rglob('*.c')] pyxmlsec = Extension('xmlsec', sources=sources) setup_reqs = ['setuptools_scm[toml]>=3.4', 'pkgconfig>=1.5.1', 'lxml>=3.8'] with io.open('README.rst', encoding='utf-8') as f: long_desc = f.read() setup( name='xmlsec', use_scm_version=True, description='Python bindings for the XML Security Library', long_description=long_desc, ext_modules=[pyxmlsec], cmdclass={'build_ext': build_ext}, python_requires='>=3.5', setup_requires=setup_reqs, install_requires=['lxml>=3.8'], author="Bulat Gaifullin", author_email='support@mehcode.com', maintainer='Oleg Hoefling', maintainer_email='oleg.hoefling@gmail.com', url='https://github.com/mehcode/python-xmlsec', project_urls={ 'Documentation': 'https://xmlsec.readthedocs.io', 'Source': 'https://github.com/mehcode/python-xmlsec', 'Changelog': 'https://github.com/mehcode/python-xmlsec/releases', }, license='MIT', keywords=['xmlsec'], classifiers=[ 'Development Status :: 5 - Production/Stable', 'Intended Audience :: Developers', 'Intended Audience :: System Administrators', 'License :: OSI Approved :: MIT License', 'Operating System :: OS Independent', 'Programming Language :: C', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', 'Topic :: Text Processing :: Markup :: XML', 'Typing :: Typed', ], zip_safe=False, packages=['xmlsec'], package_dir={'': 'src'}, package_data={'xmlsec': ['py.typed', '*.pyi']}, ) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1661028173.9615653 xmlsec-1.3.13/src/0000755000175100001710000000000014300243516013256 5ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/src/common.h0000644000175100001710000000151714300243501014715 0ustar00runnerdocker// Copyright (c) 2017 Ryan Leckey // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #ifndef __PYXMLSEC_COMMON_H__ #define __PYXMLSEC_COMMON_H__ #include "debug.h" #ifndef MODULE_NAME #define MODULE_NAME "xmlsec" #endif #define JOIN(X,Y) DO_JOIN1(X,Y) #define DO_JOIN1(X,Y) DO_JOIN2(X,Y) #define DO_JOIN2(X,Y) X##Y #define DO_STRINGIFY(x) #x #define STRINGIFY(x) DO_STRINGIFY(x) #endif //__PYXMLSEC_COMMON_H__ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/src/constants.c0000644000175100001710000005750214300243501015441 0ustar00runnerdocker// Copyright (c) 2017 Ryan Leckey // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "common.h" #include "constants.h" #define PYXMLSEC_CONSTANTS_DOC "Various constants used by the library.\n" // destructor static void PyXmlSec_Transform__del__(PyObject* self) { PYXMLSEC_DEBUGF("%p", self); Py_TYPE(self)->tp_free(self); } // __str__ method static PyObject* PyXmlSec_Transform__str__(PyObject* self) { char buf[300]; PyXmlSec_Transform* transform = (PyXmlSec_Transform*)(self); if (transform->id->href != NULL) snprintf(buf, sizeof(buf), "%s, %s", transform->id->name, transform->id->href); else snprintf(buf, sizeof(buf), "%s, None", transform->id->name); return PyUnicode_FromString(buf); } // __repr__ method static PyObject* PyXmlSec_Transform__repr__(PyObject* self) { char buf[300]; PyXmlSec_Transform* transform = (PyXmlSec_Transform*)(self); if (transform->id->href != NULL) snprintf(buf, sizeof(buf), "__Transform('%s', '%s', %d)", transform->id->name, transform->id->href, transform->id->usage); else snprintf(buf, sizeof(buf), "__Transform('%s', None, %d)", transform->id->name, transform->id->usage); return PyUnicode_FromString(buf); } static const char PyXmlSec_TransformNameGet__doc__[] = "The transform's name."; static PyObject* PyXmlSec_TransformNameGet(PyXmlSec_Transform* self, void* closure) { return PyUnicode_FromString((const char*)self->id->name); } static const char PyXmlSec_TransformHrefGet__doc__[] = "The transform's identification string (href)."; static PyObject* PyXmlSec_TransformHrefGet(PyXmlSec_Transform* self, void* closure) { if (self->id->href != NULL) return PyUnicode_FromString((const char*)self->id->href); Py_RETURN_NONE; } static const char PyXmlSec_TransformUsageGet__doc__[] = "The allowed transforms usages."; static PyObject* PyXmlSec_TransformUsageGet(PyXmlSec_Transform* self, void* closure) { return PyLong_FromUnsignedLong(self->id->usage); } static PyGetSetDef PyXmlSec_TransformGetSet[] = { { "name", (getter)PyXmlSec_TransformNameGet, NULL, (char*)PyXmlSec_TransformNameGet__doc__, NULL }, { "href", (getter)PyXmlSec_TransformHrefGet, NULL, (char*)PyXmlSec_TransformHrefGet__doc__, NULL }, { "usage", (getter)PyXmlSec_TransformUsageGet, NULL, (char*)PyXmlSec_TransformUsageGet__doc__, NULL }, {NULL} /* Sentinel */ }; static PyTypeObject _PyXmlSec_TransformType = { PyVarObject_HEAD_INIT(NULL, 0) STRINGIFY(MODULE_NAME) ".constants.__Transform", /* tp_name */ sizeof(PyXmlSec_Transform), /* tp_basicsize */ 0, /* tp_itemsize */ PyXmlSec_Transform__del__, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved */ PyXmlSec_Transform__repr__, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ PyXmlSec_Transform__str__, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ "The xmlSecTransformId reflection", /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ 0, /* tp_methods */ 0, /* tp_members */ PyXmlSec_TransformGetSet, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ 0, /* tp_new */ 0, /* tp_free */ }; PyTypeObject* PyXmlSec_TransformType = &_PyXmlSec_TransformType; static PyObject* PyXmlSec_TransformNew(xmlSecTransformId id) { PyXmlSec_Transform* transform = PyObject_New(PyXmlSec_Transform, PyXmlSec_TransformType); if (transform != NULL) { transform->id = id; } return (PyObject*)transform; } // destructor static void PyXmlSec_KeyData__del__(PyObject* self) { PYXMLSEC_DEBUGF("%p", self); Py_TYPE(self)->tp_free(self); } // __str__ method static PyObject* PyXmlSec_KeyData__str__(PyObject* self) { char buf[300]; PyXmlSec_KeyData* keydata = (PyXmlSec_KeyData*)(self); if (keydata->id->href != NULL) snprintf(buf, sizeof(buf), "%s, %s", keydata->id->name, keydata->id->href); else snprintf(buf, sizeof(buf), "%s, None", keydata->id->name); return PyUnicode_FromString(buf); } // __repr__ method static PyObject* PyXmlSec_KeyData__repr__(PyObject* self) { char buf[300]; PyXmlSec_KeyData* keydata = (PyXmlSec_KeyData*)(self); if (keydata->id->href != NULL) snprintf(buf, sizeof(buf), "__KeyData('%s', '%s')", keydata->id->name, keydata->id->href); else snprintf(buf, sizeof(buf), "__KeyData('%s', None)", keydata->id->name); return PyUnicode_FromString(buf); } static const char PyXmlSec_KeyDataNameGet__doc__[] = "The key data's name."; static PyObject* PyXmlSec_KeyDataNameGet(PyXmlSec_KeyData* self, void* closure) { return PyUnicode_FromString((const char*)self->id->name); } static const char PyXmlSec_KeyDataHrefGet__doc__[] = "The key data's identification string (href)."; static PyObject* PyXmlSec_KeyDataHrefGet(PyXmlSec_KeyData* self, void* closure) { if (self->id->href != NULL) return PyUnicode_FromString((const char*)self->id->href); Py_RETURN_NONE; } static PyGetSetDef PyXmlSec_KeyDataGetSet[] = { { "name", (getter)PyXmlSec_KeyDataNameGet, NULL, (char*)PyXmlSec_KeyDataNameGet__doc__, NULL }, { "href", (getter)PyXmlSec_KeyDataHrefGet, NULL, (char*)PyXmlSec_KeyDataHrefGet__doc__, NULL }, {NULL} /* Sentinel */ }; static PyTypeObject _PyXmlSec_KeyDataType = { PyVarObject_HEAD_INIT(NULL, 0) STRINGIFY(MODULE_NAME) ".constants.__KeyData", /* tp_name */ sizeof(PyXmlSec_KeyData), /* tp_basicsize */ 0, /* tp_itemsize */ PyXmlSec_KeyData__del__, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved */ PyXmlSec_KeyData__repr__, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ PyXmlSec_KeyData__str__, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ "The xmlSecKeyDataId reflection", /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ 0, /* tp_methods */ 0, /* tp_members */ PyXmlSec_KeyDataGetSet, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ 0, /* tp_new */ 0, /* tp_free */ }; PyTypeObject* PyXmlSec_KeyDataType = &_PyXmlSec_KeyDataType; static PyObject* PyXmlSec_KeyDataNew(xmlSecKeyDataId id) { PyXmlSec_KeyData* keydata = PyObject_New(PyXmlSec_KeyData, PyXmlSec_KeyDataType); if (keydata != NULL) { keydata->id = id; } return (PyObject*)keydata; } static PyModuleDef PyXmlSec_ConstantsModule = { PyModuleDef_HEAD_INIT, STRINGIFY(MODULE_NAME) ".constants", PYXMLSEC_CONSTANTS_DOC, -1, NULL, NULL, NULL, NULL, NULL }; // initialize constants module and registers it base package int PyXmlSec_ConstantsModule_Init(PyObject* package) { PyObject* constants = NULL; PyObject* nsCls = NULL; PyObject* nodeCls = NULL; PyObject* transformCls = NULL; PyObject* encryptionTypeCls = NULL; PyObject* keyFormatCls = NULL; PyObject* keyDataCls = NULL; PyObject* keyDataTypeCls = NULL; PyObject* tmp = NULL; constants = PyModule_Create(&PyXmlSec_ConstantsModule); if (!constants) return -1; if (PyType_Ready(PyXmlSec_TransformType) < 0) goto ON_FAIL; if (PyType_Ready(PyXmlSec_KeyDataType) < 0) goto ON_FAIL; #define PYXMLSEC_ADD_INT_CONSTANT(name) PyModule_AddIntConstant(constants, STRINGIFY(name), JOIN(xmlSec, name)) if (PYXMLSEC_ADD_INT_CONSTANT(TransformUsageUnknown) < 0) goto ON_FAIL; if (PYXMLSEC_ADD_INT_CONSTANT(TransformUsageDSigTransform) < 0) goto ON_FAIL; if (PYXMLSEC_ADD_INT_CONSTANT(TransformUsageC14NMethod) < 0) goto ON_FAIL; if (PYXMLSEC_ADD_INT_CONSTANT(TransformUsageDigestMethod) < 0) goto ON_FAIL; if (PYXMLSEC_ADD_INT_CONSTANT(TransformUsageSignatureMethod) < 0) goto ON_FAIL; if (PYXMLSEC_ADD_INT_CONSTANT(TransformUsageEncryptionMethod) < 0) goto ON_FAIL; if (PYXMLSEC_ADD_INT_CONSTANT(TransformUsageAny) < 0) goto ON_FAIL; #undef PYXMLSEC_ADD_INT_CONSTANT #define PYXMLSEC_DECLARE_NAMESPACE(var, name) \ if (!(var = PyModule_New(name))) goto ON_FAIL; \ if (PyModule_AddObject(package, name, var) < 0) goto ON_FAIL; \ Py_INCREF(var); // add object steels reference #define PYXMLSEC_CLOSE_NAMESPACE(var) \ Py_DECREF(var); var = NULL // compensate add ref from declare namespace #define PYXMLSEC_ADD_CONSTANT(ns, name, lname) \ if (tmp == NULL) goto ON_FAIL; \ if (PyModule_AddObject(constants, STRINGIFY(name), tmp) < 0) goto ON_FAIL; \ Py_INCREF(tmp); \ if (PyModule_AddObject(ns, lname, tmp) < 0) goto ON_FAIL; \ tmp = NULL; #define PYXMLSEC_ADD_NS_CONSTANT(name, lname) \ tmp = PyUnicode_FromString((const char*)(JOIN(xmlSec, name))); \ PYXMLSEC_ADD_CONSTANT(nsCls, name, lname); // namespaces PYXMLSEC_DECLARE_NAMESPACE(nsCls, "Namespace"); PYXMLSEC_ADD_NS_CONSTANT(Ns, "BASE"); PYXMLSEC_ADD_NS_CONSTANT(DSigNs, "DS"); PYXMLSEC_ADD_NS_CONSTANT(EncNs, "ENC"); #ifndef XMLSEC_NO_XKMS PYXMLSEC_ADD_NS_CONSTANT(XkmsNs, "XKMS"); #endif PYXMLSEC_ADD_NS_CONSTANT(XPathNs, "XPATH"); PYXMLSEC_ADD_NS_CONSTANT(XPath2Ns, "XPATH2"); PYXMLSEC_ADD_NS_CONSTANT(XPointerNs, "XPOINTER"); PYXMLSEC_ADD_NS_CONSTANT(Soap11Ns, "SOAP11"); PYXMLSEC_ADD_NS_CONSTANT(Soap12Ns, "SOAP12"); PYXMLSEC_ADD_NS_CONSTANT(NsExcC14N, "EXC_C14N"); PYXMLSEC_ADD_NS_CONSTANT(NsExcC14NWithComments, "EXC_C14N_WITH_COMMENT"); PYXMLSEC_CLOSE_NAMESPACE(nsCls); #undef PYXMLSEC_ADD_NS_CONSTANT #define PYXMLSEC_ADD_ENC_CONSTANT(name, lname) \ tmp = PyUnicode_FromString((const char*)(JOIN(xmlSec, name))); \ PYXMLSEC_ADD_CONSTANT(encryptionTypeCls, name, lname); // encryption type PYXMLSEC_DECLARE_NAMESPACE(encryptionTypeCls, "EncryptionType"); PYXMLSEC_ADD_ENC_CONSTANT(TypeEncContent, "CONTENT"); PYXMLSEC_ADD_ENC_CONSTANT(TypeEncElement, "ELEMENT"); PYXMLSEC_CLOSE_NAMESPACE(encryptionTypeCls); #undef PYXMLSEC_ADD_ENC_CONSTANT #define PYXMLSEC_ADD_NODE_CONSTANT(name, lname) \ tmp = PyUnicode_FromString((const char*)(JOIN(xmlSec, name))); \ PYXMLSEC_ADD_CONSTANT(nodeCls, name, lname); // node PYXMLSEC_DECLARE_NAMESPACE(nodeCls, "Node"); PYXMLSEC_ADD_NODE_CONSTANT(NodeSignature, "SIGNATURE"); PYXMLSEC_ADD_NODE_CONSTANT(NodeSignedInfo, "SIGNED_INFO"); PYXMLSEC_ADD_NODE_CONSTANT(NodeCanonicalizationMethod, "CANONICALIZATION_METHOD"); PYXMLSEC_ADD_NODE_CONSTANT(NodeSignatureMethod, "SIGNATURE_METHOD"); PYXMLSEC_ADD_NODE_CONSTANT(NodeSignatureValue, "SIGNATURE_VALUE"); PYXMLSEC_ADD_NODE_CONSTANT(NodeSignatureProperties, "SIGNATURE_PROPERTIES"); PYXMLSEC_ADD_NODE_CONSTANT(NodeDigestMethod, "DIGEST_METHOD"); PYXMLSEC_ADD_NODE_CONSTANT(NodeDigestValue, "DIGEST_VALUE"); PYXMLSEC_ADD_NODE_CONSTANT(NodeObject, "OBJECT"); PYXMLSEC_ADD_NODE_CONSTANT(NodeManifest, "MANIFEST"); PYXMLSEC_ADD_NODE_CONSTANT(NodeEncryptedData, "ENCRYPTED_DATA"); PYXMLSEC_ADD_NODE_CONSTANT(NodeEncryptedKey, "ENCRYPTED_KEY"); PYXMLSEC_ADD_NODE_CONSTANT(NodeEncryptionMethod, "ENCRYPTION_METHOD"); PYXMLSEC_ADD_NODE_CONSTANT(NodeEncryptionProperty, "ENCRYPTION_PROPERTY"); PYXMLSEC_ADD_NODE_CONSTANT(NodeEncryptionProperties, "ENCRYPTION_PROPERTIES"); PYXMLSEC_ADD_NODE_CONSTANT(NodeCipherData, "CIPHER_DATA"); PYXMLSEC_ADD_NODE_CONSTANT(NodeCipherValue, "CIPHER_VALUE"); PYXMLSEC_ADD_NODE_CONSTANT(NodeCipherReference, "CIPHER_REFERENCE"); PYXMLSEC_ADD_NODE_CONSTANT(NodeDataReference, "DATA_REFERENCE"); PYXMLSEC_ADD_NODE_CONSTANT(NodeKeyReference, "KEY_REFERENCE"); PYXMLSEC_ADD_NODE_CONSTANT(NodeReference, "REFERENCE"); PYXMLSEC_ADD_NODE_CONSTANT(NodeReferenceList, "REFERENCE_LIST"); PYXMLSEC_ADD_NODE_CONSTANT(NodeKeyInfo, "KEY_INFO"); PYXMLSEC_ADD_NODE_CONSTANT(NodeKeyName, "KEY_NAME"); PYXMLSEC_ADD_NODE_CONSTANT(NodeKeyValue, "KEY_VALUE"); PYXMLSEC_ADD_NODE_CONSTANT(NodeX509Data, "X509_DATA"); PYXMLSEC_CLOSE_NAMESPACE(nodeCls); #undef PYXMLSEC_ADD_NODE_CONSTANT #define PYXMLSEC_ADD_KEY_FORMAT_CONSTANT(name, lname) \ tmp = PyLong_FromUnsignedLong((unsigned long)(JOIN(xmlSec, name))); \ PYXMLSEC_ADD_CONSTANT(keyFormatCls, name, lname); // key format PYXMLSEC_DECLARE_NAMESPACE(keyFormatCls, "KeyFormat"); PYXMLSEC_ADD_KEY_FORMAT_CONSTANT(KeyDataFormatUnknown, "UNKNOWN"); PYXMLSEC_ADD_KEY_FORMAT_CONSTANT(KeyDataFormatBinary, "BINARY"); PYXMLSEC_ADD_KEY_FORMAT_CONSTANT(KeyDataFormatPem, "PEM"); PYXMLSEC_ADD_KEY_FORMAT_CONSTANT(KeyDataFormatDer, "DER"); PYXMLSEC_ADD_KEY_FORMAT_CONSTANT(KeyDataFormatPkcs8Pem, "PKCS8_PEM"); PYXMLSEC_ADD_KEY_FORMAT_CONSTANT(KeyDataFormatPkcs8Der, "PKCS8_DER");; PYXMLSEC_ADD_KEY_FORMAT_CONSTANT(KeyDataFormatPkcs12, "PKCS12_PEM"); PYXMLSEC_ADD_KEY_FORMAT_CONSTANT(KeyDataFormatCertPem, "CERT_PEM"); PYXMLSEC_ADD_KEY_FORMAT_CONSTANT(KeyDataFormatCertDer, "CERT_DER"); PYXMLSEC_CLOSE_NAMESPACE(keyFormatCls); #undef PYXMLSEC_ADD_KEY_FORMAT_CONSTANT #define PYXMLSEC_ADD_KEY_TYPE_CONSTANT(name, lname) \ tmp = PyLong_FromUnsignedLong((unsigned long)(JOIN(xmlSec, name))); \ PYXMLSEC_ADD_CONSTANT(keyDataTypeCls, name, lname); // key data type PYXMLSEC_DECLARE_NAMESPACE(keyDataTypeCls, "KeyDataType"); PYXMLSEC_ADD_KEY_TYPE_CONSTANT(KeyDataTypeUnknown, "UNKNOWN"); PYXMLSEC_ADD_KEY_TYPE_CONSTANT(KeyDataTypeNone, "NONE"); PYXMLSEC_ADD_KEY_TYPE_CONSTANT(KeyDataTypePublic, "PUBLIC"); PYXMLSEC_ADD_KEY_TYPE_CONSTANT(KeyDataTypePrivate, "PRIVATE"); PYXMLSEC_ADD_KEY_TYPE_CONSTANT(KeyDataTypeSymmetric, "SYMMETRIC"); PYXMLSEC_ADD_KEY_TYPE_CONSTANT(KeyDataTypeSession, "SESSION"); PYXMLSEC_ADD_KEY_TYPE_CONSTANT(KeyDataTypePermanent, "PERMANENT"); PYXMLSEC_ADD_KEY_TYPE_CONSTANT(KeyDataTypeTrusted, "TRUSTED"); PYXMLSEC_ADD_KEY_TYPE_CONSTANT(KeyDataTypeAny, "ANY"); PYXMLSEC_CLOSE_NAMESPACE(keyDataTypeCls); #undef PYXMLSEC_ADD_KEY_TYPE_CONSTANT #define PYXMLSEC_ADD_KEYDATA_CONSTANT(name, lname) \ tmp = PyXmlSec_KeyDataNew(xmlSec ## name ## Id); \ PYXMLSEC_ADD_CONSTANT(keyDataCls, name, lname); // keydata PYXMLSEC_DECLARE_NAMESPACE(keyDataCls, "KeyData"); PYXMLSEC_ADD_KEYDATA_CONSTANT(KeyDataName, "NAME") PYXMLSEC_ADD_KEYDATA_CONSTANT(KeyDataValue, "VALUE") PYXMLSEC_ADD_KEYDATA_CONSTANT(KeyDataRetrievalMethod, "RETRIEVALMETHOD") PYXMLSEC_ADD_KEYDATA_CONSTANT(KeyDataEncryptedKey, "ENCRYPTEDKEY") PYXMLSEC_ADD_KEYDATA_CONSTANT(KeyDataAes, "AES") PYXMLSEC_ADD_KEYDATA_CONSTANT(KeyDataDes, "DES") #ifndef XMLSEC_NO_DSA PYXMLSEC_ADD_KEYDATA_CONSTANT(KeyDataDsa, "DSA") #endif #if XMLSEC_VERSION_HEX > 0x10212 // from version 1.2.19 PYXMLSEC_ADD_KEYDATA_CONSTANT(KeyDataEcdsa, "ECDSA") #endif PYXMLSEC_ADD_KEYDATA_CONSTANT(KeyDataHmac, "HMAC") PYXMLSEC_ADD_KEYDATA_CONSTANT(KeyDataRsa, "RSA") PYXMLSEC_ADD_KEYDATA_CONSTANT(KeyDataX509, "X509") PYXMLSEC_ADD_KEYDATA_CONSTANT(KeyDataRawX509Cert, "RAWX509CERT") PYXMLSEC_CLOSE_NAMESPACE(keyDataCls); #undef PYXMLSEC_ADD_KEYDATA_CONSTANT #define PYXMLSEC_ADD_TRANSFORM_CONSTANT(name, lname) \ tmp = PyXmlSec_TransformNew(xmlSec ## name ## Id); \ PYXMLSEC_ADD_CONSTANT(transformCls, name, lname); // transforms PYXMLSEC_DECLARE_NAMESPACE(transformCls, "Transform"); PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformInclC14N, "C14N"); PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformInclC14NWithComments, "C14N_COMMENTS"); PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformInclC14N11, "C14N11"); PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformInclC14N11WithComments, "C14N11_COMMENTS"); PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformExclC14N, "EXCL_C14N"); PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformExclC14NWithComments, "EXCL_C14N_COMMENTS"); PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformEnveloped, "ENVELOPED"); PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformXPath, "XPATH"); PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformXPath2, "XPATH2"); PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformXPointer, "XPOINTER"); PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformRemoveXmlTagsC14N, "REMOVE_XML_TAGS_C14N"); PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformVisa3DHack, "VISA3D_HACK"); PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformAes128Cbc, "AES128"); PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformAes192Cbc, "AES192"); PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformAes256Cbc, "AES256"); PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformKWAes128, "KW_AES128"); PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformKWAes192, "KW_AES192"); PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformKWAes256, "KW_AES256"); PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformDes3Cbc, "DES3"); PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformKWDes3, "KW_DES3"); #ifndef XMLSEC_NO_DSA PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformDsaSha1, "DSA_SHA1"); #endif #ifndef XMLSEC_NO_XSLT PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformXslt, "XSLT"); #endif #if XMLSEC_VERSION_HEX > 0x10212 // from version 1.2.19 PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformEcdsaSha1, "ECDSA_SHA1"); PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformEcdsaSha224, "ECDSA_SHA224"); PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformEcdsaSha256, "ECDSA_SHA256"); PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformEcdsaSha384, "ECDSA_SHA384"); PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformEcdsaSha512, "ECDSA_SHA512"); #endif #ifndef XMLSEC_NO_MD5 PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformHmacMd5, "HMAC_MD5"); #endif #ifndef XMLSEC_NO_RIPEMD160 PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformHmacRipemd160, "HMAC_RIPEMD160"); #endif PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformHmacSha1, "HMAC_SHA1"); PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformHmacSha224, "HMAC_SHA224"); PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformHmacSha256, "HMAC_SHA256"); PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformHmacSha384, "HMAC_SHA384"); PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformHmacSha512, "HMAC_SHA512"); #ifndef XMLSEC_NO_MD5 PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformRsaMd5, "RSA_MD5"); #endif #ifndef XMLSEC_NO_RIPEMD160 PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformRsaRipemd160, "RSA_RIPEMD160"); #endif PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformRsaSha1, "RSA_SHA1"); PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformRsaSha224, "RSA_SHA224"); PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformRsaSha256, "RSA_SHA256"); PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformRsaSha384, "RSA_SHA384"); PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformRsaSha512, "RSA_SHA512"); PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformRsaPkcs1, "RSA_PKCS1"); PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformRsaOaep, "RSA_OAEP"); #ifndef XMLSEC_NO_MD5 PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformMd5, "MD5"); #endif #ifndef XMLSEC_NO_RIPEMD160 PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformRipemd160, "RIPEMD160"); #endif PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformSha1, "SHA1"); PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformSha224, "SHA224"); PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformSha256, "SHA256"); PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformSha384, "SHA384"); PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformSha512, "SHA512"); #if XMLSEC_VERSION_HEX > 0x1021B // from version 1.2.28 PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformAes128Gcm, "AES128_GCM"); PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformAes192Gcm, "AES192_GCM"); PYXMLSEC_ADD_TRANSFORM_CONSTANT(TransformAes256Gcm, "AES256_GCM"); #endif PYXMLSEC_CLOSE_NAMESPACE(transformCls); #undef PYXMLSEC_ADD_TRANSFORM_CONSTANT #undef PYXMLSEC_ADD_CONSTANT #undef PYXMLSEC_DECLARE_NAMESPACE if (PyModule_AddObject(package, "constants", constants) < 0) goto ON_FAIL; return 0; ON_FAIL: Py_XDECREF(tmp); Py_XDECREF(nsCls); Py_XDECREF(nodeCls); Py_XDECREF(transformCls); Py_XDECREF(encryptionTypeCls); Py_XDECREF(keyFormatCls); Py_XDECREF(keyDataCls); Py_XDECREF(keyDataTypeCls); Py_DECREF(constants); return -1; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/src/constants.h0000644000175100001710000000166514300243501015445 0ustar00runnerdocker// Copyright (c) 2017 Ryan Leckey // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #ifndef __PYXMLSEC_CONSTANTS_H__ #define __PYXMLSEC_CONSTANTS_H__ #include "platform.h" #include #include typedef struct { PyObject_HEAD xmlSecTransformId id; } PyXmlSec_Transform; typedef struct { PyObject_HEAD xmlSecKeyDataId id; } PyXmlSec_KeyData; extern PyTypeObject* PyXmlSec_TransformType; extern PyTypeObject* PyXmlSec_KeyDataType; #endif //__PYXMLSEC_CONSTANTS_H__ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/src/debug.h0000644000175100001710000000205114300243501014505 0ustar00runnerdocker// Copyright (c) 2017 Ryan Leckey // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #ifndef __PYXMLSEC_DEBUG_H__ #define __PYXMLSEC_DEBUG_H__ #ifdef PYXMLSEC_ENABLE_DEBUG #include #define PYXMLSEC_DEBUG(fmt) fprintf(stderr, "[%s:%d %s] " fmt "\n", __FILE__, __LINE__, __FUNCTION__) #define PYXMLSEC_DEBUGF(fmt, ...) fprintf(stderr, "[%s:%d %s] " fmt "\n", __FILE__, __LINE__, __FUNCTION__, __VA_ARGS__) #define PYXMLSEC_DUMP(method, obj) method(obj, stderr) #else #define PYXMLSEC_DEBUG(...) #define PYXMLSEC_DEBUGF(...) #define PYXMLSEC_DUMP(method, obj) #endif // PYXMLSEC_ENABLE_DEBUG #endif // __PYXMLSEC_DEBUG_H__ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/src/ds.c0000644000175100001710000005602314300243501014030 0ustar00runnerdocker// Copyright (c) 2017 Ryan Leckey // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "common.h" #include "platform.h" #include "exception.h" #include "constants.h" #include "keys.h" #include "lxml.h" #include typedef struct { PyObject_HEAD xmlSecDSigCtxPtr handle; PyXmlSec_KeysManager* manager; } PyXmlSec_SignatureContext; static PyObject* PyXmlSec_SignatureContext__new__(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyXmlSec_SignatureContext* ctx = (PyXmlSec_SignatureContext*)PyType_GenericNew(type, args, kwargs); PYXMLSEC_DEBUGF("%p: new sign context", ctx); if (ctx != NULL) { ctx->handle = NULL; ctx->manager = NULL; } return (PyObject*)(ctx); } static int PyXmlSec_SignatureContext__init__(PyObject* self, PyObject* args, PyObject* kwargs) { static char *kwlist[] = { "manager", NULL}; PyXmlSec_SignatureContext* ctx = (PyXmlSec_SignatureContext*)self; PyXmlSec_KeysManager* manager = NULL; PYXMLSEC_DEBUGF("%p: init sign context", self); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:__init__", kwlist, PyXmlSec_KeysManagerConvert, &manager)) { goto ON_FAIL; } ctx->handle = xmlSecDSigCtxCreate(manager != NULL ? manager->handle : NULL); if (ctx->handle == NULL) { PyXmlSec_SetLastError("failed to create the digital signature context"); goto ON_FAIL; } ctx->manager = manager; PYXMLSEC_DEBUGF("%p: signMethod: %p", self, ctx->handle->signMethod); PYXMLSEC_DEBUGF("%p: init sign context - ok, manager - %p", self, manager); return 0; ON_FAIL: PYXMLSEC_DEBUGF("%p: init sign context - failed", self); Py_XDECREF(manager); return -1; } static void PyXmlSec_SignatureContext__del__(PyObject* self) { PyXmlSec_SignatureContext* ctx = (PyXmlSec_SignatureContext*)self; PYXMLSEC_DEBUGF("%p: delete sign context", self); if (ctx->handle != NULL) { xmlSecDSigCtxDestroy(ctx->handle); } // release manager object Py_XDECREF(ctx->manager); Py_TYPE(self)->tp_free(self); } static const char PyXmlSec_SignatureContextKey__doc__[] = "Signature key.\n"; static PyObject* PyXmlSec_SignatureContextKeyGet(PyObject* self, void* closure) { PyXmlSec_SignatureContext* ctx = ((PyXmlSec_SignatureContext*)self); PyXmlSec_Key* key; if (ctx->handle->signKey == NULL) { Py_RETURN_NONE; } key = PyXmlSec_NewKey(); key->handle = ctx->handle->signKey; key->is_own = 0; return (PyObject*)key; } static int PyXmlSec_SignatureContextKeySet(PyObject* self, PyObject* value, void* closure) { PyXmlSec_SignatureContext* ctx = (PyXmlSec_SignatureContext*)self; PyXmlSec_Key* key; PYXMLSEC_DEBUGF("%p, %p", self, value); if (value == NULL) { // key deletion if (ctx->handle->signKey != NULL) { xmlSecKeyDestroy(ctx->handle->signKey); ctx->handle->signKey = NULL; } return 0; } if (!PyObject_IsInstance(value, (PyObject*)PyXmlSec_KeyType)) { PyErr_SetString(PyExc_TypeError, "instance of *xmlsec.Key* expected."); return -1; } key = (PyXmlSec_Key*)value; if (key->handle == NULL) { PyErr_SetString(PyExc_TypeError, "empty key."); return -1; } if (ctx->handle->signKey != NULL) { xmlSecKeyDestroy(ctx->handle->signKey); } ctx->handle->signKey = xmlSecKeyDuplicate(key->handle); if (ctx->handle->signKey == NULL) { PyXmlSec_SetLastError("failed to duplicate key"); return -1; } return 0; } static const char PyXmlSec_SignatureContextRegisterId__doc__[] = \ "register_id(node, id_attr = 'ID', id_ns = None) -> None\n" "Registers new id.\n\n" ":param node: the pointer to XML node\n" ":type node: :class:`lxml.etree._Element`\n" ":param id_attr: the attribute\n" ":type id_attr: :class:`str`\n" ":param id_ns: the namespace (optional)\n" ":type id_ns: :class:`str` or :data:`None`"; static PyObject* PyXmlSec_SignatureContextRegisterId(PyObject* self, PyObject* args, PyObject* kwargs) { static char *kwlist[] = { "node", "id_attr", "id_ns", NULL}; PyXmlSec_LxmlElementPtr node = NULL; const char* id_attr = "ID"; const char* id_ns = NULL; xmlChar* name = NULL; xmlAttrPtr attr; xmlAttrPtr tmpAttr; PYXMLSEC_DEBUGF("%p: register id - start", self); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|sz:register_id", kwlist, PyXmlSec_LxmlElementConverter, &node, &id_attr, &id_ns)) { goto ON_FAIL; } if (id_ns != NULL) { attr = xmlHasNsProp(node->_c_node, XSTR(id_attr), XSTR(id_ns)); } else { attr = xmlHasProp(node->_c_node, XSTR(id_attr)); } if (attr == NULL || attr->children == NULL) { PyErr_SetString(PyXmlSec_Error, "missing attribute."); goto ON_FAIL; } name = xmlNodeListGetString(node->_c_node->doc, attr->children, 1); tmpAttr = xmlGetID(node->_c_node->doc, name); if (tmpAttr != attr) { if (tmpAttr != NULL) { PyErr_SetString(PyXmlSec_Error, "duplicated id."); goto ON_FAIL; } Py_BEGIN_ALLOW_THREADS; xmlAddID(NULL, node->_c_node->doc, name, attr); Py_END_ALLOW_THREADS; } xmlFree(name); PYXMLSEC_DEBUGF("%p: register id - ok", self); Py_RETURN_NONE; ON_FAIL: xmlFree(name); PYXMLSEC_DEBUGF("%p: register id - fail", self); return NULL; } static const char PyXmlSec_SignatureContextSign__doc__[] = \ "sign(node) -> None\n" "Signs according to the signature template.\n\n" ":param node: the pointer to :xml:`` node with signature template\n" ":type node: :class:`lxml.etree._Element`"; static PyObject* PyXmlSec_SignatureContextSign(PyObject* self, PyObject* args, PyObject* kwargs) { static char *kwlist[] = { "node", NULL}; PyXmlSec_SignatureContext* ctx = (PyXmlSec_SignatureContext*)self; PyXmlSec_LxmlElementPtr node = NULL; int rv; PYXMLSEC_DEBUGF("%p: sign - start", self); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:sign", kwlist, PyXmlSec_LxmlElementConverter, &node)) { goto ON_FAIL; } Py_BEGIN_ALLOW_THREADS; rv = xmlSecDSigCtxSign(ctx->handle, node->_c_node); PYXMLSEC_DUMP(xmlSecDSigCtxDebugDump, ctx->handle); Py_END_ALLOW_THREADS; if (rv < 0) { PyXmlSec_SetLastError("failed to sign"); goto ON_FAIL; } PYXMLSEC_DEBUGF("%p: sign - ok", self); Py_RETURN_NONE; ON_FAIL: PYXMLSEC_DEBUGF("%p: sign - fail", self); return NULL; } static const char PyXmlSec_SignatureContextVerify__doc__[] = \ "verify(node) -> None\n" "Verifies according to the signature template.\n\n" ":param node: the pointer with :xml:`` node\n" ":type node: :class:`lxml.etree._Element`\n" ":return: :data:`None` on success\n" ":raise VerificationError: on failure\n"; static PyObject* PyXmlSec_SignatureContextVerify(PyObject* self, PyObject* args, PyObject* kwargs) { static char *kwlist[] = { "node", NULL}; PyXmlSec_SignatureContext* ctx = (PyXmlSec_SignatureContext*)self; PyXmlSec_LxmlElementPtr node = NULL; int rv; PYXMLSEC_DEBUGF("%p: verify - start", self); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:verify", kwlist, PyXmlSec_LxmlElementConverter, &node)) { goto ON_FAIL; } Py_BEGIN_ALLOW_THREADS; rv = xmlSecDSigCtxVerify(ctx->handle, node->_c_node); PYXMLSEC_DUMP(xmlSecDSigCtxDebugDump, ctx->handle); Py_END_ALLOW_THREADS; if (rv < 0) { PyXmlSec_SetLastError("failed to verify"); goto ON_FAIL; } if (ctx->handle->status != xmlSecDSigStatusSucceeded) { PyErr_SetString(PyXmlSec_VerificationError, "Signature is invalid."); goto ON_FAIL; } PYXMLSEC_DEBUGF("%p: verify - ok", self); Py_RETURN_NONE; ON_FAIL: PYXMLSEC_DEBUGF("%p: verify - fail", self); return NULL; } // common helper for operations binary_verify and binary_sign static int PyXmlSec_ProcessSignBinary(PyXmlSec_SignatureContext* ctx, const xmlSecByte* data, xmlSecSize data_size, xmlSecTransformId method) { int rv; if (!(method->usage & xmlSecTransformUsageSignatureMethod)) { PyErr_SetString(PyXmlSec_Error, "incompatible signature method"); return -1; } if (ctx->handle->signKey == NULL) { PyErr_SetString(PyXmlSec_Error, "Sign key is not specified."); return -1; } if (ctx->handle->signMethod != NULL) { PYXMLSEC_DEBUGF("%p: signMethod: %p", ctx, ctx->handle->signMethod); PyErr_SetString(PyXmlSec_Error, "Signature context already used; it is designed for one use only."); return -1; } ctx->handle->signMethod = xmlSecTransformCtxCreateAndAppend(&(ctx->handle->transformCtx), method); if (ctx->handle->signMethod == NULL) { PyXmlSec_SetLastError("could not create signature transform."); return -1; } ctx->handle->signMethod->operation = ctx->handle->operation; xmlSecTransformSetKeyReq(ctx->handle->signMethod, &(ctx->handle->keyInfoReadCtx.keyReq)); rv = xmlSecKeyMatch(ctx->handle->signKey, NULL, &(ctx->handle->keyInfoReadCtx.keyReq)); if (rv != 1) { PyXmlSec_SetLastError("inappropriate key type."); return -1; } rv = xmlSecTransformSetKey(ctx->handle->signMethod, ctx->handle->signKey); if (rv < 0) { PyXmlSec_SetLastError("cannot set key."); return -1; } ctx->handle->transformCtx.result = NULL; ctx->handle->transformCtx.status = xmlSecTransformStatusNone; Py_BEGIN_ALLOW_THREADS; rv = xmlSecTransformCtxBinaryExecute(&(ctx->handle->transformCtx), data, data_size); Py_END_ALLOW_THREADS; if (rv < 0) { PyXmlSec_SetLastError("failed to transform."); return -1; } ctx->handle->result = ctx->handle->transformCtx.result; return 0; } static const char PyXmlSec_SignatureContextSignBinary__doc__[] = \ "sign_binary(bytes, transform) -> bytes\n" "Signs binary data ``data`` with algorithm ``transform``.\n\n" ":param bytes: the binary data\n" ":type bytes: :class:`bytes`\n" ":param transform: the signature algorithm\n" ":type transform: :class:`__Transform`\n" ":return: the signature\n" ":rtype: :class:`bytes`"; static PyObject* PyXmlSec_SignatureContextSignBinary(PyObject* self, PyObject* args, PyObject* kwargs) { static char *kwlist[] = { "bytes", "transform", NULL}; PyXmlSec_SignatureContext* ctx = (PyXmlSec_SignatureContext*)self; PyXmlSec_Transform* transform = NULL; const char* data = NULL; Py_ssize_t data_size = 0; PYXMLSEC_DEBUGF("%p: sign_binary - start", self); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#O!:sign_binary", kwlist, &data, &data_size, PyXmlSec_TransformType, &transform)) { goto ON_FAIL; } ctx->handle->operation = xmlSecTransformOperationSign; if (PyXmlSec_ProcessSignBinary(ctx, (const xmlSecByte*)data, (xmlSecSize)data_size, transform->id) != 0) { goto ON_FAIL; } PYXMLSEC_DEBUGF("%p: sign_binary - ok", self); return PyBytes_FromStringAndSize( (const char*)xmlSecBufferGetData(ctx->handle->result), (Py_ssize_t)xmlSecBufferGetSize(ctx->handle->result) ); ON_FAIL: PYXMLSEC_DEBUGF("%p: sign_binary - fail", self); return NULL; } static const char PyXmlSec_SignatureContextVerifyBinary__doc__[] = \ "verify_binary(bytes, transform, signature) -> None\n" "Verifies signature for binary data.\n\n" ":param bytes: the binary data\n" ":type bytes: :class:`bytes`\n" ":param transform: the signature algorithm\n" ":type transform: :class:`__Transform`\n" ":param signature: the signature\n" ":type signature: :class:`bytes`\n" ":return: :data:`None` on success\n" ":raise VerificationError: on failure"; static PyObject* PyXmlSec_SignatureContextVerifyBinary(PyObject* self, PyObject* args, PyObject* kwargs) { static char *kwlist[] = { "bytes", "transform", "signature", NULL}; PyXmlSec_SignatureContext* ctx = (PyXmlSec_SignatureContext*)self; PyXmlSec_Transform* transform = NULL; const char* data = NULL; Py_ssize_t data_size = 0; const char* sign = NULL; Py_ssize_t sign_size = 0; int rv; PYXMLSEC_DEBUGF("%p: verify binary - start", self); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#O!s#:verify_binary", kwlist, &data, &data_size, PyXmlSec_TransformType, &transform, &sign, &sign_size)) { goto ON_FAIL; } ctx->handle->operation = xmlSecTransformOperationVerify; if (PyXmlSec_ProcessSignBinary(ctx, (const xmlSecByte*)data, (xmlSecSize)data_size, transform->id) != 0) { goto ON_FAIL; } Py_BEGIN_ALLOW_THREADS; rv = xmlSecTransformVerify(ctx->handle->signMethod, (const xmlSecByte*)sign, (xmlSecSize)sign_size, &(ctx->handle->transformCtx)); Py_END_ALLOW_THREADS; if (rv < 0) { PyXmlSec_SetLastError2(PyXmlSec_VerificationError, "Cannot verify signature."); goto ON_FAIL; } if (ctx->handle->signMethod->status != xmlSecTransformStatusOk) { PyXmlSec_SetLastError2(PyXmlSec_VerificationError, "Signature is invalid."); goto ON_FAIL; } PYXMLSEC_DEBUGF("%p: verify binary - ok", self); Py_RETURN_NONE; ON_FAIL: PYXMLSEC_DEBUGF("%p: verify binary - fail", self); return NULL; } static const char PyXmlSec_SignatureContextEnableReferenceTransform__doc__[] = \ "enable_reference_transform(transform) -> None\n" "Enables use of ``transform`` as reference transform.\n\n" ".. note:: by default, all transforms are enabled. The first call of " ":meth:`~SignatureContext.enable_reference_transform` will switch to explicitly enabled transforms.\n\n" ":param transform: the transform klass.\n" ":type transform: :class:`__Transform`"; static PyObject* PyXmlSec_SignatureContextEnableReferenceTransform(PyObject* self, PyObject* args, PyObject* kwargs) { static char *kwlist[] = { "transform", NULL}; PyXmlSec_SignatureContext* ctx = (PyXmlSec_SignatureContext*)self; PyXmlSec_Transform* transform = NULL; int rv; PYXMLSEC_DEBUGF("%p: enable_reference_transform - start", self); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!:enable_reference_transform", kwlist, PyXmlSec_TransformType, &transform)) { goto ON_FAIL; } Py_BEGIN_ALLOW_THREADS; rv = xmlSecDSigCtxEnableReferenceTransform(ctx->handle, transform->id); Py_END_ALLOW_THREADS; if (rv < 0) { PyXmlSec_SetLastError("cannot enable reference transform."); goto ON_FAIL; } PYXMLSEC_DEBUGF("%p: enable_reference_transform - ok", self); Py_RETURN_NONE; ON_FAIL: PYXMLSEC_DEBUGF("%p: enable_reference_transform - fail", self); return NULL; } static const char PyXmlSec_SignatureContextEnableSignatureTransform__doc__[] = \ "enable_signature_transform(transform) -> None\n" "Enables use of ``transform`` as signature transform.\n\n" ".. note:: by default, all transforms are enabled. The first call of " ":meth:`~SignatureContext.enable_signature_transform` will switch to explicitly enabled transforms.\n\n" ":param transform: the transform klass.\n" ":type transform: :class:`__Transform`\n"; static PyObject* PyXmlSec_SignatureContextEnableSignatureTransform(PyObject* self, PyObject* args, PyObject* kwargs) { static char *kwlist[] = { "transform", NULL}; PyXmlSec_SignatureContext* ctx = (PyXmlSec_SignatureContext*)self; PyXmlSec_Transform* transform = NULL; int rv; PYXMLSEC_DEBUGF("%p: enable_signature_transform - start", self); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!:enable_signature_transform", kwlist, PyXmlSec_TransformType, &transform)) { goto ON_FAIL; } Py_BEGIN_ALLOW_THREADS; rv = xmlSecDSigCtxEnableSignatureTransform(ctx->handle, transform->id); Py_END_ALLOW_THREADS; if (rv < 0) { PyXmlSec_SetLastError("cannot enable signature transform."); goto ON_FAIL; } PYXMLSEC_DEBUGF("%p: enable_signature_transform - ok", self); Py_RETURN_NONE; ON_FAIL: PYXMLSEC_DEBUGF("%p: enable_signature_transform - fail", self); return NULL; } static const char PyXmlSec_SignatureContextSetEnabledKeyData__doc__[] = \ "set_enabled_key_data(keydata_list) -> None\n" "Adds selected :class:`__KeyData` to the list of enabled key data list.\n\n" ":param keydata_list: the list\n" ":type keydata_list: :class:`list` of :class:`__KeyData`"; static PyObject* PyXmlSec_SignatureContextSetEnabledKeyData(PyObject* self, PyObject* args, PyObject* kwargs) { static char *kwlist[] = { "keydata_list", NULL}; PyXmlSec_SignatureContext* ctx = (PyXmlSec_SignatureContext*)self; PyObject* keydata_list = NULL; PyObject* iter = NULL; PyObject* item = NULL; xmlSecPtrListPtr enabled_list; PYXMLSEC_DEBUGF("%p: set_enabled_key_data - start", self); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:set_enabled_key_data", kwlist, &keydata_list)) { goto ON_FAIL; } if ((iter = PyObject_GetIter(keydata_list)) == NULL) goto ON_FAIL; enabled_list = &(ctx->handle->keyInfoReadCtx.enabledKeyData); xmlSecPtrListEmpty(enabled_list); while ((item = PyIter_Next(iter)) != NULL) { if (!PyObject_IsInstance(item, (PyObject*)PyXmlSec_KeyDataType)) { PyErr_SetString(PyExc_TypeError, "expected list of KeyData constants."); goto ON_FAIL; } if (xmlSecPtrListAdd(enabled_list, (xmlSecPtr)((PyXmlSec_KeyData*)item)->id) < 0) { PyXmlSec_SetLastError("cannot set enabled key."); goto ON_FAIL; } Py_DECREF(item); } Py_DECREF(iter); PYXMLSEC_DEBUGF("%p: set_enabled_key_data - ok", self); Py_RETURN_NONE; ON_FAIL: PYXMLSEC_DEBUGF("%p: set_enabled_key_data - fail", self); Py_XDECREF(item); Py_XDECREF(iter); return NULL; } static PyGetSetDef PyXmlSec_SignatureContextGetSet[] = { { "key", (getter)PyXmlSec_SignatureContextKeyGet, (setter)PyXmlSec_SignatureContextKeySet, (char*)PyXmlSec_SignatureContextKey__doc__, NULL }, {NULL} /* Sentinel */ }; static PyMethodDef PyXmlSec_SignatureContextMethods[] = { { "register_id", (PyCFunction)PyXmlSec_SignatureContextRegisterId, METH_VARARGS|METH_KEYWORDS, PyXmlSec_SignatureContextRegisterId__doc__, }, { "sign", (PyCFunction)PyXmlSec_SignatureContextSign, METH_VARARGS|METH_KEYWORDS, PyXmlSec_SignatureContextSign__doc__ }, { "verify", (PyCFunction)PyXmlSec_SignatureContextVerify, METH_VARARGS|METH_KEYWORDS, PyXmlSec_SignatureContextVerify__doc__ }, { "sign_binary", (PyCFunction)PyXmlSec_SignatureContextSignBinary, METH_VARARGS|METH_KEYWORDS, PyXmlSec_SignatureContextSignBinary__doc__ }, { "verify_binary", (PyCFunction)PyXmlSec_SignatureContextVerifyBinary, METH_VARARGS|METH_KEYWORDS, PyXmlSec_SignatureContextVerifyBinary__doc__ }, { "enable_reference_transform", (PyCFunction)PyXmlSec_SignatureContextEnableReferenceTransform, METH_VARARGS|METH_KEYWORDS, PyXmlSec_SignatureContextEnableReferenceTransform__doc__ }, { "enable_signature_transform", (PyCFunction)PyXmlSec_SignatureContextEnableSignatureTransform, METH_VARARGS|METH_KEYWORDS, PyXmlSec_SignatureContextEnableSignatureTransform__doc__, }, { "set_enabled_key_data", (PyCFunction)PyXmlSec_SignatureContextSetEnabledKeyData, METH_VARARGS|METH_KEYWORDS, PyXmlSec_SignatureContextSetEnabledKeyData__doc__, }, {NULL, NULL} /* sentinel */ }; static PyTypeObject _PyXmlSec_SignatureContextType = { PyVarObject_HEAD_INIT(NULL, 0) STRINGIFY(MODULE_NAME) ".SignatureContext", /* tp_name */ sizeof(PyXmlSec_SignatureContext), /* tp_basicsize */ 0, /* tp_itemsize */ PyXmlSec_SignatureContext__del__, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */ "XML Digital Signature implementation", /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ PyXmlSec_SignatureContextMethods, /* tp_methods */ 0, /* tp_members */ PyXmlSec_SignatureContextGetSet, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ PyXmlSec_SignatureContext__init__, /* tp_init */ 0, /* tp_alloc */ PyXmlSec_SignatureContext__new__, /* tp_new */ 0, /* tp_free */ }; PyTypeObject* PyXmlSec_SignatureContextType = &_PyXmlSec_SignatureContextType; int PyXmlSec_DSModule_Init(PyObject* package) { if (PyType_Ready(PyXmlSec_SignatureContextType) < 0) goto ON_FAIL; // since objects is created as static objects, need to increase refcount to prevent deallocate Py_INCREF(PyXmlSec_SignatureContextType); if (PyModule_AddObject(package, "SignatureContext", (PyObject*)PyXmlSec_SignatureContextType) < 0) goto ON_FAIL; return 0; ON_FAIL: return -1; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/src/enc.c0000644000175100001710000005027314300243501014170 0ustar00runnerdocker// Copyright (c) 2017 Ryan Leckey // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "common.h" #include "platform.h" #include "exception.h" #include "constants.h" #include "keys.h" #include "lxml.h" #include #include typedef struct { PyObject_HEAD xmlSecEncCtxPtr handle; PyXmlSec_KeysManager* manager; } PyXmlSec_EncryptionContext; static PyObject* PyXmlSec_EncryptionContext__new__(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyXmlSec_EncryptionContext* ctx = (PyXmlSec_EncryptionContext*)PyType_GenericNew(type, args, kwargs); PYXMLSEC_DEBUGF("%p: new enc context", ctx); if (ctx != NULL) { ctx->handle = NULL; ctx->manager = NULL; } return (PyObject*)(ctx); } static int PyXmlSec_EncryptionContext__init__(PyObject* self, PyObject* args, PyObject* kwargs) { static char *kwlist[] = { "manager", NULL}; PyXmlSec_KeysManager* manager = NULL; PyXmlSec_EncryptionContext* ctx = (PyXmlSec_EncryptionContext*)self; PYXMLSEC_DEBUGF("%p: init enc context", self); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:__init__", kwlist, PyXmlSec_KeysManagerConvert, &manager)) { goto ON_FAIL; } ctx->handle = xmlSecEncCtxCreate(manager != NULL ? manager->handle : NULL); if (ctx->handle == NULL) { PyXmlSec_SetLastError("failed to create the encryption context"); goto ON_FAIL; } ctx->manager = manager; PYXMLSEC_DEBUGF("%p: init enc context - ok, manager - %p", self, manager); return 0; ON_FAIL: PYXMLSEC_DEBUGF("%p: init enc context - failed", self); Py_XDECREF(manager); return -1; } static void PyXmlSec_EncryptionContext__del__(PyObject* self) { PyXmlSec_EncryptionContext* ctx = (PyXmlSec_EncryptionContext*)self; PYXMLSEC_DEBUGF("%p: delete enc context", self); if (ctx->handle != NULL) { xmlSecEncCtxDestroy(ctx->handle); } // release manager object Py_XDECREF(ctx->manager); Py_TYPE(self)->tp_free(self); } static const char PyXmlSec_EncryptionContextKey__doc__[] = "Encryption key.\n"; static PyObject* PyXmlSec_EncryptionContextKeyGet(PyObject* self, void* closure) { PyXmlSec_EncryptionContext* ctx = ((PyXmlSec_EncryptionContext*)self); PyXmlSec_Key* key; if (ctx->handle->encKey == NULL) { Py_RETURN_NONE; } key = PyXmlSec_NewKey(); key->handle = ctx->handle->encKey; key->is_own = 0; return (PyObject*)key; } static int PyXmlSec_EncryptionContextKeySet(PyObject* self, PyObject* value, void* closure) { PyXmlSec_EncryptionContext* ctx = (PyXmlSec_EncryptionContext*)self; PyXmlSec_Key* key; PYXMLSEC_DEBUGF("%p, %p", self, value); if (value == NULL) { // key deletion if (ctx->handle->encKey != NULL) { xmlSecKeyDestroy(ctx->handle->encKey); ctx->handle->encKey = NULL; } return 0; } if (!PyObject_IsInstance(value, (PyObject*)PyXmlSec_KeyType)) { PyErr_SetString(PyExc_TypeError, "instance of *xmlsec.Key* expected."); return -1; } key = (PyXmlSec_Key*)value; if (key->handle == NULL) { PyErr_SetString(PyExc_TypeError, "empty key."); return -1; } if (ctx->handle->encKey != NULL) { xmlSecKeyDestroy(ctx->handle->encKey); } ctx->handle->encKey = xmlSecKeyDuplicate(key->handle); if (ctx->handle->encKey == NULL) { PyXmlSec_SetLastError("failed to duplicate key"); return -1; } return 0; } static const char PyXmlSec_EncryptionContextReset__doc__[] = \ "reset() -> None\n"\ "Reset this context, user settings are not touched.\n"; static PyObject* PyXmlSec_EncryptionContextReset(PyObject* self, PyObject* args, PyObject* kwargs) { PyXmlSec_EncryptionContext* ctx = (PyXmlSec_EncryptionContext*)self; PYXMLSEC_DEBUGF("%p: reset context - start", self); Py_BEGIN_ALLOW_THREADS; xmlSecEncCtxReset(ctx->handle); PYXMLSEC_DUMP(xmlSecEncCtxDebugDump, ctx->handle); Py_END_ALLOW_THREADS; PYXMLSEC_DEBUGF("%p: reset context - ok", self); Py_RETURN_NONE; } static const char PyXmlSec_EncryptionContextEncryptBinary__doc__[] = \ "encrypt_binary(template, data) -> lxml.etree._Element\n" "Encrypts binary ``data`` according to ``EncryptedData`` template ``template``.\n\n" ".. note:: ``template`` is modified in place.\n\n" ":param template: the pointer to :xml:`` template node\n" ":type template: :class:`lxml.etree._Element`\n" ":param data: the data\n" ":type data: :class:`bytes`\n" ":return: the resulting :xml:`` subtree\n" ":rtype: :class:`lxml.etree._Element`"; static PyObject* PyXmlSec_EncryptionContextEncryptBinary(PyObject* self, PyObject* args, PyObject* kwargs) { static char *kwlist[] = { "template", "data", NULL}; PyXmlSec_EncryptionContext* ctx = (PyXmlSec_EncryptionContext*)self; PyXmlSec_LxmlElementPtr template = NULL; const char* data = NULL; Py_ssize_t data_size = 0; int rv; PYXMLSEC_DEBUGF("%p: encrypt_binary - start", self); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&s#:encrypt_binary", kwlist, PyXmlSec_LxmlElementConverter, &template, &data, &data_size)) { goto ON_FAIL; } Py_BEGIN_ALLOW_THREADS; rv = xmlSecEncCtxBinaryEncrypt(ctx->handle, template->_c_node, (const xmlSecByte*)data, (xmlSecSize)data_size); PYXMLSEC_DUMP(xmlSecEncCtxDebugDump, ctx->handle); Py_END_ALLOW_THREADS; if (rv < 0) { PyXmlSec_SetLastError("failed to encrypt binary"); goto ON_FAIL; } Py_INCREF(template); PYXMLSEC_DEBUGF("%p: encrypt_binary - ok", self); return (PyObject*)template; ON_FAIL: PYXMLSEC_DEBUGF("%p: encrypt_binary - fail", self); return NULL; } // release the replaced nodes in a way safe for `lxml` static void PyXmlSec_ClearReplacedNodes(xmlSecEncCtxPtr ctx, PyXmlSec_LxmlDocumentPtr doc) { PyXmlSec_LxmlElementPtr* elem; // release the replaced nodes in a way safe for `lxml` xmlNodePtr n = ctx->replacedNodeList; xmlNodePtr nn; while (n != NULL) { PYXMLSEC_DEBUGF("clear replaced node %p", n); nn = n->next; // if n has references, it will not be deleted elem = PyXmlSec_elementFactory(doc, n); if (NULL == elem) xmlFreeNode(n); else Py_DECREF(elem); n = nn; } ctx->replacedNodeList = NULL; } static const char PyXmlSec_EncryptionContextEncryptXml__doc__[] = \ "encrypt_xml(template, node) -> lxml.etree._Element\n" "Encrypts ``node`` using ``template``.\n\n" ".. note:: The ``\"Type\"`` attribute of ``template`` decides whether ``node`` itself " "(``http://www.w3.org/2001/04/xmlenc#Element``) or its content (``http://www.w3.org/2001/04/xmlenc#Content``) is encrypted.\n" " It must have one of these two values (or an exception is raised).\n" " The operation modifies the tree and removes replaced nodes.\n\n" ":param template: the pointer to :xml:`` template node\n\n" ":type template: :class:`lxml.etree._Element`\n" ":param node: the pointer to node for encryption\n\n" ":type node: :class:`lxml.etree._Element`\n" ":return: the pointer to newly created :xml:`` node\n" ":rtype: :class:`lxml.etree._Element`"; static PyObject* PyXmlSec_EncryptionContextEncryptXml(PyObject* self, PyObject* args, PyObject* kwargs) { static char *kwlist[] = { "template", "node", NULL}; PyXmlSec_EncryptionContext* ctx = (PyXmlSec_EncryptionContext*)self; PyXmlSec_LxmlElementPtr template = NULL; PyXmlSec_LxmlElementPtr node = NULL; xmlNodePtr xnew_node = NULL; xmlChar* tmpType = NULL; int rv = 0; PYXMLSEC_DEBUGF("%p: encrypt_xml - start", self); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:encrypt_xml", kwlist, PyXmlSec_LxmlElementConverter, &template, PyXmlSec_LxmlElementConverter, &node)) { goto ON_FAIL; } tmpType = xmlGetProp(template->_c_node, XSTR("Type")); if (tmpType == NULL || !(xmlStrEqual(tmpType, xmlSecTypeEncElement) || xmlStrEqual(tmpType, xmlSecTypeEncContent))) { PyErr_SetString(PyXmlSec_Error, "unsupported `Type`, it should be `element` or `content`"); goto ON_FAIL; } // `xmlSecEncCtxXmlEncrypt` will replace the subtree rooted // at `node._c_node` or its children by an extended subtree rooted at "c_node". // We set `XMLSEC_ENC_RETURN_REPLACED_NODE` to prevent deallocation // of the replaced node. This is important as `node` is still referencing it ctx->handle->flags = XMLSEC_ENC_RETURN_REPLACED_NODE; // try to do all actions whithin single python-free section // rv has the following codes, 1 - failed to copy node, -1 - op failed, 0 - success Py_BEGIN_ALLOW_THREADS; if (template->_doc->_c_doc != node->_doc->_c_doc) { // `xmlSecEncCtxEncrypt` expects *template* to belong to the document of *node* // if this is not the case, we copy the `libxml2` subtree there. xnew_node = xmlDocCopyNode(template->_c_node, node->_doc->_c_doc, 1); // recursive if (xnew_node == NULL) { rv = 1; } } if (rv == 0 && xmlSecEncCtxXmlEncrypt(ctx->handle, xnew_node != NULL ? xnew_node: template->_c_node, node->_c_node) < 0) { rv = -1; if (xnew_node != NULL) { xmlFreeNode(xnew_node); xnew_node = NULL; } } PYXMLSEC_DUMP(xmlSecEncCtxDebugDump, ctx->handle); Py_END_ALLOW_THREADS; PyXmlSec_ClearReplacedNodes(ctx->handle, node->_doc); if (NULL != PyErr_Occurred()) { goto ON_FAIL; } if (rv != 0) { if (rv > 0) { PyErr_SetString(PyXmlSec_InternalError, "could not copy template tree"); } else { PyXmlSec_SetLastError("failed to encrypt xml"); } goto ON_FAIL; } xmlFree(tmpType); PYXMLSEC_DEBUGF("%p: encrypt_xml - ok", self); return (PyObject*)PyXmlSec_elementFactory(node->_doc, xnew_node != NULL ? xnew_node : template->_c_node); ON_FAIL: PYXMLSEC_DEBUGF("%p: encrypt_xml - fail", self); xmlFree(tmpType); return NULL; } static const char PyXmlSec_EncryptionContextEncryptUri__doc__[] = \ "encrypt_uri(template, uri) -> lxml.etree._Element\n" "Encrypts binary data obtained from ``uri`` according to ``template``.\n\n" ".. note:: ``template`` is modified in place.\n\n" ":param template: the pointer to :xml:`` template node\n" ":type template: :class:`lxml.etree._Element`\n" ":param uri: the URI\n" ":type uri: :class:`str`\n" ":return: the resulting :xml:`` subtree\n" ":rtype: :class:`lxml.etree._Element`"; static PyObject* PyXmlSec_EncryptionContextEncryptUri(PyObject* self, PyObject* args, PyObject* kwargs) { static char *kwlist[] = { "template", "uri", NULL}; PyXmlSec_EncryptionContext* ctx = (PyXmlSec_EncryptionContext*)self; PyXmlSec_LxmlElementPtr template = NULL; const char* uri = NULL; int rv; PYXMLSEC_DEBUGF("%p: encrypt_uri - start", self); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&s:encrypt_uri", kwlist, PyXmlSec_LxmlElementConverter, &template, &uri)) { goto ON_FAIL; } Py_BEGIN_ALLOW_THREADS; rv = xmlSecEncCtxUriEncrypt(ctx->handle, template->_c_node, (const xmlSecByte*)uri); PYXMLSEC_DUMP(xmlSecEncCtxDebugDump, ctx->handle); Py_END_ALLOW_THREADS; if (rv < 0) { PyXmlSec_SetLastError("failed to encrypt URI"); goto ON_FAIL; } PYXMLSEC_DEBUGF("%p: encrypt_uri - ok", self); Py_INCREF(template); return (PyObject*)template; ON_FAIL: PYXMLSEC_DEBUGF("%p: encrypt_uri - fail", self); return NULL; } static const char PyXmlSec_EncryptionContextDecrypt__doc__[] = \ "decrypt(node)\n" "Decrypts ``node`` (an ``EncryptedData`` or ``EncryptedKey`` element) and returns the result. " "The decryption may result in binary data or an XML subtree. " "In the former case, the binary data is returned. In the latter case, " "the input tree is modified and a reference to the decrypted XML subtree is returned.\n" "If the operation modifies the tree, it removes replaced nodes.\n\n" ":param node: the pointer to :xml:`` or :xml:`` node\n" ":type node: :class:`lxml.etree._Element`\n" ":return: depends on input parameters\n" ":rtype: :class:`lxml.etree._Element` or :class:`bytes`"; static PyObject* PyXmlSec_EncryptionContextDecrypt(PyObject* self, PyObject* args, PyObject* kwargs) { static char *kwlist[] = { "node", NULL}; PyXmlSec_EncryptionContext* ctx = (PyXmlSec_EncryptionContext*)self; PyXmlSec_LxmlElementPtr node = NULL; PyObject* node_num = NULL; PyObject* parent = NULL; PyObject* tmp; xmlNodePtr root; xmlNodePtr xparent; int rv; xmlChar* ttype; int notContent; PYXMLSEC_DEBUGF("%p: decrypt - start", self); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:decrypt", kwlist, PyXmlSec_LxmlElementConverter, &node)) { goto ON_FAIL; } xparent = node->_c_node->parent; if (xparent != NULL && !PyXmlSec_IsElement(xparent)) { xparent = NULL; } if (xparent != NULL) { parent = (PyObject*)PyXmlSec_elementFactory(node->_doc, xparent); if (parent == NULL) { PyErr_SetString(PyXmlSec_InternalError, "failed to construct parent"); goto ON_FAIL; } // get index of node node_num = PyObject_CallMethod(parent, "index", "O", node); PYXMLSEC_DEBUGF("parent: %p, %p", parent, node_num); } Py_BEGIN_ALLOW_THREADS; ctx->handle->flags = XMLSEC_ENC_RETURN_REPLACED_NODE; ctx->handle->mode = xmlSecCheckNodeName(node->_c_node, xmlSecNodeEncryptedKey, xmlSecEncNs) ? xmlEncCtxModeEncryptedKey : xmlEncCtxModeEncryptedData; PYXMLSEC_DEBUGF("mode: %d", ctx->handle->mode); rv = xmlSecEncCtxDecrypt(ctx->handle, node->_c_node); PYXMLSEC_DUMP(xmlSecEncCtxDebugDump, ctx->handle); Py_END_ALLOW_THREADS; PyXmlSec_ClearReplacedNodes(ctx->handle, node->_doc); if (rv < 0) { PyXmlSec_SetLastError("failed to decrypt"); goto ON_FAIL; } if (!ctx->handle->resultReplaced) { Py_XDECREF(node_num); Py_XDECREF(parent); PYXMLSEC_DEBUGF("%p: binary.decrypt - ok", self); return PyBytes_FromStringAndSize( (const char*)xmlSecBufferGetData(ctx->handle->result), (Py_ssize_t)xmlSecBufferGetSize(ctx->handle->result) ); } if (xparent != NULL) { ttype = xmlGetProp(node->_c_node, XSTR("Type")); notContent = (ttype == NULL || !xmlStrEqual(ttype, xmlSecTypeEncContent)); xmlFree(ttype); if (notContent) { tmp = PyObject_GetItem(parent, node_num); if (tmp == NULL) goto ON_FAIL; Py_DECREF(parent); parent = tmp; } Py_DECREF(node_num); PYXMLSEC_DEBUGF("%p: parent.decrypt - ok", self); return parent; } // root has been replaced root = xmlDocGetRootElement(node->_doc->_c_doc); if (root == NULL) { PyErr_SetString(PyXmlSec_Error, "decryption resulted in a non well formed document"); goto ON_FAIL; } Py_XDECREF(node_num); Py_XDECREF(parent); PYXMLSEC_DEBUGF("%p: decrypt - ok", self); return (PyObject*)PyXmlSec_elementFactory(node->_doc, root); ON_FAIL: PYXMLSEC_DEBUGF("%p: decrypt - fail", self); Py_XDECREF(node_num); Py_XDECREF(parent); return NULL; } static PyGetSetDef PyXmlSec_EncryptionContextGetSet[] = { { "key", (getter)PyXmlSec_EncryptionContextKeyGet, (setter)PyXmlSec_EncryptionContextKeySet, (char*)PyXmlSec_EncryptionContextKey__doc__, NULL }, {NULL} /* Sentinel */ }; static PyMethodDef PyXmlSec_EncryptionContextMethods[] = { { "reset", (PyCFunction)PyXmlSec_EncryptionContextReset, METH_NOARGS, PyXmlSec_EncryptionContextReset__doc__, }, { "encrypt_binary", (PyCFunction)PyXmlSec_EncryptionContextEncryptBinary, METH_VARARGS|METH_KEYWORDS, PyXmlSec_EncryptionContextEncryptBinary__doc__, }, { "encrypt_xml", (PyCFunction)PyXmlSec_EncryptionContextEncryptXml, METH_VARARGS|METH_KEYWORDS, PyXmlSec_EncryptionContextEncryptXml__doc__ }, { "encrypt_uri", (PyCFunction)PyXmlSec_EncryptionContextEncryptUri, METH_VARARGS|METH_KEYWORDS, PyXmlSec_EncryptionContextEncryptUri__doc__ }, { "decrypt", (PyCFunction)PyXmlSec_EncryptionContextDecrypt, METH_VARARGS|METH_KEYWORDS, PyXmlSec_EncryptionContextDecrypt__doc__ }, {NULL, NULL} /* sentinel */ }; static PyTypeObject _PyXmlSec_EncryptionContextType = { PyVarObject_HEAD_INIT(NULL, 0) STRINGIFY(MODULE_NAME) ".EncryptionContext", /* tp_name */ sizeof(PyXmlSec_EncryptionContext), /* tp_basicsize */ 0, /* tp_itemsize */ PyXmlSec_EncryptionContext__del__, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */ "XML Encryption implementation", /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ PyXmlSec_EncryptionContextMethods, /* tp_methods */ 0, /* tp_members */ PyXmlSec_EncryptionContextGetSet, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ PyXmlSec_EncryptionContext__init__, /* tp_init */ 0, /* tp_alloc */ PyXmlSec_EncryptionContext__new__, /* tp_new */ 0 /* tp_free */ }; PyTypeObject* PyXmlSec_EncryptionContextType = &_PyXmlSec_EncryptionContextType; int PyXmlSec_EncModule_Init(PyObject* package) { if (PyType_Ready(PyXmlSec_EncryptionContextType) < 0) goto ON_FAIL; PYXMLSEC_DEBUGF("%p", PyXmlSec_EncryptionContextType); // since objects is created as static objects, need to increase refcount to prevent deallocate Py_INCREF(PyXmlSec_EncryptionContextType); if (PyModule_AddObject(package, "EncryptionContext", (PyObject*)PyXmlSec_EncryptionContextType) < 0) goto ON_FAIL; return 0; ON_FAIL: return -1; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/src/exception.c0000644000175100001710000001715314300243501015421 0ustar00runnerdocker// Copyright (c) 2017 Ryan Leckey // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "common.h" #include "exception.h" #include "utils.h" #include #include #include #include // default error class PyObject* PyXmlSec_Error; PyObject* PyXmlSec_InternalError; PyObject* PyXmlSec_VerificationError; #if PY_MINOR_VERSION >= 7 static Py_tss_t PyXmlSec_LastErrorKey; #else static int PyXmlSec_LastErrorKey = 0; #endif static int PyXmlSec_PrintErrorMessage = 0; typedef struct { const xmlChar* file; const xmlChar* func; const xmlChar* object; const xmlChar* subject; const xmlChar* msg; int line; int reason; } PyXmlSec_ErrorHolder; PyXmlSec_ErrorHolder* PyXmlSec_ErrorHolderCreate(const char* file, int line, const char* func, const char* object, const char* subject, int reason, const char* msg) { PyXmlSec_ErrorHolder* h = (PyXmlSec_ErrorHolder*)xmlMalloc(sizeof(PyXmlSec_ErrorHolder)); // file and func is __FILE__ and __FUNCTION__ macro, so it can be stored as is. h->file = XSTR(file); h->line = line; h->func = XSTR(func); h->reason = reason; // there is no guarantee that object and subject will not be deallocate after exit from function, // so make a copy // xmlCharStrdup returns NULL if arg is NULL h->object = xmlCharStrdup(object); h->subject = xmlCharStrdup(subject); h->msg = xmlCharStrdup(msg); PYXMLSEC_DEBUGF("new error %p", h); return h; } void PyXmlSec_ErrorHolderFree(PyXmlSec_ErrorHolder* h) { if (h != NULL) { PYXMLSEC_DEBUGF("free error %p", h); xmlFree((void*)(h->object)); xmlFree((void*)(h->subject)); xmlFree((void*)(h->msg)); xmlFree((void*)(h)); } } // saves new error in TLS and returns previous static PyXmlSec_ErrorHolder* PyXmlSec_ExchangeLastError(PyXmlSec_ErrorHolder* e) { PyXmlSec_ErrorHolder* v; int r; #if PY_MINOR_VERSION >= 7 if (PyThread_tss_is_created(&PyXmlSec_LastErrorKey) == 0) { #else if (PyXmlSec_LastErrorKey == 0) { #endif PYXMLSEC_DEBUG("WARNING: There is no error key."); PyXmlSec_ErrorHolderFree(e); return NULL; } // get_key_value and set_key_value are gil free #if PY_MINOR_VERSION >= 7 v = (PyXmlSec_ErrorHolder*)PyThread_tss_get(&PyXmlSec_LastErrorKey); //PyThread_tss_delete(&PyXmlSec_LastErrorKey); r = PyThread_tss_set(&PyXmlSec_LastErrorKey, (void*)e); #else v = (PyXmlSec_ErrorHolder*)PyThread_get_key_value(PyXmlSec_LastErrorKey); PyThread_delete_key_value(PyXmlSec_LastErrorKey); r = PyThread_set_key_value(PyXmlSec_LastErrorKey, (void*)e); #endif PYXMLSEC_DEBUGF("set_key_value returns %d", r); return v; } // xmlsec library error callback static void PyXmlSec_ErrorCallback(const char* file, int line, const char* func, const char* object, const char* subject, int reason, const char* msg) { // TODO do not allocate error object each time. PyXmlSec_ErrorHolderFree(PyXmlSec_ExchangeLastError(PyXmlSec_ErrorHolderCreate(file, line, func, object, subject, reason, msg))); if (PyXmlSec_PrintErrorMessage) { const char* error_msg = NULL; xmlSecSize i; for (i = 0; (i < XMLSEC_ERRORS_MAX_NUMBER) && (xmlSecErrorsGetMsg(i) != NULL); ++i) { if(xmlSecErrorsGetCode(i) == reason) { error_msg = xmlSecErrorsGetMsg(i); break; } } fprintf(stderr, "func=%s:file=%s:line=%d:obj=%s:subj=%s:error=%d:%s:%s\n", (func != NULL) ? func : "unknown", (file != NULL) ? file : "unknown", line, (object != NULL) ? object : "unknown", (subject != NULL) ? subject : "unknown", reason, (error_msg != NULL) ? error_msg : "", (msg != NULL) ? msg : ""); } } // pops the last error which was occurred in current thread // the gil should be acquired static PyObject* PyXmlSec_GetLastError(PyObject* type, const char* msg) { PyXmlSec_ErrorHolder* h = PyXmlSec_ExchangeLastError(NULL); PyObject* exc; if (h == NULL) { return NULL; } exc = PyObject_CallFunction(type, "is", h->reason, msg); if (exc == NULL) goto ON_FAIL; PyXmlSec_SetLongAttr(exc, "code", h->reason); PyXmlSec_SetStringAttr(exc, "message", msg); PyXmlSec_SetStringAttr(exc, "details", (const char*)xmlSecErrorsSafeString(h->msg)); PyXmlSec_SetStringAttr(exc, "file", (const char*)xmlSecErrorsSafeString(h->file)); PyXmlSec_SetLongAttr(exc, "line", h->line); PyXmlSec_SetStringAttr(exc, "func", (const char*)xmlSecErrorsSafeString(h->func)); PyXmlSec_SetStringAttr(exc, "object", (const char*)xmlSecErrorsSafeString(h->object)); PyXmlSec_SetStringAttr(exc, "subject", (const char*)xmlSecErrorsSafeString(h->subject)); ON_FAIL: PyXmlSec_ErrorHolderFree(h); return exc; } void PyXmlSec_SetLastError2(PyObject* type, const char* msg) { PyObject* last = PyXmlSec_GetLastError(type, msg); if (last == NULL) { PYXMLSEC_DEBUG("WARNING: no xmlsec error"); last = PyObject_CallFunction(PyXmlSec_InternalError, "is", (int)-1, msg); if (last == NULL) { return; } } PyErr_SetObject(type, last); Py_DECREF(last); } void PyXmlSec_SetLastError(const char* msg) { PyXmlSec_SetLastError2(PyXmlSec_Error, msg); } void PyXmlSec_ClearError(void) { PyXmlSec_ErrorHolderFree(PyXmlSec_ExchangeLastError(NULL)); } void PyXmlSecEnableDebugTrace(int v) { PyXmlSec_PrintErrorMessage = v; } void PyXmlSec_InstallErrorCallback() { #if PY_MINOR_VERSION >= 7 if (PyThread_tss_is_created(&PyXmlSec_LastErrorKey) != 0) { #else if (PyXmlSec_LastErrorKey != 0) { #endif xmlSecErrorsSetCallback(PyXmlSec_ErrorCallback); } } // initializes errors module int PyXmlSec_ExceptionsModule_Init(PyObject* package) { PyXmlSec_Error = NULL; PyXmlSec_InternalError = NULL; PyXmlSec_VerificationError = NULL; if ((PyXmlSec_Error = PyErr_NewExceptionWithDoc( STRINGIFY(MODULE_NAME) ".Error", "The common exception class.", PyExc_Exception, 0)) == NULL) goto ON_FAIL; if ((PyXmlSec_InternalError = PyErr_NewExceptionWithDoc( STRINGIFY(MODULE_NAME) ".InternalError", "The internal exception class.", PyXmlSec_Error, 0)) == NULL) goto ON_FAIL; if ((PyXmlSec_VerificationError = PyErr_NewExceptionWithDoc( STRINGIFY(MODULE_NAME) ".VerificationError", "The verification exception class.", PyXmlSec_Error, 0)) == NULL) goto ON_FAIL; if (PyModule_AddObject(package, "Error", PyXmlSec_Error) < 0) goto ON_FAIL; if (PyModule_AddObject(package, "InternalError", PyXmlSec_InternalError) < 0) goto ON_FAIL; if (PyModule_AddObject(package, "VerificationError", PyXmlSec_VerificationError) < 0) goto ON_FAIL; #if PY_MINOR_VERSION >= 7 if (PyThread_tss_create(&PyXmlSec_LastErrorKey) == 0) { PyXmlSec_InstallErrorCallback(); } #else PyXmlSec_LastErrorKey = PyThread_create_key(); PyXmlSec_InstallErrorCallback(); #endif return 0; ON_FAIL: Py_XDECREF(PyXmlSec_Error); Py_XDECREF(PyXmlSec_InternalError); Py_XDECREF(PyXmlSec_VerificationError); return -1; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/src/exception.h0000644000175100001710000000172614300243501015425 0ustar00runnerdocker// Copyright (c) 2017 Ryan Leckey // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #ifndef __PYXMLSEC_EXCEPTIONS_H__ #define __PYXMLSEC_EXCEPTIONS_H__ #include "platform.h" extern PyObject* PyXmlSec_Error; extern PyObject* PyXmlSec_InternalError; extern PyObject* PyXmlSec_VerificationError; void PyXmlSec_SetLastError(const char* msg); void PyXmlSec_SetLastError2(PyObject* type, const char* msg); void PyXmlSec_ClearError(void); void PyXmlSecEnableDebugTrace(int); void PyXmlSec_InstallErrorCallback(); #endif //__PYXMLSEC_EXCEPTIONS_H__ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/src/keys.c0000644000175100001710000007201714300243501014376 0ustar00runnerdocker// Copyright (c) 2017 Ryan Leckey // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "common.h" #include "constants.h" #include "exception.h" #include "keys.h" #include "utils.h" #include static PyObject* PyXmlSec_Key__new__(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyXmlSec_Key* key = (PyXmlSec_Key*)PyType_GenericNew(type, args, kwargs); PYXMLSEC_DEBUGF("%p: new key", key); if (key != NULL) { key->handle = NULL; key->is_own = 0; } return (PyObject*)(key); } static void PyXmlSec_Key__del__(PyObject* self) { PyXmlSec_Key* key = (PyXmlSec_Key*)self; PYXMLSEC_DEBUGF("%p: delete key", self); if (key->is_own) { PYXMLSEC_DEBUGF("%p: delete handle - %p", self, key->handle); xmlSecKeyDestroy(key->handle); } Py_TYPE(self)->tp_free(self); } static PyXmlSec_Key* PyXmlSec_NewKey1(PyTypeObject* type) { return (PyXmlSec_Key*)PyObject_CallFunctionObjArgs((PyObject*)type, NULL); } static PyObject* PyXmlSec_Key__copy__(PyObject* self) { xmlSecKeyPtr handle = ((PyXmlSec_Key*)self)->handle; PyXmlSec_Key* key2; PYXMLSEC_DEBUGF("%p: copy key", self); key2 = PyXmlSec_NewKey1(Py_TYPE(self)); if (handle == NULL || key2 == NULL) { PYXMLSEC_DEBUGF("%p: null key", self); return (PyObject*)key2; } Py_BEGIN_ALLOW_THREADS; key2->handle = xmlSecKeyDuplicate(handle); Py_END_ALLOW_THREADS; if (key2->handle == NULL) { PYXMLSEC_DEBUGF("%p: failed to duplicate key", self); PyXmlSec_SetLastError("cannot duplicate key"); Py_DECREF(key2); return NULL; } key2->is_own = 1; return (PyObject*)key2; } static const char PyXmlSec_KeyFromMemory__doc__[] = \ "from_memory(data, format, password = None) -> xmlsec.Key\n" "Loads PKI key from memory.\n\n" ":param data: the binary key data\n" ":type data: :class:`str` or :class:`bytes`\n" ":param format: the key file format\n" ":type format: :class:`int`\n" ":param password: the key file password (optional)\n" ":type password: :class:`str` or :data:`None`\n" ":return: pointer to newly created key\n" ":rtype: :class:`~xmlsec.Key`"; static PyObject* PyXmlSec_KeyFromMemory(PyObject* self, PyObject* args, PyObject* kwargs) { static char *kwlist[] = { "data", "format", "password", NULL}; const char* data = NULL; Py_ssize_t data_size = 0; const char* password = NULL; unsigned int format = 0; PyXmlSec_Key* key = NULL; PYXMLSEC_DEBUG("load key from memory - start"); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#I|z:from_memory", kwlist, &data, &data_size, &format, &password)) { goto ON_FAIL; } if ((key = PyXmlSec_NewKey1((PyTypeObject*)self)) == NULL) goto ON_FAIL; Py_BEGIN_ALLOW_THREADS; key->handle = xmlSecCryptoAppKeyLoadMemory((const xmlSecByte*)data, (xmlSecSize)data_size, format, password, NULL, NULL); Py_END_ALLOW_THREADS; if (key->handle == NULL) { PyXmlSec_SetLastError("cannot load key"); goto ON_FAIL; } key->is_own = 1; PYXMLSEC_DEBUG("load key from memory - ok"); return (PyObject*)key; ON_FAIL: PYXMLSEC_DEBUG("load key from memory - fail"); Py_XDECREF(key); return NULL; } static const char PyXmlSec_KeyFromFile__doc__[] = \ "from_file(file, format, password = None) -> xmlsec.Key\n" "Loads PKI key from a file.\n\n" ":param file: the file object or file path\n" ":type file: :class:`str`, :class:`bytes`, any :class:`~os.PathLike`, " ":class:`~typing.BinaryIO` or :class:`~typing.TextIO`\n" ":param format: the key file format\n" ":type format: :class:`int`\n" ":param password: the key file password (optional)\n" ":type password: :class:`str` or :data:`None`\n" ":return: pointer to newly created key\n" ":rtype: :class:`~xmlsec.Key`"; static PyObject* PyXmlSec_KeyFromFile(PyObject* self, PyObject* args, PyObject* kwargs) { static char *kwlist[] = { "file", "format", "password", NULL}; PyObject* file = NULL; const char* password = NULL; unsigned int format = 0; PyXmlSec_Key* key = NULL; PyObject* bytes = NULL; int is_content = 0; const char* data = NULL; Py_ssize_t data_size = 0; PYXMLSEC_DEBUG("load key from file - start"); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OI|z:from_file", kwlist, &file, &format, &password)) { goto ON_FAIL; } bytes = PyXmlSec_GetFilePathOrContent(file, &is_content); if (bytes == NULL) goto ON_FAIL; if (is_content == 1) { data = PyBytes_AsStringAndSize2(bytes, &data_size); } else { data = PyBytes_AsString(bytes); } if (data == NULL) goto ON_FAIL; if ((key = PyXmlSec_NewKey1((PyTypeObject*)self)) == NULL) goto ON_FAIL; Py_BEGIN_ALLOW_THREADS; if (is_content) { key->handle = xmlSecCryptoAppKeyLoadMemory((const xmlSecByte*)data, (xmlSecSize)data_size, format, password, NULL, NULL); } else { key->handle = xmlSecCryptoAppKeyLoad(data, format, password, NULL, NULL); } Py_END_ALLOW_THREADS; if (key->handle == NULL) { PyXmlSec_SetLastError("cannot read key"); goto ON_FAIL; } key->is_own = 1; Py_DECREF(bytes); PYXMLSEC_DEBUG("load key from file - ok"); return (PyObject*)key; ON_FAIL: PYXMLSEC_DEBUG("load key from file - fail"); Py_XDECREF(key); Py_XDECREF(bytes); return NULL; } static const char PyXmlSec_KeyGenerate__doc__[] = \ "generate(klass, size, type) -> xmlsec.Key\n" "Generates key of kind ``klass`` with ``size`` and ``type``.\n\n" ":param klass: the requested key klass (rsa, dsa, aes, ...)\n" ":type klass: :class:`__KeyData`\n" ":param size: the new key size (in bits!)\n" ":type size: :class:`int`\n" ":param type: the new key type (session, permanent, ...)\n" ":type type: :class:`int`\n" ":return: pointer to newly created key\n" ":rtype: :class:`~xmlsec.Key`"; static PyObject* PyXmlSec_KeyGenerate(PyObject* self, PyObject* args, PyObject* kwargs) { static char *kwlist[] = { "klass", "size", "type", NULL}; PyXmlSec_KeyData* keydata = NULL; short unsigned int keysize = 0; unsigned int keytype = 0; PyXmlSec_Key* key = NULL; PYXMLSEC_DEBUG("generate new key - start"); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!HI:generate", kwlist, PyXmlSec_KeyDataType, &keydata, &keysize, &keytype)) { goto ON_FAIL; } if ((key = PyXmlSec_NewKey1((PyTypeObject*)self)) == NULL) goto ON_FAIL; Py_BEGIN_ALLOW_THREADS; key->handle = xmlSecKeyGenerate(keydata->id, keysize, keytype); Py_END_ALLOW_THREADS; if (key->handle == NULL) { PyXmlSec_SetLastError("cannot generate key"); goto ON_FAIL; } key->is_own = 1; PYXMLSEC_DEBUG("generate new key - ok"); return (PyObject*)key; ON_FAIL: PYXMLSEC_DEBUG("generate new key - fail"); Py_XDECREF(key); return NULL; } static const char PyXmlSec_KeyFromBinaryFile__doc__[] = \ "from_binary_file(klass, filename) -> xmlsec.Key\n" "Loads (symmetric) key of kind ``klass`` from ``filename``.\n\n" ":param klass: the key value data klass\n" ":type klass: :class:`__KeyData`\n" ":param filename: the key binary filename\n" ":type filename: :class:`str`, :class:`bytes` or any :class:`~os.PathLike`\n" ":return: pointer to newly created key\n" ":rtype: :class:`~xmlsec.Key`"; static PyObject* PyXmlSec_KeyFromBinaryFile(PyObject* self, PyObject* args, PyObject* kwargs) { static char *kwlist[] = { "klass", "filename", NULL}; PyXmlSec_KeyData* keydata = NULL; PyObject* filepath = NULL; PyXmlSec_Key* key = NULL; const char* filename; PYXMLSEC_DEBUG("load symmetric key - start"); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!O&:from_binary_file", kwlist, PyXmlSec_KeyDataType, &keydata, PyUnicode_FSConverter, &filepath)) { goto ON_FAIL; } filename = PyBytes_AsString(filepath); if (filename == NULL) goto ON_FAIL; if ((key = PyXmlSec_NewKey1((PyTypeObject*)self)) == NULL) goto ON_FAIL; Py_BEGIN_ALLOW_THREADS; key->handle = xmlSecKeyReadBinaryFile(keydata->id, filename); Py_END_ALLOW_THREADS; if (key->handle == NULL) { PyXmlSec_SetLastError("cannot read key"); goto ON_FAIL; } key->is_own = 1; Py_DECREF(filepath); PYXMLSEC_DEBUG("load symmetric key - ok"); return (PyObject*)key; ON_FAIL: PYXMLSEC_DEBUG("load symmetric key - fail"); Py_XDECREF(key); Py_XDECREF(filepath); return NULL; } static const char PyXmlSec_KeyFromBinaryData__doc__[] = \ "from_binary_data(klass, data) -> xmlsec.Key\n" "Loads (symmetric) key of kind ``klass`` from ``data``.\n\n" ":param klass: the key value data klass\n" ":type klass: :class:`__KeyData`\n" ":param data: the key binary data\n" ":type data: :class:`str` or :class:`bytes`\n" ":return: pointer to newly created key\n" ":rtype: :class:`~xmlsec.Key`"; static PyObject* PyXmlSec_KeyFromBinaryData(PyObject* self, PyObject* args, PyObject* kwargs) { static char *kwlist[] = { "klass", "data", NULL}; PyXmlSec_KeyData* keydata = NULL; const char* data = NULL; Py_ssize_t data_size = 0; PyXmlSec_Key* key = NULL; PYXMLSEC_DEBUG("load symmetric key from memory - start"); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!s#:from_binary_data", kwlist, PyXmlSec_KeyDataType, &keydata, &data, &data_size)) { goto ON_FAIL; } if ((key = PyXmlSec_NewKey1((PyTypeObject*)self)) == NULL) goto ON_FAIL; Py_BEGIN_ALLOW_THREADS; key->handle = xmlSecKeyReadMemory(keydata->id, (const xmlSecByte*)data, (xmlSecSize)data_size); Py_END_ALLOW_THREADS; if (key->handle == NULL) { PyXmlSec_SetLastError("cannot read key"); goto ON_FAIL; } key->is_own = 1; PYXMLSEC_DEBUG("load symmetric key from memory - ok"); return (PyObject*)key; ON_FAIL: PYXMLSEC_DEBUG("load symmetric key from memory - fail"); Py_XDECREF(key); return NULL; } static const char PyXmlSec_KeyCertFromMemory__doc__[] = \ "load_cert_from_memory(data, format) -> None\n" "Loads certificate from memory.\n\n" ":param data: the certificate binary data\n" ":type data: :class:`str` or :class:`bytes`\n" ":param format: the certificate file format\n" ":type format: :class:`int`"; static PyObject* PyXmlSec_KeyCertFromMemory(PyObject* self, PyObject* args, PyObject* kwargs) { static char *kwlist[] = { "data", "format", NULL}; PyXmlSec_Key* key = (PyXmlSec_Key*)self; const char* data = NULL; Py_ssize_t data_size = 0; unsigned int format = 0; PyObject* tmp = NULL; int rv = 0; PYXMLSEC_DEBUGF("%p: load certificate from memory - start", self); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#I:load_cert_from_memory", kwlist, &data, &data_size, &format)) { goto ON_FAIL; } Py_BEGIN_ALLOW_THREADS; rv = xmlSecCryptoAppKeyCertLoadMemory(key->handle, (const xmlSecByte*)data, (xmlSecSize)data_size, format); Py_END_ALLOW_THREADS; if (rv < 0) { PyXmlSec_SetLastError("cannot load cert"); goto ON_FAIL; } Py_XDECREF(tmp); PYXMLSEC_DEBUGF("%p: load certificate from memory - ok", self); Py_RETURN_NONE; ON_FAIL: PYXMLSEC_DEBUGF("%p: load certificate from memory - fail", self); Py_XDECREF(tmp); return NULL; } static const char PyXmlSec_KeyCertFromFile__doc__[] = \ "load_cert_from_file(file, format) -> None\n" "Loads certificate from file.\n\n" ":param file: the file object or file path\n" ":type file: :class:`str`, :class:`bytes`, any :class:`~os.PathLike`, " ":class:`~typing.BinaryIO` or :class:`~typing.TextIO`\n" ":param format: the certificate file format\n" ":type format: :class:`int`"; static PyObject* PyXmlSec_KeyCertFromFile(PyObject* self, PyObject* args, PyObject* kwargs) { static char *kwlist[] = { "file", "format", NULL}; PyXmlSec_Key* key = (PyXmlSec_Key*)self; PyObject* file = NULL; unsigned int format = 0; PyObject* bytes = NULL; int is_content = 0; const char* data = NULL; Py_ssize_t data_size = 0; int rv = 0; PYXMLSEC_DEBUGF("%p: load certificate from memory - start", self); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OI:load_cert_from_file", kwlist, &file, &format)) { goto ON_FAIL; } bytes = PyXmlSec_GetFilePathOrContent(file, &is_content); if (bytes == NULL) goto ON_FAIL; if (is_content == 1) { data = PyBytes_AsStringAndSize2(bytes, &data_size); } else { data = PyBytes_AsString(bytes); } if (data == NULL) goto ON_FAIL; Py_BEGIN_ALLOW_THREADS; if (is_content) { rv = xmlSecCryptoAppKeyCertLoadMemory(key->handle, (const xmlSecByte*)data, (xmlSecSize)data_size, format); } else { rv = xmlSecCryptoAppKeyCertLoad(key->handle, data, format); } Py_END_ALLOW_THREADS; if (rv < 0) { PyXmlSec_SetLastError("cannot load cert"); goto ON_FAIL; } Py_DECREF(bytes); PYXMLSEC_DEBUGF("%p: load certificate from file - ok", self); Py_RETURN_NONE; ON_FAIL: PYXMLSEC_DEBUGF("%p: load certificate from file - fail", self); Py_XDECREF(bytes); return NULL; } static const char PyXmlSec_KeyName__doc__[] = "the name of this key.\n"; static PyObject* PyXmlSec_KeyNameGet(PyObject* self, void* closure) { PyXmlSec_Key* key = (PyXmlSec_Key*)self; const char* cname; PYXMLSEC_DEBUGF("%p: get name of key", self); if (key->handle == NULL) { PyErr_SetString(PyExc_ValueError, "key is not ready"); return NULL; } cname = (const char*)xmlSecKeyGetName(key->handle); if (cname != NULL) { return PyUnicode_FromString(cname); } Py_RETURN_NONE; } static int PyXmlSec_KeyNameSet(PyObject* self, PyObject* value, void* closure) { PyXmlSec_Key* key = (PyXmlSec_Key*)self; const char* name; PYXMLSEC_DEBUGF("%p: set name of key %p", self, value); if (key->handle == NULL) { PyErr_SetString(PyExc_ValueError, "key is not ready"); return -1; } if (value == NULL) { if (xmlSecKeySetName(key->handle, NULL) < 0) { PyXmlSec_SetLastError("cannot delete name"); return -1; } return 0; } name = PyUnicode_AsUTF8(value); if (name == NULL) return -1; if (xmlSecKeySetName(key->handle, XSTR(name)) < 0) { PyXmlSec_SetLastError("cannot set name"); return -1; } return 0; } static PyGetSetDef PyXmlSec_KeyGetSet[] = { { "name", (getter)PyXmlSec_KeyNameGet, (setter)PyXmlSec_KeyNameSet, (char*)PyXmlSec_KeyName__doc__, NULL }, {NULL} /* Sentinel */ }; static PyMethodDef PyXmlSec_KeyMethods[] = { { "from_memory", (PyCFunction)PyXmlSec_KeyFromMemory, METH_CLASS|METH_VARARGS|METH_KEYWORDS, PyXmlSec_KeyFromMemory__doc__, }, { "from_file", (PyCFunction)PyXmlSec_KeyFromFile, METH_CLASS|METH_VARARGS|METH_KEYWORDS, PyXmlSec_KeyFromFile__doc__ }, { "generate", (PyCFunction)PyXmlSec_KeyGenerate, METH_CLASS|METH_VARARGS|METH_KEYWORDS, PyXmlSec_KeyGenerate__doc__ }, { "from_binary_file", (PyCFunction)PyXmlSec_KeyFromBinaryFile, METH_CLASS|METH_VARARGS|METH_KEYWORDS, PyXmlSec_KeyFromBinaryFile__doc__ }, { "from_binary_data", (PyCFunction)PyXmlSec_KeyFromBinaryData, METH_CLASS|METH_VARARGS|METH_KEYWORDS, PyXmlSec_KeyFromBinaryData__doc__ }, { "load_cert_from_memory", (PyCFunction)PyXmlSec_KeyCertFromMemory, METH_VARARGS|METH_KEYWORDS, PyXmlSec_KeyCertFromMemory__doc__ }, { "load_cert_from_file", (PyCFunction)PyXmlSec_KeyCertFromFile, METH_VARARGS|METH_KEYWORDS, PyXmlSec_KeyCertFromFile__doc__ }, { "__copy__", (PyCFunction)PyXmlSec_Key__copy__, METH_NOARGS, "", }, { "__deepcopy__", (PyCFunction)PyXmlSec_Key__copy__, METH_NOARGS, "", }, {NULL, NULL} /* sentinel */ }; static PyTypeObject _PyXmlSec_KeyType = { PyVarObject_HEAD_INIT(NULL, 0) STRINGIFY(MODULE_NAME) ".Key", /* tp_name */ sizeof(PyXmlSec_Key), /* tp_basicsize */ 0, /* tp_itemsize */ PyXmlSec_Key__del__, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */ "Key", /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ PyXmlSec_KeyMethods, /* tp_methods */ 0, /* tp_members */ PyXmlSec_KeyGetSet, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ PyXmlSec_Key__new__, /* tp_new */ 0, /* tp_free */ }; PyTypeObject* PyXmlSec_KeyType = &_PyXmlSec_KeyType; // creates a new key object PyXmlSec_Key* PyXmlSec_NewKey(void) { return PyXmlSec_NewKey1(PyXmlSec_KeyType); } /// key manager class static PyObject* PyXmlSec_KeysManager__new__(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyXmlSec_KeysManager* mgr = (PyXmlSec_KeysManager*)PyType_GenericNew(type, args, kwargs); PYXMLSEC_DEBUGF("%p: new manager", mgr); if (mgr != NULL) { mgr->handle = NULL; } return (PyObject*)(mgr); } static int PyXmlSec_KeysManager__init__(PyObject* self, PyObject* args, PyObject* kwargs) { xmlSecKeysMngrPtr handle = xmlSecKeysMngrCreate(); PYXMLSEC_DEBUGF("%p: init key manager", self); if (handle == NULL) { PyXmlSec_SetLastError("failed to create xmlsecKeyManager"); return -1; } if (xmlSecCryptoAppDefaultKeysMngrInit(handle) < 0) { xmlSecKeysMngrDestroy(handle); PyXmlSec_SetLastError("failed to initialize xmlsecKeyManager"); return -1; } PYXMLSEC_DEBUGF("%p: init key manager - done: %p", self, handle); ((PyXmlSec_KeysManager*)self)->handle = handle; return 0; } static void PyXmlSec_KeysManager__del__(PyObject* self) { PyXmlSec_KeysManager* mgr = (PyXmlSec_KeysManager*)self; PYXMLSEC_DEBUGF("%p: delete KeysManager", self); if (mgr->handle != NULL) { PYXMLSEC_DEBUGF("%p: delete KeysManager handle - %p", self, mgr->handle); xmlSecKeysMngrDestroy(mgr->handle); } Py_TYPE(self)->tp_free(self); } static const char PyXmlSec_KeysManagerAddKey__doc__[] = \ "add_key(key: xmlsec.Key) -> None\n" "Adds a copy of ``key`` to keys manager\n\n" ":param key: the pointer to key\n" ":type key: :class:`~xmlsec.Key`"; static PyObject* PyXmlSec_KeysManagerAddKey(PyObject* self, PyObject* args, PyObject* kwargs) { static char *kwlist[] = { "key", NULL}; PyXmlSec_KeysManager* mgr = (PyXmlSec_KeysManager*)self; PyXmlSec_Key* key = NULL; xmlSecKeyPtr key2; int rv; PYXMLSEC_DEBUGF("%p(%p): add key - start", self, ((PyXmlSec_KeysManager*)self)->handle); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!:add_key", kwlist, PyXmlSec_KeyType, &key)) { goto ON_FAIL; } if (key->handle == NULL) { PyErr_SetString(PyExc_ValueError, "the provided key is invalid"); goto ON_FAIL; } Py_BEGIN_ALLOW_THREADS key2 = xmlSecKeyDuplicate(key->handle); Py_END_ALLOW_THREADS; if (key2 == NULL) { PyXmlSec_SetLastError("cannot make copy of key"); goto ON_FAIL; } Py_BEGIN_ALLOW_THREADS; rv = xmlSecCryptoAppDefaultKeysMngrAdoptKey(mgr->handle, key2); Py_END_ALLOW_THREADS; if (rv < 0) { PyXmlSec_SetLastError("cannot add key"); xmlSecKeyDestroy(key2); goto ON_FAIL; } PYXMLSEC_DEBUGF("%p: add key - ok", self); Py_RETURN_NONE; ON_FAIL: PYXMLSEC_DEBUGF("%p: add key - fail", self); return NULL; } static const char PyXmlSec_KeysManagerLoadCert__doc__[] = \ "load_cert(filename, format, type) -> None\n" "Loads certificate from ``filename``.\n\n" ":param filename: the certificate file\n" ":type filename: :class:`str`, :class:`bytes` or any :class:`~os.PathLike`\n" ":param format: the certificate file format\n" ":type format: :class:`int`\n" ":param type: the flag that indicates is the certificate in filename trusted or not\n" ":type type: :class:`int`"; static PyObject* PyXmlSec_KeysManagerLoadCert(PyObject* self, PyObject* args, PyObject* kwargs) { static char *kwlist[] = { "filename", "format", "type", NULL}; PyXmlSec_KeysManager* mgr = (PyXmlSec_KeysManager*)self; PyObject* filepath = NULL; unsigned int format = 0; unsigned int type = 0; const char* filename; int rv; PYXMLSEC_DEBUGF("%p: load cert - start", self); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&II:load_cert", kwlist, PyUnicode_FSConverter, &filepath, &format, &type)) { goto ON_FAIL; } filename = PyBytes_AsString(filepath); Py_BEGIN_ALLOW_THREADS; rv = xmlSecCryptoAppKeysMngrCertLoad(mgr->handle, filename, format, type); Py_END_ALLOW_THREADS; if (rv < 0) { PyXmlSec_SetLastError("cannot load cert"); goto ON_FAIL; } Py_DECREF(filepath); PYXMLSEC_DEBUGF("%p: load cert - ok", self); Py_RETURN_NONE; ON_FAIL: PYXMLSEC_DEBUGF("%p: load cert - fail", self); Py_XDECREF(filepath); return NULL; } static const char PyXmlSec_KeysManagerLoadCertFromMemory__doc__[] = \ "load_cert_from_memory(data, format, type) -> None\n" "Loads certificate from ``data``\n\n" ":param data: the certificate binary data\n" ":type data: :class:`str` or :class:`bytes`\n" ":param format: the certificate file format\n" ":type format: :class:`int`\n" ":param type: the flag that indicates is the certificate in filename trusted or not\n" ":type type: :class:`int`"; static PyObject* PyXmlSec_KeysManagerLoadCertFromMemory(PyObject* self, PyObject* args, PyObject* kwargs) { static char *kwlist[] = { "data", "format", "type", NULL}; PyXmlSec_KeysManager* mgr = (PyXmlSec_KeysManager*)self; const char* data = NULL; unsigned int type = 0; unsigned int format = 0; Py_ssize_t data_size = 0; int rv; PYXMLSEC_DEBUGF("%p: load cert from memory - start", self); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#II:load_cert", kwlist, &data, &data_size, &format, &type)) { goto ON_FAIL; } Py_BEGIN_ALLOW_THREADS; rv = xmlSecCryptoAppKeysMngrCertLoadMemory(mgr->handle, (const xmlSecByte*)data, (xmlSecSize)data_size, format, type); Py_END_ALLOW_THREADS; if (rv < 0) { PyXmlSec_SetLastError("cannot load cert from memory"); goto ON_FAIL; } PYXMLSEC_DEBUGF("%p: load cert from memory - ok", self); Py_RETURN_NONE; ON_FAIL: PYXMLSEC_DEBUGF("%p: load cert from memory - fail", self); return NULL; } static PyMethodDef PyXmlSec_KeysManagerMethods[] = { { "add_key", (PyCFunction)PyXmlSec_KeysManagerAddKey, METH_VARARGS|METH_KEYWORDS, PyXmlSec_KeysManagerAddKey__doc__ }, { "load_cert", (PyCFunction)PyXmlSec_KeysManagerLoadCert, METH_VARARGS|METH_KEYWORDS, PyXmlSec_KeysManagerLoadCert__doc__ }, { "load_cert_from_memory", (PyCFunction)PyXmlSec_KeysManagerLoadCertFromMemory, METH_VARARGS|METH_KEYWORDS, PyXmlSec_KeysManagerLoadCertFromMemory__doc__ }, {NULL, NULL} /* sentinel */ }; static PyTypeObject _PyXmlSec_KeysManagerType = { PyVarObject_HEAD_INIT(NULL, 0) STRINGIFY(MODULE_NAME) ".KeysManager", /* tp_name */ sizeof(PyXmlSec_KeysManager), /* tp_basicsize */ 0, /* tp_itemsize */ PyXmlSec_KeysManager__del__, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */ "Keys Manager", /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ PyXmlSec_KeysManagerMethods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ PyXmlSec_KeysManager__init__, /* tp_init */ 0, /* tp_alloc */ PyXmlSec_KeysManager__new__, /* tp_new */ 0, /* tp_free */ }; PyTypeObject* PyXmlSec_KeysManagerType = &_PyXmlSec_KeysManagerType; int PyXmlSec_KeysManagerConvert(PyObject* o, PyXmlSec_KeysManager** p) { if (o == Py_None) { *p = NULL; return 1; } if (!PyObject_IsInstance(o, (PyObject*)PyXmlSec_KeysManagerType)) { PyErr_SetString(PyExc_TypeError, "KeysManager required"); return 0; } *p = (PyXmlSec_KeysManager*)(o); Py_INCREF(o); return 1; } int PyXmlSec_KeyModule_Init(PyObject* package) { if (PyType_Ready(PyXmlSec_KeyType) < 0) goto ON_FAIL; if (PyType_Ready(PyXmlSec_KeysManagerType) < 0) goto ON_FAIL; // since objects is created as static objects, need to increase refcount to prevent deallocate Py_INCREF(PyXmlSec_KeyType); Py_INCREF(PyXmlSec_KeysManagerType); if (PyModule_AddObject(package, "Key", (PyObject*)PyXmlSec_KeyType) < 0) goto ON_FAIL; if (PyModule_AddObject(package, "KeysManager", (PyObject*)PyXmlSec_KeysManagerType) < 0) goto ON_FAIL; return 0; ON_FAIL: return -1; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/src/keys.h0000644000175100001710000000215614300243501014400 0ustar00runnerdocker// Copyright (c) 2017 Ryan Leckey // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #ifndef __PYXMLSEC_KEY_H__ #define __PYXMLSEC_KEY_H__ #include "platform.h" #include typedef struct { PyObject_HEAD xmlSecKeyPtr handle; int is_own; } PyXmlSec_Key; extern PyTypeObject* PyXmlSec_KeyType; PyXmlSec_Key* PyXmlSec_NewKey(void); typedef struct { PyObject_HEAD xmlSecKeysMngrPtr handle; } PyXmlSec_KeysManager; extern PyTypeObject* PyXmlSec_KeysManagerType; // converts object `o` to PyXmlSec_KeysManager, None will be converted to NULL, increments ref_count int PyXmlSec_KeysManagerConvert(PyObject* o, PyXmlSec_KeysManager** p); #endif //__PYXMLSEC_KEY_H__ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/src/lxml.c0000644000175100001710000000240414300243501014370 0ustar00runnerdocker// Copyright (c) 2017 Ryan Leckey // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "common.h" #include "lxml.h" #include #include #include #include #include int PyXmlSec_InitLxmlModule(void) { return import_lxml__etree(); } int PyXmlSec_IsElement(xmlNodePtr xnode) { return _isElement(xnode); } PyXmlSec_LxmlElementPtr PyXmlSec_elementFactory(PyXmlSec_LxmlDocumentPtr doc, xmlNodePtr xnode) { return elementFactory(doc, xnode); } int PyXmlSec_LxmlElementConverter(PyObject* o, PyXmlSec_LxmlElementPtr* p) { PyXmlSec_LxmlElementPtr node = rootNodeOrRaise(o); if (node == NULL) { return 0; } *p = node; // rootNodeOrRaise - increments ref-count, so need to compensate this. Py_DECREF(node); return 1; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/src/lxml.h0000644000175100001710000000225014300243501014374 0ustar00runnerdocker// Copyright (c) 2017 Ryan Leckey // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #ifndef __PYXMLSEC_LXML_H__ #define __PYXMLSEC_LXML_H__ #include "platform.h" #include #include #include #include typedef struct LxmlElement* PyXmlSec_LxmlElementPtr; typedef struct LxmlDocument* PyXmlSec_LxmlDocumentPtr; // checks that xnode is Element int PyXmlSec_IsElement(xmlNodePtr xnode); // creates a new element PyXmlSec_LxmlElementPtr PyXmlSec_elementFactory(PyXmlSec_LxmlDocumentPtr doc, xmlNodePtr node); // converts o to PyObject, None object is not allowed, does not increment ref_counts int PyXmlSec_LxmlElementConverter(PyObject* o, PyXmlSec_LxmlElementPtr* p); #endif // __PYXMLSEC_LXML_H__ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/src/main.c0000644000175100001710000004111014300243501014335 0ustar00runnerdocker// Copyright (c) 2017 Ryan Leckey // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "common.h" #include "platform.h" #include "exception.h" #include #include #include #include #include #define _PYXMLSEC_FREE_NONE 0 #define _PYXMLSEC_FREE_XMLSEC 1 #define _PYXMLSEC_FREE_CRYPTOLIB 2 #define _PYXMLSEC_FREE_ALL 3 static int free_mode = _PYXMLSEC_FREE_NONE; #define MODULE_DOC "The tiny python wrapper around xmlsec1 (" XMLSEC_VERSION ") library" #ifndef XMLSEC_NO_CRYPTO_DYNAMIC_LOADING static const xmlChar* PyXmlSec_GetCryptoLibName() { #if XMLSEC_VERSION_HEX > 0x10214 // xmlSecGetDefaultCrypto was introduced in version 1.2.21 const xmlChar* cryptoLib = xmlSecGetDefaultCrypto(); #else const xmlChar* cryptoLib = (const xmlChar*) XMLSEC_CRYPTO; #endif PYXMLSEC_DEBUGF("dynamic crypto library: %s", cryptoLib); return cryptoLib; } #endif // !XMLSEC_NO_CRYPTO_DYNAMIC_LOADING static void PyXmlSec_Free(int what) { PYXMLSEC_DEBUGF("free resources %d", what); switch (what) { case _PYXMLSEC_FREE_ALL: xmlSecCryptoAppShutdown(); case _PYXMLSEC_FREE_CRYPTOLIB: #ifndef XMLSEC_NO_CRYPTO_DYNAMIC_LOADING xmlSecCryptoDLUnloadLibrary(PyXmlSec_GetCryptoLibName()); #endif case _PYXMLSEC_FREE_XMLSEC: xmlSecShutdown(); } free_mode = _PYXMLSEC_FREE_NONE; } static int PyXmlSec_Init(void) { if (xmlSecInit() < 0) { PyXmlSec_SetLastError("cannot initialize xmlsec library."); PyXmlSec_Free(_PYXMLSEC_FREE_NONE); return -1; } if (xmlSecCheckVersion() != 1) { PyXmlSec_SetLastError("xmlsec library version mismatch."); PyXmlSec_Free(_PYXMLSEC_FREE_XMLSEC); return -1; } #ifndef XMLSEC_NO_CRYPTO_DYNAMIC_LOADING if (xmlSecCryptoDLLoadLibrary(PyXmlSec_GetCryptoLibName()) < 0) { PyXmlSec_SetLastError("cannot load crypto library for xmlsec."); PyXmlSec_Free(_PYXMLSEC_FREE_XMLSEC); return -1; } #endif /* XMLSEC_CRYPTO_DYNAMIC_LOADING */ /* Init crypto library */ if (xmlSecCryptoAppInit(NULL) < 0) { PyXmlSec_SetLastError("cannot initialize crypto library application."); PyXmlSec_Free(_PYXMLSEC_FREE_CRYPTOLIB); return -1; } /* Init xmlsec-crypto library */ if (xmlSecCryptoInit() < 0) { PyXmlSec_SetLastError("cannot initialize crypto library."); PyXmlSec_Free(_PYXMLSEC_FREE_ALL); return -1; } // xmlsec will install default callback in xmlSecCryptoInit, // overwriting any custom callbacks. // We thus reinstall our callback now. PyXmlSec_InstallErrorCallback(); free_mode = _PYXMLSEC_FREE_ALL; return 0; } static char PyXmlSec_PyInit__doc__[] = \ "init() -> None\n" "Initializes the library for general operation.\n\n" "This is called upon library import and does not need to be called\n" "again :func:`~.shutdown` is called explicitly).\n"; static PyObject* PyXmlSec_PyInit(PyObject *self) { if (PyXmlSec_Init() < 0) { return NULL; } Py_RETURN_NONE; } static char PyXmlSec_PyShutdown__doc__[] = \ "shutdown() -> None\n" "Shutdowns the library and cleanup any leftover resources.\n\n" "This is called automatically upon interpreter termination and\n" "should not need to be called explicitly."; static PyObject* PyXmlSec_PyShutdown(PyObject* self) { PyXmlSec_Free(free_mode); Py_RETURN_NONE; } static char PyXmlSec_PyEnableDebugOutput__doc__[] = \ "enable_debug_trace(enabled) -> None\n" "Enables or disables calling LibXML2 callback from the default errors callback.\n\n" ":param enabled: flag, debug trace is enabled or disabled\n" ":type enabled: :class:`bool`"; static PyObject* PyXmlSec_PyEnableDebugOutput(PyObject *self, PyObject* args, PyObject* kwargs) { static char *kwlist[] = { "enabled", NULL}; PyObject* enabled = Py_True; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O:enable_debug_trace", kwlist, &enabled)) { return NULL; } PyXmlSecEnableDebugTrace(PyObject_IsTrue(enabled)); Py_RETURN_NONE; } // NB: This whole thing assumes that the `xmlsec` callbacks are not re-entrant // (i.e. that xmlsec won't come across a link in the reference it's processing // and try to open that with these callbacks too). typedef struct CbList { PyObject* match_cb; PyObject* open_cb; PyObject* read_cb; PyObject* close_cb; struct CbList* next; } CbList; static CbList* registered_callbacks = NULL; static void RCBListCons(CbList* cb_list_item) { cb_list_item->next = registered_callbacks; registered_callbacks = cb_list_item; } static void RCBListClear() { CbList* cb_list_item = registered_callbacks; while (cb_list_item) { Py_DECREF(cb_list_item->match_cb); Py_DECREF(cb_list_item->open_cb); Py_DECREF(cb_list_item->read_cb); Py_DECREF(cb_list_item->close_cb); CbList* next = cb_list_item->next; free(cb_list_item); cb_list_item = next; } registered_callbacks = NULL; } // The currently executing set of Python callbacks: static CbList* cur_cb_list_item; static int PyXmlSec_MatchCB(const char* filename) { cur_cb_list_item = registered_callbacks; PyGILState_STATE state = PyGILState_Ensure(); PyObject* args = Py_BuildValue("(y)", filename); while (cur_cb_list_item) { PyObject* result = PyObject_CallObject(cur_cb_list_item->match_cb, args); if (result && PyObject_IsTrue(result)) { Py_DECREF(result); Py_DECREF(args); PyGILState_Release(state); return 1; } Py_XDECREF(result); cur_cb_list_item = cur_cb_list_item->next; } Py_DECREF(args); PyGILState_Release(state); return 0; } static void* PyXmlSec_OpenCB(const char* filename) { PyGILState_STATE state = PyGILState_Ensure(); // NB: Assumes the match callback left the current callback list item in the // right place: PyObject* args = Py_BuildValue("(y)", filename); PyObject* result = PyObject_CallObject(cur_cb_list_item->open_cb, args); Py_DECREF(args); PyGILState_Release(state); return result; } static int PyXmlSec_ReadCB(void* context, char* buffer, int len) { PyGILState_STATE state = PyGILState_Ensure(); // NB: Assumes the match callback left the current callback list item in the // right place: PyObject* py_buffer = PyMemoryView_FromMemory(buffer, (Py_ssize_t) len, PyBUF_WRITE); PyObject* args = Py_BuildValue("(OO)", context, py_buffer); PyObject* py_bytes_read = PyObject_CallObject(cur_cb_list_item->read_cb, args); Py_DECREF(args); Py_DECREF(py_buffer); int result; if (py_bytes_read && PyLong_Check(py_bytes_read)) { result = (int)PyLong_AsLong(py_bytes_read); } else { result = EOF; } Py_XDECREF(py_bytes_read); PyGILState_Release(state); return result; } static int PyXmlSec_CloseCB(void* context) { PyGILState_STATE state = PyGILState_Ensure(); PyObject* args = Py_BuildValue("(O)", context); PyObject* result = PyObject_CallObject(cur_cb_list_item->close_cb, args); Py_DECREF(args); Py_DECREF(context); Py_DECREF(result); PyGILState_Release(state); return 0; } static char PyXmlSec_PyIOCleanupCallbacks__doc__[] = \ "Unregister globally all sets of IO callbacks from xmlsec."; static PyObject* PyXmlSec_PyIOCleanupCallbacks(PyObject *self) { xmlSecIOCleanupCallbacks(); // We always have callbacks registered to delegate to any Python callbacks // we have registered within these bindings: if (xmlSecIORegisterCallbacks( PyXmlSec_MatchCB, PyXmlSec_OpenCB, PyXmlSec_ReadCB, PyXmlSec_CloseCB) < 0) { return NULL; } RCBListClear(); Py_RETURN_NONE; } static char PyXmlSec_PyIORegisterDefaultCallbacks__doc__[] = \ "Register globally xmlsec's own default set of IO callbacks."; static PyObject* PyXmlSec_PyIORegisterDefaultCallbacks(PyObject *self) { // NB: The default callbacks (specifically libxml2's `xmlFileMatch`) always // match, and callbacks are called in the reverse order to that which they // were added. So, there's no point in holding onto any previously registered // callbacks, because they will never be run: xmlSecIOCleanupCallbacks(); RCBListClear(); if (xmlSecIORegisterDefaultCallbacks() < 0) { return NULL; } // We need to make sure we can continue trying to match any newly added // Python callbacks: if (xmlSecIORegisterCallbacks( PyXmlSec_MatchCB, PyXmlSec_OpenCB, PyXmlSec_ReadCB, PyXmlSec_CloseCB) < 0) { return NULL; }; Py_RETURN_NONE; } static char PyXmlSec_PyIORegisterCallbacks__doc__[] = \ "Register globally a custom set of IO callbacks with xmlsec.\n\n" ":param callable input_match_callback: A callable that takes a filename `bytestring` and " "returns a boolean as to whether the other callbacks in this set can handle that name.\n" ":param callable input_open_callback: A callable that takes a filename and returns some " "context object (e.g. a file object) that the remaining callables in this set will be passed " "during handling.\n" // FIXME: How do we handle failures in ^^ (e.g. can't find the file)? ":param callable input_read_callback: A callable that that takes the context object from the " "open callback and a buffer, and should fill the buffer with data (e.g. BytesIO.readinto()). " "xmlsec will call this function several times until there is no more data returned.\n" ":param callable input_close_callback: A callable that takes the context object from the " "open callback and can do any resource cleanup necessary.\n" ; static PyObject* PyXmlSec_PyIORegisterCallbacks(PyObject *self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "input_match_callback", "input_open_callback", "input_read_callback", "input_close_callback", NULL }; CbList* cb_list_item = malloc(sizeof(CbList)); if (cb_list_item == NULL) { return NULL; } if (!PyArg_ParseTupleAndKeywords( args, kwargs, "OOOO:register_callbacks", kwlist, &cb_list_item->match_cb, &cb_list_item->open_cb, &cb_list_item->read_cb, &cb_list_item->close_cb)) { free(cb_list_item); return NULL; } if (!PyCallable_Check(cb_list_item->match_cb)) { PyErr_SetString(PyExc_TypeError, "input_match_callback must be a callable"); free(cb_list_item); return NULL; } if (!PyCallable_Check(cb_list_item->open_cb)) { PyErr_SetString(PyExc_TypeError, "input_open_callback must be a callable"); free(cb_list_item); return NULL; } if (!PyCallable_Check(cb_list_item->read_cb)) { PyErr_SetString(PyExc_TypeError, "input_read_callback must be a callable"); free(cb_list_item); return NULL; } if (!PyCallable_Check(cb_list_item->close_cb)) { PyErr_SetString(PyExc_TypeError, "input_close_callback must be a callable"); free(cb_list_item); return NULL; } Py_INCREF(cb_list_item->match_cb); Py_INCREF(cb_list_item->open_cb); Py_INCREF(cb_list_item->read_cb); Py_INCREF(cb_list_item->close_cb); cb_list_item->next = NULL; RCBListCons(cb_list_item); // NB: We don't need to register the callbacks with `xmlsec` here, because // we've already registered our helper functions that will trawl through our // list of callbacks. Py_RETURN_NONE; } static char PyXmlSec_PyBase64DefaultLineSize__doc__[] = \ "base64_default_line_size(size = None)\n" "Configures the default maximum columns size for base64 encoding.\n\n" "If ``size`` is not given, this function returns the current default size, acting as a getter. " "If ``size`` is given, a new value is applied and this function returns nothing, acting as a setter.\n" ":param size: new default size value (optional)\n" ":type size: :class:`int` or :data:`None`"; static PyObject* PyXmlSec_PyBase64DefaultLineSize(PyObject *self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "size", NULL }; PyObject *pySize = NULL; int size; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O:base64_default_line_size", kwlist, &pySize)) { return NULL; } if (pySize == NULL) { return PyLong_FromLong(xmlSecBase64GetDefaultLineSize()); } size = (int)PyLong_AsLong(pySize); if (PyErr_Occurred()) { return NULL; } if (size < 0) { PyErr_SetString(PyExc_ValueError, "size must be positive"); return NULL; } xmlSecBase64SetDefaultLineSize(size); Py_RETURN_NONE; } static PyMethodDef PyXmlSec_MainMethods[] = { { "init", (PyCFunction)PyXmlSec_PyInit, METH_NOARGS, PyXmlSec_PyInit__doc__ }, { "shutdown", (PyCFunction)PyXmlSec_PyShutdown, METH_NOARGS, PyXmlSec_PyShutdown__doc__ }, { "enable_debug_trace", (PyCFunction)PyXmlSec_PyEnableDebugOutput, METH_VARARGS|METH_KEYWORDS, PyXmlSec_PyEnableDebugOutput__doc__ }, { "cleanup_callbacks", (PyCFunction)PyXmlSec_PyIOCleanupCallbacks, METH_NOARGS, PyXmlSec_PyIOCleanupCallbacks__doc__ }, { "register_default_callbacks", (PyCFunction)PyXmlSec_PyIORegisterDefaultCallbacks, METH_NOARGS, PyXmlSec_PyIORegisterDefaultCallbacks__doc__ }, { "register_callbacks", (PyCFunction)PyXmlSec_PyIORegisterCallbacks, METH_VARARGS|METH_KEYWORDS, PyXmlSec_PyIORegisterCallbacks__doc__ }, { "base64_default_line_size", (PyCFunction)PyXmlSec_PyBase64DefaultLineSize, METH_VARARGS|METH_KEYWORDS, PyXmlSec_PyBase64DefaultLineSize__doc__ }, {NULL, NULL} /* sentinel */ }; // modules entry points // loads lxml module int PyXmlSec_InitLxmlModule(void); // constants int PyXmlSec_ConstantsModule_Init(PyObject* package); // exceptions int PyXmlSec_ExceptionsModule_Init(PyObject* package); // keys management int PyXmlSec_KeyModule_Init(PyObject* package); // init lxml.tree integration int PyXmlSec_TreeModule_Init(PyObject* package); // digital signature management int PyXmlSec_DSModule_Init(PyObject* package); // encryption management int PyXmlSec_EncModule_Init(PyObject* package); // templates management int PyXmlSec_TemplateModule_Init(PyObject* package); static int PyXmlSec_PyClear(PyObject *self) { PyXmlSec_Free(free_mode); return 0; } static PyModuleDef PyXmlSecModule = { PyModuleDef_HEAD_INIT, STRINGIFY(MODULE_NAME), /* name of module */ MODULE_DOC, /* module documentation, may be NULL */ -1, /* size of per-interpreter state of the module, or -1 if the module keeps state in global variables. */ PyXmlSec_MainMethods, /* m_methods */ NULL, /* m_slots */ NULL, /* m_traverse */ PyXmlSec_PyClear, /* m_clear */ NULL, /* m_free */ }; #define PYENTRY_FUNC_NAME JOIN(PyInit_, MODULE_NAME) #define PY_MOD_RETURN(m) return m PyMODINIT_FUNC PYENTRY_FUNC_NAME(void) { PyObject *module = NULL; module = PyModule_Create(&PyXmlSecModule); if (!module) { PY_MOD_RETURN(NULL); /* this really should never happen */ } PYXMLSEC_DEBUGF("%p", module); // init first, since PyXmlSec_Init may raise XmlSecError if (PyXmlSec_ExceptionsModule_Init(module) < 0) goto ON_FAIL; if (PyXmlSec_Init() < 0) goto ON_FAIL; if (PyModule_AddStringConstant(module, "__version__", STRINGIFY(MODULE_VERSION)) < 0) goto ON_FAIL; if (PyXmlSec_InitLxmlModule() < 0) goto ON_FAIL; /* Populate final object settings */ if (PyXmlSec_ConstantsModule_Init(module) < 0) goto ON_FAIL; if (PyXmlSec_KeyModule_Init(module) < 0) goto ON_FAIL; if (PyXmlSec_TreeModule_Init(module) < 0) goto ON_FAIL; if (PyXmlSec_DSModule_Init(module) < 0) goto ON_FAIL; if (PyXmlSec_EncModule_Init(module) < 0) goto ON_FAIL; if (PyXmlSec_TemplateModule_Init(module) < 0) goto ON_FAIL; PY_MOD_RETURN(module); ON_FAIL: PY_MOD_RETURN(NULL); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/src/platform.h0000644000175100001710000000264714300243501015256 0ustar00runnerdocker// Copyright (c) 2017 Ryan Leckey // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #ifndef __PYXMLSEC_PLATFORM_H__ #define __PYXMLSEC_PLATFORM_H__ #define PY_SSIZE_T_CLEAN 1 #include #include #ifdef MS_WIN32 #include #endif /* MS_WIN32 */ #define XMLSEC_VERSION_HEX ((XMLSEC_VERSION_MAJOR << 16) | (XMLSEC_VERSION_MINOR << 8) | (XMLSEC_VERSION_SUBMINOR)) // XKMS support was removed in version 1.2.21 // https://mail.gnome.org/archives/commits-list/2015-February/msg10555.html #if XMLSEC_VERSION_HEX > 0x10214 #define XMLSEC_NO_XKMS 1 #endif #define XSTR(c) (const xmlChar*)(c) #if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN) typedef int Py_ssize_t; #define PY_SSIZE_T_MAX INT_MAX #define PY_SSIZE_T_MIN INT_MIN #endif static inline char* PyBytes_AsStringAndSize2(PyObject *obj, Py_ssize_t* length) { char* buffer = NULL; return ((PyBytes_AsStringAndSize(obj, &buffer, length) < 0) ? (char*)(0) : buffer); } #endif //__PYXMLSEC_PLATFORM_H__ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/src/template.c0000644000175100001710000010735114300243501015236 0ustar00runnerdocker// Copyright (c) 2017 Ryan Leckey // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "common.h" #include "platform.h" #include "exception.h" #include "constants.h" #include "lxml.h" #include #define PYXMLSEC_TEMPLATES_DOC "Xml Templates processing" static char PyXmlSec_TemplateCreate__doc__[] = \ "create(node, c14n_method, sign_method, id = None, ns = None) -> lxml.etree._Element\n" "Creates new :xml:`` node with the mandatory :xml:``, :xml:``, " ":xml:`` and :xml:`` children and sub-children.\n\n" ":param node: the signature node\n" ":type node: :class:`lxml.etree._Element`\n" ":param c14n_method: the signature canonicalization method\n" ":type c14n_method: :class:`__Transform`\n" ":param sign_method: the signature method\n" ":type sign_method: :class:`__Transform`\n" ":param id: the node id (optional)\n" ":type id: :class:`str` or :data:`None`\n" ":param ns: the namespace prefix for the signature element (e.g. ``\"dsig\"``) (optional)\n" ":type ns: :class:`str` or :data:`None`\n" ":return: the pointer to newly created :xml:`` node\n" ":rtype: :class:`lxml.etree._Element`"; static PyObject* PyXmlSec_TemplateCreate(PyObject* self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "node", "c14n_method", "sign_method", "id", "ns", "name", NULL}; PyXmlSec_LxmlElementPtr node = NULL; PyXmlSec_Transform* c14n = NULL; PyXmlSec_Transform* sign = NULL; const char* id = NULL; const char* ns = NULL; xmlNodePtr res; PYXMLSEC_DEBUG("template create - start"); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O!O!|zzz:create", kwlist, PyXmlSec_LxmlElementConverter, &node, PyXmlSec_TransformType, &c14n, PyXmlSec_TransformType, &sign, &id, &ns, &id)) { goto ON_FAIL; } Py_BEGIN_ALLOW_THREADS; res = xmlSecTmplSignatureCreateNsPref(node->_doc->_c_doc, c14n->id, sign->id, XSTR(id), XSTR(ns)); Py_END_ALLOW_THREADS; if (res == NULL) { PyXmlSec_SetLastError("cannot create template."); goto ON_FAIL; } PYXMLSEC_DEBUG("template create - ok"); return (PyObject*)PyXmlSec_elementFactory(node->_doc, res); ON_FAIL: PYXMLSEC_DEBUG("template create - fail"); return NULL; } static char PyXmlSec_TemplateAddReference__doc__[] = \ "add_reference(node, digest_method, id = None, uri = None, type = None) -> lxml.etree._Element\n" "Adds :xml:`` node with given ``\"URI\"`` (``uri``), ``\"Id\"`` (``id``) and ``\"Type\"`` (``type``) attributes and " "the required children :xml:`` and :xml:`` to the :xml:`` child of ``node``.\n\n" ":param node: the pointer to :xml:`` node\n" ":type node: :class:`lxml.etree._Element`\n" ":param digest_method: the reference digest method\n" ":type digest_method: :class:`__Transform`\n" ":param id: the node id (optional)\n" ":type id: :class:`str` or :data:`None`\n" ":param uri: the reference node URI (optional)\n" ":type uri: :class:`str` or :data:`None`\n" ":param type: the reference node type (optional)\n" ":type type: :class:`str` or :data:`None`\n" ":return: the pointer to newly created :xml:`` node\n" ":rtype: :class:`lxml.etree._Element`"; static PyObject* PyXmlSec_TemplateAddReference(PyObject* self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "node", "digest_method", "id", "uri", "type", NULL}; PyXmlSec_LxmlElementPtr node = NULL; PyXmlSec_Transform* digest = NULL; const char* id = NULL; const char* uri = NULL; const char* type = NULL; xmlNodePtr res; PYXMLSEC_DEBUG("template add_reference - start"); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O!|zzz:add_reference", kwlist, PyXmlSec_LxmlElementConverter, &node, PyXmlSec_TransformType, &digest, &id, &uri, &type)) { goto ON_FAIL; } Py_BEGIN_ALLOW_THREADS; res = xmlSecTmplSignatureAddReference(node->_c_node, digest->id, XSTR(id), XSTR(uri), XSTR(type)); Py_END_ALLOW_THREADS; if (res == NULL) { PyXmlSec_SetLastError("cannot add reference."); goto ON_FAIL; } PYXMLSEC_DEBUG("template add_reference - ok"); return (PyObject*)PyXmlSec_elementFactory(node->_doc, res); ON_FAIL: PYXMLSEC_DEBUG("template add_reference - fail"); return NULL; } static char PyXmlSec_TemplateAddTransform__doc__[] = \ "add_transform(node) -> lxml.etree._Element\n" "Adds :xml:`` node to the :xml:`` node of ``node``.\n\n" ":param node: the pointer to :xml:`` node\n" ":type node: :class:`lxml.etree._Element`\n" ":param transform: the transform method id\n" ":type transform: :class:`__Transform`\n" ":return: the pointer to newly created :xml:`` node\n" ":rtype: :class:`lxml.etree._Element`"; static PyObject* PyXmlSec_TemplateAddTransform(PyObject* self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "node", "transform", NULL}; PyXmlSec_LxmlElementPtr node = NULL; PyXmlSec_Transform* transform = NULL; xmlNodePtr res; PYXMLSEC_DEBUG("template add_transform - start"); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O!:add_transform", kwlist, PyXmlSec_LxmlElementConverter, &node, PyXmlSec_TransformType, &transform)) { goto ON_FAIL; } Py_BEGIN_ALLOW_THREADS; res = xmlSecTmplReferenceAddTransform(node->_c_node, transform->id); Py_END_ALLOW_THREADS; if (res == NULL) { PyXmlSec_SetLastError("cannot add transform."); goto ON_FAIL; } PYXMLSEC_DEBUG("template add_transform - ok"); return (PyObject*)PyXmlSec_elementFactory(node->_doc, res); ON_FAIL: PYXMLSEC_DEBUG("template add_transform - fail"); return NULL; } static char PyXmlSec_TemplateEnsureKeyInfo__doc__[] = \ "ensure_key_info(node, id = None) -> lxml.etree._Element\n" "Adds (if necessary) :xml:`` node to the :xml:`` node of ``node``.\n\n" ":param node: the pointer to :xml:`` node\n" ":type node: :class:`lxml.etree._Element`\n" ":param id: the node id (optional)\n" ":type id: :class:`str` or :data:`None`\n" ":return: the pointer to newly created :xml:`` node\n" ":rtype: :class:`lxml.etree._Element`"; static PyObject* PyXmlSec_TemplateEnsureKeyInfo(PyObject* self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "node", "id", NULL}; PyXmlSec_LxmlElementPtr node = NULL; const char* id = NULL; xmlNodePtr res; PYXMLSEC_DEBUG("template ensure_key_info - start"); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|z:ensure_key_info", kwlist, PyXmlSec_LxmlElementConverter, &node, &id)) { goto ON_FAIL; } Py_BEGIN_ALLOW_THREADS; res = xmlSecTmplSignatureEnsureKeyInfo(node->_c_node, XSTR(id)); Py_END_ALLOW_THREADS; if (res == NULL) { PyXmlSec_SetLastError("cannot ensure key info."); goto ON_FAIL; } PYXMLSEC_DEBUG("template ensure_key_info - ok"); return (PyObject*)PyXmlSec_elementFactory(node->_doc, res); ON_FAIL: PYXMLSEC_DEBUG("template ensure_key_info - fail"); return NULL; } static char PyXmlSec_TemplateAddKeyName__doc__[] = \ "add_key_name(node, name = None) -> lxml.etree._Element\n" "Adds :xml:`` node to the :xml:`` node of ``node``.\n\n" ":param node: the pointer to :xml:`` node\n" ":type node: :class:`lxml.etree._Element`\n" ":param name: the key name (optional)\n" ":type name: :class:`str` or :data:`None`\n" ":return: the pointer to the newly created :xml:`` node\n" ":rtype: :class:`lxml.etree._Element`"; static PyObject* PyXmlSec_TemplateAddKeyName(PyObject* self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "node", "name", NULL}; PyXmlSec_LxmlElementPtr node = NULL; const char* name = NULL; xmlNodePtr res; PYXMLSEC_DEBUG("template add_key_name - start"); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|z:add_key_name", kwlist, PyXmlSec_LxmlElementConverter, &node, &name)) { goto ON_FAIL; } Py_BEGIN_ALLOW_THREADS; res = xmlSecTmplKeyInfoAddKeyName(node->_c_node, XSTR(name)); Py_END_ALLOW_THREADS; if (res == NULL) { PyXmlSec_SetLastError("cannot add key name."); goto ON_FAIL; } PYXMLSEC_DEBUG("template add_key_name - ok"); return (PyObject*)PyXmlSec_elementFactory(node->_doc, res); ON_FAIL: PYXMLSEC_DEBUG("template add_key_name - fail"); return NULL; } static char PyXmlSec_TemplateAddKeyValue__doc__[] = \ "add_key_value(node) -> lxml.etree._Element\n" "Adds :xml:`` node to the :xml:`` node of ``node``.\n\n" ":param node: the pointer to :xml:`` node\n" ":type node: :class:`lxml.etree._Element`\n" ":return: the pointer to the newly created :xml:`` node\n" ":rtype: :class:`lxml.etree._Element`"; static PyObject* PyXmlSec_TemplateAddKeyValue(PyObject* self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "node", NULL}; PyXmlSec_LxmlElementPtr node = NULL; xmlNodePtr res; PYXMLSEC_DEBUG("template add_key_value - start"); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:add_key_value", kwlist, PyXmlSec_LxmlElementConverter, &node)) { goto ON_FAIL; } Py_BEGIN_ALLOW_THREADS; res = xmlSecTmplKeyInfoAddKeyValue(node->_c_node); Py_END_ALLOW_THREADS; if (res == NULL) { PyXmlSec_SetLastError("cannot add key value."); goto ON_FAIL; } PYXMLSEC_DEBUG("template add_key_name - ok"); return (PyObject*)PyXmlSec_elementFactory(node->_doc, res); ON_FAIL: PYXMLSEC_DEBUG("template add_key_name - fail"); return NULL; } static char PyXmlSec_TemplateAddX509Data__doc__[] = \ "add_x509_data(node) -> lxml.etree._Element\n" "Adds :xml:`` node to the :xml:`` node of ``node``.\n\n" ":param node: the pointer to :xml:`` node\n" ":type node: :class:`lxml.etree._Element`\n" ":return: the pointer to the newly created :xml:`` node\n" ":rtype: :class:`lxml.etree._Element`\n"; static PyObject* PyXmlSec_TemplateAddX509Data(PyObject* self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "node", NULL}; PyXmlSec_LxmlElementPtr node = NULL; xmlNodePtr res; PYXMLSEC_DEBUG("template add_x509_data - start"); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:add_x509_data", kwlist, PyXmlSec_LxmlElementConverter, &node)) { goto ON_FAIL; } Py_BEGIN_ALLOW_THREADS; res = xmlSecTmplKeyInfoAddX509Data(node->_c_node); Py_END_ALLOW_THREADS; if (res == NULL) { PyXmlSec_SetLastError("cannot add x509 data."); goto ON_FAIL; } PYXMLSEC_DEBUG("template add_x509_data - ok"); return (PyObject*)PyXmlSec_elementFactory(node->_doc, res); ON_FAIL: PYXMLSEC_DEBUG("template add_x509_data - fail"); return NULL; } static char PyXmlSec_TemplateAddX509DataAddIssuerSerial__doc__[] = \ "x509_data_add_issuer_serial(node) -> lxml.etree._Element\n" "Adds :xml:`` node to the given :xml:`` node of ``node``.\n\n" ":param node: the pointer to :xml:`` node\n" ":type node: :class:`lxml.etree._Element`\n" ":return: the pointer to the newly created :xml:`` node\n" ":rtype: :class:`lxml.etree._Element`"; static PyObject* PyXmlSec_TemplateAddX509DataAddIssuerSerial(PyObject* self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "node", NULL}; PyXmlSec_LxmlElementPtr node = NULL; xmlNodePtr res; PYXMLSEC_DEBUG("template x509_data_add_issuer_serial - start"); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:x509_data_add_issuer_serial", kwlist, PyXmlSec_LxmlElementConverter, &node)) { goto ON_FAIL; } Py_BEGIN_ALLOW_THREADS; res = xmlSecTmplX509DataAddIssuerSerial(node->_c_node); Py_END_ALLOW_THREADS; if (res == NULL) { PyXmlSec_SetLastError("cannot add x509 issuer serial."); goto ON_FAIL; } PYXMLSEC_DEBUG("template x509_data_add_issuer_serial - ok"); return (PyObject*)PyXmlSec_elementFactory(node->_doc, res); ON_FAIL: PYXMLSEC_DEBUG("template x509_data_add_issuer_serial - fail"); return NULL; } static char PyXmlSec_TemplateAddX509DataIssuerSerialAddIssuerName__doc__[] = \ "x509_issuer_serial_add_issuer_name(node, name = None) -> lxml.etree._Element\n" "Adds :xml:`` node to the :xml:`` node of ``node``.\n\n" ":param node: the pointer to :xml:`` node\n" ":type node: :class:`lxml.etree._Element`\n" ":param name: the issuer name (optional)\n" ":type name: :class:`str` or :data:`None`\n" ":return: the pointer to the newly created :xml:`` node\n" ":rtype: :class:`lxml.etree._Element`"; static PyObject* PyXmlSec_TemplateAddX509DataIssuerSerialAddIssuerName(PyObject* self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "node", "name", NULL}; PyXmlSec_LxmlElementPtr node = NULL; const char* name = NULL; xmlNodePtr res; PYXMLSEC_DEBUG("template x509_issuer_serial_add_issuer_name - start"); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|z:x509_issuer_serial_add_issuer_name", kwlist, PyXmlSec_LxmlElementConverter, &node, &name)) { goto ON_FAIL; } Py_BEGIN_ALLOW_THREADS; res = xmlSecTmplX509IssuerSerialAddIssuerName(node->_c_node, XSTR(name)); Py_END_ALLOW_THREADS; if (res == NULL) { PyXmlSec_SetLastError("cannot add x509 issuer serial name."); goto ON_FAIL; } PYXMLSEC_DEBUG("template x509_issuer_serial_add_issuer_name - ok"); return (PyObject*)PyXmlSec_elementFactory(node->_doc, res); ON_FAIL: PYXMLSEC_DEBUG("template x509_issuer_serial_add_issuer_name - fail"); return NULL; } static char PyXmlSec_TemplateAddX509DataIssuerSerialAddIssuerSerialNumber__doc__[] = \ "x509_issuer_serial_add_serial_number(node, serial = None) -> lxml.etree._Element\n" "Adds :xml:`` node to the :xml:`` node of ``node``.\n\n" ":param node: the pointer to :xml:`` node\n" ":type node: :class:`lxml.etree._Element`\n" ":param serial: the serial number (optional)\n" ":type serial: :class:`str` or :data:`None`\n" ":return: the pointer to the newly created :xml:`` node\n" ":rtype: :class:`lxml.etree._Element`"; static PyObject* PyXmlSec_TemplateAddX509DataIssuerSerialAddIssuerSerialNumber(PyObject* self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "node", "serial", NULL}; PyXmlSec_LxmlElementPtr node = NULL; const char* serial = NULL; xmlNodePtr res; PYXMLSEC_DEBUG("template x509_issuer_serial_add_serial_number - start"); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|z:x509_issuer_serial_add_serial_number", kwlist, PyXmlSec_LxmlElementConverter, &node, &serial)) { goto ON_FAIL; } Py_BEGIN_ALLOW_THREADS; res = xmlSecTmplX509IssuerSerialAddSerialNumber(node->_c_node, XSTR(serial)); Py_END_ALLOW_THREADS; if (res == NULL) { PyXmlSec_SetLastError("cannot add x509 issuer serial number."); goto ON_FAIL; } PYXMLSEC_DEBUG("template x509_issuer_serial_add_serial_number - ok"); return (PyObject*)PyXmlSec_elementFactory(node->_doc, res); ON_FAIL: PYXMLSEC_DEBUG("template x509_issuer_serial_add_serial_number - fail"); return NULL; } static char PyXmlSec_TemplateAddX509DataAddSubjectName__doc__[] = \ "x509_data_add_subject_name(node) -> lxml.etree._Element\n" "Adds :xml:`` node to the given :xml:`` node of ``node``.\n\n" ":param node: the pointer to :xml:`` node\n" ":type node: :class:`lxml.etree._Element`\n" ":return: the pointer to the newly created :xml:`` node\n" ":rtype: :class:`lxml.etree._Element`"; static PyObject* PyXmlSec_TemplateAddX509DataAddSubjectName(PyObject* self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "node", NULL}; PyXmlSec_LxmlElementPtr node = NULL; xmlNodePtr res; PYXMLSEC_DEBUG("template x509_data_add_subject_name - start"); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:x509_data_add_subject_name", kwlist, PyXmlSec_LxmlElementConverter, &node)) { goto ON_FAIL; } Py_BEGIN_ALLOW_THREADS; res = xmlSecTmplX509DataAddSubjectName(node->_c_node); Py_END_ALLOW_THREADS; if (res == NULL) { PyXmlSec_SetLastError("cannot add x509 subject name."); goto ON_FAIL; } PYXMLSEC_DEBUG("template x509_data_add_subject_name - ok"); return (PyObject*)PyXmlSec_elementFactory(node->_doc, res); ON_FAIL: PYXMLSEC_DEBUG("template x509_data_add_subject_name - fail"); return NULL; } static char PyXmlSec_TemplateAddX509DataAddSKI__doc__[] = \ "x509_data_add_ski(node) -> lxml.etree._Element\n" "Adds :xml:`` node to the given :xml:`` node of ``node``.\n\n" ":param node: the pointer to :xml:`` node\n" ":type node: :class:`lxml.etree._Element`\n" ":return: the pointer to the newly created :xml:`` node\n" ":rtype: :class:`lxml.etree._Element`"; static PyObject* PyXmlSec_TemplateAddX509DataAddSKI(PyObject* self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "node", NULL}; PyXmlSec_LxmlElementPtr node = NULL; xmlNodePtr res; PYXMLSEC_DEBUG("template x509_data_add_ski - start"); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:x509_data_add_ski", kwlist, PyXmlSec_LxmlElementConverter, &node)) { goto ON_FAIL; } Py_BEGIN_ALLOW_THREADS; res = xmlSecTmplX509DataAddSKI(node->_c_node); Py_END_ALLOW_THREADS; if (res == NULL) { PyXmlSec_SetLastError("cannot add x509 SKI."); goto ON_FAIL; } PYXMLSEC_DEBUG("template x509_data_add_ski - ok"); return (PyObject*)PyXmlSec_elementFactory(node->_doc, res); ON_FAIL: PYXMLSEC_DEBUG("template x509_data_add_ski - fail"); return NULL; } static char PyXmlSec_TemplateAddX509DataAddCertificate__doc__[] = \ "x509_data_add_certificate(node) -> lxml.etree._Element\n" "Adds :xml:`` node to the given :xml:`` node of ``node``.\n\n" ":param node: the pointer to :xml:`` node\n" ":type node: :class:`lxml.etree._Element`\n" ":return: the pointer to the newly created :xml:`` node\n" ":rtype: :class:`lxml.etree._Element`"; static PyObject* PyXmlSec_TemplateAddX509DataAddCertificate(PyObject* self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "node", NULL}; PyXmlSec_LxmlElementPtr node = NULL; xmlNodePtr res; PYXMLSEC_DEBUG("template x509_data_add_certificate - start"); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:x509_data_add_certificate", kwlist, PyXmlSec_LxmlElementConverter, &node)) { goto ON_FAIL; } Py_BEGIN_ALLOW_THREADS; res = xmlSecTmplX509DataAddCertificate(node->_c_node); Py_END_ALLOW_THREADS; if (res == NULL) { PyXmlSec_SetLastError("cannot add x509 certificate."); goto ON_FAIL; } PYXMLSEC_DEBUG("template x509_data_add_certificate - ok"); return (PyObject*)PyXmlSec_elementFactory(node->_doc, res); ON_FAIL: PYXMLSEC_DEBUG("template x509_data_add_certificate - fail"); return NULL; } static char PyXmlSec_TemplateAddX509DataAddCRL__doc__[] = \ "x509_data_add_crl(node) -> lxml.etree._Element\n" "Adds :xml:`` node to the given :xml:`` node of ``node``.\n\n" ":param node: the pointer to :xml:`` node\n" ":type node: :class:`lxml.etree._Element`\n" ":return: the pointer to the newly created :xml:`` node\n" ":rtype: :class:`lxml.etree._Element`"; static PyObject* PyXmlSec_TemplateAddX509DataAddCRL(PyObject* self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "node", NULL}; PyXmlSec_LxmlElementPtr node = NULL; xmlNodePtr res; PYXMLSEC_DEBUG("template x509_data_add_crl - start"); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:x509_data_add_crl", kwlist, PyXmlSec_LxmlElementConverter, &node)) { goto ON_FAIL; } Py_BEGIN_ALLOW_THREADS; res = xmlSecTmplX509DataAddCRL(node->_c_node); Py_END_ALLOW_THREADS; if (res == NULL) { PyXmlSec_SetLastError("cannot add x509 CRL."); goto ON_FAIL; } PYXMLSEC_DEBUG("template x509_data_add_crl - ok"); return (PyObject*)PyXmlSec_elementFactory(node->_doc, res); ON_FAIL: PYXMLSEC_DEBUG("template x509_data_add_crl - fail"); return NULL; } static char PyXmlSec_TemplateAddEncryptedKey__doc__[] = \ "add_encrypted_key(node, method, id = None, type = None, recipient = None) -> lxml.etree._Element\n" "Adds :xml:`` node with given attributes to the :xml:`` node of *node*.\n\n" ":param node: the pointer to :xml:`` node\n" ":type node: :class:`lxml.etree._Element`\n" ":param method: the encryption method\n" ":type method: :class:`__Transform`\n" ":param id: the ``\"Id\"`` attribute (optional)\n" ":type id: :class:`str` or :data:`None`\n" ":param type: the ``\"Type\"`` attribute (optional)\n" ":type type: :class:`str` or :data:`None`\n" ":param recipient: the ``\"Recipient\"`` attribute (optional)\n" ":type recipient: :class:`str` or :data:`None`\n" ":return: the pointer to the newly created :xml:`` node\n" ":rtype: :class:`lxml.etree._Element`"; static PyObject* PyXmlSec_TemplateAddEncryptedKey(PyObject* self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "node", "method", "id", "type", "recipient", NULL}; PyXmlSec_LxmlElementPtr node = NULL; PyXmlSec_Transform* method = NULL; const char* id = NULL; const char* type = NULL; const char* recipient = NULL; xmlNodePtr res; PYXMLSEC_DEBUG("template add_encrypted_key - start"); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O!|zzz:add_encrypted_key", kwlist, PyXmlSec_LxmlElementConverter, &node, PyXmlSec_TransformType, &method, &id, &type, &recipient)) { goto ON_FAIL; } Py_BEGIN_ALLOW_THREADS; res = xmlSecTmplKeyInfoAddEncryptedKey(node->_c_node, method->id, XSTR(id), XSTR(type), XSTR(recipient)); Py_END_ALLOW_THREADS; if (res == NULL) { PyXmlSec_SetLastError("cannot add encrypted key."); goto ON_FAIL; } PYXMLSEC_DEBUG("template add_encrypted_key - ok"); return (PyObject*)PyXmlSec_elementFactory(node->_doc, res); ON_FAIL: PYXMLSEC_DEBUG("template add_encrypted_key - fail"); return NULL; } static char PyXmlSec_TemplateCreateEncryptedData__doc__[] = \ "encrypted_data_create(node, method, id = None, type = None, mime_type = None, encoding = None, ns = None) -> lxml.etree._Element\n" "Creates new :xml:`<{ns}:EncryptedData />` node for encryption template.\n\n" ":param node: the pointer to signature node\n" ":type node: :class:`lxml.etree._Element`\n" ":param method: the encryption method\n" ":type method: :class:`__Transform`\n" ":param id: the ``\"Id\"`` attribute (optional)\n" ":type id: :class:`str` or :data:`None`\n" ":param type: the ``\"Type\"`` attribute (optional)\n" ":type type: :class:`str` or :data:`None`\n" ":param mime_type: the ``\"Recipient\"`` attribute (optional)\n" ":type mime_type: :class:`str` or :data:`None`\n" ":param encoding: the ``\"MimeType\"`` attribute (optional)\n" ":type encoding: :class:`str` or :data:`None`\n" ":param ns: the namespace prefix (optional)\n" ":type ns: :class:`str` or :data:`None`\n" ":return: the pointer newly created :xml:`` node\n" ":rtype: :class:`lxml.etree._Element`"; static PyObject* PyXmlSec_TemplateCreateEncryptedData(PyObject* self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "node", "method", "id", "type", "mime_type", "encoding", "ns", NULL}; PyXmlSec_LxmlElementPtr node = NULL; PyXmlSec_Transform* method = NULL; const char* id = NULL; const char* type = NULL; const char* mime_type = NULL; const char* encoding = NULL; const char* ns = NULL; xmlNodePtr res; PYXMLSEC_DEBUG("template encrypted_data_create - start"); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O!|zzzzz:encrypted_data_create", kwlist, PyXmlSec_LxmlElementConverter, &node, PyXmlSec_TransformType, &method, &id, &type, &mime_type, &encoding, &ns)) { goto ON_FAIL; } Py_BEGIN_ALLOW_THREADS; res = xmlSecTmplEncDataCreate(node->_doc->_c_doc, method->id, XSTR(id), XSTR(type), XSTR(mime_type), XSTR(encoding)); Py_END_ALLOW_THREADS; if (res == NULL) { PyXmlSec_SetLastError("cannot create encrypted data."); goto ON_FAIL; } if (ns != NULL) { res->ns->prefix = xmlStrdup(XSTR(ns)); } PYXMLSEC_DEBUG("template encrypted_data_create - ok"); return (PyObject*)PyXmlSec_elementFactory(node->_doc, res); ON_FAIL: PYXMLSEC_DEBUG("template encrypted_data_create - fail"); return NULL; } static char PyXmlSec_TemplateEncryptedDataEnsureKeyInfo__doc__[] = \ "encrypted_data_ensure_key_info(node, id = None, ns = None) -> lxml.etree._Element\n" "Adds :xml:`<{ns}:KeyInfo/>` to the :xml:`` node of ``node``.\n\n" ":param node: the pointer to :xml:`` node\n" ":type node: :class:`lxml.etree._Element`\n" ":param id: the ``\"Id\"`` attribute (optional)\n" ":type id: :class:`str` or :data:`None`\n" ":param ns: the namespace prefix (optional)\n" ":type ns: :class:`str` or :data:`None`\n" ":return: the pointer to newly created :xml:`` node\n" ":rtype: :class:`lxml.etree._Element`"; static PyObject* PyXmlSec_TemplateEncryptedDataEnsureKeyInfo(PyObject* self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "node", "id", "ns", NULL}; PyXmlSec_LxmlElementPtr node = NULL; const char* id = NULL; const char* ns = NULL; xmlNodePtr res; PYXMLSEC_DEBUG("template encrypted_data_ensure_key_info - start"); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|zz:encrypted_data_ensure_key_info", kwlist, PyXmlSec_LxmlElementConverter, &node, &id, &ns)) { goto ON_FAIL; } Py_BEGIN_ALLOW_THREADS; res = xmlSecTmplEncDataEnsureKeyInfo(node->_c_node, XSTR(id)); Py_END_ALLOW_THREADS; if (res == NULL) { PyXmlSec_SetLastError("cannot ensure key info for encrypted data."); goto ON_FAIL; } if (ns != NULL) { res->ns->prefix = xmlStrdup(XSTR(ns)); } PYXMLSEC_DEBUG("template encrypted_data_ensure_key_info - ok"); return (PyObject*)PyXmlSec_elementFactory(node->_doc, res); ON_FAIL: PYXMLSEC_DEBUG("template encrypted_data_ensure_key_info - fail"); return NULL; } static char PyXmlSec_TemplateEncryptedDataEnsureCipherValue__doc__[] = \ "encrypted_data_ensure_cipher_value(node) -> lxml.etree._Element\n" "Adds :xml:`` to the :xml:`` node of ``node``.\n\n" ":param node: the pointer to :xml:`` node\n" ":type node: :class:`lxml.etree._Element`\n" ":return: the pointer to newly created :xml:`` node\n" ":rtype: :class:`lxml.etree._Element`"; static PyObject* PyXmlSec_TemplateEncryptedDataEnsureCipherValue(PyObject* self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "node", NULL}; PyXmlSec_LxmlElementPtr node = NULL; xmlNodePtr res; PYXMLSEC_DEBUG("template encrypted_data_ensure_cipher_value - start"); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:encrypted_data_ensure_cipher_value", kwlist, PyXmlSec_LxmlElementConverter, &node)) { goto ON_FAIL; } Py_BEGIN_ALLOW_THREADS; res = xmlSecTmplEncDataEnsureCipherValue(node->_c_node); Py_END_ALLOW_THREADS; if (res == NULL) { PyXmlSec_SetLastError("cannot ensure cipher value for encrypted data."); goto ON_FAIL; } PYXMLSEC_DEBUG("template encrypted_data_ensure_cipher_value - ok"); return (PyObject*)PyXmlSec_elementFactory(node->_doc, res); ON_FAIL: PYXMLSEC_DEBUG("template encrypted_data_ensure_cipher_value - fail"); return NULL; } static char PyXmlSec_TemplateTransformAddC14NInclNamespaces__doc__[] = \ "transform_add_c14n_inclusive_namespaces(node, prefixes = None) -> None\n" "Adds 'inclusive' namespaces to the ExcC14N transform node ``node``.\n\n" ":param node: the pointer to :xml:`` node.\n" ":type node: :class:`lxml.etree._Element`\n" ":param prefixes: the list of namespace prefixes, where ``'default'`` indicates the default namespace (optional).\n" ":type prefixes: :class:`str` or :class:`list` of strings"; static PyObject* PyXmlSec_TemplateTransformAddC14NInclNamespaces(PyObject* self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "node", "prefixes", NULL}; PyXmlSec_LxmlElementPtr node = NULL; PyObject* prefixes = NULL; PyObject* sep; int res; const char* c_prefixes; // transform_add_c14n_inclusive_namespaces PYXMLSEC_DEBUG("template encrypted_data_ensure_cipher_value - start"); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O:transform_add_c14n_inclusive_namespaces", kwlist, PyXmlSec_LxmlElementConverter, &node, &prefixes)) { prefixes = NULL; goto ON_FAIL; } if (PyList_Check(prefixes) || PyTuple_Check(prefixes)) { sep = PyUnicode_FromString(" "); prefixes = PyObject_CallMethod(sep, "join", "O", prefixes); Py_DECREF(sep); } else if (PyUnicode_Check(prefixes)) { Py_INCREF(prefixes); } else { PyErr_SetString(PyExc_TypeError, "expected instance of str or list of str"); prefixes = NULL; } if (prefixes == NULL) { goto ON_FAIL; } c_prefixes = PyUnicode_AsUTF8(prefixes); Py_BEGIN_ALLOW_THREADS; res = xmlSecTmplTransformAddC14NInclNamespaces(node->_c_node, XSTR(c_prefixes)); Py_END_ALLOW_THREADS; if (res != 0) { PyXmlSec_SetLastError("cannot add 'inclusive' namespaces to the ExcC14N transform node"); goto ON_FAIL; } Py_DECREF(prefixes); PYXMLSEC_DEBUG("transform_add_c14n_inclusive_namespaces - ok"); Py_RETURN_NONE; ON_FAIL: PYXMLSEC_DEBUG("transform_add_c14n_inclusive_namespaces - fail"); Py_XDECREF(prefixes); return NULL; } static PyMethodDef PyXmlSec_TemplateMethods[] = { { "create", (PyCFunction)PyXmlSec_TemplateCreate, METH_VARARGS|METH_KEYWORDS, PyXmlSec_TemplateCreate__doc__ }, { "add_reference", (PyCFunction)PyXmlSec_TemplateAddReference, METH_VARARGS|METH_KEYWORDS, PyXmlSec_TemplateAddReference__doc__ }, { "add_transform", (PyCFunction)PyXmlSec_TemplateAddTransform, METH_VARARGS|METH_KEYWORDS, PyXmlSec_TemplateAddTransform__doc__ }, { "ensure_key_info", (PyCFunction)PyXmlSec_TemplateEnsureKeyInfo, METH_VARARGS|METH_KEYWORDS, PyXmlSec_TemplateEnsureKeyInfo__doc__ }, { "add_key_name", (PyCFunction)PyXmlSec_TemplateAddKeyName, METH_VARARGS|METH_KEYWORDS, PyXmlSec_TemplateAddKeyName__doc__ }, { "add_key_value", (PyCFunction)PyXmlSec_TemplateAddKeyValue, METH_VARARGS|METH_KEYWORDS, PyXmlSec_TemplateAddKeyValue__doc__ }, { "add_x509_data", (PyCFunction)PyXmlSec_TemplateAddX509Data, METH_VARARGS|METH_KEYWORDS, PyXmlSec_TemplateAddX509Data__doc__ }, { "x509_data_add_issuer_serial", (PyCFunction)PyXmlSec_TemplateAddX509DataAddIssuerSerial, METH_VARARGS|METH_KEYWORDS, PyXmlSec_TemplateAddX509DataAddIssuerSerial__doc__ }, { "x509_issuer_serial_add_issuer_name", (PyCFunction)PyXmlSec_TemplateAddX509DataIssuerSerialAddIssuerName, METH_VARARGS|METH_KEYWORDS, PyXmlSec_TemplateAddX509DataIssuerSerialAddIssuerName__doc__ }, { "x509_issuer_serial_add_serial_number", (PyCFunction)PyXmlSec_TemplateAddX509DataIssuerSerialAddIssuerSerialNumber, METH_VARARGS|METH_KEYWORDS, PyXmlSec_TemplateAddX509DataIssuerSerialAddIssuerSerialNumber__doc__ }, { "x509_data_add_subject_name", (PyCFunction)PyXmlSec_TemplateAddX509DataAddSubjectName, METH_VARARGS|METH_KEYWORDS, PyXmlSec_TemplateAddX509DataAddSubjectName__doc__ }, { "x509_data_add_ski", (PyCFunction)PyXmlSec_TemplateAddX509DataAddSKI, METH_VARARGS|METH_KEYWORDS, PyXmlSec_TemplateAddX509DataAddSKI__doc__ }, { "x509_data_add_certificate", (PyCFunction)PyXmlSec_TemplateAddX509DataAddCertificate, METH_VARARGS|METH_KEYWORDS, PyXmlSec_TemplateAddX509DataAddCertificate__doc__ }, { "x509_data_add_crl", (PyCFunction)PyXmlSec_TemplateAddX509DataAddCRL, METH_VARARGS|METH_KEYWORDS, PyXmlSec_TemplateAddX509DataAddCRL__doc__ }, { "add_encrypted_key", (PyCFunction)PyXmlSec_TemplateAddEncryptedKey, METH_VARARGS|METH_KEYWORDS, PyXmlSec_TemplateAddEncryptedKey__doc__ }, { "encrypted_data_create", (PyCFunction)PyXmlSec_TemplateCreateEncryptedData, METH_VARARGS|METH_KEYWORDS, PyXmlSec_TemplateCreateEncryptedData__doc__ }, { "encrypted_data_ensure_key_info", (PyCFunction)PyXmlSec_TemplateEncryptedDataEnsureKeyInfo, METH_VARARGS|METH_KEYWORDS, PyXmlSec_TemplateEncryptedDataEnsureKeyInfo__doc__ }, { "encrypted_data_ensure_cipher_value", (PyCFunction)PyXmlSec_TemplateEncryptedDataEnsureCipherValue, METH_VARARGS|METH_KEYWORDS, PyXmlSec_TemplateEncryptedDataEnsureCipherValue__doc__ }, { "transform_add_c14n_inclusive_namespaces", (PyCFunction)PyXmlSec_TemplateTransformAddC14NInclNamespaces, METH_VARARGS|METH_KEYWORDS, PyXmlSec_TemplateTransformAddC14NInclNamespaces__doc__, }, {NULL, NULL} /* sentinel */ }; static PyModuleDef PyXmlSec_TemplateModule = { PyModuleDef_HEAD_INIT, STRINGIFY(MODULE_NAME) ".template", PYXMLSEC_TEMPLATES_DOC, -1, PyXmlSec_TemplateMethods, /* m_methods */ NULL, /* m_slots */ NULL, /* m_traverse */ NULL, /* m_clear */ NULL, /* m_free */ }; int PyXmlSec_TemplateModule_Init(PyObject* package) { PyObject* template = PyModule_Create(&PyXmlSec_TemplateModule); if (!template) goto ON_FAIL; PYXMLSEC_DEBUGF("%p", template); if (PyModule_AddObject(package, "template", template) < 0) goto ON_FAIL; return 0; ON_FAIL: Py_XDECREF(template); return -1; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/src/tree.c0000644000175100001710000002047414300243501014362 0ustar00runnerdocker// Copyright (c) 2017 Ryan Leckey // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "common.h" #include "utils.h" #include "lxml.h" #include #define PYXMLSEC_TREE_DOC "Common XML utility functions" static char PyXmlSec_TreeFindChild__doc__[] = \ "find_child(parent, name, namespace)\n" "Searches a direct child of the ``parent`` node having given ``name`` and ``namespace`` href.\n\n" ":param parent: the pointer to XML node\n" ":type parent: :class:`lxml.etree._Element`\n" ":param name: the name\n" ":type name: :class:`str`\n" ":param namespace: the namespace href (optional)\n" ":type namespace: :class:`str`\n" ":return: the pointer to the found node or :data:`None` if node is not found\n" ":rtype: :class:`lxml.etree._Element` or :data:`None`"; static PyObject* PyXmlSec_TreeFindChild(PyObject* self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "parent", "name", "namespace", NULL}; PyXmlSec_LxmlElementPtr node = NULL; const char* name = NULL; const char* ns = (const char*)xmlSecDSigNs; xmlNodePtr res; PYXMLSEC_DEBUG("tree find_child - start"); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&s|s:find_child", kwlist, PyXmlSec_LxmlElementConverter, &node, &name, &ns)) { goto ON_FAIL; } Py_BEGIN_ALLOW_THREADS; res = xmlSecFindChild(node->_c_node, XSTR(name), XSTR(ns)); Py_END_ALLOW_THREADS; PYXMLSEC_DEBUG("tree find_child - ok"); if (res == NULL) { Py_RETURN_NONE; } return (PyObject*)PyXmlSec_elementFactory(node->_doc, res); ON_FAIL: PYXMLSEC_DEBUG("tree find_child - fail"); return NULL; } static char PyXmlSec_TreeFindParent__doc__[] = \ "find_parent(node, name, namespace)\n" "Searches the ancestors axis of the ``node`` having given ``name`` and ``namespace`` href.\n\n" ":param node: the pointer to XML node\n" ":type node: :class:`lxml.etree._Element`\n" ":param name: the name\n" ":type name: :class:`str`\n" ":param namespace: the namespace href (optional)\n" ":type namespace: :class:`str`\n" ":return: the pointer to the found node or :data:`None` if node is not found\n" ":rtype: :class:`lxml.etree._Element` or :data:`None`"; static PyObject* PyXmlSec_TreeFindParent(PyObject* self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "node", "name", "namespace", NULL}; PyXmlSec_LxmlElementPtr node = NULL; const char* name = NULL; const char* ns = (const char*)xmlSecDSigNs; xmlNodePtr res; PYXMLSEC_DEBUG("tree find_parent - start"); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&s|s:find_parent", kwlist, PyXmlSec_LxmlElementConverter, &node, &name, &ns)) { goto ON_FAIL; } Py_BEGIN_ALLOW_THREADS; res = xmlSecFindParent(node->_c_node, XSTR(name), XSTR(ns)); Py_END_ALLOW_THREADS; PYXMLSEC_DEBUG("tree find_parent - ok"); if (res == NULL) { Py_RETURN_NONE; } return (PyObject*)PyXmlSec_elementFactory(node->_doc, res); ON_FAIL: PYXMLSEC_DEBUG("tree find_parent - fail"); return NULL; } static char PyXmlSec_TreeFindNode__doc__[] = \ "find_node(node, name, namespace)\n" "Searches all children of the given ``node`` having given ``name`` and ``namespace`` href.\n\n" ":param node: the pointer to XML node\n" ":type node: :class:`lxml.etree._Element`\n" ":param name: the name\n" ":type name: :class:`str`\n" ":param namespace: the namespace href (optional)\n" ":type namespace: :class:`str`\n" ":return: the pointer to the found node or :data:`None` if node is not found\n" ":rtype: :class:`lxml.etree._Element` or :data:`None`"; static PyObject* PyXmlSec_TreeFindNode(PyObject* self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "node", "name", "namespace", NULL}; PyXmlSec_LxmlElementPtr node = NULL; const char* name = NULL; const char* ns = (const char*)xmlSecDSigNs; xmlNodePtr res; PYXMLSEC_DEBUG("tree find_node - start"); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&s|s:find_node", kwlist, PyXmlSec_LxmlElementConverter, &node, &name, &ns)) { goto ON_FAIL; } Py_BEGIN_ALLOW_THREADS; res = xmlSecFindNode(node->_c_node, XSTR(name), XSTR(ns)); Py_END_ALLOW_THREADS; PYXMLSEC_DEBUG("tree find_node - ok"); if (res == NULL) { Py_RETURN_NONE; } return (PyObject*)PyXmlSec_elementFactory(node->_doc, res); ON_FAIL: PYXMLSEC_DEBUG("tree find_node - fail"); return NULL; } static char PyXmlSec_TreeAddIds__doc__[] = \ "add_ids(node, ids) -> None\n" "Registers ``ids`` as ids used below ``node``. ``ids`` is a sequence of attribute names "\ "used as XML ids in the subtree rooted at ``node``.\n"\ "A call to :func:`~.add_ids` may be necessary to make known which attributes contain XML ids.\n"\ "This is the case, if a transform references an id via ``XPointer`` or a self document uri and " "the id inkey_data_formation is not available by other means (e.g. an associated DTD or XML schema).\n\n" ":param node: the pointer to XML node\n" ":type node: :class:`lxml.etree._Element`\n" ":param ids: the list of ID attributes.\n" ":type ids: :class:`list` of strings"; static PyObject* PyXmlSec_TreeAddIds(PyObject* self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "node", "ids", NULL}; PyXmlSec_LxmlElementPtr node = NULL; PyObject* ids = NULL; const xmlChar** list = NULL; Py_ssize_t n; PyObject* tmp; PyObject* key; Py_ssize_t i; PYXMLSEC_DEBUG("tree add_ids - start"); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O:add_ids", kwlist, PyXmlSec_LxmlElementConverter, &node, &ids)) { goto ON_FAIL; } n = PyObject_Length(ids); if (n < 0) goto ON_FAIL; list = (const xmlChar**)xmlMalloc(sizeof(xmlChar*) * (n + 1)); if (list == NULL) { PyErr_SetString(PyExc_MemoryError, "no memory"); goto ON_FAIL; } for (i = 0; i < n; ++i) { key = PyLong_FromSsize_t(i); if (key == NULL) goto ON_FAIL; tmp = PyObject_GetItem(ids, key); Py_DECREF(key); if (tmp == NULL) goto ON_FAIL; list[i] = XSTR(PyUnicode_AsUTF8(tmp)); Py_DECREF(tmp); if (list[i] == NULL) goto ON_FAIL; } list[n] = NULL; Py_BEGIN_ALLOW_THREADS; xmlSecAddIDs(node->_doc->_c_doc, node->_c_node, list); Py_END_ALLOW_THREADS; PyMem_Free(list); PYXMLSEC_DEBUG("tree add_ids - ok"); Py_RETURN_NONE; ON_FAIL: PYXMLSEC_DEBUG("tree add_ids - fail"); xmlFree(list); return NULL; } static PyMethodDef PyXmlSec_TreeMethods[] = { { "find_child", (PyCFunction)PyXmlSec_TreeFindChild, METH_VARARGS|METH_KEYWORDS, PyXmlSec_TreeFindChild__doc__, }, { "find_parent", (PyCFunction)PyXmlSec_TreeFindParent, METH_VARARGS|METH_KEYWORDS, PyXmlSec_TreeFindParent__doc__, }, { "find_node", (PyCFunction)PyXmlSec_TreeFindNode, METH_VARARGS|METH_KEYWORDS, PyXmlSec_TreeFindNode__doc__, }, { "add_ids", (PyCFunction)PyXmlSec_TreeAddIds, METH_VARARGS|METH_KEYWORDS, PyXmlSec_TreeAddIds__doc__, }, {NULL, NULL} /* sentinel */ }; static PyModuleDef PyXmlSec_TreeModule = { PyModuleDef_HEAD_INIT, STRINGIFY(MODULE_NAME) ".tree", PYXMLSEC_TREE_DOC, -1, PyXmlSec_TreeMethods, /* m_methods */ NULL, /* m_slots */ NULL, /* m_traverse */ NULL, /* m_clear */ NULL, /* m_free */ }; int PyXmlSec_TreeModule_Init(PyObject* package) { PyObject* tree = PyModule_Create(&PyXmlSec_TreeModule); if (!tree) goto ON_FAIL; if (PyModule_AddObject(package, "tree", tree) < 0) goto ON_FAIL; return 0; ON_FAIL: Py_XDECREF(tree); return -1; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/src/utils.c0000644000175100001710000000316114300243501014555 0ustar00runnerdocker// Copyright (c) 2017 Ryan Leckey // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "utils.h" PyObject* PyXmlSec_GetFilePathOrContent(PyObject* file, int* is_content) { PyObject* data; PyObject* utf8; PyObject* tmp = NULL; if (PyObject_HasAttrString(file, "read")) { data = PyObject_CallMethod(file, "read", NULL); if (data != NULL && PyUnicode_Check(data)) { utf8 = PyUnicode_AsUTF8String(data); Py_DECREF(data); data = utf8; } *is_content = 1; return data; } *is_content = 0; if (!PyUnicode_FSConverter(file, &tmp)) { return NULL; } return tmp; } int PyXmlSec_SetStringAttr(PyObject* obj, const char* name, const char* value) { PyObject* tmp = PyUnicode_FromString(value); int r; if (tmp == NULL) { return -1; } r = PyObject_SetAttrString(obj, name, tmp); Py_DECREF(tmp); return r; } int PyXmlSec_SetLongAttr(PyObject* obj, const char* name, long value) { PyObject* tmp = PyLong_FromLong(value); int r; if (tmp == NULL) { return -1; } r = PyObject_SetAttrString(obj, name, tmp); Py_DECREF(tmp); return r; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/src/utils.h0000644000175100001710000000163114300243501014562 0ustar00runnerdocker// Copyright (c) 2017 Ryan Leckey // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #ifndef __PYXMLSEC_UTILS_H__ #define __PYXMLSEC_UTILS_H__ #include "platform.h" int PyXmlSec_SetStringAttr(PyObject* obj, const char* name, const char* value); int PyXmlSec_SetLongAttr(PyObject* obj, const char* name, long value); // return content if file is fileobject, or fs encoded filepath PyObject* PyXmlSec_GetFilePathOrContent(PyObject* file, int* is_content); #endif //__PYXMLSEC_UTILS_H__ ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1661028173.9655652 xmlsec-1.3.13/src/xmlsec/0000755000175100001710000000000014300243516014551 5ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/src/xmlsec/__init__.pyi0000644000175100001710000000622514300243501017032 0ustar00runnerdockerfrom collections.abc import Callable, Iterable from typing import IO, Any, AnyStr, TypeVar, overload from _typeshed import GenericPath, Self, StrOrBytesPath from lxml.etree import _Element from xmlsec import constants as constants from xmlsec import tree as tree from xmlsec.constants import __KeyData as KeyData from xmlsec.constants import __Transform as Transform _E = TypeVar('_E', bound=_Element) def enable_debug_trace(enabled: bool = ...) -> None: ... def init() -> None: ... def shutdown() -> None: ... def cleanup_callbacks() -> None: ... def register_default_callbacks() -> None: ... def register_callbacks( input_match_callback: Callable[[bytes], bool], input_open_callback: Callable[[bytes], Any], input_read_callback: Callable[[Any, memoryview], int], input_close_callback: Callable[[Any], None], ) -> None: ... @overload def base64_default_line_size() -> int: ... @overload def base64_default_line_size(size: int) -> None: ... class EncryptionContext: key: Key | None def __init__(self, manager: KeysManager | None = ...) -> None: ... def decrypt(self, node: _Element) -> _Element: ... def encrypt_binary(self, template: _E, data: bytes) -> _E: ... def encrypt_uri(self, template: _E, uri: str) -> _E: ... def encrypt_xml(self, template: _E, node: _Element) -> _E: ... def reset(self) -> None: ... class Error(Exception): ... class InternalError(Error): ... class Key: name: str @classmethod def from_binary_data(cls: type[Self], klass: KeyData, data: AnyStr) -> Self: ... @classmethod def from_binary_file(cls: type[Self], klass: KeyData, filename: StrOrBytesPath) -> Self: ... @classmethod def from_file(cls: type[Self], file: GenericPath[AnyStr] | IO[AnyStr], format: int, password: str | None = ...) -> Self: ... @classmethod def from_memory(cls: type[Self], data: AnyStr, format: int, password: str | None = ...) -> Self: ... @classmethod def generate(cls: type[Self], klass: KeyData, size: int, type: int) -> Self: ... def load_cert_from_file(self, file: GenericPath[AnyStr] | IO[AnyStr], format: int) -> None: ... def load_cert_from_memory(self, data: AnyStr, format: int) -> None: ... def __copy__(self: Self) -> Self: ... def __deepcopy__(self: Self) -> Self: ... class KeysManager: def add_key(self, key: Key) -> None: ... def load_cert(self, filename: StrOrBytesPath, format: int, type: int) -> None: ... def load_cert_from_memory(self, data: AnyStr, format: int, type: int) -> None: ... class SignatureContext: key: Key | None def enable_reference_transform(self, transform: Transform) -> None: ... def enable_signature_transform(self, transform: Transform) -> None: ... def register_id(self, node: _Element, id_attr: str = ..., id_ns: str | None = ...) -> None: ... def set_enabled_key_data(self, keydata_list: Iterable[KeyData]) -> None: ... def sign(self, node: _Element) -> None: ... def sign_binary(self, bytes: bytes, transform: Transform) -> bytes: ... def verify(self, node: _Element) -> None: ... def verify_binary(self, bytes: bytes, transform: Transform, signature: bytes) -> None: ... class VerificationError(Error): ... ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/src/xmlsec/constants.pyi0000644000175100001710000001136014300243501017303 0ustar00runnerdockerimport sys from typing import NamedTuple if sys.version_info >= (3, 8): from typing import Final else: from typing_extensions import Final class __KeyData(NamedTuple): # __KeyData type href: str name: str class __KeyDataNoHref(NamedTuple): # __KeyData type href: None name: str class __Transform(NamedTuple): # __Transform type href: str name: str usage: int class __TransformNoHref(NamedTuple): # __Transform type href: None name: str usage: int DSigNs: Final[str] EncNs: Final[str] KeyDataAes: Final[__KeyData] KeyDataDes: Final[__KeyData] KeyDataDsa: Final[__KeyData] KeyDataEcdsa: Final[__KeyData] KeyDataEncryptedKey: Final[__KeyData] KeyDataFormatBinary: Final[int] KeyDataFormatCertDer: Final[int] KeyDataFormatCertPem: Final[int] KeyDataFormatDer: Final[int] KeyDataFormatPem: Final[int] KeyDataFormatPkcs12: Final[int] KeyDataFormatPkcs8Der: Final[int] KeyDataFormatPkcs8Pem: Final[int] KeyDataFormatUnknown: Final[int] KeyDataHmac: Final[__KeyData] KeyDataName: Final[__KeyDataNoHref] KeyDataRawX509Cert: Final[__KeyData] KeyDataRetrievalMethod: Final[__KeyDataNoHref] KeyDataRsa: Final[__KeyData] KeyDataTypeAny: Final[int] KeyDataTypeNone: Final[int] KeyDataTypePermanent: Final[int] KeyDataTypePrivate: Final[int] KeyDataTypePublic: Final[int] KeyDataTypeSession: Final[int] KeyDataTypeSymmetric: Final[int] KeyDataTypeTrusted: Final[int] KeyDataTypeUnknown: Final[int] KeyDataValue: Final[__KeyDataNoHref] KeyDataX509: Final[__KeyData] NodeCanonicalizationMethod: Final[str] NodeCipherData: Final[str] NodeCipherReference: Final[str] NodeCipherValue: Final[str] NodeDataReference: Final[str] NodeDigestMethod: Final[str] NodeDigestValue: Final[str] NodeEncryptedData: Final[str] NodeEncryptedKey: Final[str] NodeEncryptionMethod: Final[str] NodeEncryptionProperties: Final[str] NodeEncryptionProperty: Final[str] NodeKeyInfo: Final[str] NodeKeyName: Final[str] NodeKeyReference: Final[str] NodeKeyValue: Final[str] NodeManifest: Final[str] NodeObject: Final[str] NodeReference: Final[str] NodeReferenceList: Final[str] NodeSignature: Final[str] NodeSignatureMethod: Final[str] NodeSignatureProperties: Final[str] NodeSignatureValue: Final[str] NodeSignedInfo: Final[str] NodeX509Data: Final[str] Ns: Final[str] NsExcC14N: Final[str] NsExcC14NWithComments: Final[str] Soap11Ns: Final[str] Soap12Ns: Final[str] TransformAes128Cbc: Final[__Transform] TransformAes128Gcm: Final[__Transform] TransformAes192Cbc: Final[__Transform] TransformAes192Gcm: Final[__Transform] TransformAes256Cbc: Final[__Transform] TransformAes256Gcm: Final[__Transform] TransformDes3Cbc: Final[__Transform] TransformDsaSha1: Final[__Transform] TransformEcdsaSha1: Final[__Transform] TransformEcdsaSha224: Final[__Transform] TransformEcdsaSha256: Final[__Transform] TransformEcdsaSha384: Final[__Transform] TransformEcdsaSha512: Final[__Transform] TransformEnveloped: Final[__Transform] TransformExclC14N: Final[__Transform] TransformExclC14NWithComments: Final[__Transform] TransformHmacMd5: Final[__Transform] TransformHmacRipemd160: Final[__Transform] TransformHmacSha1: Final[__Transform] TransformHmacSha224: Final[__Transform] TransformHmacSha256: Final[__Transform] TransformHmacSha384: Final[__Transform] TransformHmacSha512: Final[__Transform] TransformInclC14N: Final[__Transform] TransformInclC14N11: Final[__Transform] TransformInclC14N11WithComments: Final[__Transform] TransformInclC14NWithComments: Final[__Transform] TransformKWAes128: Final[__Transform] TransformKWAes192: Final[__Transform] TransformKWAes256: Final[__Transform] TransformKWDes3: Final[__Transform] TransformMd5: Final[__Transform] TransformRemoveXmlTagsC14N: Final[__TransformNoHref] TransformRipemd160: Final[__Transform] TransformRsaMd5: Final[__Transform] TransformRsaOaep: Final[__Transform] TransformRsaPkcs1: Final[__Transform] TransformRsaRipemd160: Final[__Transform] TransformRsaSha1: Final[__Transform] TransformRsaSha224: Final[__Transform] TransformRsaSha256: Final[__Transform] TransformRsaSha384: Final[__Transform] TransformRsaSha512: Final[__Transform] TransformSha1: Final[__Transform] TransformSha224: Final[__Transform] TransformSha256: Final[__Transform] TransformSha384: Final[__Transform] TransformSha512: Final[__Transform] TransformUsageAny: Final[int] TransformUsageC14NMethod: Final[int] TransformUsageDSigTransform: Final[int] TransformUsageDigestMethod: Final[int] TransformUsageEncryptionMethod: Final[int] TransformUsageSignatureMethod: Final[int] TransformUsageUnknown: Final[int] TransformVisa3DHack: Final[__TransformNoHref] TransformXPath: Final[__Transform] TransformXPath2: Final[__Transform] TransformXPointer: Final[__Transform] TransformXslt: Final[__Transform] TypeEncContent: Final[str] TypeEncElement: Final[str] XPath2Ns: Final[str] XPathNs: Final[str] XPointerNs: Final[str] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/src/xmlsec/py.typed0000644000175100001710000000007714300243501016246 0ustar00runnerdocker# Marker file for PEP 561. The xmlsec package uses stub files. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/src/xmlsec/template.pyi0000644000175100001710000000353714300243501017111 0ustar00runnerdockerfrom collections.abc import Sequence from typing import Any from lxml.etree import _Element from xmlsec.constants import __Transform as Transform def add_encrypted_key( node: _Element, method: Transform, id: str | None = ..., type: str | None = ..., recipient: str | None = ... ) -> _Element: ... def add_key_name(node: _Element, name: str | None = ...) -> _Element: ... def add_key_value(node: _Element) -> _Element: ... def add_reference( node: _Element, digest_method: Transform, id: str | None = ..., uri: str | None = ..., type: str | None = ... ) -> _Element: ... def add_transform(node: _Element, transform: Transform) -> Any: ... def add_x509_data(node: _Element) -> _Element: ... def create(node: _Element, c14n_method: Transform, sign_method: Transform) -> _Element: ... def encrypted_data_create( node: _Element, method: Transform, id: str | None = ..., type: str | None = ..., mime_type: str | None = ..., encoding: str | None = ..., ns: str | None = ..., ) -> _Element: ... def encrypted_data_ensure_cipher_value(node: _Element) -> _Element: ... def encrypted_data_ensure_key_info(node: _Element, id: str | None = ..., ns: str | None = ...) -> _Element: ... def ensure_key_info(node: _Element, id: str | None = ...) -> _Element: ... def transform_add_c14n_inclusive_namespaces(node: _Element, prefixes: str | Sequence[str]) -> None: ... def x509_data_add_certificate(node: _Element) -> _Element: ... def x509_data_add_crl(node: _Element) -> _Element: ... def x509_data_add_issuer_serial(node: _Element) -> _Element: ... def x509_data_add_ski(node: _Element) -> _Element: ... def x509_data_add_subject_name(node: _Element) -> _Element: ... def x509_issuer_serial_add_issuer_name(node: _Element, name: str | None = ...) -> _Element: ... def x509_issuer_serial_add_serial_number(node: _Element, serial: str | None = ...) -> _Element: ... ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/src/xmlsec/tree.pyi0000644000175100001710000000125614300243501016231 0ustar00runnerdockerfrom collections.abc import Sequence from typing import overload from lxml.etree import _Element def add_ids(node: _Element, ids: Sequence[str]) -> None: ... @overload def find_child(parent: _Element, name: str) -> _Element | None: ... @overload def find_child(parent: _Element, name: str, namespace: str = ...) -> _Element | None: ... @overload def find_node(node: _Element, name: str) -> _Element | None: ... @overload def find_node(node: _Element, name: str, namespace: str = ...) -> _Element | None: ... @overload def find_parent(node: _Element, name: str) -> _Element | None: ... @overload def find_parent(node: _Element, name: str, namespace: str = ...) -> _Element | None: ... ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1661028173.9655652 xmlsec-1.3.13/src/xmlsec.egg-info/0000755000175100001710000000000014300243516016243 5ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028173.0 xmlsec-1.3.13/src/xmlsec.egg-info/PKG-INFO0000644000175100001710000001544714300243515017352 0ustar00runnerdockerMetadata-Version: 2.1 Name: xmlsec Version: 1.3.13 Summary: Python bindings for the XML Security Library Home-page: https://github.com/mehcode/python-xmlsec Author: Bulat Gaifullin Author-email: support@mehcode.com Maintainer: Oleg Hoefling Maintainer-email: oleg.hoefling@gmail.com License: MIT Project-URL: Documentation, https://xmlsec.readthedocs.io Project-URL: Source, https://github.com/mehcode/python-xmlsec Project-URL: Changelog, https://github.com/mehcode/python-xmlsec/releases Keywords: xmlsec Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: Intended Audience :: System Administrators Classifier: License :: OSI Approved :: MIT License Classifier: Operating System :: OS Independent Classifier: Programming Language :: C Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Topic :: Text Processing :: Markup :: XML Classifier: Typing :: Typed Requires-Python: >=3.5 License-File: LICENSE python-xmlsec ============= .. image:: https://img.shields.io/pypi/v/xmlsec.svg?logo=python&logoColor=white :target: https://pypi.python.org/pypi/xmlsec .. image:: https://img.shields.io/travis/com/mehcode/python-xmlsec/master.svg?logo=travis&logoColor=white&label=Travis%20CI :target: https://travis-ci.org/mehcode/python-xmlsec .. image:: https://img.shields.io/appveyor/ci/hoefling/xmlsec/master.svg?logo=appveyor&logoColor=white&label=AppVeyor :target: https://ci.appveyor.com/project/hoefling/xmlsec .. image:: https://github.com/mehcode/python-xmlsec/workflows/manylinux2010/badge.svg :target: https://github.com/mehcode/python-xmlsec/actions?query=workflow%3A%22manylinux2010%22 .. image:: https://github.com/mehcode/python-xmlsec/workflows/MacOS/badge.svg :target: https://github.com/mehcode/python-xmlsec/actions?query=workflow%3A%22MacOS%22 .. image:: https://github.com/mehcode/python-xmlsec/workflows/linuxbrew/badge.svg :target: https://github.com/mehcode/python-xmlsec/actions?query=workflow%3A%22linuxbrew%22 .. image:: https://codecov.io/gh/mehcode/python-xmlsec/branch/master/graph/badge.svg :target: https://codecov.io/gh/mehcode/python-xmlsec .. image:: https://img.shields.io/readthedocs/xmlsec/latest?logo=read-the-docs :target: https://xmlsec.readthedocs.io/en/latest/?badge=latest :alt: Documentation Status Python bindings for the `XML Security Library `_. Documentation ************* A documentation for ``xmlsec`` can be found at `xmlsec.readthedocs.io `_. Usage ***** Check the `examples `_ section in the documentation to see various examples of signing and verifying using the library. Requirements ************ - ``libxml2 >= 2.9.1`` - ``libxmlsec1 >= 1.2.18`` Install ******* ``xmlsec`` is available on PyPI: .. code-block:: bash pip install xmlsec Depending on your OS, you may need to install the required native libraries first: Linux (Debian) ^^^^^^^^^^^^^^ .. code-block:: bash apt-get install pkg-config libxml2-dev libxmlsec1-dev libxmlsec1-openssl Note: There is no required version of LibXML2 for Ubuntu Precise, so you need to download and install it manually. .. code-block:: bash wget http://xmlsoft.org/sources/libxml2-2.9.1.tar.gz tar -xvf libxml2-2.9.1.tar.gz cd libxml2-2.9.1 ./configure && make && make install Linux (CentOS) ^^^^^^^^^^^^^^ .. code-block:: bash yum install libxml2-devel xmlsec1-devel xmlsec1-openssl-devel libtool-ltdl-devel Linux (Fedora) ^^^^^^^^^^^^^^ .. code-block:: bash dnf install libxml2-devel xmlsec1-devel xmlsec1-openssl-devel libtool-ltdl-devel Mac ^^^ .. code-block:: bash brew install libxml2 libxmlsec1 pkg-config Alpine ^^^^^^ .. code-block:: bash apk add build-base libressl libffi-dev libressl-dev libxslt-dev libxml2-dev xmlsec-dev xmlsec Troubleshooting *************** Mac ^^^ If you get any fatal errors about missing ``.h`` files, update your ``C_INCLUDE_PATH`` environment variable to include the appropriate files from the ``libxml2`` and ``libxmlsec1`` libraries. Windows ^^^^^^^ Starting with 1.3.7, prebuilt wheels are available for Windows, so running ``pip install xmlsec`` should suffice. If you want to build from source: #. Configure build environment, see `wiki.python.org `_ for more details. #. Install from source dist: .. code-block:: bash pip install xmlsec --no-binary=xmlsec Building from source ******************** #. Clone the ``xmlsec`` source code repository to your local computer. .. code-block:: bash git clone https://github.com/mehcode/python-xmlsec.git #. Change into the ``python-xmlsec`` root directory. .. code-block:: bash cd /path/to/xmlsec #. Install the project and all its dependencies using ``pip``. .. code-block:: bash pip install . Contributing ************ Setting up your environment ^^^^^^^^^^^^^^^^^^^^^^^^^^^ #. Follow steps 1 and 2 of the `manual installation instructions <#building-from-source>`_. #. Initialize a virtual environment to develop in. This is done so as to ensure every contributor is working with close-to-identicial versions of packages. .. code-block:: bash mkvirtualenv xmlsec The ``mkvirtualenv`` command is available from ``virtualenvwrapper`` package which can be installed by following `link `_. #. Activate the created virtual environment: .. code-block:: bash workon xmlsec #. Install ``xmlsec`` in development mode with testing enabled. This will download all dependencies required for running the unit tests. .. code-block:: bash pip install -r requirements-test.txt pip install -e "." Running the test suite ^^^^^^^^^^^^^^^^^^^^^^ #. `Set up your environment <#setting-up-your-environment>`_. #. Run the unit tests. .. code-block:: bash pytest tests #. Tests configuration Env variable ``PYXMLSEC_TEST_ITERATIONS`` specifies number of test iterations to detect memory leaks. Reporting an issue ^^^^^^^^^^^^^^^^^^ Please attach the output of following information: * version of ``xmlsec`` * version of ``libxmlsec1`` * version of ``libxml2`` * output from the command .. code-block:: bash pkg-config --cflags xmlsec1 License ******* Unless otherwise noted, all files contained within this project are licensed under the MIT opensource license. See the included ``LICENSE`` file or visit `opensource.org `_ for more information. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028173.0 xmlsec-1.3.13/src/xmlsec.egg-info/SOURCES.txt0000644000175100001710000000375114300243515020134 0ustar00runnerdocker.pre-commit-config.yaml .readthedocs.yaml LICENSE MANIFEST.in README.rst pyproject.toml setup.cfg setup.py /home/runner/work/xmlsec/xmlsec/src/constants.c /home/runner/work/xmlsec/xmlsec/src/ds.c /home/runner/work/xmlsec/xmlsec/src/enc.c /home/runner/work/xmlsec/xmlsec/src/exception.c /home/runner/work/xmlsec/xmlsec/src/keys.c /home/runner/work/xmlsec/xmlsec/src/lxml.c /home/runner/work/xmlsec/xmlsec/src/main.c /home/runner/work/xmlsec/xmlsec/src/template.c /home/runner/work/xmlsec/xmlsec/src/tree.c /home/runner/work/xmlsec/xmlsec/src/utils.c src/common.h src/constants.c src/constants.h src/debug.h src/ds.c src/enc.c src/exception.c src/exception.h src/keys.c src/keys.h src/lxml.c src/lxml.h src/main.c src/platform.h src/template.c src/tree.c src/utils.c src/utils.h src/xmlsec/__init__.pyi src/xmlsec/constants.pyi src/xmlsec/py.typed src/xmlsec/template.pyi src/xmlsec/tree.pyi src/xmlsec.egg-info/PKG-INFO src/xmlsec.egg-info/SOURCES.txt src/xmlsec.egg-info/dependency_links.txt src/xmlsec.egg-info/not-zip-safe src/xmlsec.egg-info/requires.txt src/xmlsec.egg-info/top_level.txt tests/__init__.py tests/base.py tests/conftest.py tests/test_constants.py tests/test_doc_examples.py tests/test_ds.py tests/test_enc.py tests/test_keys.py tests/test_main.py tests/test_templates.py tests/test_tree.py tests/test_type_stubs.py tests/test_xmlsec.py tests/data/deskey.bin tests/data/doc.xml tests/data/dsacert.der tests/data/dsakey.der tests/data/enc-bad-in.xml tests/data/enc1-in.xml tests/data/enc1-out.xml tests/data/enc2-in.xml tests/data/enc2-out.xml tests/data/enc3-in.xml tests/data/enc3-out.xml tests/data/enc_template.xml tests/data/rsacert.pem tests/data/rsakey.pem tests/data/rsapub.pem tests/data/sign1-in.xml tests/data/sign1-out.xml tests/data/sign2-in.xml tests/data/sign2-out.xml tests/data/sign3-in.xml tests/data/sign3-out.xml tests/data/sign4-in.xml tests/data/sign4-out.xml tests/data/sign5-in.xml tests/data/sign5-out.xml tests/data/sign6-in.bin tests/data/sign6-out.bin tests/data/sign_template.xml././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028173.0 xmlsec-1.3.13/src/xmlsec.egg-info/dependency_links.txt0000644000175100001710000000000114300243515022310 0ustar00runnerdocker ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028173.0 xmlsec-1.3.13/src/xmlsec.egg-info/not-zip-safe0000644000175100001710000000000114300243515020470 0ustar00runnerdocker ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028173.0 xmlsec-1.3.13/src/xmlsec.egg-info/requires.txt0000644000175100001710000000001214300243515020633 0ustar00runnerdockerlxml>=3.8 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028173.0 xmlsec-1.3.13/src/xmlsec.egg-info/top_level.txt0000644000175100001710000000000714300243515020771 0ustar00runnerdockerxmlsec ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1661028173.9655652 xmlsec-1.3.13/tests/0000755000175100001710000000000014300243516013631 5ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/tests/__init__.py0000644000175100001710000000000014300243501015722 0ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/tests/base.py0000644000175100001710000001025514300243501015112 0ustar00runnerdockerimport gc import os import sys import unittest from lxml import etree import xmlsec etype = type(etree.Element("test")) ns = {'dsig': xmlsec.constants.DSigNs, 'enc': xmlsec.constants.EncNs} try: import resource def get_memory_usage(): return resource.getrusage(resource.RUSAGE_SELF).ru_maxrss except ImportError: resource = None def get_memory_usage(): return 0 def get_iterations(): if sys.platform in ('win32',): return 0 try: return int(os.getenv("PYXMLSEC_TEST_ITERATIONS", "10")) except ValueError: return 0 class TestMemoryLeaks(unittest.TestCase): maxDiff = None iterations = get_iterations() data_dir = os.path.join(os.path.dirname(__file__), "data") def setUp(self): gc.disable() self.addTypeEqualityFunc(etype, "assertXmlEqual") xmlsec.enable_debug_trace(1) def run(self, result=None): # run first time super(TestMemoryLeaks, self).run(result=result) if self.iterations == 0: return m_usage = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss o_count = gc.get_count()[0] m_hits = 0 o_hits = 0 for _ in range(self.iterations): super(TestMemoryLeaks, self).run(result=result) m_usage_n = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss if m_usage_n > m_usage: m_usage = m_usage_n m_hits += 1 o_count_n = gc.get_count()[0] if o_count_n > o_count: o_count = o_count_n o_hits += 1 del m_usage_n del o_count_n if m_hits > int(self.iterations * 0.8): result.buffer = False try: raise AssertionError("memory leak detected") except AssertionError: result.addError(self, sys.exc_info()) if o_hits > int(self.iterations * 0.8): result.buffer = False try: raise AssertionError("unreferenced objects detected") except AssertionError: result.addError(self, sys.exc_info()) def path(self, name): """Return full path for resource.""" return os.path.join(self.data_dir, name) def load(self, name): """Load resource by name.""" with open(self.path(name), "rb") as stream: return stream.read() def load_xml(self, name, xpath=None): """Return xml.etree.""" with open(self.path(name)) as f: root = etree.parse(f).getroot() if xpath is None: return root return root.find(xpath) def dump(self, root): print(etree.tostring(root)) def assertXmlEqual(self, first, second, msg=None): # noqa: N802 """Check equality of etree.roots.""" msg = msg or '' if first.tag != second.tag: self.fail('Tags do not match: {} and {}. {}'.format(first.tag, second.tag, msg)) for name, value in first.attrib.items(): if second.attrib.get(name) != value: self.fail('Attributes do not match: {}={!r}, {}={!r}. {}'.format(name, value, name, second.attrib.get(name), msg)) for name in second.attrib.keys(): if name not in first.attrib: self.fail('x2 has an attribute x1 is missing: {}. {}'.format(name, msg)) if not xml_text_compare(first.text, second.text): self.fail('text: {!r} != {!r}. {}'.format(first.text, second.text, msg)) if not xml_text_compare(first.tail, second.tail): self.fail('tail: {!r} != {!r}. {}'.format(first.tail, second.tail, msg)) cl1 = sorted(first.getchildren(), key=lambda x: x.tag) cl2 = sorted(second.getchildren(), key=lambda x: x.tag) if len(cl1) != len(cl2): self.fail('children length differs, {} != {}. {}'.format(len(cl1), len(cl2), msg)) i = 0 for c1, c2 in zip(cl1, cl2): i += 1 self.assertXmlEqual(c1, c2) def xml_text_compare(t1, t2): if not t1 and not t2: return True if t1 == '*' or t2 == '*': return True return (t1 or '').strip() == (t2 or '').strip() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/tests/conftest.py0000644000175100001710000000055614300243501016030 0ustar00runnerdockerdef pytest_collection_modifyitems(items): """ Put the module init test first to implicitly check whether any subsequent test fails because of module reinitialization. """ def module_init_tests_first(item): return int('test_xmlsec.py::TestModule::test_reinitialize_module' not in item.nodeid) items.sort(key=module_init_tests_first) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1661028173.9695654 xmlsec-1.3.13/tests/data/0000755000175100001710000000000014300243516014542 5ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/tests/data/deskey.bin0000644000175100001710000000003114300243501016504 0ustar00runnerdocker012345670123456701234567 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/tests/data/doc.xml0000644000175100001710000000024714300243501016026 0ustar00runnerdocker Hello, World! ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/tests/data/dsacert.der0000644000175100001710000000210014300243501016646 0ustar00runnerdocker0‚<0‚æ  ¯¢‹¹3­Ú®0  *†H†÷ 0œ1 0 UUS10U California1=0;U 4XML Security Library (http://www.aleksey.com/xmlsec)10U Aleksey Sanin1!0 *†H†÷  xmlsec@aleksey.com0  140523175426Z21140429175426Z0Ç1 0 UUS10U California1=0;U 4XML Security Library (http://www.aleksey.com/xmlsec)1)0'U  Test Third Level DSA Certificate10U Aleksey Sanin1!0 *†H†÷  xmlsec@aleksey.com0ð0¨*†HÎ80œAÈ1ü:?¿Es !¯ «w‡¼&z÷=åHßbG@W%¿W¹-»Ö\áüæ Š!â¢TU%½–j93I”C«š¨É{_N=^2n3p6É@3Ã9›§Ûgæó ÔéA¡Üˆ?LWKv¾Í퉖…-¯ÿ~—”ݲ½ÍB‘‘Eþ­{×=œˆ&•dìãC@:'H0É“uZ!÷UùΊÔjW•Ïó’Ã[Ñg¥—eþª$—ךSï.ˆ~˶Å4A…ý”O$N™\QÐôoÃ`£‚E0‚A0 U0ÿ0, `†H†øB OpenSSL Generated Certificate0U¥XŸ)p-BGDÚ®g§º÷)e>0ãU#Û0Ø€þäìS$ð••ǵáDµ]9eZã~¡´¤±0®1 0 UUS10U California1=0;U 4XML Security Library (http://www.aleksey.com/xmlsec)10U Root CA10U Aleksey Sanin1!0 *†H†÷  xmlsec@aleksey.com‚ ¯¢‹¹3­Ú­0  *†H†÷ A~¥äï²4­¤ÙñE-ÅÒ—ÛšK™«Tãwn—³Éœ£8’}²cÆÒmˆ§½LZkøù¦Oÿ³­h`Ü ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/tests/data/dsakey.der0000644000175100001710000000037214300243501016512 0ustar00runnerdocker0÷AÈ1ü:?¿Es !¯ «w‡¼&z÷=åHßbG@W%¿W¹-»Ö\áüæ Š!â¢TU%½–j93I”C«š¨É{_N=^2n3p6É@3Ã9›§Ûgæó ÔéA¡Üˆ?LWKv¾Í퉖…-¯ÿ~—”ݲ½ÍB‘‘Eþ­{×=œˆ&•dìã@:'H0É“uZ!÷UùΊÔjW•Ïó’Ã[Ñg¥—eþª$—ךSï.ˆ~˶Å4A…ý”O$N™\QÐôoÃ`¤Ÿá~i_B}=U9W<¯././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/tests/data/enc-bad-in.xml0000644000175100001710000001754714300243501017171 0ustar00runnerdocker MyNextCar CreditApplication MYNEXTCAR VW 409D03 MyNextCar 2018-11-20T09:37:45Z 7f0842cc-8d47-4955-be31-c61d07ee490b VW
VCI_MNA_0000070250 Car Chantilly
14839 Stonecroft Center Ct Chantilly VA US 20151
MyNextCar MNA 7039562100 CAR
N
2017 Q7 CAR New 0 Prestige 64300.0 MSRP 64300.0 Selling Price 113456789 NationalId John Q Public
999 Washington Ave Apt #332 Front Royal VA US 22630 01 10 Own
21 E 9th Ave Boulder CO US 80301-7577 07 11 Own
3032852402 3032852405 7203554444 JohnQPublic@anydomain.org 1967-07-31 0 UPS
1775 Wiehle Ave. Reston VA US 20190
9500.0 Driver 01 05 Current
FedEx 4000.00 Driver 04 09 Previous 1252.52 1500.00 1 Consents to Credit Check
123435325 NationalId Lisa C Public
999 Lewis Street Front Royal VA US 22630 5 0 Own
5401110000 5401110073 public@test.com 1963-04-20 Christendom College
999 Christendom Dr Front Royal VA US 22630
6200.00 Professor 5 0 Current
1252.52 1 Consents to Credit Check
R 0.00 66 5000.00 INDIVCOAPP 2000.00 MyNextCar 1978 Bonneville Pontiac Coupe
././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/tests/data/enc1-in.xml0000644000175100001710000000024714300243501016513 0ustar00runnerdocker Hello, World! ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/tests/data/enc1-out.xml0000644000175100001710000000203114300243501016705 0ustar00runnerdocker UrTgE0UxQa8xevs4SyRA0rsibEz/ZFDjCBD+t4pKSdajB/cefYObZzqq2l41Q6R/ tqYLht5hEBh26AHfjmQSJAL+eChXOt/EaOf63zzJedO90HGqIQyzOeOPURAl3Li8 ivPyLVyocJDeVNeh7W+7kYwpFQ6PLuQxWsFFQXVoRAWbXHpZkSzVheR+5RpYJRTb 1UYXKxu8jg4NqbjucVMDIxUOzsVCDRyk8R8sQrM7D/H/N0y7DAY8oX/WZ45xLwUy DY/U86tTpTn95NwHD10SLyrL6rpXdbEuoIQHhWLwV9uQxnJA/Pn1KZ+xXK/fePfP 26PBo/hUrN5pm5U8ycc4iw== 2pb5Mxd0f+AW56Cs3MfQ9HJkUVeliSi1hVCNCVHTKeMyC2VL6lPhQ9+L01aSeTSY ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/tests/data/enc2-in.xml0000644000175100001710000000010114300243501016501 0ustar00runnerdocker test ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/tests/data/enc2-out.xml0000644000175100001710000000204414300243501016712 0ustar00runnerdocker HJwrfL7kOIB0QaldMJdza1HitpLCjw+eoult1C6yExDXJ09zKaSQER+pUL9Vt5fm d4Oitsf0CUNkjG1xWJdFsftqUIuvYGnkUNhT0vtqoYbdhJkCcB9cCwvTrww2+VTF NIasTdechlSD1qQOR8uf6+S94Ae4PVSfWU+5YLTJFpMjR+OT7f6BSbYNv1By6Cko G39WTSKTRcVDzcMxRepAGb59r508yKIJhwabCf3Opu+Ams7ia7BH4oa4ro9YSWwm hAJ0CN4a6b5odcRbNvuHcwWSxpoysWKbOROQ0H4xC4nGZeL/AXlpSc8eNuNG+g6D CTBwsOXCAEJYXPkTrnB3qQ== 4m5BRKEswOe8JISY7NrPGLBYv7Ay5pBV+nG6it51gz0= ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/tests/data/enc3-in.xml0000644000175100001710000000010314300243501016504 0ustar00runnerdocker test ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/tests/data/enc3-out.xml0000644000175100001710000000200414300243501016707 0ustar00runnerdocker HJwrfL7kOIB0QaldMJdza1HitpLCjw+eoult1C6yExDXJ09zKaSQER+pUL9Vt5fm d4Oitsf0CUNkjG1xWJdFsftqUIuvYGnkUNhT0vtqoYbdhJkCcB9cCwvTrww2+VTF NIasTdechlSD1qQOR8uf6+S94Ae4PVSfWU+5YLTJFpMjR+OT7f6BSbYNv1By6Cko G39WTSKTRcVDzcMxRepAGb59r508yKIJhwabCf3Opu+Ams7ia7BH4oa4ro9YSWwm hAJ0CN4a6b5odcRbNvuHcwWSxpoysWKbOROQ0H4xC4nGZeL/AXlpSc8eNuNG+g6D CTBwsOXCAEJYXPkTrnB3qQ== 4m5BRKEswOe8JISY7NrPGLBYv7Ay5pBV+nG6it51gz0= ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/tests/data/enc_template.xml0000644000175100001710000000056214300243501017721 0ustar00runnerdocker ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/tests/data/rsacert.pem0000644000175100001710000001125714300243501016710 0ustar00runnerdockerCertificate: Data: Version: 3 (0x2) Serial Number: 5 (0x5) Signature Algorithm: md5WithRSAEncryption Issuer: C=US, ST=California, L=Sunnyvale, O=XML Security Library (http://www.aleksey.com/xmlsec), OU=Root Certificate, CN=Aleksey Sanin/emailAddress=xmlsec@aleksey.com Validity Not Before: Mar 31 04:02:22 2003 GMT Not After : Mar 28 04:02:22 2013 GMT Subject: C=US, ST=California, O=XML Security Library (http://www.aleksey.com/xmlsec), OU=Examples RSA Certificate, CN=Aleksey Sanin/emailAddress=xmlsec@aleksey.com Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public Key: (2048 bit) Modulus (2048 bit): 00:97:b8:fe:b4:3f:83:35:78:16:89:04:ec:2b:61: 8c:bf:c4:5f:00:81:4a:45:e6:d9:cd:e9:e2:3c:97: 3b:45:ad:aa:e6:8d:0b:77:71:07:01:4f:7c:f9:7d: e2:19:aa:dd:91:59:f4:f1:cf:3d:ba:78:46:96:11: 9c:b6:5b:46:39:73:55:23:aa:f7:9e:00:5c:e5:e9: 49:ec:3b:9c:3f:84:99:3a:90:ad:df:7e:64:86:c6: 26:72:ce:31:08:79:7e:13:15:b8:e5:bf:d6:56:02: 8d:60:21:4c:27:18:64:fb:fb:55:70:f6:33:bd:2f: 55:70:d5:5e:7e:99:ae:a4:e0:aa:45:47:13:a8:30: d5:a0:8a:9d:cc:20:ec:e4:8e:51:c9:54:c5:7f:3e: 66:2d:74:bf:a3:7a:f8:f3:ec:94:57:39:b4:ac:00: 75:62:61:54:b4:d0:e0:52:86:f8:5e:77:ec:50:43: 9c:d2:ba:a7:8c:62:5a:bc:b2:fe:f3:cc:62:7e:23: 60:6b:c7:51:49:37:78:7e:25:15:30:ab:fa:b4:ae: 25:8f:22:fc:a3:48:7f:f2:0a:8a:6e:e0:fe:8d:f0: 01:ed:c6:33:cc:6b:a1:fd:a6:80:ef:06:8c:af:f6: 40:3a:8e:42:14:20:61:12:1f:e3:fc:05:b1:05:d5: 65:c3 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Basic Constraints: CA:FALSE Netscape Comment: OpenSSL Generated Certificate X509v3 Subject Key Identifier: 24:84:2C:F2:D4:59:20:62:8B:2E:5C:86:90:A3:AA:30:BA:27:1A:9C X509v3 Authority Key Identifier: keyid:B4:B9:EF:9A:E6:97:0E:68:65:1E:98:CE:FA:55:0D:89:06:DB:4C:7C DirName:/C=US/ST=California/L=Sunnyvale/O=XML Security Library (http://www.aleksey.com/xmlsec)/OU=Root Certificate/CN=Aleksey Sanin/emailAddress=xmlsec@aleksey.com serial:00 Signature Algorithm: md5WithRSAEncryption b5:3f:9b:32:31:4a:ff:2f:84:3b:a8:9b:11:5c:a6:5c:f0:76: 52:d9:6e:f4:90:ad:fa:0d:90:c1:98:d5:4a:12:dd:82:6b:37: e8:d9:2d:62:92:c9:61:37:98:86:8f:a4:49:6a:5e:25:d0:18: 69:30:0f:98:8f:43:58:89:31:b2:3b:05:e2:ef:c7:a6:71:5f: f7:fe:73:c5:a7:b2:cd:2e:73:53:71:7d:a8:4c:68:1a:32:1b: 5e:48:2f:8f:9b:7a:a3:b5:f3:67:e8:b1:a2:89:4e:b2:4d:1b: 79:9c:ff:f0:0d:19:4f:4e:b1:03:3d:99:f0:44:b7:8a:0b:34: 9d:83 -----BEGIN CERTIFICATE----- MIIE3zCCBEigAwIBAgIBBTANBgkqhkiG9w0BAQQFADCByzELMAkGA1UEBhMCVVMx EzARBgNVBAgTCkNhbGlmb3JuaWExEjAQBgNVBAcTCVN1bm55dmFsZTE9MDsGA1UE ChM0WE1MIFNlY3VyaXR5IExpYnJhcnkgKGh0dHA6Ly93d3cuYWxla3NleS5jb20v eG1sc2VjKTEZMBcGA1UECxMQUm9vdCBDZXJ0aWZpY2F0ZTEWMBQGA1UEAxMNQWxl a3NleSBTYW5pbjEhMB8GCSqGSIb3DQEJARYSeG1sc2VjQGFsZWtzZXkuY29tMB4X DTAzMDMzMTA0MDIyMloXDTEzMDMyODA0MDIyMlowgb8xCzAJBgNVBAYTAlVTMRMw EQYDVQQIEwpDYWxpZm9ybmlhMT0wOwYDVQQKEzRYTUwgU2VjdXJpdHkgTGlicmFy eSAoaHR0cDovL3d3dy5hbGVrc2V5LmNvbS94bWxzZWMpMSEwHwYDVQQLExhFeGFt cGxlcyBSU0EgQ2VydGlmaWNhdGUxFjAUBgNVBAMTDUFsZWtzZXkgU2FuaW4xITAf BgkqhkiG9w0BCQEWEnhtbHNlY0BhbGVrc2V5LmNvbTCCASIwDQYJKoZIhvcNAQEB BQADggEPADCCAQoCggEBAJe4/rQ/gzV4FokE7CthjL/EXwCBSkXm2c3p4jyXO0Wt quaNC3dxBwFPfPl94hmq3ZFZ9PHPPbp4RpYRnLZbRjlzVSOq954AXOXpSew7nD+E mTqQrd9+ZIbGJnLOMQh5fhMVuOW/1lYCjWAhTCcYZPv7VXD2M70vVXDVXn6ZrqTg qkVHE6gw1aCKncwg7OSOUclUxX8+Zi10v6N6+PPslFc5tKwAdWJhVLTQ4FKG+F53 7FBDnNK6p4xiWryy/vPMYn4jYGvHUUk3eH4lFTCr+rSuJY8i/KNIf/IKim7g/o3w Ae3GM8xrof2mgO8GjK/2QDqOQhQgYRIf4/wFsQXVZcMCAwEAAaOCAVcwggFTMAkG A1UdEwQCMAAwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRp ZmljYXRlMB0GA1UdDgQWBBQkhCzy1FkgYosuXIaQo6owuicanDCB+AYDVR0jBIHw MIHtgBS0ue+a5pcOaGUemM76VQ2JBttMfKGB0aSBzjCByzELMAkGA1UEBhMCVVMx EzARBgNVBAgTCkNhbGlmb3JuaWExEjAQBgNVBAcTCVN1bm55dmFsZTE9MDsGA1UE ChM0WE1MIFNlY3VyaXR5IExpYnJhcnkgKGh0dHA6Ly93d3cuYWxla3NleS5jb20v eG1sc2VjKTEZMBcGA1UECxMQUm9vdCBDZXJ0aWZpY2F0ZTEWMBQGA1UEAxMNQWxl a3NleSBTYW5pbjEhMB8GCSqGSIb3DQEJARYSeG1sc2VjQGFsZWtzZXkuY29tggEA MA0GCSqGSIb3DQEBBAUAA4GBALU/mzIxSv8vhDuomxFcplzwdlLZbvSQrfoNkMGY 1UoS3YJrN+jZLWKSyWE3mIaPpElqXiXQGGkwD5iPQ1iJMbI7BeLvx6ZxX/f+c8Wn ss0uc1NxfahMaBoyG15IL4+beqO182fosaKJTrJNG3mc//ANGU9OsQM9mfBEt4oL NJ2D -----END CERTIFICATE----- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/tests/data/rsakey.pem0000644000175100001710000000321314300243501016534 0ustar00runnerdocker-----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEAl7j+tD+DNXgWiQTsK2GMv8RfAIFKRebZzeniPJc7Ra2q5o0L d3EHAU98+X3iGardkVn08c89unhGlhGctltGOXNVI6r3ngBc5elJ7DucP4SZOpCt 335khsYmcs4xCHl+ExW45b/WVgKNYCFMJxhk+/tVcPYzvS9VcNVefpmupOCqRUcT qDDVoIqdzCDs5I5RyVTFfz5mLXS/o3r48+yUVzm0rAB1YmFUtNDgUob4XnfsUEOc 0rqnjGJavLL+88xifiNga8dRSTd4fiUVMKv6tK4ljyL8o0h/8gqKbuD+jfAB7cYz zGuh/aaA7waMr/ZAOo5CFCBhEh/j/AWxBdVlwwIDAQABAoIBAQCAvt6DnZF9gdW9 l4vAlBqXb88d4phgELCp5tmviLUnP2NSGEWuqR7Eoeru2z9NgIxblvYfazh6Ty22 kmNk6rcAcTnB9oYAcVZjUj8EUuEXlTFhXPvuNpafNu3RZd59znqJP1mSu+LpQWku NZMlabHnkTLDlGf7FXtvL9/rlgV4qk3QcDVF793JFszWrtK3mnld3KHQ6cuo9iSm 0rQKtkDjeHsRell8qTQvfBsgG1q2bv8QWT45/eQrra9mMbGTr3DbnXvoeJmTj1VN XJV7tBNllxxPahlYMByJaf/Tuva5j6HWUEIfYky5ihr2z1P/fNQ2OSCM6SQHpkiG EXQDueXBAoGBAMfW7KcmToEQEcTiqfey6C1LOLoemcX0/ROUktPq/5JQJRRrT4t7 XevLX0ed8sLyR5T29XQtdnuV0DJfvcJD+6ZwfOcQ+f6ZzCaNXJP97JtEt5kSWY01 Ei+nphZ0RFvPb04V3qDU9dElU26GR36CRBYJyM2WQPx4v+/YyDSZH9kLAoGBAMJc ZBU8pRbIia/FFOHUlS3v5P18nVmXyOd0fvRq0ZelaQCebTZ4K9wjnCfw//yzkb2Z 0vZFNB+xVBKB0Pt6nVvnSNzxdQ8EAXVFwHtXa25FUyP2RERQgTvmajqmgWjZsDYp 6GHcK3ZhmdmscQHF/Q2Uo4scvBcheahm9IXiNskpAoGAXelEgTBhSAmTMCEMmti6 fz6QQ/bJcNu2apMxhOE0hT+gjT34vaWV9481EWTKho5w0TJVGumaem1mz6VqeXaV Nhw6tiOmN91ysNNRpEJ6BGWAmjCjYNaF21s/k+HDlhmfRuTEIHSzqDuQP6pewrbY 5Dpo4SQxGfRsznvjacRj0Q0CgYBN247oBvQnDUxCkhNMZ8kersOvW5T4x9neBge5 R3UQZ12Jtu0O7dK8C7PJODyDcTeHmTAuIQjBTVrdUw1xP+v7XcoNX9hBnJws6zUw 85MAiFrGxCcSqqEqaqHRPtQGOXXiLKV/ViA++tgTn4VhbXtyTkG5P1iFd45xjFSV sUm7CQKBgDn92tHxzePly1L1mK584TkVryx4cP9RFHpebnmNduGwwjnRuYipoj8y pPPAkVbbaA3f9OB2go48rN0Ft9nHdlqgh9BpIKCVtkIb1XN0K3Oa/8BW8W/GAiNG HJcsrOtIrGVRdlyJG6bDaN8T49DnhOcsqMbf+IkIvfh50VeE9L/e -----END RSA PRIVATE KEY----- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/tests/data/rsapub.pem0000644000175100001710000000070314300243501016533 0ustar00runnerdocker-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAl7j+tD+DNXgWiQTsK2GM v8RfAIFKRebZzeniPJc7Ra2q5o0Ld3EHAU98+X3iGardkVn08c89unhGlhGctltG OXNVI6r3ngBc5elJ7DucP4SZOpCt335khsYmcs4xCHl+ExW45b/WVgKNYCFMJxhk +/tVcPYzvS9VcNVefpmupOCqRUcTqDDVoIqdzCDs5I5RyVTFfz5mLXS/o3r48+yU Vzm0rAB1YmFUtNDgUob4XnfsUEOc0rqnjGJavLL+88xifiNga8dRSTd4fiUVMKv6 tK4ljyL8o0h/8gqKbuD+jfAB7cYzzGuh/aaA7waMr/ZAOo5CFCBhEh/j/AWxBdVl wwIDAQAB -----END PUBLIC KEY----- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/tests/data/sign1-in.xml0000644000175100001710000000150714300243501016706 0ustar00runnerdocker Hello, World! ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/tests/data/sign1-out.xml0000644000175100001710000000231214300243501017102 0ustar00runnerdocker Hello, World! 9H/rQr2Axe9hYTV2n/tCp+3UIQQ= Mx4psIy9/UY+u8QBJRDrwQWKRaCGz0WOVftyDzAe6WHAFSjMNr7qb2ojq9kdipT8 Oub5q2OQ7mzdSLiiejkrO1VeqM/90yEIGI4En6KEB6ArEzw+iq4N1wm6EptcyxXx M9StAOOa9ilWYqR9Tfx3SW1urUIuKYgUitxsONiUHBVaW6HeX51bsXoTF++4ZI+D jiPBjN4HHmr0cbJ6BXk91S27ffZIfp1Qj5nL9onFLUGbR6EFgu2luiRzQbPuM2tP XxyI7GZ8AfHnRJK28ARvBC9oi+O1ej20S79CIV7gdBxbLbFprozBHAwOEC57YgJc x+YEjSjcO7SBIR1FiUA7pw== rsakey.pem ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/tests/data/sign2-in.xml0000644000175100001710000000030514300243501016702 0ustar00runnerdocker Hello, World! ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/tests/data/sign2-out.xml0000644000175100001710000000214714300243501017111 0ustar00runnerdocker Hello, World! HjY8ilZAIEM2tBbPn5mYO1ieIX4= SIaj/6KY3C1SmDXU2++Gm31U1xTadFp04WhBgfsJFbxrL+q7GKSKN9kfQ+UpN9+i D5fWmuavXEHe4Gw6RMaMEkq2URQo7F68+d5J/ajq8/l4n+xE6/reGScVwT6L4dEP XXVJcAi2ZnQ3O7GTNvNGCPibL9mUcyCWBFZ92Uemtc/vJFCQ7ZyKMdMfACgxOwyN T/9971oog241/2doudhonc0I/3mgPYWkZdX6yvr62mEjnG+oUZkhWYJ4ewZJ4hM4 JjbFqZO+OEzDRSbw3DkmuBA/mtlx+3t13SESfEub5hqoMdVmtth/eTb64dsPdl9r 3k1ACVX9f8aHfQQdJOmLFQ== rsakey.pem ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/tests/data/sign3-in.xml0000644000175100001710000000030514300243501016703 0ustar00runnerdocker Hello, World! ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/tests/data/sign3-out.xml0000644000175100001710000000544214300243501017113 0ustar00runnerdocker Hello, World! HjY8ilZAIEM2tBbPn5mYO1ieIX4= SIaj/6KY3C1SmDXU2++Gm31U1xTadFp04WhBgfsJFbxrL+q7GKSKN9kfQ+UpN9+i D5fWmuavXEHe4Gw6RMaMEkq2URQo7F68+d5J/ajq8/l4n+xE6/reGScVwT6L4dEP XXVJcAi2ZnQ3O7GTNvNGCPibL9mUcyCWBFZ92Uemtc/vJFCQ7ZyKMdMfACgxOwyN T/9971oog241/2doudhonc0I/3mgPYWkZdX6yvr62mEjnG+oUZkhWYJ4ewZJ4hM4 JjbFqZO+OEzDRSbw3DkmuBA/mtlx+3t13SESfEub5hqoMdVmtth/eTb64dsPdl9r 3k1ACVX9f8aHfQQdJOmLFQ== MIIE3zCCBEigAwIBAgIBBTANBgkqhkiG9w0BAQQFADCByzELMAkGA1UEBhMCVVMx EzARBgNVBAgTCkNhbGlmb3JuaWExEjAQBgNVBAcTCVN1bm55dmFsZTE9MDsGA1UE ChM0WE1MIFNlY3VyaXR5IExpYnJhcnkgKGh0dHA6Ly93d3cuYWxla3NleS5jb20v eG1sc2VjKTEZMBcGA1UECxMQUm9vdCBDZXJ0aWZpY2F0ZTEWMBQGA1UEAxMNQWxl a3NleSBTYW5pbjEhMB8GCSqGSIb3DQEJARYSeG1sc2VjQGFsZWtzZXkuY29tMB4X DTAzMDMzMTA0MDIyMloXDTEzMDMyODA0MDIyMlowgb8xCzAJBgNVBAYTAlVTMRMw EQYDVQQIEwpDYWxpZm9ybmlhMT0wOwYDVQQKEzRYTUwgU2VjdXJpdHkgTGlicmFy eSAoaHR0cDovL3d3dy5hbGVrc2V5LmNvbS94bWxzZWMpMSEwHwYDVQQLExhFeGFt cGxlcyBSU0EgQ2VydGlmaWNhdGUxFjAUBgNVBAMTDUFsZWtzZXkgU2FuaW4xITAf BgkqhkiG9w0BCQEWEnhtbHNlY0BhbGVrc2V5LmNvbTCCASIwDQYJKoZIhvcNAQEB BQADggEPADCCAQoCggEBAJe4/rQ/gzV4FokE7CthjL/EXwCBSkXm2c3p4jyXO0Wt quaNC3dxBwFPfPl94hmq3ZFZ9PHPPbp4RpYRnLZbRjlzVSOq954AXOXpSew7nD+E mTqQrd9+ZIbGJnLOMQh5fhMVuOW/1lYCjWAhTCcYZPv7VXD2M70vVXDVXn6ZrqTg qkVHE6gw1aCKncwg7OSOUclUxX8+Zi10v6N6+PPslFc5tKwAdWJhVLTQ4FKG+F53 7FBDnNK6p4xiWryy/vPMYn4jYGvHUUk3eH4lFTCr+rSuJY8i/KNIf/IKim7g/o3w Ae3GM8xrof2mgO8GjK/2QDqOQhQgYRIf4/wFsQXVZcMCAwEAAaOCAVcwggFTMAkG A1UdEwQCMAAwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRp ZmljYXRlMB0GA1UdDgQWBBQkhCzy1FkgYosuXIaQo6owuicanDCB+AYDVR0jBIHw MIHtgBS0ue+a5pcOaGUemM76VQ2JBttMfKGB0aSBzjCByzELMAkGA1UEBhMCVVMx EzARBgNVBAgTCkNhbGlmb3JuaWExEjAQBgNVBAcTCVN1bm55dmFsZTE9MDsGA1UE ChM0WE1MIFNlY3VyaXR5IExpYnJhcnkgKGh0dHA6Ly93d3cuYWxla3NleS5jb20v eG1sc2VjKTEZMBcGA1UECxMQUm9vdCBDZXJ0aWZpY2F0ZTEWMBQGA1UEAxMNQWxl a3NleSBTYW5pbjEhMB8GCSqGSIb3DQEJARYSeG1sc2VjQGFsZWtzZXkuY29tggEA MA0GCSqGSIb3DQEBBAUAA4GBALU/mzIxSv8vhDuomxFcplzwdlLZbvSQrfoNkMGY 1UoS3YJrN+jZLWKSyWE3mIaPpElqXiXQGGkwD5iPQ1iJMbI7BeLvx6ZxX/f+c8Wn ss0uc1NxfahMaBoyG15IL4+beqO182fosaKJTrJNG3mc//ANGU9OsQM9mfBEt4oL NJ2D ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/tests/data/sign4-in.xml0000644000175100001710000000035714300243501016713 0ustar00runnerdocker Hello, World! ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/tests/data/sign4-out.xml0000644000175100001710000000561614300243501017117 0ustar00runnerdocker Hello, World! ERS7F/ifxZoyTe0mhco+HeAEKGo= G+mZNFqh9w0wIkDSbuYwvVDu7CMP8PEsw7jfwiZBC8nyF3loAtYKKAkdi6Zy3dJs tU8qKfhzvabmCjdIrGkFTdtlCNCVKDMzwogFtxEX4Oh77X6jjx4b22XNJx4AbnUG JV/EcsD+po8s5qVEXw62lRRd8cMDafbzOA/rBH96CMNgZhzxyaF9VRLa/vbt1ht2 hE1KkdZCB4Y0Lv3QyeDL2jax3NFks9FUv8IqoWYQSvywdMLY2ZMiQ9UpPeVfMizi trd5zDUSD/s3hyIEs4gD5NJF3HZPD/Fe2Zw1PBPj9eLADdEzcdueyCdPJ2YioFIi 1sMW/qPDhR/DoOJwGpUxwQ== MIIE3zCCBEigAwIBAgIBBTANBgkqhkiG9w0BAQQFADCByzELMAkGA1UEBhMCVVMx EzARBgNVBAgTCkNhbGlmb3JuaWExEjAQBgNVBAcTCVN1bm55dmFsZTE9MDsGA1UE ChM0WE1MIFNlY3VyaXR5IExpYnJhcnkgKGh0dHA6Ly93d3cuYWxla3NleS5jb20v eG1sc2VjKTEZMBcGA1UECxMQUm9vdCBDZXJ0aWZpY2F0ZTEWMBQGA1UEAxMNQWxl a3NleSBTYW5pbjEhMB8GCSqGSIb3DQEJARYSeG1sc2VjQGFsZWtzZXkuY29tMB4X DTAzMDMzMTA0MDIyMloXDTEzMDMyODA0MDIyMlowgb8xCzAJBgNVBAYTAlVTMRMw EQYDVQQIEwpDYWxpZm9ybmlhMT0wOwYDVQQKEzRYTUwgU2VjdXJpdHkgTGlicmFy eSAoaHR0cDovL3d3dy5hbGVrc2V5LmNvbS94bWxzZWMpMSEwHwYDVQQLExhFeGFt cGxlcyBSU0EgQ2VydGlmaWNhdGUxFjAUBgNVBAMTDUFsZWtzZXkgU2FuaW4xITAf BgkqhkiG9w0BCQEWEnhtbHNlY0BhbGVrc2V5LmNvbTCCASIwDQYJKoZIhvcNAQEB BQADggEPADCCAQoCggEBAJe4/rQ/gzV4FokE7CthjL/EXwCBSkXm2c3p4jyXO0Wt quaNC3dxBwFPfPl94hmq3ZFZ9PHPPbp4RpYRnLZbRjlzVSOq954AXOXpSew7nD+E mTqQrd9+ZIbGJnLOMQh5fhMVuOW/1lYCjWAhTCcYZPv7VXD2M70vVXDVXn6ZrqTg qkVHE6gw1aCKncwg7OSOUclUxX8+Zi10v6N6+PPslFc5tKwAdWJhVLTQ4FKG+F53 7FBDnNK6p4xiWryy/vPMYn4jYGvHUUk3eH4lFTCr+rSuJY8i/KNIf/IKim7g/o3w Ae3GM8xrof2mgO8GjK/2QDqOQhQgYRIf4/wFsQXVZcMCAwEAAaOCAVcwggFTMAkG A1UdEwQCMAAwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRp ZmljYXRlMB0GA1UdDgQWBBQkhCzy1FkgYosuXIaQo6owuicanDCB+AYDVR0jBIHw MIHtgBS0ue+a5pcOaGUemM76VQ2JBttMfKGB0aSBzjCByzELMAkGA1UEBhMCVVMx EzARBgNVBAgTCkNhbGlmb3JuaWExEjAQBgNVBAcTCVN1bm55dmFsZTE9MDsGA1UE ChM0WE1MIFNlY3VyaXR5IExpYnJhcnkgKGh0dHA6Ly93d3cuYWxla3NleS5jb20v eG1sc2VjKTEZMBcGA1UECxMQUm9vdCBDZXJ0aWZpY2F0ZTEWMBQGA1UEAxMNQWxl a3NleSBTYW5pbjEhMB8GCSqGSIb3DQEJARYSeG1sc2VjQGFsZWtzZXkuY29tggEA MA0GCSqGSIb3DQEBBAUAA4GBALU/mzIxSv8vhDuomxFcplzwdlLZbvSQrfoNkMGY 1UoS3YJrN+jZLWKSyWE3mIaPpElqXiXQGGkwD5iPQ1iJMbI7BeLvx6ZxX/f+c8Wn ss0uc1NxfahMaBoyG15IL4+beqO182fosaKJTrJNG3mc//ANGU9OsQM9mfBEt4oL NJ2D ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/tests/data/sign5-in.xml0000644000175100001710000000030514300243501016705 0ustar00runnerdocker Hello, World! ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/tests/data/sign5-out.xml0000644000175100001710000000621214300243501017111 0ustar00runnerdocker Hello, World! HjY8ilZAIEM2tBbPn5mYO1ieIX4= SIaj/6KY3C1SmDXU2++Gm31U1xTadFp04WhBgfsJFbxrL+q7GKSKN9kfQ+UpN9+i D5fWmuavXEHe4Gw6RMaMEkq2URQo7F68+d5J/ajq8/l4n+xE6/reGScVwT6L4dEP XXVJcAi2ZnQ3O7GTNvNGCPibL9mUcyCWBFZ92Uemtc/vJFCQ7ZyKMdMfACgxOwyN T/9971oog241/2doudhonc0I/3mgPYWkZdX6yvr62mEjnG+oUZkhWYJ4ewZJ4hM4 JjbFqZO+OEzDRSbw3DkmuBA/mtlx+3t13SESfEub5hqoMdVmtth/eTb64dsPdl9r 3k1ACVX9f8aHfQQdJOmLFQ== Test Issuer 1 MIIE3zCCBEigAwIBAgIBBTANBgkqhkiG9w0BAQQFADCByzELMAkGA1UEBhMCVVMx EzARBgNVBAgTCkNhbGlmb3JuaWExEjAQBgNVBAcTCVN1bm55dmFsZTE9MDsGA1UE ChM0WE1MIFNlY3VyaXR5IExpYnJhcnkgKGh0dHA6Ly93d3cuYWxla3NleS5jb20v eG1sc2VjKTEZMBcGA1UECxMQUm9vdCBDZXJ0aWZpY2F0ZTEWMBQGA1UEAxMNQWxl a3NleSBTYW5pbjEhMB8GCSqGSIb3DQEJARYSeG1sc2VjQGFsZWtzZXkuY29tMB4X DTAzMDMzMTA0MDIyMloXDTEzMDMyODA0MDIyMlowgb8xCzAJBgNVBAYTAlVTMRMw EQYDVQQIEwpDYWxpZm9ybmlhMT0wOwYDVQQKEzRYTUwgU2VjdXJpdHkgTGlicmFy eSAoaHR0cDovL3d3dy5hbGVrc2V5LmNvbS94bWxzZWMpMSEwHwYDVQQLExhFeGFt cGxlcyBSU0EgQ2VydGlmaWNhdGUxFjAUBgNVBAMTDUFsZWtzZXkgU2FuaW4xITAf BgkqhkiG9w0BCQEWEnhtbHNlY0BhbGVrc2V5LmNvbTCCASIwDQYJKoZIhvcNAQEB BQADggEPADCCAQoCggEBAJe4/rQ/gzV4FokE7CthjL/EXwCBSkXm2c3p4jyXO0Wt quaNC3dxBwFPfPl94hmq3ZFZ9PHPPbp4RpYRnLZbRjlzVSOq954AXOXpSew7nD+E mTqQrd9+ZIbGJnLOMQh5fhMVuOW/1lYCjWAhTCcYZPv7VXD2M70vVXDVXn6ZrqTg qkVHE6gw1aCKncwg7OSOUclUxX8+Zi10v6N6+PPslFc5tKwAdWJhVLTQ4FKG+F53 7FBDnNK6p4xiWryy/vPMYn4jYGvHUUk3eH4lFTCr+rSuJY8i/KNIf/IKim7g/o3w Ae3GM8xrof2mgO8GjK/2QDqOQhQgYRIf4/wFsQXVZcMCAwEAAaOCAVcwggFTMAkG A1UdEwQCMAAwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRp ZmljYXRlMB0GA1UdDgQWBBQkhCzy1FkgYosuXIaQo6owuicanDCB+AYDVR0jBIHw MIHtgBS0ue+a5pcOaGUemM76VQ2JBttMfKGB0aSBzjCByzELMAkGA1UEBhMCVVMx EzARBgNVBAgTCkNhbGlmb3JuaWExEjAQBgNVBAcTCVN1bm55dmFsZTE9MDsGA1UE ChM0WE1MIFNlY3VyaXR5IExpYnJhcnkgKGh0dHA6Ly93d3cuYWxla3NleS5jb20v eG1sc2VjKTEZMBcGA1UECxMQUm9vdCBDZXJ0aWZpY2F0ZTEWMBQGA1UEAxMNQWxl a3NleSBTYW5pbjEhMB8GCSqGSIb3DQEJARYSeG1sc2VjQGFsZWtzZXkuY29tggEA MA0GCSqGSIb3DQEBBAUAA4GBALU/mzIxSv8vhDuomxFcplzwdlLZbvSQrfoNkMGY 1UoS3YJrN+jZLWKSyWE3mIaPpElqXiXQGGkwD5iPQ1iJMbI7BeLvx6ZxX/f+c8Wn ss0uc1NxfahMaBoyG15IL4+beqO182fosaKJTrJNG3mc//ANGU9OsQM9mfBEt4oL NJ2D emailAddress=xmlsec@aleksey.com,CN=Aleksey Sanin,OU=Examples RSA Certificate,O=XML Security Library (http://www.aleksey.com/xmlsec),ST=California,C=US JIQs8tRZIGKLLlyGkKOqMLonGpw= ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/tests/data/sign6-in.bin0000644000175100001710000000005014300243501016653 0ustar00runnerdocker¨f4dP‚Óõ.ÁïĆ«Cì·>Ž££Å¹qc±-¤Bß>ºÑ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/tests/data/sign6-out.bin0000644000175100001710000000040014300243501017053 0ustar00runnerdockerh˱‚ú`e‰xåÅirÖÑQš êU_GÌ'¤c£>›27¿^`§pû˜ËÒ± 'â ì²<Ï@˜=à}O8}fyÂÄéì‡öÁÞý–*o«®É{Ì“yš€o’ë^h| ›<™_—Ëâ7éuÃú_Ìt/sTb  Ó“'´¤zËLDÛㄈ6éJ[çÎÀ±™{Æ:ÿtý«^2÷ž¤ÌTŽ~bÛšºMú½ì)z»‰×²Q¬¯ÜDÍ 6’úo¹Ù–$Î¦ÏøäBb60õÒa±oŒ‹lˆvhµhúú¶6íQÄïúðÉ.^˜PQSž¯Ayä•V ¥dÂ*¶×$À 2¡././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/tests/data/sign_template.xml0000644000175100001710000000342014300243501020110 0ustar00runnerdocker ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/tests/test_constants.py0000644000175100001710000000273114300243501017253 0ustar00runnerdocker"""Test constants from :mod:`xmlsec.constants` module.""" import pytest import xmlsec def _constants(typename): return list( sorted( ( getattr(xmlsec.constants, name) for name in dir(xmlsec.constants) if type(getattr(xmlsec.constants, name)).__name__ == typename ), key=lambda t: t.name.lower(), ) ) @pytest.mark.parametrize('transform', _constants('__Transform'), ids=repr) def test_transform_str(transform): """Test string representation of ``xmlsec.constants.__Transform``.""" assert str(transform) == '{}, {}'.format(transform.name, transform.href) @pytest.mark.parametrize('transform', _constants('__Transform'), ids=repr) def test_transform_repr(transform): """Test raw string representation of ``xmlsec.constants.__Transform``.""" assert repr(transform) == '__Transform({!r}, {!r}, {})'.format(transform.name, transform.href, transform.usage) @pytest.mark.parametrize('keydata', _constants('__KeyData'), ids=repr) def test_keydata_str(keydata): """Test string representation of ``xmlsec.constants.__KeyData``.""" assert str(keydata) == '{}, {}'.format(keydata.name, keydata.href) @pytest.mark.parametrize('keydata', _constants('__KeyData'), ids=repr) def test_keydata_repr(keydata): """Test raw string representation of ``xmlsec.constants.__KeyData``.""" assert repr(keydata) == '__KeyData({!r}, {!r})'.format(keydata.name, keydata.href) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/tests/test_doc_examples.py0000644000175100001710000000175414300243501017706 0ustar00runnerdocker"""Run tests over code examples in the documentation.""" import contextlib import os import runpy import sys import pytest if sys.version_info >= (3, 4): from pathlib import Path else: # python2.7 compat from _pytest.pathlib import Path examples_dir = Path(__file__, '../../doc/source/examples').resolve() examples = sorted(examples_dir.glob('*.py')) @contextlib.contextmanager def cd(where_to): """ Temporarily change the working directory. Restore the current working dir after exiting the context. """ curr = Path.cwd() try: os.chdir(str(where_to)) yield finally: os.chdir(str(curr)) @pytest.mark.parametrize('example', examples, ids=lambda p: p.name) def test_doc_example(example): """ Verify example scripts included in the docs are up to date. Execute each script in :file:`docs/source/examples`, not raising any errors is good enough. """ with cd(example.parent): runpy.run_path(str(example)) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/tests/test_ds.py0000644000175100001710000003463014300243501015650 0ustar00runnerdockerimport unittest import xmlsec from tests import base consts = xmlsec.constants class TestSignContext(base.TestMemoryLeaks): def test_init(self): ctx = xmlsec.SignatureContext(manager=xmlsec.KeysManager()) del ctx def test_init_no_keys_manager(self): ctx = xmlsec.SignatureContext() del ctx def test_init_bad_args(self): with self.assertRaisesRegex(TypeError, 'KeysManager required'): xmlsec.SignatureContext(manager='foo') def test_no_key(self): ctx = xmlsec.SignatureContext(manager=xmlsec.KeysManager()) self.assertIsNone(ctx.key) def test_del_key(self): ctx = xmlsec.SignatureContext(manager=xmlsec.KeysManager()) ctx.key = xmlsec.Key.from_file(self.path("rsakey.pem"), format=consts.KeyDataFormatPem) del ctx.key self.assertIsNone(ctx.key) def test_set_key(self): ctx = xmlsec.SignatureContext(manager=xmlsec.KeysManager()) ctx.key = xmlsec.Key.from_file(self.path("rsakey.pem"), format=consts.KeyDataFormatPem) self.assertIsNotNone(ctx.key) def test_set_key_bad_type(self): ctx = xmlsec.SignatureContext(manager=xmlsec.KeysManager()) with self.assertRaisesRegex(TypeError, r'instance of \*xmlsec.Key\* expected.'): ctx.key = '' def test_set_invalid_key(self): ctx = xmlsec.SignatureContext(manager=xmlsec.KeysManager()) with self.assertRaisesRegex(TypeError, 'empty key.'): ctx.key = xmlsec.Key() def test_register_id(self): ctx = xmlsec.SignatureContext() root = self.load_xml("sign_template.xml") sign = xmlsec.template.create(root, consts.TransformExclC14N, consts.TransformRsaSha1, "Id") ctx.register_id(sign, "Id") def test_register_id_bad_args(self): ctx = xmlsec.SignatureContext() with self.assertRaises(TypeError): ctx.register_id('') def test_register_id_with_namespace_without_attribute(self): ctx = xmlsec.SignatureContext() root = self.load_xml("sign_template.xml") sign = xmlsec.template.create(root, consts.TransformExclC14N, consts.TransformRsaSha1, "Id") with self.assertRaisesRegex(xmlsec.Error, 'missing attribute.'): ctx.register_id(sign, "Id", id_ns='foo') def test_sign_bad_args(self): ctx = xmlsec.SignatureContext() ctx.key = xmlsec.Key.from_file(self.path("rsakey.pem"), format=consts.KeyDataFormatPem) with self.assertRaises(TypeError): ctx.sign('') def test_sign_fail(self): ctx = xmlsec.SignatureContext() ctx.key = xmlsec.Key.from_file(self.path("rsakey.pem"), format=consts.KeyDataFormatPem) with self.assertRaisesRegex(xmlsec.Error, 'failed to sign'): ctx.sign(self.load_xml('sign1-in.xml')) def test_sign_case1(self): """Should sign a pre-constructed template file using a key from a PEM file.""" root = self.load_xml("sign1-in.xml") sign = xmlsec.tree.find_node(root, consts.NodeSignature) self.assertIsNotNone(sign) ctx = xmlsec.SignatureContext() ctx.key = xmlsec.Key.from_file(self.path("rsakey.pem"), format=consts.KeyDataFormatPem) self.assertIsNotNone(ctx.key) ctx.key.name = 'rsakey.pem' self.assertEqual("rsakey.pem", ctx.key.name) ctx.sign(sign) self.assertEqual(self.load_xml("sign1-out.xml"), root) def test_sign_case2(self): """Should sign a dynamicaly constructed template file using a key from a PEM file.""" root = self.load_xml("sign2-in.xml") sign = xmlsec.template.create(root, consts.TransformExclC14N, consts.TransformRsaSha1) self.assertIsNotNone(sign) root.append(sign) ref = xmlsec.template.add_reference(sign, consts.TransformSha1) xmlsec.template.add_transform(ref, consts.TransformEnveloped) ki = xmlsec.template.ensure_key_info(sign) xmlsec.template.add_key_name(ki) ctx = xmlsec.SignatureContext() ctx.key = xmlsec.Key.from_file(self.path("rsakey.pem"), format=consts.KeyDataFormatPem) self.assertIsNotNone(ctx.key) ctx.key.name = 'rsakey.pem' self.assertEqual("rsakey.pem", ctx.key.name) ctx.sign(sign) self.assertEqual(self.load_xml("sign2-out.xml"), root) def test_sign_case3(self): """Should sign a file using a dynamicaly created template, key from PEM and an X509 cert.""" root = self.load_xml("sign3-in.xml") sign = xmlsec.template.create(root, consts.TransformExclC14N, consts.TransformRsaSha1) self.assertIsNotNone(sign) root.append(sign) ref = xmlsec.template.add_reference(sign, consts.TransformSha1) xmlsec.template.add_transform(ref, consts.TransformEnveloped) ki = xmlsec.template.ensure_key_info(sign) xmlsec.template.add_x509_data(ki) ctx = xmlsec.SignatureContext() ctx.key = xmlsec.Key.from_file(self.path("rsakey.pem"), format=consts.KeyDataFormatPem) self.assertIsNotNone(ctx.key) ctx.key.load_cert_from_file(self.path('rsacert.pem'), consts.KeyDataFormatPem) ctx.key.name = 'rsakey.pem' self.assertEqual("rsakey.pem", ctx.key.name) ctx.sign(sign) self.assertEqual(self.load_xml("sign3-out.xml"), root) def test_sign_case4(self): """Should sign a file using a dynamically created template, key from PEM and an X509 cert with custom ns.""" root = self.load_xml("sign4-in.xml") xmlsec.tree.add_ids(root, ["ID"]) elem_id = root.get('ID', None) if elem_id: elem_id = '#' + elem_id sign = xmlsec.template.create(root, consts.TransformExclC14N, consts.TransformRsaSha1, ns="ds") self.assertIsNotNone(sign) root.append(sign) ref = xmlsec.template.add_reference(sign, consts.TransformSha1, uri=elem_id) xmlsec.template.add_transform(ref, consts.TransformEnveloped) xmlsec.template.add_transform(ref, consts.TransformExclC14N) ki = xmlsec.template.ensure_key_info(sign) xmlsec.template.add_x509_data(ki) ctx = xmlsec.SignatureContext() ctx.key = xmlsec.Key.from_file(self.path("rsakey.pem"), format=consts.KeyDataFormatPem) self.assertIsNotNone(ctx.key) ctx.key.load_cert_from_file(self.path('rsacert.pem'), consts.KeyDataFormatPem) ctx.key.name = 'rsakey.pem' self.assertEqual("rsakey.pem", ctx.key.name) ctx.sign(sign) self.assertEqual(self.load_xml("sign4-out.xml"), root) def test_sign_case5(self): """Should sign a file using a dynamicaly created template, key from PEM file and an X509 certificate.""" root = self.load_xml("sign5-in.xml") sign = xmlsec.template.create(root, consts.TransformExclC14N, consts.TransformRsaSha1) self.assertIsNotNone(sign) root.append(sign) ref = xmlsec.template.add_reference(sign, consts.TransformSha1) xmlsec.template.add_transform(ref, consts.TransformEnveloped) ki = xmlsec.template.ensure_key_info(sign) x509 = xmlsec.template.add_x509_data(ki) xmlsec.template.x509_data_add_subject_name(x509) xmlsec.template.x509_data_add_certificate(x509) xmlsec.template.x509_data_add_ski(x509) x509_issuer_serial = xmlsec.template.x509_data_add_issuer_serial(x509) xmlsec.template.x509_issuer_serial_add_issuer_name(x509_issuer_serial, 'Test Issuer') xmlsec.template.x509_issuer_serial_add_serial_number(x509_issuer_serial, '1') ctx = xmlsec.SignatureContext() ctx.key = xmlsec.Key.from_file(self.path("rsakey.pem"), format=consts.KeyDataFormatPem) self.assertIsNotNone(ctx.key) ctx.key.load_cert_from_file(self.path('rsacert.pem'), consts.KeyDataFormatPem) ctx.key.name = 'rsakey.pem' self.assertEqual("rsakey.pem", ctx.key.name) ctx.sign(sign) self.assertEqual(self.load_xml("sign5-out.xml"), root) def test_sign_binary_bad_args(self): ctx = xmlsec.SignatureContext() ctx.key = xmlsec.Key.from_file(self.path("rsakey.pem"), format=consts.KeyDataFormatPem) with self.assertRaises(TypeError): ctx.sign_binary(bytes=1, transform='') def test_sign_binary_no_key(self): ctx = xmlsec.SignatureContext() with self.assertRaisesRegex(xmlsec.Error, 'Sign key is not specified.'): ctx.sign_binary(bytes=b'', transform=consts.TransformRsaSha1) @unittest.skipIf(not hasattr(consts, 'TransformXslt'), reason='XSLT transformations not enabled') def test_sign_binary_invalid_signature_method(self): ctx = xmlsec.SignatureContext() ctx.key = xmlsec.Key.from_file(self.path("rsakey.pem"), format=consts.KeyDataFormatPem) with self.assertRaisesRegex(xmlsec.Error, 'incompatible signature method'): ctx.sign_binary(bytes=b'', transform=consts.TransformXslt) def test_sign_binary(self): ctx = xmlsec.SignatureContext() ctx.key = xmlsec.Key.from_file(self.path("rsakey.pem"), format=consts.KeyDataFormatPem) self.assertIsNotNone(ctx.key) ctx.key.name = 'rsakey.pem' self.assertEqual("rsakey.pem", ctx.key.name) sign = ctx.sign_binary(self.load("sign6-in.bin"), consts.TransformRsaSha1) self.assertEqual(self.load("sign6-out.bin"), sign) def test_sign_binary_twice_not_possible(self): ctx = xmlsec.SignatureContext() ctx.key = xmlsec.Key.from_file(self.path("rsakey.pem"), format=consts.KeyDataFormatPem) data = self.load('sign6-in.bin') ctx.sign_binary(data, consts.TransformRsaSha1) with self.assertRaisesRegex(xmlsec.Error, 'Signature context already used; it is designed for one use only.'): ctx.sign_binary(data, consts.TransformRsaSha1) def test_verify_bad_args(self): ctx = xmlsec.SignatureContext() ctx.key = xmlsec.Key.from_file(self.path("rsakey.pem"), format=consts.KeyDataFormatPem) with self.assertRaises(TypeError): ctx.verify('') def test_verify_fail(self): ctx = xmlsec.SignatureContext() ctx.key = xmlsec.Key.from_file(self.path("rsakey.pem"), format=consts.KeyDataFormatPem) with self.assertRaisesRegex(xmlsec.Error, 'failed to verify'): ctx.verify(self.load_xml('sign1-in.xml')) def test_verify_case_1(self): self.check_verify(1) def test_verify_case_2(self): self.check_verify(2) def test_verify_case_3(self): self.check_verify(3) def test_verify_case_4(self): self.check_verify(4) def test_verify_case_5(self): self.check_verify(5) def check_verify(self, i): root = self.load_xml("sign%d-out.xml" % i) xmlsec.tree.add_ids(root, ["ID"]) sign = xmlsec.tree.find_node(root, consts.NodeSignature) self.assertIsNotNone(sign) self.assertEqual(consts.NodeSignature, sign.tag.partition("}")[2]) ctx = xmlsec.SignatureContext() ctx.key = xmlsec.Key.from_file(self.path("rsapub.pem"), format=consts.KeyDataFormatPem) self.assertIsNotNone(ctx.key) ctx.key.name = 'rsapub.pem' self.assertEqual("rsapub.pem", ctx.key.name) ctx.verify(sign) def test_validate_binary_sign(self): ctx = xmlsec.SignatureContext() ctx.key = xmlsec.Key.from_file(self.path("rsakey.pem"), format=consts.KeyDataFormatPem) self.assertIsNotNone(ctx.key) ctx.key.name = 'rsakey.pem' self.assertEqual("rsakey.pem", ctx.key.name) ctx.verify_binary(self.load("sign6-in.bin"), consts.TransformRsaSha1, self.load("sign6-out.bin")) def test_validate_binary_sign_fail(self): ctx = xmlsec.SignatureContext() ctx.key = xmlsec.Key.from_file(self.path("rsakey.pem"), format=consts.KeyDataFormatPem) self.assertIsNotNone(ctx.key) ctx.key.name = 'rsakey.pem' self.assertEqual("rsakey.pem", ctx.key.name) with self.assertRaises(xmlsec.Error): ctx.verify_binary(self.load("sign6-in.bin"), consts.TransformRsaSha1, b"invalid") def test_enable_reference_transform(self): ctx = xmlsec.SignatureContext() ctx.key = xmlsec.Key.from_file(self.path("rsakey.pem"), format=consts.KeyDataFormatPem) ctx.enable_reference_transform(consts.TransformRsaSha1) def test_enable_reference_transform_bad_args(self): ctx = xmlsec.SignatureContext() ctx.key = xmlsec.Key.from_file(self.path('rsakey.pem'), format=consts.KeyDataFormatPem) with self.assertRaises(TypeError): ctx.enable_reference_transform('') with self.assertRaises(TypeError): ctx.enable_reference_transform(0) with self.assertRaises(TypeError): ctx.enable_reference_transform(consts.KeyDataAes) def test_enable_signature_transform(self): ctx = xmlsec.SignatureContext() ctx.key = xmlsec.Key.from_file(self.path("rsakey.pem"), format=consts.KeyDataFormatPem) ctx.enable_signature_transform(consts.TransformRsaSha1) def test_enable_signature_transform_bad_args(self): ctx = xmlsec.SignatureContext() ctx.key = xmlsec.Key.from_file(self.path('rsakey.pem'), format=consts.KeyDataFormatPem) with self.assertRaises(TypeError): ctx.enable_signature_transform('') with self.assertRaises(TypeError): ctx.enable_signature_transform(0) with self.assertRaises(TypeError): ctx.enable_signature_transform(consts.KeyDataAes) def test_set_enabled_key_data(self): ctx = xmlsec.SignatureContext() ctx.key = xmlsec.Key.from_file(self.path("rsakey.pem"), format=consts.KeyDataFormatPem) ctx.set_enabled_key_data([consts.KeyDataAes]) def test_set_enabled_key_data_empty(self): ctx = xmlsec.SignatureContext() ctx.key = xmlsec.Key.from_file(self.path("rsakey.pem"), format=consts.KeyDataFormatPem) ctx.set_enabled_key_data([]) def test_set_enabled_key_data_bad_args(self): ctx = xmlsec.SignatureContext() ctx.key = xmlsec.Key.from_file(self.path('rsakey.pem'), format=consts.KeyDataFormatPem) with self.assertRaises(TypeError): ctx.set_enabled_key_data(0) def test_set_enabled_key_data_bad_list(self): ctx = xmlsec.SignatureContext() ctx.key = xmlsec.Key.from_file(self.path('rsakey.pem'), format=consts.KeyDataFormatPem) with self.assertRaisesRegex(TypeError, 'expected list of KeyData constants.'): ctx.set_enabled_key_data('foo') ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/tests/test_enc.py0000644000175100001710000002674614300243501016020 0ustar00runnerdockerimport os import tempfile from lxml import etree import xmlsec from tests import base consts = xmlsec.constants class TestEncryptionContext(base.TestMemoryLeaks): def test_init(self): ctx = xmlsec.EncryptionContext(manager=xmlsec.KeysManager()) del ctx def test_init_no_keys_manager(self): ctx = xmlsec.EncryptionContext() del ctx def test_init_bad_args(self): with self.assertRaisesRegex(TypeError, 'KeysManager required'): xmlsec.EncryptionContext(manager='foo') def test_no_key(self): ctx = xmlsec.EncryptionContext(manager=xmlsec.KeysManager()) self.assertIsNone(ctx.key) def test_get_key(self): ctx = xmlsec.EncryptionContext(manager=xmlsec.KeysManager()) self.assertIsNone(ctx.key) ctx.key = xmlsec.Key.from_file(self.path("rsacert.pem"), format=consts.KeyDataFormatCertPem) self.assertIsNotNone(ctx.key) def test_del_key(self): ctx = xmlsec.EncryptionContext(manager=xmlsec.KeysManager()) ctx.key = xmlsec.Key.from_file(self.path("rsacert.pem"), format=consts.KeyDataFormatCertPem) del ctx.key self.assertIsNone(ctx.key) def test_set_key(self): ctx = xmlsec.EncryptionContext(manager=xmlsec.KeysManager()) ctx.key = xmlsec.Key.from_file(self.path("rsacert.pem"), format=consts.KeyDataFormatCertPem) self.assertIsNotNone(ctx.key) def test_set_key_bad_type(self): ctx = xmlsec.EncryptionContext(manager=xmlsec.KeysManager()) with self.assertRaisesRegex(TypeError, r'instance of \*xmlsec.Key\* expected.'): ctx.key = '' def test_set_invalid_key(self): ctx = xmlsec.EncryptionContext(manager=xmlsec.KeysManager()) with self.assertRaisesRegex(TypeError, 'empty key.'): ctx.key = xmlsec.Key() def test_encrypt_xml(self): root = self.load_xml('enc1-in.xml') enc_data = xmlsec.template.encrypted_data_create(root, consts.TransformAes128Cbc, type=consts.TypeEncElement, ns="xenc") xmlsec.template.encrypted_data_ensure_cipher_value(enc_data) ki = xmlsec.template.encrypted_data_ensure_key_info(enc_data, ns="dsig") ek = xmlsec.template.add_encrypted_key(ki, consts.TransformRsaOaep) xmlsec.template.encrypted_data_ensure_cipher_value(ek) data = root.find('./Data') self.assertIsNotNone(data) manager = xmlsec.KeysManager() manager.add_key(xmlsec.Key.from_file(self.path("rsacert.pem"), format=consts.KeyDataFormatCertPem)) ctx = xmlsec.EncryptionContext(manager) ctx.key = xmlsec.Key.generate(consts.KeyDataAes, 128, consts.KeyDataTypeSession) encrypted = ctx.encrypt_xml(enc_data, data) self.assertIsNotNone(encrypted) enc_method = xmlsec.tree.find_child(enc_data, consts.NodeEncryptionMethod, consts.EncNs) self.assertIsNotNone(enc_method) self.assertEqual("http://www.w3.org/2001/04/xmlenc#aes128-cbc", enc_method.get("Algorithm")) ki = xmlsec.tree.find_child(enc_data, consts.NodeKeyInfo, consts.DSigNs) self.assertIsNotNone(ki) enc_method2 = xmlsec.tree.find_node(ki, consts.NodeEncryptionMethod, consts.EncNs) self.assertIsNotNone(enc_method2) self.assertEqual("http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p", enc_method2.get("Algorithm")) cipher_value = xmlsec.tree.find_node(ki, consts.NodeCipherValue, consts.EncNs) self.assertIsNotNone(cipher_value) def test_encrypt_xml_bad_args(self): ctx = xmlsec.EncryptionContext() with self.assertRaises(TypeError): ctx.encrypt_xml('', 0) def test_encrypt_xml_bad_template(self): ctx = xmlsec.EncryptionContext() with self.assertRaisesRegex(xmlsec.Error, 'unsupported `Type`, it should be `element` or `content`'): ctx.encrypt_xml(etree.Element('root'), etree.Element('node')) def test_encrypt_xml_bad_template_bad_type_attribute(self): ctx = xmlsec.EncryptionContext() with self.assertRaisesRegex(xmlsec.Error, 'unsupported `Type`, it should be `element` or `content`'): root = etree.Element('root') root.attrib['Type'] = 'foo' ctx.encrypt_xml(root, etree.Element('node')) def test_encrypt_xml_fail(self): ctx = xmlsec.EncryptionContext() with self.assertRaisesRegex(xmlsec.Error, 'failed to encrypt xml'): root = etree.Element('root') root.attrib['Type'] = consts.TypeEncElement ctx.encrypt_xml(root, etree.Element('node')) def test_encrypt_binary(self): root = self.load_xml('enc2-in.xml') enc_data = xmlsec.template.encrypted_data_create( root, consts.TransformAes128Cbc, type=consts.TypeEncContent, ns="xenc", mime_type="binary/octet-stream" ) xmlsec.template.encrypted_data_ensure_cipher_value(enc_data) ki = xmlsec.template.encrypted_data_ensure_key_info(enc_data, ns="dsig") ek = xmlsec.template.add_encrypted_key(ki, consts.TransformRsaOaep) xmlsec.template.encrypted_data_ensure_cipher_value(ek) manager = xmlsec.KeysManager() manager.add_key(xmlsec.Key.from_file(self.path("rsacert.pem"), format=consts.KeyDataFormatCertPem)) ctx = xmlsec.EncryptionContext(manager) ctx.key = xmlsec.Key.generate(consts.KeyDataAes, 128, consts.KeyDataTypeSession) encrypted = ctx.encrypt_binary(enc_data, b'test') self.assertIsNotNone(encrypted) self.assertEqual("{%s}%s" % (consts.EncNs, consts.NodeEncryptedData), encrypted.tag) enc_method = xmlsec.tree.find_child(enc_data, consts.NodeEncryptionMethod, consts.EncNs) self.assertIsNotNone(enc_method) self.assertEqual("http://www.w3.org/2001/04/xmlenc#aes128-cbc", enc_method.get("Algorithm")) ki = xmlsec.tree.find_child(enc_data, consts.NodeKeyInfo, consts.DSigNs) self.assertIsNotNone(ki) enc_method2 = xmlsec.tree.find_node(ki, consts.NodeEncryptionMethod, consts.EncNs) self.assertIsNotNone(enc_method2) self.assertEqual("http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p", enc_method2.get("Algorithm")) cipher_value = xmlsec.tree.find_node(ki, consts.NodeCipherValue, consts.EncNs) self.assertIsNotNone(cipher_value) def test_encrypt_binary_bad_args(self): ctx = xmlsec.EncryptionContext() with self.assertRaises(TypeError): ctx.encrypt_binary('', 0) def test_encrypt_binary_bad_template(self): ctx = xmlsec.EncryptionContext() with self.assertRaisesRegex(xmlsec.Error, 'failed to encrypt binary'): ctx.encrypt_binary(etree.Element('root'), b'data') def test_encrypt_uri(self): root = self.load_xml('enc2-in.xml') enc_data = xmlsec.template.encrypted_data_create( root, consts.TransformAes128Cbc, type=consts.TypeEncContent, ns="xenc", mime_type="binary/octet-stream" ) xmlsec.template.encrypted_data_ensure_cipher_value(enc_data) ki = xmlsec.template.encrypted_data_ensure_key_info(enc_data, ns="dsig") ek = xmlsec.template.add_encrypted_key(ki, consts.TransformRsaOaep) xmlsec.template.encrypted_data_ensure_cipher_value(ek) manager = xmlsec.KeysManager() manager.add_key(xmlsec.Key.from_file(self.path("rsacert.pem"), format=consts.KeyDataFormatCertPem)) ctx = xmlsec.EncryptionContext(manager) ctx.key = xmlsec.Key.generate(consts.KeyDataAes, 128, consts.KeyDataTypeSession) with tempfile.NamedTemporaryFile(delete=False) as tmpfile: tmpfile.write(b'test') encrypted = ctx.encrypt_binary(enc_data, 'file://' + tmpfile.name) self.assertIsNotNone(encrypted) self.assertEqual("{%s}%s" % (consts.EncNs, consts.NodeEncryptedData), encrypted.tag) enc_method = xmlsec.tree.find_child(enc_data, consts.NodeEncryptionMethod, consts.EncNs) self.assertIsNotNone(enc_method) self.assertEqual("http://www.w3.org/2001/04/xmlenc#aes128-cbc", enc_method.get("Algorithm")) ki = xmlsec.tree.find_child(enc_data, consts.NodeKeyInfo, consts.DSigNs) self.assertIsNotNone(ki) enc_method2 = xmlsec.tree.find_node(ki, consts.NodeEncryptionMethod, consts.EncNs) self.assertIsNotNone(enc_method2) self.assertEqual("http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p", enc_method2.get("Algorithm")) cipher_value = xmlsec.tree.find_node(ki, consts.NodeCipherValue, consts.EncNs) self.assertIsNotNone(cipher_value) def test_encrypt_uri_bad_args(self): ctx = xmlsec.EncryptionContext() with self.assertRaises(TypeError): ctx.encrypt_uri('', 0) def test_encrypt_uri_fail(self): ctx = xmlsec.EncryptionContext() with self.assertRaisesRegex(xmlsec.Error, 'failed to encrypt URI'): ctx.encrypt_uri(etree.Element('root'), '') def test_decrypt1(self): self.check_decrypt(1) def test_decrypt2(self): self.check_decrypt(2) def test_decrypt_key(self): root = self.load_xml('enc3-out.xml') enc_key = xmlsec.tree.find_child(root, consts.NodeEncryptedKey, consts.EncNs) self.assertIsNotNone(enc_key) manager = xmlsec.KeysManager() manager.add_key(xmlsec.Key.from_file(self.path("rsakey.pem"), format=consts.KeyDataFormatPem)) ctx = xmlsec.EncryptionContext(manager) keydata = ctx.decrypt(enc_key) ctx.reset() root.remove(enc_key) ctx.key = xmlsec.Key.from_binary_data(consts.KeyDataAes, keydata) enc_data = xmlsec.tree.find_child(root, consts.NodeEncryptedData, consts.EncNs) self.assertIsNotNone(enc_data) decrypted = ctx.decrypt(enc_data) self.assertIsNotNone(decrypted) self.assertEqual(self.load_xml("enc3-in.xml"), decrypted) def check_decrypt(self, i): root = self.load_xml('enc%d-out.xml' % i) enc_data = xmlsec.tree.find_child(root, consts.NodeEncryptedData, consts.EncNs) self.assertIsNotNone(enc_data) manager = xmlsec.KeysManager() manager.add_key(xmlsec.Key.from_file(self.path("rsakey.pem"), format=consts.KeyDataFormatPem)) ctx = xmlsec.EncryptionContext(manager) decrypted = ctx.decrypt(enc_data) self.assertIsNotNone(decrypted) self.assertEqual(self.load_xml("enc%d-in.xml" % i), root) def test_decrypt_bad_args(self): ctx = xmlsec.EncryptionContext() with self.assertRaises(TypeError): ctx.decrypt('') def check_no_segfault(self): namespaces = {'soap': 'http://schemas.xmlsoap.org/soap/envelope/'} manager = xmlsec.KeysManager() key = xmlsec.Key.from_file(self.path("rsacert.pem"), format=consts.KeyDataFormatCertPem) manager.add_key(key) template = self.load_xml('enc-bad-in.xml') enc_data = xmlsec.template.encrypted_data_create( template, xmlsec.Transform.AES128, type=xmlsec.EncryptionType.CONTENT, ns='xenc' ) xmlsec.template.encrypted_data_ensure_cipher_value(enc_data) key_info = xmlsec.template.encrypted_data_ensure_key_info(enc_data, ns='dsig') enc_key = xmlsec.template.add_encrypted_key(key_info, xmlsec.Transform.RSA_PKCS1) xmlsec.template.encrypted_data_ensure_cipher_value(enc_key) data = template.find('soap:Body', namespaces=namespaces) enc_ctx = xmlsec.EncryptionContext(manager) enc_ctx.key = xmlsec.Key.generate(xmlsec.KeyData.AES, 192, xmlsec.KeyDataType.SESSION) self.assertRaises(Exception, enc_ctx.encrypt_xml(enc_data, data)) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/tests/test_keys.py0000644000175100001710000002345214300243501016215 0ustar00runnerdockerimport copy import tempfile import xmlsec from tests import base consts = xmlsec.constants class TestKeys(base.TestMemoryLeaks): def test_key_from_memory(self): key = xmlsec.Key.from_memory(self.load("rsakey.pem"), format=consts.KeyDataFormatPem) self.assertIsNotNone(key) def test_key_from_memory_with_bad_args(self): with self.assertRaises(TypeError): xmlsec.Key.from_memory(1, format="") def test_key_from_memory_invalid_data(self): with self.assertRaisesRegex(xmlsec.Error, '.*cannot load key.*'): xmlsec.Key.from_memory(b'foo', format=consts.KeyDataFormatPem) def test_key_from_file(self): key = xmlsec.Key.from_file(self.path("rsakey.pem"), format=consts.KeyDataFormatPem) self.assertIsNotNone(key) def test_key_from_file_with_bad_args(self): with self.assertRaises(TypeError): xmlsec.Key.from_file(1, format="") def test_key_from_invalid_file(self): with self.assertRaisesRegex(xmlsec.Error, '.*cannot read key.*'): with tempfile.NamedTemporaryFile() as tmpfile: tmpfile.write(b'foo') xmlsec.Key.from_file(tmpfile.name, format=consts.KeyDataFormatPem) def test_key_from_fileobj(self): with open(self.path("rsakey.pem"), "rb") as fobj: key = xmlsec.Key.from_file(fobj, format=consts.KeyDataFormatPem) self.assertIsNotNone(key) def test_key_from_invalid_fileobj(self): with tempfile.NamedTemporaryFile(delete=False) as tmpfile: tmpfile.write(b'foo') with self.assertRaisesRegex(xmlsec.Error, '.*cannot read key.*'), open(tmpfile.name) as fp: xmlsec.Key.from_file(fp, format=consts.KeyDataFormatPem) def test_generate(self): key = xmlsec.Key.generate(klass=consts.KeyDataAes, size=256, type=consts.KeyDataTypeSession) self.assertIsNotNone(key) def test_generate_with_bad_args(self): with self.assertRaises(TypeError): xmlsec.Key.generate(klass="", size="", type="") def test_generate_invalid_size(self): with self.assertRaisesRegex(xmlsec.Error, '.*cannot generate key.*'): xmlsec.Key.generate(klass=consts.KeyDataAes, size=0, type=consts.KeyDataTypeSession) def test_from_binary_file(self): key = xmlsec.Key.from_binary_file(klass=consts.KeyDataDes, filename=self.path("deskey.bin")) self.assertIsNotNone(key) def test_from_binary_file_with_bad_args(self): with self.assertRaises(TypeError): xmlsec.Key.from_binary_file(klass="", filename=1) def test_from_invalid_binary_file(self): with self.assertRaisesRegex(xmlsec.Error, '.*cannot read key.*'): with tempfile.NamedTemporaryFile() as tmpfile: tmpfile.write(b'foo') xmlsec.Key.from_binary_file(klass=consts.KeyDataDes, filename=tmpfile.name) def test_from_binary_data(self): key = xmlsec.Key.from_binary_data(klass=consts.KeyDataDes, data=self.load("deskey.bin")) self.assertIsNotNone(key) def test_from_binary_data_with_bad_args(self): with self.assertRaises(TypeError): xmlsec.Key.from_binary_data(klass="", data=1) def test_from_invalid_binary_data(self): with self.assertRaisesRegex(xmlsec.Error, '.*cannot read key.*'): xmlsec.Key.from_binary_data(klass=consts.KeyDataDes, data=b'') def test_load_cert_from_file(self): key = xmlsec.Key.from_file(self.path("rsakey.pem"), format=consts.KeyDataFormatPem) self.assertIsNotNone(key) key.load_cert_from_file(self.path("rsacert.pem"), format=consts.KeyDataFormatPem) def test_load_cert_from_file_with_bad_args(self): key = xmlsec.Key.from_file(self.path("rsakey.pem"), format=consts.KeyDataFormatPem) self.assertIsNotNone(key) with self.assertRaises(TypeError): key.load_cert_from_file(1, format="") def test_load_cert_from_invalid_file(self): key = xmlsec.Key.from_file(self.path("rsakey.pem"), format=consts.KeyDataFormatPem) self.assertIsNotNone(key) with self.assertRaisesRegex(xmlsec.Error, '.*cannot load cert.*'): with tempfile.NamedTemporaryFile() as tmpfile: tmpfile.write(b'foo') key.load_cert_from_file(tmpfile.name, format=consts.KeyDataFormatPem) def test_load_cert_from_fileobj(self): key = xmlsec.Key.from_file(self.path("rsakey.pem"), format=consts.KeyDataFormatPem) self.assertIsNotNone(key) with open(self.path("rsacert.pem"), "rb") as fobj: key.load_cert_from_file(fobj, format=consts.KeyDataFormatPem) def test_load_cert_from_fileobj_with_bad_args(self): key = xmlsec.Key.from_file(self.path("rsakey.pem"), format=consts.KeyDataFormatPem) self.assertIsNotNone(key) with self.assertRaises(TypeError), open(self.path("rsacert.pem"), "rb") as fobj: key.load_cert_from_file(fobj, format='') def test_load_cert_from_invalid_fileobj(self): key = xmlsec.Key.from_file(self.path("rsakey.pem"), format=consts.KeyDataFormatPem) self.assertIsNotNone(key) with tempfile.NamedTemporaryFile(delete=False) as tmpfile: tmpfile.write(b'foo') with self.assertRaisesRegex(xmlsec.Error, '.*cannot load cert.*'), open(tmpfile.name) as fp: key.load_cert_from_file(fp, format=consts.KeyDataFormatPem) def test_load_cert_from_memory(self): key = xmlsec.Key.from_file(self.path("rsakey.pem"), format=consts.KeyDataFormatPem) self.assertIsNotNone(key) key.load_cert_from_memory(self.load("rsacert.pem"), format=consts.KeyDataFormatPem) def test_load_cert_from_memory_with_bad_args(self): key = xmlsec.Key.from_file(self.path("rsakey.pem"), format=consts.KeyDataFormatPem) self.assertIsNotNone(key) with self.assertRaises(TypeError): key.load_cert_from_memory(1, format="") def test_load_cert_from_memory_invalid_data(self): key = xmlsec.Key.from_file(self.path("rsakey.pem"), format=consts.KeyDataFormatPem) self.assertIsNotNone(key) with self.assertRaisesRegex(xmlsec.Error, '.*cannot load cert.*'): key.load_cert_from_memory(b'', format=consts.KeyDataFormatPem) def test_get_name(self): key = xmlsec.Key.from_file(self.path("rsakey.pem"), format=consts.KeyDataFormatPem) self.assertIsNone(key.name) def test_get_name_invalid_key(self): key = xmlsec.Key() with self.assertRaisesRegex(ValueError, 'key is not ready'): key.name def test_del_name(self): key = xmlsec.Key.from_file(self.path("rsakey.pem"), format=consts.KeyDataFormatPem) key.name = "rsakey" del key.name self.assertIsNone(key.name) def test_set_name(self): key = xmlsec.Key.from_file(self.path("rsakey.pem"), format=consts.KeyDataFormatPem) key.name = "rsakey" self.assertEqual("rsakey", key.name) def test_set_name_invalid_key(self): key = xmlsec.Key() with self.assertRaisesRegex(ValueError, 'key is not ready'): key.name = 'foo' def test_copy(self): key = xmlsec.Key.from_file(self.path("rsakey.pem"), format=consts.KeyDataFormatPem) key2 = copy.copy(key) del key key2.load_cert_from_file(self.path("rsacert.pem"), format=consts.KeyDataFormatPem) class TestKeysManager(base.TestMemoryLeaks): def test_add_key(self): key = xmlsec.Key.from_file(self.path("rsakey.pem"), format=consts.KeyDataFormatPem) mngr = xmlsec.KeysManager() mngr.add_key(key) def test_add_key_with_bad_args(self): mngr = xmlsec.KeysManager() with self.assertRaises(TypeError): mngr.add_key("") def test_load_cert(self): mngr = xmlsec.KeysManager() mngr.add_key(xmlsec.Key.from_file(self.path("rsakey.pem"), format=consts.KeyDataFormatPem)) mngr.load_cert(self.path("rsacert.pem"), format=consts.KeyDataFormatPem, type=consts.KeyDataTypeTrusted) def test_load_cert_with_bad_args(self): mngr = xmlsec.KeysManager() mngr.add_key(xmlsec.Key.from_file(self.path("rsakey.pem"), format=consts.KeyDataFormatPem)) with self.assertRaisesRegex(xmlsec.Error, '.*cannot load cert.*'): with tempfile.NamedTemporaryFile() as tmpfile: tmpfile.write(b'foo') mngr.load_cert(tmpfile.name, format=consts.KeyDataFormatPem, type=consts.KeyDataTypeTrusted) def test_load_invalid_cert(self): mngr = xmlsec.KeysManager() mngr.add_key(xmlsec.Key.from_file(self.path("rsakey.pem"), format=consts.KeyDataFormatPem)) with self.assertRaises(TypeError): mngr.load_cert(1, format="", type="") def test_load_cert_from_memory(self): mngr = xmlsec.KeysManager() mngr.add_key(xmlsec.Key.from_file(self.path("rsakey.pem"), format=consts.KeyDataFormatPem)) mngr.load_cert_from_memory(self.load("rsacert.pem"), format=consts.KeyDataFormatPem, type=consts.KeyDataTypeTrusted) def test_load_cert_from_memory_with_bad_args(self): mngr = xmlsec.KeysManager() mngr.add_key(xmlsec.Key.from_file(self.path("rsakey.pem"), format=consts.KeyDataFormatPem)) with self.assertRaises(TypeError): mngr.load_cert_from_memory(1, format="", type="") def test_load_cert_from_memory_invalid_data(self): mngr = xmlsec.KeysManager() mngr.add_key(xmlsec.Key.from_file(self.path("rsakey.pem"), format=consts.KeyDataFormatPem)) with self.assertRaisesRegex(xmlsec.Error, '.*cannot load cert.*'): mngr.load_cert_from_memory(b'', format=consts.KeyDataFormatPem, type=consts.KeyDataTypeTrusted) def test_load_invalid_key(self): mngr = xmlsec.KeysManager() with self.assertRaises(ValueError): mngr.add_key(xmlsec.Key()) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/tests/test_main.py0000644000175100001710000001306314300243501016163 0ustar00runnerdockerimport sys from io import BytesIO from unittest import skipIf import xmlsec from tests import base from xmlsec import constants as consts class TestBase64LineSize(base.TestMemoryLeaks): def tearDown(self): xmlsec.base64_default_line_size(64) super(TestBase64LineSize, self).tearDown() def test_get_base64_default_line_size(self): self.assertEqual(xmlsec.base64_default_line_size(), 64) def test_set_base64_default_line_size_positional_arg(self): xmlsec.base64_default_line_size(0) self.assertEqual(xmlsec.base64_default_line_size(), 0) def test_set_base64_default_line_size_keyword_arg(self): xmlsec.base64_default_line_size(size=0) self.assertEqual(xmlsec.base64_default_line_size(), 0) def test_set_base64_default_line_size_with_bad_args(self): size = xmlsec.base64_default_line_size() for bad_size in (None, '', object()): with self.assertRaises(TypeError): xmlsec.base64_default_line_size(bad_size) self.assertEqual(xmlsec.base64_default_line_size(), size) def test_set_base64_default_line_size_rejects_negative_values(self): size = xmlsec.base64_default_line_size() with self.assertRaises(ValueError): xmlsec.base64_default_line_size(-1) self.assertEqual(xmlsec.base64_default_line_size(), size) class TestCallbacks(base.TestMemoryLeaks): def setUp(self): super().setUp() xmlsec.cleanup_callbacks() def _sign_doc(self): root = self.load_xml("doc.xml") sign = xmlsec.template.create(root, c14n_method=consts.TransformExclC14N, sign_method=consts.TransformRsaSha1) xmlsec.template.add_reference(sign, consts.TransformSha1, uri="cid:123456") ctx = xmlsec.SignatureContext() ctx.key = xmlsec.Key.from_file(self.path("rsakey.pem"), format=consts.KeyDataFormatPem) ctx.sign(sign) return sign def _expect_sign_failure(self): with self.assertRaisesRegex(xmlsec.Error, 'failed to sign'): self._sign_doc() def _mismatch_callbacks(self, match_cb=lambda filename: False): return [ match_cb, lambda filename: None, lambda none, buf: 0, lambda none: None, ] def _register_mismatch_callbacks(self, match_cb=lambda filename: False): xmlsec.register_callbacks(*self._mismatch_callbacks(match_cb)) def _register_match_callbacks(self): xmlsec.register_callbacks( lambda filename: filename == b'cid:123456', lambda filename: BytesIO(b''), lambda bio, buf: bio.readinto(buf), lambda bio: bio.close(), ) def _find(self, elem, *tags): try: return elem.xpath( './' + '/'.join('xmldsig:{}'.format(tag) for tag in tags), namespaces={ 'xmldsig': 'http://www.w3.org/2000/09/xmldsig#', }, )[0] except IndexError as e: raise KeyError(tags) from e def _verify_external_data_signature(self): signature = self._sign_doc() digest = self._find(signature, 'SignedInfo', 'Reference', 'DigestValue').text self.assertEqual(digest, 'VihZwVMGJ48NsNl7ertVHiURXk8=') def test_sign_external_data_no_callbacks_fails(self): self._expect_sign_failure() def test_sign_external_data_default_callbacks_fails(self): xmlsec.register_default_callbacks() self._expect_sign_failure() def test_sign_external_data_no_matching_callbacks_fails(self): self._register_mismatch_callbacks() self._expect_sign_failure() def test_sign_data_from_callbacks(self): self._register_match_callbacks() self._verify_external_data_signature() def test_sign_data_not_first_callback(self): bad_match_calls = 0 def match_cb(filename): nonlocal bad_match_calls bad_match_calls += 1 False for _ in range(2): self._register_mismatch_callbacks(match_cb) self._register_match_callbacks() for _ in range(2): self._register_mismatch_callbacks() self._verify_external_data_signature() self.assertEqual(bad_match_calls, 0) @skipIf(sys.platform == "win32", "unclear behaviour on windows") def test_failed_sign_because_default_callbacks(self): mismatch_calls = 0 def mismatch_cb(filename): nonlocal mismatch_calls mismatch_calls += 1 False # NB: These first two sets of callbacks should never get called, # because the default callbacks always match beforehand: self._register_match_callbacks() self._register_mismatch_callbacks(mismatch_cb) xmlsec.register_default_callbacks() self._register_mismatch_callbacks(mismatch_cb) self._register_mismatch_callbacks(mismatch_cb) self._expect_sign_failure() self.assertEqual(mismatch_calls, 2) def test_register_non_callables(self): for idx in range(4): cbs = self._mismatch_callbacks() cbs[idx] = None self.assertRaises(TypeError, xmlsec.register_callbacks, *cbs) def test_sign_external_data_fails_on_read_callback_wrong_returns(self): xmlsec.register_callbacks( lambda filename: filename == b'cid:123456', lambda filename: BytesIO(b''), lambda bio, buf: None, lambda bio: bio.close(), ) self._expect_sign_failure() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/tests/test_templates.py0000644000175100001710000002426314300243501017241 0ustar00runnerdockerimport unittest from lxml import etree import xmlsec from tests import base consts = xmlsec.constants class TestTemplates(base.TestMemoryLeaks): def test_create(self): root = self.load_xml("doc.xml") sign = xmlsec.template.create( root, c14n_method=consts.TransformExclC14N, sign_method=consts.TransformRsaSha1, id="Id", ns="test" ) self.assertEqual("Id", sign.get("Id")) self.assertEqual("test", sign.prefix) def test_create_bad_args(self): with self.assertRaises(TypeError): xmlsec.template.create('', c14n_method=consts.TransformExclC14N, sign_method=consts.TransformRsaSha1) def test_encrypt_data_create(self): root = self.load_xml("doc.xml") enc = xmlsec.template.encrypted_data_create( root, method=consts.TransformDes3Cbc, id="Id", type="Type", mime_type="MimeType", encoding="Encoding", ns="test" ) for a in ("Id", "Type", "MimeType", "Encoding"): self.assertEqual(a, enc.get(a)) self.assertEqual("test", enc.prefix) def test_ensure_key_info(self): root = self.load_xml("doc.xml") sign = xmlsec.template.create(root, c14n_method=consts.TransformExclC14N, sign_method=consts.TransformRsaSha1) ki = xmlsec.template.ensure_key_info(sign, id="Id") self.assertEqual("Id", ki.get("Id")) def test_ensure_key_info_fail(self): with self.assertRaisesRegex(xmlsec.Error, 'cannot ensure key info.'): xmlsec.template.ensure_key_info(etree.fromstring(b''), id="Id") def test_ensure_key_info_bad_args(self): with self.assertRaises(TypeError): xmlsec.template.ensure_key_info('', id=0) def test_add_encrypted_key(self): root = self.load_xml("doc.xml") sign = xmlsec.template.create(root, c14n_method=consts.TransformExclC14N, sign_method=consts.TransformRsaSha1) ki = xmlsec.template.ensure_key_info(sign) ek = xmlsec.template.add_encrypted_key(ki, consts.TransformRsaOaep) self.assertEqual(ek, xmlsec.tree.find_node(self.load_xml("sign_template.xml"), consts.NodeEncryptedKey, consts.EncNs)) ek2 = xmlsec.template.add_encrypted_key(ki, consts.TransformRsaOaep, id="Id", type="Type", recipient="Recipient") for a in ("Id", "Type", "Recipient"): self.assertEqual(a, ek2.get(a)) def test_add_key_name(self): root = self.load_xml("doc.xml") sign = xmlsec.template.create(root, c14n_method=consts.TransformExclC14N, sign_method=consts.TransformRsaSha1) ki = xmlsec.template.ensure_key_info(sign) kn = xmlsec.template.add_key_name(ki) self.assertEqual(kn, xmlsec.tree.find_node(self.load_xml("sign_template.xml"), consts.NodeKeyName, consts.DSigNs)) kn2 = xmlsec.template.add_key_name(ki, name="name") self.assertEqual("name", kn2.text) def test_add_key_name_none(self): root = self.load_xml("doc.xml") sign = xmlsec.template.create(root, c14n_method=consts.TransformExclC14N, sign_method=consts.TransformRsaSha1) ki = xmlsec.template.ensure_key_info(sign) kn2 = xmlsec.template.add_key_name(ki, name=None) self.assertEqual(kn2.text, None) print(etree.tostring(kn2)) def test_add_key_name_bad_args(self): with self.assertRaises(TypeError): xmlsec.template.add_key_name('') def test_add_reference(self): root = self.load_xml("doc.xml") sign = xmlsec.template.create(root, c14n_method=consts.TransformExclC14N, sign_method=consts.TransformRsaSha1) ref = xmlsec.template.add_reference(sign, consts.TransformSha1, id="Id", uri="URI", type="Type") for a in ("Id", "URI", "Type"): self.assertEqual(a, ref.get(a)) def test_add_reference_bad_args(self): with self.assertRaises(TypeError): xmlsec.template.add_reference('', consts.TransformSha1) with self.assertRaises(TypeError): xmlsec.template.add_reference(etree.Element('root'), '') def test_add_reference_fail(self): with self.assertRaisesRegex(xmlsec.Error, 'cannot add reference.'): xmlsec.template.add_reference(etree.Element('root'), consts.TransformSha1) def test_add_transform_bad_args(self): with self.assertRaises(TypeError): xmlsec.template.add_transform('', consts.TransformSha1) with self.assertRaises(TypeError): xmlsec.template.add_transform(etree.Element('root'), '') def test_add_key_value(self): root = self.load_xml("doc.xml") sign = xmlsec.template.create(root, c14n_method=consts.TransformExclC14N, sign_method=consts.TransformRsaSha1) ki = xmlsec.template.ensure_key_info(sign) kv = xmlsec.template.add_key_value(ki) self.assertEqual(kv, xmlsec.tree.find_node(self.load_xml("sign_template.xml"), consts.NodeKeyValue, consts.DSigNs)) def test_add_key_value_bad_args(self): with self.assertRaises(TypeError): xmlsec.template.add_key_value('') def test_add_x509_data(self): root = self.load_xml("doc.xml") sign = xmlsec.template.create(root, c14n_method=consts.TransformExclC14N, sign_method=consts.TransformRsaSha1) ki = xmlsec.template.ensure_key_info(sign) x509 = xmlsec.template.add_x509_data(ki) xmlsec.template.x509_data_add_certificate(x509) xmlsec.template.x509_data_add_crl(x509) issuer = xmlsec.template.x509_data_add_issuer_serial(x509) xmlsec.template.x509_data_add_ski(x509) xmlsec.template.x509_data_add_subject_name(x509) xmlsec.template.x509_issuer_serial_add_issuer_name(issuer) xmlsec.template.x509_issuer_serial_add_serial_number(issuer) self.assertEqual(x509, xmlsec.tree.find_node(self.load_xml("sign_template.xml"), consts.NodeX509Data, consts.DSigNs)) def test_add_x509_data_bad_args(self): with self.assertRaises(TypeError): xmlsec.template.add_x509_data('') def test_x509_issuer_serial_add_issuer(self): root = self.load_xml("doc.xml") sign = xmlsec.template.create(root, c14n_method=consts.TransformExclC14N, sign_method=consts.TransformRsaSha1) ki = xmlsec.template.ensure_key_info(sign) x509 = xmlsec.template.add_x509_data(ki) issuer = xmlsec.template.x509_data_add_issuer_serial(x509) name = xmlsec.template.x509_issuer_serial_add_issuer_name(issuer, name="Name") serial = xmlsec.template.x509_issuer_serial_add_serial_number(issuer, serial="Serial") self.assertEqual("Name", name.text) self.assertEqual("Serial", serial.text) def test_x509_issuer_serial_add_issuer_bad_args(self): with self.assertRaises(TypeError): xmlsec.template.x509_data_add_issuer_serial('') def test_x509_issuer_serial_add_issuer_name_bad_args(self): with self.assertRaises(TypeError): xmlsec.template.x509_issuer_serial_add_issuer_name('') def test_x509_issuer_serial_add_serial_number_bad_args(self): with self.assertRaises(TypeError): xmlsec.template.x509_issuer_serial_add_serial_number('') def test_x509_data_add_subject_name_bad_args(self): with self.assertRaises(TypeError): xmlsec.template.x509_data_add_subject_name('') def test_x509_data_add_ski_bad_args(self): with self.assertRaises(TypeError): xmlsec.template.x509_data_add_ski('') def test_x509_data_add_certificate_bad_args(self): with self.assertRaises(TypeError): xmlsec.template.x509_data_add_certificate('') def test_x509_data_add_crl_bad_args(self): with self.assertRaises(TypeError): xmlsec.template.x509_data_add_crl('') def test_add_encrypted_key_bad_args(self): with self.assertRaises(TypeError): xmlsec.template.add_encrypted_key('', 0) def test_encrypted_data_create_bad_args(self): with self.assertRaises(TypeError): xmlsec.template.encrypted_data_create('', 0) def test_encrypted_data_ensure_cipher_value(self): root = self.load_xml("doc.xml") enc = xmlsec.template.encrypted_data_create(root, method=consts.TransformDes3Cbc) cv = xmlsec.template.encrypted_data_ensure_cipher_value(enc) self.assertEqual(cv, xmlsec.tree.find_node(self.load_xml("sign_template.xml"), consts.NodeCipherValue, consts.EncNs)) def test_encrypted_data_ensure_cipher_value_bad_args(self): with self.assertRaises(TypeError): xmlsec.template.encrypted_data_ensure_cipher_value('') def test_encrypted_data_ensure_key_info(self): root = self.load_xml("doc.xml") enc = xmlsec.template.encrypted_data_create(root, method=consts.TransformDes3Cbc) ki = xmlsec.template.encrypted_data_ensure_key_info(enc) self.assertEqual(ki, xmlsec.tree.find_node(self.load_xml("enc_template.xml"), consts.NodeKeyInfo, consts.DSigNs)) ki2 = xmlsec.template.encrypted_data_ensure_key_info(enc, id="Id", ns="test") self.assertEqual("Id", ki2.get("Id")) self.assertEqual("test", ki2.prefix) def test_encrypted_data_ensure_key_info_bad_args(self): with self.assertRaises(TypeError): xmlsec.template.encrypted_data_ensure_key_info('') @unittest.skipIf(not hasattr(consts, 'TransformXslt'), reason='XSLT transformations not enabled') def test_transform_add_c14n_inclusive_namespaces(self): root = self.load_xml("doc.xml") sign = xmlsec.template.create(root, c14n_method=consts.TransformExclC14N, sign_method=consts.TransformRsaSha1) ref = xmlsec.template.add_reference(sign, consts.TransformSha1) trans1 = xmlsec.template.add_transform(ref, consts.TransformEnveloped) xmlsec.template.transform_add_c14n_inclusive_namespaces(trans1, "default") trans2 = xmlsec.template.add_transform(ref, consts.TransformXslt) xmlsec.template.transform_add_c14n_inclusive_namespaces(trans2, ["ns1", "ns2"]) self.assertEqual(ref, xmlsec.tree.find_node(self.load_xml("sign_template.xml"), consts.NodeReference, consts.DSigNs)) def test_transform_add_c14n_inclusive_namespaces_bad_args(self): with self.assertRaises(TypeError): xmlsec.template.transform_add_c14n_inclusive_namespaces('', []) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/tests/test_tree.py0000644000175100001710000000340314300243501016173 0ustar00runnerdockerimport xmlsec from tests import base consts = xmlsec.constants class TestTree(base.TestMemoryLeaks): def test_find_child(self): root = self.load_xml("sign_template.xml") si = xmlsec.tree.find_child(root, consts.NodeSignedInfo, consts.DSigNs) self.assertEqual(consts.NodeSignedInfo, si.tag.partition('}')[2]) self.assertIsNone(xmlsec.tree.find_child(root, consts.NodeReference)) self.assertIsNone(xmlsec.tree.find_child(root, consts.NodeSignedInfo, consts.EncNs)) def test_find_child_bad_args(self): with self.assertRaises(TypeError): xmlsec.tree.find_child('', 0, True) def test_find_parent(self): root = self.load_xml("sign_template.xml") si = xmlsec.tree.find_child(root, consts.NodeSignedInfo, consts.DSigNs) self.assertIs(root, xmlsec.tree.find_parent(si, consts.NodeSignature)) self.assertIsNone(xmlsec.tree.find_parent(root, consts.NodeSignedInfo)) def test_find_parent_bad_args(self): with self.assertRaises(TypeError): xmlsec.tree.find_parent('', 0, True) def test_find_node(self): root = self.load_xml("sign_template.xml") ref = xmlsec.tree.find_node(root, consts.NodeReference) self.assertEqual(consts.NodeReference, ref.tag.partition('}')[2]) self.assertIsNone(xmlsec.tree.find_node(root, consts.NodeReference, consts.EncNs)) def test_find_node_bad_args(self): with self.assertRaises(TypeError): xmlsec.tree.find_node('', 0, True) def test_add_ids(self): root = self.load_xml("sign_template.xml") xmlsec.tree.add_ids(root, ["id1", "id2", "id3"]) def test_add_ids_bad_args(self): with self.assertRaises(TypeError): xmlsec.tree.add_ids('', []) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/tests/test_type_stubs.py0000644000175100001710000000370514300243501017442 0ustar00runnerdocker"""Test type stubs for correctness where possible.""" import os import pytest import xmlsec black = pytest.importorskip('black') constants_stub_header = """ import sys from typing import NamedTuple if sys.version_info >= (3, 8): from typing import Final else: from typing_extensions import Final class __KeyData(NamedTuple): # __KeyData type href: str name: str class __KeyDataNoHref(NamedTuple): # __KeyData type href: None name: str class __Transform(NamedTuple): # __Transform type href: str name: str usage: int class __TransformNoHref(NamedTuple): # __Transform type href: None name: str usage: int """ def gen_constants_stub(): """ Generate contents of the file:`xmlsec/constants.pyi`. Simply load all constants at runtime, generate appropriate type hint for each constant type. """ def process_constant(name): """Generate line in stub file for constant name.""" obj = getattr(xmlsec.constants, name) type_name = type(obj).__name__ if type_name in ('__KeyData', '__Transform') and obj.href is None: type_name += 'NoHref' return '{name}: Final[{type_name}]'.format(name=name, type_name=type_name) names = list(sorted(name for name in dir(xmlsec.constants) if not name.startswith('__'))) lines = [process_constant(name) for name in names] return constants_stub_header + os.linesep.join(lines) def test_xmlsec_constants_stub(request): """ Generate the stub file for :mod:`xmlsec.constants` from existing code. Compare it against the existing stub :file:`xmlsec/constants.pyi`. """ stub = request.config.rootpath / 'src' / 'xmlsec' / 'constants.pyi' mode = black.FileMode(target_versions={black.TargetVersion.PY39}, line_length=130, is_pyi=True, string_normalization=False) formatted = black.format_file_contents(gen_constants_stub(), fast=False, mode=mode) assert formatted == stub.read_text() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1661028161.0 xmlsec-1.3.13/tests/test_xmlsec.py0000644000175100001710000000064614300243501016535 0ustar00runnerdockerimport xmlsec from tests import base class TestModule(base.TestMemoryLeaks): def test_reinitialize_module(self): """ This doesn't explicitly test anything, but will be invoked first in the suite, so if the subsequent tests don't fail, we know that the ``init()``/``shutdown()`` function pair doesn't break anything. """ xmlsec.shutdown() xmlsec.init()