lib/xml/kit/decryption.rb in xml-kit-0.2.0 vs lib/xml/kit/decryption.rb in xml-kit-0.3.0

- old
+ new

@@ -1,10 +1,10 @@ # frozen_string_literal: true module Xml module Kit - # {include:file:spec/saml/xml_decryption_spec.rb} + # {include:file:spec/xml/kit/decryption_spec.rb} class Decryption # The list of private keys to use to attempt to decrypt the document. attr_reader :cipher_registry, :private_keys def initialize(private_keys:, cipher_registry: ::Xml::Kit::Crypto) @@ -13,12 +13,15 @@ end # Decrypts an EncryptedData section of an XML document. # # @param data [Hash] the XML document converted to a [Hash] using Hash.from_xml. + # @deprecated Use {#decrypt_hash} instead of this def decrypt(data) - ::Xml::Kit.deprecate('decrypt is deprecated. Use decrypt_xml or decrypt_hash instead.') + ::Xml::Kit.deprecate( + 'decrypt is deprecated. Use decrypt_xml or decrypt_hash instead.' + ) decrypt_hash(data) end # Decrypts an EncryptedData section of an XML document. # @@ -29,15 +32,15 @@ # Decrypts an EncryptedData section of an XML document. # # @param hash [Hash] the XML document converted to a [Hash] using Hash.from_xml. def decrypt_hash(hash) - encrypted_data = hash['EncryptedData'] + data = hash['EncryptedData'] to_plaintext( - Base64.decode64(encrypted_data['CipherData']['CipherValue']), - symmetric_key_from(encrypted_data), - encrypted_data['EncryptionMethod']['Algorithm'] + Base64.decode64(data['CipherData']['CipherValue']), + symmetric_key_from(data['KeyInfo']['EncryptedKey']), + data['EncryptionMethod']['Algorithm'] ) end # Decrypts an EncryptedData Nokogiri::XML::Element. # @@ -48,24 +51,31 @@ node.parent.replace(decrypt_xml(node.to_s))[0] end private - def symmetric_key_from(encrypted_data, attempts = private_keys.count) - cipher_text = Base64.decode64(encrypted_data['KeyInfo']['EncryptedKey']['CipherData']['CipherValue']) + def symmetric_key_from(encrypted_key, attempts = private_keys.count) + cipher, algorithm = cipher_and_algorithm_from(encrypted_key) private_keys.each do |private_key| begin attempts -= 1 - return to_plaintext(cipher_text, private_key, encrypted_data['KeyInfo']['EncryptedKey']['EncryptionMethod']['Algorithm']) + return to_plaintext(cipher, private_key, algorithm) rescue OpenSSL::PKey::RSAError raise if attempts.zero? end end raise DecryptionError, private_keys end def to_plaintext(cipher_text, private_key, algorithm) cipher_registry.cipher_for(algorithm, private_key).decrypt(cipher_text) + end + + def cipher_and_algorithm_from(encrypted_key) + [ + Base64.decode64(encrypted_key['CipherData']['CipherValue']), + encrypted_key['EncryptionMethod']['Algorithm'] + ] end end end end