# File lib/omniauth/strategies/saml/xml_security.rb, line 64
          def validate_doc(base64_cert, soft = true)
            # validate references

            # check for inclusive namespaces

            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

            # remove signature node
            sig_element = REXML::XPath.first(self, "//ds:Signature", {"ds"=>"http://www.w3.org/2000/09/xmldsig#"})
            sig_element.remove

            # check digests
            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

            # verify signature
            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)

            # get certificate object
            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