def test_xbox_non_ascii_ava(): conf = config.SPConfig() conf.load_file("server_conf") md = MetadataStore([saml, samlp], None, conf) md.load("local", IDP_EXAMPLE) conf.metadata = md conf.only_use_keys_in_metadata = False sec = sigver.security_context(conf) assertion = factory( saml.Assertion, version="2.0", id="id-11111", issue_instant="2009-10-30T13:20:28Z", signature=sigver.pre_signature_part("id-11111", sec.my_cert, 1), attribute_statement=do_attribute_statement( { ("", "", "surName"): ("Föö", ""), ("", "", "givenName"): ("Bär", ""), } ) ) sigass = sec.sign_statement( assertion, class_name(assertion), key_file=PRIV_KEY, node_id=assertion.id, ) _ass0 = saml.assertion_from_string(sigass) encrypted_assertion = EncryptedAssertion() encrypted_assertion.add_extension_element(_ass0) tmp = make_temp( str(pre_encryption_part()).encode('utf-8'), decode=False ) enctext = sec.crypto.encrypt( str(encrypted_assertion), conf.cert_file, tmp.name, "des-192", '/*[local-name()="EncryptedAssertion"]/*[local-name()="Assertion"]', ) decr_text = sec.decrypt(enctext, key_file=PRIV_KEY) _seass = saml.encrypted_assertion_from_string(decr_text) assertions = [] assers = extension_elements_to_elements( _seass.extension_elements, [saml, samlp] ) for ass in assers: _txt = sec.verify_signature( str(ass), PUB_KEY, node_name=class_name(assertion) ) if _txt: assertions.append(ass) assert assertions print(assertions)
def test_xbox_non_ascii_ava(): conf = config.SPConfig() conf.load_file("server_conf") md = MetadataStore([saml, samlp], None, conf) md.load("local", IDP_EXAMPLE) conf.metadata = md conf.only_use_keys_in_metadata = False sec = sigver.security_context(conf) assertion = factory( saml.Assertion, version="2.0", id="11111", issue_instant="2009-10-30T13:20:28Z", signature=sigver.pre_signature_part("11111", sec.my_cert, 1), attribute_statement=do_attribute_statement( { ("", "", "surName"): ("Föö", ""), ("", "", "givenName"): ("Bär", ""), } ) ) sigass = sec.sign_statement( assertion, class_name(assertion), key_file=PRIV_KEY, node_id=assertion.id, ) _ass0 = saml.assertion_from_string(sigass) encrypted_assertion = EncryptedAssertion() encrypted_assertion.add_extension_element(_ass0) _, pre = make_temp( str(pre_encryption_part()).encode('utf-8'), decode=False ) enctext = sec.crypto.encrypt( str(encrypted_assertion), conf.cert_file, pre, "des-192", '/*[local-name()="EncryptedAssertion"]/*[local-name()="Assertion"]', ) decr_text = sec.decrypt(enctext, key_file=PRIV_KEY) _seass = saml.encrypted_assertion_from_string(decr_text) assertions = [] assers = extension_elements_to_elements( _seass.extension_elements, [saml, samlp] ) for ass in assers: _txt = sec.verify_signature( str(ass), PUB_KEY, node_name=class_name(assertion) ) if _txt: assertions.append(ass) assert assertions print(assertions)
def _encrypt_assertion(self, encrypt_cert, sp_entity_id, response, node_xpath=None): """ Encryption of assertions. :param encrypt_cert: Certificate to be used for encryption. :param sp_entity_id: Entity ID for the calling service provider. :param response: A samlp.Response :param node_xpath: Unquie path to the element to be encrypted. :return: A new samlp.Resonse with the designated assertion encrypted. """ _certs = [] cbxs = CryptoBackendXmlSec1(self.config.xmlsec_binary) if encrypt_cert: _certs = [] _certs.append(encrypt_cert) elif sp_entity_id is not None: _certs = self.metadata.certs(sp_entity_id, "any", "encryption") exception = None for _cert in _certs: try: begin_cert = "-----BEGIN CERTIFICATE-----\n" end_cert = "\n-----END CERTIFICATE-----\n" if begin_cert not in _cert: _cert = "%s%s" % (begin_cert, _cert) if end_cert not in _cert: _cert = "%s%s" % (_cert, end_cert) _, cert_file = make_temp(_cert.encode('ascii'), decode=False) response = cbxs.encrypt_assertion(response, cert_file, pre_encryption_part(), node_xpath=node_xpath) return response except Exception as ex: exception = ex pass if exception: raise exception return response
def test_pre_enc_with_generated_key(): tmpl = pre_encryption_part() expected = TMPL_NO_HEADER.format( ed_id=tmpl.id, ek_id=tmpl.key_info.encrypted_key.id, ) assert str(tmpl) == expected
def test_pre_enc_with_named_key(): tmpl = pre_encryption_part(key_name="my-rsa-key") expected = TMPL_NO_HEADER.format( ed_id=tmpl.id, ek_id=tmpl.key_info.encrypted_key.id, key_info= '<ns1:KeyInfo><ns1:KeyName>my-rsa-key</ns1:KeyName></ns1:KeyInfo>') assert str(tmpl) == expected
def _response(self, in_response_to, consumer_url=None, status=None, issuer=None, sign=False, to_sign=None, encrypt_assertion=False, encrypt_cert=None, **kwargs): """ Create a Response. :param in_response_to: The session identifier of the request :param consumer_url: The URL which should receive the response :param status: The status of the response :param issuer: The issuer of the response :param sign: Whether the response should be signed or not :param to_sign: If there are other parts to sign :param kwargs: Extra key word arguments :return: A Response instance """ if not status: status = success_status_factory() _issuer = self._issuer(issuer) response = response_factory(issuer=_issuer, in_response_to=in_response_to, status=status) if consumer_url: response.destination = consumer_url self._add_info(response, **kwargs) if not sign and to_sign and not encrypt_assertion: return signed_instance_factory(response, self.sec, to_sign) if encrypt_assertion: sign_class = [(class_name(response), response.id)] if sign: response.signature = pre_signature_part( response.id, self.sec.my_cert, 1) cbxs = CryptoBackendXmlSec1(self.config.xmlsec_binary) _, cert_file = make_temp("%s" % encrypt_cert, decode=False) response = cbxs.encrypt_assertion(response, cert_file, pre_encryption_part()) #template(response.assertion.id)) if sign: return signed_instance_factory(response, self.sec, sign_class) else: return response if sign: return self.sign(response, to_sign=to_sign) else: return response
def test_xbox(): conf = config.SPConfig() conf.load_file("server_conf") md = MetadataStore([saml, samlp], None, conf) md.load("local", full_path("idp_example.xml")) conf.metadata = md conf.only_use_keys_in_metadata = False sec = sigver.security_context(conf) assertion = factory(saml.Assertion, version="2.0", id="11111", issue_instant="2009-10-30T13:20:28Z", signature=sigver.pre_signature_part( "11111", sec.my_cert, 1), attribute_statement=do_attribute_statement({ ("", "", "surName"): ("Foo", ""), ("", "", "givenName"): ("Bar", ""), })) sigass = sec.sign_statement(assertion, class_name(assertion), key_file=full_path("test.key"), node_id=assertion.id) _ass0 = saml.assertion_from_string(sigass) encrypted_assertion = EncryptedAssertion() encrypted_assertion.add_extension_element(_ass0) _, pre = make_temp(str(pre_encryption_part()).encode('utf-8'), decode=False) enctext = sec.crypto.encrypt( str(encrypted_assertion), conf.cert_file, pre, "des-192", '/*[local-name()="EncryptedAssertion"]/*[local-name()="Assertion"]') decr_text = sec.decrypt(enctext) _seass = saml.encrypted_assertion_from_string(decr_text) assertions = [] assers = extension_elements_to_elements(_seass.extension_elements, [saml, samlp]) sign_cert_file = full_path("test.pem") for ass in assers: _ass = "%s" % ass #_ass = _ass.replace('xsi:nil="true" ', '') #assert sigass == _ass _txt = sec.verify_signature(_ass, sign_cert_file, node_name=class_name(assertion)) if _txt: assertions.append(ass) print(assertions)
def _response(self, in_response_to, consumer_url=None, status=None, issuer=None, sign=False, to_sign=None, encrypt_assertion=False, encrypt_cert=None, **kwargs): """ Create a Response. :param in_response_to: The session identifier of the request :param consumer_url: The URL which should receive the response :param status: The status of the response :param issuer: The issuer of the response :param sign: Whether the response should be signed or not :param to_sign: If there are other parts to sign :param kwargs: Extra key word arguments :return: A Response instance """ if not status: status = success_status_factory() _issuer = self._issuer(issuer) response = response_factory(issuer=_issuer, in_response_to=in_response_to, status=status) if consumer_url: response.destination = consumer_url self._add_info(response, **kwargs) if not sign and to_sign and not encrypt_assertion: return signed_instance_factory(response, self.sec, to_sign) if encrypt_assertion: if sign: response.signature = pre_signature_part(response.id, self.sec.my_cert, 1) cbxs = CryptoBackendXmlSec1(self.config.xmlsec_binary) _, cert_file = make_temp("%s" % encrypt_cert, decode=False) response = cbxs.encrypt_assertion(response, cert_file, pre_encryption_part()) # template(response.assertion.id)) if sign: if to_sign: signed_instance_factory(response, self.sec, to_sign) else: # default is to sign the whole response if anything sign_class = [(class_name(response), response.id)] return signed_instance_factory(response, self.sec, sign_class) else: return response if sign: return self.sign(response, to_sign=to_sign) else: return response
def test_sign_then_encrypt_assertion2(self): # Begin with the IdPs side _sec = self.server.sec nameid_policy = samlp.NameIDPolicy( allow_create="false", format=saml.NAMEID_FORMAT_PERSISTENT) asser = Assertion({"givenName": "Derek", "surName": "Jeter"}) assertion = asser.construct( self.client.config.entityid, "_012345", "http://lingon.catalogix.se:8087/", factory(saml.NameID, format=saml.NAMEID_FORMAT_TRANSIENT), policy=self.server.config.getattr("policy", "idp"), issuer=self.server._issuer(), attrconvs=self.server.config.attribute_converters, authn_class=INTERNETPROTOCOLPASSWORD, authn_auth="http://www.example.com/login") assertion.signature = sigver.pre_signature_part( assertion.id, _sec.my_cert, 1) sigass = _sec.sign_statement(assertion, class_name(assertion), key_file=self.client.sec.key_file, node_id=assertion.id) sigass = rm_xmltag(sigass) response = sigver.response_factory( in_response_to="_012345", destination="http://lingon.catalogix.se:8087/", status=s_utils.success_status_factory(), issuer=self.server._issuer(), encrypted_assertion=EncryptedAssertion()) xmldoc = "%s" % response # strangely enough I get different tags if I run this test separately # or as part of a bunch of tests. xmldoc = add_subelement(xmldoc, "EncryptedAssertion", sigass) enctext = _sec.crypto.encrypt_assertion(xmldoc, _sec.cert_file, pre_encryption_part()) #seresp = samlp.response_from_string(enctext) resp_str = base64.encodestring(enctext) # Now over to the client side resp = self.client.parse_authn_request_response( resp_str, BINDING_HTTP_POST, {"_012345": "http://foo.example.com/service"}) #assert resp.encrypted_assertion == [] assert resp.assertion assert resp.ava == {'givenName': ['Derek'], 'sn': ['Jeter']}
def test_sign_then_encrypt_assertion2(self): # Begin with the IdPs side _sec = self.server.sec nameid_policy = samlp.NameIDPolicy(allow_create="false", format=saml.NAMEID_FORMAT_PERSISTENT) asser = Assertion({"givenName": "Derek", "surName": "Jeter"}) assertion = asser.construct( self.client.config.entityid, "_012345", "http://lingon.catalogix.se:8087/", factory(saml.NameID, format=saml.NAMEID_FORMAT_TRANSIENT), policy=self.server.config.getattr("policy", "idp"), issuer=self.server._issuer(), attrconvs=self.server.config.attribute_converters, authn_class=INTERNETPROTOCOLPASSWORD, authn_auth="http://www.example.com/login") assertion.signature = sigver.pre_signature_part( assertion.id, _sec.my_cert, 1) sigass = _sec.sign_statement(assertion, class_name(assertion), key_file=self.client.sec.key_file, node_id=assertion.id) sigass = rm_xmltag(sigass) response = sigver.response_factory( in_response_to="_012345", destination="https://www.example.com", status=s_utils.success_status_factory(), issuer=self.server._issuer(), encrypted_assertion=EncryptedAssertion() ) xmldoc = "%s" % response # strangely enough I get different tags if I run this test separately # or as part of a bunch of tests. xmldoc = add_subelement(xmldoc, "EncryptedAssertion", sigass) enctext = _sec.crypto.encrypt_assertion(xmldoc, _sec.cert_file, pre_encryption_part()) #seresp = samlp.response_from_string(enctext) resp_str = base64.encodestring(enctext) # Now over to the client side resp = self.client.parse_authn_request_response( resp_str, BINDING_HTTP_POST, {"_012345": "http://foo.example.com/service"}) #assert resp.encrypted_assertion == [] assert resp.assertion assert resp.ava == {'givenName': ['Derek'], 'sn': ['Jeter']}
def test_xbox(): conf = config.SPConfig() conf.load_file("server_conf") md = MetadataStore([saml, samlp], None, conf) md.load("local", full_path("idp_example.xml")) conf.metadata = md conf.only_use_keys_in_metadata = False sec = sigver.security_context(conf) assertion = factory( saml.Assertion, version="2.0", id="11111", issue_instant="2009-10-30T13:20:28Z", signature=sigver.pre_signature_part("11111", sec.my_cert, 1), attribute_statement=do_attribute_statement( {("", "", "surName"): ("Foo", ""), ("", "", "givenName"): ("Bar", "")} ), ) sigass = sec.sign_statement(assertion, class_name(assertion), key_file=full_path("test.key"), node_id=assertion.id) _ass0 = saml.assertion_from_string(sigass) encrypted_assertion = EncryptedAssertion() encrypted_assertion.add_extension_element(_ass0) _, pre = make_temp(str(pre_encryption_part()).encode("utf-8"), decode=False) enctext = sec.crypto.encrypt( str(encrypted_assertion), conf.cert_file, pre, "des-192", '/*[local-name()="EncryptedAssertion"]/*[local-name()="Assertion"]', ) decr_text = sec.decrypt(enctext) _seass = saml.encrypted_assertion_from_string(decr_text) assertions = [] assers = extension_elements_to_elements(_seass.extension_elements, [saml, samlp]) sign_cert_file = full_path("test.pem") for ass in assers: _ass = "%s" % ass # _ass = _ass.replace('xsi:nil="true" ', '') # assert sigass == _ass _txt = sec.verify_signature(_ass, sign_cert_file, node_name=class_name(assertion)) if _txt: assertions.append(ass) print(assertions)
def test_sign_then_encrypt_assertion2(self): # Begin with the IdPs side _sec = self.server.sec nameid_policy = samlp.NameIDPolicy( allow_create="false", format=saml.NAMEID_FORMAT_PERSISTENT) asser = Assertion({"givenName": "Derek", "surName": "Jeter"}) assertion = asser.construct( self.client.config.entityid, "_012345", "http://lingon.catalogix.se:8087/", factory(saml.NameID, format=saml.NAMEID_FORMAT_TRANSIENT), policy=self.server.config.getattr("policy", "idp"), issuer=self.server._issuer(), attrconvs=self.server.config.attribute_converters, authn_class=INTERNETPROTOCOLPASSWORD, authn_auth="http://www.example.com/login") assertion.signature = sigver.pre_signature_part( assertion.id, _sec.my_cert, 1) sigass = _sec.sign_statement( assertion, class_name(assertion), #key_file="pki/mykey.pem", key_file="test.key", node_id=assertion.id) # Create an Assertion instance from the signed assertion _ass = saml.assertion_from_string(sigass) response = sigver.response_factory( in_response_to="_012345", destination="https://www.example.com", status=s_utils.success_status_factory(), issuer=self.server._issuer(), assertion=_ass) enctext = _sec.crypto.encrypt_assertion(response, _sec.cert_file, pre_encryption_part()) #seresp = samlp.response_from_string(enctext) resp_str = base64.encodestring(enctext) # Now over to the client side resp = self.client.parse_authn_request_response( resp_str, BINDING_HTTP_POST, {"_012345": "http://foo.example.com/service"}) #assert resp.encrypted_assertion == [] assert resp.assertion assert resp.ava == {'givenName': ['Derek'], 'sn': ['Jeter']}
def test_enc2(): crypto = CryptoBackendXmlSec1(xmlsec_path) server = Server("idp_conf") name_id = server.ident.transient_nameid("urn:mace:example.com:saml:roland:sp", "id12") resp_ = server.create_authn_response( IDENTITY, "id12", "http://lingon.catalogix.se:8087/", "urn:mace:example.com:saml:roland:sp", name_id=name_id ) enc_resp = crypto.encrypt_assertion(resp_, full_path("pubkey.pem"), pre_encryption_part()) print enc_resp assert enc_resp
def test_pre_enc_key_format(): def the_xsd_ID_value_must_start_with_either_a_letter_or_underscore(id): result = re.match(r"^[a-zA-Z_]", id[0]) return result def the_xsd_ID_value_may_contain_only_letters_digits_underscores_hyphens_periods( id): result = re.match(r"^[a-zA-Z0-9._-]*$", id[1:]) return result tmpl = pre_encryption_part() for id in (tmpl.id, tmpl.key_info.encrypted_key.id): assert the_xsd_ID_value_must_start_with_either_a_letter_or_underscore( id) assert the_xsd_ID_value_may_contain_only_letters_digits_underscores_hyphens_periods( id)
def test_enc2(): crypto = CryptoBackendXmlSec1(xmlsec_path) with closing(Server("idp_conf")) as server: name_id = server.ident.transient_nameid( "urn:mace:example.com:saml:roland:sp", "id12") resp_ = server.create_authn_response( IDENTITY, "id12", "http://lingon.catalogix.se:8087/", "urn:mace:example.com:saml:roland:sp", name_id=name_id) enc_resp = crypto.encrypt_assertion(resp_, full_path("pubkey.pem"), pre_encryption_part()) assert enc_resp
def test_sign_then_encrypt_assertion(self): # Begin with the IdPs side _sec = self.server.sec assertion = s_utils.assertion_factory( subject=factory(saml.Subject, text="_aaa", name_id=factory( saml.NameID, format=saml.NAMEID_FORMAT_TRANSIENT)), attribute_statement=do_attribute_statement({ ("", "", "surName"): ("Jeter", ""), ("", "", "givenName"): ("Derek", ""), }), issuer=self.server._issuer(), ) assertion.signature = sigver.pre_signature_part( assertion.id, _sec.my_cert, 1) sigass = _sec.sign_statement(assertion, class_name(assertion), key_file=full_path("test.key"), node_id=assertion.id) # Create an Assertion instance from the signed assertion _ass = saml.assertion_from_string(sigass) response = sigver.response_factory( in_response_to="_012345", destination="https:#www.example.com", status=s_utils.success_status_factory(), issuer=self.server._issuer(), assertion=_ass) enctext = _sec.crypto.encrypt_assertion(response, _sec.cert_file, pre_encryption_part()) seresp = samlp.response_from_string(enctext) # Now over to the client side _csec = self.client.sec if seresp.encrypted_assertion: decr_text = _csec.decrypt(enctext) seresp = samlp.response_from_string(decr_text) resp_ass = [] sign_cert_file = full_path("test.pem") for enc_ass in seresp.encrypted_assertion: assers = extension_elements_to_elements( enc_ass.extension_elements, [saml, samlp]) for ass in assers: if ass.signature: if not _csec.verify_signature( "%s" % ass, sign_cert_file, node_name=class_name(ass)): continue resp_ass.append(ass) seresp.assertion = resp_ass seresp.encrypted_assertion = None #print _sresp assert seresp.assertion
def test_sign_then_encrypt_assertion(self): # Begin with the IdPs side _sec = self.server.sec assertion = s_utils.assertion_factory( subject=factory(saml.Subject, text="_aaa", name_id=factory( saml.NameID, format=saml.NAMEID_FORMAT_TRANSIENT)), attribute_statement=do_attribute_statement( { ("", "", "surName"): ("Jeter", ""), ("", "", "givenName"): ("Derek", ""), } ), issuer=self.server._issuer(), ) assertion.signature = sigver.pre_signature_part( assertion.id, _sec.my_cert, 1) sigass = _sec.sign_statement(assertion, class_name(assertion), key_file="pki/mykey.pem", node_id=assertion.id) # Create an Assertion instance from the signed assertion _ass = saml.assertion_from_string(sigass) response = sigver.response_factory( in_response_to="_012345", destination="https:#www.example.com", status=s_utils.success_status_factory(), issuer=self.server._issuer(), assertion=_ass ) enctext = _sec.crypto.encrypt_assertion(response, _sec.cert_file, pre_encryption_part()) seresp = samlp.response_from_string(enctext) # Now over to the client side _csec = self.client.sec if seresp.encrypted_assertion: decr_text = _csec.decrypt(enctext) seresp = samlp.response_from_string(decr_text) resp_ass = [] sign_cert_file = "pki/mycert.pem" for enc_ass in seresp.encrypted_assertion: assers = extension_elements_to_elements( enc_ass.extension_elements, [saml, samlp]) for ass in assers: if ass.signature: if not _csec.verify_signature("%s" % ass, sign_cert_file, node_name=class_name(ass)): continue resp_ass.append(ass) seresp.assertion = resp_ass seresp.encrypted_assertion = None #print _sresp assert seresp.assertion
def _response(self, in_response_to, consumer_url=None, status=None, issuer=None, sign=False, to_sign=None, encrypt_assertion=False, encrypt_assertion_self_contained=False, encrypted_advice_attributes=False, encrypt_cert=None, **kwargs): """ Create a Response. Encryption: encrypt_assertion must be true for encryption to be performed. If encrypted_advice_attributes also is true, then will the function try to encrypt the assertion in the the advice element of the main assertion. Only one assertion element is allowed in the advice element, if multiple assertions exists in the advice element the main assertion will be encrypted instead, since it's no point to encrypt If encrypted_advice_attributes is false the main assertion will be encrypted. Since the same key :param in_response_to: The session identifier of the request :param consumer_url: The URL which should receive the response :param status: The status of the response :param issuer: The issuer of the response :param sign: Whether the response should be signed or not :param to_sign: If there are other parts to sign :param kwargs: Extra key word arguments :return: A Response instance """ if not status: status = success_status_factory() _issuer = self._issuer(issuer) response = response_factory(issuer=_issuer, in_response_to=in_response_to, status=status) if consumer_url: response.destination = consumer_url self._add_info(response, **kwargs) if not sign and to_sign and not encrypt_assertion: return signed_instance_factory(response, self.sec, to_sign) if encrypt_assertion: node_xpath = None if sign: response.signature = pre_signature_part(response.id, self.sec.my_cert, 1) sign_class = [(class_name(response), response.id)] cbxs = CryptoBackendXmlSec1(self.config.xmlsec_binary) if encrypted_advice_attributes and response.assertion.advice is not None \ and len(response.assertion.advice.assertion) == 1: tmp_assertion = response.assertion.advice.assertion[0] response.assertion.advice.encrypted_assertion = [] response.assertion.advice.encrypted_assertion.append(EncryptedAssertion()) if isinstance(tmp_assertion, list): response.assertion.advice.encrypted_assertion[0].add_extension_elements(tmp_assertion) else: response.assertion.advice.encrypted_assertion[0].add_extension_element(tmp_assertion) response.assertion.advice.assertion = [] if encrypt_assertion_self_contained: advice_tag = response.assertion.advice._to_element_tree().tag assertion_tag = tmp_assertion._to_element_tree().tag response = response.get_xml_string_with_self_contained_assertion_within_advice_encrypted_assertion( assertion_tag, advice_tag) node_xpath = ''.join(["/*[local-name()=\"%s\"]" % v for v in ["Response", "Assertion", "Advice", "EncryptedAssertion", "Assertion"]]) elif encrypt_assertion_self_contained: assertion_tag = response.assertion._to_element_tree().tag response = pre_encrypt_assertion(response) response = response.get_xml_string_with_self_contained_assertion_within_encrypted_assertion( assertion_tag) else: response = pre_encrypt_assertion(response) if to_sign: response = signed_instance_factory(response, self.sec, to_sign) _, cert_file = make_temp("%s" % encrypt_cert, decode=False) response = cbxs.encrypt_assertion(response, cert_file, pre_encryption_part(), node_xpath=node_xpath) # template(response.assertion.id)) if sign: return signed_instance_factory(response, self.sec, sign_class) else: return response if sign: return self.sign(response, to_sign=to_sign) else: return response
def test_sign_then_encrypt_assertion_advice(self): # Begin with the IdPs side _sec = self.server.sec nameid_policy = samlp.NameIDPolicy( allow_create="false", format=saml.NAMEID_FORMAT_PERSISTENT) asser = Assertion({"givenName": "Derek", "surName": "Jeter"}) assertion = asser.construct( self.client.config.entityid, "_012345", "http://lingon.catalogix.se:8087/", factory(saml.NameID, format=saml.NAMEID_FORMAT_TRANSIENT), policy=self.server.config.getattr("policy", "idp"), issuer=self.server._issuer(), attrconvs=self.server.config.attribute_converters, authn_class=INTERNETPROTOCOLPASSWORD, authn_auth="http://www.example.com/login") a_asser = Assertion({ "uid": "test01", "email": "*****@*****.**" }) a_assertion = a_asser.construct( self.client.config.entityid, "_012345", "http://lingon.catalogix.se:8087/", factory(saml.NameID, format=saml.NAMEID_FORMAT_TRANSIENT), policy=self.server.config.getattr("policy", "idp"), issuer=self.server._issuer(), attrconvs=self.server.config.attribute_converters, authn_class=INTERNETPROTOCOLPASSWORD, authn_auth="http://www.example.com/login") a_assertion.signature = sigver.pre_signature_part( a_assertion.id, _sec.my_cert, 1) assertion.advice = Advice() assertion.advice.encrypted_assertion = [] assertion.advice.encrypted_assertion.append(EncryptedAssertion()) assertion.advice.encrypted_assertion[0].add_extension_element( a_assertion) response = sigver.response_factory( in_response_to="_012345", destination="http://lingon.catalogix.se:8087/", status=s_utils.success_status_factory(), issuer=self.server._issuer()) response.assertion.append(assertion) response = _sec.sign_statement("%s" % response, class_name(a_assertion), key_file=self.client.sec.key_file, node_id=a_assertion.id) #xmldoc = "%s" % response # strangely enough I get different tags if I run this test separately # or as part of a bunch of tests. #xmldoc = add_subelement(xmldoc, "EncryptedAssertion", sigass) node_xpath = ''.join([ "/*[local-name()=\"%s\"]" % v for v in [ "Response", "Assertion", "Advice", "EncryptedAssertion", "Assertion" ] ]) enctext = _sec.crypto.encrypt_assertion(response, _sec.cert_file, pre_encryption_part(), node_xpath=node_xpath) #seresp = samlp.response_from_string(enctext) resp_str = base64.encodestring(enctext) # Now over to the client side resp = self.client.parse_authn_request_response( resp_str, BINDING_HTTP_POST, {"_012345": "http://foo.example.com/service"}) #assert resp.encrypted_assertion == [] assert resp.assertion assert resp.assertion.advice assert resp.assertion.advice.assertion assert resp.ava == \ {'sn': ['Jeter'], 'givenName': ['Derek'], 'uid': ['test01'], 'email': ['*****@*****.**']}
def test_pre_enc(): tmpl = pre_encryption_part() print tmpl assert "%s" % tmpl == TMPL
def test_pre_enc_with_pregenerated_key(): tmpl = pre_encryption_part(encrypted_key_id="EK", encrypted_data_id="ED") expected = TMPL_NO_HEADER.format(ed_id=tmpl.id, ek_id=tmpl.key_info.encrypted_key.id, key_info='') assert str(tmpl) == expected
def _response(self, in_response_to, consumer_url=None, status=None, issuer=None, sign=False, to_sign=None, encrypt_assertion=False, encrypt_assertion_self_contained=False, encrypted_advice_attributes=False, encrypt_cert=None, **kwargs): """ Create a Response. Encryption: encrypt_assertion must be true for encryption to be performed. If encrypted_advice_attributes also is true, then will the function try to encrypt the assertion in the the advice element of the main assertion. Only one assertion element is allowed in the advice element, if multiple assertions exists in the advice element the main assertion will be encrypted instead, since it's no point to encrypt If encrypted_advice_attributes is false the main assertion will be encrypted. Since the same key :param in_response_to: The session identifier of the request :param consumer_url: The URL which should receive the response :param status: The status of the response :param issuer: The issuer of the response :param sign: Whether the response should be signed or not :param to_sign: If there are other parts to sign :param kwargs: Extra key word arguments :return: A Response instance """ if not status: status = success_status_factory() _issuer = self._issuer(issuer) response = response_factory(issuer=_issuer, in_response_to=in_response_to, status=status) if consumer_url: response.destination = consumer_url self._add_info(response, **kwargs) if not sign and to_sign and not encrypt_assertion: return signed_instance_factory(response, self.sec, to_sign) if encrypt_assertion: node_xpath = None if sign: response.signature = pre_signature_part( response.id, self.sec.my_cert, 1) sign_class = [(class_name(response), response.id)] cbxs = CryptoBackendXmlSec1(self.config.xmlsec_binary) if encrypted_advice_attributes and response.assertion.advice is not None \ and len(response.assertion.advice.assertion) == 1: tmp_assertion = response.assertion.advice.assertion[0] response.assertion.advice.encrypted_assertion = [] response.assertion.advice.encrypted_assertion.append( EncryptedAssertion()) if isinstance(tmp_assertion, list): response.assertion.advice.encrypted_assertion[ 0].add_extension_elements(tmp_assertion) else: response.assertion.advice.encrypted_assertion[ 0].add_extension_element(tmp_assertion) response.assertion.advice.assertion = [] if encrypt_assertion_self_contained: advice_tag = response.assertion.advice._to_element_tree( ).tag assertion_tag = tmp_assertion._to_element_tree().tag response = response.get_xml_string_with_self_contained_assertion_within_advice_encrypted_assertion( assertion_tag, advice_tag) node_xpath = ''.join([ "/*[local-name()=\"%s\"]" % v for v in [ "Response", "Assertion", "Advice", "EncryptedAssertion", "Assertion" ] ]) elif encrypt_assertion_self_contained: assertion_tag = response.assertion._to_element_tree().tag response = pre_encrypt_assertion(response) response = response.get_xml_string_with_self_contained_assertion_within_encrypted_assertion( assertion_tag) else: response = pre_encrypt_assertion(response) if to_sign: response = signed_instance_factory(response, self.sec, to_sign) _, cert_file = make_temp("%s" % encrypt_cert, decode=False) response = cbxs.encrypt_assertion(response, cert_file, pre_encryption_part(), node_xpath=node_xpath) # template(response.assertion.id)) if sign: return signed_instance_factory(response, self.sec, sign_class) else: return response if sign: return self.sign(response, to_sign=to_sign) else: return response
def test_pre_enc(): tmpl = pre_encryption_part(encrypted_key_id="EK", encrypted_data_id="ED") print(tmpl) assert "%s" % tmpl in (TMPL_NO_HEADER, TMPL)
def test_sign_then_encrypt_assertion_advice(self): # Begin with the IdPs side _sec = self.server.sec nameid_policy = samlp.NameIDPolicy(allow_create="false", format=saml.NAMEID_FORMAT_PERSISTENT) asser = Assertion({"givenName": "Derek", "surName": "Jeter"}) assertion = asser.construct( self.client.config.entityid, "_012345", "http://lingon.catalogix.se:8087/", factory(saml.NameID, format=saml.NAMEID_FORMAT_TRANSIENT), policy=self.server.config.getattr("policy", "idp"), issuer=self.server._issuer(), attrconvs=self.server.config.attribute_converters, authn_class=INTERNETPROTOCOLPASSWORD, authn_auth="http://www.example.com/login") a_asser = Assertion({"uid": "test01", "email": "*****@*****.**"}) a_assertion = a_asser.construct( self.client.config.entityid, "_012345", "http://lingon.catalogix.se:8087/", factory(saml.NameID, format=saml.NAMEID_FORMAT_TRANSIENT), policy=self.server.config.getattr("policy", "idp"), issuer=self.server._issuer(), attrconvs=self.server.config.attribute_converters, authn_class=INTERNETPROTOCOLPASSWORD, authn_auth="http://www.example.com/login") a_assertion.signature = sigver.pre_signature_part( a_assertion.id, _sec.my_cert, 1) assertion.advice = Advice() assertion.advice.encrypted_assertion = [] assertion.advice.encrypted_assertion.append(EncryptedAssertion()) assertion.advice.encrypted_assertion[0].add_extension_element(a_assertion) response = sigver.response_factory( in_response_to="_012345", destination="http://lingon.catalogix.se:8087/", status=s_utils.success_status_factory(), issuer=self.server._issuer() ) response.assertion.append(assertion) response = _sec.sign_statement("%s" % response, class_name(a_assertion), key_file=self.client.sec.key_file, node_id=a_assertion.id) #xmldoc = "%s" % response # strangely enough I get different tags if I run this test separately # or as part of a bunch of tests. #xmldoc = add_subelement(xmldoc, "EncryptedAssertion", sigass) node_xpath = ''.join(["/*[local-name()=\"%s\"]" % v for v in ["Response", "Assertion", "Advice", "EncryptedAssertion", "Assertion"]]) enctext = _sec.crypto.encrypt_assertion(response, _sec.cert_file, pre_encryption_part(), node_xpath=node_xpath) #seresp = samlp.response_from_string(enctext) resp_str = base64.encodestring(enctext) # Now over to the client side resp = self.client.parse_authn_request_response( resp_str, BINDING_HTTP_POST, {"_012345": "http://foo.example.com/service"}) #assert resp.encrypted_assertion == [] assert resp.assertion assert resp.assertion.advice assert resp.assertion.advice.assertion assert resp.ava == \ {'sn': ['Jeter'], 'givenName': ['Derek'], 'uid': ['test01'], 'email': ['*****@*****.**']}
def test_pre_enc(): tmpl = pre_encryption_part() print(tmpl) assert "%s" % tmpl in (TMPL_NO_HEADER, TMPL)