summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Kanakarakis <ivan.kanak@gmail.com>2021-12-21 01:23:44 +0200
committerIvan Kanakarakis <ivan.kanak@gmail.com>2021-12-21 01:25:20 +0200
commit4122e36369bdd2340165425a6ca9ea237e592846 (patch)
treeeb90ab1a7401e49333628cd50f3525f01eff70a8
parent3b5b7c70241315d2794ace3d4e13116495a7b4e3 (diff)
downloadpysaml2-4122e36369bdd2340165425a6ca9ea237e592846.tar.gz
metadata: Verify signature with both EntitiesDescriptor and EntityDescriptor
Signed-off-by: Ivan Kanakarakis <ivan.kanak@gmail.com>
-rw-r--r--src/saml2/mdstore.py52
1 files changed, 45 insertions, 7 deletions
diff --git a/src/saml2/mdstore.py b/src/saml2/mdstore.py
index 105d8509..5fdf8344 100644
--- a/src/saml2/mdstore.py
+++ b/src/saml2/mdstore.py
@@ -30,6 +30,7 @@ from saml2.extension.idpdisc import BINDING_DISCO
from saml2.extension.idpdisc import DiscoveryResponse
from saml2.md import NAMESPACE as NS_MD
from saml2.md import EntitiesDescriptor
+from saml2.md import EntityDescriptor
from saml2.md import ArtifactResolutionService
from saml2.md import NameIDMappingService
from saml2.md import SingleSignOnService
@@ -44,6 +45,7 @@ from saml2.time_util import add_duration
from saml2.time_util import before
from saml2.time_util import str_to_time
from saml2.validate import NotValid
+from saml2.sigver import SignatureError
from saml2.sigver import security_context
from saml2.extension.mdattr import NAMESPACE as NS_MDATTR
from saml2.extension.mdattr import EntityAttributes
@@ -742,14 +744,50 @@ class InMemoryMetaData(MetaData):
if not self.signed():
return True
- fallback_name = "{ns}:{tag}".format(
- ns=md.EntitiesDescriptor.c_namespace, tag=md.EntitiesDescriptor.c_tag
- )
- node_name = self.node_name or fallback_name
+ if self.node_name is not None:
+ try:
+ self.security.verify_signature(
+ txt, node_name=self.node_name, cert_file=self.cert
+ )
+ except SignatureError as e:
+ error_context = {
+ "message": "Failed to verify signature",
+ "node_name": self.node_name,
+ }
+ raise SignatureError(error_context) from e
+ else:
+ return True
+
+ def try_verify_signature(node_name):
+ try:
+ self.security.verify_signature(
+ txt, node_name=node_name, cert_file=self.cert
+ )
+ except SignatureError as e:
+ return False
+ else:
+ return True
+
+ descriptor_names = [
+ f"{ns}:{tag}"
+ for ns, tag in [
+ (EntitiesDescriptor.c_namespace, EntitiesDescriptor.c_tag),
+ (EntityDescriptor.c_namespace, EntityDescriptor.c_tag),
+ ]
+ ]
- return self.security.verify_signature(
- txt, node_name=node_name, cert_file=self.cert
+ verified_w_descriptor_name = any(
+ try_verify_signature(node_name)
+ for node_name in descriptor_names
)
+ if not verified_w_descriptor_name:
+ error_context = {
+ "message": "Failed to verify signature",
+ "descriptor_names": descriptor_names,
+ }
+ raise SignatureError(error_context)
+
+ return verified_w_descriptor_name
class MetaDataFile(InMemoryMetaData):
@@ -926,7 +964,7 @@ class MetaDataMDX(InMemoryMetaData):
# that use case since it is unlikely to be leveraged for most
# flows.
self.node_name = "{ns}:{tag}".format(
- ns=md.EntityDescriptor.c_namespace, tag=md.EntityDescriptor.c_tag
+ ns=EntityDescriptor.c_namespace, tag=EntityDescriptor.c_tag
)
def load(self, *args, **kwargs):