From 8a7c03ec47dd094836f1e9587b5aef0cd88222f6 Mon Sep 17 00:00:00 2001 From: Sergei Maertens Date: Thu, 19 Dec 2024 11:29:17 +0100 Subject: [PATCH] :test_tube: [open-formulieren/open-forms#4785] Add test for unexpected 'use' attribute Per the standard, key descriptors elements must contain at least one key that is used for signing and at least one key used for encryption, OR, if both are done with a single key, the 'use' attribute must not be specified to imply the default behaviour. See https://afsprakenstelsel.etoegang.nl/Startpagina/v3/dv-metadata-for-hm version AS1.24a --- tests/test_eherkenning_metadata.py | 142 ++++++++++++++++------------- 1 file changed, 80 insertions(+), 62 deletions(-) diff --git a/tests/test_eherkenning_metadata.py b/tests/test_eherkenning_metadata.py index f9c0242..a50d147 100644 --- a/tests/test_eherkenning_metadata.py +++ b/tests/test_eherkenning_metadata.py @@ -182,40 +182,56 @@ def test_generate_metadata_all_options_specified(self): "http://test-entity.id", entity_descriptor_node.attrib["entityID"] ) - sspo_descriptor_node = entity_descriptor_node.find( - ".//md:SPSSODescriptor", - namespaces=NAME_SPACES, - ) + with self.subTest("metadata signature"): + certificate_node = entity_descriptor_node.find( + ".//ds:X509Certificate", + namespaces=NAME_SPACES, + ) + self.assertIn( + "MIIC0DCCAbigAwIBAgIUEjGmfCGa1cOiTi+UKtDQVtySOHUwDQYJKoZIhvcNAQEL", + certificate_node.text, + ) - self.assertEqual("true", sspo_descriptor_node.attrib["AuthnRequestsSigned"]) - self.assertEqual("true", sspo_descriptor_node.attrib["WantAssertionsSigned"]) + signature_algorithm_node = entity_descriptor_node.find( + ".//ds:SignatureMethod", + namespaces=NAME_SPACES, + ) + self.assertEqual( + "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", + signature_algorithm_node.attrib["Algorithm"], + ) - certificate_node = entity_descriptor_node.find( - ".//ds:X509Certificate", - namespaces=NAME_SPACES, - ) - self.assertIn( - "MIIC0DCCAbigAwIBAgIUEjGmfCGa1cOiTi+UKtDQVtySOHUwDQYJKoZIhvcNAQEL", - certificate_node.text, - ) + digest_algorithm_node = entity_descriptor_node.find( + ".//ds:DigestMethod", + namespaces=NAME_SPACES, + ) + self.assertEqual( + "http://www.w3.org/2001/04/xmlenc#sha256", + digest_algorithm_node.attrib["Algorithm"], + ) - signature_algorithm_node = entity_descriptor_node.find( - ".//ds:SignatureMethod", - namespaces=NAME_SPACES, - ) - self.assertEqual( - "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", - signature_algorithm_node.attrib["Algorithm"], - ) + with self.subTest("SPSSODescriptor"): + sspo_descriptor_node = entity_descriptor_node.find( + ".//md:SPSSODescriptor", + namespaces=NAME_SPACES, + ) + assert sspo_descriptor_node is not None - digest_algorithm_node = entity_descriptor_node.find( - ".//ds:DigestMethod", - namespaces=NAME_SPACES, - ) - self.assertEqual( - "http://www.w3.org/2001/04/xmlenc#sha256", - digest_algorithm_node.attrib["Algorithm"], - ) + self.assertEqual("true", sspo_descriptor_node.attrib["AuthnRequestsSigned"]) + self.assertEqual( + "true", sspo_descriptor_node.attrib["WantAssertionsSigned"] + ) + + with self.subTest("key descriptors"): + key_descriptor_nodes = sspo_descriptor_node.findall( + ".//md:KeyDescriptor", namespaces=NAME_SPACES + ) + self.assertEqual(len(key_descriptor_nodes), 1) + + key_descriptor_node = key_descriptor_nodes[0] + # use attribute should not be specified if it's used for both signing and + # encryption + self.assertNotIn("use", key_descriptor_node.attrib) assertion_consuming_service_node = entity_descriptor_node.find( ".//md:AssertionConsumerService", @@ -279,41 +295,43 @@ def test_generate_metadata_all_options_specified(self): ).text, ) - organisation_name_node = entity_descriptor_node.find( - ".//md:OrganizationName", - namespaces=NAME_SPACES, - ) - self.assertEqual("Test organisation", organisation_name_node.text) + with self.subTest("organization details"): + organisation_name_node = entity_descriptor_node.find( + ".//md:OrganizationName", + namespaces=NAME_SPACES, + ) + self.assertEqual("Test organisation", organisation_name_node.text) - organisation_display_node = entity_descriptor_node.find( - ".//md:OrganizationDisplayName", - namespaces=NAME_SPACES, - ) - self.assertEqual("Test organisation", organisation_display_node.text) + organisation_display_node = entity_descriptor_node.find( + ".//md:OrganizationDisplayName", + namespaces=NAME_SPACES, + ) + self.assertEqual("Test organisation", organisation_display_node.text) - organisation_url_node = entity_descriptor_node.find( - ".//md:OrganizationURL", - namespaces=NAME_SPACES, - ) - self.assertEqual("http://test-organisation.nl", organisation_url_node.text) + organisation_url_node = entity_descriptor_node.find( + ".//md:OrganizationURL", + namespaces=NAME_SPACES, + ) + self.assertEqual("http://test-organisation.nl", organisation_url_node.text) - contact_person_node = entity_descriptor_node.find( - ".//md:ContactPerson", - namespaces=NAME_SPACES, - ) - self.assertEqual("technical", contact_person_node.attrib["contactType"]) + with self.subTest("technical contact person details"): + contact_person_node = entity_descriptor_node.find( + ".//md:ContactPerson", + namespaces=NAME_SPACES, + ) + self.assertEqual("technical", contact_person_node.attrib["contactType"]) - contact_email_node = entity_descriptor_node.find( - ".//md:EmailAddress", - namespaces=NAME_SPACES, - ) - self.assertEqual("test@test.nl", contact_email_node.text) + contact_email_node = entity_descriptor_node.find( + ".//md:EmailAddress", + namespaces=NAME_SPACES, + ) + self.assertEqual("test@test.nl", contact_email_node.text) - contact_telephone_node = entity_descriptor_node.find( - ".//md:TelephoneNumber", - namespaces=NAME_SPACES, - ) - self.assertEqual("06123123123", contact_telephone_node.text) + contact_telephone_node = entity_descriptor_node.find( + ".//md:TelephoneNumber", + namespaces=NAME_SPACES, + ) + self.assertEqual("06123123123", contact_telephone_node.text) def test_contact_telephone_no_email(self): self.eherkenning_config.technical_contact_person_telephone = "06123123123" @@ -418,8 +436,8 @@ def test_current_and_next_certificate_in_metadata( key_nodes = metadata_node.findall("md:KeyDescriptor", namespaces=NAME_SPACES) assert len(key_nodes) == 2 # we expect current + next key key1_node, key2_node = key_nodes - assert key1_node.attrib["use"] == "signing" - assert key2_node.attrib["use"] == "signing" + assert "use" not in key1_node.attrib + assert "use" not in key2_node.attrib with ( eherkenning_certificate.public_certificate.open("r") as _current,