def perform_decryption(
      encryption_data,
      password,
      content_entry,
      roo_content_xml_path
    )
      # Extract various expected attributes from the manifest that
      # describe the encryption

      algorithm_node            = encryption_data.xpath('manifest:algorithm').first
      key_derivation_node       =
        encryption_data.xpath('manifest:key-derivation').first
      start_key_generation_node =
        encryption_data.xpath('manifest:start-key-generation').first

      # If we have all the expected elements, then we can perform
      # the decryption.

      if !algorithm_node.nil? && !key_derivation_node.nil? &&
         !start_key_generation_node.nil?

        # The algorithm is a URI describing the algorithm used
        algorithm           = algorithm_node['manifest:algorithm-name']

        # The initialization vector is base-64 encoded
        iv                  = Base64.decode64(
          algorithm_node['manifest:initialisation-vector']
        )
        key_derivation_name = key_derivation_node['manifest:key-derivation-name']
        iteration_count     = key_derivation_node['manifest:iteration-count'].to_i
        salt                = Base64.decode64(key_derivation_node['manifest:salt'])

        # The key is hashed with an algorithm represented by this URI
        key_generation_name =
          start_key_generation_node[
            'manifest:start-key-generation-name'
          ]

        hashed_password = password

        if key_generation_name == 'http://www.w3.org/2000/09/xmldsig#sha256'

          hashed_password = Digest::SHA256.digest(password)
        else
          fail ArgumentError, "Unknown key generation algorithm #{key_generation_name}"
        end

        cipher = find_cipher(
          algorithm,
          key_derivation_name,
          hashed_password,
          salt,
          iteration_count,
          iv
        )

        begin
          decrypted = decrypt(content_entry, cipher)

          # Finally, inflate the decrypted stream and overwrite
          # content.xml
          IO.binwrite(
            roo_content_xml_path,
            Zlib::Inflate.new(-Zlib::MAX_WBITS).inflate(decrypted)
          )
        rescue StandardError => error
          raise ArgumentError, "Invalid password or other data error: #{error}"
        end
      else
        fail ArgumentError, 'manifest.xml missing encryption-data elements'
      end
    end
def perform_decryption(
      encryption_data,
      password,
      content_entry,
      roo_content_xml_path
    )
      # Extract various expected attributes from the manifest that
      # describe the encryption

      algorithm_node            = encryption_data.xpath('manifest:algorithm').first
      key_derivation_node       =
        encryption_data.xpath('manifest:key-derivation').first
      start_key_generation_node =
        encryption_data.xpath('manifest:start-key-generation').first

      # If we have all the expected elements, then we can perform
      # the decryption.

      if !algorithm_node.nil? && !key_derivation_node.nil? &&
         !start_key_generation_node.nil?

        # The algorithm is a URI describing the algorithm used
        algorithm           = algorithm_node['manifest:algorithm-name']

        # The initialization vector is base-64 encoded
        iv                  = Base64.decode64(
          algorithm_node['manifest:initialisation-vector']
        )
        key_derivation_name = key_derivation_node['manifest:key-derivation-name']
        iteration_count     = key_derivation_node['manifest:iteration-count'].to_i
        salt                = Base64.decode64(key_derivation_node['manifest:salt'])

        # The key is hashed with an algorithm represented by this URI
        key_generation_name =
          start_key_generation_node[
            'manifest:start-key-generation-name'
          ]

        hashed_password = password

        if key_generation_name == 'http://www.w3.org/2000/09/xmldsig#sha256'

          hashed_password = Digest::SHA256.digest(password)
        else
          fail ArgumentError, "Unknown key generation algorithm #{key_generation_name}"
        end

        cipher = find_cipher(
          algorithm,
          key_derivation_name,
          hashed_password,
          salt,
          iteration_count,
          iv
        )

        begin
          decrypted = decrypt(content_entry, cipher)

          # Finally, inflate the decrypted stream and overwrite
          # content.xml
          IO.binwrite(
            roo_content_xml_path,
            Zlib::Inflate.new(-Zlib::MAX_WBITS).inflate(decrypted)
          )
        rescue StandardError => error
          raise ArgumentError, "Invalid password or other data error: #{error}"
        end
      else
        fail ArgumentError, 'manifest.xml missing encryption-data elements'
      end
    end
Process the ODS encryption manifest and perform the decryption