Skip to content

Commit

Permalink
Fully remove the ca_path parameter; add docs for signature location p…
Browse files Browse the repository at this point in the history
…inning
  • Loading branch information
kislyuk committed Sep 20, 2024
1 parent 5fbc7df commit 46f7712
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 19 deletions.
12 changes: 9 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,14 @@ Assuming ``metadata.xml`` contains SAML metadata for the assertion source:
`SAML signature wrapping <https://www.usenix.org/system/files/conference/usenixsecurity12/sec12-final91.pdf>`_.

In SignXML, you can ensure that the information signed is what you expect to be signed by only trusting the
data returned by the ``verify()`` method. The ``signed_xml`` attribute of the return value is the XML node or string that
was signed.
data returned by ``XMLVerifier.verify()``. The ``signed_xml`` attribute of the return value is the XML node or string
that was signed. We also recommend that you assert the expected location for the signature within the document:

.. code-block:: python
XMLVerifier.verify(
expect_config=SignatureConfiguration(location="./{urn:oasis:names:tc:SAML:2.0:assertion}Assertion")
)
**Recommended reading:** `W3C XML Signature Best Practices for Applications
<http://www.w3.org/TR/xmldsig-bestpractices/#practices-applications>`_, `On Breaking SAML: Be Whoever You Want to Be
Expand All @@ -106,7 +112,7 @@ Assuming ``metadata.xml`` contains SAML metadata for the assertion source:
``x509_cert`` argument to specify a certificate that was pre-shared out-of-band (e.g. via SAML metadata, as
shown in *Verifying SAML assertions*), or ``cert_subject_name`` to specify a
subject name that must be in the signing X.509 certificate given by the signature (verified as if it were a
domain name), or ``ca_pem_file``/``ca_path`` to give a custom CA.
domain name), or ``ca_pem_file`` to give a custom CA.

XML signature construction methods: enveloped, detached, enveloping
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand Down
6 changes: 1 addition & 5 deletions signxml/util/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,14 +225,10 @@ class X509CertChainVerifier:
contact SignXML maintainers.
"""

def __init__(self, ca_pem_file=None, ca_path=None, verification_time=None):
def __init__(self, ca_pem_file=None, verification_time=None):
if ca_pem_file is None:
ca_pem_file = certifi.where()
self.ca_pem_file = ca_pem_file
if ca_path is not None:
msg = "CApath is not supported. If you need this feature, please contact SignXML maintainers."
raise NotImplementedError(msg)

self.verification_time = verification_time

@property
Expand Down
13 changes: 4 additions & 9 deletions signxml/verifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,8 @@ def _apply_transforms(self, payload, *, transforms_node: etree._Element, signatu

return payload

def get_cert_chain_verifier(self, ca_pem_file, ca_path):
return X509CertChainVerifier(ca_pem_file=ca_pem_file, ca_path=ca_path)
def get_cert_chain_verifier(self, ca_pem_file):
return X509CertChainVerifier(ca_pem_file=ca_pem_file)

def _match_key_values(self, key_value, der_encoded_key_value, signing_cert, signature_alg):
if self.config.ignore_ambiguous_key_info is False:
Expand Down Expand Up @@ -279,7 +279,6 @@ def verify(
cert_subject_name: Optional[str] = None,
cert_resolver: Optional[Callable] = None,
ca_pem_file: Optional[Union[str, bytes]] = None,
ca_path: Optional[str] = None,
hmac_key: Optional[str] = None,
validate_schema: bool = True,
parser=None,
Expand Down Expand Up @@ -316,7 +315,7 @@ def verify(
``x509_cert`` argument to specify a certificate that was pre-shared out-of-band (e.g. via SAML metadata, as
shown in :ref:`Verifying SAML assertions <verifying-saml-assertions>`), or ``cert_subject_name`` to specify a
subject name that must be in the signing X.509 certificate given by the signature (verified as if it were a
domain name), or ``ca_pem_file``/``ca_path`` to give a custom CA.
domain name), or ``ca_pem_file`` to give a custom CA.
:param data: Signature data to verify
:type data: String, file-like object, or XML ElementTree Element API compatible object
Expand All @@ -336,10 +335,6 @@ def verify(
:param ca_pem_file:
Filename of a PEM file containing certificate authority information to use when verifying certificate-based
signatures.
:param ca_path:
Path to a directory containing PEM-formatted certificate authority files to use when verifying
certificate-based signatures. If neither **ca_pem_file** nor **ca_path** is given, the Mozilla CA bundle
provided by :py:mod:`certifi` will be loaded.
:param hmac_key: If using HMAC, a string containing the shared secret.
:param validate_schema: Whether to validate **data** against the XML Signature schema.
:param parser:
Expand Down Expand Up @@ -433,7 +428,7 @@ def verify(
else:
cert_chain = [x509.load_pem_x509_certificate(add_pem_header(cert)) for cert in certs]

cert_verifier = self.get_cert_chain_verifier(ca_pem_file=ca_pem_file, ca_path=ca_path)
cert_verifier = self.get_cert_chain_verifier(ca_pem_file=ca_pem_file)

signing_cert = cert_verifier.verify(cert_chain)
elif isinstance(self.x509_cert, x509.Certificate):
Expand Down
4 changes: 2 additions & 2 deletions test/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ def reset_tree(t, method):

def get_verifier_for_year(year: int):
class _Verifier(XMLVerifier):
def get_cert_chain_verifier(self, ca_pem_file, ca_path):
verifier = super().get_cert_chain_verifier(ca_pem_file, ca_path)
def get_cert_chain_verifier(self, ca_pem_file):
verifier = super().get_cert_chain_verifier(ca_pem_file)
verifier.verification_time = datetime(year, 1, 1)
return verifier

Expand Down

0 comments on commit 46f7712

Please sign in to comment.