Commit 172a4ac
Changed files (6)
lib
saml
kit
spec
saml
lib/saml/kit/builders/response.rb
@@ -20,6 +20,7 @@ module Saml
@version = "2.0"
@status_code = Namespaces::SUCCESS
@issuer = configuration.entity_id
+ @encryption_certificate = request.try(:provider).try(:encryption_certificates).try(:last)
@encrypt = encryption_certificate.present?
@configuration = configuration
end
@@ -28,13 +29,6 @@ module Saml
Saml::Kit::Response.new(to_xml, request_id: request.id, configuration: configuration)
end
- def encryption_certificate
- request.provider.encryption_certificates.first
- rescue => error
- Saml::Kit.logger.error(error)
- nil
- end
-
def assertion
@assertion ||=
begin
lib/saml/kit/assertion.rb
@@ -9,12 +9,13 @@ module Saml
attr_reader :name
attr_accessor :occurred_at
- def initialize(node, configuration: Saml::Kit.configuration)
+ def initialize(node, configuration: Saml::Kit.configuration, private_keys: [])
@name = "Assertion"
@node = node
@xml_hash = hash_from(node)['Response'] || {}
@configuration = configuration
@occurred_at = Time.current
+ @private_keys = configuration.private_keys(use: :encryption) + private_keys
end
def issuer
@@ -79,14 +80,18 @@ module Saml
assertion.present?
end
+ def to_xml(pretty: false)
+ pretty ? @node.to_xml(indent: 2) : @node.to_s
+ end
+
private
attr_reader :configuration
+ attr_reader :private_keys
def assertion
@assertion ||=
if encrypted?
- private_keys = configuration.private_keys(use: :encryption)
decryptor = ::Xml::Kit::Decryption.new(private_keys: private_keys)
decrypted = decryptor.decrypt_hash(@xml_hash['EncryptedAssertion'])
Saml::Kit.logger.debug(decrypted)
lib/saml/kit/configuration.rb
@@ -85,7 +85,7 @@ module Saml
# Return each private for a specific use.
#
# @param use [Symbol] the type of key pair to return `nil`, `:signing` or `:encryption`
- def private_keys(use: :signing)
+ def private_keys(use: nil)
key_pairs(use: use).flat_map(&:private_key)
end
lib/saml/kit/response.rb
@@ -15,16 +15,14 @@ module Saml
super(xml, name: "Response", configuration: configuration)
end
- def assertion
- @assertion ||=
+ def assertion(private_keys = configuration.private_keys(use: :encryption))
+ @assertion ||=
begin
- node = at_xpath(
- [
- '/samlp:Response/saml:Assertion',
- '/samlp:Response/saml:EncryptedAssertion'
- ].join('|')
- )
- Saml::Kit::Assertion.new(node, configuration: @configuration)
+ node = at_xpath([
+ '/samlp:Response/saml:Assertion',
+ '/samlp:Response/saml:EncryptedAssertion'
+ ].join('|'))
+ Saml::Kit::Assertion.new(node, configuration: @configuration, private_keys: private_keys)
end
end
lib/saml/kit/xml_templatable.rb
@@ -16,6 +16,11 @@ module Saml
(embed_signature && @signing_key_pair.present?)
end
+ def encrypt_with(key_pair)
+ self.encrypt = true
+ self.encryption_certificate = key_pair.certificate
+ end
+
def digest_method
configuration.digest_method
end
spec/saml/assertion_spec.rb
@@ -111,4 +111,19 @@ XML
expect(subject).to be_present
end
end
+
+ describe "#signed?" do
+ let(:request) { instance_double(Saml::Kit::AuthenticationRequest, id: ::Xml::Kit::Id.generate, issuer: FFaker::Internet.http_url, assertion_consumer_service_url: FFaker::Internet.http_url, name_id_format: Saml::Kit::Namespaces::PERSISTENT, provider: nil, signed?: true, trusted?: true) }
+ let(:user) { double(:user, name_id_for: SecureRandom.uuid, assertion_attributes_for: { id: SecureRandom.uuid }) }
+
+ it 'detects a signature in an encrypted assertion' do
+ encryption_key_pair = Xml::Kit::KeyPair.generate(use: :encryption)
+ response = Saml::Kit::Response.build(user, request) do |x|
+ x.sign_with(Xml::Kit::KeyPair.generate(use: :signing))
+ x.encrypt_with(encryption_key_pair)
+ end
+ subject = response.assertion([encryption_key_pair.private_key])
+ expect(subject).to be_signed
+ end
+ end
end