From 3b84f65d849c2035636e1691ae0d35fe664640b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Ho=CC=88rberg?= Date: Fri, 6 Nov 2015 12:17:34 +0100 Subject: [PATCH 1/6] Added the possibility to set signature and digest algorithm on all the functions I identified. pysaml2 has a default value for sign and digest. To make it possible to always use the same algorithm this default value has been replaced with a singleton class. The first time the singleton class is instantiated the sign and digest algorithm will be set. After that it cannot be changed. A good place to setup this single class is in the server setup. Example: ds.DefaultSignature(ds.SIG_RSA_SHA512, ds.DIGEST_SHA512) --- setup.py | 1 + src/saml2/client.py | 16 +- src/saml2/client_base.py | 26 +- src/saml2/entity.py | 60 ++- src/saml2/metadata.py | 8 +- src/saml2/server.py | 40 +- src/saml2/sigver.py | 12 +- src/saml2/xmldsig/__init__.py | 789 ++++++++++++++++-------------- tests/test_50_server.py | 2 + tests/test_52_default_sign_alg.py | 175 +++++++ 10 files changed, 700 insertions(+), 429 deletions(-) create mode 100644 tests/test_52_default_sign_alg.py diff --git a/setup.py b/setup.py index 682daa2..341592b 100755 --- a/setup.py +++ b/setup.py @@ -43,6 +43,7 @@ tests_require = [ 'pytest', 'mako', 'webob', + 'mock' #'pytest-coverage', ] diff --git a/src/saml2/client.py b/src/saml2/client.py index 64871d6..c082a79 100644 --- a/src/saml2/client.py +++ b/src/saml2/client.py @@ -135,7 +135,7 @@ class Saml2Client(Base): raise SignOnError( "No supported bindings available for authentication") - def global_logout(self, name_id, reason="", expire=None, sign=None): + def global_logout(self, name_id, reason="", expire=None, sign=None, sign_alg=None, digest_alg=None): """ More or less a layer of indirection :-/ Bootstrapping the whole thing by finding all the IdPs that should be notified. @@ -160,10 +160,10 @@ class Saml2Client(Base): # find out which IdPs/AAs I should notify entity_ids = self.users.issuers_of_info(name_id) - return self.do_logout(name_id, entity_ids, reason, expire, sign) + return self.do_logout(name_id, entity_ids, reason, expire, sign, sign_alg=sign_alg) def do_logout(self, name_id, entity_ids, reason, expire, sign=None, - expected_binding=None, **kwargs): + expected_binding=None, sign_alg=None, digest_alg=None, **kwargs): """ :param name_id: Identifier of the Subject (a NameID instance) @@ -226,11 +226,11 @@ class Saml2Client(Base): key = None if sign: if binding == BINDING_HTTP_REDIRECT: - sigalg = kwargs.get("sigalg", ds.sig_default) + sigalg = kwargs.get("sigalg", ds.DefaultSignature().get_sign_alg()) key = kwargs.get("key", self.signkey) srequest = str(request) else: - srequest = self.sign(request) + srequest = self.sign(request, sign_alg=sign_alg) else: srequest = str(request) @@ -290,7 +290,7 @@ class Saml2Client(Base): identity = self.users.get_identity(name_id)[0] return bool(identity) - def handle_logout_response(self, response): + def handle_logout_response(self, response, sign_alg=None, digest_alg=None): """ handles a Logout response :param response: A response.Response instance @@ -309,10 +309,12 @@ class Saml2Client(Base): return 0, "200 Ok", [("Content-type", "text/html")], [] else: status["entity_ids"].remove(issuer) + if "sign_alg" in status: + sign_alg = status["sign_alg"] return self.do_logout(decode(status["name_id"]), status["entity_ids"], status["reason"], status["not_on_or_after"], - status["sign"]) + status["sign"], sign_alg=sign_alg) def _use_soap(self, destination, query_type, **kwargs): _create_func = getattr(self, "create_%s" % query_type) diff --git a/src/saml2/client_base.py b/src/saml2/client_base.py index b499e19..deddab2 100644 --- a/src/saml2/client_base.py +++ b/src/saml2/client_base.py @@ -202,7 +202,7 @@ class Base(Entity): nameid_format=None, service_url_binding=None, message_id=0, consent=None, extensions=None, sign=None, - allow_create=False, sign_prepare=False, **kwargs): + allow_create=False, sign_prepare=False, sign_alg=None, digest_alg=None, **kwargs): """ Creates an authentication request. :param destination: Where the request should be sent. @@ -339,15 +339,15 @@ class Base(Entity): return self._message(AuthnRequest, destination, message_id, consent, extensions, sign, sign_prepare, protocol_binding=binding, - scoping=scoping, nsprefix=nsprefix, **args) + scoping=scoping, nsprefix=nsprefix, sign_alg=sign_alg, **args) return self._message(AuthnRequest, destination, message_id, consent, extensions, sign, sign_prepare, protocol_binding=binding, - scoping=scoping, nsprefix=nsprefix, **args) + scoping=scoping, nsprefix=nsprefix, sign_alg=sign_alg, **args) def create_attribute_query(self, destination, name_id=None, attribute=None, message_id=0, consent=None, - extensions=None, sign=False, sign_prepare=False, + extensions=None, sign=False, sign_prepare=False, sign_alg=None, digest_alg=None, **kwargs): """ Constructs an AttributeQuery @@ -404,7 +404,7 @@ class Base(Entity): return self._message(AttributeQuery, destination, message_id, consent, extensions, sign, sign_prepare, subject=subject, - attribute=attribute, nsprefix=nsprefix) + attribute=attribute, nsprefix=nsprefix, sign_alg=sign_alg) # MUST use SOAP for # AssertionIDRequest, SubjectQuery, @@ -412,7 +412,7 @@ class Base(Entity): def create_authz_decision_query(self, destination, action, evidence=None, resource=None, subject=None, message_id=0, consent=None, extensions=None, - sign=None, **kwargs): + sign=None, sign_alg=None, digest_alg=None, **kwargs): """ Creates an authz decision query. :param destination: The IdP endpoint @@ -430,7 +430,7 @@ class Base(Entity): return self._message(AuthzDecisionQuery, destination, message_id, consent, extensions, sign, action=action, evidence=evidence, resource=resource, - subject=subject, **kwargs) + subject=subject, sign_alg=sign_alg, **kwargs) def create_authz_decision_query_using_assertion(self, destination, assertion, action=None, @@ -482,7 +482,7 @@ class Base(Entity): def create_authn_query(self, subject, destination=None, authn_context=None, session_index="", message_id=0, consent=None, - extensions=None, sign=False, nsprefix=None): + extensions=None, sign=False, nsprefix=None, sign_alg=None, digest_alg=None): """ :param subject: The subject its all about as a instance @@ -499,14 +499,14 @@ class Base(Entity): extensions, sign, subject=subject, session_index=session_index, requested_authn_context=authn_context, - nsprefix=nsprefix) + nsprefix=nsprefix, sign_alg=sign_alg) def create_name_id_mapping_request(self, name_id_policy, name_id=None, base_id=None, encrypted_id=None, destination=None, message_id=0, consent=None, extensions=None, sign=False, - nsprefix=None): + nsprefix=None, sign_alg=None, digest_alg=None): """ :param name_id_policy: @@ -528,17 +528,17 @@ class Base(Entity): return self._message(NameIDMappingRequest, destination, message_id, consent, extensions, sign, name_id_policy=name_id_policy, name_id=name_id, - nsprefix=nsprefix) + nsprefix=nsprefix, sign_alg=sign_alg) elif base_id: return self._message(NameIDMappingRequest, destination, message_id, consent, extensions, sign, name_id_policy=name_id_policy, base_id=base_id, - nsprefix=nsprefix) + nsprefix=nsprefix, sign_alg=sign_alg) else: return self._message(NameIDMappingRequest, destination, message_id, consent, extensions, sign, name_id_policy=name_id_policy, - encrypted_id=encrypted_id, nsprefix=nsprefix) + encrypted_id=encrypted_id, nsprefix=nsprefix, sign_alg=sign_alg) # ======== response handling =========== diff --git a/src/saml2/entity.py b/src/saml2/entity.py index 60de964..f816677 100644 --- a/src/saml2/entity.py +++ b/src/saml2/entity.py @@ -409,9 +409,9 @@ class Entity(HTTPBase): # -------------------------------------------------------------------------- - def sign(self, msg, mid=None, to_sign=None, sign_prepare=False): + def sign(self, msg, mid=None, to_sign=None, sign_prepare=False, sign_alg=None, digest_alg=None): if msg.signature is None: - msg.signature = pre_signature_part(msg.id, self.sec.my_cert, 1) + msg.signature = pre_signature_part(msg.id, self.sec.my_cert, 1, sign_alg=sign_alg) if sign_prepare: return msg @@ -429,7 +429,7 @@ class Entity(HTTPBase): def _message(self, request_cls, destination=None, message_id=0, consent=None, extensions=None, sign=False, sign_prepare=False, - nsprefix=None, **kwargs): + nsprefix=None, sign_alg=None, digest_alg=None, **kwargs): """ Some parameters appear in all requests so simplify by doing it in one place @@ -468,7 +468,7 @@ class Entity(HTTPBase): req.register_prefix(nsprefix) if sign: - return reqid, self.sign(req, sign_prepare=sign_prepare) + return reqid, self.sign(req, sign_prepare=sign_prepare, sign_alg=sign_alg) else: logger.info("REQUEST: %s" % req) return reqid, req @@ -559,8 +559,10 @@ class Entity(HTTPBase): def _response(self, in_response_to, consumer_url=None, status=None, issuer=None, sign=False, to_sign=None, sp_entity_id=None, - encrypt_assertion=False, encrypt_assertion_self_contained=False, encrypted_advice_attributes=False, - encrypt_cert_advice=None, encrypt_cert_assertion=None,sign_assertion=None, pefim=False, **kwargs): + encrypt_assertion=False, encrypt_assertion_self_contained=False, + encrypted_advice_attributes=False, + encrypt_cert_advice=None, encrypt_cert_assertion=None,sign_assertion=None, + pefim=False, sign_alg=None, digest_alg=None, **kwargs): """ Create a Response. Encryption: encrypt_assertion must be true for encryption to be performed. If encrypted_advice_attributes also is @@ -596,7 +598,7 @@ class Entity(HTTPBase): response = response_factory(issuer=_issuer, in_response_to=in_response_to, - status=status) + status=status, sign_alg=sign_alg) if consumer_url: response.destination = consumer_url @@ -616,7 +618,7 @@ class Entity(HTTPBase): len(response.assertion.advice.assertion) == 1): if sign: response.signature = pre_signature_part(response.id, - self.sec.my_cert, 1) + self.sec.my_cert, 1, sign_alg=sign_alg) sign_class = [(class_name(response), response.id)] cbxs = CryptoBackendXmlSec1(self.config.xmlsec_binary) encrypt_advice = False @@ -635,7 +637,9 @@ class Entity(HTTPBase): for tmp_assertion in _advice_assertions: to_sign_advice = [] if sign_assertion and not pefim: - tmp_assertion.signature = pre_signature_part(tmp_assertion.id, self.sec.my_cert, 1) + tmp_assertion.signature = pre_signature_part(tmp_assertion.id, + self.sec.my_cert, 1, + sign_alg=sign_alg) to_sign_advice.append((class_name(tmp_assertion), tmp_assertion.id)) #tmp_assertion = response.assertion.advice.assertion[0] _assertion.advice.encrypted_assertion[0].add_extension_element(tmp_assertion) @@ -661,7 +665,9 @@ class Entity(HTTPBase): if not isinstance(_assertions, list): _assertions = [_assertions] for _assertion in _assertions: - _assertion.signature = pre_signature_part(_assertion.id, self.sec.my_cert, 1) + _assertion.signature = pre_signature_part(_assertion.id, self.sec.my_cert, + 1, + sign_alg=sign_alg) to_sign_assertion.append((class_name(_assertion), _assertion.id)) if encrypt_assertion_self_contained: try: @@ -685,11 +691,11 @@ class Entity(HTTPBase): return response if sign: - return self.sign(response, to_sign=to_sign) + return self.sign(response, to_sign=to_sign, sign_alg=sign_alg) else: return response - def _status_response(self, response_class, issuer, status, sign=False, + def _status_response(self, response_class, issuer, status, sign=False, sign_alg=None, digest_alg=None, **kwargs): """ Create a StatusResponse. @@ -718,7 +724,7 @@ class Entity(HTTPBase): status=status, **kwargs) if sign: - return self.sign(response, mid) + return self.sign(response, mid, sign_alg=sign_alg) else: return response @@ -797,7 +803,7 @@ class Entity(HTTPBase): # ------------------------------------------------------------------------ def create_error_response(self, in_response_to, destination, info, - sign=False, issuer=None, **kwargs): + sign=False, issuer=None, sign_alg=None, digest_alg=None, **kwargs): """ Create a error response. :param in_response_to: The identifier of the message this is a response @@ -813,7 +819,7 @@ class Entity(HTTPBase): status = error_status_factory(info) return self._response(in_response_to, destination, status, issuer, - sign) + sign, sign_alg=sign_alg) # ------------------------------------------------------------------------ @@ -821,7 +827,7 @@ class Entity(HTTPBase): subject_id=None, name_id=None, reason=None, expire=None, message_id=0, consent=None, extensions=None, sign=False, - session_indexes=None): + session_indexes=None, sign_alg=None, digest_alg=None): """ Constructs a LogoutRequest :param destination: Destination of the request @@ -865,10 +871,10 @@ class Entity(HTTPBase): return self._message(LogoutRequest, destination, message_id, consent, extensions, sign, name_id=name_id, reason=reason, not_on_or_after=expire, - issuer=self._issuer(), **args) + issuer=self._issuer(), sign_alg=sign_alg, **args) def create_logout_response(self, request, bindings=None, status=None, - sign=False, issuer=None): + sign=False, issuer=None, sign_alg=None, digest_alg=None): """ Create a LogoutResponse. :param request: The request this is a response to @@ -886,14 +892,14 @@ class Entity(HTTPBase): issuer = self._issuer() response = self._status_response(samlp.LogoutResponse, issuer, status, - sign, **rinfo) + sign, sign_alg=sign_alg, **rinfo) logger.info("Response: %s" % (response,)) return response def create_artifact_resolve(self, artifact, destination, sessid, - consent=None, extensions=None, sign=False): + consent=None, extensions=None, sign=False, sign_alg=None, digest_alg=None): """ Create a ArtifactResolve request @@ -909,10 +915,10 @@ class Entity(HTTPBase): artifact = Artifact(text=artifact) return self._message(ArtifactResolve, destination, sessid, - consent, extensions, sign, artifact=artifact) + consent, extensions, sign, artifact=artifact, sign_alg=sign_alg) def create_artifact_response(self, request, artifact, bindings=None, - status=None, sign=False, issuer=None): + status=None, sign=False, issuer=None, sign_alg=None, digest_alg=None): """ Create an ArtifactResponse :return: @@ -920,7 +926,7 @@ class Entity(HTTPBase): rinfo = self.response_args(request, bindings) response = self._status_response(ArtifactResponse, issuer, status, - sign=sign, **rinfo) + sign=sign, sign_alg=sign_alg, **rinfo) msg = element_to_extension_element(self.artifact[artifact]) response.extension_elements = [msg] @@ -933,7 +939,7 @@ class Entity(HTTPBase): consent=None, extensions=None, sign=False, name_id=None, new_id=None, encrypted_id=None, new_encrypted_id=None, - terminate=None): + terminate=None, sign_alg=None, digest_alg=None): """ :param destination: @@ -969,7 +975,7 @@ class Entity(HTTPBase): "One of NewID, NewEncryptedNameID or Terminate has to be provided") return self._message(ManageNameIDRequest, destination, consent=consent, - extensions=extensions, sign=sign, **kwargs) + extensions=extensions, sign=sign, sign_alg=sign_alg, **kwargs) def parse_manage_name_id_request(self, xmlstr, binding=BINDING_SOAP): """ Deal with a LogoutRequest @@ -985,13 +991,13 @@ class Entity(HTTPBase): "manage_name_id_service", binding) def create_manage_name_id_response(self, request, bindings=None, - status=None, sign=False, issuer=None, + status=None, sign=False, issuer=None, sign_alg=None, digest_alg=None, **kwargs): rinfo = self.response_args(request, bindings) response = self._status_response(samlp.ManageNameIDResponse, issuer, - status, sign, **rinfo) + status, sign, sign_alg=sign_alg, **rinfo) logger.info("Response: %s" % (response,)) diff --git a/src/saml2/metadata.py b/src/saml2/metadata.py index eb33788..b095252 100644 --- a/src/saml2/metadata.py +++ b/src/saml2/metadata.py @@ -754,7 +754,7 @@ def entity_descriptor(confd): return entd -def entities_descriptor(eds, valid_for, name, ident, sign, secc): +def entities_descriptor(eds, valid_for, name, ident, sign, secc, sign_alg=None, digest_alg=None): entities = md.EntitiesDescriptor(entity_descriptor=eds) if valid_for: entities.valid_until = in_a_while(hours=valid_for) @@ -775,7 +775,7 @@ def entities_descriptor(eds, valid_for, name, ident, sign, secc): raise SAMLError("If you want to do signing you should define " + "where your public key are") - entities.signature = pre_signature_part(ident, secc.my_cert, 1) + entities.signature = pre_signature_part(ident, secc.my_cert, 1, sign_alg=sign_alg) entities.id = ident xmldoc = secc.sign_statement("%s" % entities, class_name(entities)) entities = md.entities_descriptor_from_string(xmldoc) @@ -785,7 +785,7 @@ def entities_descriptor(eds, valid_for, name, ident, sign, secc): return entities, xmldoc -def sign_entity_descriptor(edesc, ident, secc): +def sign_entity_descriptor(edesc, ident, secc, sign_alg=None, digest_alg=None): """ :param edesc: EntityDescriptor instance @@ -797,7 +797,7 @@ def sign_entity_descriptor(edesc, ident, secc): if not ident: ident = sid() - edesc.signature = pre_signature_part(ident, secc.my_cert, 1) + edesc.signature = pre_signature_part(ident, secc.my_cert, 1, sign_alg=sign_alg) edesc.id = ident xmldoc = secc.sign_statement("%s" % edesc, class_name(edesc)) edesc = md.entity_descriptor_from_string(xmldoc) diff --git a/src/saml2/server.py b/src/saml2/server.py index 7a38524..85f2f91 100644 --- a/src/saml2/server.py +++ b/src/saml2/server.py @@ -332,7 +332,8 @@ class Server(Entity): sign_assertion=False, sign_response=False, best_effort=False, encrypt_assertion=False, encrypt_cert_advice=None, encrypt_cert_assertion=None, authn_statement=None, - encrypt_assertion_self_contained=False, encrypted_advice_attributes=False, pefim=False): + encrypt_assertion_self_contained=False, encrypted_advice_attributes=False, pefim=False, + sign_alg=None, digest_alg=None): """ Create a response. A layer of indirection. :param in_response_to: The session identifier of the request @@ -397,7 +398,8 @@ class Server(Entity): to_sign = [] if not encrypt_assertion: if sign_assertion: - assertion.signature = pre_signature_part(assertion.id, self.sec.my_cert, 1) + assertion.signature = pre_signature_part(assertion.id, self.sec.my_cert, 1, + sign_alg=sign_alg) to_sign.append((class_name(assertion), assertion.id)) #if not encrypted_advice_attributes: @@ -420,12 +422,14 @@ class Server(Entity): self.session_db.store_assertion(assertion, to_sign) return self._response(in_response_to, consumer_url, status, issuer, - sign_response, to_sign,sp_entity_id=sp_entity_id, encrypt_assertion=encrypt_assertion, + sign_response, to_sign,sp_entity_id=sp_entity_id, + encrypt_assertion=encrypt_assertion, encrypt_cert_advice=encrypt_cert_advice, encrypt_cert_assertion=encrypt_cert_assertion, encrypt_assertion_self_contained=encrypt_assertion_self_contained, - encrypted_advice_attributes=encrypted_advice_attributes,sign_assertion=sign_assertion, - pefim=pefim, + encrypted_advice_attributes=encrypted_advice_attributes, + sign_assertion=sign_assertion, + pefim=pefim, sign_alg=sign_alg, **args) # ------------------------------------------------------------------------ @@ -435,7 +439,7 @@ class Server(Entity): sp_entity_id, userid="", name_id=None, status=None, issuer=None, sign_assertion=False, sign_response=False, - attributes=None, **kwargs): + attributes=None, sign_alg=None, digest_alg=None, **kwargs): """ Create an attribute assertion response. :param identity: A dictionary with attributes and values that are @@ -485,14 +489,14 @@ class Server(Entity): if sign_assertion: assertion.signature = pre_signature_part(assertion.id, - self.sec.my_cert, 1) + self.sec.my_cert, 1, sign_alg=sign_alg) # Just the assertion or the response and the assertion ? to_sign = [(class_name(assertion), assertion.id)] args["assertion"] = assertion return self._response(in_response_to, destination, status, issuer, - sign_response, to_sign, **args) + sign_response, to_sign, sign_alg=sign_alg, **args) # ------------------------------------------------------------------------ @@ -502,7 +506,7 @@ class Server(Entity): sign_response=None, sign_assertion=None, encrypt_cert_advice=None, encrypt_cert_assertion=None, encrypt_assertion=None, encrypt_assertion_self_contained=True, - encrypted_advice_attributes=False, pefim=False, + encrypted_advice_attributes=False, pefim=False, sign_alg=None, digest_alg=None, **kwargs): """ Constructs an AuthenticationResponse @@ -644,7 +648,8 @@ class Server(Entity): encrypted_advice_attributes=encrypted_advice_attributes, encrypt_cert_advice=encrypt_cert_advice, encrypt_cert_assertion=encrypt_cert_assertion, - pefim=pefim) + pefim=pefim, + sign_alg=sign_alg) return self._authn_response(in_response_to, # in_response_to destination, # consumer_url sp_entity_id, # sp_entity_id @@ -661,7 +666,8 @@ class Server(Entity): encrypted_advice_attributes=encrypted_advice_attributes, encrypt_cert_advice=encrypt_cert_advice, encrypt_cert_assertion=encrypt_cert_assertion, - pefim=pefim) + pefim=pefim, + sign_alg=sign_alg) except MissingValue as exc: return self.create_error_response(in_response_to, destination, @@ -681,7 +687,7 @@ class Server(Entity): authn_decl=authn_decl) #noinspection PyUnusedLocal - def create_assertion_id_request_response(self, assertion_id, sign=False, + def create_assertion_id_request_response(self, assertion_id, sign=False, sign_alg=None, digest_alg=None, **kwargs): """ @@ -698,7 +704,7 @@ class Server(Entity): if to_sign: if assertion.signature is None: assertion.signature = pre_signature_part(assertion.id, - self.sec.my_cert, 1) + self.sec.my_cert, 1, sign_alg=sign_alg) return signed_instance_factory(assertion, self.sec, to_sign) else: @@ -708,7 +714,7 @@ class Server(Entity): def create_name_id_mapping_response(self, name_id=None, encrypted_id=None, in_response_to=None, issuer=None, sign_response=False, - status=None, **kwargs): + status=None, sign_alg=None, digest_alg=None, **kwargs): """ protocol for mapping a principal's name identifier into a different name identifier for the same principal. @@ -730,7 +736,7 @@ class Server(Entity): in_response_to=in_response_to, **ms_args) if sign_response: - return self.sign(_resp) + return self.sign(_resp, sign_alg=sign_alg) else: logger.info("Message: %s" % _resp) return _resp @@ -738,7 +744,7 @@ class Server(Entity): def create_authn_query_response(self, subject, session_index=None, requested_context=None, in_response_to=None, issuer=None, sign_response=False, - status=None, **kwargs): + status=None, sign_alg=None, digest_alg=None, **kwargs): """ A successful will contain one or more assertions containing authentication statements. @@ -759,7 +765,7 @@ class Server(Entity): args = {} return self._response(in_response_to, "", status, issuer, - sign_response, to_sign=[], **args) + sign_response, to_sign=[], sign_alg=sign_alg, **args) # --------- diff --git a/src/saml2/sigver.py b/src/saml2/sigver.py index c8d2daa..fd3db6f 100644 --- a/src/saml2/sigver.py +++ b/src/saml2/sigver.py @@ -1761,7 +1761,7 @@ class SecurityContext(object): return self.sign_statement(statement, class_name( samlp.AttributeQuery()), **kwargs) - def multiple_signatures(self, statement, to_sign, key=None, key_file=None): + def multiple_signatures(self, statement, to_sign, key=None, key_file=None, sign_alg=None, digest_alg=None): """ Sign multiple parts of a statement @@ -1780,7 +1780,7 @@ class SecurityContext(object): sid = item.id if not item.signature: - item.signature = pre_signature_part(sid, self.cert_file) + item.signature = pre_signature_part(sid, self.cert_file, sign_alg=sign_alg) statement = self.sign_statement(statement, class_name(item), key=key, key_file=key_file, @@ -1806,9 +1806,9 @@ def pre_signature_part(ident, public_key=None, identifier=None, """ if not digest_alg: - digest_alg=ds.digest_default + digest_alg = ds.DefaultSignature().get_digest_alg() if not sign_alg: - sign_alg=ds.sig_default + sign_alg = ds.DefaultSignature().get_sign_alg() signature_method = ds.SignatureMethod(algorithm=sign_alg) canonicalization_method = ds.CanonicalizationMethod( algorithm=ds.ALG_EXC_C14N) @@ -1918,12 +1918,12 @@ def pre_encrypt_assertion(response): return response -def response_factory(sign=False, encrypt=False, **kwargs): +def response_factory(sign=False, encrypt=False, sign_alg=None, digest_alg=None, **kwargs): response = samlp.Response(id=sid(), version=VERSION, issue_instant=instant()) if sign: - response.signature = pre_signature_part(kwargs["id"]) + response.signature = pre_signature_part(kwargs["id"], sign_alg=sign_alg) if encrypt: pass diff --git a/src/saml2/xmldsig/__init__.py b/src/saml2/xmldsig/__init__.py index 12d46ce..ded87ec 100644 --- a/src/saml2/xmldsig/__init__.py +++ b/src/saml2/xmldsig/__init__.py @@ -12,7 +12,7 @@ NAMESPACE = 'http://www.w3.org/2000/09/xmldsig#' ENCODING_BASE64 = 'http://www.w3.org/2000/09/xmldsig#base64' # digest and signature algorithms (not implemented = commented out) -DIGEST_MD5 = 'http://www.w3.org/2001/04/xmldsig-more#md5' # test framework only! +DIGEST_MD5 = 'http://www.w3.org/2001/04/xmldsig-more#md5' # test framework only! DIGEST_SHA1 = 'http://www.w3.org/2000/09/xmldsig#sha1' DIGEST_SHA224 = 'http://www.w3.org/2001/04/xmldsig-more#sha224' DIGEST_SHA256 = 'http://www.w3.org/2001/04/xmlenc#sha256' @@ -26,29 +26,29 @@ DIGEST_ALLOWED_ALG = (('DIGEST_SHA1', DIGEST_SHA1), ('DIGEST_SHA384', DIGEST_SHA384), ('DIGEST_SHA512', DIGEST_SHA512), ('DIGEST_RIPEMD160', DIGEST_RIPEMD160)) -DIGEST_AVAIL_ALG = DIGEST_ALLOWED_ALG + (('DIGEST_MD5', DIGEST_MD5), ) +DIGEST_AVAIL_ALG = DIGEST_ALLOWED_ALG + (('DIGEST_MD5', DIGEST_MD5),) -#SIG_DSA_SHA1 = 'http,//www.w3.org/2000/09/xmldsig#dsa-sha1' -#SIG_DSA_SHA256 = 'http://www.w3.org/2009/xmldsig11#dsa-sha256' -#SIG_ECDSA_SHA1 = 'http://www.w3.org/2001/04/xmldsig-more#ECDSA_sha1' -#SIG_ECDSA_SHA224 = 'http://www.w3.org/2001/04/xmldsig-more#ECDSA_sha224' -#SIG_ECDSA_SHA256 = 'http://www.w3.org/2001/04/xmldsig-more#ECDSA_sha256' -#SIG_ECDSA_SHA384 = 'http://www.w3.org/2001/04/xmldsig-more#ECDSA_sha384' -#SIG_ECDSA_SHA512 = 'http://www.w3.org/2001/04/xmldsig-more#ECDSA_sha512' -SIG_RSA_MD5 = 'http://www.w3.org/2001/04/xmldsig-more#rsa-md5' # test framework +# SIG_DSA_SHA1 = 'http,//www.w3.org/2000/09/xmldsig#dsa-sha1' +# SIG_DSA_SHA256 = 'http://www.w3.org/2009/xmldsig11#dsa-sha256' +# SIG_ECDSA_SHA1 = 'http://www.w3.org/2001/04/xmldsig-more#ECDSA_sha1' +# SIG_ECDSA_SHA224 = 'http://www.w3.org/2001/04/xmldsig-more#ECDSA_sha224' +# SIG_ECDSA_SHA256 = 'http://www.w3.org/2001/04/xmldsig-more#ECDSA_sha256' +# SIG_ECDSA_SHA384 = 'http://www.w3.org/2001/04/xmldsig-more#ECDSA_sha384' +# SIG_ECDSA_SHA512 = 'http://www.w3.org/2001/04/xmldsig-more#ECDSA_sha512' +SIG_RSA_MD5 = 'http://www.w3.org/2001/04/xmldsig-more#rsa-md5' # test framework SIG_RSA_SHA1 = 'http://www.w3.org/2000/09/xmldsig#rsa-sha1' SIG_RSA_SHA224 = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha224' SIG_RSA_SHA256 = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256' SIG_RSA_SHA384 = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha384' SIG_RSA_SHA512 = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha512' -#SIG_RSA_RIPEMD160 = 'http://www.w3.org/2001/04/xmldsig-more#rsa-ripemd160' +# SIG_RSA_RIPEMD160 = 'http://www.w3.org/2001/04/xmldsig-more#rsa-ripemd160' sig_default = SIG_RSA_SHA1 SIG_ALLOWED_ALG = (('SIG_RSA_SHA1', SIG_RSA_SHA1), ('SIG_RSA_SHA224', SIG_RSA_SHA224), ('SIG_RSA_SHA256', SIG_RSA_SHA256), ('SIG_RSA_SHA384', SIG_RSA_SHA384), ('SIG_RSA_SHA512', SIG_RSA_SHA512)) -SIG_AVAIL_ALG = SIG_ALLOWED_ALG + (('SIG_RSA_MD5', SIG_RSA_MD5), ) +SIG_AVAIL_ALG = SIG_ALLOWED_ALG + (('SIG_RSA_MD5', SIG_RSA_MD5),) MAC_SHA1 = 'http://www.w3.org/2000/09/xmldsig#hmac-sha1' @@ -61,6 +61,34 @@ TRANSFORM_XPATH = 'http://www.w3.org/TR/1999/REC-xpath-19991116' TRANSFORM_ENVELOPED = 'http://www.w3.org/2000/09/xmldsig#enveloped-signature' +class DefaultSignature: + class _DefaultSignature: + def __init__(self, sign_alg=None, digest_alg=None): + if sign_alg is None: + self.sign_alg = sig_default + else: + self.sign_alg = sign_alg + if digest_alg is None: + self.digest_alg = digest_default + else: + self.digest_alg = digest_alg + + def __str__(self): + return repr(self) + self.sign_alg + instance = None + + def __init__(self, sign_alg=None, digest_alg=None): + if not DefaultSignature.instance: + DefaultSignature.instance = DefaultSignature._DefaultSignature(sign_alg, digest_alg) + + def __getattr__(self, name): + return getattr(self.instance, name) + + def get_sign_alg(self): + return self.sign_alg + + def get_digest_alg(self): + return self.digest_alg class CryptoBinary_(SamlBase): @@ -74,6 +102,7 @@ class CryptoBinary_(SamlBase): c_child_order = SamlBase.c_child_order[:] c_cardinality = SamlBase.c_cardinality.copy() + def crypto_binary__from_string(xml_string): return saml2.create_class_from_xml_string(CryptoBinary_, xml_string) @@ -91,17 +120,18 @@ class SignatureValueType_(SamlBase): c_attributes['Id'] = ('id', 'ID', False) def __init__(self, - id=None, - text=None, - extension_elements=None, - extension_attributes=None, - ): + id=None, + text=None, + extension_elements=None, + extension_attributes=None, + ): SamlBase.__init__(self, - text=text, - extension_elements=extension_elements, - extension_attributes=extension_attributes, - ) - self.id=id + text=text, + extension_elements=extension_elements, + extension_attributes=extension_attributes, + ) + self.id = id + def signature_value_type__from_string(xml_string): return saml2.create_class_from_xml_string(SignatureValueType_, xml_string) @@ -119,17 +149,18 @@ class CanonicalizationMethodType_(SamlBase): c_attributes['Algorithm'] = ('algorithm', 'anyURI', True) def __init__(self, - algorithm=None, - text=None, - extension_elements=None, - extension_attributes=None, - ): + algorithm=None, + text=None, + extension_elements=None, + extension_attributes=None, + ): SamlBase.__init__(self, - text=text, - extension_elements=extension_elements, - extension_attributes=extension_attributes, - ) - self.algorithm=algorithm + text=text, + extension_elements=extension_elements, + extension_attributes=extension_attributes, + ) + self.algorithm = algorithm + def canonicalization_method_type__from_string(xml_string): return saml2.create_class_from_xml_string(CanonicalizationMethodType_, @@ -137,7 +168,6 @@ def canonicalization_method_type__from_string(xml_string): class TransformType_XPath(SamlBase): - c_tag = 'XPath' c_namespace = NAMESPACE c_value_type = {'base': 'string'} @@ -146,6 +176,7 @@ class TransformType_XPath(SamlBase): c_child_order = SamlBase.c_child_order[:] c_cardinality = SamlBase.c_cardinality.copy() + def transform_type__x_path_from_string(xml_string): return saml2.create_class_from_xml_string(TransformType_XPath, xml_string) @@ -161,24 +192,25 @@ class TransformType_(SamlBase): c_cardinality = SamlBase.c_cardinality.copy() c_children['{http://www.w3.org/2000/09/xmldsig#}XPath'] = ('x_path', [TransformType_XPath]) - c_cardinality['x_path'] = {"min":0} + c_cardinality['x_path'] = {"min": 0} c_attributes['Algorithm'] = ('algorithm', 'anyURI', True) c_child_order.extend(['x_path']) def __init__(self, - x_path=None, - algorithm=None, - text=None, - extension_elements=None, - extension_attributes=None, - ): + x_path=None, + algorithm=None, + text=None, + extension_elements=None, + extension_attributes=None, + ): SamlBase.__init__(self, - text=text, - extension_elements=extension_elements, - extension_attributes=extension_attributes, - ) - self.x_path=x_path or [] - self.algorithm=algorithm + text=text, + extension_elements=extension_elements, + extension_attributes=extension_attributes, + ) + self.x_path = x_path or [] + self.algorithm = algorithm + def transform_type__from_string(xml_string): return saml2.create_class_from_xml_string(TransformType_, xml_string) @@ -196,17 +228,18 @@ class DigestMethodType_(SamlBase): c_attributes['Algorithm'] = ('algorithm', 'anyURI', True) def __init__(self, - algorithm=None, - text=None, - extension_elements=None, - extension_attributes=None, - ): + algorithm=None, + text=None, + extension_elements=None, + extension_attributes=None, + ): SamlBase.__init__(self, - text=text, - extension_elements=extension_elements, - extension_attributes=extension_attributes, - ) - self.algorithm=algorithm + text=text, + extension_elements=extension_elements, + extension_attributes=extension_attributes, + ) + self.algorithm = algorithm + def digest_method_type__from_string(xml_string): return saml2.create_class_from_xml_string(DigestMethodType_, xml_string) @@ -223,6 +256,7 @@ class DigestValueType_(SamlBase): c_child_order = SamlBase.c_child_order[:] c_cardinality = SamlBase.c_cardinality.copy() + def digest_value_type__from_string(xml_string): return saml2.create_class_from_xml_string(DigestValueType_, xml_string) @@ -238,6 +272,7 @@ class KeyName(SamlBase): c_child_order = SamlBase.c_child_order[:] c_cardinality = SamlBase.c_cardinality.copy() + def key_name_from_string(xml_string): return saml2.create_class_from_xml_string(KeyName, xml_string) @@ -253,12 +288,12 @@ class MgmtData(SamlBase): c_child_order = SamlBase.c_child_order[:] c_cardinality = SamlBase.c_cardinality.copy() + def mgmt_data_from_string(xml_string): return saml2.create_class_from_xml_string(MgmtData, xml_string) class X509IssuerName(SamlBase): - c_tag = 'X509IssuerName' c_namespace = NAMESPACE c_value_type = {'base': 'string'} @@ -267,12 +302,12 @@ class X509IssuerName(SamlBase): c_child_order = SamlBase.c_child_order[:] c_cardinality = SamlBase.c_cardinality.copy() + def x509_issuer_name_from_string(xml_string): return saml2.create_class_from_xml_string(X509IssuerName, xml_string) class X509SerialNumber(SamlBase): - c_tag = 'X509SerialNumber' c_namespace = NAMESPACE c_value_type = {'base': 'integer'} @@ -281,6 +316,7 @@ class X509SerialNumber(SamlBase): c_child_order = SamlBase.c_child_order[:] c_cardinality = SamlBase.c_cardinality.copy() + def x509_serial_number_from_string(xml_string): return saml2.create_class_from_xml_string(X509SerialNumber, xml_string) @@ -294,31 +330,33 @@ class X509IssuerSerialType_(SamlBase): c_attributes = SamlBase.c_attributes.copy() c_child_order = SamlBase.c_child_order[:] c_cardinality = SamlBase.c_cardinality.copy() - c_children['{http://www.w3.org/2000/09/xmldsig#}X509IssuerName'] = ('x509_issuer_name', X509IssuerName) - c_children['{http://www.w3.org/2000/09/xmldsig#}X509SerialNumber'] = ('x509_serial_number', X509SerialNumber) + c_children['{http://www.w3.org/2000/09/xmldsig#}X509IssuerName'] = ( + 'x509_issuer_name', X509IssuerName) + c_children['{http://www.w3.org/2000/09/xmldsig#}X509SerialNumber'] = ( + 'x509_serial_number', X509SerialNumber) c_child_order.extend(['x509_issuer_name', 'x509_serial_number']) def __init__(self, - x509_issuer_name=None, - x509_serial_number=None, - text=None, - extension_elements=None, - extension_attributes=None, - ): + x509_issuer_name=None, + x509_serial_number=None, + text=None, + extension_elements=None, + extension_attributes=None, + ): SamlBase.__init__(self, - text=text, - extension_elements=extension_elements, - extension_attributes=extension_attributes, - ) - self.x509_issuer_name=x509_issuer_name - self.x509_serial_number=x509_serial_number + text=text, + extension_elements=extension_elements, + extension_attributes=extension_attributes, + ) + self.x509_issuer_name = x509_issuer_name + self.x509_serial_number = x509_serial_number + def x509_issuer_serial_type__from_string(xml_string): return saml2.create_class_from_xml_string(X509IssuerSerialType_, xml_string) class PGPKeyID(SamlBase): - c_tag = 'PGPKeyID' c_namespace = NAMESPACE c_value_type = {'base': 'base64Binary'} @@ -327,12 +365,12 @@ class PGPKeyID(SamlBase): c_child_order = SamlBase.c_child_order[:] c_cardinality = SamlBase.c_cardinality.copy() + def pgp_key_id_from_string(xml_string): return saml2.create_class_from_xml_string(PGPKeyID, xml_string) class PGPKeyPacket(SamlBase): - c_tag = 'PGPKeyPacket' c_namespace = NAMESPACE c_value_type = {'base': 'base64Binary'} @@ -341,6 +379,7 @@ class PGPKeyPacket(SamlBase): c_child_order = SamlBase.c_child_order[:] c_cardinality = SamlBase.c_cardinality.copy() + def pgp_key_packet_from_string(xml_string): return saml2.create_class_from_xml_string(PGPKeyPacket, xml_string) @@ -355,31 +394,32 @@ class PGPDataType_(SamlBase): c_child_order = SamlBase.c_child_order[:] c_cardinality = SamlBase.c_cardinality.copy() c_children['{http://www.w3.org/2000/09/xmldsig#}PGPKeyID'] = ('pgp_key_id', PGPKeyID) - c_children['{http://www.w3.org/2000/09/xmldsig#}PGPKeyPacket'] = ('pgp_key_packet', PGPKeyPacket) - c_cardinality['pgp_key_packet'] = {"min":0, "max":1} + c_children['{http://www.w3.org/2000/09/xmldsig#}PGPKeyPacket'] = ( + 'pgp_key_packet', PGPKeyPacket) + c_cardinality['pgp_key_packet'] = {"min": 0, "max": 1} c_child_order.extend(['pgp_key_id', 'pgp_key_packet']) def __init__(self, - pgp_key_id=None, - pgp_key_packet=None, - text=None, - extension_elements=None, - extension_attributes=None, - ): + pgp_key_id=None, + pgp_key_packet=None, + text=None, + extension_elements=None, + extension_attributes=None, + ): SamlBase.__init__(self, - text=text, - extension_elements=extension_elements, - extension_attributes=extension_attributes, - ) - self.pgp_key_id=pgp_key_id - self.pgp_key_packet=pgp_key_packet + text=text, + extension_elements=extension_elements, + extension_attributes=extension_attributes, + ) + self.pgp_key_id = pgp_key_id + self.pgp_key_packet = pgp_key_packet + def pgp_data_type__from_string(xml_string): return saml2.create_class_from_xml_string(PGPDataType_, xml_string) class SPKISexp(SamlBase): - c_tag = 'SPKISexp' c_namespace = NAMESPACE c_value_type = {'base': 'base64Binary'} @@ -388,6 +428,7 @@ class SPKISexp(SamlBase): c_child_order = SamlBase.c_child_order[:] c_cardinality = SamlBase.c_cardinality.copy() + def spki_sexp_from_string(xml_string): return saml2.create_class_from_xml_string(SPKISexp, xml_string) @@ -403,21 +444,22 @@ class SPKIDataType_(SamlBase): c_cardinality = SamlBase.c_cardinality.copy() c_children['{http://www.w3.org/2000/09/xmldsig#}SPKISexp'] = ('spki_sexp', [SPKISexp]) - c_cardinality['spki_sexp'] = {"min":1} + c_cardinality['spki_sexp'] = {"min": 1} c_child_order.extend(['spki_sexp']) def __init__(self, - spki_sexp=None, - text=None, - extension_elements=None, - extension_attributes=None, - ): + spki_sexp=None, + text=None, + extension_elements=None, + extension_attributes=None, + ): SamlBase.__init__(self, - text=text, - extension_elements=extension_elements, - extension_attributes=extension_attributes, - ) - self.spki_sexp=spki_sexp or [] + text=text, + extension_elements=extension_elements, + extension_attributes=extension_attributes, + ) + self.spki_sexp = spki_sexp or [] + def spki_data_type__from_string(xml_string): return saml2.create_class_from_xml_string(SPKIDataType_, xml_string) @@ -437,21 +479,22 @@ class ObjectType_(SamlBase): c_attributes['Encoding'] = ('encoding', 'anyURI', False) def __init__(self, - id=None, - mime_type=None, - encoding=None, - text=None, - extension_elements=None, - extension_attributes=None, - ): + id=None, + mime_type=None, + encoding=None, + text=None, + extension_elements=None, + extension_attributes=None, + ): SamlBase.__init__(self, - text=text, - extension_elements=extension_elements, - extension_attributes=extension_attributes, - ) - self.id=id - self.mime_type=mime_type - self.encoding=encoding + text=text, + extension_elements=extension_elements, + extension_attributes=extension_attributes, + ) + self.id = id + self.mime_type = mime_type + self.encoding = encoding + def object_type__from_string(xml_string): return saml2.create_class_from_xml_string(ObjectType_, xml_string) @@ -470,19 +513,20 @@ class SignaturePropertyType_(SamlBase): c_attributes['Id'] = ('id', 'ID', False) def __init__(self, - target=None, - id=None, - text=None, - extension_elements=None, - extension_attributes=None, - ): + target=None, + id=None, + text=None, + extension_elements=None, + extension_attributes=None, + ): SamlBase.__init__(self, - text=text, - extension_elements=extension_elements, - extension_attributes=extension_attributes, - ) - self.target=target - self.id=id + text=text, + extension_elements=extension_elements, + extension_attributes=extension_attributes, + ) + self.target = target + self.id = id + def signature_property_type__from_string(xml_string): return saml2.create_class_from_xml_string(SignaturePropertyType_, xml_string) @@ -499,12 +543,12 @@ class HMACOutputLengthType_(SamlBase): c_child_order = SamlBase.c_child_order[:] c_cardinality = SamlBase.c_cardinality.copy() + def hmac_output_length_type__from_string(xml_string): return saml2.create_class_from_xml_string(HMACOutputLengthType_, xml_string) class P(CryptoBinary_): - c_tag = 'P' c_namespace = NAMESPACE c_children = CryptoBinary_.c_children.copy() @@ -512,12 +556,12 @@ class P(CryptoBinary_): c_child_order = CryptoBinary_.c_child_order[:] c_cardinality = CryptoBinary_.c_cardinality.copy() + def p_from_string(xml_string): return saml2.create_class_from_xml_string(P, xml_string) class Q(CryptoBinary_): - c_tag = 'Q' c_namespace = NAMESPACE c_children = CryptoBinary_.c_children.copy() @@ -525,12 +569,12 @@ class Q(CryptoBinary_): c_child_order = CryptoBinary_.c_child_order[:] c_cardinality = CryptoBinary_.c_cardinality.copy() + def q_from_string(xml_string): return saml2.create_class_from_xml_string(Q, xml_string) class G(CryptoBinary_): - c_tag = 'G' c_namespace = NAMESPACE c_children = CryptoBinary_.c_children.copy() @@ -538,12 +582,12 @@ class G(CryptoBinary_): c_child_order = CryptoBinary_.c_child_order[:] c_cardinality = CryptoBinary_.c_cardinality.copy() + def g_from_string(xml_string): return saml2.create_class_from_xml_string(G, xml_string) class Y(CryptoBinary_): - c_tag = 'Y' c_namespace = NAMESPACE c_children = CryptoBinary_.c_children.copy() @@ -551,12 +595,12 @@ class Y(CryptoBinary_): c_child_order = CryptoBinary_.c_child_order[:] c_cardinality = CryptoBinary_.c_cardinality.copy() + def y_from_string(xml_string): return saml2.create_class_from_xml_string(Y, xml_string) class J(CryptoBinary_): - c_tag = 'J' c_namespace = NAMESPACE c_children = CryptoBinary_.c_children.copy() @@ -564,12 +608,12 @@ class J(CryptoBinary_): c_child_order = CryptoBinary_.c_child_order[:] c_cardinality = CryptoBinary_.c_cardinality.copy() + def j_from_string(xml_string): return saml2.create_class_from_xml_string(J, xml_string) class Seed(CryptoBinary_): - c_tag = 'Seed' c_namespace = NAMESPACE c_children = CryptoBinary_.c_children.copy() @@ -577,12 +621,12 @@ class Seed(CryptoBinary_): c_child_order = CryptoBinary_.c_child_order[:] c_cardinality = CryptoBinary_.c_cardinality.copy() + def seed_from_string(xml_string): return saml2.create_class_from_xml_string(Seed, xml_string) class PgenCounter(CryptoBinary_): - c_tag = 'PgenCounter' c_namespace = NAMESPACE c_children = CryptoBinary_.c_children.copy() @@ -590,6 +634,7 @@ class PgenCounter(CryptoBinary_): c_child_order = CryptoBinary_.c_child_order[:] c_cardinality = CryptoBinary_.c_cardinality.copy() + def pgen_counter_from_string(xml_string): return saml2.create_class_from_xml_string(PgenCounter, xml_string) @@ -604,52 +649,52 @@ class DSAKeyValueType_(SamlBase): c_child_order = SamlBase.c_child_order[:] c_cardinality = SamlBase.c_cardinality.copy() c_children['{http://www.w3.org/2000/09/xmldsig#}P'] = ('p', P) - c_cardinality['p'] = {"min":0, "max":1} + c_cardinality['p'] = {"min": 0, "max": 1} c_children['{http://www.w3.org/2000/09/xmldsig#}Q'] = ('q', Q) - c_cardinality['q'] = {"min":0, "max":1} + c_cardinality['q'] = {"min": 0, "max": 1} c_children['{http://www.w3.org/2000/09/xmldsig#}G'] = ('g', G) - c_cardinality['g'] = {"min":0, "max":1} + c_cardinality['g'] = {"min": 0, "max": 1} c_children['{http://www.w3.org/2000/09/xmldsig#}Y'] = ('y', Y) c_children['{http://www.w3.org/2000/09/xmldsig#}J'] = ('j', J) - c_cardinality['j'] = {"min":0, "max":1} + c_cardinality['j'] = {"min": 0, "max": 1} c_children['{http://www.w3.org/2000/09/xmldsig#}Seed'] = ('seed', Seed) - c_cardinality['seed'] = {"min":0, "max":1} + c_cardinality['seed'] = {"min": 0, "max": 1} c_children['{http://www.w3.org/2000/09/xmldsig#}PgenCounter'] = ('pgen_counter', PgenCounter) - c_cardinality['pgen_counter'] = {"min":0, "max":1} + c_cardinality['pgen_counter'] = {"min": 0, "max": 1} c_child_order.extend(['p', 'q', 'g', 'y', 'j', 'seed', 'pgen_counter']) def __init__(self, - p=None, - q=None, - g=None, - y=None, - j=None, - seed=None, - pgen_counter=None, - text=None, - extension_elements=None, - extension_attributes=None, - ): + p=None, + q=None, + g=None, + y=None, + j=None, + seed=None, + pgen_counter=None, + text=None, + extension_elements=None, + extension_attributes=None, + ): SamlBase.__init__(self, - text=text, - extension_elements=extension_elements, - extension_attributes=extension_attributes, - ) - self.p=p - self.q=q - self.g=g - self.y=y - self.j=j - self.seed=seed - self.pgen_counter=pgen_counter + text=text, + extension_elements=extension_elements, + extension_attributes=extension_attributes, + ) + self.p = p + self.q = q + self.g = g + self.y = y + self.j = j + self.seed = seed + self.pgen_counter = pgen_counter + def dsa_key_value_type__from_string(xml_string): return saml2.create_class_from_xml_string(DSAKeyValueType_, xml_string) class Modulus(CryptoBinary_): - c_tag = 'Modulus' c_namespace = NAMESPACE c_children = CryptoBinary_.c_children.copy() @@ -657,12 +702,12 @@ class Modulus(CryptoBinary_): c_child_order = CryptoBinary_.c_child_order[:] c_cardinality = CryptoBinary_.c_cardinality.copy() + def modulus_from_string(xml_string): return saml2.create_class_from_xml_string(Modulus, xml_string) class Exponent(CryptoBinary_): - c_tag = 'Exponent' c_namespace = NAMESPACE c_children = CryptoBinary_.c_children.copy() @@ -670,6 +715,7 @@ class Exponent(CryptoBinary_): c_child_order = CryptoBinary_.c_child_order[:] c_cardinality = CryptoBinary_.c_cardinality.copy() + def exponent_from_string(xml_string): return saml2.create_class_from_xml_string(Exponent, xml_string) @@ -690,19 +736,20 @@ class RSAKeyValueType_(SamlBase): c_child_order.extend(['modulus', 'exponent']) def __init__(self, - modulus=None, - exponent=None, - text=None, - extension_elements=None, - extension_attributes=None, - ): + modulus=None, + exponent=None, + text=None, + extension_elements=None, + extension_attributes=None, + ): SamlBase.__init__(self, - text=text, - extension_elements=extension_elements, - extension_attributes=extension_attributes, - ) - self.modulus=modulus - self.exponent=exponent + text=text, + extension_elements=extension_elements, + extension_attributes=extension_attributes, + ) + self.modulus = modulus + self.exponent = exponent + def rsa_key_value_type__from_string(xml_string): return saml2.create_class_from_xml_string(RSAKeyValueType_, xml_string) @@ -718,6 +765,7 @@ class SignatureValue(SignatureValueType_): c_child_order = SignatureValueType_.c_child_order[:] c_cardinality = SignatureValueType_.c_cardinality.copy() + def signature_value_from_string(xml_string): return saml2.create_class_from_xml_string(SignatureValue, xml_string) @@ -732,13 +780,13 @@ class CanonicalizationMethod(CanonicalizationMethodType_): c_child_order = CanonicalizationMethodType_.c_child_order[:] c_cardinality = CanonicalizationMethodType_.c_cardinality.copy() + def canonicalization_method_from_string(xml_string): return saml2.create_class_from_xml_string(CanonicalizationMethod, xml_string) class HMACOutputLength(HMACOutputLengthType_): - c_tag = 'HMACOutputLength' c_namespace = NAMESPACE c_children = HMACOutputLengthType_.c_children.copy() @@ -746,6 +794,7 @@ class HMACOutputLength(HMACOutputLengthType_): c_child_order = HMACOutputLengthType_.c_child_order[:] c_cardinality = HMACOutputLengthType_.c_cardinality.copy() + def hmac_output_length_from_string(xml_string): return saml2.create_class_from_xml_string(HMACOutputLength, xml_string) @@ -759,25 +808,27 @@ class SignatureMethodType_(SamlBase): c_attributes = SamlBase.c_attributes.copy() c_child_order = SamlBase.c_child_order[:] c_cardinality = SamlBase.c_cardinality.copy() - c_children['{http://www.w3.org/2000/09/xmldsig#}HMACOutputLength'] = ('hmac_output_length', HMACOutputLength) - c_cardinality['hmac_output_length'] = {"min":0, "max":1} + c_children['{http://www.w3.org/2000/09/xmldsig#}HMACOutputLength'] = ( + 'hmac_output_length', HMACOutputLength) + c_cardinality['hmac_output_length'] = {"min": 0, "max": 1} c_attributes['Algorithm'] = ('algorithm', 'anyURI', True) c_child_order.extend(['hmac_output_length']) def __init__(self, - hmac_output_length=None, - algorithm=None, - text=None, - extension_elements=None, - extension_attributes=None, - ): + hmac_output_length=None, + algorithm=None, + text=None, + extension_elements=None, + extension_attributes=None, + ): SamlBase.__init__(self, - text=text, - extension_elements=extension_elements, - extension_attributes=extension_attributes, - ) - self.hmac_output_length=hmac_output_length - self.algorithm=algorithm + text=text, + extension_elements=extension_elements, + extension_attributes=extension_attributes, + ) + self.hmac_output_length = hmac_output_length + self.algorithm = algorithm + def signature_method_type__from_string(xml_string): return saml2.create_class_from_xml_string(SignatureMethodType_, xml_string) @@ -793,6 +844,7 @@ class Transform(TransformType_): c_child_order = TransformType_.c_child_order[:] c_cardinality = TransformType_.c_cardinality.copy() + def transform_from_string(xml_string): return saml2.create_class_from_xml_string(Transform, xml_string) @@ -807,6 +859,7 @@ class DigestMethod(DigestMethodType_): c_child_order = DigestMethodType_.c_child_order[:] c_cardinality = DigestMethodType_.c_cardinality.copy() + def digest_method_from_string(xml_string): return saml2.create_class_from_xml_string(DigestMethod, xml_string) @@ -821,12 +874,12 @@ class DigestValue(DigestValueType_): c_child_order = DigestValueType_.c_child_order[:] c_cardinality = DigestValueType_.c_cardinality.copy() + def digest_value_from_string(xml_string): return saml2.create_class_from_xml_string(DigestValue, xml_string) class X509IssuerSerial(X509IssuerSerialType_): - c_tag = 'X509IssuerSerial' c_namespace = NAMESPACE c_children = X509IssuerSerialType_.c_children.copy() @@ -834,12 +887,12 @@ class X509IssuerSerial(X509IssuerSerialType_): c_child_order = X509IssuerSerialType_.c_child_order[:] c_cardinality = X509IssuerSerialType_.c_cardinality.copy() + def x509_issuer_serial_from_string(xml_string): return saml2.create_class_from_xml_string(X509IssuerSerial, xml_string) class X509SKI(SamlBase): - c_tag = 'X509SKI' c_namespace = NAMESPACE c_value_type = {'base': 'base64Binary'} @@ -848,12 +901,12 @@ class X509SKI(SamlBase): c_child_order = SamlBase.c_child_order[:] c_cardinality = SamlBase.c_cardinality.copy() + def x509_ski_from_string(xml_string): return saml2.create_class_from_xml_string(X509SKI, xml_string) class X509SubjectName(SamlBase): - c_tag = 'X509SubjectName' c_namespace = NAMESPACE c_value_type = {'base': 'string'} @@ -862,12 +915,12 @@ class X509SubjectName(SamlBase): c_child_order = SamlBase.c_child_order[:] c_cardinality = SamlBase.c_cardinality.copy() + def x509_subject_name_from_string(xml_string): return saml2.create_class_from_xml_string(X509SubjectName, xml_string) class X509Certificate(SamlBase): - c_tag = 'X509Certificate' c_namespace = NAMESPACE c_value_type = {'base': 'base64Binary'} @@ -876,12 +929,12 @@ class X509Certificate(SamlBase): c_child_order = SamlBase.c_child_order[:] c_cardinality = SamlBase.c_cardinality.copy() + def x509_certificate_from_string(xml_string): return saml2.create_class_from_xml_string(X509Certificate, xml_string) class X509CRL(SamlBase): - c_tag = 'X509CRL' c_namespace = NAMESPACE c_value_type = {'base': 'base64Binary'} @@ -890,6 +943,7 @@ class X509CRL(SamlBase): c_child_order = SamlBase.c_child_order[:] c_cardinality = SamlBase.c_cardinality.copy() + def x509_crl_from_string(xml_string): return saml2.create_class_from_xml_string(X509CRL, xml_string) @@ -905,42 +959,43 @@ class X509DataType_(SamlBase): c_cardinality = SamlBase.c_cardinality.copy() c_children['{http://www.w3.org/2000/09/xmldsig#}X509IssuerSerial'] = ('x509_issuer_serial', X509IssuerSerial) - c_cardinality['x509_issuer_serial'] = {"min":0, "max":1} + c_cardinality['x509_issuer_serial'] = {"min": 0, "max": 1} c_children['{http://www.w3.org/2000/09/xmldsig#}X509SKI'] = ('x509_ski', X509SKI) - c_cardinality['x509_ski'] = {"min":0, "max":1} + c_cardinality['x509_ski'] = {"min": 0, "max": 1} c_children['{http://www.w3.org/2000/09/xmldsig#}X509SubjectName'] = ('x509_subject_name', X509SubjectName) - c_cardinality['x509_subject_name'] = {"min":0, "max":1} + c_cardinality['x509_subject_name'] = {"min": 0, "max": 1} c_children['{http://www.w3.org/2000/09/xmldsig#}X509Certificate'] = ('x509_certificate', X509Certificate) - c_cardinality['x509_certificate'] = {"min":0, "max":1} + c_cardinality['x509_certificate'] = {"min": 0, "max": 1} c_children['{http://www.w3.org/2000/09/xmldsig#}X509CRL'] = ('x509_crl', X509CRL) - c_cardinality['x509_crl'] = {"min":0, "max":1} + c_cardinality['x509_crl'] = {"min": 0, "max": 1} c_child_order.extend(['x509_issuer_serial', 'x509_ski', 'x509_subject_name', 'x509_certificate', 'x509_crl']) def __init__(self, - x509_issuer_serial=None, - x509_ski=None, - x509_subject_name=None, - x509_certificate=None, - x509_crl=None, - text=None, - extension_elements=None, - extension_attributes=None, - ): + x509_issuer_serial=None, + x509_ski=None, + x509_subject_name=None, + x509_certificate=None, + x509_crl=None, + text=None, + extension_elements=None, + extension_attributes=None, + ): SamlBase.__init__(self, - text=text, - extension_elements=extension_elements, - extension_attributes=extension_attributes, - ) - self.x509_issuer_serial=x509_issuer_serial - self.x509_ski=x509_ski - self.x509_subject_name=x509_subject_name - self.x509_certificate=x509_certificate - self.x509_crl=x509_crl + text=text, + extension_elements=extension_elements, + extension_attributes=extension_attributes, + ) + self.x509_issuer_serial = x509_issuer_serial + self.x509_ski = x509_ski + self.x509_subject_name = x509_subject_name + self.x509_certificate = x509_certificate + self.x509_crl = x509_crl + def x509_data_type__from_string(xml_string): return saml2.create_class_from_xml_string(X509DataType_, xml_string) @@ -956,6 +1011,7 @@ class PGPData(PGPDataType_): c_child_order = PGPDataType_.c_child_order[:] c_cardinality = PGPDataType_.c_cardinality.copy() + def pgp_data_from_string(xml_string): return saml2.create_class_from_xml_string(PGPData, xml_string) @@ -970,6 +1026,7 @@ class SPKIData(SPKIDataType_): c_child_order = SPKIDataType_.c_child_order[:] c_cardinality = SPKIDataType_.c_cardinality.copy() + def spki_data_from_string(xml_string): return saml2.create_class_from_xml_string(SPKIData, xml_string) @@ -984,6 +1041,7 @@ class Object(ObjectType_): c_child_order = ObjectType_.c_child_order[:] c_cardinality = ObjectType_.c_cardinality.copy() + def object_from_string(xml_string): return saml2.create_class_from_xml_string(Object, xml_string) @@ -998,6 +1056,7 @@ class SignatureProperty(SignaturePropertyType_): c_child_order = SignaturePropertyType_.c_child_order[:] c_cardinality = SignaturePropertyType_.c_cardinality.copy() + def signature_property_from_string(xml_string): return saml2.create_class_from_xml_string(SignatureProperty, xml_string) @@ -1012,6 +1071,7 @@ class DSAKeyValue(DSAKeyValueType_): c_child_order = DSAKeyValueType_.c_child_order[:] c_cardinality = DSAKeyValueType_.c_cardinality.copy() + def dsa_key_value_from_string(xml_string): return saml2.create_class_from_xml_string(DSAKeyValue, xml_string) @@ -1026,6 +1086,7 @@ class RSAKeyValue(RSAKeyValueType_): c_child_order = RSAKeyValueType_.c_child_order[:] c_cardinality = RSAKeyValueType_.c_cardinality.copy() + def rsa_key_value_from_string(xml_string): return saml2.create_class_from_xml_string(RSAKeyValue, xml_string) @@ -1040,6 +1101,7 @@ class SignatureMethod(SignatureMethodType_): c_child_order = SignatureMethodType_.c_child_order[:] c_cardinality = SignatureMethodType_.c_cardinality.copy() + def signature_method_from_string(xml_string): return saml2.create_class_from_xml_string(SignatureMethod, xml_string) @@ -1055,21 +1117,22 @@ class TransformsType_(SamlBase): c_cardinality = SamlBase.c_cardinality.copy() c_children['{http://www.w3.org/2000/09/xmldsig#}Transform'] = ('transform', [Transform]) - c_cardinality['transform'] = {"min":1} + c_cardinality['transform'] = {"min": 1} c_child_order.extend(['transform']) def __init__(self, - transform=None, - text=None, - extension_elements=None, - extension_attributes=None, - ): + transform=None, + text=None, + extension_elements=None, + extension_attributes=None, + ): SamlBase.__init__(self, - text=text, - extension_elements=extension_elements, - extension_attributes=extension_attributes, - ) - self.transform=transform or [] + text=text, + extension_elements=extension_elements, + extension_attributes=extension_attributes, + ) + self.transform = transform or [] + def transforms_type__from_string(xml_string): return saml2.create_class_from_xml_string(TransformsType_, xml_string) @@ -1086,26 +1149,27 @@ class KeyValueType_(SamlBase): c_cardinality = SamlBase.c_cardinality.copy() c_children['{http://www.w3.org/2000/09/xmldsig#}DSAKeyValue'] = ('dsa_key_value', DSAKeyValue) - c_cardinality['dsa_key_value'] = {"min":0, "max":1} + c_cardinality['dsa_key_value'] = {"min": 0, "max": 1} c_children['{http://www.w3.org/2000/09/xmldsig#}RSAKeyValue'] = ('rsa_key_value', RSAKeyValue) - c_cardinality['rsa_key_value'] = {"min":0, "max":1} + c_cardinality['rsa_key_value'] = {"min": 0, "max": 1} c_child_order.extend(['dsa_key_value', 'rsa_key_value']) def __init__(self, - dsa_key_value=None, - rsa_key_value=None, - text=None, - extension_elements=None, - extension_attributes=None, - ): + dsa_key_value=None, + rsa_key_value=None, + text=None, + extension_elements=None, + extension_attributes=None, + ): SamlBase.__init__(self, - text=text, - extension_elements=extension_elements, - extension_attributes=extension_attributes, - ) - self.dsa_key_value=dsa_key_value - self.rsa_key_value=rsa_key_value + text=text, + extension_elements=extension_elements, + extension_attributes=extension_attributes, + ) + self.dsa_key_value = dsa_key_value + self.rsa_key_value = rsa_key_value + def key_value_type__from_string(xml_string): return saml2.create_class_from_xml_string(KeyValueType_, xml_string) @@ -1121,6 +1185,7 @@ class X509Data(X509DataType_): c_child_order = X509DataType_.c_child_order[:] c_cardinality = X509DataType_.c_cardinality.copy() + def x509_data_from_string(xml_string): return saml2.create_class_from_xml_string(X509Data, xml_string) @@ -1134,25 +1199,27 @@ class SignaturePropertiesType_(SamlBase): c_attributes = SamlBase.c_attributes.copy() c_child_order = SamlBase.c_child_order[:] c_cardinality = SamlBase.c_cardinality.copy() - c_children['{http://www.w3.org/2000/09/xmldsig#}SignatureProperty'] = ('signature_property', [SignatureProperty]) - c_cardinality['signature_property'] = {"min":1} + c_children['{http://www.w3.org/2000/09/xmldsig#}SignatureProperty'] = ( + 'signature_property', [SignatureProperty]) + c_cardinality['signature_property'] = {"min": 1} c_attributes['Id'] = ('id', 'ID', False) c_child_order.extend(['signature_property']) def __init__(self, - signature_property=None, - id=None, - text=None, - extension_elements=None, - extension_attributes=None, - ): + signature_property=None, + id=None, + text=None, + extension_elements=None, + extension_attributes=None, + ): SamlBase.__init__(self, - text=text, - extension_elements=extension_elements, - extension_attributes=extension_attributes, - ) - self.signature_property=signature_property or [] - self.id=id + text=text, + extension_elements=extension_elements, + extension_attributes=extension_attributes, + ) + self.signature_property = signature_property or [] + self.id = id + def signature_properties_type__from_string(xml_string): return saml2.create_class_from_xml_string(SignaturePropertiesType_, xml_string) @@ -1168,6 +1235,7 @@ class Transforms(TransformsType_): c_child_order = TransformsType_.c_child_order[:] c_cardinality = TransformsType_.c_cardinality.copy() + def transforms_from_string(xml_string): return saml2.create_class_from_xml_string(Transforms, xml_string) @@ -1182,6 +1250,7 @@ class KeyValue(KeyValueType_): c_child_order = KeyValueType_.c_child_order[:] c_cardinality = KeyValueType_.c_cardinality.copy() + def key_value_from_string(xml_string): return saml2.create_class_from_xml_string(KeyValue, xml_string) @@ -1197,27 +1266,27 @@ class RetrievalMethodType_(SamlBase): c_cardinality = SamlBase.c_cardinality.copy() c_children['{http://www.w3.org/2000/09/xmldsig#}Transforms'] = ('transforms', Transforms) - c_cardinality['transforms'] = {"min":0, "max":1} + c_cardinality['transforms'] = {"min": 0, "max": 1} c_attributes['URI'] = ('uri', 'anyURI', False) c_attributes['Type'] = ('type', 'anyURI', False) c_child_order.extend(['transforms']) def __init__(self, - transforms=None, - uri=None, - type=None, - text=None, - extension_elements=None, - extension_attributes=None, - ): + transforms=None, + uri=None, + type=None, + text=None, + extension_elements=None, + extension_attributes=None, + ): SamlBase.__init__(self, - text=text, - extension_elements=extension_elements, - extension_attributes=extension_attributes, - ) - self.transforms=transforms - self.uri=uri - self.type=type + text=text, + extension_elements=extension_elements, + extension_attributes=extension_attributes, + ) + self.transforms = transforms + self.uri = uri + self.type = type def retrieval_method_type__from_string(xml_string): @@ -1250,7 +1319,7 @@ class ReferenceType_(SamlBase): c_cardinality = SamlBase.c_cardinality.copy() c_children['{http://www.w3.org/2000/09/xmldsig#}Transforms'] = ('transforms', Transforms) - c_cardinality['transforms'] = {"min":0, "max":1} + c_cardinality['transforms'] = {"min": 0, "max": 1} c_children['{http://www.w3.org/2000/09/xmldsig#}DigestMethod'] = ('digest_method', DigestMethod) c_children['{http://www.w3.org/2000/09/xmldsig#}DigestValue'] = ('digest_value', @@ -1261,27 +1330,27 @@ class ReferenceType_(SamlBase): c_child_order.extend(['transforms', 'digest_method', 'digest_value']) def __init__(self, - transforms=None, - digest_method=None, - digest_value=None, - id=None, - uri=None, - type=None, - text=None, - extension_elements=None, - extension_attributes=None, - ): + transforms=None, + digest_method=None, + digest_value=None, + id=None, + uri=None, + type=None, + text=None, + extension_elements=None, + extension_attributes=None, + ): SamlBase.__init__(self, - text=text, - extension_elements=extension_elements, - extension_attributes=extension_attributes, - ) - self.transforms=transforms - self.digest_method=digest_method - self.digest_value=digest_value - self.id=id - self.uri=uri - self.type=type + text=text, + extension_elements=extension_elements, + extension_attributes=extension_attributes, + ) + self.transforms = transforms + self.digest_method = digest_method + self.digest_value = digest_value + self.id = id + self.uri = uri + self.type = type def reference_type__from_string(xml_string): @@ -1317,7 +1386,8 @@ class Reference(ReferenceType_): def reference_from_string(xml_string): return saml2.create_class_from_xml_string(Reference, xml_string) -#import xmlenc as enc + +# import xmlenc as enc class KeyInfoType_(SamlBase): @@ -1331,28 +1401,28 @@ class KeyInfoType_(SamlBase): c_cardinality = SamlBase.c_cardinality.copy() c_children['{http://www.w3.org/2000/09/xmldsig#}KeyName'] = ('key_name', [KeyName]) - c_cardinality['key_name'] = {"min":0} + c_cardinality['key_name'] = {"min": 0} c_children['{http://www.w3.org/2000/09/xmldsig#}KeyValue'] = ('key_value', [KeyValue]) - c_cardinality['key_value'] = {"min":0} + c_cardinality['key_value'] = {"min": 0} c_children['{http://www.w3.org/2000/09/xmldsig#}RetrievalMethod'] = ( 'retrieval_method', [RetrievalMethod]) - c_cardinality['retrieval_method'] = {"min":0} + c_cardinality['retrieval_method'] = {"min": 0} c_children['{http://www.w3.org/2000/09/xmldsig#}X509Data'] = ('x509_data', [X509Data]) - c_cardinality['x509_data'] = {"min":0} + c_cardinality['x509_data'] = {"min": 0} c_children['{http://www.w3.org/2000/09/xmldsig#}PGPData'] = ('pgp_data', [PGPData]) - c_cardinality['pgp_data'] = {"min":0} + c_cardinality['pgp_data'] = {"min": 0} c_children['{http://www.w3.org/2000/09/xmldsig#}SPKIData'] = ('spki_data', [SPKIData]) - c_cardinality['spki_data'] = {"min":0} + c_cardinality['spki_data'] = {"min": 0} c_children['{http://www.w3.org/2000/09/xmldsig#}MgmtData'] = ('mgmt_data', [MgmtData]) - c_cardinality['mgmt_data'] = {"min":0} + c_cardinality['mgmt_data'] = {"min": 0} c_children['{http://www.w3.org/2000/09/xmlenc#}EncryptedKey'] = ( 'encrypted_key', None) - c_cardinality['key_info'] = {"min":0, "max":1} + c_cardinality['key_info'] = {"min": 0, "max": 1} c_attributes['Id'] = ('id', 'ID', False) c_child_order.extend(['key_name', 'key_value', 'retrieval_method', @@ -1387,6 +1457,7 @@ class KeyInfoType_(SamlBase): self.encrypted_key = encrypted_key self.id = id + def key_info_type__from_string(xml_string): return saml2.create_class_from_xml_string(KeyInfoType_, xml_string) @@ -1402,24 +1473,25 @@ class ManifestType_(SamlBase): c_cardinality = SamlBase.c_cardinality.copy() c_children['{http://www.w3.org/2000/09/xmldsig#}Reference'] = ('reference', [Reference]) - c_cardinality['reference'] = {"min":1} + c_cardinality['reference'] = {"min": 1} c_attributes['Id'] = ('id', 'ID', False) c_child_order.extend(['reference']) def __init__(self, - reference=None, - id=None, - text=None, - extension_elements=None, - extension_attributes=None, - ): + reference=None, + id=None, + text=None, + extension_elements=None, + extension_attributes=None, + ): SamlBase.__init__(self, - text=text, - extension_elements=extension_elements, - extension_attributes=extension_attributes, - ) - self.reference=reference or [] - self.id=id + text=text, + extension_elements=extension_elements, + extension_attributes=extension_attributes, + ) + self.reference = reference or [] + self.id = id + def manifest_type__from_string(xml_string): return saml2.create_class_from_xml_string(ManifestType_, xml_string) @@ -1434,34 +1506,36 @@ class SignedInfoType_(SamlBase): c_attributes = SamlBase.c_attributes.copy() c_child_order = SamlBase.c_child_order[:] c_cardinality = SamlBase.c_cardinality.copy() - c_children['{http://www.w3.org/2000/09/xmldsig#}CanonicalizationMethod'] = ('canonicalization_method', CanonicalizationMethod) + c_children['{http://www.w3.org/2000/09/xmldsig#}CanonicalizationMethod'] = ( + 'canonicalization_method', CanonicalizationMethod) c_children['{http://www.w3.org/2000/09/xmldsig#}SignatureMethod'] = ('signature_method', SignatureMethod) c_children['{http://www.w3.org/2000/09/xmldsig#}Reference'] = ('reference', [Reference]) - c_cardinality['reference'] = {"min":1} + c_cardinality['reference'] = {"min": 1} c_attributes['Id'] = ('id', 'ID', False) c_child_order.extend(['canonicalization_method', 'signature_method', 'reference']) def __init__(self, - canonicalization_method=None, - signature_method=None, - reference=None, - id=None, - text=None, - extension_elements=None, - extension_attributes=None, - ): + canonicalization_method=None, + signature_method=None, + reference=None, + id=None, + text=None, + extension_elements=None, + extension_attributes=None, + ): SamlBase.__init__(self, - text=text, - extension_elements=extension_elements, - extension_attributes=extension_attributes, - ) - self.canonicalization_method=canonicalization_method - self.signature_method=signature_method - self.reference=reference or [] - self.id=id + text=text, + extension_elements=extension_elements, + extension_attributes=extension_attributes, + ) + self.canonicalization_method = canonicalization_method + self.signature_method = signature_method + self.reference = reference or [] + self.id = id + def signed_info_type__from_string(xml_string): return saml2.create_class_from_xml_string(SignedInfoType_, xml_string) @@ -1477,6 +1551,7 @@ class KeyInfo(KeyInfoType_): c_child_order = KeyInfoType_.c_child_order[:] c_cardinality = KeyInfoType_.c_cardinality.copy() + def key_info_from_string(xml_string): return saml2.create_class_from_xml_string(KeyInfo, xml_string) @@ -1491,6 +1566,7 @@ class Manifest(ManifestType_): c_child_order = ManifestType_.c_child_order[:] c_cardinality = ManifestType_.c_cardinality.copy() + def manifest_from_string(xml_string): return saml2.create_class_from_xml_string(Manifest, xml_string) @@ -1505,6 +1581,7 @@ class SignedInfo(SignedInfoType_): c_child_order = SignedInfoType_.c_child_order[:] c_cardinality = SignedInfoType_.c_cardinality.copy() + def signed_info_from_string(xml_string): return saml2.create_class_from_xml_string(SignedInfo, xml_string) @@ -1520,37 +1597,39 @@ class SignatureType_(SamlBase): c_cardinality = SamlBase.c_cardinality.copy() c_children['{http://www.w3.org/2000/09/xmldsig#}SignedInfo'] = ('signed_info', SignedInfo) - c_children['{http://www.w3.org/2000/09/xmldsig#}SignatureValue'] = ('signature_value', SignatureValue) + c_children['{http://www.w3.org/2000/09/xmldsig#}SignatureValue'] = ( + 'signature_value', SignatureValue) c_children['{http://www.w3.org/2000/09/xmldsig#}KeyInfo'] = ('key_info', KeyInfo) - c_cardinality['key_info'] = {"min":0, "max":1} + c_cardinality['key_info'] = {"min": 0, "max": 1} c_children['{http://www.w3.org/2000/09/xmldsig#}Object'] = ('object', [Object]) - c_cardinality['object'] = {"min":0} + c_cardinality['object'] = {"min": 0} c_attributes['Id'] = ('id', 'ID', False) c_child_order.extend(['signed_info', 'signature_value', 'key_info', 'object']) def __init__(self, - signed_info=None, - signature_value=None, - key_info=None, - object=None, - id=None, - text=None, - extension_elements=None, - extension_attributes=None, - ): + signed_info=None, + signature_value=None, + key_info=None, + object=None, + id=None, + text=None, + extension_elements=None, + extension_attributes=None, + ): SamlBase.__init__(self, - text=text, - extension_elements=extension_elements, - extension_attributes=extension_attributes, - ) - self.signed_info=signed_info - self.signature_value=signature_value - self.key_info=key_info - self.object=object or [] - self.id=id + text=text, + extension_elements=extension_elements, + extension_attributes=extension_attributes, + ) + self.signed_info = signed_info + self.signature_value = signature_value + self.key_info = key_info + self.object = object or [] + self.id = id + def signature_type__from_string(xml_string): return saml2.create_class_from_xml_string(SignatureType_, xml_string) @@ -1566,6 +1645,7 @@ class Signature(SignatureType_): c_child_order = SignatureType_.c_child_order[:] c_cardinality = SignatureType_.c_cardinality.copy() + def signature_from_string(xml_string): return saml2.create_class_from_xml_string(Signature, xml_string) @@ -1719,4 +1799,3 @@ ELEMENT_BY_TAG = { def factory(tag, **kwargs): return ELEMENT_BY_TAG[tag](**kwargs) - diff --git a/tests/test_50_server.py b/tests/test_50_server.py index c43d489..09c3bb0 100644 --- a/tests/test_50_server.py +++ b/tests/test_50_server.py @@ -32,6 +32,7 @@ from saml2 import BINDING_HTTP_REDIRECT from py.test import raises from pathutils import full_path +import saml2.xmldsig as ds nid = NameID(name_qualifier="foo", format=NAMEID_FORMAT_TRANSIENT, text="123456") @@ -86,6 +87,7 @@ def generate_cert(): class TestServer1(): + def setup_class(self): self.server = Server("idp_conf") diff --git a/tests/test_52_default_sign_alg.py b/tests/test_52_default_sign_alg.py new file mode 100644 index 0000000..2329e70 --- /dev/null +++ b/tests/test_52_default_sign_alg.py @@ -0,0 +1,175 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +import os +from saml2.authn_context import INTERNETPROTOCOLPASSWORD +from saml2.saml import NameID, NAMEID_FORMAT_TRANSIENT +from saml2.samlp import response_from_string + +from saml2.server import Server +from saml2 import client +from saml2 import config +from mock.mock import Mock, MagicMock +import saml2.xmldsig as ds + +nid = NameID(name_qualifier="foo", format=NAMEID_FORMAT_TRANSIENT, + text="123456") + +AUTHN = { + "class_ref": INTERNETPROTOCOLPASSWORD, + "authn_auth": "http://www.example.com/login" +} + + +def _eq(l1, l2): + return set(l1) == set(l2) + + +BASEDIR = os.path.abspath(os.path.dirname(__file__)) + + +def get_ava(assertion): + ava = {} + for statement in assertion.attribute_statement: + for attr in statement.attribute: + value = [] + for tmp_val in attr.attribute_value: + value.append(tmp_val.text) + key = attr.friendly_name + if key is None or len(key) == 0: + key = attr.text + ava[key] = value + return ava + + +class TestSignedResponse(): + + def setup_class(self): + self.server = Server("idp_conf") + sign_alg = Mock() + sign_alg.return_value = ds.SIG_RSA_SHA512 + digest_alg = Mock() + digest_alg.return_value = ds.DIGEST_SHA512 + self.restet_default = ds.DefaultSignature + ds.DefaultSignature = MagicMock() + ds.DefaultSignature().get_sign_alg = sign_alg + ds.DefaultSignature().get_digest_alg = digest_alg + conf = config.SPConfig() + conf.load_file("server_conf") + self.client = client.Saml2Client(conf) + self.name_id = self.server.ident.transient_nameid( + "urn:mace:example.com:saml:roland:sp", "id12") + self.ava = {"givenName": ["Derek"], "surName": ["Jeter"], + "mail": ["derek@nyy.mlb.com"], "title": "The man"} + + def teardown_class(self): + ds.DefaultSignature = self.restet_default + self.server.close() + + def verify_assertion(self, assertion): + assert assertion + assert assertion[0].attribute_statement + + ava = ava = get_ava(assertion[0]) + + assert ava ==\ + {'mail': ['derek@nyy.mlb.com'], 'givenName': ['Derek'], + 'surName': ['Jeter'], 'title': ['The man']} + + def test_signed_response(self): + + print(ds.DefaultSignature().get_digest_alg()) + name_id = self.server.ident.transient_nameid( + "urn:mace:example.com:saml:roland:sp", "id12") + ava = {"givenName": ["Derek"], "surName": ["Jeter"], + "mail": ["derek@nyy.mlb.com"], "title": "The man"} + + signed_resp = self.server.create_authn_response( + ava, + "id12", # in_response_to + "http://lingon.catalogix.se:8087/", # consumer_url + "urn:mace:example.com:saml:roland:sp", # sp_entity_id + name_id=name_id, + sign_assertion=True + ) + + print(signed_resp) + assert signed_resp + + sresponse = response_from_string(signed_resp) + assert ds.SIG_RSA_SHA512 in str(sresponse), "Not correctly signed!" + assert ds.DIGEST_SHA512 in str(sresponse), "Not correctly signed!" + + def test_signed_response_1(self): + + signed_resp = self.server.create_authn_response( + self.ava, + "id12", # in_response_to + "http://lingon.catalogix.se:8087/", # consumer_url + "urn:mace:example.com:saml:roland:sp", # sp_entity_id + name_id=self.name_id, + sign_response=True, + sign_assertion=True, + ) + + sresponse = response_from_string(signed_resp) + assert ds.SIG_RSA_SHA512 in str(sresponse), "Not correctly signed!" + assert ds.DIGEST_SHA512 in str(sresponse), "Not correctly signed!" + valid = self.server.sec.verify_signature(signed_resp, + self.server.config.cert_file, + node_name='urn:oasis:names:tc:SAML:2.0:protocol:Response', + node_id=sresponse.id, + id_attr="") + assert valid + assert ds.SIG_RSA_SHA512 in str(sresponse.assertion[0]), "Not correctly signed!" + assert ds.DIGEST_SHA512 in str(sresponse.assertion[0]), "Not correctly signed!" + valid = self.server.sec.verify_signature(signed_resp, + self.server.config.cert_file, + node_name='urn:oasis:names:tc:SAML:2.0:assertion:Assertion', + node_id=sresponse.assertion[0].id, + id_attr="") + assert valid + + self.verify_assertion(sresponse.assertion) + + def test_signed_response_2(self): + + signed_resp = self.server.create_authn_response( + self.ava, + "id12", # in_response_to + "http://lingon.catalogix.se:8087/", # consumer_url + "urn:mace:example.com:saml:roland:sp", # sp_entity_id + name_id=self.name_id, + sign_response=True, + sign_assertion=True, + sign_alg=ds.SIG_RSA_SHA256, + digest_alg=ds.DIGEST_SHA512 + ) + + sresponse = response_from_string(signed_resp) + assert ds.SIG_RSA_SHA256 in str(sresponse), "Not correctly signed!" + assert ds.DIGEST_SHA512 in str(sresponse), "Not correctly signed!" + valid = self.server.sec.verify_signature(signed_resp, + self.server.config.cert_file, + node_name='urn:oasis:names:tc:SAML:2.0:protocol:Response', + node_id=sresponse.id, + id_attr="") + assert valid + assert ds.SIG_RSA_SHA256 in str(sresponse.assertion[0]), "Not correctly signed!" + assert ds.DIGEST_SHA512 in str(sresponse.assertion[0]), "Not correctly signed!" + valid = self.server.sec.verify_signature(signed_resp, + self.server.config.cert_file, + node_name='urn:oasis:names:tc:SAML:2.0:assertion:Assertion', + node_id=sresponse.assertion[0].id, + id_attr="") + assert valid + + self.verify_assertion(sresponse.assertion) + + + +if __name__ == "__main__": + ts = TestSignedResponse() + ts.setup_class() + ts.test_signed_response() + ts.test_signed_response_1() + ts.test_signed_response_2() \ No newline at end of file From 664503f3f8a92f53a807d31c1b77fae8a153a681 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Ho=CC=88rberg?= Date: Fri, 6 Nov 2015 12:25:59 +0100 Subject: [PATCH 2/6] Added configuration so the test sp can change sign and digest algorithm. If SIGN_ALG = None DIGEST_ALG = None in service_conf sha1 will be used. --- example/sp-wsgi/service_conf.py | 7 ++++++- example/sp-wsgi/sp.py | 3 +++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/example/sp-wsgi/service_conf.py b/example/sp-wsgi/service_conf.py index 1d18261..b2461f2 100644 --- a/example/sp-wsgi/service_conf.py +++ b/example/sp-wsgi/service_conf.py @@ -1,8 +1,13 @@ from saml2.assertion import Policy +import saml2.xmldsig as ds -HOST = '127.0.0.1' +HOST = 'localhost' PORT = 8087 HTTPS = False +SIGN_ALG = None +DIGEST_ALG = None +#SIGN_ALG = ds.SIG_RSA_SHA512 +#DIGEST_ALG = ds.DIGEST_SHA512 # Which groups of entity categories to use POLICY = Policy( diff --git a/example/sp-wsgi/sp.py b/example/sp-wsgi/sp.py index 9461575..9d21695 100755 --- a/example/sp-wsgi/sp.py +++ b/example/sp-wsgi/sp.py @@ -41,6 +41,7 @@ from saml2.s_utils import rndstr #from srtest import exception_trace from saml2.samlp import Extensions from saml2 import xmldsig as ds +import saml2.xmldsig as ds logger = logging.getLogger("") hdlr = logging.FileHandler('spx.log') @@ -877,6 +878,8 @@ if __name__ == '__main__': add_urls() + ds.DefaultSignature(service_conf.SIGN_ALG, service_conf.DIGEST_ALG) + SRV = wsgiserver.CherryPyWSGIServer((HOST, PORT), application) _https = "" From 1d1b7b2624745e8d3605a159a0de37fb8ac95f5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Ho=CC=88rberg?= Date: Fri, 6 Nov 2015 12:40:47 +0100 Subject: [PATCH 3/6] Changed the sp to accept config files without sign and digest configurations. --- example/sp-wsgi/sp.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/example/sp-wsgi/sp.py b/example/sp-wsgi/sp.py index 9d21695..2775959 100755 --- a/example/sp-wsgi/sp.py +++ b/example/sp-wsgi/sp.py @@ -877,8 +877,17 @@ if __name__ == '__main__': POLICY = service_conf.POLICY add_urls() - - ds.DefaultSignature(service_conf.SIGN_ALG, service_conf.DIGEST_ALG) + sign_alg = None + digest_alg = None + try: + sign_alg = service_conf.SIGN_ALG + except: + pass + try: + digest_alg = service_conf.DIGEST_ALG + except: + pass + ds.DefaultSignature(sign_alg, digest_alg) SRV = wsgiserver.CherryPyWSGIServer((HOST, PORT), application) From 8c901a8f84748a2a2e273a729b16077d8dbcd606 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Ho=CC=88rberg?= Date: Fri, 6 Nov 2015 12:41:30 +0100 Subject: [PATCH 4/6] Added configuration so the test idp can change sign and digest algorithm. If SIGN_ALG = None DIGEST_ALG = None in service_conf sha1 will be used. --- example/idp2/idp.py | 13 +++++++++++++ example/idp2/idp_conf.py.example | 6 ++++++ 2 files changed, 19 insertions(+) diff --git a/example/idp2/idp.py b/example/idp2/idp.py index f3db83e..4d67a8d 100755 --- a/example/idp2/idp.py +++ b/example/idp2/idp.py @@ -51,6 +51,7 @@ from saml2.sigver import encrypt_cert_from_item from idp_user import USERS from idp_user import EXTRA from mako.lookup import TemplateLookup +import saml2.xmldsig as ds logger = logging.getLogger("saml2.idp") logger.setLevel(logging.WARNING) @@ -1067,6 +1068,18 @@ if __name__ == '__main__': HOST = CONFIG.HOST PORT = CONFIG.PORT + sign_alg = None + digest_alg = None + try: + sign_alg = CONFIG.SIGN_ALG + except: + pass + try: + digest_alg = CONFIG.DIGEST_ALG + except: + pass + ds.DefaultSignature(sign_alg, digest_alg) + SRV = wsgiserver.CherryPyWSGIServer((HOST, PORT), application) _https = "" diff --git a/example/idp2/idp_conf.py.example b/example/idp2/idp_conf.py.example index 1a2e4ec..dda1733 100644 --- a/example/idp2/idp_conf.py.example +++ b/example/idp2/idp_conf.py.example @@ -8,6 +8,7 @@ from saml2.saml import NAME_FORMAT_URI from saml2.saml import NAMEID_FORMAT_TRANSIENT from saml2.saml import NAMEID_FORMAT_PERSISTENT import os.path +import saml2.xmldsig as ds try: from saml2.sigver import get_xmlsec_binary @@ -39,6 +40,11 @@ else: SERVER_CERT = "pki/mycert.pem" SERVER_KEY = "pki/mykey.pem" CERT_CHAIN = "" +SIGN_ALG = None +DIGEST_ALG = None +#SIGN_ALG = ds.SIG_RSA_SHA512 +#DIGEST_ALG = ds.DIGEST_SHA512 + CONFIG = { "entityid": "%s/idp.xml" % BASE, From 361b29f4641c2e75d7a522990e0e5789e488c3c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Ho=CC=88rberg?= Date: Thu, 19 Nov 2015 10:36:56 +0100 Subject: [PATCH 5/6] Merge remote-tracking branch 'upstream/master' # Conflicts: # src/saml2/entity.py digest algorithm added to the same functions as sign alg. --- src/saml2/client.py | 6 +++--- src/saml2/client_base.py | 16 ++++++++-------- src/saml2/metadata.py | 4 ++-- src/saml2/server.py | 18 +++++++++--------- src/saml2/sigver.py | 4 ++-- src/saml2/xmldsig/__init__.py | 4 ++-- tests/test_52_default_sign_alg.py | 6 +++--- 7 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/saml2/client.py b/src/saml2/client.py index 54525cb..42c6eb8 100644 --- a/src/saml2/client.py +++ b/src/saml2/client.py @@ -160,7 +160,7 @@ class Saml2Client(Base): # find out which IdPs/AAs I should notify entity_ids = self.users.issuers_of_info(name_id) - return self.do_logout(name_id, entity_ids, reason, expire, sign, sign_alg=sign_alg) + return self.do_logout(name_id, entity_ids, reason, expire, sign, sign_alg=sign_alg, digest_alg=digest_alg) def do_logout(self, name_id, entity_ids, reason, expire, sign=None, expected_binding=None, sign_alg=None, digest_alg=None, **kwargs): @@ -232,7 +232,7 @@ class Saml2Client(Base): key = kwargs.get("key", self.signkey) srequest = str(request) else: - srequest = self.sign(request, sign_alg=sign_alg) + srequest = self.sign(request, sign_alg=sign_alg, digest_alg=digest_alg) else: srequest = str(request) @@ -316,7 +316,7 @@ class Saml2Client(Base): return self.do_logout(decode(status["name_id"]), status["entity_ids"], status["reason"], status["not_on_or_after"], - status["sign"], sign_alg=sign_alg) + status["sign"], sign_alg=sign_alg, digest_alg=digest_alg) def _use_soap(self, destination, query_type, **kwargs): _create_func = getattr(self, "create_%s" % query_type) diff --git a/src/saml2/client_base.py b/src/saml2/client_base.py index 02be7ae..e4152a0 100644 --- a/src/saml2/client_base.py +++ b/src/saml2/client_base.py @@ -339,11 +339,11 @@ class Base(Entity): return self._message(AuthnRequest, destination, message_id, consent, extensions, sign, sign_prepare, protocol_binding=binding, - scoping=scoping, nsprefix=nsprefix, sign_alg=sign_alg, **args) + scoping=scoping, nsprefix=nsprefix, sign_alg=sign_alg, digest_alg=digest_alg, **args) return self._message(AuthnRequest, destination, message_id, consent, extensions, sign, sign_prepare, protocol_binding=binding, - scoping=scoping, nsprefix=nsprefix, sign_alg=sign_alg, **args) + scoping=scoping, nsprefix=nsprefix, sign_alg=sign_alg, digest_alg=digest_alg, **args) def create_attribute_query(self, destination, name_id=None, attribute=None, message_id=0, consent=None, @@ -404,7 +404,7 @@ class Base(Entity): return self._message(AttributeQuery, destination, message_id, consent, extensions, sign, sign_prepare, subject=subject, - attribute=attribute, nsprefix=nsprefix, sign_alg=sign_alg) + attribute=attribute, nsprefix=nsprefix, sign_alg=sign_alg, digest_alg=digest_alg) # MUST use SOAP for # AssertionIDRequest, SubjectQuery, @@ -430,7 +430,7 @@ class Base(Entity): return self._message(AuthzDecisionQuery, destination, message_id, consent, extensions, sign, action=action, evidence=evidence, resource=resource, - subject=subject, sign_alg=sign_alg, **kwargs) + subject=subject, sign_alg=sign_alg, digest_alg=digest_alg, **kwargs) def create_authz_decision_query_using_assertion(self, destination, assertion, action=None, @@ -499,7 +499,7 @@ class Base(Entity): extensions, sign, subject=subject, session_index=session_index, requested_authn_context=authn_context, - nsprefix=nsprefix, sign_alg=sign_alg) + nsprefix=nsprefix, sign_alg=sign_alg, digest_alg=digest_alg) def create_name_id_mapping_request(self, name_id_policy, name_id=None, base_id=None, @@ -528,17 +528,17 @@ class Base(Entity): return self._message(NameIDMappingRequest, destination, message_id, consent, extensions, sign, name_id_policy=name_id_policy, name_id=name_id, - nsprefix=nsprefix, sign_alg=sign_alg) + nsprefix=nsprefix, sign_alg=sign_alg, digest_alg=digest_alg) elif base_id: return self._message(NameIDMappingRequest, destination, message_id, consent, extensions, sign, name_id_policy=name_id_policy, base_id=base_id, - nsprefix=nsprefix, sign_alg=sign_alg) + nsprefix=nsprefix, sign_alg=sign_alg, digest_alg=digest_alg) else: return self._message(NameIDMappingRequest, destination, message_id, consent, extensions, sign, name_id_policy=name_id_policy, - encrypted_id=encrypted_id, nsprefix=nsprefix, sign_alg=sign_alg) + encrypted_id=encrypted_id, nsprefix=nsprefix, sign_alg=sign_alg, digest_alg=digest_alg) # ======== response handling =========== diff --git a/src/saml2/metadata.py b/src/saml2/metadata.py index b095252..4a85ccf 100644 --- a/src/saml2/metadata.py +++ b/src/saml2/metadata.py @@ -775,7 +775,7 @@ def entities_descriptor(eds, valid_for, name, ident, sign, secc, sign_alg=None, raise SAMLError("If you want to do signing you should define " + "where your public key are") - entities.signature = pre_signature_part(ident, secc.my_cert, 1, sign_alg=sign_alg) + entities.signature = pre_signature_part(ident, secc.my_cert, 1, sign_alg=sign_alg, digest_alg=digest_alg) entities.id = ident xmldoc = secc.sign_statement("%s" % entities, class_name(entities)) entities = md.entities_descriptor_from_string(xmldoc) @@ -797,7 +797,7 @@ def sign_entity_descriptor(edesc, ident, secc, sign_alg=None, digest_alg=None): if not ident: ident = sid() - edesc.signature = pre_signature_part(ident, secc.my_cert, 1, sign_alg=sign_alg) + edesc.signature = pre_signature_part(ident, secc.my_cert, 1, sign_alg=sign_alg, digest_alg=digest_alg) edesc.id = ident xmldoc = secc.sign_statement("%s" % edesc, class_name(edesc)) edesc = md.entity_descriptor_from_string(xmldoc) diff --git a/src/saml2/server.py b/src/saml2/server.py index b4bc9e2..2e540ce 100644 --- a/src/saml2/server.py +++ b/src/saml2/server.py @@ -399,7 +399,7 @@ class Server(Entity): if not encrypt_assertion: if sign_assertion: assertion.signature = pre_signature_part(assertion.id, self.sec.my_cert, 1, - sign_alg=sign_alg) + sign_alg=sign_alg, digest_alg=digest_alg) to_sign.append((class_name(assertion), assertion.id)) #if not encrypted_advice_attributes: @@ -429,7 +429,7 @@ class Server(Entity): encrypt_assertion_self_contained=encrypt_assertion_self_contained, encrypted_advice_attributes=encrypted_advice_attributes, sign_assertion=sign_assertion, - pefim=pefim, sign_alg=sign_alg, + pefim=pefim, sign_alg=sign_alg, digest_alg=digest_alg, **args) # ------------------------------------------------------------------------ @@ -489,14 +489,14 @@ class Server(Entity): if sign_assertion: assertion.signature = pre_signature_part(assertion.id, - self.sec.my_cert, 1, sign_alg=sign_alg) + self.sec.my_cert, 1, sign_alg=sign_alg, digest_alg=digest_alg) # Just the assertion or the response and the assertion ? to_sign = [(class_name(assertion), assertion.id)] args["assertion"] = assertion return self._response(in_response_to, destination, status, issuer, - sign_response, to_sign, sign_alg=sign_alg, **args) + sign_response, to_sign, sign_alg=sign_alg, digest_alg=digest_alg, **args) # ------------------------------------------------------------------------ @@ -648,7 +648,7 @@ class Server(Entity): encrypt_cert_advice=encrypt_cert_advice, encrypt_cert_assertion=encrypt_cert_assertion, pefim=pefim, - sign_alg=sign_alg) + sign_alg=sign_alg, digest_alg=digest_alg) return self._authn_response(in_response_to, # in_response_to destination, # consumer_url sp_entity_id, # sp_entity_id @@ -666,7 +666,7 @@ class Server(Entity): encrypt_cert_advice=encrypt_cert_advice, encrypt_cert_assertion=encrypt_cert_assertion, pefim=pefim, - sign_alg=sign_alg) + sign_alg=sign_alg, digest_alg=digest_alg) except MissingValue as exc: return self.create_error_response(in_response_to, destination, @@ -703,7 +703,7 @@ class Server(Entity): if to_sign: if assertion.signature is None: assertion.signature = pre_signature_part(assertion.id, - self.sec.my_cert, 1, sign_alg=sign_alg) + self.sec.my_cert, 1, sign_alg=sign_alg, digest_alg=digest_alg) return signed_instance_factory(assertion, self.sec, to_sign) else: @@ -735,7 +735,7 @@ class Server(Entity): in_response_to=in_response_to, **ms_args) if sign_response: - return self.sign(_resp, sign_alg=sign_alg) + return self.sign(_resp, sign_alg=sign_alg, digest_alg=digest_alg) else: logger.info("Message: %s", _resp) return _resp @@ -764,7 +764,7 @@ class Server(Entity): args = {} return self._response(in_response_to, "", status, issuer, - sign_response, to_sign=[], sign_alg=sign_alg, **args) + sign_response, to_sign=[], sign_alg=sign_alg, digest_alg=digest_alg, **args) # --------- diff --git a/src/saml2/sigver.py b/src/saml2/sigver.py index 7ec8f6a..ec48f4e 100644 --- a/src/saml2/sigver.py +++ b/src/saml2/sigver.py @@ -1779,7 +1779,7 @@ class SecurityContext(object): sid = item.id if not item.signature: - item.signature = pre_signature_part(sid, self.cert_file, sign_alg=sign_alg) + item.signature = pre_signature_part(sid, self.cert_file, sign_alg=sign_alg, digest_alg=digest_alg) statement = self.sign_statement(statement, class_name(item), key=key, key_file=key_file, @@ -1922,7 +1922,7 @@ def response_factory(sign=False, encrypt=False, sign_alg=None, digest_alg=None, issue_instant=instant()) if sign: - response.signature = pre_signature_part(kwargs["id"], sign_alg=sign_alg) + response.signature = pre_signature_part(kwargs["id"], sign_alg=sign_alg, digest_alg=digest_alg) if encrypt: pass diff --git a/src/saml2/xmldsig/__init__.py b/src/saml2/xmldsig/__init__.py index ded87ec..d753bb1 100644 --- a/src/saml2/xmldsig/__init__.py +++ b/src/saml2/xmldsig/__init__.py @@ -61,8 +61,8 @@ TRANSFORM_XPATH = 'http://www.w3.org/TR/1999/REC-xpath-19991116' TRANSFORM_ENVELOPED = 'http://www.w3.org/2000/09/xmldsig#enveloped-signature' -class DefaultSignature: - class _DefaultSignature: +class DefaultSignature(object): + class _DefaultSignature(object): def __init__(self, sign_alg=None, digest_alg=None): if sign_alg is None: self.sign_alg = sig_default diff --git a/tests/test_52_default_sign_alg.py b/tests/test_52_default_sign_alg.py index 2329e70..73da3d1 100644 --- a/tests/test_52_default_sign_alg.py +++ b/tests/test_52_default_sign_alg.py @@ -142,12 +142,12 @@ class TestSignedResponse(): sign_response=True, sign_assertion=True, sign_alg=ds.SIG_RSA_SHA256, - digest_alg=ds.DIGEST_SHA512 + digest_alg=ds.DIGEST_SHA256 ) sresponse = response_from_string(signed_resp) assert ds.SIG_RSA_SHA256 in str(sresponse), "Not correctly signed!" - assert ds.DIGEST_SHA512 in str(sresponse), "Not correctly signed!" + assert ds.DIGEST_SHA256 in str(sresponse), "Not correctly signed!" valid = self.server.sec.verify_signature(signed_resp, self.server.config.cert_file, node_name='urn:oasis:names:tc:SAML:2.0:protocol:Response', @@ -155,7 +155,7 @@ class TestSignedResponse(): id_attr="") assert valid assert ds.SIG_RSA_SHA256 in str(sresponse.assertion[0]), "Not correctly signed!" - assert ds.DIGEST_SHA512 in str(sresponse.assertion[0]), "Not correctly signed!" + assert ds.DIGEST_SHA256 in str(sresponse.assertion[0]), "Not correctly signed!" valid = self.server.sec.verify_signature(signed_resp, self.server.config.cert_file, node_name='urn:oasis:names:tc:SAML:2.0:assertion:Assertion', From be15a1e9c5f28cddb28b095f8da720a9f029c5c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Ho=CC=88rberg?= Date: Thu, 19 Nov 2015 15:48:38 +0100 Subject: [PATCH 6/6] Added mock --- tests/test_52_default_sign_alg.py | 4 +--- tests/test_requirements.txt | 3 ++- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/test_52_default_sign_alg.py b/tests/test_52_default_sign_alg.py index 73da3d1..6ef8d63 100644 --- a/tests/test_52_default_sign_alg.py +++ b/tests/test_52_default_sign_alg.py @@ -165,11 +165,9 @@ class TestSignedResponse(): self.verify_assertion(sresponse.assertion) - - if __name__ == "__main__": ts = TestSignedResponse() ts.setup_class() ts.test_signed_response() ts.test_signed_response_1() - ts.test_signed_response_2() \ No newline at end of file + ts.test_signed_response_2() diff --git a/tests/test_requirements.txt b/tests/test_requirements.txt index 56bc7ad..537fccd 100644 --- a/tests/test_requirements.txt +++ b/tests/test_requirements.txt @@ -1,2 +1,3 @@ pymongo==3.0.1 -responses==0.5.0 \ No newline at end of file +responses==0.5.0 +mock \ No newline at end of file