Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions gems/aws-sdk-s3/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
Unreleased Changes
------------------

* Issue - S3 Encryption Client, encryptionV2 and encryptionV3, returns a decryption error for a malformed material description.

1.228.1 (2026-07-23)
------------------

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def encryption_cipher(options = {})
# @return [Cipher] Given an encryption envelope, returns a
# decryption cipher.
def decryption_cipher(envelope, options = {})
encryption_context = Json.load(envelope['x-amz-matdesc'])
encryption_context = extract_encryption_context(envelope['x-amz-matdesc'])
cek_alg = envelope['x-amz-cek-alg']

case envelope['x-amz-wrap-alg']
Expand Down Expand Up @@ -115,6 +115,19 @@ def decryption_cipher(envelope, options = {})

private

# Raise a decryption error for a malformed material description. A
# material description must be a JSON object.
def extract_encryption_context(matdesc)
context = Json.load(matdesc) if matdesc.is_a?(String)
unless context.is_a?(Hash)
raise Errors::DecryptionError, 'Malformed material description'
end

context
rescue Aws::Json::ParseError, EncodingError
raise Errors::DecryptionError, 'Malformed material description'
end

def validate_key_wrap(key_wrap_schema)
case key_wrap_schema
when :kms_context then 'kms+context'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def decryption_cipher(envelope, options = {})
cek_alg = envelope['x-amz-c']
encryption_context =
if !envelope['x-amz-t'].nil?
Json.load(envelope['x-amz-t'])
extract_encryption_context(envelope['x-amz-t'])
else
##= ../specification/s3-encryption/data-format/content-metadata.md#v3-only
##% If the mapkey x-amz-t is not present, the default Material Description value MUST be set to an empty map (`{}`).
Expand Down Expand Up @@ -102,6 +102,18 @@ def decryption_cipher(envelope, options = {})

private

# Raise a decryption error for a malformed material description.
def extract_encryption_context(matdesc)
context = Json.load(matdesc) if matdesc.is_a?(String)
unless context.is_a?(Hash)
raise Errors::DecryptionError, 'Malformed material description'
end

context
rescue Aws::Json::ParseError, EncodingError
raise Errors::DecryptionError, 'Malformed material description'
end

def validate_key_wrap(key_wrap_schema)
case key_wrap_schema
when :kms_context then '12'
Expand Down
43 changes: 43 additions & 0 deletions gems/aws-sdk-s3/spec/encryptionV2/kms_cipher_provider_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
require_relative '../spec_helper'

module Aws
module S3
module EncryptionV2
describe KmsCipherProvider do
let(:provider) do
KmsCipherProvider.new(
kms_key_id: 'kms-key-id',
kms_client: KMS::Client.new(stub_responses: true),
key_wrap_schema: :kms_context,
content_encryption_schema: :aes_gcm_no_padding
)
end

describe '#decryption_cipher' do
# A malformed material description raises DecryptionError.
['=?utf-8?B?gA==?=', '=?utf-8?B?/w==?=', '=?utf-8?B?YWJj/w==?=', "abc\xFF"].each do |matdesc|
it "raises DecryptionError (#{matdesc.inspect})" do
expect do
provider.decryption_cipher('x-amz-matdesc' => matdesc)
end.to raise_error(Errors::DecryptionError, /Malformed material description/)
end
end

# Valid JSON that isn't an object, or an absent matdesc, is malformed.
['123', nil].each do |matdesc|
it "raises DecryptionError (#{matdesc.inspect})" do
envelope = {
'x-amz-matdesc' => matdesc,
'x-amz-wrap-alg' => 'kms+context',
'x-amz-cek-alg' => 'AES/GCM/NoPadding'
}
expect do
provider.decryption_cipher(envelope)
end.to raise_error(Errors::DecryptionError, /Malformed material description/)
end
end
end
end
end
end
end
29 changes: 29 additions & 0 deletions gems/aws-sdk-s3/spec/encryptionv3/kms_cipher_provider_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
require_relative '../spec_helper'

module Aws
module S3
module EncryptionV3
describe KmsCipherProvider do
let(:provider) do
KmsCipherProvider.new(
kms_key_id: 'kms-key-id',
kms_client: KMS::Client.new(stub_responses: true),
key_wrap_schema: :kms_context,
content_encryption_schema: :alg_aes_256_gcm_hkdf_sha512_commit_key
)
end

describe '#decryption_cipher' do
# A malformed material description raises DecryptionError.
['=?utf-8?B?gA==?=', '=?utf-8?B?/w==?=', '=?utf-8?B?YWJj/w==?=', "abc\xFF", '123'].each do |matdesc|
it "raises DecryptionError (#{matdesc.inspect})" do
expect do
provider.decryption_cipher('x-amz-w' => '12', 'x-amz-t' => matdesc)
end.to raise_error(Errors::DecryptionError, /Malformed material description/)
end
end
end
end
end
end
end
Loading