Commit 1131f36

mo <mo@mokhan.ca>
2017-12-13 21:06:53
allow adding multiple signing certificates.
1 parent bdfc930
lib/saml/kit/builders/templates/identity_provider_metadata.builder
@@ -2,8 +2,8 @@ xml.instruct!
 xml.EntityDescriptor entity_descriptor_options do
   signature_for(reference_id: id, xml: xml)
   xml.IDPSSODescriptor idp_sso_descriptor_options do
-    if configuration.signing_certificate_pem.present?
-      render configuration.signing_certificate, xml: xml
+    configuration.certificates(use: :signing).each do |certificate|
+      render certificate, xml: xml
     end
     if configuration.encryption_certificate_pem.present?
       render configuration.encryption_certificate, xml: xml
lib/saml/kit/builders/templates/service_provider_metadata.builder
@@ -2,8 +2,8 @@ xml.instruct!
 xml.EntityDescriptor entity_descriptor_options do
   signature_for(reference_id: id, xml: xml)
   xml.SPSSODescriptor descriptor_options do
-    if configuration.signing_certificate_pem.present?
-      render configuration.signing_certificate, xml: xml
+    configuration.certificates(use: :signing).each do |certificate|
+      render certificate, xml: xml
     end
     if configuration.encryption_certificate_pem.present?
       render configuration.encryption_certificate, xml: xml
lib/saml/kit/configuration.rb
@@ -3,7 +3,6 @@ module Saml
     class Configuration
       attr_accessor :issuer
       attr_accessor :signature_method, :digest_method
-      attr_accessor :signing_certificate_pem, :signing_private_key_pem, :signing_private_key_password
       attr_accessor :encryption_certificate_pem, :encryption_private_key_pem, :encryption_private_key_password
       attr_accessor :registry, :session_timeout
       attr_accessor :logger
@@ -11,17 +10,33 @@ module Saml
       def initialize
         @signature_method = :SHA256
         @digest_method = :SHA256
-        @signing_private_key_password = SecureRandom.uuid
+        signing_private_key_password = SecureRandom.uuid
         @encryption_private_key_password = SecureRandom.uuid
-        @signing_certificate_pem, @signing_private_key_pem = SelfSignedCertificate.new(@signing_private_key_password).create
+        signing_certificate_pem, signing_private_key_pem = SelfSignedCertificate.new(signing_private_key_password).create
+        add_key_pair(signing_certificate_pem, signing_private_key_pem, password: signing_private_key_password, use: :signing)
         @encryption_certificate_pem, @encryption_private_key_pem = SelfSignedCertificate.new(@encryption_private_key_password).create
         @registry = DefaultRegistry.new
         @session_timeout = 3.hours
         @logger = Logger.new(STDOUT)
       end
 
+      def add_key_pair(certificate, private_key, password:, use: :signing)
+        key_pairs.push({
+          certificate: Saml::Kit::Certificate.new(certificate, use: use),
+          private_key: OpenSSL::PKey::RSA.new(private_key, password)
+        })
+      end
+
+      def certificates(use: :signing)
+        key_pairs.map { |x| x[:certificate] }.find_all { |x| x.for?(use) }
+      end
+
+      def private_keys(use: :signing)
+        key_pairs.find_all { |x| x[:certificate].for?(use) }.map { |x| x[:private_key] }
+      end
+
       def signing_certificate
-        Saml::Kit::Certificate.new(signing_certificate_pem, use: :signing)
+        certificates(use: :signing).last
       end
 
       def encryption_certificate
@@ -29,12 +44,18 @@ module Saml
       end
 
       def signing_private_key
-        OpenSSL::PKey::RSA.new(signing_private_key_pem, signing_private_key_password)
+        private_keys(use: :signing).last
       end
 
       def encryption_private_key
         OpenSSL::PKey::RSA.new(encryption_private_key_pem, encryption_private_key_password)
       end
+
+      private
+
+      def key_pairs
+        @key_pairs ||= []
+      end
     end
   end
 end
spec/saml/signature_spec.rb
@@ -3,9 +3,7 @@ require "spec_helper"
 RSpec.describe Saml::Kit::Signature do
   let(:configuration) do
     config = Saml::Kit::Configuration.new
-    config.signing_certificate_pem = certificate
-    config.signing_private_key_pem = private_key
-    config.signing_private_key_password = password
+    config.add_key_pair(certificate, private_key, password: password, use: :signing)
     config
   end
 
@@ -20,10 +18,6 @@ RSpec.describe Saml::Kit::Signature do
     x.public_key = public_key
     x.serial = 0x0
     x.version = 2
-    factory = OpenSSL::X509::ExtensionFactory.new
-    factory.subject_certificate = factory.issuer_certificate = x
-    x.extensions = [ factory.create_extension("basicConstraints","CA:TRUE", true), factory.create_extension("subjectKeyIdentifier", "hash"), ]
-    x.add_extension(factory.create_extension("authorityKeyIdentifier", "keyid:always,issuer:always"))
     x.sign(rsa_key, OpenSSL::Digest::SHA256.new)
     x.to_pem
   end