def testToElement(self): """ Tests the to_etree method of the OneLogin_Saml2_XML """ xml = '<test>test1</test>' elem = etree.fromstring(xml) xml_expected = etree.tostring(elem) res = OneLogin_Saml2_XML.to_etree(xml) self.assertIsInstance(res, etree._Element) self.assertEqual(xml_expected, etree.tostring(res)) res = OneLogin_Saml2_XML.to_etree(xml.encode('utf8')) self.assertIsInstance(res, etree._Element) self.assertEqual(xml_expected, etree.tostring(res)) self.assertIsInstance(res, etree._Element) self.assertEqual(xml_expected, etree.tostring(res)) res = OneLogin_Saml2_XML.to_etree(elem) self.assertIs(res, elem) with self.assertRaises(ValueError) as context: OneLogin_Saml2_XML.to_etree(1) exception = context.exception self.assertIn("unsupported type", str(exception))
def testValidateXML(self): """ Tests the validate_xml method of the OneLogin_Saml2_XML """ metadata_unloaded = '<xml><EntityDescriptor>' res = OneLogin_Saml2_XML.validate_xml(metadata_unloaded, 'saml-schema-metadata-2.0.xsd') self.assertIsInstance(res, str) self.assertIn('unloaded_xml', res) metadata_invalid = self.file_contents( join(self.data_path, 'metadata', 'noentity_metadata_settings1.xml')) res = OneLogin_Saml2_XML.validate_xml(metadata_invalid, 'saml-schema-metadata-2.0.xsd') self.assertIsInstance(res, str) self.assertIn('invalid_xml', res) metadata_expired = self.file_contents( join(self.data_path, 'metadata', 'expired_metadata_settings1.xml')) res = OneLogin_Saml2_XML.validate_xml(metadata_expired, 'saml-schema-metadata-2.0.xsd') self.assertIsInstance(res, OneLogin_Saml2_XML._element_class) metadata_ok = self.file_contents( join(self.data_path, 'metadata', 'metadata_settings1.xml')) res = OneLogin_Saml2_XML.validate_xml(metadata_ok, 'saml-schema-metadata-2.0.xsd') self.assertIsInstance(res, OneLogin_Saml2_XML._element_class)
def testToElement(self): """ Tests the to_etree method of the OneLogin_Saml2_XML """ xml = '<test>test1</test>' elem = etree.fromstring(xml) xml_expected = etree.tostring(elem) res = OneLogin_Saml2_XML.to_etree(xml) self.assertIsInstance(res, etree._Element) self.assertEqual(xml_expected, etree.tostring(res)) res = OneLogin_Saml2_XML.to_etree(xml.encode('utf8')) self.assertIsInstance(res, etree._Element) self.assertEqual(xml_expected, etree.tostring(res)) self.assertIsInstance(res, etree._Element) self.assertEqual(xml_expected, etree.tostring(res)) res = OneLogin_Saml2_XML.to_etree(elem) self.assertIs(res, elem) self.assertRaisesRegexp(ValueError, 'unsupported type', OneLogin_Saml2_XML.to_etree, 1)
def test_start_authentication(self, _, service_provider, identity_providers): configuration = create_autospec(spec=SAMLConfiguration) configuration.service_provider_debug_mode = MagicMock( return_value=False) configuration.service_provider_strict_mode = MagicMock( return_value=False) configuration.get_service_provider = MagicMock( return_value=service_provider) configuration.get_identity_providers = MagicMock( return_value=identity_providers) onelogin_configuration = SAMLOneLoginConfiguration(configuration) subject_parser = SAMLSubjectParser() parser = DSLParser() visitor = DSLEvaluationVisitor() evaluator = DSLEvaluator(parser, visitor) subject_filter = SAMLSubjectFilter(evaluator) authentication_manager = SAMLAuthenticationManager( onelogin_configuration, subject_parser, subject_filter) with self.app.test_request_context("/"): result = authentication_manager.start_authentication( self._db, fixtures.IDP_1_ENTITY_ID, "") query_items = parse_qs(urlsplit(result).query) saml_request = query_items["SAMLRequest"][0] decoded_saml_request = OneLogin_Saml2_Utils.decode_base64_and_inflate( saml_request) validation_result = OneLogin_Saml2_XML.validate_xml( decoded_saml_request, "saml-schema-protocol-2.0.xsd", False) assert isinstance(validation_result, OneLogin_Saml2_XML._element_class) saml_request_dom = fromstring(decoded_saml_request) acs_url = saml_request_dom.get("AssertionConsumerServiceURL") assert acs_url == SERVICE_PROVIDER_WITH_UNSIGNED_REQUESTS.acs_service.url acs_binding = saml_request_dom.get("ProtocolBinding") assert (acs_binding == SERVICE_PROVIDER_WITH_UNSIGNED_REQUESTS. acs_service.binding.value) sso_url = saml_request_dom.get("Destination") assert sso_url == IDENTITY_PROVIDERS[0].sso_service.url name_id_policy_nodes = OneLogin_Saml2_XML.query( saml_request_dom, "./samlp:NameIDPolicy") assert name_id_policy_nodes is not None assert len(name_id_policy_nodes) == 1 name_id_policy_node = name_id_policy_nodes[0] name_id_format = name_id_policy_node.get("Format") assert (name_id_format == SERVICE_PROVIDER_WITH_UNSIGNED_REQUESTS.name_id_format)
def testQuery(self): """ Tests the query method of the OneLogin_Saml2_Utils """ xml = self.file_contents( join(self.data_path, 'responses', 'valid_response.xml.base64')) xml = b64decode(xml) dom = etree.fromstring(xml) assertion_nodes = OneLogin_Saml2_XML.query( dom, '/samlp:Response/saml:Assertion') self.assertEqual(1, len(assertion_nodes)) assertion = assertion_nodes[0] self.assertIn('Assertion', assertion.tag) attribute_statement_nodes = OneLogin_Saml2_XML.query( dom, '/samlp:Response/saml:Assertion/saml:AttributeStatement') self.assertEqual(1, len(assertion_nodes)) attribute_statement = attribute_statement_nodes[0] self.assertIn('AttributeStatement', attribute_statement.tag) attribute_statement_nodes_2 = OneLogin_Saml2_XML.query( dom, './saml:AttributeStatement', assertion) self.assertEqual(1, len(attribute_statement_nodes_2)) attribute_statement_2 = attribute_statement_nodes_2[0] self.assertEqual(attribute_statement, attribute_statement_2) signature_res_nodes = OneLogin_Saml2_XML.query( dom, '/samlp:Response/ds:Signature') self.assertEqual(1, len(signature_res_nodes)) signature_res = signature_res_nodes[0] self.assertIn('Signature', signature_res.tag) signature_nodes = OneLogin_Saml2_XML.query( dom, '/samlp:Response/saml:Assertion/ds:Signature') self.assertEqual(1, len(signature_nodes)) signature = signature_nodes[0] self.assertIn('Signature', signature.tag) signature_nodes_2 = OneLogin_Saml2_XML.query(dom, './ds:Signature', assertion) self.assertEqual(1, len(signature_nodes_2)) signature2 = signature_nodes_2[0] self.assertNotEqual(signature_res, signature2) self.assertEqual(signature, signature2) signature_nodes_3 = OneLogin_Saml2_XML.query(dom, './ds:SignatureValue', assertion) self.assertEqual(0, len(signature_nodes_3)) signature_nodes_4 = OneLogin_Saml2_XML.query( dom, './ds:Signature/ds:SignatureValue', assertion) self.assertEqual(1, len(signature_nodes_4)) signature_nodes_5 = OneLogin_Saml2_XML.query(dom, './/ds:SignatureValue', assertion) self.assertEqual(1, len(signature_nodes_5))
def testToString(self): """ Tests the to_string method of the OneLogin_Saml2_XML """ xml = '<test>test1</test>' elem = etree.fromstring(xml) bxml = xml.encode('utf8') self.assertIs(xml, OneLogin_Saml2_XML.to_string(xml)) self.assertIs(bxml, OneLogin_Saml2_XML.to_string(bxml)) self.assertEqual(etree.tostring(elem), OneLogin_Saml2_XML.to_string(elem)) self.assertRaisesRegexp(ValueError, 'unsupported type', OneLogin_Saml2_XML.to_string, 1)
def testToString(self): """ Tests the to_string method of the OneLogin_Saml2_XML """ xml = '<test>test1</test>' elem = etree.fromstring(xml) bxml = xml.encode('utf8') self.assertIs(xml, OneLogin_Saml2_XML.to_string(xml)) self.assertIs(bxml, OneLogin_Saml2_XML.to_string(bxml)) self.assertEqual(etree.tostring(elem), OneLogin_Saml2_XML.to_string(elem)) with self.assertRaises(ValueError) as context: OneLogin_Saml2_XML.to_string(1) exception = context.exception self.assertIn("unsupported type", str(exception))
def testConstructor(self): """ Tests the OneLogin_Saml2_LogoutResponse Constructor. """ settings = OneLogin_Saml2_Settings(self.loadSettingsJSON()) message = self.file_contents(join(self.data_path, 'logout_responses', 'logout_response_deflated.xml.base64')) response = OneLogin_Saml2_Logout_Response(settings, message) self.assertRegex(compat.to_string(OneLogin_Saml2_XML.to_string(response.document)), '<samlp:LogoutResponse')
def testQuery(self): """ Tests the query method of the OneLogin_Saml2_Utils """ xml = self.file_contents(join(self.data_path, 'responses', 'valid_response.xml.base64')) xml = b64decode(xml) dom = etree.fromstring(xml) assertion_nodes = OneLogin_Saml2_XML.query(dom, '/samlp:Response/saml:Assertion') self.assertEqual(1, len(assertion_nodes)) assertion = assertion_nodes[0] self.assertIn('Assertion', assertion.tag) attribute_statement_nodes = OneLogin_Saml2_XML.query(dom, '/samlp:Response/saml:Assertion/saml:AttributeStatement') self.assertEqual(1, len(assertion_nodes)) attribute_statement = attribute_statement_nodes[0] self.assertIn('AttributeStatement', attribute_statement.tag) attribute_statement_nodes_2 = OneLogin_Saml2_XML.query(dom, './saml:AttributeStatement', assertion) self.assertEqual(1, len(attribute_statement_nodes_2)) attribute_statement_2 = attribute_statement_nodes_2[0] self.assertEqual(attribute_statement, attribute_statement_2) signature_res_nodes = OneLogin_Saml2_XML.query(dom, '/samlp:Response/ds:Signature') self.assertEqual(1, len(signature_res_nodes)) signature_res = signature_res_nodes[0] self.assertIn('Signature', signature_res.tag) signature_nodes = OneLogin_Saml2_XML.query(dom, '/samlp:Response/saml:Assertion/ds:Signature') self.assertEqual(1, len(signature_nodes)) signature = signature_nodes[0] self.assertIn('Signature', signature.tag) signature_nodes_2 = OneLogin_Saml2_XML.query(dom, './ds:Signature', assertion) self.assertEqual(1, len(signature_nodes_2)) signature2 = signature_nodes_2[0] self.assertNotEqual(signature_res, signature2) self.assertEqual(signature, signature2) signature_nodes_3 = OneLogin_Saml2_XML.query(dom, './ds:SignatureValue', assertion) self.assertEqual(0, len(signature_nodes_3)) signature_nodes_4 = OneLogin_Saml2_XML.query(dom, './ds:Signature/ds:SignatureValue', assertion) self.assertEqual(1, len(signature_nodes_4)) signature_nodes_5 = OneLogin_Saml2_XML.query(dom, './/ds:SignatureValue', assertion) self.assertEqual(1, len(signature_nodes_5))
def testConstructor(self): """ Tests the OneLogin_Saml2_LogoutResponse Constructor. """ settings = OneLogin_Saml2_Settings(self.loadSettingsJSON()) message = self.file_contents( join(self.data_path, 'logout_responses', 'logout_response_deflated.xml.base64')) response = OneLogin_Saml2_Logout_Response(settings, message) self.assertRegex( compat.to_string(OneLogin_Saml2_XML.to_string(response.document)), '<samlp:LogoutResponse')
def testValidateXML(self): """ Tests the validate_xml method of the OneLogin_Saml2_XML """ metadata_unloaded = '<xml><EntityDescriptor>' res = OneLogin_Saml2_XML.validate_xml(metadata_unloaded, 'saml-schema-metadata-2.0.xsd') self.assertIsInstance(res, str) self.assertIn('unloaded_xml', res) metadata_invalid = self.file_contents(join(self.data_path, 'metadata', 'noentity_metadata_settings1.xml')) res = OneLogin_Saml2_XML.validate_xml(metadata_invalid, 'saml-schema-metadata-2.0.xsd') self.assertIsInstance(res, str) self.assertIn('invalid_xml', res) metadata_expired = self.file_contents(join(self.data_path, 'metadata', 'expired_metadata_settings1.xml')) res = OneLogin_Saml2_XML.validate_xml(metadata_expired, 'saml-schema-metadata-2.0.xsd') self.assertIsInstance(res, OneLogin_Saml2_XML._element_class) metadata_ok = self.file_contents(join(self.data_path, 'metadata', 'metadata_settings1.xml')) res = OneLogin_Saml2_XML.validate_xml(metadata_ok, 'saml-schema-metadata-2.0.xsd') self.assertIsInstance(res, OneLogin_Saml2_XML._element_class)
def validateAssertion(xml, fingerprint=None, fingerprintalg=None): result = { 'schemaValidate': False, 'signCheck': False, 'certValidity': False, 'certAllowed': True, 'error': 0, 'msg': '', 'assertionName': None, 'chkTime': None, 'chkStatus': None, 'serviceAttributes': None } assert isinstance(xml, compat.text_types) if len(xml) == 0: result['error'] = 1 result['msg'] = 'Empty string supplied as input' return result OneLoginResponse = OneLogin_Saml2_Response({}, Saml2_Utils.b64encode(xml)) xml = xmlRemoveDeclaration(xml) parsedassertion = etree.fromstring(xml) # assertion name path assertionNameXpath = "local-name(/*)" assertionName = parsedassertion.xpath(assertionNameXpath) assertionName = str(assertionName) # find assertion schema if assertionName == 'EntityDescriptor': asscertionShema = 'saml-schema-metadata-2.0.xsd' elif assertionName == 'Response': asscertionShema = 'saml-schema-protocol-2.0.xsd' elif assertionName == 'AuthnRequest': asscertionShema = 'saml-schema-protocol-2.0.xsd' else: result['error'] = 2 result['msg'] = 'Assertion unknown' return result # siganture node path signatureNodeXpath = ".//*[local-name()='Signature']" if assertionName == 'Response': signatureNodeXpath = "*[local-name(/*)='Response']//*[local-name()='Signature']" result['assertionName'] = assertionName # get certificate signing try: signingcert = easyspid.lib.easyspid.get_signature_cert(xml) except Exception as error: signingcert = False # validate xml against its schema schemaCheck = OneLogin_Saml2_XML.validate_xml(xml, asscertionShema, False) if isinstance(schemaCheck, str): result['msg'] = schemaCheck result['schemaValidate'] = False result['error'] = 3 else: result['schemaValidate'] = True # check signature if signingcert: signingfingerprintalg = 'sha1' if fingerprintalg is not None: signingfingerprintalg = fingerprintalg signingfingerprint = (easyspid.lib.easyspid.calcCertFingerprint( signingcert, signingfingerprintalg))['result'] if assertionName == 'EntityDescriptor' and fingerprint is None: allowedCert = easyspid.lib.easyspid.get_metadata_allowed_cert(xml) allowedfingerprint = (easyspid.lib.easyspid.calcCertFingerprint( allowedCert, signingfingerprintalg))['result'] elif assertionName != 'EntityDescriptor' and fingerprint is None: allowedfingerprint = signingfingerprint if fingerprint is not None: allowedfingerprint = fingerprint signCheck = Saml2_Utils.validate_sign( xml, cert=signingcert, fingerprint=signingfingerprint, fingerprintalg=signingfingerprintalg, validatecert=False, debug=False, xpath=signatureNodeXpath, multicerts=None) if signCheck: result['signCheck'] = True else: result['error'] = 3 # check expired certificate certTimeValdity = easyspid.lib.easyspid.timeValidateCert(signingcert) if certTimeValdity: result['certValidity'] = True # checktime certificate allow if allowedfingerprint != signingfingerprint: result['certAllowed'] = False result['error'] = 3 elif not signingcert and assertionName == 'AuthnRequest': result['signCheck'] = None result['certValidity'] = None result['certAllowed'] = None if assertionName == 'Response': try: OneLoginResponse.validate_timestamps(raise_exceptions=True) result['chkTime'] = True except OneLogin_Saml2_ValidationError as error: result['chkTime'] = False result['error'] = 3 try: OneLoginResponse.check_status() result['chkStatus'] = True except OneLogin_Saml2_ValidationError as error: result['chkStatus'] = False result['error'] = 3 try: result['serviceAttributes'] = OneLoginResponse.get_attributes() except: pass return result
def AddSign(xml, key, cert, debug=False, sign_algorithm=OneLogin_Saml2_Constants.RSA_SHA1, digest_algorithm=OneLogin_Saml2_Constants.SHA1, addKeyValue=False): """ Adds signature key and senders certificate to an element (Message or Assertion). :param xml: The element we should sign :type: string | Document :param key: The private key :type: string :param cert: The public :type: string :param debug: Activate the xmlsec debug :type: bool :param sign_algorithm: Signature algorithm method :type sign_algorithm: string :param digest_algorithm: Digest algorithm method :type digest_algorithm: string :returns: Signed XML :rtype: string """ if xml is None or xml == '': raise Exception('Empty string supplied as input') elem = OneLogin_Saml2_XML.to_etree(xml) xmlsec.enable_debug_trace(debug) xmlsec.tree.add_ids(elem, ["ID"]) # Sign the metadata with our private key. sign_algorithm_transform_map = { OneLogin_Saml2_Constants.DSA_SHA1: xmlsec.Transform.DSA_SHA1, OneLogin_Saml2_Constants.RSA_SHA1: xmlsec.Transform.RSA_SHA1, OneLogin_Saml2_Constants.RSA_SHA256: xmlsec.Transform.RSA_SHA256, OneLogin_Saml2_Constants.RSA_SHA384: xmlsec.Transform.RSA_SHA384, OneLogin_Saml2_Constants.RSA_SHA512: xmlsec.Transform.RSA_SHA512 } sign_algorithm_transform = sign_algorithm_transform_map.get( sign_algorithm, xmlsec.Transform.RSA_SHA1) signature = xmlsec.template.create(elem, xmlsec.Transform.EXCL_C14N, sign_algorithm_transform, ns='ds') issuer = OneLogin_Saml2_XML.query(elem, '//saml:Issuer') if len(issuer) > 0: issuer = issuer[0] issuer.addnext(signature) else: elem.insert(0, signature) elem_id = elem.get('ID', None) if elem_id: elem_id = '#' + elem_id #else: # elem_id = "" digest_algorithm_transform_map = { OneLogin_Saml2_Constants.SHA1: xmlsec.Transform.SHA1, OneLogin_Saml2_Constants.SHA256: xmlsec.Transform.SHA256, OneLogin_Saml2_Constants.SHA384: xmlsec.Transform.SHA384, OneLogin_Saml2_Constants.SHA512: xmlsec.Transform.SHA512 } digest_algorithm_transform = digest_algorithm_transform_map.get( digest_algorithm, xmlsec.Transform.SHA1) ref = xmlsec.template.add_reference(signature, digest_algorithm_transform, uri=elem_id) xmlsec.template.add_transform(ref, xmlsec.Transform.ENVELOPED) xmlsec.template.add_transform(ref, xmlsec.Transform.EXCL_C14N) key_info = xmlsec.template.ensure_key_info(signature) if addKeyValue: xmlsec.template.add_key_value(key_info) xmlsec.template.add_x509_data(key_info) dsig_ctx = xmlsec.SignatureContext() sign_key = xmlsec.Key.from_memory(key, xmlsec.KeyFormat.PEM, None) sign_key.load_cert_from_memory(cert, xmlsec.KeyFormat.PEM) dsig_ctx.key = sign_key dsig_ctx.sign(signature) return OneLogin_Saml2_XML.to_string(elem)
def validate_metadata_sign(xml, cert=None, fingerprint=None, fingerprintalg='sha1', validatecert=False, debug=False): """ Validates a signature of a EntityDescriptor. :param xml: The element we should validate :type: string | Document :param cert: The public cert :type: string :param fingerprint: The fingerprint of the public cert :type: string :param fingerprintalg: The algorithm used to build the fingerprint :type: string :param validatecert: If true, will verify the signature and if the cert is valid. :type: bool :param debug: Activate the xmlsec debug :type: bool :param raise_exceptions: Whether to return false on failure or raise an exception :type raise_exceptions: Boolean """ if xml is None or xml == '': raise Exception('Empty string supplied as input') elem = OneLogin_Saml2_XML.to_etree(xml) xmlsec.enable_debug_trace(debug) xmlsec.tree.add_ids(elem, ["ID"]) signature_nodes = OneLogin_Saml2_XML.query( elem, '/md:EntitiesDescriptor/ds:Signature') if len(signature_nodes) == 0: signature_nodes += OneLogin_Saml2_XML.query( elem, '/md:EntityDescriptor/ds:Signature') if len(signature_nodes) == 0: signature_nodes += OneLogin_Saml2_XML.query( elem, '/md:EntityDescriptor/md:SPSSODescriptor/ds:Signature') signature_nodes += OneLogin_Saml2_XML.query( elem, '/md:EntityDescriptor/md:IDPSSODescriptor/ds:Signature') if len(signature_nodes) > 0: for signature_node in signature_nodes: # Raises expection if invalid Saml2_Utils.validate_node_sign(signature_node, elem, cert, fingerprint, fingerprintalg, validatecert, debug, raise_exceptions=True) return True else: raise Exception( 'Could not validate metadata signature: No signature nodes found.' )
def validate_node_sign(signature_node, elem, cert=None, fingerprint=None, fingerprintalg='sha1', validatecert=False, debug=False): """ Validates a signature node. :param signature_node: The signature node :type: Node :param xml: The element we should validate :type: Document :param cert: The public cert :type: string :param fingerprint: The fingerprint of the public cert :type: string :param fingerprintalg: The algorithm used to build the fingerprint :type: string :param validatecert: If true, will verify the signature and if the cert is valid. :type: bool :param debug: Activate the xmlsec debug :type: bool :param raise_exceptions: Whether to return false on failure or raise an exception :type raise_exceptions: Boolean """ if (cert is None or cert == '') and fingerprint: x509_certificate_nodes = OneLogin_Saml2_XML.query( signature_node, '//ds:Signature/ds:KeyInfo/ds:X509Data/ds:X509Certificate') if len(x509_certificate_nodes) > 0: x509_certificate_node = x509_certificate_nodes[0] x509_cert_value = OneLogin_Saml2_XML.element_text( x509_certificate_node) x509_cert_value_formatted = Saml2_Utils.format_cert( x509_cert_value) x509_fingerprint_value = Saml2_Utils.calculate_x509_fingerprint( x509_cert_value_formatted, fingerprintalg) if fingerprint == x509_fingerprint_value: cert = x509_cert_value_formatted if cert is None or cert == '': raise OneLogin_Saml2_Error( 'Could not validate node signature: No certificate provided.', OneLogin_Saml2_Error.CERT_NOT_FOUND) # Check if Reference URI is empty #reference_elem = OneLogin_Saml2_XML.query(signature_node, '//ds:Reference') #if len(reference_elem) > 0: # if reference_elem[0].get('URI') == '': # reference_elem[0].set('URI', '#%s' % signature_node.getparent().get('ID')) if validatecert: manager = xmlsec.KeysManager() manager.load_cert_from_memory(cert, xmlsec.KeyFormat.CERT_PEM, xmlsec.KeyDataType.TRUSTED) dsig_ctx = xmlsec.SignatureContext(manager) else: dsig_ctx = xmlsec.SignatureContext() dsig_ctx.key = xmlsec.Key.from_memory(cert, xmlsec.KeyFormat.CERT_PEM, None) dsig_ctx.set_enabled_key_data([xmlsec.KeyData.X509]) try: dsig_ctx.verify(signature_node) except Exception as err: raise OneLogin_Saml2_ValidationError( 'Signature validation failed. SAML Response rejected. %s', OneLogin_Saml2_ValidationError.INVALID_SIGNATURE, str(err)) return True
def validate_metadata(self, xml, fingerprint=None, fingerprintalg='sha1', validatecert=False): """ Validates an XML SP Metadata. :param xml: Metadata's XML that will be validate :type xml: string :param fingerprint: The fingerprint of the public cert :type: string :param fingerprintalg: The algorithm used to build the fingerprint :type: string :param validatecert: If true, will verify the signature and if the cert is valid. :type: bool :returns: a dictionary with the list of found validation errors and signature check :rtype: dict """ result = { 'schemaValidate': True, 'signCheck': False, 'error': 0, 'msg': '' } assert isinstance(xml, compat.text_types) if len(xml) == 0: raise Exception('Empty string supplied as input') #errors = {'validate':[], 'signCheck':0} root = OneLogin_Saml2_XML.validate_xml( xml, 'saml-schema-metadata-2.0.xsd', self._OneLogin_Saml2_Settings__debug) if isinstance(root, str): result['msg'] = root result['schemaValidate'] = False else: if root.tag != '{%s}EntityDescriptor' % OneLogin_Saml2_Constants.NS_MD: result['msg'] = 'noEntityDescriptor_xml' result['error'] = 1 result['schemaValidate'] = False #errors.append('noEntityDescriptor_xml') else: if (len( root.findall( './/md:SPSSODescriptor', namespaces=OneLogin_Saml2_Constants.NSMAP))) != 1: #errors.append('onlySPSSODescriptor_allowed_xml') result['msg'] = 'onlySPSSODescriptor_allowed_xml' result['error'] = 2 result['schemaValidate'] = False else: valid_until, cache_duration = root.get( 'validUntil'), root.get('cacheDuration') if valid_until: valid_until = Saml2_Utils.parse_SAML_to_time( valid_until) expire_time = Saml2_Utils.get_expire_time( cache_duration, valid_until) if expire_time is not None and int( time()) > int(expire_time): #errors.append('expired_xml') result['msg'] = 'expired_xml' result['error'] = 3 result['schemaValidate'] = False # Validate Sign signCheck = Saml2_Utils.validate_metadata_sign( xml, fingerprint=fingerprint, fingerprintalg=fingerprintalg, validatecert=validatecert) if signCheck: result['signCheck'] = True return result