Skip to content

Commit

Permalink
Only takes the first reference node in the document to verify the sig…
Browse files Browse the repository at this point in the history
…nature. As per the SAML specification, a signature can only have one reference node. (5.4.2 References)
  • Loading branch information
levelboy committed Oct 29, 2015
1 parent 1fa804d commit 9bb26bd
Showing 1 changed file with 28 additions and 29 deletions.
57 changes: 28 additions & 29 deletions lib/xml_security.rb
Original file line number Diff line number Diff line change
Expand Up @@ -286,35 +286,34 @@ def validate_signature(base64_cert, soft = true)
inclusive_namespaces = extract_inclusive_namespaces

# check digests
REXML::XPath.each(sig_element, "//ds:Reference", {"ds"=>DSIG}) do |ref|
uri = ref.attributes.get_attribute("URI").value

hashed_element = uri.empty? ? document : document.at_xpath("//*[@ID=$uri]", nil, { 'uri' => uri[1..-1] })
# hashed_element = document.at_xpath("//*[@ID=$uri]", nil, { 'uri' => uri[1..-1] })
canon_algorithm = canon_algorithm REXML::XPath.first(
ref,
'//ds:CanonicalizationMethod',
{ "ds" => DSIG }
)
canon_hashed_element = hashed_element.canonicalize(canon_algorithm, inclusive_namespaces)

digest_algorithm = algorithm(REXML::XPath.first(
ref,
"//ds:DigestMethod",
{ "ds" => DSIG }
))
hash = digest_algorithm.digest(canon_hashed_element)
encoded_digest_value = REXML::XPath.first(
ref,
"//ds:DigestValue",
{ "ds" => DSIG }
).text
digest_value = Base64.decode64(encoded_digest_value)

unless digests_match?(hash, digest_value)
@errors << "Digest mismatch"
return soft ? false : (raise OneLogin::RubySaml::ValidationError.new("Digest mismatch"))
end
ref = REXML::XPath.first(sig_element, "//ds:Reference", {"ds"=>DSIG})
uri = ref.attributes.get_attribute("URI").value

hashed_element = uri.empty? ? document : document.at_xpath("//*[@ID=$uri]", nil, { 'uri' => uri[1..-1] })
# hashed_element = document.at_xpath("//*[@ID=$uri]", nil, { 'uri' => uri[1..-1] })
canon_algorithm = canon_algorithm REXML::XPath.first(
ref,
'//ds:CanonicalizationMethod',
{ "ds" => DSIG }
)
canon_hashed_element = hashed_element.canonicalize(canon_algorithm, inclusive_namespaces)

digest_algorithm = algorithm(REXML::XPath.first(
ref,
"//ds:DigestMethod",
{ "ds" => DSIG }
))
hash = digest_algorithm.digest(canon_hashed_element)
encoded_digest_value = REXML::XPath.first(
ref,
"//ds:DigestValue",
{ "ds" => DSIG }
).text
digest_value = Base64.decode64(encoded_digest_value)

unless digests_match?(hash, digest_value)
@errors << "Digest mismatch"
return soft ? false : (raise OneLogin::RubySaml::ValidationError.new("Digest mismatch"))
end

# get certificate object
Expand Down

0 comments on commit 9bb26bd

Please sign in to comment.