aws-sdk-s3 1.75.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/aws-sdk-s3.rb +73 -0
- data/lib/aws-sdk-s3/bucket.rb +861 -0
- data/lib/aws-sdk-s3/bucket_acl.rb +277 -0
- data/lib/aws-sdk-s3/bucket_cors.rb +262 -0
- data/lib/aws-sdk-s3/bucket_lifecycle.rb +264 -0
- data/lib/aws-sdk-s3/bucket_lifecycle_configuration.rb +283 -0
- data/lib/aws-sdk-s3/bucket_logging.rb +251 -0
- data/lib/aws-sdk-s3/bucket_notification.rb +293 -0
- data/lib/aws-sdk-s3/bucket_policy.rb +242 -0
- data/lib/aws-sdk-s3/bucket_region_cache.rb +81 -0
- data/lib/aws-sdk-s3/bucket_request_payment.rb +236 -0
- data/lib/aws-sdk-s3/bucket_tagging.rb +251 -0
- data/lib/aws-sdk-s3/bucket_versioning.rb +312 -0
- data/lib/aws-sdk-s3/bucket_website.rb +292 -0
- data/lib/aws-sdk-s3/client.rb +11818 -0
- data/lib/aws-sdk-s3/client_api.rb +3014 -0
- data/lib/aws-sdk-s3/customizations.rb +34 -0
- data/lib/aws-sdk-s3/customizations/bucket.rb +162 -0
- data/lib/aws-sdk-s3/customizations/multipart_upload.rb +44 -0
- data/lib/aws-sdk-s3/customizations/object.rb +389 -0
- data/lib/aws-sdk-s3/customizations/object_summary.rb +85 -0
- data/lib/aws-sdk-s3/customizations/types/list_object_versions_output.rb +13 -0
- data/lib/aws-sdk-s3/encryption.rb +21 -0
- data/lib/aws-sdk-s3/encryption/client.rb +375 -0
- data/lib/aws-sdk-s3/encryption/decrypt_handler.rb +190 -0
- data/lib/aws-sdk-s3/encryption/default_cipher_provider.rb +65 -0
- data/lib/aws-sdk-s3/encryption/default_key_provider.rb +40 -0
- data/lib/aws-sdk-s3/encryption/encrypt_handler.rb +61 -0
- data/lib/aws-sdk-s3/encryption/errors.rb +15 -0
- data/lib/aws-sdk-s3/encryption/io_auth_decrypter.rb +58 -0
- data/lib/aws-sdk-s3/encryption/io_decrypter.rb +36 -0
- data/lib/aws-sdk-s3/encryption/io_encrypter.rb +71 -0
- data/lib/aws-sdk-s3/encryption/key_provider.rb +31 -0
- data/lib/aws-sdk-s3/encryption/kms_cipher_provider.rb +75 -0
- data/lib/aws-sdk-s3/encryption/materials.rb +60 -0
- data/lib/aws-sdk-s3/encryption/utils.rb +81 -0
- data/lib/aws-sdk-s3/encryptionV2/client.rb +388 -0
- data/lib/aws-sdk-s3/encryptionV2/decrypt_handler.rb +198 -0
- data/lib/aws-sdk-s3/encryptionV2/default_cipher_provider.rb +103 -0
- data/lib/aws-sdk-s3/encryptionV2/default_key_provider.rb +38 -0
- data/lib/aws-sdk-s3/encryptionV2/encrypt_handler.rb +66 -0
- data/lib/aws-sdk-s3/encryptionV2/errors.rb +13 -0
- data/lib/aws-sdk-s3/encryptionV2/io_auth_decrypter.rb +56 -0
- data/lib/aws-sdk-s3/encryptionV2/io_decrypter.rb +35 -0
- data/lib/aws-sdk-s3/encryptionV2/io_encrypter.rb +71 -0
- data/lib/aws-sdk-s3/encryptionV2/key_provider.rb +29 -0
- data/lib/aws-sdk-s3/encryptionV2/kms_cipher_provider.rb +99 -0
- data/lib/aws-sdk-s3/encryptionV2/materials.rb +58 -0
- data/lib/aws-sdk-s3/encryptionV2/utils.rb +116 -0
- data/lib/aws-sdk-s3/encryption_v2.rb +20 -0
- data/lib/aws-sdk-s3/errors.rb +115 -0
- data/lib/aws-sdk-s3/event_streams.rb +69 -0
- data/lib/aws-sdk-s3/file_downloader.rb +142 -0
- data/lib/aws-sdk-s3/file_part.rb +78 -0
- data/lib/aws-sdk-s3/file_uploader.rb +70 -0
- data/lib/aws-sdk-s3/legacy_signer.rb +189 -0
- data/lib/aws-sdk-s3/multipart_file_uploader.rb +227 -0
- data/lib/aws-sdk-s3/multipart_stream_uploader.rb +173 -0
- data/lib/aws-sdk-s3/multipart_upload.rb +401 -0
- data/lib/aws-sdk-s3/multipart_upload_error.rb +18 -0
- data/lib/aws-sdk-s3/multipart_upload_part.rb +423 -0
- data/lib/aws-sdk-s3/object.rb +1422 -0
- data/lib/aws-sdk-s3/object_acl.rb +333 -0
- data/lib/aws-sdk-s3/object_copier.rb +101 -0
- data/lib/aws-sdk-s3/object_multipart_copier.rb +182 -0
- data/lib/aws-sdk-s3/object_summary.rb +1181 -0
- data/lib/aws-sdk-s3/object_version.rb +550 -0
- data/lib/aws-sdk-s3/plugins/accelerate.rb +87 -0
- data/lib/aws-sdk-s3/plugins/bucket_arn.rb +212 -0
- data/lib/aws-sdk-s3/plugins/bucket_dns.rb +91 -0
- data/lib/aws-sdk-s3/plugins/bucket_name_restrictions.rb +45 -0
- data/lib/aws-sdk-s3/plugins/dualstack.rb +74 -0
- data/lib/aws-sdk-s3/plugins/expect_100_continue.rb +28 -0
- data/lib/aws-sdk-s3/plugins/get_bucket_location_fix.rb +25 -0
- data/lib/aws-sdk-s3/plugins/http_200_errors.rb +55 -0
- data/lib/aws-sdk-s3/plugins/iad_regional_endpoint.rb +62 -0
- data/lib/aws-sdk-s3/plugins/location_constraint.rb +35 -0
- data/lib/aws-sdk-s3/plugins/md5s.rb +84 -0
- data/lib/aws-sdk-s3/plugins/redirects.rb +45 -0
- data/lib/aws-sdk-s3/plugins/s3_host_id.rb +30 -0
- data/lib/aws-sdk-s3/plugins/s3_signer.rb +222 -0
- data/lib/aws-sdk-s3/plugins/sse_cpk.rb +70 -0
- data/lib/aws-sdk-s3/plugins/streaming_retry.rb +118 -0
- data/lib/aws-sdk-s3/plugins/url_encoded_keys.rb +97 -0
- data/lib/aws-sdk-s3/presigned_post.rb +686 -0
- data/lib/aws-sdk-s3/presigner.rb +253 -0
- data/lib/aws-sdk-s3/resource.rb +117 -0
- data/lib/aws-sdk-s3/types.rb +13154 -0
- data/lib/aws-sdk-s3/waiters.rb +243 -0
- metadata +184 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module Aws
|
|
2
|
+
module S3
|
|
3
|
+
module EncryptionV2
|
|
4
|
+
# @api private
|
|
5
|
+
class IODecrypter
|
|
6
|
+
|
|
7
|
+
# @param [OpenSSL::Cipher] cipher
|
|
8
|
+
# @param [IO#write] io An IO-like object that responds to `#write`.
|
|
9
|
+
def initialize(cipher, io)
|
|
10
|
+
@cipher = cipher
|
|
11
|
+
# Ensure that IO is reset between retries
|
|
12
|
+
@io = io.tap { |io| io.truncate(0) if io.respond_to?(:truncate) }
|
|
13
|
+
@cipher_buffer = String.new
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# @return [#write]
|
|
17
|
+
attr_reader :io
|
|
18
|
+
|
|
19
|
+
def write(chunk)
|
|
20
|
+
# decrypt and write
|
|
21
|
+
if @cipher.method(:update).arity == 1
|
|
22
|
+
@io.write(@cipher.update(chunk))
|
|
23
|
+
else
|
|
24
|
+
@io.write(@cipher.update(chunk, @cipher_buffer))
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def finalize
|
|
29
|
+
@io.write(@cipher.final)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
require 'stringio'
|
|
2
|
+
require 'tempfile'
|
|
3
|
+
|
|
4
|
+
module Aws
|
|
5
|
+
module S3
|
|
6
|
+
module EncryptionV2
|
|
7
|
+
|
|
8
|
+
# Provides an IO wrapper encrypting a stream of data.
|
|
9
|
+
# @api private
|
|
10
|
+
class IOEncrypter
|
|
11
|
+
|
|
12
|
+
# @api private
|
|
13
|
+
ONE_MEGABYTE = 1024 * 1024
|
|
14
|
+
|
|
15
|
+
def initialize(cipher, io)
|
|
16
|
+
@encrypted = io.size <= ONE_MEGABYTE ?
|
|
17
|
+
encrypt_to_stringio(cipher, io.read) :
|
|
18
|
+
encrypt_to_tempfile(cipher, io)
|
|
19
|
+
@size = @encrypted.size
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# @return [Integer]
|
|
23
|
+
attr_reader :size
|
|
24
|
+
|
|
25
|
+
def read(bytes = nil, output_buffer = nil)
|
|
26
|
+
if @encrypted.is_a?(Tempfile) && @encrypted.closed?
|
|
27
|
+
@encrypted.open
|
|
28
|
+
@encrypted.binmode
|
|
29
|
+
end
|
|
30
|
+
@encrypted.read(bytes, output_buffer)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def rewind
|
|
34
|
+
@encrypted.rewind
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# @api private
|
|
38
|
+
def close
|
|
39
|
+
@encrypted.close if @encrypted.is_a?(Tempfile)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
|
|
44
|
+
def encrypt_to_stringio(cipher, plain_text)
|
|
45
|
+
if plain_text.empty?
|
|
46
|
+
StringIO.new(cipher.final + cipher.auth_tag)
|
|
47
|
+
else
|
|
48
|
+
StringIO.new(cipher.update(plain_text) + cipher.final + cipher.auth_tag)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def encrypt_to_tempfile(cipher, io)
|
|
53
|
+
encrypted = Tempfile.new(self.object_id.to_s)
|
|
54
|
+
encrypted.binmode
|
|
55
|
+
while chunk = io.read(ONE_MEGABYTE, read_buffer ||= String.new)
|
|
56
|
+
if cipher.method(:update).arity == 1
|
|
57
|
+
encrypted.write(cipher.update(chunk))
|
|
58
|
+
else
|
|
59
|
+
encrypted.write(cipher.update(chunk, cipher_buffer ||= String.new))
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
encrypted.write(cipher.final)
|
|
63
|
+
encrypted.write(cipher.auth_tag)
|
|
64
|
+
encrypted.rewind
|
|
65
|
+
encrypted
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Aws
|
|
2
|
+
module S3
|
|
3
|
+
module EncryptionV2
|
|
4
|
+
|
|
5
|
+
# This module defines the interface required for a {Client#key_provider}.
|
|
6
|
+
# A key provider is any object that:
|
|
7
|
+
#
|
|
8
|
+
# * Responds to {#encryption_materials} with an {Materials} object.
|
|
9
|
+
#
|
|
10
|
+
# * Responds to {#key_for}, receiving a JSON document String,
|
|
11
|
+
# returning an encryption key. The returned encryption key
|
|
12
|
+
# must be one of:
|
|
13
|
+
#
|
|
14
|
+
# * `OpenSSL::PKey::RSA` - for asymmetric encryption
|
|
15
|
+
# * `String` - 32, 24, or 16 bytes long, for symmetric encryption
|
|
16
|
+
#
|
|
17
|
+
module KeyProvider
|
|
18
|
+
|
|
19
|
+
# @return [Materials]
|
|
20
|
+
def encryption_materials; end
|
|
21
|
+
|
|
22
|
+
# @param [String<JSON>] materials_description
|
|
23
|
+
# @return [OpenSSL::PKey::RSA, String] encryption_key
|
|
24
|
+
def key_for(materials_description); end
|
|
25
|
+
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
require 'base64'
|
|
2
|
+
|
|
3
|
+
module Aws
|
|
4
|
+
module S3
|
|
5
|
+
module EncryptionV2
|
|
6
|
+
# @api private
|
|
7
|
+
class KmsCipherProvider
|
|
8
|
+
|
|
9
|
+
def initialize(options = {})
|
|
10
|
+
@kms_key_id = options[:kms_key_id]
|
|
11
|
+
@kms_client = options[:kms_client]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# @return [Array<Hash,Cipher>] Creates and returns a new encryption
|
|
15
|
+
# envelope and encryption cipher.
|
|
16
|
+
def encryption_cipher(options = {})
|
|
17
|
+
cek_alg = 'AES/GCM/NoPadding'
|
|
18
|
+
encryption_context = build_encryption_context(cek_alg, options)
|
|
19
|
+
key_data = @kms_client.generate_data_key(
|
|
20
|
+
key_id: @kms_key_id,
|
|
21
|
+
encryption_context: encryption_context,
|
|
22
|
+
key_spec: 'AES_256'
|
|
23
|
+
)
|
|
24
|
+
cipher = Utils.aes_encryption_cipher(:GCM)
|
|
25
|
+
cipher.key = key_data.plaintext
|
|
26
|
+
envelope = {
|
|
27
|
+
'x-amz-key-v2' => encode64(key_data.ciphertext_blob),
|
|
28
|
+
'x-amz-iv' => encode64(cipher.iv = cipher.random_iv),
|
|
29
|
+
'x-amz-cek-alg' => cek_alg,
|
|
30
|
+
'x-amz-tag-len' => 16 * 8,
|
|
31
|
+
'x-amz-wrap-alg' => 'kms+context',
|
|
32
|
+
'x-amz-matdesc' => Json.dump(encryption_context)
|
|
33
|
+
}
|
|
34
|
+
cipher.auth_data = '' # auth_data must be set after key and iv
|
|
35
|
+
[envelope, cipher]
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# @return [Cipher] Given an encryption envelope, returns a
|
|
39
|
+
# decryption cipher.
|
|
40
|
+
def decryption_cipher(envelope, options={})
|
|
41
|
+
encryption_context = Json.load(envelope['x-amz-matdesc'])
|
|
42
|
+
cek_alg = envelope['x-amz-wrap-alg'] == 'kms+context' ?
|
|
43
|
+
encryption_context['aws:x-amz-cek-alg'] : envelope['x-amz-cek-alg']
|
|
44
|
+
if cek_alg != envelope['x-amz-cek-alg']
|
|
45
|
+
raise Errors::DecryptionError, 'Value of cek-alg from envelope'\
|
|
46
|
+
' does not match the value in the encryption context'
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
if envelope['x-amz-wrap-alg'] == 'kms+context' &&
|
|
50
|
+
encryption_context != build_encryption_context(cek_alg, options)
|
|
51
|
+
raise Errors::DecryptionError, 'Value of encryption context from'\
|
|
52
|
+
' envelope does not match the provided encryption context'
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
key = @kms_client.decrypt(
|
|
56
|
+
ciphertext_blob: decode64(envelope['x-amz-key-v2']),
|
|
57
|
+
encryption_context: encryption_context
|
|
58
|
+
).plaintext
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
iv = decode64(envelope['x-amz-iv'])
|
|
62
|
+
block_mode =
|
|
63
|
+
case cek_alg
|
|
64
|
+
when 'AES/CBC/PKCS5Padding'
|
|
65
|
+
:CBC
|
|
66
|
+
when 'AES/CBC/PKCS7Padding'
|
|
67
|
+
:CBC
|
|
68
|
+
when 'AES/GCM/NoPadding'
|
|
69
|
+
:GCM
|
|
70
|
+
else
|
|
71
|
+
type = envelope['x-amz-cek-alg'].inspect
|
|
72
|
+
msg = "unsupported content encrypting key (cek) format: #{type}"
|
|
73
|
+
raise Errors::DecryptionError, msg
|
|
74
|
+
end
|
|
75
|
+
Utils.aes_decryption_cipher(block_mode, key, iv)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
private
|
|
79
|
+
|
|
80
|
+
def build_encryption_context(cek_alg, options = {})
|
|
81
|
+
kms_context = (options[:kms_encryption_context] || {})
|
|
82
|
+
.each_with_object({}) { |(k, v), h| h[k.to_s] = v }
|
|
83
|
+
{
|
|
84
|
+
'aws:x-amz-cek-alg' => cek_alg
|
|
85
|
+
}.merge(kms_context)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def encode64(str)
|
|
89
|
+
Base64.encode64(str).split("\n") * ""
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def decode64(str)
|
|
93
|
+
Base64.decode64(str)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require 'base64'
|
|
2
|
+
|
|
3
|
+
module Aws
|
|
4
|
+
module S3
|
|
5
|
+
module EncryptionV2
|
|
6
|
+
class Materials
|
|
7
|
+
|
|
8
|
+
# @option options [required, OpenSSL::PKey::RSA, String] :key
|
|
9
|
+
# The master key to use for encrypting/decrypting all objects.
|
|
10
|
+
#
|
|
11
|
+
# @option options [String<JSON>] :description ('{}')
|
|
12
|
+
# The encryption materials description. This is must be
|
|
13
|
+
# a JSON document string.
|
|
14
|
+
#
|
|
15
|
+
def initialize(options = {})
|
|
16
|
+
@key = validate_key(options[:key])
|
|
17
|
+
@description = validate_desc(options[:description])
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# @return [OpenSSL::PKey::RSA, String]
|
|
21
|
+
attr_reader :key
|
|
22
|
+
|
|
23
|
+
# @return [String<JSON>]
|
|
24
|
+
attr_reader :description
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def validate_key(key)
|
|
29
|
+
case key
|
|
30
|
+
when OpenSSL::PKey::RSA then key
|
|
31
|
+
when String
|
|
32
|
+
if [32, 24, 16].include?(key.bytesize)
|
|
33
|
+
key
|
|
34
|
+
else
|
|
35
|
+
msg = 'invalid key, symmetric key required to be 16, 24, or '\
|
|
36
|
+
'32 bytes in length, saw length ' + key.bytesize.to_s
|
|
37
|
+
raise ArgumentError, msg
|
|
38
|
+
end
|
|
39
|
+
else
|
|
40
|
+
msg = 'invalid encryption key, expected an OpenSSL::PKey::RSA key '\
|
|
41
|
+
'(for asymmetric encryption) or a String (for symmetric '\
|
|
42
|
+
'encryption).'
|
|
43
|
+
raise ArgumentError, msg
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def validate_desc(description)
|
|
48
|
+
Json.load(description)
|
|
49
|
+
description
|
|
50
|
+
rescue Json::ParseError, EncodingError
|
|
51
|
+
msg = 'expected description to be a valid JSON document string'
|
|
52
|
+
raise ArgumentError, msg
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
require 'openssl'
|
|
2
|
+
|
|
3
|
+
module Aws
|
|
4
|
+
module S3
|
|
5
|
+
module EncryptionV2
|
|
6
|
+
# @api private
|
|
7
|
+
module Utils
|
|
8
|
+
|
|
9
|
+
UNSAFE_MSG = "unsafe encryption, data is longer than key length"
|
|
10
|
+
|
|
11
|
+
class << self
|
|
12
|
+
|
|
13
|
+
def encrypt(key, data)
|
|
14
|
+
case key
|
|
15
|
+
when OpenSSL::PKey::RSA # asymmetric encryption
|
|
16
|
+
warn(UNSAFE_MSG) if key.public_key.n.num_bits < cipher_size(data)
|
|
17
|
+
key.public_encrypt(data)
|
|
18
|
+
when String # symmetric encryption
|
|
19
|
+
warn(UNSAFE_MSG) if cipher_size(key) < cipher_size(data)
|
|
20
|
+
cipher = aes_encryption_cipher(:ECB, key)
|
|
21
|
+
cipher.update(data) + cipher.final
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def encrypt_aes_gcm(key, data, auth_data)
|
|
26
|
+
warn(UNSAFE_MSG) if cipher_size(key) < cipher_size(data)
|
|
27
|
+
cipher = aes_encryption_cipher(:GCM, key)
|
|
28
|
+
cipher.iv = (iv = cipher.random_iv)
|
|
29
|
+
cipher.auth_data = auth_data
|
|
30
|
+
|
|
31
|
+
iv + cipher.update(data) + cipher.final + cipher.auth_tag
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def encrypt_rsa(key, data, auth_data)
|
|
35
|
+
# Plaintext must be KeyLengthInBytes (1 Byte) + DataKey + AuthData
|
|
36
|
+
buf = [data.bytesize] + data.unpack('C*') + auth_data.unpack('C*')
|
|
37
|
+
key.public_encrypt(buf.pack('C*'), OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def decrypt(key, data)
|
|
41
|
+
begin
|
|
42
|
+
case key
|
|
43
|
+
when OpenSSL::PKey::RSA # asymmetric decryption
|
|
44
|
+
key.private_decrypt(data)
|
|
45
|
+
when String # symmetric Decryption
|
|
46
|
+
cipher = aes_cipher(:decrypt, :ECB, key, nil)
|
|
47
|
+
cipher.update(data) + cipher.final
|
|
48
|
+
end
|
|
49
|
+
rescue OpenSSL::Cipher::CipherError
|
|
50
|
+
msg = 'decryption failed, possible incorrect key'
|
|
51
|
+
raise Errors::DecryptionError, msg
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def decrypt_aes_gcm(key, data, auth_data)
|
|
56
|
+
# data is iv (12B) + key + tag (16B)
|
|
57
|
+
buf = data.unpack('C*')
|
|
58
|
+
iv = buf[0,12].pack('C*') # iv will always be 12 bytes
|
|
59
|
+
tag = buf[-16, 16].pack('C*') # tag is 16 bytes
|
|
60
|
+
enc_key = buf[12, buf.size - (12+16)].pack('C*')
|
|
61
|
+
cipher = aes_cipher(:decrypt, :GCM, key, iv)
|
|
62
|
+
cipher.auth_tag = tag
|
|
63
|
+
cipher.auth_data = auth_data
|
|
64
|
+
cipher.update(enc_key) + cipher.final
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# returns the decrypted data + auth_data
|
|
68
|
+
def decrypt_rsa(key, enc_data)
|
|
69
|
+
# Plaintext must be KeyLengthInBytes (1 Byte) + DataKey + AuthData
|
|
70
|
+
buf = key.private_decrypt(enc_data, OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING).unpack('C*')
|
|
71
|
+
key_length = buf[0]
|
|
72
|
+
data = buf[1, key_length].pack('C*')
|
|
73
|
+
auth_data = buf[key_length+1, buf.length - key_length].pack('C*')
|
|
74
|
+
[data, auth_data]
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# @param [String] block_mode "CBC" or "ECB"
|
|
78
|
+
# @param [OpenSSL::PKey::RSA, String, nil] key
|
|
79
|
+
# @param [String, nil] iv The initialization vector
|
|
80
|
+
def aes_encryption_cipher(block_mode, key = nil, iv = nil)
|
|
81
|
+
aes_cipher(:encrypt, block_mode, key, iv)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# @param [String] block_mode "CBC" or "ECB"
|
|
85
|
+
# @param [OpenSSL::PKey::RSA, String, nil] key
|
|
86
|
+
# @param [String, nil] iv The initialization vector
|
|
87
|
+
def aes_decryption_cipher(block_mode, key = nil, iv = nil)
|
|
88
|
+
aes_cipher(:decrypt, block_mode, key, iv)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# @param [String] mode "encrypt" or "decrypt"
|
|
92
|
+
# @param [String] block_mode "CBC" or "ECB"
|
|
93
|
+
# @param [OpenSSL::PKey::RSA, String, nil] key
|
|
94
|
+
# @param [String, nil] iv The initialization vector
|
|
95
|
+
def aes_cipher(mode, block_mode, key, iv)
|
|
96
|
+
cipher = key ?
|
|
97
|
+
OpenSSL::Cipher.new("aes-#{cipher_size(key)}-#{block_mode.downcase}") :
|
|
98
|
+
OpenSSL::Cipher.new("aes-256-#{block_mode.downcase}")
|
|
99
|
+
cipher.send(mode) # encrypt or decrypt
|
|
100
|
+
cipher.key = key if key
|
|
101
|
+
cipher.iv = iv if iv
|
|
102
|
+
cipher
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# @param [String] key
|
|
106
|
+
# @return [Integer]
|
|
107
|
+
# @raise ArgumentError
|
|
108
|
+
def cipher_size(key)
|
|
109
|
+
key.bytesize * 8
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require 'aws-sdk-s3/encryptionV2/client'
|
|
2
|
+
require 'aws-sdk-s3/encryptionV2/decrypt_handler'
|
|
3
|
+
require 'aws-sdk-s3/encryptionV2/default_cipher_provider'
|
|
4
|
+
require 'aws-sdk-s3/encryptionV2/encrypt_handler'
|
|
5
|
+
require 'aws-sdk-s3/encryptionV2/errors'
|
|
6
|
+
require 'aws-sdk-s3/encryptionV2/io_encrypter'
|
|
7
|
+
require 'aws-sdk-s3/encryptionV2/io_decrypter'
|
|
8
|
+
require 'aws-sdk-s3/encryptionV2/io_auth_decrypter'
|
|
9
|
+
require 'aws-sdk-s3/encryptionV2/key_provider'
|
|
10
|
+
require 'aws-sdk-s3/encryptionV2/kms_cipher_provider'
|
|
11
|
+
require 'aws-sdk-s3/encryptionV2/materials'
|
|
12
|
+
require 'aws-sdk-s3/encryptionV2/utils'
|
|
13
|
+
require 'aws-sdk-s3/encryptionV2/default_key_provider'
|
|
14
|
+
|
|
15
|
+
module Aws
|
|
16
|
+
module S3
|
|
17
|
+
module EncryptionV2; end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# WARNING ABOUT GENERATED CODE
|
|
4
|
+
#
|
|
5
|
+
# This file is generated. See the contributing guide for more information:
|
|
6
|
+
# https://github.com/aws/aws-sdk-ruby/blob/master/CONTRIBUTING.md
|
|
7
|
+
#
|
|
8
|
+
# WARNING ABOUT GENERATED CODE
|
|
9
|
+
|
|
10
|
+
module Aws::S3
|
|
11
|
+
|
|
12
|
+
# When S3 returns an error response, the Ruby SDK constructs and raises an error.
|
|
13
|
+
# These errors all extend Aws::S3::Errors::ServiceError < {Aws::Errors::ServiceError}
|
|
14
|
+
#
|
|
15
|
+
# You can rescue all S3 errors using ServiceError:
|
|
16
|
+
#
|
|
17
|
+
# begin
|
|
18
|
+
# # do stuff
|
|
19
|
+
# rescue Aws::S3::Errors::ServiceError
|
|
20
|
+
# # rescues all S3 API errors
|
|
21
|
+
# end
|
|
22
|
+
#
|
|
23
|
+
#
|
|
24
|
+
# ## Request Context
|
|
25
|
+
# ServiceError objects have a {Aws::Errors::ServiceError#context #context} method that returns
|
|
26
|
+
# information about the request that generated the error.
|
|
27
|
+
# See {Seahorse::Client::RequestContext} for more information.
|
|
28
|
+
#
|
|
29
|
+
# ## Error Classes
|
|
30
|
+
# * {BucketAlreadyExists}
|
|
31
|
+
# * {BucketAlreadyOwnedByYou}
|
|
32
|
+
# * {NoSuchBucket}
|
|
33
|
+
# * {NoSuchKey}
|
|
34
|
+
# * {NoSuchUpload}
|
|
35
|
+
# * {ObjectAlreadyInActiveTierError}
|
|
36
|
+
# * {ObjectNotInActiveTierError}
|
|
37
|
+
#
|
|
38
|
+
# Additionally, error classes are dynamically generated for service errors based on the error code
|
|
39
|
+
# if they are not defined above.
|
|
40
|
+
module Errors
|
|
41
|
+
|
|
42
|
+
extend Aws::Errors::DynamicErrors
|
|
43
|
+
|
|
44
|
+
class BucketAlreadyExists < ServiceError
|
|
45
|
+
|
|
46
|
+
# @param [Seahorse::Client::RequestContext] context
|
|
47
|
+
# @param [String] message
|
|
48
|
+
# @param [Aws::S3::Types::BucketAlreadyExists] data
|
|
49
|
+
def initialize(context, message, data = Aws::EmptyStructure.new)
|
|
50
|
+
super(context, message, data)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
class BucketAlreadyOwnedByYou < ServiceError
|
|
55
|
+
|
|
56
|
+
# @param [Seahorse::Client::RequestContext] context
|
|
57
|
+
# @param [String] message
|
|
58
|
+
# @param [Aws::S3::Types::BucketAlreadyOwnedByYou] data
|
|
59
|
+
def initialize(context, message, data = Aws::EmptyStructure.new)
|
|
60
|
+
super(context, message, data)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
class NoSuchBucket < ServiceError
|
|
65
|
+
|
|
66
|
+
# @param [Seahorse::Client::RequestContext] context
|
|
67
|
+
# @param [String] message
|
|
68
|
+
# @param [Aws::S3::Types::NoSuchBucket] data
|
|
69
|
+
def initialize(context, message, data = Aws::EmptyStructure.new)
|
|
70
|
+
super(context, message, data)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
class NoSuchKey < ServiceError
|
|
75
|
+
|
|
76
|
+
# @param [Seahorse::Client::RequestContext] context
|
|
77
|
+
# @param [String] message
|
|
78
|
+
# @param [Aws::S3::Types::NoSuchKey] data
|
|
79
|
+
def initialize(context, message, data = Aws::EmptyStructure.new)
|
|
80
|
+
super(context, message, data)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
class NoSuchUpload < ServiceError
|
|
85
|
+
|
|
86
|
+
# @param [Seahorse::Client::RequestContext] context
|
|
87
|
+
# @param [String] message
|
|
88
|
+
# @param [Aws::S3::Types::NoSuchUpload] data
|
|
89
|
+
def initialize(context, message, data = Aws::EmptyStructure.new)
|
|
90
|
+
super(context, message, data)
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
class ObjectAlreadyInActiveTierError < ServiceError
|
|
95
|
+
|
|
96
|
+
# @param [Seahorse::Client::RequestContext] context
|
|
97
|
+
# @param [String] message
|
|
98
|
+
# @param [Aws::S3::Types::ObjectAlreadyInActiveTierError] data
|
|
99
|
+
def initialize(context, message, data = Aws::EmptyStructure.new)
|
|
100
|
+
super(context, message, data)
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
class ObjectNotInActiveTierError < ServiceError
|
|
105
|
+
|
|
106
|
+
# @param [Seahorse::Client::RequestContext] context
|
|
107
|
+
# @param [String] message
|
|
108
|
+
# @param [Aws::S3::Types::ObjectNotInActiveTierError] data
|
|
109
|
+
def initialize(context, message, data = Aws::EmptyStructure.new)
|
|
110
|
+
super(context, message, data)
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
end
|
|
115
|
+
end
|