Commit d1e6069

mokha <mo@mokhan.ca>
2019-04-20 16:18:12
allow keyinfo to provide symmetric and asymmetric key data
1 parent 13f67b5
Changed files (2)
lib
spec
lib/xml/kit/key_info.rb
@@ -21,6 +21,18 @@ module Xml
         yield self if block_given?
       end
 
+      def asymmetric_cipher(algorithm: Crypto::RsaCipher::ALGORITHM)
+        return encrypted_key.asymmetric_cipher if encrypted_key
+        return Crypto.cipher_for(derive_algorithm_from(x509_data.public_key), x509_data.public_key) if x509_data
+        super
+      end
+
+      def symmetric_cipher
+        return super if encrypted_key.nil?
+
+        encrypted_key.symmetric_cipher
+      end
+
       def key_value
         @key_value ||= KeyValue.new
       end
@@ -35,6 +47,17 @@ module Xml
 
         Base64.strict_encode64(ski.value)
       end
+
+      private
+
+      def derive_algorithm_from(key)
+        case key
+        when OpenSSL::PKey::RSA
+          "#{::Xml::Kit::Namespaces::XMLENC}rsa-1_5"
+        else
+          raise 'unsupported key type'
+        end
+      end
     end
   end
 end
spec/xml/kit/key_info_spec.rb
@@ -19,6 +19,8 @@ RSpec.describe Xml::Kit::KeyInfo do
 
       specify { expect(result['KeyInfo']['EncryptedKey']['EncryptionMethod']['Algorithm']).to eql(algorithm) }
       specify { expect(private_key.private_decrypt(Base64.decode64(result['KeyInfo']['EncryptedKey']['CipherData']['CipherValue']))).to eql(symmetric_cipher.key) }
+      specify { expect(subject.symmetric_cipher).to eql(symmetric_cipher) }
+      specify { expect(subject.asymmetric_cipher).to eql(asymmetric_cipher) }
     end
 
     context 'with key name' do
@@ -65,14 +67,14 @@ RSpec.describe Xml::Kit::KeyInfo do
       let(:key_pair) { ::Xml::Kit::KeyPair.generate(use: :encryption) }
       let(:x509_certificate) { key_pair.certificate.x509 }
       let(:subject_key_identifier) { x509_certificate.extensions.find { |x| x.oid == 'subjectKeyIdentifier' }.value }
-      let(:result) { Hash.from_xml(subject.to_xml) }
 
       before do
         subject.x509_data = x509_certificate
       end
 
-      specify { expect(result['KeyInfo']['X509Data']['X509SKI']).to eql(Base64.strict_encode64(subject_key_identifier)) }
-      specify { expect(result['KeyInfo']['X509Data']['X509Certificate']).to eql(key_pair.certificate.stripped) }
+      specify { expect(Hash.from_xml(subject.to_xml)['KeyInfo']['X509Data']['X509SKI']).to eql(Base64.strict_encode64(subject_key_identifier)) }
+      specify { expect(Hash.from_xml(subject.to_xml)['KeyInfo']['X509Data']['X509Certificate']).to eql(key_pair.certificate.stripped) }
+      specify { expect(subject.asymmetric_cipher.key.to_pem).to eql(x509_certificate.public_key.to_pem) }
     end
   end
 end