Skip to content

Commit

Permalink
Validate an idp fingerprint using a configurable method.
Browse files Browse the repository at this point in the history
  • Loading branch information
bpedro committed Oct 12, 2014
1 parent ce20514 commit de18afd
Showing 1 changed file with 22 additions and 0 deletions.
22 changes: 22 additions & 0 deletions lib/omniauth/strategies/saml.rb
Expand Up @@ -29,6 +29,16 @@ def callback_phase
raise OmniAuth::Strategies::SAML::ValidationError.new("SAML response missing")
end

# Call a fingerprint validation method if there's one
if options.idp_cert_fingerprint_validate_method
fingerprint_exists = eval(options.idp_cert_fingerprint_validate_method << '(\'' << response_fingerprint << '\')')
unless fingerprint_exists
raise OmniAuth::Strategies::SAML::ValidationError.new("Non-existent fingerprint")
end
# id_cert_fingerprint becomes the given fingerprint if it exists
options.idp_cert_fingerprint = fingerprint_exists
end

response = Onelogin::Saml::Response.new(request.params['SAMLResponse'], options)
response.settings = Onelogin::Saml::Settings.new(options)

Expand All @@ -48,6 +58,18 @@ def callback_phase
fail!(:invalid_ticket, $!)
end

# Obtain an idp certificate fingerprint from the response.
def response_fingerprint
response = request.params['SAMLResponse']
response = (response =~ /^</) ? response : Base64.decode64(response)
document = XMLSecurity::SignedDocument::new(response)
cert_element = REXML::XPath.first(document, "//ds:X509Certificate", { "ds"=> 'http://www.w3.org/2000/09/xmldsig#' })
base64_cert = cert_element.text
cert_text = Base64.decode64(base64_cert)
cert = OpenSSL::X509::Certificate.new(cert_text)
Digest::SHA1.hexdigest(cert.to_der).upcase.scan(/../).join(':')
end

def other_phase
if on_path?("#{request_path}/metadata")
# omniauth does not set the strategy on the other_phase
Expand Down

0 comments on commit de18afd

Please sign in to comment.