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