5
5
"context"
6
6
"crypto/md5"
7
7
"encoding/base64"
8
+ "errors"
8
9
"fmt"
9
10
"github.com/aws/aws-sdk-go-v2/aws"
10
11
"os"
@@ -113,6 +114,13 @@ func ResourceObject() *schema.Resource {
113
114
Sensitive : true ,
114
115
Description : "Customer's encryption keys to encrypt data (SSE-C)" ,
115
116
},
117
+ "sse_cutomer_key_md5" : {
118
+ Type : schema .TypeString ,
119
+ Optional : true ,
120
+ Sensitive : true ,
121
+ Description : "Cutomer's encryption key MD5 to encrypt data (SSE-C)" ,
122
+ Computed : true ,
123
+ },
116
124
"region" : regional .Schema (),
117
125
"project_id" : account .ProjectIDSchema (),
118
126
},
@@ -157,17 +165,13 @@ func resourceObjectCreate(ctx context.Context, d *schema.ResourceData, m interfa
157
165
}
158
166
159
167
if encryptionKeyStr , ok := d .Get ("sse_customer_key" ).(string ); ok {
160
- encryptionKey := []byte (encryptionKeyStr )
161
- h := md5 .New ()
162
- _ , err := h .Write (encryptionKey )
168
+ digestMD5 , encryption , err := EncryptCustomerKey (encryptionKeyStr )
163
169
if err != nil {
164
170
return diag .FromErr (err )
165
171
}
166
- digest := h .Sum (nil )
167
- digestMD5 := base64 .StdEncoding .EncodeToString (digest )
168
172
req .SSECustomerAlgorithm = scw .StringPtr ("AES256" )
169
173
req .SSECustomerKeyMD5 = & digestMD5
170
- req .SSECustomerKey = aws . String ( base64 . StdEncoding . EncodeToString ( encryptionKey ))
174
+ req .SSECustomerKey = encryption
171
175
}
172
176
173
177
if filePath , hasFile := d .GetOk ("file" ); hasFile {
@@ -214,6 +218,23 @@ func resourceObjectCreate(ctx context.Context, d *schema.ResourceData, m interfa
214
218
return resourceObjectRead (ctx , d , m )
215
219
}
216
220
221
+ func EncryptCustomerKey (encryptionKeyStr string ) (string , * string , error ) {
222
+ encryptionKey := []byte (encryptionKeyStr )
223
+ // TODO remove when error message fix
224
+ if len (encryptionKey ) != 32 {
225
+ return "" , nil , errors .New ("encryption key must be 32 bytes long" )
226
+ }
227
+ h := md5 .New ()
228
+ _ , err := h .Write (encryptionKey )
229
+ if err != nil {
230
+ return "" , nil , err
231
+ }
232
+ digest := h .Sum (nil )
233
+ digestMD5 := base64 .StdEncoding .EncodeToString (digest )
234
+ encryption := aws .String (base64 .StdEncoding .EncodeToString (encryptionKey ))
235
+ return digestMD5 , encryption , nil
236
+ }
237
+
217
238
func resourceObjectUpdate (ctx context.Context , d * schema.ResourceData , m interface {}) diag.Diagnostics {
218
239
s3Client , region , key , bucket , err := s3ClientWithRegionAndNestedName (ctx , d , m , d .Id ())
219
240
if err != nil {
@@ -234,7 +255,15 @@ func resourceObjectUpdate(ctx context.Context, d *schema.ResourceData, m interfa
234
255
Metadata : types .ExpandMapStringString (d .Get ("metadata" )),
235
256
ACL : s3Types .ObjectCannedACL (d .Get ("visibility" ).(string )),
236
257
}
237
-
258
+ if encryptionKey , ok := d .GetOk ("sse_customer_key" ); ok {
259
+ digestMD5 , encryption , err := EncryptCustomerKey (encryptionKey .(string ))
260
+ if err != nil {
261
+ return diag .FromErr (err )
262
+ }
263
+ req .SSECustomerAlgorithm = scw .StringPtr ("AES256" )
264
+ req .SSECustomerKeyMD5 = & digestMD5
265
+ req .SSECustomerKey = encryption
266
+ }
238
267
if filePath , hasFile := d .GetOk ("file" ); hasFile {
239
268
file , err := os .Open (filePath .(string ))
240
269
if err != nil {
@@ -246,14 +275,24 @@ func resourceObjectUpdate(ctx context.Context, d *schema.ResourceData, m interfa
246
275
}
247
276
_ , err = s3Client .PutObject (ctx , req )
248
277
} else {
249
- _ , err = s3Client . CopyObject ( ctx , & s3.CopyObjectInput {
278
+ req := & s3.CopyObjectInput {
250
279
Bucket : types .ExpandStringPtr (bucketUpdated ),
251
280
Key : types .ExpandStringPtr (keyUpdated ),
252
281
StorageClass : s3Types .StorageClass (d .Get ("storage_class" ).(string )),
253
282
CopySource : scw .StringPtr (fmt .Sprintf ("%s/%s" , bucket , key )),
254
283
Metadata : types .ExpandMapStringString (d .Get ("metadata" )),
255
284
ACL : s3Types .ObjectCannedACL (d .Get ("visibility" ).(string )),
256
- })
285
+ }
286
+ if encryptionKey , ok := d .GetOk ("sse_customer_key" ); ok {
287
+ digestMD5 , encryption , err := EncryptCustomerKey (encryptionKey .(string ))
288
+ if err != nil {
289
+ return diag .FromErr (err )
290
+ }
291
+ req .CopySourceSSECustomerAlgorithm = scw .StringPtr ("AES256" )
292
+ req .CopySourceSSECustomerKeyMD5 = & digestMD5
293
+ req .CopySourceSSECustomerKey = encryption
294
+ }
295
+ _ , err = s3Client .CopyObject (ctx , req )
257
296
}
258
297
if err != nil {
259
298
return diag .FromErr (err )
@@ -301,6 +340,11 @@ func resourceObjectRead(ctx context.Context, d *schema.ResourceData, m interface
301
340
Key : types .ExpandStringPtr (key ),
302
341
}
303
342
343
+ if encryption , ok := d .GetOk ("sse_customer_key" ); ok {
344
+ req .SSECustomerKey = aws .String (base64 .StdEncoding .EncodeToString ([]byte (encryption .(string ))))
345
+ req .SSECustomerAlgorithm = scw .StringPtr ("AES256" )
346
+ }
347
+
304
348
obj , err := s3Client .HeadObject (ctx , req )
305
349
if err != nil {
306
350
return diag .FromErr (err )
0 commit comments