././@PaxHeader 0000000 0000000 0000000 00000000034 00000000000 010212 x ustar 00 28 mtime=1630860869.3961322
xmlsec-1.3.12/ 0000755 0001751 0000171 00000000000 00000000000 012431 5 ustar 00runner docker ././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1630860861.0
xmlsec-1.3.12/.readthedocs.yaml 0000644 0001751 0000171 00000000253 00000000000 015660 0 ustar 00runner docker version: 2
sphinx:
configuration: doc/source/conf.py
python:
version: 3.8
install:
- method: pip
path: .
- requirements: doc/source/requirements.txt
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1630860861.0
xmlsec-1.3.12/LICENSE 0000644 0001751 0000171 00000002066 00000000000 013442 0 ustar 00runner docker The 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.
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1630860861.0
xmlsec-1.3.12/MANIFEST.in 0000644 0001751 0000171 00000000463 00000000000 014172 0 ustar 00runner docker recursive-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
././@PaxHeader 0000000 0000000 0000000 00000000034 00000000000 010212 x ustar 00 28 mtime=1630860869.3961322
xmlsec-1.3.12/PKG-INFO 0000644 0001751 0000171 00000015473 00000000000 013540 0 ustar 00runner docker Metadata-Version: 2.1
Name: xmlsec
Version: 1.3.12
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
Platform: UNKNOWN
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.
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1630860861.0
xmlsec-1.3.12/README.rst 0000644 0001751 0000171 00000013137 00000000000 014125 0 ustar 00runner docker 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.
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1630860861.0
xmlsec-1.3.12/mypy.ini 0000644 0001751 0000171 00000000650 00000000000 014131 0 ustar 00runner docker [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
no_implicit_optional = True
warn_redundant_casts = True
warn_unused_ignores = True
warn_return_any = True
no_implicit_reexport = True
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1630860861.0
xmlsec-1.3.12/pyproject.toml 0000644 0001751 0000171 00000001002 00000000000 015336 0 ustar 00runner docker [tool.black]
line_length = 130
skip-string-normalization = true
target_version = ['py38']
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']
././@PaxHeader 0000000 0000000 0000000 00000000034 00000000000 010212 x ustar 00 28 mtime=1630860869.3961322
xmlsec-1.3.12/setup.cfg 0000644 0001751 0000171 00000000617 00000000000 014256 0 ustar 00runner docker [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]
max-line-length = 130
[egg_info]
tag_build =
tag_date = 0
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1630860861.0
xmlsec-1.3.12/setup.py 0000644 0001751 0000171 00000043202 00000000000 014144 0 ustar 00runner docker import io
import multiprocessing
import os
import subprocess
import sys
import tarfile
import zipfile
from distutils import log
from distutils.errors import DistutilsError
from pathlib import Path
from urllib.request import urlcleanup, urljoin, urlretrieve
from setuptools import Extension, setup
from setuptools.command.build_ext import build_ext as build_ext_orig
class build_ext(build_ext_orig, object):
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)
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.1g')
self.libiconv_version = os.environ.get('PYXMLSEC_LIBICONV_VERSION', '1.16')
self.libxml2_version = os.environ.get('PYXMLSEC_LIBXML2_VERSION', None)
self.libxslt_version = os.environ.get('PYXMLSEC_LIBXLST_VERSION', None)
self.zlib_version = os.environ.get('PYXMLSEC_ZLIB_VERSION', '1.2.11')
self.xmlsec1_version = os.environ.get('PYXMLSEC_XMLSEC1_VERSION', '1.2.31')
self.info('Settings:')
self.info('{:20} {}'.format('Lib sources in:', self.libs_dir.absolute()))
self.info('{:20} {}'.format('zlib version:', self.zlib_version))
self.info('{:20} {}'.format('libiconv version:', self.libiconv_version))
self.info('{:20} {}'.format('libxml2 version:', self.libxml2_version or 'unset, using latest'))
self.info('{:20} {}'.format('libxslt version:', self.libxslt_version or 'unset, using latest'))
self.info('{:20} {}'.format('xmlsec1 version:', self.xmlsec1_version))
# fetch openssl
openssl_tar = next(self.libs_dir.glob('openssl*.tar.gz'), None)
if openssl_tar is None:
self.info('OpenSSL source tar not found, downloading ...')
openssl_tar = self.libs_dir / 'openssl.tar.gz'
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('zlib source tar not found, downloading ...')
zlib_tar = self.libs_dir / 'zlib.tar.gz'
urlretrieve('https://zlib.net/zlib-{}.tar.gz'.format(self.zlib_version), str(zlib_tar))
# fetch libiconv
libiconv_tar = next(self.libs_dir.glob('libiconv*.tar.gz'), None)
if libiconv_tar is None:
self.info('libiconv source tar not found, downloading ...')
libiconv_tar = self.libs_dir / 'libiconv.tar.gz'
urlretrieve(
'https://ftp.gnu.org/pub/gnu/libiconv/libiconv-{}.tar.gz'.format(self.libiconv_version), str(libiconv_tar)
)
# fetch libxml2
libxml2_tar = next(self.libs_dir.glob('libxml2*.tar.gz'), None)
if libxml2_tar is None:
self.info('Libxml2 source tar not found, downloading ...')
if self.libxml2_version is None:
url = 'http://xmlsoft.org/sources/LATEST_LIBXML2'
else:
url = 'http://xmlsoft.org/sources/libxml2-{}.tar.gz'.format(self.libxml2_version)
libxml2_tar = self.libs_dir / 'libxml2.tar.gz'
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('libxslt source tar not found, downloading ...')
if self.libxslt_version is None:
url = 'http://xmlsoft.org/sources/LATEST_LIBXSLT'
else:
url = 'http://xmlsoft.org/sources/libxslt-{}.tar.gz'.format(self.libxslt_version)
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('xmlsec1 source tar not found, downloading ...')
url = 'http://www.aleksey.com/xmlsec/download/xmlsec1-{}.tar.gz'.format(self.xmlsec1_version)
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']},
)
././@PaxHeader 0000000 0000000 0000000 00000000033 00000000000 010211 x ustar 00 27 mtime=1630860869.392132
xmlsec-1.3.12/src/ 0000755 0001751 0000171 00000000000 00000000000 013220 5 ustar 00runner docker ././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1630860861.0
xmlsec-1.3.12/src/common.h 0000644 0001751 0000171 00000001517 00000000000 014665 0 ustar 00runner docker // 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__
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1630860861.0
xmlsec-1.3.12/src/constants.c 0000644 0001751 0000171 00000057502 00000000000 015411 0 ustar 00runner docker // 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;
}
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1630860861.0
xmlsec-1.3.12/src/constants.h 0000644 0001751 0000171 00000001665 00000000000 015415 0 ustar 00runner docker // 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__
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1630860861.0
xmlsec-1.3.12/src/debug.h 0000644 0001751 0000171 00000002051 00000000000 014455 0 ustar 00runner docker // 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__
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1630860861.0
xmlsec-1.3.12/src/ds.c 0000644 0001751 0000171 00000056023 00000000000 014000 0 ustar 00runner docker // 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;
}
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1630860861.0
xmlsec-1.3.12/src/enc.c 0000644 0001751 0000171 00000050273 00000000000 014140 0 ustar 00runner docker // 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;
}
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1630860861.0
xmlsec-1.3.12/src/exception.c 0000644 0001751 0000171 00000017153 00000000000 015371 0 ustar 00runner docker // 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;
}
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1630860861.0
xmlsec-1.3.12/src/exception.h 0000644 0001751 0000171 00000001726 00000000000 015375 0 ustar 00runner docker // 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__
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1630860861.0
xmlsec-1.3.12/src/keys.c 0000644 0001751 0000171 00000072017 00000000000 014346 0 ustar 00runner docker // 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, "OH|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;
}
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1630860861.0
xmlsec-1.3.12/src/keys.h 0000644 0001751 0000171 00000002156 00000000000 014350 0 ustar 00runner docker // 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__
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1630860861.0
xmlsec-1.3.12/src/lxml.c 0000644 0001751 0000171 00000002411 00000000000 014336 0 ustar 00runner docker // 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;
}
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1630860861.0
xmlsec-1.3.12/src/lxml.h 0000644 0001751 0000171 00000002255 00000000000 014351 0 ustar 00runner docker // 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__
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1630860861.0
xmlsec-1.3.12/src/main.c 0000644 0001751 0000171 00000041110 00000000000 014305 0 ustar 00runner docker // 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);
}
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1630860861.0
xmlsec-1.3.12/src/platform.h 0000644 0001751 0000171 00000002647 00000000000 015226 0 ustar 00runner docker // 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__
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1630860861.0
xmlsec-1.3.12/src/template.c 0000644 0001751 0000171 00000107351 00000000000 015206 0 ustar 00runner docker // 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;
}
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1630860861.0
xmlsec-1.3.12/src/tree.c 0000644 0001751 0000171 00000020474 00000000000 014332 0 ustar 00runner docker // 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;
}
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1630860861.0
xmlsec-1.3.12/src/utils.c 0000644 0001751 0000171 00000003161 00000000000 014525 0 ustar 00runner docker // 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;
}
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1630860861.0
xmlsec-1.3.12/src/utils.h 0000644 0001751 0000171 00000001631 00000000000 014532 0 ustar 00runner docker // 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__
././@PaxHeader 0000000 0000000 0000000 00000000033 00000000000 010211 x ustar 00 27 mtime=1630860869.392132
xmlsec-1.3.12/src/xmlsec/ 0000755 0001751 0000171 00000000000 00000000000 014513 5 ustar 00runner docker ././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1630860861.0
xmlsec-1.3.12/src/xmlsec/__init__.pyi 0000644 0001751 0000171 00000006560 00000000000 017004 0 ustar 00runner docker import sys
from typing import (
Any, AnyStr, Callable, IO, Iterable, Optional, Type, TypeVar, Union,
overload)
from lxml.etree import _Element
from xmlsec import constants, template, tree
from xmlsec.constants import __KeyData as KeyData, __Transform as Transform
if sys.version_info >= (3, 6):
from os import PathLike
from pathlib import PurePath
_Path = Union[str, bytes, PurePath, PathLike[str], PathLike[bytes]]
elif sys.version_info >= (3, 4):
from pathlib import PurePath
_Path = Union[str, bytes, PurePath]
else:
_Path = Union[str, bytes]
_E = TypeVar('_E', bound=_Element)
_K = TypeVar('_K', bound=Key)
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: Optional[Key]
def __init__(self, manager: Optional[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[_K], klass: KeyData, data: AnyStr) -> _K: ...
@classmethod
def from_binary_file(cls: Type[_K], klass: KeyData, filename: _Path) -> _K: ...
@classmethod
def from_file(cls: Type[_K], file: Union[_Path, IO[AnyStr]], format: int, password: Optional[str] = ...) -> _K: ...
@classmethod
def from_memory(cls: Type[_K], data: AnyStr, format: int, password: Optional[str] = ...) -> _K: ...
@classmethod
def generate(cls: Type[_K], klass: KeyData, size: int, type: int) -> _K: ...
def load_cert_from_file(self, file: Union[_Path, IO[AnyStr]], format: int) -> None: ...
def load_cert_from_memory(self, data: AnyStr, format: int) -> None: ...
def __copy__(self: _K) -> _K: ...
def __deepcopy__(self: _K) -> _K: ...
class KeysManager:
def add_key(self, key: Key) -> None: ...
def load_cert(self, filename: _Path, format: int, type: int) -> None: ...
def load_cert_from_memory(self, data: AnyStr, format: int, type: int) -> None: ...
class SignatureContext:
key: Optional[Key]
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", id_ns: Optional[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): ...
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1630860861.0
xmlsec-1.3.12/src/xmlsec/constants.pyi 0000644 0001751 0000171 00000022621 00000000000 017255 0 ustar 00runner docker import sys
from typing import NamedTuple, Optional
if sys.version_info >= (3, 8):
from typing import Final
else:
from typing_extensions import Final
class __KeyData(NamedTuple): # __KeyData type
name: str
href: Optional[str]
class __Transform(NamedTuple): # __Transform type
name: str
href: Optional[str]
usage: int
DSigNs: Final = 'http://www.w3.org/2000/09/xmldsig#'
EncNs: Final = 'http://www.w3.org/2001/04/xmlenc#'
KeyDataAes: Final = __KeyData('aes', 'http://www.aleksey.com/xmlsec/2002#AESKeyValue')
KeyDataDes: Final = __KeyData('des', 'http://www.aleksey.com/xmlsec/2002#DESKeyValue')
KeyDataDsa: Final = __KeyData('dsa', 'http://www.w3.org/2000/09/xmldsig#DSAKeyValue')
KeyDataEcdsa: Final = __KeyData('ecdsa', 'http://scap.nist.gov/specifications/tmsad/#resource-1.0')
KeyDataEncryptedKey: Final = __KeyData('enc-key', 'http://www.w3.org/2001/04/xmlenc#EncryptedKey')
KeyDataFormatBinary: Final = 1
KeyDataFormatCertDer: Final = 8
KeyDataFormatCertPem: Final = 7
KeyDataFormatDer: Final = 3
KeyDataFormatPem: Final = 2
KeyDataFormatPkcs12: Final = 6
KeyDataFormatPkcs8Der: Final = 5
KeyDataFormatPkcs8Pem: Final = 4
KeyDataFormatUnknown: Final = 0
KeyDataHmac: Final = __KeyData('hmac', 'http://www.aleksey.com/xmlsec/2002#HMACKeyValue')
KeyDataName: Final = __KeyData('key-name', None)
KeyDataRawX509Cert: Final = __KeyData('raw-x509-cert', 'http://www.w3.org/2000/09/xmldsig#rawX509Certificate')
KeyDataRetrievalMethod: Final = __KeyData('retrieval-method', None)
KeyDataRsa: Final = __KeyData('rsa', 'http://www.w3.org/2000/09/xmldsig#RSAKeyValue')
KeyDataTypeAny: Final = 65535
KeyDataTypeNone: Final = 0
KeyDataTypePermanent: Final = 16
KeyDataTypePrivate: Final = 2
KeyDataTypePublic: Final = 1
KeyDataTypeSession: Final = 8
KeyDataTypeSymmetric: Final = 4
KeyDataTypeTrusted: Final = 256
KeyDataTypeUnknown: Final = 0
KeyDataValue: Final = __KeyData('key-value', None)
KeyDataX509: Final = __KeyData('x509', 'http://www.w3.org/2000/09/xmldsig#X509Data')
NodeCanonicalizationMethod: Final = 'CanonicalizationMethod'
NodeCipherData: Final = 'CipherData'
NodeCipherReference: Final = 'CipherReference'
NodeCipherValue: Final = 'CipherValue'
NodeDataReference: Final = 'DataReference'
NodeDigestMethod: Final = 'DigestMethod'
NodeDigestValue: Final = 'DigestValue'
NodeEncryptedData: Final = 'EncryptedData'
NodeEncryptedKey: Final = 'EncryptedKey'
NodeEncryptionMethod: Final = 'EncryptionMethod'
NodeEncryptionProperties: Final = 'EncryptionProperties'
NodeEncryptionProperty: Final = 'EncryptionProperty'
NodeKeyInfo: Final = 'KeyInfo'
NodeKeyName: Final = 'KeyName'
NodeKeyReference: Final = 'KeyReference'
NodeKeyValue: Final = 'KeyValue'
NodeManifest: Final = 'Manifest'
NodeObject: Final = 'Object'
NodeReference: Final = 'Reference'
NodeReferenceList: Final = 'ReferenceList'
NodeSignature: Final = 'Signature'
NodeSignatureMethod: Final = 'SignatureMethod'
NodeSignatureProperties: Final = 'SignatureProperties'
NodeSignatureValue: Final = 'SignatureValue'
NodeSignedInfo: Final = 'SignedInfo'
NodeX509Data: Final = 'X509Data'
Ns: Final = 'http://www.aleksey.com/xmlsec/2002'
NsExcC14N: Final = 'http://www.w3.org/2001/10/xml-exc-c14n#'
NsExcC14NWithComments: Final = 'http://www.w3.org/2001/10/xml-exc-c14n#WithComments'
Soap11Ns: Final = 'http://schemas.xmlsoap.org/soap/envelope/'
Soap12Ns: Final = 'http://www.w3.org/2002/06/soap-envelope'
TransformAes128Cbc: Final = __Transform('aes128-cbc', 'http://www.w3.org/2001/04/xmlenc#aes128-cbc', 16)
TransformAes128Gcm: Final = __Transform('aes128-gcm', 'http://www.w3.org/2009/xmlenc11#aes128-gcm', 16)
TransformAes192Cbc: Final = __Transform('aes192-cbc', 'http://www.w3.org/2001/04/xmlenc#aes192-cbc', 16)
TransformAes192Gcm: Final = __Transform('aes192-gcm', 'http://www.w3.org/2009/xmlenc11#aes192-gcm', 16)
TransformAes256Cbc: Final = __Transform('aes256-cbc', 'http://www.w3.org/2001/04/xmlenc#aes256-cbc', 16)
TransformAes256Gcm: Final = __Transform('aes256-gcm', 'http://www.w3.org/2009/xmlenc11#aes256-gcm', 16)
TransformDes3Cbc: Final = __Transform('tripledes-cbc', 'http://www.w3.org/2001/04/xmlenc#tripledes-cbc', 16)
TransformDsaSha1: Final = __Transform('dsa-sha1', 'http://www.w3.org/2000/09/xmldsig#dsa-sha1', 8)
TransformEcdsaSha1: Final = __Transform('ecdsa-sha1', 'http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1', 8)
TransformEcdsaSha224: Final = __Transform('ecdsa-sha224', 'http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha224', 8)
TransformEcdsaSha256: Final = __Transform('ecdsa-sha256', 'http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256', 8)
TransformEcdsaSha384: Final = __Transform('ecdsa-sha384', 'http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha384', 8)
TransformEcdsaSha512: Final = __Transform('ecdsa-sha512', 'http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha512', 8)
TransformEnveloped: Final = __Transform('enveloped-signature', 'http://www.w3.org/2000/09/xmldsig#enveloped-signature', 1)
TransformExclC14N: Final = __Transform('exc-c14n', 'http://www.w3.org/2001/10/xml-exc-c14n#', 3)
TransformExclC14NWithComments: Final = __Transform(
'exc-c14n-with-comments', 'http://www.w3.org/2001/10/xml-exc-c14n#WithComments', 3
)
TransformHmacMd5: Final = __Transform('hmac-md5', 'http://www.w3.org/2001/04/xmldsig-more#hmac-md5', 8)
TransformHmacRipemd160: Final = __Transform('hmac-ripemd160', 'http://www.w3.org/2001/04/xmldsig-more#hmac-ripemd160', 8)
TransformHmacSha1: Final = __Transform('hmac-sha1', 'http://www.w3.org/2000/09/xmldsig#hmac-sha1', 8)
TransformHmacSha224: Final = __Transform('hmac-sha224', 'http://www.w3.org/2001/04/xmldsig-more#hmac-sha224', 8)
TransformHmacSha256: Final = __Transform('hmac-sha256', 'http://www.w3.org/2001/04/xmldsig-more#hmac-sha256', 8)
TransformHmacSha384: Final = __Transform('hmac-sha384', 'http://www.w3.org/2001/04/xmldsig-more#hmac-sha384', 8)
TransformHmacSha512: Final = __Transform('hmac-sha512', 'http://www.w3.org/2001/04/xmldsig-more#hmac-sha512', 8)
TransformInclC14N: Final = __Transform('c14n', 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315', 3)
TransformInclC14N11: Final = __Transform('c14n11', 'http://www.w3.org/2006/12/xml-c14n11', 3)
TransformInclC14N11WithComments: Final = __Transform(
'c14n11-with-comments', 'http://www.w3.org/2006/12/xml-c14n11#WithComments', 3
)
TransformInclC14NWithComments: Final = __Transform(
'c14n-with-comments',
'http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments',
3,
)
TransformKWAes128: Final = __Transform('kw-aes128', 'http://www.w3.org/2001/04/xmlenc#kw-aes128', 16)
TransformKWAes192: Final = __Transform('kw-aes192', 'http://www.w3.org/2001/04/xmlenc#kw-aes192', 16)
TransformKWAes256: Final = __Transform('kw-aes256', 'http://www.w3.org/2001/04/xmlenc#kw-aes256', 16)
TransformKWDes3: Final = __Transform('kw-tripledes', 'http://www.w3.org/2001/04/xmlenc#kw-tripledes', 16)
TransformMd5: Final = __Transform('md5', 'http://www.w3.org/2001/04/xmldsig-more#md5', 4)
TransformRemoveXmlTagsC14N: Final = __Transform('remove-xml-tags-transform', None, 3)
TransformRipemd160: Final = __Transform('ripemd160', 'http://www.w3.org/2001/04/xmlenc#ripemd160', 4)
TransformRsaMd5: Final = __Transform('rsa-md5', 'http://www.w3.org/2001/04/xmldsig-more#rsa-md5', 8)
TransformRsaOaep: Final = __Transform('rsa-oaep-mgf1p', 'http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p', 16)
TransformRsaPkcs1: Final = __Transform('rsa-1_5', 'http://www.w3.org/2001/04/xmlenc#rsa-1_5', 16)
TransformRsaRipemd160: Final = __Transform('rsa-ripemd160', 'http://www.w3.org/2001/04/xmldsig-more#rsa-ripemd160', 8)
TransformRsaSha1: Final = __Transform('rsa-sha1', 'http://www.w3.org/2000/09/xmldsig#rsa-sha1', 8)
TransformRsaSha224: Final = __Transform('rsa-sha224', 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha224', 8)
TransformRsaSha256: Final = __Transform('rsa-sha256', 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256', 8)
TransformRsaSha384: Final = __Transform('rsa-sha384', 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha384', 8)
TransformRsaSha512: Final = __Transform('rsa-sha512', 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha512', 8)
TransformSha1: Final = __Transform('sha1', 'http://www.w3.org/2000/09/xmldsig#sha1', 4)
TransformSha224: Final = __Transform('sha224', 'http://www.w3.org/2001/04/xmldsig-more#sha224', 4)
TransformSha256: Final = __Transform('sha256', 'http://www.w3.org/2001/04/xmlenc#sha256', 4)
TransformSha384: Final = __Transform('sha384', 'http://www.w3.org/2001/04/xmldsig-more#sha384', 4)
TransformSha512: Final = __Transform('sha512', 'http://www.w3.org/2001/04/xmlenc#sha512', 4)
TransformUsageAny: Final = 65535
TransformUsageC14NMethod: Final = 2
TransformUsageDSigTransform: Final = 1
TransformUsageDigestMethod: Final = 4
TransformUsageEncryptionMethod: Final = 16
TransformUsageSignatureMethod: Final = 8
TransformUsageUnknown: Final = 0
TransformVisa3DHack: Final = __Transform('Visa3DHackTransform', None, 1)
TransformXPath: Final = __Transform('xpath', 'http://www.w3.org/TR/1999/REC-xpath-19991116', 1)
TransformXPath2: Final = __Transform('xpath2', 'http://www.w3.org/2002/06/xmldsig-filter2', 1)
TransformXPointer: Final = __Transform('xpointer', 'http://www.w3.org/2001/04/xmldsig-more/xptr', 1)
TransformXslt: Final = __Transform('xslt', 'http://www.w3.org/TR/1999/REC-xslt-19991116', 1)
TypeEncContent: Final = 'http://www.w3.org/2001/04/xmlenc#Content'
TypeEncElement: Final = 'http://www.w3.org/2001/04/xmlenc#Element'
XPath2Ns: Final = 'http://www.w3.org/2002/06/xmldsig-filter2'
XPathNs: Final = 'http://www.w3.org/TR/1999/REC-xpath-19991116'
XPointerNs: Final = 'http://www.w3.org/2001/04/xmldsig-more/xptr'
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1630860861.0
xmlsec-1.3.12/src/xmlsec/py.typed 0000644 0001751 0000171 00000000077 00000000000 016216 0 ustar 00runner docker # Marker file for PEP 561. The xmlsec package uses stub files.
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1630860861.0
xmlsec-1.3.12/src/xmlsec/template.pyi 0000644 0001751 0000171 00000003621 00000000000 017053 0 ustar 00runner docker from typing import Any, Optional, Sequence, Union
from lxml.etree import _Element
from xmlsec.constants import __Transform as Transform
def add_encrypted_key(
node: _Element, method: Transform, id: Optional[str] = None, type: Optional[str] = None, recipient: Optional[str] = None
) -> _Element: ...
def add_key_name(node: _Element, name: Optional[str] = ...) -> _Element: ...
def add_key_value(node: _Element) -> _Element: ...
def add_reference(
node: _Element, digest_method: Transform, id: Optional[str] = ..., uri: Optional[str] = ..., type: Optional[str] = ...
) -> _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: Optional[str] = ...,
type: Optional[str] = ...,
mime_type: Optional[str] = ...,
encoding: Optional[str] = ...,
ns: Optional[str] = ...,
) -> _Element: ...
def encrypted_data_ensure_cipher_value(node: _Element) -> _Element: ...
def encrypted_data_ensure_key_info(node: _Element, id: Optional[str] = ..., ns: Optional[str] = ...) -> _Element: ...
def ensure_key_info(node: _Element, id: Optional[str] = ...) -> _Element: ...
def transform_add_c14n_inclusive_namespaces(node: _Element, prefixes: Union[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: Optional[str] = ...) -> _Element: ...
def x509_issuer_serial_add_serial_number(node: _Element, serial: Optional[str] = ...) -> _Element: ...
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1630860861.0
xmlsec-1.3.12/src/xmlsec/tree.pyi 0000644 0001751 0000171 00000001257 00000000000 016202 0 ustar 00runner docker from typing import Optional, overload, Sequence
from lxml.etree import _Element
def add_ids(node: _Element, ids: Sequence[str]) -> None: ...
@overload
def find_child(parent: _Element, name: str) -> Optional[_Element]: ...
@overload
def find_child(parent: _Element, name: str, namespace: str = ...) -> Optional[_Element]: ...
@overload
def find_node(node: _Element, name: str) -> Optional[_Element]: ...
@overload
def find_node(node: _Element, name: str, namespace: str = ...) -> Optional[_Element]: ...
@overload
def find_parent(node: _Element, name: str) -> Optional[_Element]: ...
@overload
def find_parent(node: _Element, name: str, namespace: str = ...) -> Optional[_Element]: ...
././@PaxHeader 0000000 0000000 0000000 00000000033 00000000000 010211 x ustar 00 27 mtime=1630860869.392132
xmlsec-1.3.12/src/xmlsec.egg-info/ 0000755 0001751 0000171 00000000000 00000000000 016205 5 ustar 00runner docker ././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1630860869.0
xmlsec-1.3.12/src/xmlsec.egg-info/PKG-INFO 0000644 0001751 0000171 00000015473 00000000000 017314 0 ustar 00runner docker Metadata-Version: 2.1
Name: xmlsec
Version: 1.3.12
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
Platform: UNKNOWN
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.
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1630860869.0
xmlsec-1.3.12/src/xmlsec.egg-info/SOURCES.txt 0000644 0001751 0000171 00000003732 00000000000 020076 0 ustar 00runner docker .readthedocs.yaml
LICENSE
MANIFEST.in
README.rst
mypy.ini
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 ././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1630860869.0
xmlsec-1.3.12/src/xmlsec.egg-info/dependency_links.txt 0000644 0001751 0000171 00000000001 00000000000 022253 0 ustar 00runner docker
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1630860869.0
xmlsec-1.3.12/src/xmlsec.egg-info/not-zip-safe 0000644 0001751 0000171 00000000001 00000000000 020433 0 ustar 00runner docker
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1630860869.0
xmlsec-1.3.12/src/xmlsec.egg-info/requires.txt 0000644 0001751 0000171 00000000012 00000000000 020576 0 ustar 00runner docker lxml>=3.8
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1630860869.0
xmlsec-1.3.12/src/xmlsec.egg-info/top_level.txt 0000644 0001751 0000171 00000000007 00000000000 020734 0 ustar 00runner docker xmlsec
././@PaxHeader 0000000 0000000 0000000 00000000033 00000000000 010211 x ustar 00 27 mtime=1630860869.392132
xmlsec-1.3.12/tests/ 0000755 0001751 0000171 00000000000 00000000000 013573 5 ustar 00runner docker ././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1630860861.0
xmlsec-1.3.12/tests/__init__.py 0000644 0001751 0000171 00000000000 00000000000 015672 0 ustar 00runner docker ././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1630860861.0
xmlsec-1.3.12/tests/base.py 0000644 0001751 0000171 00000010276 00000000000 015065 0 ustar 00runner docker import gc
import os
import sys
import unittest
from lxml import etree
import xmlsec
if sys.version_info < (3,):
unittest.TestCase.assertRaisesRegex = unittest.TestCase.assertRaisesRegexp
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 i 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):
"""returns full path for resource"""
return os.path.join(self.data_dir, name)
def load(self, name):
"""loads resource by name"""
with open(self.path(name), "rb") as stream:
return stream.read()
def load_xml(self, name, xpath=None):
"""returns xml.etree"""
root = etree.parse(self.path(name)).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):
"""Checks equality of etree.roots"""
msg = msg or ''
if first.tag != second.tag:
self.fail('Tags do not match: %s and %s. %s' % (first.tag, second.tag, msg))
for name, value in first.attrib.items():
if second.attrib.get(name) != value:
self.fail('Attributes do not match: %s=%r, %s=%r. %s' % (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: %s. %s' % (name, msg))
if not xml_text_compare(first.text, second.text):
self.fail('text: %r != %r. %s' % (first.text, second.text, msg))
if not xml_text_compare(first.tail, second.tail):
self.fail('tail: %r != %r. %s' % (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, %i != %i. %s' % (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()
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1630860861.0
xmlsec-1.3.12/tests/conftest.py 0000644 0001751 0000171 00000000556 00000000000 016000 0 ustar 00runner docker def 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)
././@PaxHeader 0000000 0000000 0000000 00000000034 00000000000 010212 x ustar 00 28 mtime=1630860869.3961322
xmlsec-1.3.12/tests/data/ 0000755 0001751 0000171 00000000000 00000000000 014504 5 ustar 00runner docker ././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1630860861.0
xmlsec-1.3.12/tests/data/deskey.bin 0000644 0001751 0000171 00000000030 00000000000 016453 0 ustar 00runner docker 012345670123456701234567 ././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1630860861.0
xmlsec-1.3.12/tests/data/doc.xml 0000644 0001751 0000171 00000000246 00000000000 015775 0 ustar 00runner docker
Hello, World!