diff --git a/src/saml2/sigver.py b/src/saml2/sigver.py index 5b83df4..e598781 100644 --- a/src/saml2/sigver.py +++ b/src/saml2/sigver.py @@ -611,18 +611,18 @@ RESP_ORDER = ["SAMLResponse", "RelayState", "SigAlg"] def verify_redirect_signature(saml_msg, cert=None, sigkey=None): """ - :param saml_msg: A dictionary as produced by parse_qs, means all values are - lists. + :param saml_msg: A dictionary with strings as values, *NOT* lists as + produced by parse_qs. :param cert: A certificate to use when verifying the signature :return: True, if signature verified """ try: - signer = SIGNER_ALGS[saml_msg["SigAlg"][0]] + signer = SIGNER_ALGS[saml_msg["SigAlg"]] except KeyError: raise Unsupported("Signature algorithm: %s" % saml_msg["SigAlg"]) else: - if saml_msg["SigAlg"][0] in SIGNER_ALGS: + if saml_msg["SigAlg"] in SIGNER_ALGS: if "SAMLRequest" in saml_msg: _order = REQ_ORDER elif "SAMLResponse" in saml_msg: @@ -631,15 +631,15 @@ def verify_redirect_signature(saml_msg, cert=None, sigkey=None): raise Unsupported( "Verifying signature on something that should not be " "signed") - args = saml_msg.copy() - del args["Signature"] # everything but the signature + _args = saml_msg.copy() + del _args["Signature"] # everything but the signature string = "&".join( - [urllib.urlencode({k: args[k][0]}) for k in _order if k in args]) + [urllib.urlencode({k: _args[k]}) for k in _order if k in _args]) if cert: _key = extract_rsa_key_from_x509_cert(pem_format(cert)) else: _key = sigkey - _sign = base64.b64decode(saml_msg["Signature"][0]) + _sign = base64.b64decode(saml_msg["Signature"]) return bool(signer.verify(string, _sign, _key)) diff --git a/tests/test_51_client.py b/tests/test_51_client.py index fc89870..5e4c0b2 100644 --- a/tests/test_51_client.py +++ b/tests/test_51_client.py @@ -24,8 +24,9 @@ from saml2.saml import NAMEID_FORMAT_PERSISTENT, EncryptedAssertion from saml2.saml import NAMEID_FORMAT_TRANSIENT from saml2.saml import NameID from saml2.server import Server -from saml2.sigver import pre_encryption_part, rm_xmltag, \ - verify_redirect_signature +from saml2.sigver import pre_encryption_part +from saml2.sigver import rm_xmltag +from saml2.sigver import verify_redirect_signature from saml2.s_utils import do_attribute_statement from saml2.s_utils import factory from saml2.time_util import in_a_while @@ -114,6 +115,10 @@ nid = NameID(name_qualifier="foo", format=NAMEID_FORMAT_TRANSIENT, text="123456") +def list_values2simpletons(_dict): + return dict([(k, v[0]) for k, v in _dict.items()]) + + class TestClient: def setup_class(self): self.server = Server("idp_conf") @@ -510,7 +515,8 @@ class TestClient: assert _leq(qs.keys(), ['SigAlg', 'SAMLRequest', 'RelayState', 'Signature']) - assert verify_redirect_signature(qs, sigkey=key) + assert verify_redirect_signature(list_values2simpletons(qs), + sigkey=key) res = self.server.parse_authn_request(qs["SAMLRequest"][0], BINDING_HTTP_REDIRECT) diff --git a/tests/test_70_redirect_signing.py b/tests/test_70_redirect_signing.py index d54f70a..cb2ca0c 100644 --- a/tests/test_70_redirect_signing.py +++ b/tests/test_70_redirect_signing.py @@ -13,6 +13,11 @@ from pathutils import dotname __author__ = 'rolandh' + +def list_values2simpletons(_dict): + return dict([(k, v[0]) for k, v in _dict.items()]) + + def test(): with closing(Server(config_file=dotname("idp_all_conf"))) as idp: conf = SPConfig() @@ -41,7 +46,12 @@ def test(): _dict = parse_qs(val.split("?")[1]) _certs = idp.metadata.certs(sp.config.entityid, "any", "signing") for cert in _certs: - if verify_redirect_signature(_dict, cert): + if verify_redirect_signature( + list_values2simpletons(_dict), cert): verified_ok = True assert verified_ok + + +if __name__ == "__main__": + test() \ No newline at end of file