def test_sign_verify_with_cert_from_instance(self): response = factory(samlp.Response, assertion=self._assertion, id="22222", signature=sigver.pre_signature_part("22222", self.sec .my_cert)) to_sign = [(class_name(self._assertion), self._assertion.id), (class_name(response), response.id)] s_response = sigver.signed_instance_factory(response, self.sec, to_sign) response2 = response_from_string(s_response) ci = "".join(sigver.cert_from_instance(response2)[0].split()) assert ci == self.sec.my_cert res = self.sec.verify_signature(s_response, node_name=class_name(samlp.Response())) assert res res = self.sec._check_signature(s_response, response2, class_name(response2), s_response) assert res == response2
def test_create_class_from_xml_string_nameid(): kl = create_class_from_xml_string(NameID, ITEMS[NameID][0]) assert kl != None assert kl.format == "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" assert kl.sp_provided_id == "sp provided id" assert kl.text.strip() == "*****@*****.**" assert _eq(kl.keyswv(), ['sp_provided_id', 'format', 'text']) assert class_name(kl) == "urn:oasis:names:tc:SAML:2.0:assertion:NameID" assert _eq(kl.keys(), ['sp_provided_id', 'sp_name_qualifier', 'name_qualifier', 'format', 'text']) kl = create_class_from_xml_string(NameID, ITEMS[NameID][1]) assert kl != None assert kl.format == "urn:oasis:names:tc:SAML:2.0:nameid-format:transient" assert kl.sp_name_qualifier == "https://foo.example.com/sp" assert kl.text.strip() == "_1632879f09d08ea5ede2dc667cbed7e429ebc4335c" assert _eq(kl.keyswv(), ['sp_name_qualifier', 'format', 'text']) assert class_name(kl) == "urn:oasis:names:tc:SAML:2.0:assertion:NameID" kl = create_class_from_xml_string(NameID, ITEMS[NameID][2]) assert kl != None assert kl.format == "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" assert kl.name_qualifier == "http://authentic.example.com/saml/metadata" assert kl.sp_name_qualifier == "http://auth.example.com/saml/metadata" assert kl.text.strip() == "test" assert _eq(kl.keyswv(), ['sp_name_qualifier', 'format', 'name_qualifier', 'text']) assert class_name(kl) == "urn:oasis:names:tc:SAML:2.0:assertion:NameID"
def test_exception_sign_verify_with_cert_from_instance(self): assertion = factory(saml.Assertion, version="2.0", id="11100", issue_instant="2009-10-30T13:20:28Z", #signature= sigver.pre_signature_part("11100", # self.sec.my_cert), attribute_statement=do_attribute_statement({ ("", "", "surName"): ("Föö", ""), ("", "", "givenName"): ("Bär", ""), }) ) response = factory(samlp.Response, assertion=assertion, id="22222", signature=sigver.pre_signature_part("22222", self.sec .my_cert)) to_sign = [(class_name(response), response.id)] s_response = sigver.signed_instance_factory(response, self.sec, to_sign) response2 = response_from_string(s_response) # Change something that should make everything fail response2.id = "23456" raises(sigver.SignatureError, self.sec._check_signature, s_response, response2, class_name(response2))
def test_create_class_from_xml_string_nameid(): kl = create_class_from_xml_string(NameID, ITEMS[NameID][0]) assert kl != None assert kl.format == "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" assert kl.sp_provided_id == "sp provided id" assert kl.text.strip() == "*****@*****.**" assert _eq(kl.keyswv(), ['sp_provided_id', 'format', 'text']) assert class_name(kl) == "urn:oasis:names:tc:SAML:2.0:assertion:NameID" assert _eq(kl.keys(), [ 'sp_provided_id', 'sp_name_qualifier', 'name_qualifier', 'format', 'text' ]) kl = create_class_from_xml_string(NameID, ITEMS[NameID][1]) assert kl != None assert kl.format == "urn:oasis:names:tc:SAML:2.0:nameid-format:transient" assert kl.sp_name_qualifier == "https://foo.example.com/sp" assert kl.text.strip() == "_1632879f09d08ea5ede2dc667cbed7e429ebc4335c" assert _eq(kl.keyswv(), ['sp_name_qualifier', 'format', 'text']) assert class_name(kl) == "urn:oasis:names:tc:SAML:2.0:assertion:NameID" kl = create_class_from_xml_string(NameID, ITEMS[NameID][2]) assert kl != None assert kl.format == "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" assert kl.name_qualifier == "http://authentic.example.com/saml/metadata" assert kl.sp_name_qualifier == "http://auth.example.com/saml/metadata" assert kl.text.strip() == "test" assert _eq(kl.keyswv(), ['sp_name_qualifier', 'format', 'name_qualifier', 'text']) assert class_name(kl) == "urn:oasis:names:tc:SAML:2.0:assertion:NameID"
def test_sign_response(self): response = factory(samlp.Response, assertion=self._assertion, id="22222", signature=sigver.pre_signature_part("22222", self.sec .my_cert)) to_sign = [(class_name(self._assertion), self._assertion.id), (class_name(response), response.id)] s_response = sigver.signed_instance_factory(response, self.sec, to_sign) assert s_response is not None print(s_response) response = response_from_string(s_response) sass = response.assertion[0] print(sass) assert _eq(sass.keyswv(), ['attribute_statement', 'issue_instant', 'version', 'signature', 'id']) assert sass.version == "2.0" assert sass.id == "11111" item = self.sec.check_signature(response, class_name(response), s_response) assert isinstance(item, samlp.Response) assert item.id == "22222"
def test_sign_verify_assertion_with_cert_from_instance(self): assertion = factory(saml.Assertion, version="2.0", id="11100", issue_instant="2009-10-30T13:20:28Z", signature=sigver.pre_signature_part("11100", self.sec .my_cert), attribute_statement=do_attribute_statement({ ("", "", "surName"): ("Räv", ""), ("", "", "givenName"): ("Björn", ""), }) ) to_sign = [(class_name(assertion), assertion.id)] s_assertion = sigver.signed_instance_factory(assertion, self.sec, to_sign) print(s_assertion) ass = assertion_from_string(s_assertion) ci = "".join(sigver.cert_from_instance(ass)[0].split()) assert ci == self.sec.my_cert res = self.sec.verify_signature(s_assertion, node_name=class_name(ass)) assert res res = self.sec._check_signature(s_assertion, ass, class_name(ass)) assert res
def test_xbox_non_ascii_ava(): 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"): ("Föö", ""), ("", "", "givenName"): ("Bär", ""), }) ) 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 use_soap(self, request, destination="", soap_headers=None, sign=False, **kwargs): """ Construct the necessary information for using SOAP+POST :param request: :param destination: :param soap_headers: :param sign: :return: dictionary """ headers = [("content-type", "application/soap+xml")] soap_message = make_soap_enveloped_saml_thingy(request, soap_headers) logger.debug("SOAP message: %s", soap_message) if sign and self.sec: _signed = self.sec.sign_statement(soap_message, class_name=class_name(request), node_id=request.id) soap_message = _signed return {"url": destination, "method": "POST", "data": soap_message, "headers": headers}
def test_SAML_sign_with_pkcs11(self): """ Test signing a SAML assertion using PKCS#11 and then verifying it. """ os.environ['SOFTHSM_CONF'] = self.softhsm_conf ass = self._assertion print(ass) sign_ass = self.sec.sign_assertion("%s" % ass, node_id=ass.id) #print(sign_ass) sass = saml.assertion_from_string(sign_ass) #print(sass) assert _eq(sass.keyswv(), ['attribute_statement', 'issue_instant', 'version', 'signature', 'id']) assert sass.version == "2.0" assert sass.id == "11111" assert time_util.str_to_time(sass.issue_instant) print("Crypto version : %s" % (self.sec.crypto.version())) item = self.sec.check_signature(sass, class_name(sass), sign_ass) assert isinstance(item, saml.Assertion) print("Test PASSED")
def test_SAML_sign_with_pkcs11(self): """ Test signing a SAML assertion using PKCS#11 and then verifying it. """ os.environ['SOFTHSM_CONF'] = self.softhsm_conf ass = self._assertion print(ass) sign_ass = self.sec.sign_assertion("%s" % ass, node_id=ass.id) #print(sign_ass) sass = saml.assertion_from_string(sign_ass) #print(sass) assert _eq(sass.keyswv(), [ 'attribute_statement', 'issue_instant', 'version', 'signature', 'id' ]) assert sass.version == "2.0" assert sass.id == "11111" assert time_util.str_to_time(sass.issue_instant) print("Crypto version : %s" % (self.sec.crypto.version())) item = self.sec.check_signature(sass, class_name(sass), sign_ass) assert isinstance(item, saml.Assertion) print("Test PASSED")
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) if name: entities.name = name if ident: entities.id = ident if sign: if not ident: ident = sid() if not secc.key_file: raise SAMLError("If you want to do signing you should define " + "a key to sign with") if not secc.my_cert: 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, digest_alg=digest_alg) entities.id = ident xmldoc = secc.sign_statement("%s" % entities, class_name(entities)) entities = md.entities_descriptor_from_string(xmldoc) else: xmldoc = None return entities, xmldoc
def test_xmlsec_err_non_ascii_ava(): 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"): ("Föö", ""), ("", "", "givenName"): ("Bär", ""), }) ) try: sec.sign_statement(assertion, class_name(assertion), key_file=full_path("tes.key"), node_id=assertion.id) except (XmlsecError, SigverError) as err: # should throw an exception pass else: assert False
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 parse_authn_request_response(self, xmlstr, binding, outstanding=None, outstanding_certs=None, conv_info=None): """ Deal with an AuthnResponse :param xmlstr: The reply as a xml string :param binding: Which binding that was used for the transport :param outstanding: A dictionary with session IDs as keys and the original web request from the user before redirection as values. :param outstanding_certs: :param conv_info: Information about the conversation. :return: An response.AuthnResponse or None """ if not getattr(self.config, 'entityid', None): raise SAMLError("Missing entity_id specification") if not xmlstr: return None kwargs = { "outstanding_queries": outstanding, "outstanding_certs": outstanding_certs, "allow_unsolicited": self.allow_unsolicited, "want_assertions_signed": self.want_assertions_signed, "want_assertions_or_response_signed": self.want_assertions_or_response_signed, "want_response_signed": self.want_response_signed, "return_addrs": self.service_urls(binding=binding), "entity_id": self.config.entityid, "attribute_converters": self.config.attribute_converters, "allow_unknown_attributes": self.config.allow_unknown_attributes, 'conv_info': conv_info, "valid_destination_regex": self.valid_destination_regex, } try: resp = self._parse_response(xmlstr, AuthnResponse, "assertion_consumer_service", binding, **kwargs) except StatusError as err: logger.error("SAML status error: %s", err) raise except UnravelError: return None except Exception as err: logger.error("XML parse error: %s", err) raise if not isinstance(resp, AuthnResponse): logger.error("Response type not supported: %s", saml2_tophat.class_name(resp)) return None if (resp.assertion and len(resp.response.encrypted_assertion) == 0 and resp.assertion.subject.name_id): self.users.add_information_about_person(resp.session_info()) logger.info("--- ADDED person info ----") return resp
def test_create_class_from_xml_string_subject_locality(): kl = create_class_from_xml_string(SubjectLocality, ITEMS[SubjectLocality]) assert kl != None assert _eq(kl.keyswv(), ['address', "dns_name"]) assert kl.address == "127.0.0.1" assert kl.dns_name == "localhost" assert class_name( kl) == "urn:oasis:names:tc:SAML:2.0:assertion:SubjectLocality"
def test_sign_verify(self): response = factory(samlp.Response, assertion=self._assertion, id="22233", signature=sigver.pre_signature_part("22233", self.sec .my_cert)) to_sign = [(class_name(self._assertion), self._assertion.id), (class_name(response), response.id)] s_response = sigver.signed_instance_factory(response, self.sec, to_sign) print(s_response) res = self.sec.verify_signature(s_response, node_name=class_name(samlp.Response())) print(res) assert res
def test_create_class_from_xml_string_subject_confirmation_data(): kl = create_class_from_xml_string(SubjectConfirmationData, ITEMS[SubjectConfirmationData]) assert kl != None assert _eq(kl.keyswv(), ['in_response_to', 'not_on_or_after', 'not_before', 'recipient']) assert kl.in_response_to == "_1683146e27983964fbe7bf8f08961108d166a652e5" assert kl.not_on_or_after == "2010-02-18T13:52:13.959Z" assert kl.not_before == "2010-01-16T12:00:00Z" assert kl.recipient == "http://192.168.0.10/saml/sp" assert class_name(kl) == \ "urn:oasis:names:tc:SAML:2.0:assertion:SubjectConfirmationData"
def _assertion(self, assertion, verified=False): """ Check the assertion :param assertion: :return: True/False depending on if the assertion is sane or not """ if not hasattr(assertion, 'signature') or not assertion.signature: logger.debug("unsigned") if self.require_signature: raise SignatureError("Signature missing for assertion") else: logger.debug("signed") if not verified and self.do_not_verify is False: try: self.sec.check_signature(assertion, class_name(assertion), self.xmlstr) except Exception as exc: logger.error("correctly_signed_response: %s", exc) raise self.assertion = assertion logger.debug("assertion context: %s", self.context) logger.debug("assertion keys: %s", assertion.keyswv()) logger.debug("outstanding_queries: %s", self.outstanding_queries) # if self.context == "AuthnReq" or self.context == "AttrQuery": if self.context == "AuthnReq": self.authn_statement_ok() # elif self.context == "AttrQuery": # self.authn_statement_ok(True) if not self.condition_ok(): raise VerificationError("Condition not OK") logger.debug("--- Getting Identity ---") # if self.context == "AuthnReq" or self.context == "AttrQuery": # self.ava = self.get_identity() # logger.debug("--- AVA: %s", self.ava) try: self.get_subject() if self.asynchop: if self.allow_unsolicited: pass elif self.came_from is None: raise VerificationError("Came from") return True except Exception: logger.exception("get subject") raise
def test_create_class_from_xml_string_subject_confirmation_data(): kl = create_class_from_xml_string(SubjectConfirmationData, ITEMS[SubjectConfirmationData]) assert kl != None assert _eq( kl.keyswv(), ['in_response_to', 'not_on_or_after', 'not_before', 'recipient']) assert kl.in_response_to == "_1683146e27983964fbe7bf8f08961108d166a652e5" assert kl.not_on_or_after == "2010-02-18T13:52:13.959Z" assert kl.not_before == "2010-01-16T12:00:00Z" assert kl.recipient == "http://192.168.0.10/saml/sp" assert class_name(kl) == \ "urn:oasis:names:tc:SAML:2.0:assertion:SubjectConfirmationData"
def test_sign_response_2(self): assertion2 = factory(saml.Assertion, version="2.0", id="11122", issue_instant="2009-10-30T13:20:28Z", signature=sigver.pre_signature_part("11122", self.sec .my_cert), attribute_statement=do_attribute_statement({ ("", "", "surName"): ("Räv", ""), ("", "", "givenName"): ("Björn", ""), }) ) response = factory(samlp.Response, assertion=assertion2, id="22233", signature=sigver.pre_signature_part("22233", self.sec .my_cert)) to_sign = [(class_name(assertion2), assertion2.id), (class_name(response), response.id)] s_response = sigver.signed_instance_factory(response, self.sec, to_sign) assert s_response is not None response2 = response_from_string(s_response) sass = response2.assertion[0] assert _eq(sass.keyswv(), ['attribute_statement', 'issue_instant', 'version', 'signature', 'id']) assert sass.version == "2.0" assert sass.id == "11122" item = self.sec.check_signature(response2, class_name(response), s_response) assert isinstance(item, samlp.Response)
def test_nameid_with_extension(): kl = create_class_from_xml_string(NameID, NAMEID_WITH_ATTRIBUTE_EXTENSION) assert kl != None print(kl.__dict__) assert kl.format == "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" assert kl.sp_provided_id == "sp provided id" assert kl.text.strip() == "*****@*****.**" assert _eq(kl.keyswv(), ['sp_provided_id', 'format', 'extension_attributes', 'text']) assert class_name(kl) == "urn:oasis:names:tc:SAML:2.0:assertion:NameID" assert _eq(kl.keys(), ['sp_provided_id', 'sp_name_qualifier', 'name_qualifier', 'format', 'text']) assert kl.extension_attributes == { '{urn:mace:example.com:saml:assertion}Foo': 'BAR'}
def test_multiple_signatures_response(self): response = factory(samlp.Response, assertion=self._assertion, id="22222", signature=sigver.pre_signature_part( "22222", self.sec.my_cert)) # order is important, we can't validate if the signatures are made # in the reverse order to_sign = [(self._assertion, self._assertion.id, ''), (response, response.id, '')] s_response = self.sec.multiple_signatures("%s" % response, to_sign) assert s_response is not None response = response_from_string(s_response) item = self.sec.check_signature(response, class_name(response), s_response, must=True) assert item == response assert item.id == "22222" s_assertion = item.assertion[0] assert isinstance(s_assertion, saml.Assertion) # make sure the assertion was modified when we supposedly signed it assert s_assertion != self._assertion ci = "".join(sigver.cert_from_instance(s_assertion)[0].split()) assert ci == self.sec.my_cert res = self.sec.check_signature(s_assertion, class_name(s_assertion), s_response, must=True) assert res == s_assertion assert s_assertion.id == "11111" assert s_assertion.version == "2.0" assert _eq(s_assertion.keyswv(), ['attribute_statement', 'issue_instant', 'version', 'signature', 'id'])
def test_nameid_with_extension(): kl = create_class_from_xml_string(NameID, NAMEID_WITH_ATTRIBUTE_EXTENSION) assert kl != None print(kl.__dict__) assert kl.format == "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" assert kl.sp_provided_id == "sp provided id" assert kl.text.strip() == "*****@*****.**" assert _eq(kl.keyswv(), ['sp_provided_id', 'format', 'extension_attributes', 'text']) assert class_name(kl) == "urn:oasis:names:tc:SAML:2.0:assertion:NameID" assert _eq(kl.keys(), [ 'sp_provided_id', 'sp_name_qualifier', 'name_qualifier', 'format', 'text' ]) assert kl.extension_attributes == { '{urn:mace:example.com:saml:assertion}Foo': 'BAR' }
def sign_entity_descriptor(edesc, ident, secc, sign_alg=None, digest_alg=None): """ :param edesc: EntityDescriptor instance :param ident: EntityDescriptor identifier :param secc: Security context :return: Tuple with EntityDescriptor instance and Signed XML document """ if not ident: ident = sid() 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) return edesc, xmldoc
def test_sign_assertion(self): ass = self._assertion print(ass) sign_ass = self.sec.sign_assertion("%s" % ass, node_id=ass.id) #print(sign_ass) sass = saml.assertion_from_string(sign_ass) #print(sass) assert _eq(sass.keyswv(), ['attribute_statement', 'issue_instant', 'version', 'signature', 'id']) assert sass.version == "2.0" assert sass.id == "11111" assert time_util.str_to_time(sass.issue_instant) print("Crypto version : %s" % (self.sec.crypto.version())) item = self.sec.check_signature(sass, class_name(sass), sign_ass) assert isinstance(item, saml.Assertion)
def test_multiple_signatures_assertion(self): ass = self._assertion # basic test with two of the same to_sign = [(ass, ass.id, ''), (ass, ass.id, '') ] sign_ass = self.sec.multiple_signatures("%s" % ass, to_sign) sass = saml.assertion_from_string(sign_ass) assert _eq(sass.keyswv(), ['attribute_statement', 'issue_instant', 'version', 'signature', 'id']) assert sass.version == "2.0" assert sass.id == "11111" assert time_util.str_to_time(sass.issue_instant) print("Crypto version : %s" % (self.sec.crypto.version())) item = self.sec.check_signature(sass, class_name(sass), sign_ass, must=True) assert isinstance(item, saml.Assertion)
def test_create_class_from_xml_string_subject_confirmation(): kl = create_class_from_xml_string(SubjectConfirmation, ITEMS[SubjectConfirmation]) assert kl != None assert _eq(kl.keyswv(), ['method', 'name_id', 'subject_confirmation_data']) assert kl.method == "urn:oasis:names:tc:SAML:2.0:cm:bearer" name_id = kl.name_id assert _eq(name_id.keyswv(), ['format', 'name_qualifier', 'text']) assert name_id.format == "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" assert name_id.name_qualifier == "http://authentic.example.com/saml/metadata" assert name_id.text.strip() == "*****@*****.**" subject_confirmation_data = kl.subject_confirmation_data assert _eq(subject_confirmation_data.keyswv(), ['not_on_or_after', 'recipient', 'in_response_to']) assert subject_confirmation_data.recipient == \ "http://auth.example.com/saml/proxySingleSignOnRedirect" assert subject_confirmation_data.not_on_or_after == "2010-02-17T17:02:38Z" assert subject_confirmation_data.in_response_to == \ "_59B3A01B03334032C31E434C63F89E3E" assert class_name(kl) == \ "urn:oasis:names:tc:SAML:2.0:assertion:SubjectConfirmation"
def test_sha256_signing_non_ascii_ava(): 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, sign_alg=SIG_RSA_SHA256), attribute_statement=do_attribute_statement( {("", "", "surName"): ("Föö", ""), ("", "", "givenName"): ("Bär", ""), }) ) s = sec.sign_statement(assertion, class_name(assertion), key_file=full_path("test.key"), node_id=assertion.id) assert s
def test_create_class_from_xml_string_issuer(): kl = create_class_from_xml_string(Issuer, ITEMS[Issuer]) assert kl != None assert kl.text.strip() == "http://www.example.com/test" assert _eq(kl.keyswv(), ['text']) assert class_name(kl) == "urn:oasis:names:tc:SAML:2.0:assertion:Issuer"
def _authn_response(self, in_response_to, consumer_url, sp_entity_id, identity=None, name_id=None, status=None, authn=None, issuer=None, policy=None, 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, sign_alg=None, digest_alg=None, farg=None, session_not_on_or_after=None): """ Create a response. A layer of indirection. :param in_response_to: The session identifier of the request :param consumer_url: The URL which should receive the response :param sp_entity_id: The entity identifier of the SP :param identity: A dictionary with attributes and values that are expected to be the bases for the assertion in the response. :param name_id: The identifier of the subject :param status: The status of the response :param authn: A dictionary containing information about the authn context. :param issuer: The issuer of the response :param policy: :param sign_assertion: Whether the assertion should be signed or not :param sign_response: Whether the response should be signed or not :param best_effort: Even if not the SPs demands can be met send a response. :param encrypt_assertion: True if assertions should be encrypted. :param encrypt_assertion_self_contained: True if all encrypted assertions should have alla namespaces selfcontained. :param encrypted_advice_attributes: True if assertions in the advice element should be encrypted. :param encrypt_cert_advice: Certificate to be used for encryption of assertions in the advice element. :param encrypt_cert_assertion: Certificate to be used for encryption of assertions. :param authn_statement: Authentication statement. :param sign_assertion: True if assertions should be signed. :param pefim: True if a response according to the PEFIM profile should be created. :param farg: Argument to pass on to the assertion constructor :return: A response instance """ if farg is None: assertion_args = {} args = {} # if identity: _issuer = self._issuer(issuer) # if encrypt_assertion and show_nameid: # tmp_name_id = name_id # name_id = None # name_id = None # tmp_authn = authn # authn = None # tmp_authn_statement = authn_statement # authn_statement = None if pefim: encrypted_advice_attributes = True encrypt_assertion_self_contained = True assertion_attributes = self.setup_assertion( None, sp_entity_id, None, None, None, policy, None, None, identity, best_effort, sign_response, farg=farg) assertion = self.setup_assertion( authn, sp_entity_id, in_response_to, consumer_url, name_id, policy, _issuer, authn_statement, [], True, sign_response, farg=farg, session_not_on_or_after=session_not_on_or_after) assertion.advice = saml.Advice() # assertion.advice.assertion_id_ref.append(saml.AssertionIDRef()) # assertion.advice.assertion_uri_ref.append(saml.AssertionURIRef()) assertion.advice.assertion.append(assertion_attributes) else: assertion = self.setup_assertion( authn, sp_entity_id, in_response_to, consumer_url, name_id, policy, _issuer, authn_statement, identity, True, sign_response, farg=farg, session_not_on_or_after=session_not_on_or_after) to_sign = [] if not encrypt_assertion: if sign_assertion: assertion.signature = pre_signature_part(assertion.id, self.sec.my_cert, 2, sign_alg=sign_alg, digest_alg=digest_alg) to_sign.append((class_name(assertion), assertion.id)) args["assertion"] = assertion if (self.support_AssertionIDRequest() or self.support_AuthnQuery()): 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, 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, sign_alg=sign_alg, digest_alg=digest_alg, **args)
def create_attribute_response(self, identity, in_response_to, destination, sp_entity_id, userid="", name_id=None, status=None, issuer=None, sign_assertion=False, sign_response=False, attributes=None, sign_alg=None, digest_alg=None, farg=None, **kwargs): """ Create an attribute assertion response. :param identity: A dictionary with attributes and values that are expected to be the bases for the assertion in the response. :param in_response_to: The session identifier of the request :param destination: The URL which should receive the response :param sp_entity_id: The entity identifier of the SP :param userid: A identifier of the user :param name_id: The identifier of the subject :param status: The status of the response :param issuer: The issuer of the response :param sign_assertion: Whether the assertion should be signed or not :param sign_response: Whether the whole response should be signed :param attributes: :param kwargs: To catch extra keyword arguments :return: A response instance """ policy = self.config.getattr("policy", "aa") if not name_id and userid: try: name_id = self.ident.construct_nameid(userid, policy, sp_entity_id) logger.warning("Unspecified NameID format") except Exception: pass to_sign = [] if identity: farg = self.update_farg(in_response_to, sp_entity_id, farg=farg) _issuer = self._issuer(issuer) ast = Assertion(identity) if policy: ast.apply_policy(sp_entity_id, policy, self.metadata) else: policy = Policy() if attributes: restr = restriction_from_attribute_spec(attributes) ast = filter_attribute_value_assertions(ast) assertion = ast.construct(sp_entity_id, self.config.attribute_converters, policy, issuer=_issuer, name_id=name_id, farg=farg['assertion']) if sign_assertion: assertion.signature = pre_signature_part(assertion.id, 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)] kwargs['sign_assertion'] = True kwargs["assertion"] = assertion if sp_entity_id: kwargs['sp_entity_id'] = sp_entity_id return self._response(in_response_to, destination, status, issuer, sign_response, to_sign, sign_alg=sign_alg, digest_alg=digest_alg, **kwargs)
def _authn_response(self, in_response_to, consumer_url, sp_entity_id, identity=None, name_id=None, status=None, authn=None, issuer=None, policy=None, 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, sign_alg=None, digest_alg=None, farg=None, session_not_on_or_after=None): """ Create a response. A layer of indirection. :param in_response_to: The session identifier of the request :param consumer_url: The URL which should receive the response :param sp_entity_id: The entity identifier of the SP :param identity: A dictionary with attributes and values that are expected to be the bases for the assertion in the response. :param name_id: The identifier of the subject :param status: The status of the response :param authn: A dictionary containing information about the authn context. :param issuer: The issuer of the response :param policy: :param sign_assertion: Whether the assertion should be signed or not :param sign_response: Whether the response should be signed or not :param best_effort: Even if not the SPs demands can be met send a response. :param encrypt_assertion: True if assertions should be encrypted. :param encrypt_assertion_self_contained: True if all encrypted assertions should have alla namespaces selfcontained. :param encrypted_advice_attributes: True if assertions in the advice element should be encrypted. :param encrypt_cert_advice: Certificate to be used for encryption of assertions in the advice element. :param encrypt_cert_assertion: Certificate to be used for encryption of assertions. :param authn_statement: Authentication statement. :param sign_assertion: True if assertions should be signed. :param pefim: True if a response according to the PEFIM profile should be created. :param farg: Argument to pass on to the assertion constructor :return: A response instance """ if farg is None: assertion_args = {} args = {} # if identity: _issuer = self._issuer(issuer) # if encrypt_assertion and show_nameid: # tmp_name_id = name_id # name_id = None # name_id = None # tmp_authn = authn # authn = None # tmp_authn_statement = authn_statement # authn_statement = None if pefim: encrypted_advice_attributes = True encrypt_assertion_self_contained = True assertion_attributes = self.setup_assertion(None, sp_entity_id, None, None, None, policy, None, None, identity, best_effort, sign_response, farg=farg) assertion = self.setup_assertion( authn, sp_entity_id, in_response_to, consumer_url, name_id, policy, _issuer, authn_statement, [], True, sign_response, farg=farg, session_not_on_or_after=session_not_on_or_after) assertion.advice = saml.Advice() # assertion.advice.assertion_id_ref.append(saml.AssertionIDRef()) # assertion.advice.assertion_uri_ref.append(saml.AssertionURIRef()) assertion.advice.assertion.append(assertion_attributes) else: assertion = self.setup_assertion( authn, sp_entity_id, in_response_to, consumer_url, name_id, policy, _issuer, authn_statement, identity, True, sign_response, farg=farg, session_not_on_or_after=session_not_on_or_after) to_sign = [] if not encrypt_assertion: if sign_assertion: assertion.signature = pre_signature_part(assertion.id, self.sec.my_cert, 2, sign_alg=sign_alg, digest_alg=digest_alg) to_sign.append((class_name(assertion), assertion.id)) args["assertion"] = assertion if (self.support_AssertionIDRequest() or self.support_AuthnQuery()): 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, 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, sign_alg=sign_alg, digest_alg=digest_alg, **args)
def create_attribute_response(self, identity, in_response_to, destination, sp_entity_id, userid="", name_id=None, status=None, issuer=None, sign_assertion=False, sign_response=False, attributes=None, sign_alg=None, digest_alg=None, farg=None, **kwargs): """ Create an attribute assertion response. :param identity: A dictionary with attributes and values that are expected to be the bases for the assertion in the response. :param in_response_to: The session identifier of the request :param destination: The URL which should receive the response :param sp_entity_id: The entity identifier of the SP :param userid: A identifier of the user :param name_id: The identifier of the subject :param status: The status of the response :param issuer: The issuer of the response :param sign_assertion: Whether the assertion should be signed or not :param sign_response: Whether the whole response should be signed :param attributes: :param kwargs: To catch extra keyword arguments :return: A response instance """ policy = self.config.getattr("policy", "aa") if not name_id and userid: try: name_id = self.ident.construct_nameid(userid, policy, sp_entity_id) logger.warning("Unspecified NameID format") except Exception: pass to_sign = [] if identity: farg = self.update_farg(in_response_to, sp_entity_id, farg=farg) _issuer = self._issuer(issuer) ast = Assertion(identity) if policy: ast.apply_policy(sp_entity_id, policy, self.metadata) else: policy = Policy() if attributes: restr = restriction_from_attribute_spec(attributes) ast = filter_attribute_value_assertions(ast) assertion = ast.construct( sp_entity_id, self.config.attribute_converters, policy, issuer=_issuer, name_id=name_id, farg=farg['assertion']) if sign_assertion: assertion.signature = pre_signature_part(assertion.id, 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)] kwargs['sign_assertion'] = True kwargs["assertion"] = assertion if sp_entity_id: kwargs['sp_entity_id'] = sp_entity_id return self._response(in_response_to, destination, status, issuer, sign_response, to_sign, sign_alg=sign_alg, digest_alg=digest_alg, **kwargs)