class Aws::S3::Encryption::DecryptHandler

@api private

Constants

POSSIBLE_ENVELOPE_KEYS
V1_ENVELOPE_KEYS
V2_ENVELOPE_KEYS

Public Instance Methods

call(context) click to toggle source
# File lib/aws-sdk-resources/services/s3/encryption/decrypt_handler.rb, line 25
def call(context)
  attach_http_event_listeners(context)
  @handler.call(context)
end

Private Instance Methods

attach_http_event_listeners(context) click to toggle source
# File lib/aws-sdk-resources/services/s3/encryption/decrypt_handler.rb, line 32
def attach_http_event_listeners(context)
  context.http_response.on_headers(200) do
    cipher = decryption_cipher(context)
    body = context.http_response.body
    context.http_response.body = IODecrypter.new(cipher, body)
  end

  context.http_response.on_success(200) do
    decrypter = context.http_response.body
    decrypter.finalize
    decrypter.io.rewind if decrypter.io.respond_to?(:rewind)
    context.http_response.body = decrypter.io
  end

  context.http_response.on_error do
    if context.http_response.body.is_a?(IODecrypter)
      context.http_response.body = context.http_response.body.io
    end
  end
end
decryption_cipher(context) click to toggle source
# File lib/aws-sdk-resources/services/s3/encryption/decrypt_handler.rb, line 53
def decryption_cipher(context)
  if envelope = get_encryption_envelope(context)
    context[:encryption][:cipher_provider].decryption_cipher(envelope)
  else
    raise Errors::DecryptionError, "unable to locate encyrption envelope"
  end
end
envelope_from_instr_file(context) click to toggle source
# File lib/aws-sdk-resources/services/s3/encryption/decrypt_handler.rb, line 79
def envelope_from_instr_file(context)
  suffix = context[:encryption][:instruction_file_suffix]
  possible_envelope = Json.load(context.client.get_object(
    bucket: context.params[:bucket],
    key: context.params[:key] + suffix
  ).body.read)
  extract_envelope(possible_envelope)
rescue S3::Errors::ServiceError, Json::ParseError
  nil
end
envelope_from_metadata(context) click to toggle source
# File lib/aws-sdk-resources/services/s3/encryption/decrypt_handler.rb, line 69
def envelope_from_metadata(context)
  possible_envelope = {}
  POSSIBLE_ENVELOPE_KEYS.each do |suffix|
    if value = context.http_response.headers["x-amz-meta-#{suffix}"]
      possible_envelope[suffix] = value
    end
  end
  extract_envelope(possible_envelope)
end
extract_envelope(hash) click to toggle source
# File lib/aws-sdk-resources/services/s3/encryption/decrypt_handler.rb, line 90
def extract_envelope(hash)
  return v1_envelope(hash) if hash.key?('x-amz-key')
  return v2_envelope(hash) if hash.key?('x-amz-key-v2')
  if hash.keys.any? { |key| key.match(/^x-amz-key-(.+)$/) }
    msg = "unsupported envelope encryption version #{$1}"
    raise Errors::DecryptionError, msg
  else
    nil # no envelope found
  end
end
get_encryption_envelope(context) click to toggle source
# File lib/aws-sdk-resources/services/s3/encryption/decrypt_handler.rb, line 61
def get_encryption_envelope(context)
  if context[:encryption][:envelope_location] == :metadata
    envelope_from_metadata(context) || envelope_from_instr_file(context)
  else
    envelope_from_instr_file(context) || envelope_from_metadata(context)
  end
end
v1_envelope(envelope) click to toggle source
# File lib/aws-sdk-resources/services/s3/encryption/decrypt_handler.rb, line 101
def v1_envelope(envelope)
  envelope
end
v2_envelope(envelope) click to toggle source
# File lib/aws-sdk-resources/services/s3/encryption/decrypt_handler.rb, line 105
def v2_envelope(envelope)
  unless envelope['x-amz-cek-alg'] == 'AES/CBC/PKCS5Padding'
    alg = envelope['x-amz-cek-alg'].inspect
    msg = "unsupported content encrypting key (cek) format: #{alg}"
    raise Errors::DecryptionError, msg
  end
  unless envelope['x-amz-wrap-alg'] == 'kms'
    # possible to support
    #   RSA/ECB/OAEPWithSHA-256AndMGF1Padding
    alg = envelope['x-amz-wrap-alg'].inspect
    msg = "unsupported key wrapping algorithm: #{alg}"
    raise Errors::DecryptionError, msg
  end
  unless V2_ENVELOPE_KEYS.sort == envelope.keys.sort
    msg = "incomplete v2 encryption envelope:\n"
    msg += "  expected: #{V2_ENVELOPE_KEYS.join(',')}\n"
    msg += "  got: #{envelope_keys.join(', ')}"
    raise Errors::DecryptionError, msg
  end
  envelope
end