Fixed making redirect signature work, cleaned up.

This commit is contained in:
Roland Hedberg
2014-12-15 13:04:56 +01:00
parent 3d2fe2332a
commit cf577a42ca
5 changed files with 38 additions and 22 deletions

View File

@@ -641,8 +641,8 @@ class Entity(HTTPBase):
only_valid_cert = False only_valid_cert = False
if only_valid_cert: if only_valid_cert:
must = True must = True
_request = _request.loads(xmlstr, binding, origdoc=enc_request, must=must, _request = _request.loads(xmlstr, binding, origdoc=enc_request,
only_valid_cert=only_valid_cert) must=must, only_valid_cert=only_valid_cert)
_log_debug("Loaded request") _log_debug("Loaded request")

View File

@@ -1,7 +1,7 @@
import logging import logging
from attribute_converter import to_local from attribute_converter import to_local
from saml2 import time_util from saml2 import time_util, BINDING_HTTP_REDIRECT
from saml2.s_utils import OtherError from saml2.s_utils import OtherError
from saml2.validate import valid_instance from saml2.validate import valid_instance
@@ -38,6 +38,9 @@ class Request(object):
def _loads(self, xmldata, binding=None, origdoc=None, must=None, def _loads(self, xmldata, binding=None, origdoc=None, must=None,
only_valid_cert=False): only_valid_cert=False):
if binding == BINDING_HTTP_REDIRECT:
pass
# own copy # own copy
self.xmlstr = xmldata[:] self.xmlstr = xmldata[:]
logger.info("xmlstr: %s" % (self.xmlstr,)) logger.info("xmlstr: %s" % (self.xmlstr,))
@@ -87,8 +90,10 @@ class Request(object):
assert self.issue_instant_ok() assert self.issue_instant_ok()
return self return self
def loads(self, xmldata, binding, origdoc=None, must=None, only_valid_cert=False): def loads(self, xmldata, binding, origdoc=None, must=None,
return self._loads(xmldata, binding, origdoc, must, only_valid_cert=only_valid_cert) only_valid_cert=False):
return self._loads(xmldata, binding, origdoc, must,
only_valid_cert=only_valid_cert)
def verify(self): def verify(self):
try: try:

View File

@@ -12,18 +12,18 @@ import importlib
import shelve import shelve
import threading import threading
from saml2.eptid import EptidShelve, Eptid from saml2 import saml
from saml2.saml import EncryptedAssertion from saml2 import element_to_extension_element
from saml2.sdb import SessionStorage
from saml2.schema import soapenv
from saml2.samlp import NameIDMappingResponse
from saml2.entity import Entity
from saml2 import saml, element_to_extension_element
from saml2 import class_name from saml2 import class_name
from saml2 import BINDING_HTTP_REDIRECT from saml2 import BINDING_HTTP_REDIRECT
from saml2.entity import Entity
from saml2.eptid import Eptid
from saml2.eptid import EptidShelve
from saml2.samlp import NameIDMappingResponse
from saml2.sdb import SessionStorage
from saml2.schema import soapenv
from saml2.request import AuthnRequest from saml2.request import AuthnRequest
from saml2.request import AssertionIDRequest from saml2.request import AssertionIDRequest
from saml2.request import AttributeQuery from saml2.request import AttributeQuery
@@ -33,7 +33,9 @@ from saml2.request import AuthnQuery
from saml2.s_utils import MissingValue, Unknown, rndstr from saml2.s_utils import MissingValue, Unknown, rndstr
from saml2.sigver import pre_signature_part, signed_instance_factory, CertificateError, CryptoBackendXmlSec1 from saml2.sigver import pre_signature_part
from saml2.sigver import signed_instance_factory
from saml2.sigver import CertificateError
from saml2.assertion import Assertion from saml2.assertion import Assertion
from saml2.assertion import Policy from saml2.assertion import Policy

View File

@@ -608,7 +608,7 @@ REQ_ORDER = ["SAMLRequest", "RelayState", "SigAlg"]
RESP_ORDER = ["SAMLResponse", "RelayState", "SigAlg"] RESP_ORDER = ["SAMLResponse", "RelayState", "SigAlg"]
def verify_redirect_signature(saml_msg, cert): def verify_redirect_signature(saml_msg, cert=None, sigkey=None):
""" """
:param saml_msg: A dictionary as produced by parse_qs, means all values are :param saml_msg: A dictionary as produced by parse_qs, means all values are
@@ -622,7 +622,7 @@ def verify_redirect_signature(saml_msg, cert):
except KeyError: except KeyError:
raise Unsupported("Signature algorithm: %s" % saml_msg["SigAlg"]) raise Unsupported("Signature algorithm: %s" % saml_msg["SigAlg"])
else: else:
if saml_msg["SigAlg"][0] == SIG_RSA_SHA1: if saml_msg["SigAlg"][0] in SIGNER_ALGS:
if "SAMLRequest" in saml_msg: if "SAMLRequest" in saml_msg:
_order = REQ_ORDER _order = REQ_ORDER
elif "SAMLResponse" in saml_msg: elif "SAMLResponse" in saml_msg:
@@ -635,7 +635,10 @@ def verify_redirect_signature(saml_msg, cert):
del args["Signature"] # everything but the signature del args["Signature"] # everything but the signature
string = "&".join( string = "&".join(
[urllib.urlencode({k: args[k][0]}) for k in _order if k in args]) [urllib.urlencode({k: args[k][0]}) for k in _order if k in args])
_key = extract_rsa_key_from_x509_cert(pem_format(cert)) 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"][0])
return bool(signer.verify(string, _sign, _key)) return bool(signer.verify(string, _sign, _key))

View File

@@ -4,7 +4,6 @@
import base64 import base64
import urllib import urllib
import urlparse import urlparse
from Crypto.PublicKey import RSA
from xmldsig import SIG_RSA_SHA256 from xmldsig import SIG_RSA_SHA256
from saml2 import BINDING_HTTP_POST from saml2 import BINDING_HTTP_POST
from saml2 import BINDING_HTTP_REDIRECT from saml2 import BINDING_HTTP_REDIRECT
@@ -25,7 +24,8 @@ from saml2.saml import NAMEID_FORMAT_PERSISTENT, EncryptedAssertion
from saml2.saml import NAMEID_FORMAT_TRANSIENT from saml2.saml import NAMEID_FORMAT_TRANSIENT
from saml2.saml import NameID from saml2.saml import NameID
from saml2.server import Server from saml2.server import Server
from saml2.sigver import pre_encryption_part, rm_xmltag from saml2.sigver import pre_encryption_part, rm_xmltag, \
verify_redirect_signature
from saml2.s_utils import do_attribute_statement from saml2.s_utils import do_attribute_statement
from saml2.s_utils import factory from saml2.s_utils import factory
from saml2.time_util import in_a_while from saml2.time_util import in_a_while
@@ -497,7 +497,7 @@ class TestClient:
def test_signed_redirect(self): def test_signed_redirect(self):
msg_str = "%s" % self.client.create_authn_request( msg_str = "%s" % self.client.create_authn_request(
"http://www.example.com/sso", message_id="id1")[1] "http://localhost:8088/sso", message_id="id1")[1]
key = self.client.signkey key = self.client.signkey
@@ -508,7 +508,13 @@ class TestClient:
loc = info["headers"][0][1] loc = info["headers"][0][1]
qs = urlparse.parse_qs(loc[1:]) qs = urlparse.parse_qs(loc[1:])
assert _leq(qs.keys(), assert _leq(qs.keys(),
['SigAlg', 'SAMLRequest', 'RelayState', 'Signature']) ['SigAlg', 'SAMLRequest', 'RelayState', 'Signature'])
assert verify_redirect_signature(qs, sigkey=key)
res = self.server.parse_authn_request(qs["SAMLRequest"][0],
BINDING_HTTP_REDIRECT)
print res
# Below can only be done with dummy Server # Below can only be done with dummy Server
IDP = "urn:mace:example.com:saml:roland:idp" IDP = "urn:mace:example.com:saml:roland:idp"