Skip to content

Commit 01f4801

Browse files
committed
Add docs and link to technotes.shemyak.com blog post on etree compatibility
1 parent ad33ca6 commit 01f4801

File tree

1 file changed

+23
-5
lines changed

1 file changed

+23
-5
lines changed

README.rst

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ payload security in `SAML 2.0 <http://en.wikipedia.org/wiki/SAML_2.0>`_ and
1414
* Support for exclusive XML canonicalization with inclusive prefixes (`InclusiveNamespaces PrefixList
1515
<http://www.w3.org/TR/xml-exc-c14n/#def-InclusiveNamespaces-PrefixList>`_, required to verify signatures generated by
1616
some SAML implementations)
17-
* Modern Python compatibility (2.7-3.6+ and PyPy)
17+
* Modern Python compatibility (2.7-3.8+ and PyPy)
1818
* Well-supported, portable, reliable dependencies: `lxml <https://github.com/lxml/lxml>`_, `defusedxml
1919
<https://bitbucket.org/tiran/defusedxml>`_, `cryptography <https://github.com/pyca/cryptography>`_, `eight
2020
<https://github.com/kislyuk/eight>`_, `pyOpenSSL <https://github.com/pyca/pyopenssl>`_
@@ -53,18 +53,28 @@ Note: SignXML depends on `lxml <https://github.com/lxml/lxml>`_ and `cryptograph
5353
Synopsis
5454
--------
5555

56-
SignXML uses the ElementTree API (also supported by lxml) to work with XML data.
56+
SignXML uses the `lxml ElementTree API <https://lxml.de/tutorial.html>`_ to work with XML data. See the
57+
*Compatibility with xml.etree.ElementTree* section below for some subtle differences.
5758

5859
.. code-block:: python
5960
61+
from lxml import etree
6062
from signxml import XMLSigner, XMLVerifier
6163
62-
cert = open("example.pem").read()
63-
key = open("example.key").read()
64-
root = ElementTree.fromstring(data_to_sign)
64+
data_to_sign = "<Test/>"
65+
cert = open("example.pem", "rb").read()
66+
key = open("example.key", "rb").read()
67+
root = etree.fromstring(data_to_sign)
6568
signed_root = XMLSigner().sign(root, key=key, cert=cert)
6669
verified_data = XMLVerifier().verify(signed_root).signed_xml
6770
71+
To make this example self-sufficient for test purposes:
72+
73+
- Generate a test certificate and key using
74+
``openssl req -x509 -sha256 -nodes -subj "/CN=test" -days 1 -newkey rsa:2048 -keyout example.key -out example.pem``.
75+
- Pass the ``x509_cert=cert`` keyword argument to ``XMLVerifier.verify()``. (In production, ensure this is replaced with
76+
the correct configuration for the trusted CA or certificate - this determines which signatures your software trusts.)
77+
6878
.. _verifying-saml-assertions:
6979

7080
Verifying SAML assertions
@@ -131,6 +141,14 @@ For detached signatures, the code above will use the ``Id`` or ``ID`` attribute
131141

132142
See the `API documentation <https://signxml.readthedocs.io/en/latest/#id4>`_ for more.
133143

144+
Compatibility with ``xml.etree.ElementTree``
145+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
146+
SignXML uses the `lxml <https://github.com/lxml/lxml>`_ ElementTree library, not the
147+
`ElementTree from Python's standard library <https://docs.python.org/3.8/library/xml.etree.elementtree.html>`_,
148+
to work with XML. lxml is used due to its XML canonicalization and namespace organization features. Using SignXML
149+
with ``xml.etree.ElementTree`` is possible, but care must be taken to work around some of its namespace manipulation
150+
issues, as covered in `this blog post <https://technotes.shemyak.com/posts/xml-signatures-with-python-elementtree/>`_.
151+
134152
Authors
135153
-------
136154
* Andrey Kislyuk

0 commit comments

Comments
 (0)