aws-sdk-resources 2.3.12 → 2.3.13
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/aws-sdk-resources/services/s3/encryption.rb +1 -0
- data/lib/aws-sdk-resources/services/s3/encryption/decrypt_handler.rb +48 -4
- data/lib/aws-sdk-resources/services/s3/encryption/io_auth_decrypter.rb +50 -0
- data/lib/aws-sdk-resources/services/s3/encryption/io_decrypter.rb +2 -9
- data/lib/aws-sdk-resources/services/s3/encryption/kms_cipher_provider.rb +12 -1
- data/lib/aws-sdk-resources/services/s3/encryption/utils.rb +2 -2
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 11c22ca5443cb742557f0ff0d51e1fef0df79fcf
|
4
|
+
data.tar.gz: e4491cd6fc35298e073d7a8b2acc125d51b1f4ff
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 415203dbe9f34837a545a8665a75c2573ff78bdbce65fb04556fed2d8168b9144b7e7d8205334e3aac2cfa3d544d4c29cd5b9a4ef12cc1a10c5621f832cd9817
|
7
|
+
data.tar.gz: de05df3ec9627f3f6a53b9e41914921ec0476fd22702bf8a15736c53673ad13fe222c7c7c7b9e456dcf23bd5e2477043707793aaadd0583e3a9990b4cd77d932
|
@@ -9,6 +9,7 @@ module Aws
|
|
9
9
|
autoload :EncryptHandler, 'aws-sdk-resources/services/s3/encryption/encrypt_handler'
|
10
10
|
autoload :Errors, 'aws-sdk-resources/services/s3/encryption/errors'
|
11
11
|
autoload :IOEncrypter, 'aws-sdk-resources/services/s3/encryption/io_encrypter'
|
12
|
+
autoload :IOAuthDecrypter, 'aws-sdk-resources/services/s3/encryption/io_auth_decrypter'
|
12
13
|
autoload :IODecrypter, 'aws-sdk-resources/services/s3/encryption/io_decrypter'
|
13
14
|
autoload :KeyProvider, 'aws-sdk-resources/services/s3/encryption/key_provider'
|
14
15
|
autoload :KmsCipherProvider, 'aws-sdk-resources/services/s3/encryption/kms_cipher_provider'
|
@@ -22,6 +22,11 @@ module Aws
|
|
22
22
|
|
23
23
|
POSSIBLE_ENVELOPE_KEYS = (V1_ENVELOPE_KEYS + V2_ENVELOPE_KEYS).uniq
|
24
24
|
|
25
|
+
POSSIBLE_ENCRYPTION_FORMATS = %w(
|
26
|
+
AES/GCM/NoPadding
|
27
|
+
AES/CBC/PKCS5Padding
|
28
|
+
)
|
29
|
+
|
25
30
|
def call(context)
|
26
31
|
attach_http_event_listeners(context)
|
27
32
|
@handler.call(context)
|
@@ -30,10 +35,13 @@ module Aws
|
|
30
35
|
private
|
31
36
|
|
32
37
|
def attach_http_event_listeners(context)
|
38
|
+
|
33
39
|
context.http_response.on_headers(200) do
|
34
40
|
cipher = decryption_cipher(context)
|
35
|
-
|
36
|
-
|
41
|
+
decrypter = body_contains_auth_tag?(context) ?
|
42
|
+
authenticated_decrypter(context, cipher) :
|
43
|
+
IODecrypter.new(cipher, context.http_response.body)
|
44
|
+
context.http_response.body = decrypter
|
37
45
|
end
|
38
46
|
|
39
47
|
context.http_response.on_success(200) do
|
@@ -44,7 +52,7 @@ module Aws
|
|
44
52
|
end
|
45
53
|
|
46
54
|
context.http_response.on_error do
|
47
|
-
if context.http_response.body.
|
55
|
+
if context.http_response.body.respond_to?(:io)
|
48
56
|
context.http_response.body = context.http_response.body.io
|
49
57
|
end
|
50
58
|
end
|
@@ -103,7 +111,7 @@ module Aws
|
|
103
111
|
end
|
104
112
|
|
105
113
|
def v2_envelope(envelope)
|
106
|
-
unless envelope['x-amz-cek-alg']
|
114
|
+
unless POSSIBLE_ENCRYPTION_FORMATS.include? envelope['x-amz-cek-alg']
|
107
115
|
alg = envelope['x-amz-cek-alg'].inspect
|
108
116
|
msg = "unsupported content encrypting key (cek) format: #{alg}"
|
109
117
|
raise Errors::DecryptionError, msg
|
@@ -124,6 +132,42 @@ module Aws
|
|
124
132
|
envelope
|
125
133
|
end
|
126
134
|
|
135
|
+
# When the x-amz-meta-x-amz-tag-len header is present, it indicates
|
136
|
+
# that the body of this object has a trailing auth tag. The header
|
137
|
+
# indicates the length of that tag.
|
138
|
+
#
|
139
|
+
# This method fetches the tag from the end of the object by
|
140
|
+
# making a GET Object w/range request. This auth tag is used
|
141
|
+
# to initialize the cipher, and the decrypter truncates the
|
142
|
+
# auth tag from the body when writing the final bytes.
|
143
|
+
def authenticated_decrypter(context, cipher)
|
144
|
+
http_resp = context.http_response
|
145
|
+
content_length = http_resp.headers['content-length'].to_i
|
146
|
+
auth_tag_length = http_resp.headers['x-amz-meta-x-amz-tag-len']
|
147
|
+
auth_tag_length = auth_tag_length.to_i / 8
|
148
|
+
|
149
|
+
auth_tag = context.client.get_object(
|
150
|
+
bucket: context.params[:bucket],
|
151
|
+
key: context.params[:key],
|
152
|
+
range: "bytes=-#{auth_tag_length}"
|
153
|
+
).body.read
|
154
|
+
|
155
|
+
cipher.auth_tag = auth_tag
|
156
|
+
cipher.auth_data = ''
|
157
|
+
|
158
|
+
# The encrypted object contains both the cipher text
|
159
|
+
# plus a trailing auth tag. This decrypter will the body
|
160
|
+
# expect for the trailing auth tag.
|
161
|
+
decrypter = IOAuthDecrypter.new(
|
162
|
+
io: http_resp.body,
|
163
|
+
encrypted_content_length: content_length - auth_tag_length,
|
164
|
+
cipher: cipher)
|
165
|
+
end
|
166
|
+
|
167
|
+
def body_contains_auth_tag?(context)
|
168
|
+
context.http_response.headers['x-amz-meta-x-amz-tag-len']
|
169
|
+
end
|
170
|
+
|
127
171
|
end
|
128
172
|
end
|
129
173
|
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Aws
|
2
|
+
module S3
|
3
|
+
module Encryption
|
4
|
+
# @api private
|
5
|
+
class IOAuthDecrypter
|
6
|
+
|
7
|
+
# @option options [required, IO#write] :io
|
8
|
+
# An IO-like object that responds to {#write}.
|
9
|
+
# @option options [required, Integer] :encrypted_content_length
|
10
|
+
# The number of bytes to decrypt from the `:io` object.
|
11
|
+
# This should be the total size of `:io` minus the length of
|
12
|
+
# the cipher auth tag.
|
13
|
+
# @option options [required, OpenSSL::Cipher] :cipher An initialized
|
14
|
+
# cipher that can be used to decrypt the bytes as they are
|
15
|
+
# written to the `:io` object. The cipher should already have
|
16
|
+
# its `#auth_tag` set.
|
17
|
+
def initialize(options = {})
|
18
|
+
@decrypter = IODecrypter.new(options[:cipher], options[:io])
|
19
|
+
@max_bytes = options[:encrypted_content_length]
|
20
|
+
@bytes_written = 0
|
21
|
+
end
|
22
|
+
|
23
|
+
def write(chunk)
|
24
|
+
chunk = truncate_chunk(chunk)
|
25
|
+
@bytes_written += chunk.bytesize
|
26
|
+
@decrypter.write(chunk)
|
27
|
+
end
|
28
|
+
|
29
|
+
def finalize
|
30
|
+
@decrypter.finalize
|
31
|
+
end
|
32
|
+
|
33
|
+
def io
|
34
|
+
@decrypter.io
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def truncate_chunk(chunk)
|
40
|
+
if chunk.bytesize + @bytes_written <= @max_bytes
|
41
|
+
chunk
|
42
|
+
else
|
43
|
+
chunk[0..(@max_bytes - @bytes_written - 1)]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -5,18 +5,17 @@ module Aws
|
|
5
5
|
class IODecrypter
|
6
6
|
|
7
7
|
# @param [OpenSSL::Cipher] cipher
|
8
|
-
# @param [#write] io An IO-like object that responds to
|
8
|
+
# @param [IO#write] io An IO-like object that responds to `#write`.
|
9
9
|
def initialize(cipher, io)
|
10
|
-
@orig_cipher = cipher.clone
|
11
10
|
@cipher = cipher.clone
|
12
11
|
@io = io
|
13
|
-
reset_cipher
|
14
12
|
end
|
15
13
|
|
16
14
|
# @return [#write]
|
17
15
|
attr_reader :io
|
18
16
|
|
19
17
|
def write(chunk)
|
18
|
+
# decrypt and write
|
20
19
|
@io.write(@cipher.update(chunk))
|
21
20
|
end
|
22
21
|
|
@@ -24,12 +23,6 @@ module Aws
|
|
24
23
|
@io.write(@cipher.final)
|
25
24
|
end
|
26
25
|
|
27
|
-
private
|
28
|
-
|
29
|
-
def reset_cipher
|
30
|
-
@cipher = @orig_cipher.clone
|
31
|
-
end
|
32
|
-
|
33
26
|
end
|
34
27
|
end
|
35
28
|
end
|
@@ -41,7 +41,18 @@ module Aws
|
|
41
41
|
encryption_context: encryption_context,
|
42
42
|
).plaintext
|
43
43
|
iv = decode64(envelope['x-amz-iv'])
|
44
|
-
|
44
|
+
block_mode =
|
45
|
+
case envelope['x-amz-cek-alg']
|
46
|
+
when 'AES/CBC/PKCS5Padding'
|
47
|
+
:CBC
|
48
|
+
when 'AES/GCM/NoPadding'
|
49
|
+
:GCM
|
50
|
+
else
|
51
|
+
type = envelope['x-amz-cek-alg'].inspect
|
52
|
+
msg = "unsupported content encrypting key (cek) format: #{type}"
|
53
|
+
raise Errors::DecryptionError, msg
|
54
|
+
end
|
55
|
+
Utils.aes_decryption_cipher(block_mode, key, iv)
|
45
56
|
end
|
46
57
|
|
47
58
|
private
|
@@ -57,8 +57,8 @@ module Aws
|
|
57
57
|
# @param [String, nil] iv The initialization vector
|
58
58
|
def aes_cipher(mode, block_mode, key, iv)
|
59
59
|
cipher = key ?
|
60
|
-
OpenSSL::Cipher.new("
|
61
|
-
OpenSSL::Cipher.new("
|
60
|
+
OpenSSL::Cipher.new("aes-#{cipher_size(key)}-#{block_mode.downcase}") :
|
61
|
+
OpenSSL::Cipher.new("aes-256-#{block_mode.downcase}")
|
62
62
|
cipher.send(mode) # encrypt or decrypt
|
63
63
|
cipher.key = key if key
|
64
64
|
cipher.iv = iv if iv
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aws-sdk-resources
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.3.
|
4
|
+
version: 2.3.13
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Amazon Web Services
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-06-
|
11
|
+
date: 2016-06-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk-core
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 2.3.
|
19
|
+
version: 2.3.13
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 2.3.
|
26
|
+
version: 2.3.13
|
27
27
|
description: Provides resource oriented interfaces and other higher-level abstractions
|
28
28
|
for many AWS services. This gem is part of the official AWS SDK for Ruby.
|
29
29
|
email:
|
@@ -65,6 +65,7 @@ files:
|
|
65
65
|
- lib/aws-sdk-resources/services/s3/encryption/default_key_provider.rb
|
66
66
|
- lib/aws-sdk-resources/services/s3/encryption/encrypt_handler.rb
|
67
67
|
- lib/aws-sdk-resources/services/s3/encryption/errors.rb
|
68
|
+
- lib/aws-sdk-resources/services/s3/encryption/io_auth_decrypter.rb
|
68
69
|
- lib/aws-sdk-resources/services/s3/encryption/io_decrypter.rb
|
69
70
|
- lib/aws-sdk-resources/services/s3/encryption/io_encrypter.rb
|
70
71
|
- lib/aws-sdk-resources/services/s3/encryption/key_provider.rb
|