1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
|
# frozen_string_literal: true
require 'stringio'
require 'tempfile'
module Aws
module S3
module Encryption
# Provides an IO wrapper encrpyting a stream of data.
# It is possible to use this same object for decrypting. You must
# initialize it with a decryptiion cipher in that case and the
# IO object must contain cipher text instead of plain text.
# @api private
class IOEncrypter
# @api private
ONE_MEGABYTE = 1024 * 1024
def initialize(cipher, io)
@encrypted = io.size <= ONE_MEGABYTE ?
encrypt_to_stringio(cipher, io.read) :
encrypt_to_tempfile(cipher, io)
@size = @encrypted.size
end
# @return [Integer]
attr_reader :size
def read(bytes = nil, output_buffer = nil)
if Tempfile === @encrypted && @encrypted.closed?
@encrypted.open
@encrypted.binmode
end
@encrypted.read(bytes, output_buffer)
end
def rewind
@encrypted.rewind
end
# @api private
def close
@encrypted.close if Tempfile === @encrypted
end
private
def encrypt_to_stringio(cipher, plain_text)
if plain_text.empty?
StringIO.new(cipher.final)
else
StringIO.new(cipher.update(plain_text) + cipher.final)
end
end
def encrypt_to_tempfile(cipher, io)
encrypted = Tempfile.new(self.object_id.to_s)
encrypted.binmode
while chunk = io.read(ONE_MEGABYTE)
encrypted.write(cipher.update(chunk))
end
encrypted.write(cipher.final)
encrypted.rewind
encrypted
end
end
end
end
end
|