def test_encrypted_signed_response_4(self): cert_str, cert_key_str = generate_cert() 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, encrypt_assertion=True, encrypt_assertion_self_contained=True, pefim=True, encrypt_cert_advice=cert_str, ) sresponse = response_from_string(signed_resp) 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 decr_text = self.server.sec.decrypt(signed_resp, self.client.config.encryption_keypairs[1]["key_file"]) resp = samlp.response_from_string(decr_text) resp.assertion = extension_elements_to_elements(resp.encrypted_assertion[0].extension_elements, [saml, samlp]) valid = self.server.sec.verify_signature(decr_text, self.server.config.cert_file, node_name='urn:oasis:names:tc:SAML:2.0:assertion:Assertion', node_id=resp.assertion[0].id, id_attr="") assert valid _, key_file = make_temp(cert_key_str, decode=False) decr_text = self.server.sec.decrypt(decr_text, key_file) resp = samlp.response_from_string(decr_text) assertion = extension_elements_to_elements(resp.encrypted_assertion[0].extension_elements, [saml, samlp]) assertion = \ extension_elements_to_elements(assertion[0].advice.encrypted_assertion[0].extension_elements,[saml, samlp]) self.verify_assertion(assertion) #PEFIM never signs assertion in advice assert assertion[0].signature is None #valid = self.server.sec.verify_signature(decr_text, # self.server.config.cert_file, # node_name='urn:oasis:names:tc:SAML:2.0:assertion:Assertion', # node_id=assertion[0].id, # id_attr="") assert valid
def test_encrypted_response_7(self): _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=False, sign_assertion=False, encrypt_assertion=True, encrypt_assertion_self_contained=True, pefim=True ) sresponse = response_from_string(_resp) assert sresponse.signature is None decr_text_1 = self.server.sec.decrypt(_resp, self.client.config.encryption_keypairs[1]["key_file"]) decr_text_2 = self.server.sec.decrypt(decr_text_1, self.client.config.encryption_keypairs[1]["key_file"]) resp = samlp.response_from_string(decr_text_2) resp.assertion = extension_elements_to_elements(resp.encrypted_assertion[0].extension_elements, [saml, samlp]) self.verify_advice_assertion(resp, decr_text_2)
def test_encrypted_response_3(self): cert_str_assertion, cert_key_str_assertion = generate_cert() _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=False, sign_assertion=False, encrypt_assertion=True, encrypt_assertion_self_contained=True, encrypted_advice_attributes=False, encrypt_cert_assertion=cert_str_assertion ) sresponse = response_from_string(_resp) assert sresponse.signature is None _, key_file = make_temp(cert_key_str_assertion, decode=False) decr_text = self.server.sec.decrypt(_resp, key_file) resp = samlp.response_from_string(decr_text) assert resp.encrypted_assertion[0].extension_elements assertion = extension_elements_to_elements(resp.encrypted_assertion[0].extension_elements, [saml, samlp]) self.verify_encrypted_assertion(assertion, decr_text)
def test_encrypted_signed_response_2(self): cert_str, cert_key_str = generate_cert() 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=False, encrypt_assertion=True, encrypt_assertion_self_contained=True, ) sresponse = response_from_string(signed_resp) 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 decr_text = self.server.sec.decrypt(signed_resp, self.client.config.key_file) resp = samlp.response_from_string(decr_text) resp.assertion = extension_elements_to_elements(resp.encrypted_assertion[0].extension_elements, [saml, samlp]) assert resp.assertion[0].signature == None self.verify_assertion(resp.assertion)
def ava_from(self, attribute): try: attr = self._fro[attribute.name.strip()] except (AttributeError, KeyError): try: attr = attribute.friendly_name.strip() except AttributeError: attr = attribute.name.strip() val = [] for value in attribute.attribute_value: if value.extension_elements: ext = extension_elements_to_elements(value.extension_elements, [saml]) for ex in ext: if isinstance(ex, NameID): cval = '' for key, (name, type, mul) in ex.c_attributes.items(): exv = getattr(ex, name) if exv and name in ['text', 'value']: cval = exv if ex.text and not cval: cval = ex.text.strip() val.append(cval) elif not value.text: val.append('') else: val.append(value.text.strip()) return attr, val
def ava_from(self, attribute): try: attr = self._fro[attribute.name.strip().lower()] except (AttributeError, KeyError): try: attr = attribute.friendly_name.strip().lower() except AttributeError: attr = attribute.name.strip().lower() val = [] for value in attribute.attribute_value: if value.extension_elements: ext = extension_elements_to_elements(value.extension_elements, [saml]) for ex in ext: cval = {} for key, (name, typ, mul) in ex.c_attributes.items(): exv = getattr(ex, name) if exv: cval[name] = exv if ex.text: cval["value"] = ex.text.strip() val.append({ex.c_tag: cval}) elif not value.text: val.append('') else: val.append(value.text.strip()) return attr, val
def authn_context_decl_from_extension_elements(extelems): res = extension_elements_to_elements(extelems, [ippword, mobiletwofactor, ppt, pword, sslcert]) try: return res[0] except IndexError: return None
def decrypt_assertions(self, encrypted_assertions, decr_txt, issuer=None, verified=False): """ Moves the decrypted assertion from the encrypted assertion to a list. :param encrypted_assertions: A list of encrypted assertions. :param decr_txt: The string representation containing the decrypted data. Used when verifying signatures. :param issuer: The issuer of the response. :param verified: If True do not verify signatures, otherwise verify the signature if it exists. :return: A list of decrypted assertions. """ res = [] for encrypted_assertion in encrypted_assertions: if encrypted_assertion.extension_elements: assertions = extension_elements_to_elements(encrypted_assertion.extension_elements, [saml, samlp]) for assertion in assertions: if assertion.signature and not verified: if not self.sec.check_signature( assertion, origdoc=decr_txt, node_name=class_name(assertion), issuer=issuer ): logger.error("Failed to verify signature on '%s'", assertion) raise SignatureError() res.append(assertion) return res
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 to_dict(_dict, onts): """ Convert a pysaml2 SAML2 metadata format into a basic dictionary format The export interface. :param _dict: The pysaml2 metadata instance :param onts: Schemas to use for the conversion :return: The converted information """ res = {} if isinstance(_dict, SamlBase): res["__class__"] = "%s&%s" % (_dict.c_namespace,_dict.c_tag) for key in _dict.keyswv(): if key in IMP_SKIP: continue val = getattr(_dict, key) if key == "extension_elements": _eel = extension_elements_to_elements(val, onts) _val = [_eval(_v, onts) for _v in _eel] else: _val = _eval(val, onts) if _val: res[key] = _val else: for key, val in _dict.items(): _val = _eval(val, onts) if _val: res[key] = _val return res
def verify_advice_assertion(self, resp, decr_text): assert resp.assertion[0].signature is None assert resp.assertion[0].advice.encrypted_assertion[0].extension_elements assertion = extension_elements_to_elements(resp.assertion[0].advice.encrypted_assertion[0].extension_elements, [saml, samlp]) self.verify_encrypted_assertion(assertion, decr_text)
def test_encrypted_signed_response_2(self): name_id = self.server.ident.transient_nameid( "urn:mace:example.com:saml:roland:sp", "id12") ava = {"givenName": ["Derek"], "surName": ["Jeter"], "mail": ["*****@*****.**"], "title": "The man"} cert_str, cert_key_str = generate_cert() 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_response=True, sign_assertion=True, encrypt_assertion=True, encrypt_assertion_self_contained=True, encrypt_cert=cert_str, ) sresponse = response_from_string(signed_resp) 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 _, key_file = make_temp("%s" % cert_key_str, decode=False) decr_text = self.server.sec.decrypt(signed_resp, key_file) resp = samlp.response_from_string(decr_text) assert resp.encrypted_assertion[0].extension_elements assertion = extension_elements_to_elements(resp.encrypted_assertion[0].extension_elements, [saml, samlp]) assert assertion assert assertion[0].attribute_statement ava = get_ava(assertion[0]) assert ava ==\ {'mail': ['*****@*****.**'], 'givenname': ['Derek'], 'surname': ['Jeter'], 'title': ['The man']} assert 'EncryptedAssertion><encas2:Assertion xmlns:encas0="http://www.w3.org/2000/09/xmldsig#" ' \ 'xmlns:encas1="http://www.w3.org/2001/XMLSchema-instance" ' \ 'xmlns:encas2="urn:oasis:names:tc:SAML:2.0:assertion"' in decr_text valid = self.server.sec.verify_signature(decr_text, self.server.config.cert_file, node_name='urn:oasis:names:tc:SAML:2.0:assertion:Assertion', node_id=assertion[0].id, id_attr="") assert valid
def _holder_of_key_confirmed(self, data): if not data: return False has_keyinfo = False for element in extension_elements_to_elements(data, [samlp, saml, xenc, ds]): if isinstance(element, ds.KeyInfo): has_keyinfo = True return has_keyinfo
def parse_artifact_resolve_response(self, xmlstr): kwargs = {"entity_id": self.config.entityid, "attribute_converters": self.config.attribute_converters} resp = self._parse_response(xmlstr, response.ArtifactResponse, "artifact_resolve", BINDING_SOAP, **kwargs) # should just be one elems = extension_elements_to_elements(resp.response.extension_elements, [samlp, saml]) return elems[0]
def parse_artifact_resolve_response(self, xmlstr): kwargs = {"entity_id": self.config.entityid, "attribute_converters": self.config.attribute_converters} resp = self._parse_response(xmlstr, saml_response.ArtifactResponse, "artifact_resolve", BINDING_SOAP, **kwargs) # should just be one elems = extension_elements_to_elements(resp.response.extension_elements, [samlp, saml]) return elems[0]
def to_dict(_dict, onts, mdb_safe=False): """ Convert a pysaml2 SAML2 message class instance into a basic dictionary format. The export interface. :param _dict: The pysaml2 metadata instance :param onts: List of schemas to use for the conversion :return: The converted information """ res = {} if isinstance(_dict, SamlBase): res["__class__"] = "%s&%s" % (_dict.c_namespace, _dict.c_tag) for key in _dict.keyswv(): if key in IMP_SKIP: continue val = getattr(_dict, key) if key == "extension_elements": _eel = extension_elements_to_elements( val, onts, keep_unmatched=True ) _val = [_eval(_v, onts, mdb_safe) for _v in _eel] elif key == "extension_attributes": if mdb_safe: _val = dict([(k.replace(".", "__"), v) for k, v in val.items()]) #_val = {k.replace(".", "__"): v for k, v in val.items()} else: _val = val else: _val = _eval(val, onts, mdb_safe) if _val: if mdb_safe: key = key.replace(".", "__") res[key] = _val elif isinstance(_dict, ExtensionElement): res = { key: _val for key, val in _dict.__dict__.items() if val and key not in IMP_SKIP for _val in [_eval(val, onts, mdb_safe)] if _val } res["__class__"] = "%s&%s" % (_dict.namespace, _dict.tag) else: for key, val in _dict.items(): _val = _eval(val, onts, mdb_safe) if _val: if mdb_safe and "." in key: key = key.replace(".", "__") res[key] = _val return res
def decrypt_assertions(self, encrypted_assertions, key_file=""): res = [] for encrypted_assertion in encrypted_assertions: if encrypted_assertion.extension_elements: assertions = extension_elements_to_elements(encrypted_assertion.extension_elements, [saml, samlp]) for assertion in assertions: if assertion.signature: if not self.sec.verify_signature("%s" % assertion, key_file, node_name=class_name(assertion)): logger.error("Failed to verify signature on '%s'" % assertion) raise SignatureError() res.append(assertion) return res
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_encrypted_response_2(self): name_id = self.server.ident.transient_nameid( "urn:mace:example.com:saml:roland:sp", "id12") ava = { "givenName": ["Derek"], "surName": ["Jeter"], "mail": ["*****@*****.**"], "title": "The man" } cert_str, cert_key_str = generate_cert() 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_response=False, sign_assertion=False, encrypt_assertion=True, encrypt_assertion_self_contained=True, encrypted_advice_attributes=False, encrypt_cert=cert_str, ) sresponse = response_from_string(signed_resp) assert sresponse.signature is None _, key_file = make_temp("%s" % cert_key_str, decode=False) decr_text = self.server.sec.decrypt(signed_resp, key_file) resp = samlp.response_from_string(decr_text) assert resp.encrypted_assertion[0].extension_elements assertion = extension_elements_to_elements( resp.encrypted_assertion[0].extension_elements, [saml, samlp]) assert assertion assert assertion[0].attribute_statement ava = ava = get_ava(assertion[0]) assert ava ==\ {'mail': ['*****@*****.**'], 'givenname': ['Derek'], 'surname': ['Jeter'], 'title': ['The man']} assert 'EncryptedAssertion><encas1:Assertion xmlns:encas0="http://www.w3.org/2001/XMLSchema-instance" ' \ 'xmlns:encas1="urn:oasis:names:tc:SAML:2.0:assertion"' in decr_text assert assertion[0].signature is None
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_do_idp_sso_descriptor(): conf = IdPConfig().load(IDP) idpsso = metadata.do_idpsso_descriptor(conf) assert isinstance(idpsso, md.IDPSSODescriptor) assert _eq(idpsso.keyswv(), [ 'protocol_support_enumeration', 'single_sign_on_service', 'want_authn_requests_signed', "extensions" ]) exts = idpsso.extensions.extension_elements assert len(exts) == 2 print(exts) inst = saml2.extension_element_to_element(exts[0], shibmd.ELEMENT_FROM_STRING, namespace=shibmd.NAMESPACE) assert isinstance(inst, shibmd.Scope) assert inst.text == "example.org" assert inst.regexp == "false" uiinfo = saml2.extension_element_to_element(exts[1], mdui.ELEMENT_FROM_STRING, namespace=mdui.NAMESPACE) assert uiinfo assert _eq(uiinfo.keyswv(), [ 'display_name', 'description', 'information_url', 'privacy_statement_url', 'keywords', 'logo' ]) assert len(uiinfo.privacy_statement_url) == 1 assert uiinfo.privacy_statement_url[ 0].text == "http://example.com/saml2/privacyStatement.html" assert len(uiinfo.description) == 1 assert uiinfo.description[0].text == "Exempel bolag" assert uiinfo.description[0].lang == "se" res = extension_elements_to_elements(exts, [shibmd, mdui]) assert len(res) == 2 # one is a shibmd.Scope instance and the other a mdui.UIInfo instance if isinstance(res[0], shibmd.Scope): assert isinstance(res[1], mdui.UIInfo) elif isinstance(res[1], shibmd.Scope): assert isinstance(res[0], mdui.UIInfo) found = idpsso.extensions.find_extensions(mdui.UIInfo.c_tag, mdui.NAMESPACE) assert len(found) == 1 elem = idpsso.extensions.extensions_as_elements(mdui.UIInfo.c_tag, mdui) assert len(elem) == 1 assert isinstance(elem[0], mdui.UIInfo)
def test_do_idp_sso_descriptor(): conf = IdPConfig().load(IDP, metadata_construction=True) idpsso = metadata.do_idpsso_descriptor(conf) assert isinstance(idpsso, md.IDPSSODescriptor) assert _eq(idpsso.keyswv(), ['protocol_support_enumeration', 'single_sign_on_service', 'want_authn_requests_signed', "extensions"]) exts = idpsso.extensions.extension_elements assert len(exts) == 2 print exts inst = saml2.extension_element_to_element(exts[0], shibmd.ELEMENT_FROM_STRING, namespace=shibmd.NAMESPACE) assert isinstance(inst, shibmd.Scope) assert inst.text == "example.org" assert inst.regexp == "false" uiinfo = saml2.extension_element_to_element(exts[1], mdui.ELEMENT_FROM_STRING, namespace=mdui.NAMESPACE) assert uiinfo assert _eq(uiinfo.keyswv(), ['display_name', 'description', 'information_url', 'privacy_statement_url', 'keywords', 'logo']) assert len(uiinfo.privacy_statement_url) == 1 assert uiinfo.privacy_statement_url[0].text == "http://example.com/saml2/privacyStatement.html" assert len(uiinfo.description) == 1 assert uiinfo.description[0].text == "Exempel bolag" assert uiinfo.description[0].lang == "se" res = extension_elements_to_elements(exts,[shibmd, mdui]) assert len(res) == 2 # one is a shibmd.Scope instance and the other a mdui.UIInfo instance if isinstance(res[0], shibmd.Scope): assert isinstance(res[1], mdui.UIInfo) elif isinstance(res[1], shibmd.Scope): assert isinstance(res[0], mdui.UIInfo) found = idpsso.extensions.find_extensions(mdui.UIInfo.c_tag, mdui.NAMESPACE) assert len(found) == 1 elem = idpsso.extensions.extensions_as_elements(mdui.UIInfo.c_tag, mdui) assert len(elem) == 1 assert isinstance(elem[0], mdui.UIInfo)
def test_encrypted_signed_response_3(self): cert_str, cert_key_str = generate_cert() 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, encrypt_assertion=True, encrypt_assertion_self_contained=False, encrypt_cert_assertion=cert_str, ) sresponse = response_from_string(signed_resp) 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 _, key_file = make_temp(str(cert_key_str).encode('ascii'), decode=False) decr_text = self.server.sec.decrypt(signed_resp, key_file) resp = samlp.response_from_string(decr_text) resp.assertion = extension_elements_to_elements( resp.encrypted_assertion[0].extension_elements, [saml, samlp]) valid = self.server.sec.verify_signature( decr_text, self.server.config.cert_file, node_name='urn:oasis:names:tc:SAML:2.0:assertion:Assertion', node_id=resp.assertion[0].id, id_attr="") assert valid self.verify_assertion(resp.assertion) assert 'xmlns:encas' not in decr_text
def decrypt_assertions(self, encrypted_assertions, decr_txt): res = [] for encrypted_assertion in encrypted_assertions: if encrypted_assertion.extension_elements: assertions = extension_elements_to_elements( encrypted_assertion.extension_elements, [saml, samlp]) for assertion in assertions: if assertion.signature: if not self.sec.check_signature( assertion, origdoc=decr_txt, node_name=class_name(assertion)): logger.error( "Failed to verify signature on '%s'" % assertion) raise SignatureError() res.append(assertion) return res
def test_encrypted_signed_response_2(self): cert_str, cert_key_str = generate_cert() 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=False, encrypt_assertion=True, encrypt_assertion_self_contained=True, ) sresponse = response_from_string(signed_resp) 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 decr_text_old = copy.deepcopy("%s" % signed_resp) decr_text = self.server.sec.decrypt( signed_resp, self.client.config.encryption_keypairs[0]["key_file"]) assert decr_text == decr_text_old decr_text = self.server.sec.decrypt( signed_resp, self.client.config.encryption_keypairs[1]["key_file"]) assert decr_text != decr_text_old resp = samlp.response_from_string(decr_text) resp.assertion = extension_elements_to_elements( resp.encrypted_assertion[0].extension_elements, [saml, samlp]) assert resp.assertion[0].signature == None self.verify_assertion(resp.assertion)
def test_encrypted_signed_response_3(self): cert_str, cert_key_str = generate_cert() 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, encrypt_assertion=True, encrypt_assertion_self_contained=False, encrypt_cert_assertion=cert_str, ) sresponse = response_from_string(signed_resp) 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 _, key_file = make_temp(str(cert_key_str).encode('ascii'), decode=False) decr_text = self.server.sec.decrypt(signed_resp, key_file) resp = samlp.response_from_string(decr_text) resp.assertion = extension_elements_to_elements(resp.encrypted_assertion[0].extension_elements, [saml, samlp]) valid = self.server.sec.verify_signature(decr_text, self.server.config.cert_file, node_name='urn:oasis:names:tc:SAML:2.0:assertion:Assertion', node_id=resp.assertion[0].id, id_attr="") assert valid self.verify_assertion(resp.assertion) assert 'xmlns:encas' not in decr_text
def to_dict(_dict, onts, mdb_safe=False): """ Convert a pysaml2 SAML2 message class instance into a basic dictionary format. The export interface. :param _dict: The pysaml2 metadata instance :param onts: List of schemas to use for the conversion :return: The converted information """ res = {} if isinstance(_dict, SamlBase): res["__class__"] = "%s&%s" % (_dict.c_namespace, _dict.c_tag) for key in _dict.keyswv(): if key in IMP_SKIP: continue val = getattr(_dict, key) if key == "extension_elements": _eel = extension_elements_to_elements(val, onts) _val = [_eval(_v, onts, mdb_safe) for _v in _eel] elif key == "extension_attributes": if mdb_safe: _val = dict([(k.replace(".", "__"), v) for k, v in val.items()]) #_val = {k.replace(".", "__"): v for k, v in val.items()} else: _val = val else: _val = _eval(val, onts, mdb_safe) if _val: if mdb_safe: key = key.replace(".", "__") res[key] = _val else: for key, val in _dict.items(): _val = _eval(val, onts, mdb_safe) if _val: if mdb_safe and "." in key: key = key.replace(".", "__") res[key] = _val return res
def decrypt_assertions(self, encrypted_assertions, decr_txt, issuer=None, verified=False): """ Moves the decrypted assertion from the encrypted assertion to a list. :param encrypted_assertions: A list of encrypted assertions. :param decr_txt: The string representation containing the decrypted data. Used when verifying signatures. :param issuer: The issuer of the response. :param verified: If True do not verify signatures, otherwise verify the signature if it exists. :return: A list of decrypted assertions. """ res = [] for encrypted_assertion in encrypted_assertions: if encrypted_assertion.extension_elements: assertions = extension_elements_to_elements( encrypted_assertion.extension_elements, [saml, samlp]) for assertion in assertions: if assertion.signature and not verified: assertion_id_pos = decr_txt.index(assertion.id) assertion_beg_tag = decr_txt.rindex( '<', 0, assertion_id_pos) closing_assertion_pos = decr_txt.index( 'Assertion', assertion_id_pos) assertion_end_tag = decr_txt.index( '>', closing_assertion_pos) + 1 origdoc = decr_txt[assertion_beg_tag:assertion_end_tag] if not self.sec.check_signature( assertion, origdoc=origdoc, node_name=class_name(assertion), issuer=issuer): logger.error("Failed to verify signature on '%s'" % assertion) raise SignatureError() res.append(assertion) return res
def test_okta(): conf = config.Config() conf.load_file("server_conf") conf.id_attr_name = 'Id' 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) with open(OKTA_RESPONSE) as f: enctext = f.read() decr_text = sec.decrypt(enctext) _seass = saml.encrypted_assertion_from_string(decr_text) assers = extension_elements_to_elements(_seass.extension_elements, [saml, samlp]) with open(OKTA_ASSERTION) as f: okta_assertion = f.read() expected_assert = assertion_from_string(okta_assertion) assert len(assers) == 1 assert assers[0] == expected_assert
def test_encrypted_response_6(self): _server = Server("idp_conf_verify_cert") cert_str_advice, cert_key_str_advice = generate_cert() cert_str_assertion, cert_key_str_assertion = generate_cert() _resp = _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=False, sign_assertion=False, encrypt_assertion=True, encrypt_assertion_self_contained=True, pefim=True, encrypt_cert_advice=cert_str_advice, encrypt_cert_assertion=cert_str_assertion) sresponse = response_from_string(_resp) assert sresponse.signature is None _, key_file = make_temp(cert_key_str_assertion, decode=False) decr_text_1 = _server.sec.decrypt(_resp, key_file) _, key_file = make_temp(cert_key_str_advice, decode=False) decr_text_2 = _server.sec.decrypt(decr_text_1, key_file) resp = samlp.response_from_string(decr_text_2) resp.assertion = extension_elements_to_elements( resp.encrypted_assertion[0].extension_elements, [saml, samlp]) self.verify_advice_assertion(resp, decr_text_2)
def ava_from(self, attribute, allow_unknown=False): try: attr = self._fro[attribute.name.strip().lower()] except AttributeError: attr = attribute.friendly_name.strip().lower() except KeyError: if allow_unknown: try: attr = attribute.name.strip().lower() except AttributeError: attr = attribute.friendly_name.strip().lower() else: raise val = [] for value in attribute.attribute_value: if value.extension_elements: ext = extension_elements_to_elements(value.extension_elements, [saml]) for ex in ext: if attr == "eduPersonTargetedID" and ex.text: val.append(ex.text.strip()) else: cval = {} for key, (name, typ, mul) in ex.c_attributes.items(): exv = getattr(ex, name) if exv: cval[name] = exv if ex.text: cval["value"] = ex.text.strip() val.append({ex.c_tag: cval}) elif not value.text: val.append('') else: val.append(value.text.strip()) return attr, val
def _parse_response(self, xmlstr, response_cls, service, binding, outstanding_certs=None, **kwargs): """ Deal with a Response :param xmlstr: The response as a xml string :param response_cls: What type of response it is :param binding: What type of binding this message came through. :param kwargs: Extra key word arguments :return: None if the reply doesn't contain a valid SAML Response, otherwise the response. """ response = None if self.config.accepted_time_diff: kwargs["timeslack"] = self.config.accepted_time_diff if "asynchop" not in kwargs: if binding in [BINDING_SOAP, BINDING_PAOS]: kwargs["asynchop"] = False else: kwargs["asynchop"] = True if xmlstr: if "return_addrs" not in kwargs: if binding in [BINDING_HTTP_REDIRECT, BINDING_HTTP_POST]: try: # expected return address kwargs["return_addrs"] = self.config.endpoint( service, binding=binding) except Exception: logger.info("Not supposed to handle this!") return None try: response = response_cls(self.sec, **kwargs) except Exception as exc: logger.info("%s" % exc) raise xmlstr = self.unravel(xmlstr, binding, response_cls.msgtype) origxml = xmlstr if outstanding_certs is not None: _response = samlp.any_response_from_string(xmlstr) if len(_response.encrypted_assertion) > 0: _, cert_file = make_temp( "%s" % outstanding_certs[_response.in_response_to]["key"], decode=False) cbxs = CryptoBackendXmlSec1(self.config.xmlsec_binary) xmlstr = cbxs.decrypt(xmlstr, cert_file) if not xmlstr: # Not a valid reponse return None try: response = response.loads(xmlstr, False, origxml=origxml) except SigverError as err: logger.error("Signature Error: %s" % err) raise except UnsolicitedResponse: logger.error("Unsolicited response") raise except Exception as err: if "not well-formed" in "%s" % err: logger.error("Not well-formed XML") raise logger.debug("XMLSTR: %s" % xmlstr) if hasattr(response.response, 'encrypted_assertion'): for encrypted_assertion in response.response\ .encrypted_assertion: if encrypted_assertion.extension_elements is not None: assertion_list = extension_elements_to_elements( encrypted_assertion.extension_elements, [saml]) for assertion in assertion_list: _assertion = saml.assertion_from_string( str(assertion)) response.response.assertion.append(_assertion) if response: response = response.verify() if not response: return None #logger.debug(response) return response
def test_encrypted_signed_response_4(self): cert_str, cert_key_str = generate_cert() 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, encrypt_assertion=True, encrypt_assertion_self_contained=True, pefim=True, encrypt_cert_advice=cert_str, ) sresponse = response_from_string(signed_resp) 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 decr_text = self.server.sec.decrypt( signed_resp, self.client.config.encryption_keypairs[1]["key_file"]) resp = samlp.response_from_string(decr_text) resp.assertion = extension_elements_to_elements( resp.encrypted_assertion[0].extension_elements, [saml, samlp]) valid = self.server.sec.verify_signature( decr_text, self.server.config.cert_file, node_name='urn:oasis:names:tc:SAML:2.0:assertion:Assertion', node_id=resp.assertion[0].id, id_attr="") assert valid _, key_file = make_temp(cert_key_str, decode=False) decr_text = self.server.sec.decrypt(decr_text, key_file) resp = samlp.response_from_string(decr_text) assertion = extension_elements_to_elements( resp.encrypted_assertion[0].extension_elements, [saml, samlp]) assertion = \ extension_elements_to_elements(assertion[0].advice.encrypted_assertion[0].extension_elements,[saml, samlp]) self.verify_assertion(assertion) #PEFIM never signs assertion in advice assert assertion[0].signature is None #valid = self.server.sec.verify_signature(decr_text, # self.server.config.cert_file, # node_name='urn:oasis:names:tc:SAML:2.0:assertion:Assertion', # node_id=assertion[0].id, # id_attr="") assert valid
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 test_encrypted_signed_response_4(self): name_id = self.server.ident.transient_nameid( "urn:mace:example.com:saml:roland:sp", "id12") ava = { "givenName": ["Derek"], "surName": ["Jeter"], "mail": ["*****@*****.**"], "title": "The man" } cert_str, cert_key_str = generate_cert() 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_response=True, sign_assertion=True, encrypt_assertion=True, encrypted_advice_attributes=True, encrypt_cert=cert_str, ) sresponse = response_from_string(signed_resp) 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 _, key_file = make_temp("%s" % cert_key_str, decode=False) decr_text = self.server.sec.decrypt(signed_resp, key_file) resp = samlp.response_from_string(decr_text) valid = self.server.sec.verify_signature( decr_text, self.server.config.cert_file, node_name='urn:oasis:names:tc:SAML:2.0:assertion:Assertion', node_id=resp.assertion[0].id, id_attr="") assert valid assert resp.assertion[0].advice.encrypted_assertion[ 0].extension_elements assertion = extension_elements_to_elements( resp.assertion[0].advice.encrypted_assertion[0].extension_elements, [saml, samlp]) assert assertion assert assertion[0].attribute_statement ava = ava = get_ava(assertion[0]) assert ava ==\ {'mail': ['*****@*****.**'], 'givenname': ['Derek'], 'surname': ['Jeter'], 'title': ['The man']} #Should work, but I suspect that xmlsec manipulates the xml to much while encrypting that the signature #is no longer working. :( assert 'xmlns:encas' not in decr_text valid = self.server.sec.verify_signature( decr_text, self.server.config.cert_file, node_name='urn:oasis:names:tc:SAML:2.0:assertion:Assertion', node_id=assertion[0].id, id_attr="") assert valid
logger.error("Signature Error: %s" % err) raise except UnsolicitedResponse: logger.error("Unsolicited response") raise except Exception, err: if "not well-formed" in "%s" % err: logger.error("Not well-formed XML") raise logger.debug("XMLSTR: %s" % xmlstr) if hasattr(response.response, 'encrypted_assertion'): for encrypted_assertion in response.response.encrypted_assertion: if encrypted_assertion.extension_elements is not None: assertion_list = extension_elements_to_elements(encrypted_assertion.extension_elements, [saml]) for assertion in assertion_list: _assertion = saml.assertion_from_string(str(assertion)) response.response.assertion.append(_assertion) if response: response = response.verify() if not response: return None #logger.debug(response) return response # ------------------------------------------------------------------------
def _parse_response(self, xmlstr, response_cls, service, binding, outstanding_certs=None, **kwargs): """ Deal with a Response :param xmlstr: The response as a xml string :param response_cls: What type of response it is :param binding: What type of binding this message came through. :param kwargs: Extra key word arguments :return: None if the reply doesn't contain a valid SAML Response, otherwise the response. """ response = None if self.config.accepted_time_diff: kwargs["timeslack"] = self.config.accepted_time_diff if "asynchop" not in kwargs: if binding in [BINDING_SOAP, BINDING_PAOS]: kwargs["asynchop"] = False else: kwargs["asynchop"] = True if xmlstr: if "return_addrs" not in kwargs: if binding in [BINDING_HTTP_REDIRECT, BINDING_HTTP_POST]: try: # expected return address kwargs["return_addrs"] = self.config.endpoint( service, binding=binding) except Exception: logger.info("Not supposed to handle this!") return None try: response = response_cls(self.sec, **kwargs) except Exception as exc: logger.info("%s" % exc) raise xmlstr = self.unravel(xmlstr, binding, response_cls.msgtype) origxml = xmlstr if outstanding_certs is not None: _response = samlp.any_response_from_string(xmlstr) if len(_response.encrypted_assertion) > 0: _, cert_file = make_temp( "%s" % outstanding_certs[_response.in_response_to][ "key"], decode=False) cbxs = CryptoBackendXmlSec1(self.config.xmlsec_binary) xmlstr = cbxs.decrypt(xmlstr, cert_file) if not xmlstr: # Not a valid reponse return None try: response = response.loads(xmlstr, False, origxml=origxml) except SigverError as err: logger.error("Signature Error: %s" % err) raise except UnsolicitedResponse: logger.error("Unsolicited response") raise except Exception as err: if "not well-formed" in "%s" % err: logger.error("Not well-formed XML") raise logger.debug("XMLSTR: %s" % xmlstr) if hasattr(response.response, 'encrypted_assertion'): for encrypted_assertion in response.response\ .encrypted_assertion: if encrypted_assertion.extension_elements is not None: assertion_list = extension_elements_to_elements( encrypted_assertion.extension_elements, [saml]) for assertion in assertion_list: _assertion = saml.assertion_from_string( str(assertion)) response.response.assertion.append(_assertion) if response: response = response.verify() if not response: return None #logger.debug(response) return response
cert = read_cert_from_file(full_path("test.pem"), "pem") spcertenc = SPCertEnc(x509_data=ds.X509Data( x509_certificate=ds.X509Certificate(text=cert))) extensions = Extensions( extension_elements=[element_to_extension_element(spcertenc)]) req_id, req = client.create_authn_request( "http://www.example.com/sso", "urn:mace:example.com:it:tek", nameid_format=saml.NAMEID_FORMAT_PERSISTENT, message_id="666", extensions=extensions) print req # Get a certificate from an authn request xml = "%s" % req parsed = authn_request_from_string(xml) _elem = extension_elements_to_elements(parsed.extensions.extension_elements, [pefim, ds]) assert len(_elem) == 1 _spcertenc = _elem[0] _cert = _spcertenc.x509_data[0].x509_certificate.text assert cert == _cert
def test_encrypted_signed_response_4(self): name_id = self.server.ident.transient_nameid( "urn:mace:example.com:saml:roland:sp", "id12") ava = {"givenName": ["Derek"], "surName": ["Jeter"], "mail": ["*****@*****.**"], "title": "The man"} cert_str, cert_key_str = generate_cert() 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_response=True, sign_assertion=True, encrypt_assertion=True, encrypted_advice_attributes=True, encrypt_cert=cert_str, ) sresponse = response_from_string(signed_resp) 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 _, key_file = make_temp("%s" % cert_key_str, decode=False) decr_text = self.server.sec.decrypt(signed_resp, key_file) resp = samlp.response_from_string(decr_text) valid = self.server.sec.verify_signature(decr_text, self.server.config.cert_file, node_name='urn:oasis:names:tc:SAML:2.0:assertion:Assertion', node_id=resp.assertion[0].id, id_attr="") assert valid assert resp.assertion[0].advice.encrypted_assertion[0].extension_elements assertion = extension_elements_to_elements(resp.assertion[0].advice.encrypted_assertion[0].extension_elements, [saml, samlp]) assert assertion assert assertion[0].attribute_statement ava = ava = get_ava(assertion[0]) assert ava ==\ {'mail': ['*****@*****.**'], 'givenname': ['Derek'], 'surname': ['Jeter'], 'title': ['The man']} #Should work, but I suspect that xmlsec manipulates the xml to much while encrypting that the signature #is no longer working. :( assert 'xmlns:encas' not in decr_text valid = self.server.sec.verify_signature(decr_text, self.server.config.cert_file, node_name='urn:oasis:names:tc:SAML:2.0:assertion:Assertion', node_id=assertion[0].id, id_attr="") assert valid
def ava_from(self, attribute, allow_unknown=False): try: attr = self._fro[attribute.name.strip().lower()] except AttributeError: attr = attribute.friendly_name.strip().lower() except KeyError: if allow_unknown: try: attr = attribute.name.strip().lower() except AttributeError: attr = attribute.friendly_name.strip().lower() else: raise val = [] for value in attribute.attribute_value: if value.extension_elements: ext = extension_elements_to_elements(value.extension_elements, [saml]) for ex in ext: if attr == "eduPersonTargetedID" and ex.text: val.append(ex.text.strip()) else: cval = {} for key, (name, typ, mul) in ex.c_attributes.items(): exv = getattr(ex, name) if exv: cval[name] = exv if ex.text: cval["value"] = ex.text.strip() val.append({ex.c_tag: cval}) elif not value.text: val.append('') else: cur_val = value.text.strip() if XSI_TYPE in value.extension_attributes: cur_type = value.extension_attributes[XSI_TYPE] cur_type_prefix = None if cur_type.find(":") > 0: cur_type_prefix = cur_type[0:cur_type.find(":")] if ("xmlns:" + cur_type_prefix) in value.extension_attributes: cur_type = "{" + value.extension_attributes[ "xmlns:" + cur_type_prefix] + "}" + cur_type[ (len(cur_type_prefix) + 1):] if cur_type == "{http://www.w3.org/2001/XMLSchema}boolean": cur_val = (True if cur_val == "true" else False) elif cur_type in [ "{http://www.w3.org/2001/XMLSchema}decimal", "{http://www.w3.org/2001/XMLSchema}float", "{http://www.w3.org/2001/XMLSchema}double", "{http://www.w3.org/2001/XMLSchema}float" ]: cur_val = float(cur_val) elif cur_type in [ "{http://www.w3.org/2001/XMLSchema}integer", "{http://www.w3.org/2001/XMLSchema}nonPositiveInteger", "{http://www.w3.org/2001/XMLSchema}negativeInteger", "{http://www.w3.org/2001/XMLSchema}int", "{http://www.w3.org/2001/XMLSchema}short", "{http://www.w3.org/2001/XMLSchema}byte", "{http://www.w3.org/2001/XMLSchema}nonNegativeInteger", "{http://www.w3.org/2001/XMLSchema}unsignedInt", "{http://www.w3.org/2001/XMLSchema}unsignedShort", "{http://www.w3.org/2001/XMLSchema}unsignedByte", "{http://www.w3.org/2001/XMLSchema}positiveInteger" ]: cur_val = int(cur_val) elif cur_type in [ "{http://www.w3.org/2001/XMLSchema}long", "{http://www.w3.org/2001/XMLSchema}unsignedLong" ]: cur_val = long(cur_val) val.append(cur_val) return attr, val
spcertenc = SPCertEnc( x509_data=ds.X509Data( x509_certificate=ds.X509Certificate(text=cert))) extensions = Extensions( extension_elements=[element_to_extension_element(spcertenc)]) req_id, req = client.create_authn_request( "http://www.example.com/sso", "urn:mace:example.com:it:tek", nameid_format=saml.NAMEID_FORMAT_PERSISTENT, message_id="666", extensions=extensions) print req # Get a certificate from an authn request xml = "%s" % req parsed = authn_request_from_string(xml) _elem = extension_elements_to_elements(parsed.extensions.extension_elements, [pefim, ds]) assert len(_elem) == 1 _spcertenc = _elem[0] _cert = _spcertenc.x509_data[0].x509_certificate.text assert cert == _cert
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