@@ -62,26 +62,58 @@ def is_valid?(collect_errors = false)
6262 # @return [String] Gets the NameID of the Logout Request.
6363 #
6464 def name_id
65- @name_id ||= begin
66- node = REXML ::XPath . first ( document , "/p:LogoutRequest/a:NameID" , { "p" => PROTOCOL , "a" => ASSERTION } )
67- Utils . element_text ( node )
68- end
65+ @name_id ||= Utils . element_text ( name_id_node )
6966 end
7067
7168 alias_method :nameid , :name_id
7269
7370 # @return [String] Gets the NameID Format of the Logout Request.
7471 #
7572 def name_id_format
76- @name_id_node ||= REXML ::XPath . first ( document , "/p:LogoutRequest/a:NameID" , { "p" => PROTOCOL , "a" => ASSERTION } )
7773 @name_id_format ||=
78- if @ name_id_node && @ name_id_node. attribute ( "Format" )
79- @ name_id_node. attribute ( "Format" ) . value
74+ if name_id_node && name_id_node . attribute ( "Format" )
75+ name_id_node . attribute ( "Format" ) . value
8076 end
8177 end
8278
8379 alias_method :nameid_format , :name_id_format
8480
81+ def name_id_node
82+ @name_id_node ||=
83+ begin
84+ encrypted_node = REXML ::XPath . first ( document , "/p:LogoutRequest/a:EncryptedID" , { "p" => PROTOCOL , "a" => ASSERTION } )
85+ if encrypted_node
86+ node = decrypt_nameid ( encrypted_node )
87+ else
88+ node = REXML ::XPath . first ( document , "/p:LogoutRequest/a:NameID" , { "p" => PROTOCOL , "a" => ASSERTION } )
89+ end
90+ end
91+ end
92+
93+ # Decrypts an EncryptedID element
94+ # @param encryptedid_node [REXML::Element] The EncryptedID element
95+ # @return [REXML::Document] The decrypted EncrypedtID element
96+ #
97+ def decrypt_nameid ( encrypt_node )
98+
99+ if settings . nil? || !settings . get_sp_key
100+ raise ValidationError . new ( 'An ' + encrypt_node . name + ' found and no SP private key found on the settings to decrypt it' )
101+ end
102+
103+ node_header = '<node xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">'
104+
105+ elem_plaintext = OneLogin ::RubySaml ::Utils . decrypt_data ( encrypt_node , settings . get_sp_key )
106+ # If we get some problematic noise in the plaintext after decrypting.
107+ # This quick regexp parse will grab only the Element and discard the noise.
108+ elem_plaintext = elem_plaintext . match ( /(.*<\/ (\w +:)?NameID>)/m ) [ 0 ]
109+
110+ # To avoid namespace errors if saml namespace is not defined
111+ # create a parent node first with the namespace defined
112+ elem_plaintext = node_header + elem_plaintext + '</node>'
113+ doc = REXML ::Document . new ( elem_plaintext )
114+ doc . root [ 0 ]
115+ end
116+
85117 # @return [String|nil] Gets the ID attribute from the Logout Request. if exists.
86118 #
87119 def id
0 commit comments