Commit 70ed388

mokha <mo@mokhan.ca>
2019-01-25 22:58:37
extract encrypted data class
1 parent 7891f1e
lib/xml/kit/templates/encrypted_data.builder
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+xml.EncryptedData xmlns: ::Xml::Kit::Namespaces::XMLENC do
+  xml.EncryptionMethod Algorithm: symmetric_cipher.algorithm
+  render key_info, xml: xml
+  xml.CipherData do
+    xml.CipherValue symmetric_cipher_value
+  end
+end
lib/xml/kit/encrypted_data.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+module Xml
+  module Kit
+    class EncryptedData
+      attr_reader :key_info
+      attr_reader :symmetric_cipher
+      attr_reader :symmetric_cipher_value
+
+      def initialize(
+        raw_xml,
+        symmetric_cipher:,
+        asymmetric_cipher:,
+        key_info: nil
+      )
+        @symmetric_cipher = symmetric_cipher
+        @symmetric_cipher_value = Base64.strict_encode64(symmetric_cipher.encrypt(raw_xml))
+        @key_info = key_info || create_key_info_for(symmetric_cipher, asymmetric_cipher)
+      end
+
+      def to_xml(xml: ::Builder::XmlMarkup.new)
+        ::Xml::Kit::Template.new(self).to_xml(xml: xml)
+      end
+
+      def render(model, options)
+        ::Xml::Kit::Template.new(model).to_xml(options)
+      end
+
+      private
+
+      def create_key_info_for(symmetric_cipher, asymmetric_cipher)
+        KeyInfo.new do |x|
+          x.encrypted_key = EncryptedKey.new(asymmetric_cipher: asymmetric_cipher, symmetric_cipher: symmetric_cipher)
+        end
+      end
+    end
+  end
+end
lib/xml/kit/templatable.rb
@@ -41,11 +41,10 @@ module Xml
 
         temp = ::Builder::XmlMarkup.new
         yield temp
-        ::Xml::Kit::Encryption.new(
+        ::Xml::Kit::EncryptedData.new(
           signatures.complete(temp.target!),
-          encryption_certificate.public_key,
-          symmetric_algorithm: symmetric_cipher,
-          asymmetric_algorithm: asymmetric_cipher,
+          symmetric_cipher: symmetric_cipher,
+          asymmetric_cipher: asymmetric_cipher,
           key_info: key_info
         ).to_xml(xml: xml)
       end
lib/xml/kit.rb
@@ -19,6 +19,7 @@ require 'xml/kit/crypto'
 require 'xml/kit/decryption'
 require 'xml/kit/decryption_error'
 require 'xml/kit/document'
+require 'xml/kit/encrypted_data'
 require 'xml/kit/encrypted_key'
 require 'xml/kit/encryption'
 require 'xml/kit/fingerprint'
spec/xml/kit/encrypted_data_spec.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+RSpec.describe Xml::Kit::EncryptedData do
+  describe '#to_xml' do
+    [
+      ::Xml::Kit::Crypto::RsaCipher::ALGORITHM,
+      ::Xml::Kit::Crypto::OaepCipher::ALGORITHM,
+    ].each do |asymmetric_algorithm|
+      [
+        "#{::Xml::Kit::Namespaces::XMLENC}tripledes-cbc",
+        "#{::Xml::Kit::Namespaces::XMLENC}aes128-cbc",
+        "#{::Xml::Kit::Namespaces::XMLENC}aes192-cbc",
+        "#{::Xml::Kit::Namespaces::XMLENC}aes256-cbc",
+      ].each do |symmetric_algorithm|
+        describe symmetric_algorithm do
+          subject do
+            described_class.new(xml, symmetric_cipher: symmetric_cipher, asymmetric_cipher: asymmetric_cipher)
+          end
+
+          let(:symmetric_cipher) { ::Xml::Kit::Crypto::SymmetricCipher.new(symmetric_algorithm) }
+          let(:asymmetric_cipher) { ::Xml::Kit::Crypto.cipher_for(asymmetric_algorithm, key_pair.public_key) }
+          let(:key_pair) { Xml::Kit::KeyPair.generate(use: :encryption, algorithm: symmetric_algorithm) }
+          let(:decryptor) { Xml::Kit::Decryption.new(private_keys: [key_pair.private_key]) }
+          let(:xml) do
+            xml = ::Builder::XmlMarkup.new
+            xml.HellWorld do
+              xml.Now Time.now.iso8601
+            end
+            xml.target!
+          end
+
+          specify { expect(decryptor.decrypt_xml(subject.to_xml)).to eql(xml) }
+        end
+      end
+    end
+  end
+end
spec/xml/kit/soap_spec.rb
@@ -6,6 +6,10 @@ RSpec.describe Soap do
 
     let(:result) { Hash.from_xml(subject.to_xml) }
 
+    before do
+      puts subject.to_xml(pretty: true)
+    end
+
     specify { expect(result['Envelope']).to be_present }
     specify { expect(result['Envelope']['Header']).to be_present }
     specify do