def validate_doc(base64_cert, soft = true)
inclusive_namespaces = []
inclusive_namespace_element = REXML::XPath.first(self, "//ec:InclusiveNamespaces")
if inclusive_namespace_element
prefix_list = inclusive_namespace_element.attributes.get_attribute('PrefixList').value
inclusive_namespaces = prefix_list.split(" ")
end
sig_element = REXML::XPath.first(self, "//ds:Signature", {"ds"=>"http://www.w3.org/2000/09/xmldsig#"})
sig_element.remove
REXML::XPath.each(sig_element, "//ds:Reference", {"ds"=>"http://www.w3.org/2000/09/xmldsig#"}) do |ref|
uri = ref.attributes.get_attribute("URI").value
hashed_element = REXML::XPath.first(self, "//[@ID='#{uri[1,uri.size]}']")
canoner = XML::Util::XmlCanonicalizer.new(false, true)
canoner.inclusive_namespaces = inclusive_namespaces if canoner.respond_to?(:inclusive_namespaces) && !inclusive_namespaces.empty?
canon_hashed_element = canoner.canonicalize(hashed_element)
hash = Base64.encode64(Digest::SHA1.digest(canon_hashed_element)).chomp
digest_value = REXML::XPath.first(ref, "//ds:DigestValue", {"ds"=>"http://www.w3.org/2000/09/xmldsig#"}).text
if hash != digest_value
return soft ? false : (raise OmniAuth::Strategies::SAML::ValidationError.new("Digest mismatch"))
end
end
canoner = XML::Util::XmlCanonicalizer.new(false, true)
signed_info_element = REXML::XPath.first(sig_element, "//ds:SignedInfo", {"ds"=>"http://www.w3.org/2000/09/xmldsig#"})
canon_string = canoner.canonicalize(signed_info_element)
base64_signature = REXML::XPath.first(sig_element, "//ds:SignatureValue", {"ds"=>"http://www.w3.org/2000/09/xmldsig#"}).text
signature = Base64.decode64(base64_signature)
cert_text = Base64.decode64(base64_cert)
cert = OpenSSL::X509::Certificate.new(cert_text)
if !cert.public_key.verify(OpenSSL::Digest::SHA1.new, signature, canon_string)
return soft ? false : (raise OmniAuth::Strategies::SAML::ValidationError.new("Key validation error"))
end
return true
end