Commit ade47ec

mo <mo.khan@gmail.com>
2017-12-30 18:02:10
add encryption spec.
1 parent c7874cd
lib/xml/kit/decryption.rb
@@ -13,7 +13,21 @@ module Xml
       #
       # @param data [Hash] the XML document converted to a [Hash] using Hash.from_xml.
       def decrypt(data)
-        encrypted_data = data['EncryptedData']
+        decrypt_hash(data)
+      end
+
+      # Decrypts an EncryptedData section of an XML document.
+      #
+      # @param raw_xml [String] the XML document as a string.
+      def decrypt_xml(raw_xml)
+        decrypt(Hash.from_xml(raw_xml))
+      end
+
+      # Decrypts an EncryptedData section of an XML document.
+      #
+      # @param data [Hash] the XML document converted to a [Hash] using Hash.from_xml.
+      def decrypt_hash(hash)
+        encrypted_data = hash['EncryptedData']
         symmetric_key = symmetric_key_from(encrypted_data)
         cipher_text = Base64.decode64(encrypted_data["CipherData"]["CipherValue"])
         to_plaintext(cipher_text, symmetric_key, encrypted_data["EncryptionMethod"]['Algorithm'])
lib/xml/kit/encryption.rb
@@ -12,6 +12,10 @@ module Xml
         @iv = cipher.random_iv
         @encrypted = cipher.update(raw_xml) + cipher.final
       end
+
+      def to_xml(xml: ::Builder::XmlMarkup.new)
+        ::Xml::Kit::Template.new(self).to_xml(xml: xml)
+      end
     end
   end
 end
lib/xml/kit/key_pair.rb
@@ -16,6 +16,10 @@ module Xml
         @use == use
       end
 
+      def public_key
+        certificate.public_key
+      end
+
       # Returns a generated self signed certificate with private key.
       #
       # @param use [Symbol] Can be either `:signing` or `:encryption`.
lib/xml/kit/templatable.rb
@@ -24,12 +24,10 @@ module Xml
         if encrypt?
           temp = ::Builder::XmlMarkup.new
           yield temp
-          signed_xml = signatures.complete(temp.target!)
-          xml_encryption = ::Xml::Kit::Encryption.new(
-            signed_xml,
+          ::Xml::Kit::Encryption.new(
+            signatures.complete(temp.target!),
             encryption_certificate.public_key
-          )
-          render(xml_encryption, xml: xml)
+          ).to_xml(xml: xml)
         else
           yield xml
         end
spec/xml/encryption_spec.rb
@@ -0,0 +1,21 @@
+RSpec.describe Xml::Kit::Encryption do
+  subject { described_class.new(xml, public_key) }
+  let(:public_key) { key_pair.public_key }
+  let(:key_pair) { Xml::Kit::KeyPair.generate(use: :encryption) }
+  let(:xml) do
+    xml = ::Builder::XmlMarkup.new
+    xml.HellWorld do
+      xml.Now Time.now.iso8601
+    end
+    xml.target!
+  end
+
+  describe "#to_xml" do
+    let(:decryptor) { Xml::Kit::Decryption.new(private_keys: [key_pair.private_key]) }
+
+    it 'generates an encrypted xml using AES-256-CBC' do
+      result = subject.to_xml
+      expect(decryptor.decrypt_xml(result)).to eql(xml)
+    end
+  end
+end