Commit ec28fa9

mo <mo@mokhan.ca>
2017-12-14 16:39:23
disable signing and encryption key generation by default.
1 parent 77d1530
lib/saml/kit/bindings/http_redirect.rb
@@ -12,7 +12,7 @@ module Saml
           builder.sign = false
           builder.destination = location
           document = builder.build
-          [UrlBuilder.new.build(document, relay_state: relay_state), {}]
+          [UrlBuilder.new(configuration: builder.configuration).build(document, relay_state: relay_state), {}]
         end
 
         def deserialize(params)
lib/saml/kit/bindings/url_builder.rb
@@ -3,21 +3,25 @@ module Saml
     module Bindings
       class UrlBuilder
         include Serializable
+        attr_reader :configuration
 
-        def initialize(private_key: Saml::Kit.configuration.signing_private_key)
-          @private_key = private_key
+        def initialize(configuration: Saml::Kit.configuration)
+          @configuration = configuration
         end
 
         def build(saml_document, relay_state: nil)
           payload = canonicalize(saml_document, relay_state)
-          "#{saml_document.destination}?#{payload}&Signature=#{signature_for(payload)}"
+          if configuration.sign?
+            "#{saml_document.destination}?#{payload}&Signature=#{signature_for(payload)}"
+          else
+            "#{saml_document.destination}?#{payload}"
+          end
         end
 
         private
 
-        attr_reader :private_key
-
         def signature_for(payload)
+          private_key = configuration.signing_private_key
           encode(private_key.sign(OpenSSL::Digest::SHA256.new, payload))
         end
 
lib/saml/kit/builders/authentication_request.rb
@@ -3,17 +3,16 @@ module Saml
     module Builders
       class AuthenticationRequest
         include Saml::Kit::Templatable
-        attr_accessor :id, :now, :issuer, :assertion_consumer_service_url, :name_id_format, :sign, :destination
+        attr_accessor :id, :now, :issuer, :assertion_consumer_service_url, :name_id_format, :destination
         attr_accessor :version
         attr_reader :configuration
 
-        def initialize(configuration: Saml::Kit.configuration, sign: true)
+        def initialize(configuration: Saml::Kit.configuration)
           @configuration = configuration
           @id = Id.generate
           @issuer = configuration.issuer
           @name_id_format = Namespaces::PERSISTENT
           @now = Time.now.utc
-          @sign = sign
           @version = "2.0"
         end
 
lib/saml/kit/builders/identity_provider_metadata.rb
@@ -4,18 +4,17 @@ module Saml
       class IdentityProviderMetadata
         include Saml::Kit::Templatable
         attr_accessor :id, :organization_name, :organization_url, :contact_email, :entity_id, :attributes, :name_id_formats
-        attr_accessor :want_authn_requests_signed, :sign
+        attr_accessor :want_authn_requests_signed
         attr_reader :logout_urls, :single_sign_on_urls
         attr_reader :configuration
 
-        def initialize(configuration = Saml::Kit.configuration)
+        def initialize(configuration: Saml::Kit.configuration)
           @attributes = []
           @configuration = configuration
           @entity_id = configuration.issuer
           @id = Id.generate
           @logout_urls = []
           @name_id_formats = [Namespaces::PERSISTENT]
-          @sign = true
           @single_sign_on_urls = []
           @want_authn_requests_signed = true
         end
lib/saml/kit/builders/logout_request.rb
@@ -4,10 +4,10 @@ module Saml
       class LogoutRequest
         include Saml::Kit::Templatable
         attr_accessor :id, :destination, :issuer, :name_id_format, :now
-        attr_accessor :sign, :version
+        attr_accessor :version
         attr_reader :user, :configuration
 
-        def initialize(user, configuration: Saml::Kit.configuration, sign: true)
+        def initialize(user, configuration: Saml::Kit.configuration)
           @configuration = configuration
           @user = user
           @id = "_#{SecureRandom.uuid}"
@@ -15,7 +15,6 @@ module Saml
           @name_id_format = Saml::Kit::Namespaces::PERSISTENT
           @now = Time.now.utc
           @version = "2.0"
-          @sign = sign
         end
 
         def build
lib/saml/kit/builders/logout_response.rb
@@ -3,17 +3,16 @@ module Saml
     module Builders
       class LogoutResponse
         include Saml::Kit::Templatable
-        attr_accessor :id, :issuer, :version, :status_code, :sign, :now, :destination
+        attr_accessor :id, :issuer, :version, :status_code, :now, :destination
         attr_reader :request
         attr_reader :configuration
 
-        def initialize(user, request, configuration: Saml::Kit.configuration, sign: true)
+        def initialize(user, request, configuration: Saml::Kit.configuration)
           @configuration = configuration
           @id = Id.generate
           @issuer = configuration.issuer
           @now = Time.now.utc
           @request = request
-          @sign = sign
           @status_code = Namespaces::SUCCESS
           @user = user
           @version = "2.0"
lib/saml/kit/builders/response.rb
@@ -6,7 +6,7 @@ module Saml
         attr_reader :user, :request
         attr_accessor :id, :reference_id, :now
         attr_accessor :version, :status_code
-        attr_accessor :issuer, :sign, :destination, :encrypt
+        attr_accessor :issuer, :destination, :encrypt
         attr_reader :configuration
 
         def initialize(user, request, configuration: Saml::Kit.configuration)
@@ -27,11 +27,11 @@ module Saml
           request.provider.want_assertions_signed
         rescue => error
           Saml::Kit.logger.error(error)
-          true
+          nil
         end
 
         def build
-          Saml::Kit::Response.new(to_xml, request_id: request.id)
+          Saml::Kit::Response.new(to_xml, request_id: request.id, configuration: configuration)
         end
 
         private
lib/saml/kit/builders/service_provider_metadata.rb
@@ -3,19 +3,18 @@ module Saml
     module Builders
       class ServiceProviderMetadata
         include Saml::Kit::Templatable
-        attr_accessor :id, :entity_id, :acs_urls, :logout_urls, :name_id_formats, :sign
+        attr_accessor :id, :entity_id, :acs_urls, :logout_urls, :name_id_formats
         attr_accessor :organization_name, :organization_url, :contact_email
         attr_accessor :want_assertions_signed
         attr_reader :configuration
 
-        def initialize(configuration = Saml::Kit.configuration)
+        def initialize(configuration: Saml::Kit.configuration)
           @acs_urls = []
           @configuration = configuration
           @entity_id = configuration.issuer
           @id = Id.generate
           @logout_urls = []
           @name_id_formats = [Namespaces::PERSISTENT]
-          @sign = true
           @want_assertions_signed = true
         end
 
@@ -43,7 +42,7 @@ module Saml
 
         def descriptor_options
           {
-            AuthnRequestsSigned: sign,
+            AuthnRequestsSigned: sign?,
             WantAssertionsSigned: want_assertions_signed,
             protocolSupportEnumeration: Namespaces::PROTOCOL,
           }
lib/saml/kit/builders/xml_signature.rb
@@ -21,11 +21,10 @@ module Saml
         attr_reader :reference_id
         attr_reader :x509_certificate
 
-        def initialize(reference_id, configuration:, sign: true)
+        def initialize(reference_id, configuration:)
           @configuration = configuration
           @reference_id = reference_id
-          @sign = sign
-          @x509_certificate = configuration.certificates(use: :signing).last.stripped
+          @x509_certificate = configuration.certificates(use: :signing).sample.stripped
         end
 
         def signature_method
lib/saml/kit/assertion.rb
@@ -1,8 +1,9 @@
 module Saml
   module Kit
     class Assertion
-      def initialize(xml_hash)
+      def initialize(xml_hash, configuration: configuration)
         @xml_hash = xml_hash
+        @configuration = configuration
       end
 
       def name_id
@@ -53,7 +54,7 @@ module Saml
 
       def assertion
         if encrypted?
-          decrypted = XmlDecryption.new.decrypt(@xml_hash['Response']['EncryptedAssertion'])
+          decrypted = XmlDecryption.new(configuration: @configuration).decrypt(@xml_hash['Response']['EncryptedAssertion'])
           Saml::Kit.logger.debug(decrypted)
           Hash.from_xml(decrypted)['Assertion']
         else
lib/saml/kit/configuration.rb
@@ -12,9 +12,9 @@ module Saml
         @registry = DefaultRegistry.new
         @session_timeout = 3.hours
         @logger = Logger.new(STDOUT)
-
-        create_default_key_pair_for(use: :signing)
-        create_default_key_pair_for(use: :encryption)
+        #generate_key_pair_for(use: :signing)
+        #generate_key_pair_for(use: :encryption)
+        yield self if block_given?
       end
 
       def add_key_pair(certificate, private_key, password:, use: :signing)
@@ -24,6 +24,12 @@ module Saml
         })
       end
 
+      def generate_key_pair_for(use:)
+        private_key_password = SecureRandom.uuid
+        certificate_pem, private_key_pem = SelfSignedCertificate.new(private_key_password).create
+        add_key_pair(certificate_pem, private_key_pem, password: private_key_password, use: use)
+      end
+
       def certificates(use: nil)
         certificates = key_pairs.map { |x| x[:certificate] }
         use.present? ? certificates.find_all { |x| x.for?(use) } : certificates
@@ -45,17 +51,15 @@ module Saml
         private_keys(use: :encryption).last
       end
 
+      def sign?
+        certificates(use: :signing).any?
+      end
+
       private
 
       def key_pairs
         @key_pairs ||= []
       end
-
-      def create_default_key_pair_for(use:)
-        private_key_password = SecureRandom.uuid
-        certificate_pem, private_key_pem = SelfSignedCertificate.new(private_key_password).create
-        add_key_pair(certificate_pem, private_key_pem, password: private_key_password, use: use)
-      end
     end
   end
 end
lib/saml/kit/response.rb
@@ -9,8 +9,9 @@ module Saml
       validate :must_be_active_session
       validate :must_match_issuer
 
-      def initialize(xml, request_id: nil)
+      def initialize(xml, request_id: nil, configuration: Saml::Kit.configuration)
         @request_id = request_id
+        @configuration = configuration
         super(xml, name: "Response")
       end
 
@@ -23,7 +24,7 @@ module Saml
       end
 
       def assertion
-        @assertion = Saml::Kit::Assertion.new(to_h)
+        @assertion = Saml::Kit::Assertion.new(to_h, configuration: @configuration)
       end
 
       def signed?
lib/saml/kit/self_signed_certificate.rb
@@ -17,15 +17,6 @@ module Saml
         certificate.public_key = public_key
         certificate.serial = 0x0
         certificate.version = 2
-        factory = OpenSSL::X509::ExtensionFactory.new
-        factory.subject_certificate = factory.issuer_certificate = certificate
-        certificate.extensions = [
-          factory.create_extension("basicConstraints","CA:TRUE", true),
-          factory.create_extension("subjectKeyIdentifier", "hash"),
-        ]
-        certificate.add_extension(
-          factory.create_extension("authorityKeyIdentifier", "keyid:always,issuer:always")
-        )
         certificate.sign(rsa_key, OpenSSL::Digest::SHA256.new)
         [
           certificate.to_pem,
lib/saml/kit/signature.rb
@@ -13,8 +13,8 @@ module Saml
         Template.new(signatures.build(reference_id)).to_xml(xml: xml)
       end
 
-      def self.sign(sign: true, xml: ::Builder::XmlMarkup.new, configuration: Saml::Kit.configuration)
-        signatures = Saml::Kit::Signatures.new(configuration: configuration, sign: sign)
+      def self.sign(xml: ::Builder::XmlMarkup.new, configuration: Saml::Kit.configuration)
+        signatures = Saml::Kit::Signatures.new(configuration: configuration)
         yield xml, new(xml, signatures)
         signatures.complete(xml.target!)
       end
lib/saml/kit/signatures.rb
@@ -1,20 +1,19 @@
 module Saml
   module Kit
     class Signatures
-      attr_reader :sign, :configuration
+      attr_reader :configuration
 
-      def initialize(configuration:, sign: true)
+      def initialize(configuration:)
         @configuration = configuration
-        @sign = sign
       end
 
       def build(reference_id)
-        return nil unless sign
-        Saml::Kit::Builders::XmlSignature.new(reference_id, configuration: configuration, sign: sign)
+        return nil unless configuration.sign?
+        Saml::Kit::Builders::XmlSignature.new(reference_id, configuration: configuration)
       end
 
       def complete(raw_xml)
-        return raw_xml unless sign
+        return raw_xml unless configuration.sign?
         private_key = configuration.signing_private_key
         Xmldsig::SignedDocument.new(raw_xml).sign(private_key)
       end
lib/saml/kit/templatable.rb
@@ -1,17 +1,23 @@
 module Saml
   module Kit
     module Templatable
+      attr_accessor :sign
+
       def to_xml(xml: ::Builder::XmlMarkup.new)
         signatures.complete(render(self, xml: xml))
       end
 
       def signature_for(reference_id:, xml:)
-        return unless sign
+        return unless sign?
         render(signatures.build(reference_id), xml: xml)
       end
 
+      def sign?
+        sign.nil? ? configuration.sign? : sign && configuration.sign?
+      end
+
       def signatures
-        @signatures ||= Saml::Kit::Signatures.new(configuration: configuration, sign: sign)
+        @signatures ||= Saml::Kit::Signatures.new(configuration: configuration)
       end
 
       def encryption_for(xml:)
lib/saml/kit/xml_decryption.rb
@@ -3,8 +3,8 @@ module Saml
     class XmlDecryption
       attr_reader :private_key
 
-      def initialize(private_key = Saml::Kit.configuration.encryption_private_key)
-        @private_key = private_key
+      def initialize(configuration: Saml::Kit.configuration)
+        @private_key = configuration.encryption_private_key
       end
 
       def decrypt(data)
spec/saml/bindings/http_post_spec.rb
@@ -1,14 +1,37 @@
 require 'spec_helper'
 
 RSpec.describe Saml::Kit::Bindings::HttpPost do
-  let(:location) { FFaker::Internet.http_url }
+  let(:location) { FFaker::Internet.uri("https") }
   subject { described_class.new(location: location) }
 
+  describe "equality" do
+    it 'is referentially equal' do
+      expect(subject).to eql(subject)
+    end
+
+    it 'is equal by value' do
+      expect(subject).to eql(
+        Saml::Kit::Bindings::HttpPost.new(location: location)
+      )
+    end
+
+    it 'is not equal' do
+      expect(subject).to_not eql(
+        described_class.new(location: FFaker::Internet.uri("https"))
+      )
+    end
+  end
+
   describe "#serialize" do
     let(:relay_state) { "ECHO" }
+    let(:configuration) do
+      Saml::Kit::Configuration.new do |config|
+        config.generate_key_pair_for(use: :signing)
+      end
+    end
 
     it 'encodes the request using the HTTP-POST encoding for a AuthenticationRequest' do
-      builder = Saml::Kit::AuthenticationRequest.builder_class.new
+      builder = Saml::Kit::AuthenticationRequest.builder_class.new(configuration: configuration)
       url, saml_params = subject.serialize(builder, relay_state: relay_state)
 
       expect(url).to eql(location)
@@ -22,7 +45,7 @@ RSpec.describe Saml::Kit::Bindings::HttpPost do
 
     it 'returns a SAMLRequest for a LogoutRequest' do
       user = double(:user, name_id_for: SecureRandom.uuid)
-      builder = Saml::Kit::LogoutRequest.builder_class.new(user)
+      builder = Saml::Kit::LogoutRequest.builder_class.new(user, configuration: configuration)
       url, saml_params = subject.serialize(builder, relay_state: relay_state)
 
       expect(url).to eql(location)
@@ -37,7 +60,7 @@ RSpec.describe Saml::Kit::Bindings::HttpPost do
     it 'returns a SAMLResponse for a LogoutResponse' do
       user = double(:user, name_id_for: SecureRandom.uuid)
       request = instance_double(Saml::Kit::AuthenticationRequest, id: SecureRandom.uuid)
-      builder = Saml::Kit::LogoutResponse.builder_class.new(user, request)
+      builder = Saml::Kit::LogoutResponse.builder_class.new(user, request, configuration: configuration)
       url, saml_params = subject.serialize(builder, relay_state: relay_state)
 
       expect(url).to eql(location)
spec/saml/bindings/http_redirect_spec.rb
@@ -6,9 +6,14 @@ RSpec.describe Saml::Kit::Bindings::HttpRedirect do
 
   describe "#serialize" do
     let(:relay_state) { "ECHO" }
+    let(:configuration) do
+      Saml::Kit::Configuration.new do |config|
+        config.generate_key_pair_for(use: :signing)
+      end
+    end
 
     it 'encodes the request using the HTTP-Redirect encoding' do
-      builder = Saml::Kit::AuthenticationRequest.builder_class.new
+      builder = Saml::Kit::AuthenticationRequest.builder_class.new(configuration: configuration)
       url, _ = subject.serialize(builder, relay_state: relay_state)
       expect(url).to start_with(location)
       expect(url).to have_query_param('SAMLRequest')
spec/saml/bindings/url_builder_spec.rb
@@ -13,6 +13,13 @@ RSpec.describe Saml::Kit::Bindings::UrlBuilder do
       [Saml::Kit::LogoutResponse, 'SAMLResponse'],
     ].each do |(response_type, query_string_parameter)|
       describe response_type.to_s do
+        subject { described_class.new(configuration: configuration) }
+        let(:configuration) do
+          Saml::Kit::Configuration.new do |config|
+            config.generate_key_pair_for(use: :signing)
+          end
+        end
+
         let(:response) { instance_double(response_type, destination: destination, to_xml: xml, query_string_parameter: query_string_parameter) }
 
         def to_query_params(url)
@@ -54,7 +61,7 @@ RSpec.describe Saml::Kit::Bindings::UrlBuilder do
           payload = "#{query_string_parameter}=#{query_params[query_string_parameter]}"
           payload << "&RelayState=#{query_params['RelayState']}"
           payload << "&SigAlg=#{query_params['SigAlg']}"
-          expected_signature = Base64.strict_encode64(Saml::Kit.configuration.signing_private_key.sign(OpenSSL::Digest::SHA256.new, payload))
+          expected_signature = Base64.strict_encode64(configuration.signing_private_key.sign(OpenSSL::Digest::SHA256.new, payload))
           expect(query_params['Signature']).to eql(expected_signature)
         end
 
@@ -65,7 +72,7 @@ RSpec.describe Saml::Kit::Bindings::UrlBuilder do
 
           payload = "#{query_string_parameter}=#{query_params[query_string_parameter]}"
           payload << "&SigAlg=#{query_params['SigAlg']}"
-          expected_signature = Base64.strict_encode64(Saml::Kit.configuration.signing_private_key.sign(OpenSSL::Digest::SHA256.new, payload))
+          expected_signature = Base64.strict_encode64(configuration.signing_private_key.sign(OpenSSL::Digest::SHA256.new, payload))
           expect(query_params['Signature']).to eql(expected_signature)
         end
       end
spec/saml/builders/identity_provider_metadata_spec.rb
@@ -1,7 +1,13 @@
 require 'spec_helper'
 
 RSpec.describe Saml::Kit::Builders::IdentityProviderMetadata do
-  subject { described_class.new }
+  subject { described_class.new(configuration: configuration) }
+  let(:configuration) do
+    Saml::Kit::Configuration.new do |config|
+      config.generate_key_pair_for(use: :signing)
+      config.generate_key_pair_for(use: :encryption)
+    end
+  end
   let(:email) { FFaker::Internet.email }
   let(:org_name) { FFaker::Movie.title }
   let(:url) { FFaker::Internet.uri("https") }
@@ -38,7 +44,7 @@ RSpec.describe Saml::Kit::Builders::IdentityProviderMetadata do
     expect(result['EntityDescriptor']['IDPSSODescriptor']['SingleLogoutService']['Location']).to eql("https://www.example.com/logout")
     expect(result['EntityDescriptor']['IDPSSODescriptor']['Attribute']['Name']).to eql("id")
     certificates = result['EntityDescriptor']['IDPSSODescriptor']['KeyDescriptor'].map { |x| x['KeyInfo']['X509Data']['X509Certificate'] }
-    expected_certificates = Saml::Kit.configuration.certificates.map(&:stripped)
+    expected_certificates = configuration.certificates.map(&:stripped)
     expect(certificates).to match_array(expected_certificates)
     expect(result['EntityDescriptor']['Organization']['OrganizationName']).to eql(org_name)
     expect(result['EntityDescriptor']['Organization']['OrganizationDisplayName']).to eql(org_name)
spec/saml/builders/logout_request_spec.rb
@@ -1,9 +1,14 @@
 require 'spec_helper'
 
 RSpec.describe Saml::Kit::Builders::LogoutRequest do
-  subject { described_class.new(user) }
+  subject { described_class.new(user, configuration: configuration) }
   let(:user) { double(:user, name_id_for: name_id) }
   let(:name_id) { SecureRandom.uuid }
+  let(:configuration) do
+    Saml::Kit::Configuration.new do |config|
+      config.generate_key_pair_for(use: :signing)
+    end
+  end
 
   it 'produces the expected xml' do
     travel_to 1.second.from_now
spec/saml/builders/response_spec.rb
@@ -1,26 +1,28 @@
 require 'spec_helper'
 
 RSpec.describe Saml::Kit::Builders::Response do
-  subject { described_class.new(user, request) }
+  subject { described_class.new(user, request, configuration: configuration) }
+  let(:configuration) do
+    Saml::Kit::Configuration.new do |config|
+      config.issuer = issuer
+      config.generate_key_pair_for(use: :signing)
+      config.generate_key_pair_for(use: :encryption)
+    end
+  end
   let(:email) { FFaker::Internet.email }
   let(:assertion_consumer_service_url) { FFaker::Internet.uri("https") }
   let(:user) { double(:user, name_id_for: SecureRandom.uuid, assertion_attributes_for: { email: email, created_at: Time.now.utc.iso8601 }) }
   let(:request) { double(:request, id: Saml::Kit::Id.generate, assertion_consumer_service_url: assertion_consumer_service_url, issuer: issuer, name_id_format: Saml::Kit::Namespaces::EMAIL_ADDRESS, provider: provider, trusted?: true, signed?: true) }
-  let(:provider) { double(want_assertions_signed: false, encryption_certificates: [Saml::Kit::Certificate.new(encryption_pem, use: :encryption)]) }
-  let(:encryption_pem) { Saml::Kit.configuration.encryption_certificate.stripped }
+  let(:provider) { double(:provider, want_assertions_signed: false, encryption_certificates: [configuration.encryption_certificate] ) }
   let(:issuer) { FFaker::Internet.uri("https") }
 
-  before :each do
-    allow(Saml::Kit.configuration).to receive(:issuer).and_return(issuer)
-  end
-
   describe "#build" do
     it 'builds a response with the request_id' do
       expect(subject.build.request_id).to eql(request.id)
     end
 
     it 'builds a valid encrypted assertion' do
-      allow(Saml::Kit.configuration.registry).to receive(:metadata_for).with(issuer).and_return(provider)
+      allow(configuration.registry).to receive(:metadata_for).with(issuer).and_return(provider)
       allow(provider).to receive(:matches?).and_return(true)
 
       subject.sign = true
@@ -83,6 +85,7 @@ RSpec.describe Saml::Kit::Builders::Response do
       metadata = builder.build
       allow(request).to receive(:provider).and_return(metadata)
 
+      subject = described_class.new(user, request)
       hash = Hash.from_xml(subject.to_xml)
       expect(hash['Response']['Signature']).to be_nil
     end
@@ -92,7 +95,7 @@ RSpec.describe Saml::Kit::Builders::Response do
       result = Hash.from_xml(subject.to_xml)
       expect(result['Response']['EncryptedAssertion']).to be_present
       encrypted_assertion = result['Response']['EncryptedAssertion']
-      decrypted_assertion = Saml::Kit::XmlDecryption.new.decrypt(encrypted_assertion)
+      decrypted_assertion = Saml::Kit::XmlDecryption.new(configuration: configuration).decrypt(encrypted_assertion)
       decrypted_hash = Hash.from_xml(decrypted_assertion)
       expect(decrypted_hash['Assertion']).to be_present
       expect(decrypted_hash['Assertion']['Issuer']).to be_present
spec/saml/builders/service_provider_metadata_spec.rb
@@ -1,6 +1,13 @@
 require 'spec_helper'
 
 RSpec.describe Saml::Kit::Builders::ServiceProviderMetadata do
+  subject { described_class.new(configuration: configuration) }
+  let(:configuration) do
+    Saml::Kit::Configuration.new do |config|
+      config.generate_key_pair_for(use: :signing)
+      config.generate_key_pair_for(use: :encryption)
+    end
+  end
   let(:assertion_consumer_service_url) { FFaker::Internet.http_url }
   let(:email) { FFaker::Internet.email }
   let(:org_name) { FFaker::Movie.title }
@@ -37,7 +44,7 @@ RSpec.describe Saml::Kit::Builders::ServiceProviderMetadata do
     expect(result['EntityDescriptor']['SPSSODescriptor']['AssertionConsumerService']['index']).to eql('0')
     expect(result['EntityDescriptor']['Signature']).to be_present
     expect(result['EntityDescriptor']['SPSSODescriptor']['KeyDescriptor'].map { |x| x['use'] }).to match_array(['signing', 'encryption'])
-    expected_certificates = Saml::Kit.configuration.certificates.map(&:stripped)
+    expected_certificates = configuration.certificates.map(&:stripped)
     expect(result['EntityDescriptor']['SPSSODescriptor']['KeyDescriptor'].map { |x| x['KeyInfo']['X509Data']['X509Certificate'] }).to match_array(expected_certificates)
     expect(result['EntityDescriptor']['Organization']['OrganizationName']).to eql(org_name)
     expect(result['EntityDescriptor']['Organization']['OrganizationDisplayName']).to eql(org_name)
spec/saml/authentication_request_spec.rb
@@ -78,7 +78,9 @@ RSpec.describe Saml::Kit::AuthenticationRequest do
 
     it 'validates the schema of the request' do
       id = Saml::Kit::Id.generate
-      signed_xml = Saml::Kit::Signature.sign(sign: true) do |xml, signature|
+      configuration = Saml::Kit::Configuration.new
+      configuration.generate_key_pair_for(use: :signing)
+      signed_xml = Saml::Kit::Signature.sign(configuration: configuration) do |xml, signature|
         xml.tag!('samlp:AuthnRequest', "xmlns:samlp" => Saml::Kit::Namespaces::PROTOCOL, AssertionConsumerServiceURL: assertion_consumer_service_url, ID: id) do
           signature.template(id)
           xml.Fake do
spec/saml/certificate_spec.rb
@@ -1,7 +1,12 @@
 require 'spec_helper'
 
 RSpec.describe Saml::Kit::Certificate do
-  subject { Saml::Kit.configuration.certificates(use: :signing).last }
+  #subject { Saml::Kit.configuration.certificates(use: :signing).last }
+  subject { described_class.new(certificate, use: :signing) }
+  let(:certificate) do
+    cert, _ = Saml::Kit::SelfSignedCertificate.new('password').create
+    cert
+  end
 
   describe "#fingerprint" do
     it 'returns a fingerprint' do
spec/saml/http_post_spec.rb
@@ -1,26 +0,0 @@
-require 'spec_helper'
-
-RSpec.describe Saml::Kit::Bindings::HttpPost do
-  describe "equality" do
-    let(:location) { FFaker::Internet.uri("https") }
-    subject { Saml::Kit::Bindings::HttpPost.new(location: location) }
-
-    it 'is referentially equal' do
-      expect(subject).to eql(subject)
-    end
-
-    it 'is equal by value' do
-      expect(subject).to eql(
-        Saml::Kit::Bindings::HttpPost.new(location: location)
-      )
-    end
-
-    it 'is not equal' do
-      expect(subject).to_not eql(
-        Saml::Kit::Bindings::HttpPost.new(
-          location: FFaker::Internet.uri("https")
-        )
-      )
-    end
-  end
-end
spec/saml/logout_request_spec.rb
@@ -108,7 +108,9 @@ RSpec.describe Saml::Kit::LogoutRequest do
 
     it 'validates the schema of the request' do
       id = Saml::Kit::Id.generate
-      signed_xml = Saml::Kit::Signature.sign(sign: true) do |xml, signature|
+      configuration = Saml::Kit::Configuration.new
+      configuration.generate_key_pair_for(use: :signing)
+      signed_xml = Saml::Kit::Signature.sign(configuration: configuration) do |xml, signature|
         xml.LogoutRequest ID: id do
           signature.template(id)
           xml.Fake do
spec/saml/response_spec.rb
@@ -55,7 +55,9 @@ RSpec.describe Saml::Kit::Response do
       allow(registry).to receive(:metadata_for).and_return(metadata)
       allow(metadata).to receive(:matches?).and_return(true)
       id = Saml::Kit::Id.generate
-      signed_xml = Saml::Kit::Signature.sign(sign: true) do |xml, signature|
+      configuration = Saml::Kit::Configuration.new
+      configuration.generate_key_pair_for(use: :signing)
+      signed_xml = Saml::Kit::Signature.sign(configuration: configuration) do |xml, signature|
         xml.tag! "samlp:Response", "xmlns:samlp" => Saml::Kit::Namespaces::PROTOCOL, ID: id do
           signature.template(id)
           xml.Fake do
spec/saml/service_provider_metadata_spec.rb
@@ -113,7 +113,12 @@ RSpec.describe Saml::Kit::ServiceProviderMetadata do
   end
 
   describe "#matches?" do
-    subject { Saml::Kit::ServiceProviderMetadata.build }
+    let(:configuration) do
+      config = Saml::Kit::Configuration.new
+      config.generate_key_pair_for(use: :signing)
+      config
+    end
+    subject { Saml::Kit::ServiceProviderMetadata.build(configuration: configuration) }
 
     it 'returns true when the fingerprint matches one of the signing certificates' do
       certificate = Hash.from_xml(subject.to_xml)['EntityDescriptor']['Signature']['KeyInfo']['X509Data']['X509Certificate']
spec/saml/signature_spec.rb
@@ -30,7 +30,7 @@ RSpec.describe Saml::Kit::Signature do
       "xmlns:saml" => "urn:oasis:names:tc:SAML:2.0:assertion",
       ID: reference_id,
     }
-    signed_xml = described_class.sign(sign: true, configuration: configuration) do |xml, signature|
+    signed_xml = described_class.sign(configuration: configuration) do |xml, signature|
       xml.tag!('samlp:AuthnRequest', options) do
         signature.template(reference_id)
         xml.tag!('saml:Issuer', "MyEntityID")
@@ -57,7 +57,7 @@ RSpec.describe Saml::Kit::Signature do
   end
 
   it 'does not add a signature' do
-    signed_xml = described_class.sign(sign: false, configuration: configuration) do |xml, signature|
+    signed_xml = described_class.sign(configuration: Saml::Kit::Configuration.new) do |xml, signature|
       xml.AuthnRequest do
         signature.template(reference_id)
         xml.Issuer "MyEntityID"
spec/saml/xml_decryption_spec.rb
@@ -40,7 +40,7 @@ RSpec.describe Saml::Kit::XmlDecryption do
           }
         }
       }
-      subject = described_class.new(private_key)
+      subject = described_class.new(configuration: double(encryption_private_key: private_key))
       decrypted = subject.decrypt(data)
       expect(decrypted.strip).to eql(secret)
     end
spec/saml/xml_spec.rb
@@ -4,9 +4,14 @@ RSpec.describe Saml::Kit::Xml do
   describe "#valid_signature?" do
     let(:login_url) { "https://#{FFaker::Internet.domain_name}/login" }
     let(:logout_url) { "https://#{FFaker::Internet.domain_name}/logout" }
+    let(:configuration) do
+      configuration = Saml::Kit::Configuration.new
+      configuration.generate_key_pair_for(use: :signing)
+      configuration
+    end
 
     let(:signed_xml) do
-      Saml::Kit::ServiceProviderMetadata.build do |builder|
+      Saml::Kit::ServiceProviderMetadata.build(configuration: configuration) do |builder|
         builder.entity_id = FFaker::Movie.title
         builder.add_assertion_consumer_service(login_url, binding: :http_post)
         builder.add_assertion_consumer_service(login_url, binding: :http_redirect)