main
  1# frozen_string_literal: true
  2
  3RSpec.describe Saml::Kit::Configuration do
  4  describe '#generate_key_pair_for' do
  5    subject { described_class.new }
  6
  7    it 'raises an error when the use is not known' do
  8      expect do
  9        subject.generate_key_pair_for(use: :blah)
 10      end.to raise_error(/:signing or :encryption/)
 11    end
 12
 13    it 'generates a signing key pair' do
 14      subject.generate_key_pair_for(use: :signing)
 15      expect(subject.key_pairs(use: :signing).count).to be(1)
 16    end
 17
 18    it 'generates an encryption key pair' do
 19      subject.generate_key_pair_for(use: :encryption)
 20      expect(subject.key_pairs(use: :encryption).count).to be(1)
 21    end
 22  end
 23
 24  describe '#add_key_pair' do
 25    subject { described_class.new }
 26
 27    let(:active_certificate) do
 28      certificate = OpenSSL::X509::Certificate.new
 29      certificate.not_before = 1.minute.ago
 30      certificate.not_after = 1.minute.from_now
 31      certificate.public_key = private_key.public_key
 32      certificate.sign(private_key, OpenSSL::Digest::SHA256.new)
 33      certificate
 34    end
 35    let(:expired_certificate) do
 36      certificate = OpenSSL::X509::Certificate.new
 37      certificate.not_before = 2.minutes.ago
 38      certificate.not_after = 1.minute.ago
 39      certificate.public_key = private_key.public_key
 40      certificate.sign(private_key, OpenSSL::Digest::SHA256.new)
 41      certificate
 42    end
 43    let(:unsigned_certificate) do
 44      certificate = OpenSSL::X509::Certificate.new
 45      certificate.not_before = 2.minutes.ago
 46      certificate.not_after = 1.minute.ago
 47      certificate.public_key = private_key.public_key
 48      certificate
 49    end
 50    let(:private_key) { OpenSSL::PKey::RSA.new(2048) }
 51
 52    context 'when the use is not known' do
 53      specify { expect { subject.add_key_pair(active_certificate, private_key.export, use: :blah) }.to raise_error(/:signing or :encryption/) }
 54    end
 55
 56    context 'when adding a signing key pair' do
 57      before do
 58        subject.add_key_pair(active_certificate.to_pem, private_key.export, use: :signing)
 59        subject.add_key_pair(expired_certificate.to_pem, private_key.export, use: :signing)
 60        if Gem::Version.new('3.1.0') > Gem::Version.new(RUBY_VERSION)
 61          subject.add_key_pair(unsigned_certificate.to_pem, private_key.export, use: :signing)
 62        end
 63      end
 64
 65      specify do
 66        expect(subject.key_pairs(use: :signing).map(&:certificate).map(&:fingerprint).map(&:to_s)).to match_array([
 67          Xml::Kit::Fingerprint.new(active_certificate.to_pem).to_s
 68        ])
 69      end
 70    end
 71
 72    context 'when adding an encryption key pair' do
 73      before do
 74        subject.add_key_pair(active_certificate.to_pem, private_key.export, use: :encryption)
 75        subject.add_key_pair(expired_certificate.to_pem, private_key.export, use: :encryption)
 76        if Gem::Version.new('3.1.0') > Gem::Version.new(RUBY_VERSION)
 77          subject.add_key_pair(unsigned_certificate.to_pem, private_key.export, use: :encryption)
 78        end
 79      end
 80
 81      specify do
 82        expect(subject.key_pairs(use: :encryption).map(&:certificate).map(&:fingerprint).map(&:to_s)).to match_array([
 83          Xml::Kit::Fingerprint.new(active_certificate.to_pem).to_s
 84        ])
 85      end
 86    end
 87  end
 88
 89  describe '#key_pairs' do
 90    context 'when a certificate expires' do
 91      let(:active_certificate) do
 92        certificate = OpenSSL::X509::Certificate.new
 93        certificate.not_before = 1.minute.ago
 94        certificate.not_after = 1.minute.from_now
 95        certificate.public_key = private_key.public_key
 96        certificate.sign(private_key, OpenSSL::Digest::SHA256.new)
 97        certificate
 98      end
 99      let(:expired_certificate) do
100        certificate = OpenSSL::X509::Certificate.new
101        certificate.not_before = 2.minutes.ago
102        certificate.not_after = 1.minute.ago
103        certificate.public_key = private_key.public_key
104        certificate.sign(private_key, OpenSSL::Digest::SHA256.new)
105        certificate
106      end
107      let(:unsigned_certificate) do
108        certificate = OpenSSL::X509::Certificate.new
109        certificate.not_before = 2.minutes.ago
110        certificate.not_after = 1.minute.ago
111        certificate.public_key = private_key.public_key
112        certificate
113      end
114      let(:private_key) { OpenSSL::PKey::RSA.new(2048) }
115
116      before do
117        subject.add_key_pair(active_certificate.to_pem, private_key.export, use: :signing)
118        subject.add_key_pair(expired_certificate.to_pem, private_key.export, use: :signing)
119        if Gem::Version.new('3.1.0') > Gem::Version.new(RUBY_VERSION)
120          subject.add_key_pair(unsigned_certificate.to_pem, private_key.export, use: :signing)
121        end
122      end
123
124      specify { expect(subject.key_pairs.count).to be(1) }
125      specify { expect(subject.key_pairs.map(&:certificate).map(&:fingerprint).map(&:to_s)).to match_array([Xml::Kit::Fingerprint.new(active_certificate).to_s]) }
126    end
127
128    context 'when there is more than one key pair' do
129      let(:oldest_certificate) do
130        certificate = OpenSSL::X509::Certificate.new
131        certificate.not_before = 45.minutes.ago
132        certificate.not_after = 15.minutes.from_now
133        certificate.public_key = private_key.public_key
134        certificate.sign(private_key, OpenSSL::Digest::SHA256.new)
135        certificate
136      end
137      let(:newest_certificate) do
138        certificate = OpenSSL::X509::Certificate.new
139        certificate.not_before = 30.minutes.ago
140        certificate.not_after = 30.minutes.from_now
141        certificate.public_key = private_key.public_key
142        certificate.sign(private_key, OpenSSL::Digest::SHA256.new)
143        certificate
144      end
145      let(:private_key) { OpenSSL::PKey::RSA.new(2048) }
146      let(:fingerprints) { subject.key_pairs.map(&:certificate).map(&:fingerprint).map(&:to_s) }
147
148      before do
149        subject.add_key_pair(oldest_certificate.to_pem, private_key.export, use: :signing)
150        subject.add_key_pair(newest_certificate.to_pem, private_key.export, use: :signing)
151      end
152
153      specify { expect(fingerprints[0]).to eql(Xml::Kit::Fingerprint.new(newest_certificate).to_s) }
154      specify { expect(fingerprints[1]).to eql(Xml::Kit::Fingerprint.new(oldest_certificate).to_s) }
155    end
156  end
157end