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