Commit 394b9a9

mo <mo.khan@gmail.com>
2017-11-26 18:28:04
extract multiple decryptors.
1 parent 8519764
Changed files (2)
lib/saml/kit/cryptography.rb
@@ -23,37 +23,92 @@ module Saml
       end
 
       def to_plaintext(cipher_text, symmetric_key, algorithm)
-        case algorithm
-        when 'http://www.w3.org/2001/04/xmlenc#tripledes-cbc'
-          cipher = OpenSSL::Cipher.new('DES-EDE3-CBC').decrypt
-        when 'http://www.w3.org/2001/04/xmlenc#aes128-cbc'
-          cipher = OpenSSL::Cipher.new('AES-128-CBC').decrypt
-        when 'http://www.w3.org/2001/04/xmlenc#aes192-cbc'
-          cipher = OpenSSL::Cipher.new('AES-192-CBC').decrypt
-        when 'http://www.w3.org/2001/04/xmlenc#aes256-cbc'
-          cipher = OpenSSL::Cipher.new('AES-256-CBC').decrypt
-        when 'http://www.w3.org/2001/04/xmlenc#rsa-1_5'
-          rsa = symmetric_key
-        when 'http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p'
-          oaep = symmetric_key
-        end
-
-        if cipher
-          iv = cipher_text[0..cipher.iv_len-1]
-          data = cipher_text[cipher.iv_len..-1]
-          #cipher.padding = 0
-          cipher.key = symmetric_key
-          cipher.iv = iv
-
-          Saml::Kit.logger.debug ['-key', symmetric_key].inspect
+        return decryptor_for(algorithm, symmetric_key).decrypt(cipher_text)
+      end
+
+      def decryptor_for(algorithm, key)
+        decryptors = [ SimpleCipher, RsaCipher, OaepCipher, UnknownCipher ]
+        decryptors.find { |x| x.matches?(algorithm) }.new(algorithm, key)
+      end
+
+      class SimpleCipher
+        ALGORITHMS = {
+          'http://www.w3.org/2001/04/xmlenc#tripledes-cbc' => true,
+          'http://www.w3.org/2001/04/xmlenc#aes128-cbc' => true,
+          'http://www.w3.org/2001/04/xmlenc#aes192-cbc' => true,
+          'http://www.w3.org/2001/04/xmlenc#aes256-cbc' => true,
+        }
+
+        def initialize(algorithm, key)
+          @key = key
+          @cipher = case algorithm
+          when 'http://www.w3.org/2001/04/xmlenc#tripledes-cbc'
+            OpenSSL::Cipher.new('DES-EDE3-CBC')
+          when 'http://www.w3.org/2001/04/xmlenc#aes128-cbc'
+            OpenSSL::Cipher.new('AES-128-CBC')
+          when 'http://www.w3.org/2001/04/xmlenc#aes192-cbc'
+            OpenSSL::Cipher.new('AES-192-CBC')
+          when 'http://www.w3.org/2001/04/xmlenc#aes256-cbc'
+            OpenSSL::Cipher.new('AES-256-CBC')
+          end
+        end
+
+        def self.matches?(algorithm)
+          ALGORITHMS[algorithm]
+        end
+
+        def decrypt(cipher_text)
+          @cipher.decrypt
+          iv = cipher_text[0..@cipher.iv_len-1]
+          data = cipher_text[@cipher.iv_len..-1]
+          #@cipher.padding = 0
+          @cipher.key = @key
+          @cipher.iv = iv
+
+          Saml::Kit.logger.debug ['-key', @key].inspect
           Saml::Kit.logger.debug ['-iv', iv].inspect
 
-          cipher.update(data) + cipher.final
-        elsif rsa
-          rsa.private_decrypt(cipher_text)
-        elsif oaep
-          oaep.private_decrypt(cipher_text, OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING)
-        else
+          @cipher.update(data) + @cipher.final
+        end
+      end
+
+      class RsaCipher
+        def initialize(algorithm, key)
+          @key = key
+        end
+
+        def self.matches?(algorithm)
+          'http://www.w3.org/2001/04/xmlenc#rsa-1_5' == algorithm
+        end
+
+        def decrypt(cipher_text)
+          @key.private_decrypt(cipher_text)
+        end
+      end
+
+      class OaepCipher
+        def initialize(algorithm, key)
+          @key = key
+        end
+
+        def self.matches?(algorithm)
+          'http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p' == algorithm
+        end
+
+        def decrypt(cipher_text)
+          @key.private_decrypt(cipher_text, OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING)
+        end
+      end
+
+      class UnknownCipher
+        def initialize(algorithm, key)
+        end
+
+        def self.matches?(algorithm)
+          true
+        end
+
+        def decrypt(cipher_text)
           cipher_text
         end
       end
spec/saml/cryptography_spec.rb
@@ -2,8 +2,7 @@ require 'spec_helper'
 
 RSpec.describe Saml::Kit::Cryptography do
   describe "#decrypt" do
-    #let(:secret) { FFaker::Movie.title }
-    let(:secret) { "SECRET" }
+    let(:secret) { FFaker::Movie.title }
     let(:password) { FFaker::Movie.title }
 
     it 'decrypts the data' do