Fixed making redirect signature work, cleaned up.
This commit is contained in:
@@ -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")
|
||||||
|
|
||||||
|
@@ -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:
|
||||||
|
@@ -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
|
||||||
|
@@ -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])
|
||||||
|
if cert:
|
||||||
_key = extract_rsa_key_from_x509_cert(pem_format(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))
|
||||||
|
@@ -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
|
||||||
|
|
||||||
@@ -510,6 +510,12 @@ class TestClient:
|
|||||||
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"
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user