Commit c8303e5

mo <mo.khan@gmail.com>
2017-12-30 18:30:01
add support for more symmetric ciphers.
1 parent ade47ec
lib/xml/kit/crypto/simple_cipher.rb
@@ -3,10 +3,10 @@ module Xml
     module Crypto
       class SimpleCipher
         ALGORITHMS = {
-          'http://www.w3.org/2001/04/xmlenc#tripledes-cbc' => 'DES-EDE3-CBC',
-          'http://www.w3.org/2001/04/xmlenc#aes128-cbc' => 'AES-128-CBC',
-          'http://www.w3.org/2001/04/xmlenc#aes192-cbc' => 'AES-192-CBC',
-          'http://www.w3.org/2001/04/xmlenc#aes256-cbc' => 'AES-256-CBC',
+          "#{Namespaces::XMLENC}tripledes-cbc" => "DES-EDE3-CBC",
+          "#{Namespaces::XMLENC}aes128-cbc" => "AES-128-CBC",
+          "#{Namespaces::XMLENC}aes192-cbc" => "AES-192-CBC",
+          "#{Namespaces::XMLENC}aes256-cbc" => "AES-256-CBC",
         }
 
         def initialize(algorithm, private_key)
lib/xml/kit/templates/encryption.builder
@@ -1,8 +1,8 @@
 xml.EncryptedData xmlns: ::Xml::Kit::Namespaces::XMLENC do
-  xml.EncryptionMethod Algorithm: "http://www.w3.org/2001/04/xmlenc#aes256-cbc"
+  xml.EncryptionMethod Algorithm: algorithm
   xml.KeyInfo xmlns: ::Xml::Kit::Namespaces::XMLDSIG do
     xml.EncryptedKey xmlns: ::Xml::Kit::Namespaces::XMLENC do
-      xml.EncryptionMethod Algorithm: "http://www.w3.org/2001/04/xmlenc#rsa-1_5"
+      xml.EncryptionMethod Algorithm: "#{::Xml::Kit::Namespaces::XMLENC}rsa-1_5"
       xml.CipherData do
         xml.CipherValue Base64.encode64(public_key.public_encrypt(key))
       end
lib/xml/kit/encryption.rb
@@ -1,13 +1,17 @@
 module Xml
   module Kit
     class Encryption
+      DEFAULT_ALGORITHM="AES-256-CBC"
       attr_reader :public_key
+      attr_reader :algorithm
       attr_reader :key, :iv, :encrypted
 
-      def initialize(raw_xml, public_key)
+      def initialize(raw_xml, public_key, algorithm = DEFAULT_ALGORITHM)
         @public_key = public_key
-        cipher = OpenSSL::Cipher.new('AES-256-CBC')
+
+        cipher = OpenSSL::Cipher.new(algorithm)
         cipher.encrypt
+        @algorithm = ::Xml::Kit::Crypto::SimpleCipher::ALGORITHMS.key(algorithm)
         @key = cipher.random_key
         @iv = cipher.random_iv
         @encrypted = cipher.update(raw_xml) + cipher.final
lib/xml/kit/key_pair.rb
@@ -24,8 +24,8 @@ module Xml
       #
       # @param use [Symbol] Can be either `:signing` or `:encryption`.
       # @param passphrase [String] the passphrase to use to encrypt the private key.
-      def self.generate(use:, passphrase: SecureRandom.uuid)
-        certificate, private_key = ::Xml::Kit::SelfSignedCertificate.new(passphrase).create
+      def self.generate(use:, passphrase: SecureRandom.uuid, algorithm: 'AES-256-CBC')
+        certificate, private_key = ::Xml::Kit::SelfSignedCertificate.new(passphrase).create(algorithm)
         new(certificate, private_key, passphrase, use)
       end
     end
lib/xml/kit/self_signed_certificate.rb
@@ -7,20 +7,19 @@ module Xml
         @passphrase = passphrase
       end
 
-      def create
+      def create(algorithm = 'AES-256-CBC')
         rsa_key = OpenSSL::PKey::RSA.new(2048)
-        public_key = rsa_key.public_key
         certificate = OpenSSL::X509::Certificate.new
         certificate.subject = certificate.issuer = OpenSSL::X509::Name.parse(SUBJECT)
         certificate.not_before = Time.now.to_i
         certificate.not_after = (Date.today + 30).to_time.to_i
-        certificate.public_key = public_key
+        certificate.public_key = rsa_key.public_key
         certificate.serial = 0x0
         certificate.version = 2
         certificate.sign(rsa_key, OpenSSL::Digest::SHA256.new)
         [
           certificate.to_pem,
-          rsa_key.to_pem(OpenSSL::Cipher.new('AES-256-CBC'), @passphrase)
+          rsa_key.to_pem(OpenSSL::Cipher.new(algorithm), @passphrase)
         ]
       end
     end
spec/xml/encryption_spec.rb
@@ -1,21 +1,27 @@
 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]) }
+    [
+      'AES-128-CBC',
+      'AES-192-CBC',
+      'AES-256-CBC',
+    ].each do |algorithm|
+      describe algorithm do
+        subject { described_class.new(xml, public_key, algorithm) }
+        let(:key_pair) { Xml::Kit::KeyPair.generate(use: :encryption, algorithm: algorithm) }
+        let(:decryptor) { Xml::Kit::Decryption.new(private_keys: [key_pair.private_key]) }
+        let(:public_key) { key_pair.public_key }
+        let(:xml) do
+          xml = ::Builder::XmlMarkup.new
+          xml.HellWorld do
+            xml.Now Time.now.iso8601
+          end
+          xml.target!
+        end
 
-    it 'generates an encrypted xml using AES-256-CBC' do
-      result = subject.to_xml
-      expect(decryptor.decrypt_xml(result)).to eql(xml)
+        it "generates an encrypted xml" do
+          expect(decryptor.decrypt_xml(subject.to_xml)).to eql(xml)
+        end
+      end
     end
   end
 end