Skip to content

Commit 17bacb3

Browse files
author
Alexander Schrijver
committed
Make sure EncryptedKey is included in the KeyInfo when decrypting EncryptedIDs.
1 parent 397cfc8 commit 17bacb3

File tree

1 file changed

+37
-28
lines changed

1 file changed

+37
-28
lines changed

src/onelogin/saml2/response.py

Lines changed: 37 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,9 @@ def get_attributes(self):
594594
# Parse encrypted ids
595595
for encrypted_id in attr.iterchildren('{%s}EncryptedID' % OneLogin_Saml2_Constants.NSMAP['saml']):
596596
key = self.__settings.get_sp_key()
597+
self.__prepare_keyinfo(encrypted_id)
597598
encrypted_data = encrypted_id.getchildren()[0]
599+
598600
nameid = OneLogin_Saml2_Utils.decrypt_element(encrypted_data, key)
599601
values.append({
600602
'NameID': {
@@ -859,6 +861,39 @@ def __query(self, query, tagid=None):
859861
document = self.document
860862
return OneLogin_Saml2_XML.query(document, query, None, tagid)
861863

864+
def __prepare_keyinfo(self, node):
865+
"""
866+
Directly include the EncryptedKey in the KeyInfo of the EncryptedData. This
867+
is needed for decrypting with OneLogin_Saml2_Utils.decrypt_element.
868+
"""
869+
encrypted_data_keyinfo = OneLogin_Saml2_XML.query(node, 'xenc:EncryptedData/ds:KeyInfo')
870+
if not encrypted_data_keyinfo:
871+
raise OneLogin_Saml2_ValidationError(
872+
'No KeyInfo present, invalid Assertion',
873+
OneLogin_Saml2_ValidationError.KEYINFO_NOT_FOUND_IN_ENCRYPTED_DATA
874+
)
875+
encrypted_data_keyinfo = encrypted_data_keyinfo[0]
876+
children = encrypted_data_keyinfo.getchildren()
877+
if not children:
878+
raise OneLogin_Saml2_ValidationError(
879+
'KeyInfo has no children nodes, invalid Assertion',
880+
OneLogin_Saml2_ValidationError.CHILDREN_NODE_NOT_FOUND_IN_KEYINFO
881+
)
882+
for child in children:
883+
if 'RetrievalMethod' in child.tag:
884+
if child.attrib['Type'] != 'http://www.w3.org/2001/04/xmlenc#EncryptedKey':
885+
raise OneLogin_Saml2_ValidationError(
886+
'Unsupported Retrieval Method found',
887+
OneLogin_Saml2_ValidationError.UNSUPPORTED_RETRIEVAL_METHOD
888+
)
889+
uri = child.attrib['URI']
890+
if not uri.startswith('#'):
891+
break
892+
uri = uri.split('#')[1]
893+
encrypted_key = OneLogin_Saml2_XML.query(node, './xenc:EncryptedKey[@Id=$tagid]', None, uri)
894+
if encrypted_key:
895+
encrypted_data_keyinfo.append(encrypted_key[0])
896+
862897
def __decrypt_assertion(self, xml):
863898
"""
864899
Decrypts the Assertion
@@ -882,35 +917,9 @@ def __decrypt_assertion(self, xml):
882917
if encrypted_assertion_nodes:
883918
encrypted_data_nodes = OneLogin_Saml2_XML.query(encrypted_assertion_nodes[0], '//saml:EncryptedAssertion/xenc:EncryptedData')
884919
if encrypted_data_nodes:
885-
keyinfo = OneLogin_Saml2_XML.query(encrypted_assertion_nodes[0], '//saml:EncryptedAssertion/xenc:EncryptedData/ds:KeyInfo')
886-
if not keyinfo:
887-
raise OneLogin_Saml2_ValidationError(
888-
'No KeyInfo present, invalid Assertion',
889-
OneLogin_Saml2_ValidationError.KEYINFO_NOT_FOUND_IN_ENCRYPTED_DATA
890-
)
891-
keyinfo = keyinfo[0]
892-
children = keyinfo.getchildren()
893-
if not children:
894-
raise OneLogin_Saml2_ValidationError(
895-
'KeyInfo has no children nodes, invalid Assertion',
896-
OneLogin_Saml2_ValidationError.CHILDREN_NODE_NOT_FOUND_IN_KEYINFO
897-
)
898-
for child in children:
899-
if 'RetrievalMethod' in child.tag:
900-
if child.attrib['Type'] != 'http://www.w3.org/2001/04/xmlenc#EncryptedKey':
901-
raise OneLogin_Saml2_ValidationError(
902-
'Unsupported Retrieval Method found',
903-
OneLogin_Saml2_ValidationError.UNSUPPORTED_RETRIEVAL_METHOD
904-
)
905-
uri = child.attrib['URI']
906-
if not uri.startswith('#'):
907-
break
908-
uri = uri.split('#')[1]
909-
encrypted_key = OneLogin_Saml2_XML.query(encrypted_assertion_nodes[0], './xenc:EncryptedKey[@Id=$tagid]', None, uri)
910-
if encrypted_key:
911-
keyinfo.append(encrypted_key[0])
912-
913920
encrypted_data = encrypted_data_nodes[0]
921+
self.__prepare_keyinfo(encrypted_data)
922+
914923
decrypted = OneLogin_Saml2_Utils.decrypt_element(encrypted_data, key, debug=debug, inplace=True)
915924
xml.replace(encrypted_assertion_nodes[0], decrypted)
916925
return xml

0 commit comments

Comments
 (0)