main
1# frozen_string_literal: true
2
3RSpec.describe Xml::Kit::KeyInfo do
4 subject { described_class.new }
5
6 describe '#to_xml' do
7 specify { expect(Hash.from_xml(subject.to_xml)).not_to be_empty }
8 specify { expect { subject.asymmetric_cipher }.to raise_error(/encryption_certificate is not specified/) }
9
10 context 'when using a DSA key' do
11 subject { described_class.new(x509: x509) }
12
13 let(:x509) do
14 certificate = OpenSSL::X509::Certificate.new
15 certificate.subject = certificate.issuer = OpenSSL::X509::Name.parse(Xml::Kit::SelfSignedCertificate::SUBJECT)
16 certificate.not_before = Time.now
17 certificate.not_after = certificate.not_before + 30 * 24 * 60 * 60
18 certificate.public_key = public_key
19 certificate.serial = 0x0
20 certificate.version = 2
21 certificate
22 end
23 let(:public_key) { private_key.public_key }
24 let(:private_key) { OpenSSL::PKey::DSA.new(2048) }
25
26 specify { expect { subject.asymmetric_cipher }.to raise_error(/OpenSSL::PKey::DSA is not supported/) }
27 end
28
29 context 'with encrypted key' do
30 let(:encrypted_key) { ::Xml::Kit::EncryptedKey.new(id: id, asymmetric_cipher: asymmetric_cipher, symmetric_cipher: symmetric_cipher) }
31 let(:symmetric_cipher) { ::Xml::Kit::Crypto::SymmetricCipher.new }
32 let(:asymmetric_cipher) { ::Xml::Kit::Crypto.cipher_for(algorithm, private_key.public_key) }
33 let(:algorithm) { ::Xml::Kit::Crypto::RsaCipher::ALGORITHM }
34 let(:id) { ::Xml::Kit::Id.generate }
35 let(:private_key) { OpenSSL::PKey::RSA.new(2048) }
36 let(:result) { Hash.from_xml(subject.to_xml) }
37
38 before do
39 subject.encrypted_key = encrypted_key
40 end
41
42 specify { expect(result['KeyInfo']['EncryptedKey']['EncryptionMethod']['Algorithm']).to eql(algorithm) }
43 specify { expect(private_key.private_decrypt(Base64.decode64(result['KeyInfo']['EncryptedKey']['CipherData']['CipherValue']))).to eql(symmetric_cipher.key) }
44 specify { expect(subject.symmetric_cipher).to eql(symmetric_cipher) }
45 specify { expect(subject.asymmetric_cipher).to eql(asymmetric_cipher) }
46 end
47
48 context 'with key name' do
49 let(:result) { Hash.from_xml(subject.to_xml) }
50
51 before do
52 subject.key_name = 'samlkey'
53 end
54
55 specify { expect(result['KeyInfo']['KeyName']).to eql('samlkey') }
56 end
57
58 context 'with key value' do
59 let(:result) { Hash.from_xml(subject.to_xml) }
60 let(:modulus) { 'xA7SEU+e0yQH5rm9kbCDN9o3aPIo7HbP7tX6WOocLZAtNfyxSZDU16ksL6WjubafOqNEpcwR3RdFsT7bCqnXPBe5ELh5u4VEy19MzxkXRgrMvavzyBpVRgBUwUlV5foK5hhmbktQhyNdy/6LpQRhDUDsTvK+g9Ucj47es9AQJ3U=' }
61 let(:exponent) { 'AQAB' }
62
63 before do
64 subject.key_value.rsa.modulus = modulus
65 subject.key_value.rsa.exponent = exponent
66 end
67
68 specify { expect(result['KeyInfo']['KeyValue']['RSAKeyValue']['Modulus']).to eql(modulus) }
69 specify { expect(result['KeyInfo']['KeyValue']['RSAKeyValue']['Exponent']).to eql(exponent) }
70 end
71
72 context 'with retrieval method' do
73 let(:result) { Hash.from_xml(subject.to_xml) }
74 let(:uri) { Xml::Kit::Id.generate }
75 let(:type) { 'http://www.w3.org/2001/04/xmlenc#EncryptedKey' }
76
77 before do
78 subject.retrieval_method.uri = uri
79 subject.retrieval_method.type = type
80 end
81
82 specify { expect(result['KeyInfo']['RetrievalMethod']).to be_present }
83 specify { expect(result['KeyInfo']['RetrievalMethod']['xmlns']).to eql(::Xml::Kit::Namespaces::XMLDSIG) }
84 specify { expect(result['KeyInfo']['RetrievalMethod']['URI']).to eql(uri) }
85 specify { expect(result['KeyInfo']['RetrievalMethod']['Type']).to eql(type) }
86 end
87
88 context 'with x509 data' do
89 let(:key_pair) { ::Xml::Kit::KeyPair.generate(use: :encryption) }
90 let(:x509_certificate) { key_pair.certificate.x509 }
91 let(:subject_key_identifier) { x509_certificate.extensions.find { |x| x.oid == 'subjectKeyIdentifier' }.value }
92
93 before do
94 subject.x509_data = x509_certificate
95 end
96
97 specify { expect(Hash.from_xml(subject.to_xml)['KeyInfo']['X509Data']['X509SKI']).to eql(Base64.strict_encode64(subject_key_identifier)) }
98 specify { expect(Hash.from_xml(subject.to_xml)['KeyInfo']['X509Data']['X509Certificate']).to eql(key_pair.certificate.stripped) }
99 specify { expect(subject.asymmetric_cipher.key.to_pem).to eql(x509_certificate.public_key.to_pem) }
100 end
101 end
102end