def testSignMetadata(self): """ Tests the signMetadata method of the OneLogin_Saml2_Metadata """ settings = OneLogin_Saml2_Settings(self.loadSettingsJSON()) sp_data = settings.get_sp_data() security = settings.get_security_data() metadata = OneLogin_Saml2_Metadata.builder( sp_data, security['authnRequestsSigned'], security['wantAssertionsSigned'] ) self.assertIsNotNone(metadata) cert_path = settings.get_cert_path() key = self.file_contents(join(cert_path, 'sp.key')) cert = self.file_contents(join(cert_path, 'sp.crt')) signed_metadata = OneLogin_Saml2_Metadata.sign_metadata(metadata, key, cert) self.assertIn('<md:SPSSODescriptor', signed_metadata) self.assertIn('entityID="http://stuff.com/endpoints/metadata.php"', signed_metadata) self.assertIn('AuthnRequestsSigned="false"', signed_metadata) self.assertIn('WantAssertionsSigned="false"', signed_metadata) self.assertIn('<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"', signed_metadata) self.assertIn('Location="http://stuff.com/endpoints/endpoints/acs.php"', signed_metadata) self.assertIn('<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"', signed_metadata) self.assertIn(' Location="http://stuff.com/endpoints/endpoints/sls.php"/>', signed_metadata) self.assertIn('<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>', signed_metadata) self.assertIn('<ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>', signed_metadata) self.assertIn('<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>', signed_metadata) self.assertIn('<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>', signed_metadata) self.assertIn('<ds:Reference', signed_metadata) self.assertIn('<ds:KeyInfo><ds:X509Data>\n<ds:X509Certificate>', signed_metadata) with self.assertRaisesRegexp(Exception, 'Empty string supplied as input'): OneLogin_Saml2_Metadata.sign_metadata('', key, cert) signed_metadata_2 = OneLogin_Saml2_Metadata.sign_metadata(metadata, key, cert, OneLogin_Saml2_Constants.RSA_SHA256, OneLogin_Saml2_Constants.SHA384) self.assertIn('<md:SPSSODescriptor', signed_metadata_2) self.assertIn('entityID="http://stuff.com/endpoints/metadata.php"', signed_metadata_2) self.assertIn('AuthnRequestsSigned="false"', signed_metadata_2) self.assertIn('WantAssertionsSigned="false"', signed_metadata_2) self.assertIn('<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"', signed_metadata_2) self.assertIn('Location="http://stuff.com/endpoints/endpoints/acs.php"', signed_metadata_2) self.assertIn('<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"', signed_metadata_2) self.assertIn(' Location="http://stuff.com/endpoints/endpoints/sls.php"/>', signed_metadata_2) self.assertIn('<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>', signed_metadata_2) self.assertIn('<ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>', signed_metadata_2) self.assertIn('<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#sha384"/>', signed_metadata_2) self.assertIn('<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>', signed_metadata_2) self.assertIn('<ds:Reference', signed_metadata_2) self.assertIn('<ds:KeyInfo><ds:X509Data>\n<ds:X509Certificate>', signed_metadata_2)
def testSignMetadata(self): """ Tests the signMetadata method of the OneLogin_Saml2_Metadata """ settings = OneLogin_Saml2_Settings(self.loadSettingsJSON()) sp_data = settings.get_sp_data() security = settings.get_security_data() metadata = OneLogin_Saml2_Metadata.builder( sp_data, security["authnRequestsSigned"], security["wantAssertionsSigned"] ) self.assertIsNotNone(metadata) cert_path = settings.get_cert_path() key = self.file_contents(join(cert_path, "sp.key")) cert = self.file_contents(join(cert_path, "sp.crt")) signed_metadata = OneLogin_Saml2_Metadata.sign_metadata(metadata, key, cert) self.assertIn("<md:SPSSODescriptor", signed_metadata) self.assertIn('entityID="http://stuff.com/endpoints/metadata.php"', signed_metadata) self.assertIn('AuthnRequestsSigned="false"', signed_metadata) self.assertIn('WantAssertionsSigned="false"', signed_metadata) self.assertIn( '<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"', signed_metadata ) self.assertIn('Location="http://stuff.com/endpoints/endpoints/acs.php"', signed_metadata) self.assertIn( '<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"', signed_metadata ) self.assertIn(' Location="http://stuff.com/endpoints/endpoints/sls.php"/>', signed_metadata) self.assertIn( "<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>", signed_metadata ) self.assertIn( '<ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>', signed_metadata, ) self.assertIn('<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>', signed_metadata) self.assertIn("<ds:Reference", signed_metadata) self.assertIn("<ds:KeyInfo><ds:X509Data>\n<ds:X509Certificate>", signed_metadata) try: OneLogin_Saml2_Metadata.sign_metadata("", key, cert) self.assertTrue(False) except Exception as e: self.assertIn("Empty string supplied as input", e.message)
def get_sp_metadata(self): """ Gets the SP metadata. The XML representation. :returns: SP metadata (xml) :rtype: string """ metadata = OneLogin_Saml2_Metadata.builder( self.__sp, self.__security['authnRequestsSigned'], self.__security['wantAssertionsSigned'], None, None, self.get_contacts(), self.get_organization()) cert = self.get_sp_cert() metadata = OneLogin_Saml2_Metadata.add_x509_key_descriptors( metadata, cert) # Sign metadata if 'signMetadata' in self.__security and self.__security[ 'signMetadata'] is not False: if self.__security['signMetadata'] is True: key_file_name = 'sp.key' cert_file_name = 'sp.crt' else: if ('keyFileName' not in self.__security['signMetadata'] or 'certFileName' not in self.__security['signMetadata']): raise OneLogin_Saml2_Error( 'Invalid Setting: signMetadata value of the sp is not valid', OneLogin_Saml2_Error.SETTINGS_INVALID_SYNTAX) key_file_name = self.__security['signMetadata']['keyFileName'] cert_file_name = self.__security['signMetadata'][ 'certFileName'] key_metadata_file = self.__paths['cert'] + key_file_name cert_metadata_file = self.__paths['cert'] + cert_file_name if not exists(key_metadata_file): raise OneLogin_Saml2_Error( 'Private key file not found: %s', OneLogin_Saml2_Error.PRIVATE_KEY_FILE_NOT_FOUND, key_metadata_file) if not exists(cert_metadata_file): raise OneLogin_Saml2_Error( 'Public cert file not found: %s', OneLogin_Saml2_Error.PUBLIC_CERT_FILE_NOT_FOUND, cert_metadata_file) f_metadata_key = open(key_metadata_file, 'r') key_metadata = f_metadata_key.read() f_metadata_key.close() f_metadata_cert = open(cert_metadata_file, 'r') cert_metadata = f_metadata_cert.read() f_metadata_cert.close() metadata = OneLogin_Saml2_Metadata.sign_metadata( metadata, key_metadata, cert_metadata) return metadata
def get_sp_metadata(self): """ Gets the SP metadata. The XML representation. :returns: SP metadata (xml) :rtype: string """ metadata = OneLogin_Saml2_Metadata.builder( self.__sp, self.__security['authnRequestsSigned'], self.__security['wantAssertionsSigned'], None, None, self.get_contacts(), self.get_organization() ) cert = self.get_sp_cert() metadata = OneLogin_Saml2_Metadata.add_x509_key_descriptors(metadata, cert) # Sign metadata if 'signMetadata' in self.__security and self.__security['signMetadata'] is not False: if self.__security['signMetadata'] is True: key_file_name = 'sp.key' cert_file_name = 'sp.crt' else: if ('keyFileName' not in self.__security['signMetadata'] or 'certFileName' not in self.__security['signMetadata']): raise OneLogin_Saml2_Error( 'Invalid Setting: signMetadata value of the sp is not valid', OneLogin_Saml2_Error.SETTINGS_INVALID_SYNTAX ) key_file_name = self.__security['signMetadata']['keyFileName'] cert_file_name = self.__security['signMetadata']['certFileName'] key_metadata_file = self.__paths['cert'] + key_file_name cert_metadata_file = self.__paths['cert'] + cert_file_name if not exists(key_metadata_file): raise OneLogin_Saml2_Error( 'Private key file not found: %s', OneLogin_Saml2_Error.PRIVATE_KEY_FILE_NOT_FOUND, key_metadata_file ) if not exists(cert_metadata_file): raise OneLogin_Saml2_Error( 'Public cert file not found: %s', OneLogin_Saml2_Error.PUBLIC_CERT_FILE_NOT_FOUND, cert_metadata_file ) f_metadata_key = open(key_metadata_file, 'r') key_metadata = f_metadata_key.read() f_metadata_key.close() f_metadata_cert = open(cert_metadata_file, 'r') cert_metadata = f_metadata_cert.read() f_metadata_cert.close() metadata = OneLogin_Saml2_Metadata.sign_metadata(metadata, key_metadata, cert_metadata) return metadata
def get_sp_metadata(self): """ Gets the SP metadata. The XML representation. :returns: SP metadata (xml) :rtype: string """ metadata = OneLogin_Saml2_Metadata.builder( self.__sp, self.__security['authnRequestsSigned'], self.__security['wantAssertionsSigned'], self.__security['metadataValidUntil'], self.__security['metadataCacheDuration'], self.get_contacts(), self.get_organization()) add_encryption = self.__security[ 'wantNameIdEncrypted'] or self.__security['wantAssertionsEncrypted'] cert_new = self.get_sp_cert_new() metadata = OneLogin_Saml2_Metadata.add_x509_key_descriptors( metadata, cert_new, add_encryption) cert = self.get_sp_cert() metadata = OneLogin_Saml2_Metadata.add_x509_key_descriptors( metadata, cert, add_encryption) # Sign metadata if 'signMetadata' in self.__security and self.__security[ 'signMetadata'] is not False: if self.__security['signMetadata'] is True: # Use the SP's normal key to sign the metadata: if not cert: raise OneLogin_Saml2_Error( 'Cannot sign metadata: missing SP public key certificate.', OneLogin_Saml2_Error.PUBLIC_CERT_FILE_NOT_FOUND) cert_metadata = cert key_metadata = self.get_sp_key() if not key_metadata: raise OneLogin_Saml2_Error( 'Cannot sign metadata: missing SP private key.', OneLogin_Saml2_Error.PRIVATE_KEY_FILE_NOT_FOUND) else: # Use a custom key to sign the metadata: if ('keyFileName' not in self.__security['signMetadata'] or 'certFileName' not in self.__security['signMetadata']): raise OneLogin_Saml2_Error( 'Invalid Setting: signMetadata value of the sp is not valid', OneLogin_Saml2_Error.SETTINGS_INVALID_SYNTAX) key_file_name = self.__security['signMetadata']['keyFileName'] cert_file_name = self.__security['signMetadata'][ 'certFileName'] key_metadata_file = self.__paths['cert'] + key_file_name cert_metadata_file = self.__paths['cert'] + cert_file_name try: with open(key_metadata_file, 'r') as f_metadata_key: key_metadata = f_metadata_key.read() except IOError: raise OneLogin_Saml2_Error( 'Private key file not readable: %s', OneLogin_Saml2_Error.PRIVATE_KEY_FILE_NOT_FOUND, key_metadata_file) try: with open(cert_metadata_file, 'r') as f_metadata_cert: cert_metadata = f_metadata_cert.read() except IOError: raise OneLogin_Saml2_Error( 'Public cert file not readable: %s', OneLogin_Saml2_Error.PUBLIC_CERT_FILE_NOT_FOUND, cert_metadata_file) signature_algorithm = self.__security['signatureAlgorithm'] digest_algorithm = self.__security['digestAlgorithm'] metadata = OneLogin_Saml2_Metadata.sign_metadata( metadata, key_metadata, cert_metadata, signature_algorithm, digest_algorithm) return metadata
def get_sp_metadata(self): """ Gets the SP metadata. The XML representation. :returns: SP metadata (xml) :rtype: string """ metadata = OneLogin_Saml2_Metadata.builder( self.__sp, self.__security['authnRequestsSigned'], self.__security['wantAssertionsSigned'], self.__security['metadataValidUntil'], self.__security['metadataCacheDuration'], self.get_contacts(), self.get_organization() ) cert = self.get_sp_cert() metadata = OneLogin_Saml2_Metadata.add_x509_key_descriptors(metadata, cert) # Sign metadata if 'signMetadata' in self.__security and self.__security['signMetadata'] is not False: if self.__security['signMetadata'] is True: # Use the SP's normal key to sign the metadata: if not cert: raise OneLogin_Saml2_Error( 'Cannot sign metadata: missing SP public key certificate.', OneLogin_Saml2_Error.PUBLIC_CERT_FILE_NOT_FOUND ) cert_metadata = cert key_metadata = self.get_sp_key() if not key_metadata: raise OneLogin_Saml2_Error( 'Cannot sign metadata: missing SP private key.', OneLogin_Saml2_Error.PRIVATE_KEY_FILE_NOT_FOUND ) else: # Use a custom key to sign the metadata: if ('keyFileName' not in self.__security['signMetadata'] or 'certFileName' not in self.__security['signMetadata']): raise OneLogin_Saml2_Error( 'Invalid Setting: signMetadata value of the sp is not valid', OneLogin_Saml2_Error.SETTINGS_INVALID_SYNTAX ) key_file_name = self.__security['signMetadata']['keyFileName'] cert_file_name = self.__security['signMetadata']['certFileName'] key_metadata_file = self.__paths['cert'] + key_file_name cert_metadata_file = self.__paths['cert'] + cert_file_name try: with open(key_metadata_file, 'r') as f_metadata_key: key_metadata = f_metadata_key.read() except IOError: raise OneLogin_Saml2_Error( 'Private key file not readable: %s', OneLogin_Saml2_Error.PRIVATE_KEY_FILE_NOT_FOUND, key_metadata_file ) try: with open(cert_metadata_file, 'r') as f_metadata_cert: cert_metadata = f_metadata_cert.read() except IOError: raise OneLogin_Saml2_Error( 'Public cert file not readable: %s', OneLogin_Saml2_Error.PUBLIC_CERT_FILE_NOT_FOUND, cert_metadata_file ) metadata = OneLogin_Saml2_Metadata.sign_metadata(metadata, key_metadata, cert_metadata) return metadata
def testSignMetadata(self): """ Tests the signMetadata method of the OneLogin_Saml2_Metadata """ settings = OneLogin_Saml2_Settings(self.loadSettingsJSON()) sp_data = settings.get_sp_data() security = settings.get_security_data() metadata = OneLogin_Saml2_Metadata.builder( sp_data, security['authnRequestsSigned'], security['wantAssertionsSigned']) self.assertIsNotNone(metadata) cert_path = settings.get_cert_path() key = self.file_contents(join(cert_path, 'sp.key')) cert = self.file_contents(join(cert_path, 'sp.crt')) signed_metadata = compat.to_string( OneLogin_Saml2_Metadata.sign_metadata(metadata, key, cert)) self.assertTrue( OneLogin_Saml2_Utils.validate_metadata_sign(signed_metadata, cert)) self.assertIn('<md:SPSSODescriptor', signed_metadata) self.assertIn('entityID="http://stuff.com/endpoints/metadata.php"', signed_metadata) self.assertIn('ID="ONELOGIN_', signed_metadata) self.assertIn('AuthnRequestsSigned="false"', signed_metadata) self.assertIn('WantAssertionsSigned="false"', signed_metadata) self.assertIn( '<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"', signed_metadata) self.assertIn( 'Location="http://stuff.com/endpoints/endpoints/acs.php"', signed_metadata) self.assertIn( '<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"', signed_metadata) self.assertIn( ' Location="http://stuff.com/endpoints/endpoints/sls.php"/>', signed_metadata) self.assertIn( '<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>', signed_metadata) self.assertIn( '<ds:SignedInfo>\n<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>', signed_metadata) self.assertIn( '<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>', signed_metadata) self.assertIn( '<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>', signed_metadata) self.assertIn('<ds:Reference', signed_metadata) self.assertIn('<ds:KeyInfo>\n<ds:X509Data>\n<ds:X509Certificate>', signed_metadata) with self.assertRaises(Exception) as context: OneLogin_Saml2_Metadata.sign_metadata('', key, cert) exception = context.exception self.assertIn("Empty string supplied as input", str(exception)) signed_metadata_2 = compat.to_string( OneLogin_Saml2_Metadata.sign_metadata( metadata, key, cert, OneLogin_Saml2_Constants.RSA_SHA256, OneLogin_Saml2_Constants.SHA384)) self.assertTrue( OneLogin_Saml2_Utils.validate_metadata_sign( signed_metadata_2, cert)) self.assertIn('<md:SPSSODescriptor', signed_metadata_2) self.assertIn('entityID="http://stuff.com/endpoints/metadata.php"', signed_metadata_2) self.assertIn('ID="ONELOGIN_', signed_metadata_2) self.assertIn('AuthnRequestsSigned="false"', signed_metadata_2) self.assertIn('WantAssertionsSigned="false"', signed_metadata_2) self.assertIn( '<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"', signed_metadata_2) self.assertIn( 'Location="http://stuff.com/endpoints/endpoints/acs.php"', signed_metadata_2) self.assertIn( '<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"', signed_metadata_2) self.assertIn( ' Location="http://stuff.com/endpoints/endpoints/sls.php"/>', signed_metadata_2) self.assertIn( '<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>', signed_metadata_2) self.assertIn( '<ds:SignedInfo>\n<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>', signed_metadata_2) self.assertIn( '<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#sha384"/>', signed_metadata_2) self.assertIn( '<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>', signed_metadata_2) self.assertIn('<ds:Reference', signed_metadata_2) self.assertIn('<ds:KeyInfo>\n<ds:X509Data>\n<ds:X509Certificate>', signed_metadata_2) root = OneLogin_Saml2_XML.to_etree(signed_metadata_2) first_child = OneLogin_Saml2_XML.query(root, '/md:EntityDescriptor/*[1]')[0] self.assertEqual('{http://www.w3.org/2000/09/xmldsig#}Signature', first_child.tag)
def testSignMetadata(self): """ Tests the signMetadata method of the OneLogin_Saml2_Metadata """ settings = OneLogin_Saml2_Settings(self.loadSettingsJSON()) sp_data = settings.get_sp_data() security = settings.get_security_data() metadata = OneLogin_Saml2_Metadata.builder( sp_data, security['authnRequestsSigned'], security['wantAssertionsSigned'] ) self.assertIsNotNone(metadata) cert_path = settings.get_cert_path() key = self.file_contents(join(cert_path, 'sp.key')) cert = self.file_contents(join(cert_path, 'sp.crt')) signed_metadata = OneLogin_Saml2_Metadata.sign_metadata(metadata, key, cert) self.assertTrue(OneLogin_Saml2_Utils.validate_metadata_sign(signed_metadata, cert)) self.assertIn('<md:SPSSODescriptor', signed_metadata) self.assertIn('entityID="http://stuff.com/endpoints/metadata.php"', signed_metadata) self.assertIn('ID="ONELOGIN_', signed_metadata) self.assertIn('AuthnRequestsSigned="false"', signed_metadata) self.assertIn('WantAssertionsSigned="false"', signed_metadata) self.assertIn('<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"', signed_metadata) self.assertIn('Location="http://stuff.com/endpoints/endpoints/acs.php"', signed_metadata) self.assertIn('<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"', signed_metadata) self.assertIn(' Location="http://stuff.com/endpoints/endpoints/sls.php"/>', signed_metadata) self.assertIn('<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>', signed_metadata) self.assertIn('<ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>', signed_metadata) self.assertIn('<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>', signed_metadata) self.assertIn('<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>', signed_metadata) self.assertIn('<ds:Reference', signed_metadata) self.assertIn('<ds:KeyInfo><ds:X509Data>\n<ds:X509Certificate>', signed_metadata) with self.assertRaisesRegexp(Exception, 'Empty string supplied as input'): OneLogin_Saml2_Metadata.sign_metadata('', key, cert) signed_metadata_2 = OneLogin_Saml2_Metadata.sign_metadata(metadata, key, cert, OneLogin_Saml2_Constants.RSA_SHA256, OneLogin_Saml2_Constants.SHA384) self.assertTrue(OneLogin_Saml2_Utils.validate_metadata_sign(signed_metadata_2, cert)) self.assertIn('<md:SPSSODescriptor', signed_metadata_2) self.assertIn('entityID="http://stuff.com/endpoints/metadata.php"', signed_metadata_2) self.assertIn('ID="ONELOGIN_', signed_metadata_2) self.assertIn('AuthnRequestsSigned="false"', signed_metadata_2) self.assertIn('WantAssertionsSigned="false"', signed_metadata_2) self.assertIn('<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"', signed_metadata_2) self.assertIn('Location="http://stuff.com/endpoints/endpoints/acs.php"', signed_metadata_2) self.assertIn('<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"', signed_metadata_2) self.assertIn(' Location="http://stuff.com/endpoints/endpoints/sls.php"/>', signed_metadata_2) self.assertIn('<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>', signed_metadata_2) self.assertIn('<ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>', signed_metadata_2) self.assertIn('<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#sha384"/>', signed_metadata_2) self.assertIn('<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>', signed_metadata_2) self.assertIn('<ds:Reference', signed_metadata_2) self.assertIn('<ds:KeyInfo><ds:X509Data>\n<ds:X509Certificate>', signed_metadata_2)
def get_sp_metadata(self): """ Gets the SP metadata. The XML representation. :returns: SP metadata (xml) :rtype: string """ metadata = OneLogin_Saml2_Metadata.builder( self._OneLogin_Saml2_Settings__sp, self._OneLogin_Saml2_Settings__security['authnRequestsSigned'], self._OneLogin_Saml2_Settings__security['wantAssertionsSigned'], self._OneLogin_Saml2_Settings__security['metadataValidUntil'], self._OneLogin_Saml2_Settings__security['metadataCacheDuration'], self.get_contacts(), self.get_organization()) ##### SP SPid patch ## mapping xml tag tagMapping = { "md0:AssertionConsumerService": 'assertionConsumerService', "md0:AttributeConsumingService": 'attributeConsumingService', "md0:ServiceName": 'serviceName', "md0:ServiceDescription": 'serviceDescription', "md0:RequestedAttribute": 'requestedAttributes', "md1:AttributeValue": 'attributeValue' } ## edit meta data ns = { 'md0': OneLogin_Saml2_Constants.NS_MD, 'md1': OneLogin_Saml2_Constants.NS_SAML } xml.etree.ElementTree.register_namespace( 'md0', OneLogin_Saml2_Constants.NS_MD) xml.etree.ElementTree.register_namespace( 'md1', OneLogin_Saml2_Constants.NS_SAML) parsedMetadata = xml.etree.ElementTree.fromstring(metadata) SPSSODescriptor = parsedMetadata.find('md0:SPSSODescriptor', ns) if not self._OneLogin_Saml2_Settings__security[ 'putMetadataCacheDuration']: parsedMetadata.attrib.pop('cacheDuration') if not self._OneLogin_Saml2_Settings__security['putMetadataValidUntil']: parsedMetadata.attrib.pop('validUntil') ## fix AssertionConsumerService index 0 assertionConsumerService = SPSSODescriptor.find( 'md0:AssertionConsumerService', ns) assertionConsumerService.attrib['index'] = '0' assertionConsumerService.set('isDefault', 'true') ## fix AttributeConsumingService index 0 attributeConsumingService = SPSSODescriptor.find( 'md0:AttributeConsumingService', ns) attributeConsumingService.attrib['index'] = '0' attributeConsumingService.find('md0:ServiceName', ns).attrib[ '{http://www.w3.org/XML/1998/namespace}lang'] = self._OneLogin_Saml2_Settings__sp[ 'lang'] attributeConsumingService.find('md0:ServiceDescription', ns).attrib[ '{http://www.w3.org/XML/1998/namespace}lang'] = self._OneLogin_Saml2_Settings__sp[ 'lang'] ## add other AssertionConsumerService try: for index, value1 in enumerate(self._OneLogin_Saml2_Settings__sp[ 'otherAssertionConsumerService']): #indexValue = str(index+1) tag = "md0:AssertionConsumerService" element = xml.etree.ElementTree.Element( tag, attrib={ 'Location': value1[tagMapping[tag]]['url'], 'Binding': value1[tagMapping[tag]]['binding'], 'index': value1[tagMapping[tag]]['index'] }) #AssertionConsumerService.append(element) #SPSSODescriptor.append(element) SPSSODescriptor.insert(index + 3, element) tag1 = "md0:AttributeConsumingService" element1 = xml.etree.ElementTree.Element( tag1, attrib={'index': value1[tagMapping[tag]]['index']}) #SPSSODescriptor.append(element1) #AttributeConsumingService.append(element1) #attributeConsumingService = SPSSODescriptor.find("md0:AttributeConsumingService[@index=\""+indexValue+"\"]", ns) SPSSODescriptor.append(element1) tag2 = "md0:ServiceName" element2 = xml.etree.ElementTree.Element( tag2, attrib={ 'xml:lang': self._OneLogin_Saml2_Settings__sp['lang'] }) element2.text = value1[tagMapping[tag]][tagMapping[tag1]][ tagMapping[tag2]] element1.append(element2) tag2 = "md0:ServiceDescription" element2 = xml.etree.ElementTree.Element( tag2, attrib={ 'xml:lang': self._OneLogin_Saml2_Settings__sp['lang'] }) element2.text = value1[tagMapping[tag]][tagMapping[tag1]][ tagMapping[tag2]] element1.append(element2) tag3 = "md0:RequestedAttribute" for index2, value2 in enumerate(value1[tagMapping[tag]][ tagMapping[tag1]][tagMapping[tag3]]): if value2['isRequired']: attrRequired = "true" else: attrRequired = "false" attributi = { 'Name': value2['name'], 'FriendlyName': value2['friendlyName'], 'isRequired': attrRequired } element3 = xml.etree.ElementTree.Element(tag3, attrib=attributi) element1.append(element3) for index3, value3 in enumerate( value1[tagMapping[tag]][tagMapping[tag1]][ tagMapping[tag3]][index2]['attributeValue']): xml.etree.ElementTree.Element(tag3, attrib=attributi) tag4 = "md1:AttributeValue" element4 = xml.etree.ElementTree.Element(tag4) element4.text = value3 element3.append(element4) except: pass metadata = xml.etree.ElementTree.tostring(parsedMetadata, encoding="unicode") #### add_encryption = self._OneLogin_Saml2_Settings__security[ 'wantNameIdEncrypted'] or self._OneLogin_Saml2_Settings__security[ 'wantAssertionsEncrypted'] cert_new = self.get_sp_cert_new() metadata = OneLogin_Saml2_Metadata.add_x509_key_descriptors( metadata, cert_new, add_encryption) cert = self.get_sp_cert() metadata = OneLogin_Saml2_Metadata.add_x509_key_descriptors( metadata, cert, add_encryption) # Sign metadata if 'signMetadata' in self._OneLogin_Saml2_Settings__security and self._OneLogin_Saml2_Settings__security[ 'signMetadata'] is not False: if self._OneLogin_Saml2_Settings__security['signMetadata'] is True: # Use the SP's normal key to sign the metadata: if not cert: raise OneLogin_Saml2_Error( 'Cannot sign metadata: missing SP public key certificate.', OneLogin_Saml2_Error.PUBLIC_CERT_FILE_NOT_FOUND) cert_metadata = cert key_metadata = self.get_sp_key() if not key_metadata: raise OneLogin_Saml2_Error( 'Cannot sign metadata: missing SP private key.', OneLogin_Saml2_Error.PRIVATE_KEY_FILE_NOT_FOUND) else: # Use a custom key to sign the metadata: if ('keyFileName' not in self._OneLogin_Saml2_Settings__security['signMetadata'] or 'certFileName' not in self. _OneLogin_Saml2_Settings__security['signMetadata']): raise OneLogin_Saml2_Error( 'Invalid Setting: signMetadata value of the sp is not valid', OneLogin_Saml2_Error.SETTINGS_INVALID_SYNTAX) key_file_name = self._OneLogin_Saml2_Settings__security[ 'signMetadata']['keyFileName'] cert_file_name = self._OneLogin_Saml2_Settings__security[ 'signMetadata']['certFileName'] key_metadata_file = self._OneLogin_Saml2_Settings__paths[ 'cert'] + key_file_name cert_metadata_file = self._OneLogin_Saml2_Settings__paths[ 'cert'] + cert_file_name try: with open(key_metadata_file, 'r') as f_metadata_key: key_metadata = f_metadata_key.read() except IOError: raise OneLogin_Saml2_Error( 'Private key file not readable: %s', OneLogin_Saml2_Error.PRIVATE_KEY_FILE_NOT_FOUND, key_metadata_file) try: with open(cert_metadata_file, 'r') as f_metadata_cert: cert_metadata = f_metadata_cert.read() except IOError: raise OneLogin_Saml2_Error( 'Public cert file not readable: %s', OneLogin_Saml2_Error.PUBLIC_CERT_FILE_NOT_FOUND, cert_metadata_file) signature_algorithm = self._OneLogin_Saml2_Settings__security[ 'signatureAlgorithm'] digest_algorithm = self._OneLogin_Saml2_Settings__security[ 'digestAlgorithm'] metadata = OneLogin_Saml2_Metadata.sign_metadata( metadata, key_metadata, cert_metadata, signature_algorithm, digest_algorithm) ## fix signature element position #parsedMetadata = xml.etree.ElementTree.fromstring(metadata) #if parsedMetadata.find('{http://www.w3.org/2000/09/xmldsig#}Signature') == None: # for i, j in enumerate(parsedMetadata): # if j.find('{http://www.w3.org/2000/09/xmldsig#}Signature') != None: # signature = j.find('{http://www.w3.org/2000/09/xmldsig#}Signature') # parsedMetadata[i].remove(signature) # parsedMetadata.insert(0, signature) # break # metadata = xml.etree.ElementTree.tostring(parsedMetadata) return metadata