Skip to content

Commit 9bb26bd

Browse files
committed
Only takes the first reference node in the document to verify the signature. As per the SAML specification, a signature can only have one reference node. (5.4.2 References)
1 parent 1fa804d commit 9bb26bd

File tree

1 file changed

+28
-29
lines changed

1 file changed

+28
-29
lines changed

lib/xml_security.rb

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -286,35 +286,34 @@ def validate_signature(base64_cert, soft = true)
286286
inclusive_namespaces = extract_inclusive_namespaces
287287

288288
# check digests
289-
REXML::XPath.each(sig_element, "//ds:Reference", {"ds"=>DSIG}) do |ref|
290-
uri = ref.attributes.get_attribute("URI").value
291-
292-
hashed_element = uri.empty? ? document : document.at_xpath("//*[@ID=$uri]", nil, { 'uri' => uri[1..-1] })
293-
# hashed_element = document.at_xpath("//*[@ID=$uri]", nil, { 'uri' => uri[1..-1] })
294-
canon_algorithm = canon_algorithm REXML::XPath.first(
295-
ref,
296-
'//ds:CanonicalizationMethod',
297-
{ "ds" => DSIG }
298-
)
299-
canon_hashed_element = hashed_element.canonicalize(canon_algorithm, inclusive_namespaces)
300-
301-
digest_algorithm = algorithm(REXML::XPath.first(
302-
ref,
303-
"//ds:DigestMethod",
304-
{ "ds" => DSIG }
305-
))
306-
hash = digest_algorithm.digest(canon_hashed_element)
307-
encoded_digest_value = REXML::XPath.first(
308-
ref,
309-
"//ds:DigestValue",
310-
{ "ds" => DSIG }
311-
).text
312-
digest_value = Base64.decode64(encoded_digest_value)
313-
314-
unless digests_match?(hash, digest_value)
315-
@errors << "Digest mismatch"
316-
return soft ? false : (raise OneLogin::RubySaml::ValidationError.new("Digest mismatch"))
317-
end
289+
ref = REXML::XPath.first(sig_element, "//ds:Reference", {"ds"=>DSIG})
290+
uri = ref.attributes.get_attribute("URI").value
291+
292+
hashed_element = uri.empty? ? document : document.at_xpath("//*[@ID=$uri]", nil, { 'uri' => uri[1..-1] })
293+
# hashed_element = document.at_xpath("//*[@ID=$uri]", nil, { 'uri' => uri[1..-1] })
294+
canon_algorithm = canon_algorithm REXML::XPath.first(
295+
ref,
296+
'//ds:CanonicalizationMethod',
297+
{ "ds" => DSIG }
298+
)
299+
canon_hashed_element = hashed_element.canonicalize(canon_algorithm, inclusive_namespaces)
300+
301+
digest_algorithm = algorithm(REXML::XPath.first(
302+
ref,
303+
"//ds:DigestMethod",
304+
{ "ds" => DSIG }
305+
))
306+
hash = digest_algorithm.digest(canon_hashed_element)
307+
encoded_digest_value = REXML::XPath.first(
308+
ref,
309+
"//ds:DigestValue",
310+
{ "ds" => DSIG }
311+
).text
312+
digest_value = Base64.decode64(encoded_digest_value)
313+
314+
unless digests_match?(hash, digest_value)
315+
@errors << "Digest mismatch"
316+
return soft ? false : (raise OneLogin::RubySaml::ValidationError.new("Digest mismatch"))
318317
end
319318

320319
# get certificate object

0 commit comments

Comments
 (0)