Commit c90bb8a

mokha <mo@mokhan.ca>
2019-01-23 00:33:08
delegate to encrpyted key
1 parent d3caa66
bin/cibuild
@@ -17,5 +17,5 @@ export RUBY_HEAP_SLOTS_INCREMENT=400000
 export RUBY_HEAP_SLOTS_GROWTH_FACTOR=1
 
 ruby -v
-gem install bundler
+gem install bundler --conservative
 bin/test
lib/xml/kit/templates/key_info.builder
@@ -6,10 +6,5 @@ xml.KeyInfo xmlns: ::Xml::Kit::Namespaces::XMLDSIG do
     xml.X509SKI subject_key_identifier
     xml.X509Certificate ::Xml::Kit::Certificate.strip(x509_data.to_pem)
   end if x509_data
-  xml.EncryptedKey xmlns: ::Xml::Kit::Namespaces::XMLENC do
-    xml.EncryptionMethod Algorithm: algorithm
-    xml.CipherData do
-      xml.CipherValue cipher_value
-    end
-  end
+  render(encrypted_key, xml: xml) if encrypted_key
 end
lib/xml/kit/encrypted_key.rb
@@ -10,7 +10,7 @@ module Xml
       attr_reader :public_key, :key
       attr_accessor :key_info
 
-      def initialize(id:, public_key:, key:, key_info: nil, algorithm: DEFAULT_ALGORITHM)
+      def initialize(id: Id.generate, public_key:, key:, key_info: nil, algorithm: DEFAULT_ALGORITHM)
         @id = id
         @algorithm = algorithm
         @public_key = public_key
@@ -19,7 +19,16 @@ module Xml
       end
 
       def cipher_value
-        Base64.strict_encode64(public_key.public_encrypt(key))
+        asymmetric_cipher = asymmetric(algorithm, public_key)
+        Base64.strict_encode64(asymmetric_cipher.encrypt(key))
+      end
+
+      private
+
+      def asymmetric(algorithm, public_key)
+        return algorithm unless algorithm.is_a?(String)
+
+        ::Xml::Kit::Crypto.cipher_for(algorithm, public_key)
       end
     end
   end
lib/xml/kit/encryption.rb
@@ -20,10 +20,15 @@ module Xml
         symmetric_cipher = symmetric(symmetric_algorithm)
         @symmetric_cipher_value = Base64.strict_encode64(symmetric_cipher.encrypt(raw_xml))
 
-        @asymmetric_algorithm = asymmetric_algorithm
-        asymmetric_cipher = asymmetric(asymmetric_algorithm, public_key)
-        @asymmetric_cipher_value = Base64.strict_encode64(asymmetric_cipher.encrypt(symmetric_cipher.key))
-        @key_info = key_info || KeyInfo.new(algorithm: asymmetric_algorithm, cipher_value: asymmetric_cipher_value)
+        if key_info
+          @key_info = key_info
+        else
+          @key_info = KeyInfo.new
+          @key_info.encrypted_key = EncryptedKey.new(public_key: public_key, key: symmetric_cipher.key, algorithm: asymmetric_algorithm)
+
+          @asymmetric_algorithm = asymmetric_algorithm
+          @asymmetric_cipher_value = @key_info.encrypted_key.cipher_value
+        end
       end
 
       def to_xml(xml: ::Builder::XmlMarkup.new)
@@ -41,12 +46,6 @@ module Xml
 
         ::Xml::Kit::Crypto::SymmetricCipher.new(algorithm)
       end
-
-      def asymmetric(algorithm, public_key)
-        return algorithm unless algorithm.is_a?(String)
-
-        ::Xml::Kit::Crypto.cipher_for(algorithm, public_key)
-      end
     end
   end
 end
lib/xml/kit/key_info.rb
@@ -20,14 +20,9 @@ module Xml
 
     class KeyInfo
       include Templatable
-      attr_reader :algorithm, :cipher_value
       attr_accessor :key_name
       attr_accessor :x509_data
-
-      def initialize(algorithm:, cipher_value:)
-        @algorithm = algorithm
-        @cipher_value = cipher_value
-      end
+      attr_accessor :encrypted_key
 
       def key_value
         @key_value ||= KeyValue.new
spec/xml/kit/encrypted_key_spec.rb
@@ -2,14 +2,17 @@ RSpec.describe ::Xml::Kit::EncryptedKey do
   describe "#to_xml" do
     subject { described_class.new(id: id, algorithm: algorithm, public_key: public_key, key: symmetric_key, key_info: key_info) }
     let(:algorithm) { ::Xml::Kit::Crypto::RsaCipher::ALGORITHM }
-    let(:key_info) { ::Xml::Kit::KeyInfo.new(algorithm: algorithm, cipher_value: '') }
+    let(:key_info) { ::Xml::Kit::KeyInfo.new }
     let(:id) { ::Xml::Kit::Id.generate }
     let(:private_key) { OpenSSL::PKey::RSA.new(2048) }
     let(:public_key) { private_key.public_key }
-    let(:expected_cipher_value) { Base64.strict_encode64(public_key.public_encrypt(symmetric_key)) }
     let(:symmetric_key) { SecureRandom.hex(32) }
     let(:result) { Hash.from_xml(subject.to_xml) }
 
+    before do
+      key_info.key_name = 'samlkey'
+    end
+
     specify { expect(result.key?('EncryptedKey')).to be_present }
     specify { expect(result['EncryptedKey']['Id']).to eql(id) }
     specify { expect(result['EncryptedKey']['xmlns']).to eql(::Xml::Kit::Namespaces::XMLENC) }
spec/xml/kit/key_info_spec.rb
@@ -1,16 +1,22 @@
 RSpec.describe Xml::Kit::KeyInfo do
-  subject { described_class.new(algorithm: algorithm, cipher_value: cipher_value) }
-  let(:algorithm) { 'asymmetric_cipher' }
-  let(:cipher_value) { Base64.strict_encode64('asymmetric CIPHERTEXT') }
+  subject { described_class.new }
 
   describe "#to_xml" do
     context "with encrypted key" do
-
+      let(:encrypted_key) { ::Xml::Kit::EncryptedKey.new(id: id, algorithm: algorithm, public_key: public_key, key: symmetric_key) }
+      let(:algorithm) { ::Xml::Kit::Crypto::RsaCipher::ALGORITHM }
+      let(:id) { ::Xml::Kit::Id.generate }
+      let(:private_key) { OpenSSL::PKey::RSA.new(2048) }
+      let(:public_key) { private_key.public_key }
+      let(:symmetric_key) { SecureRandom.hex(32) }
       let(:result) { Hash.from_xml(subject.to_xml) }
 
-      specify { expect(result['KeyInfo']).to be_present }
+      before do
+        subject.encrypted_key = encrypted_key
+      end
+
       specify { expect(result['KeyInfo']['EncryptedKey']['EncryptionMethod']['Algorithm']).to eql(algorithm) }
-      specify { expect(result['KeyInfo']['EncryptedKey']['CipherData']['CipherValue']).to eql(cipher_value) }
+      specify { expect(private_key.private_decrypt(Base64.decode64(result['KeyInfo']['EncryptedKey']['CipherData']['CipherValue']))).to eql(symmetric_key) }
     end
 
     context "with key name" do
@@ -18,7 +24,6 @@ RSpec.describe Xml::Kit::KeyInfo do
 
       before do
         subject.key_name = "samlkey"
-        puts subject.to_xml(pretty: true)
       end
 
       specify { expect(result['KeyInfo']['KeyName']).to eql('samlkey') }
xml-kit.gemspec
@@ -29,7 +29,7 @@ Gem::Specification.new do |spec|
   spec.add_dependency 'nokogiri', '>= 1.8.5'
   spec.add_dependency 'tilt', '>= 1.4.1'
   spec.add_dependency 'xmldsig', '~> 0.6'
-  spec.add_development_dependency 'bundler', '~> 1.16'
+  spec.add_development_dependency 'bundler', '~> 2.0'
   spec.add_development_dependency 'bundler-audit', '~> 0.6'
   spec.add_development_dependency 'ffaker', '~> 2.7'
   spec.add_development_dependency 'rake', '~> 10.0'