55 "context"
66 "crypto/md5"
77 "encoding/base64"
8+ "errors"
89 "fmt"
910 "github.com/aws/aws-sdk-go-v2/aws"
1011 "os"
@@ -113,6 +114,13 @@ func ResourceObject() *schema.Resource {
113114 Sensitive : true ,
114115 Description : "Customer's encryption keys to encrypt data (SSE-C)" ,
115116 },
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+ },
116124 "region" : regional .Schema (),
117125 "project_id" : account .ProjectIDSchema (),
118126 },
@@ -157,17 +165,13 @@ func resourceObjectCreate(ctx context.Context, d *schema.ResourceData, m interfa
157165 }
158166
159167 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 )
163169 if err != nil {
164170 return diag .FromErr (err )
165171 }
166- digest := h .Sum (nil )
167- digestMD5 := base64 .StdEncoding .EncodeToString (digest )
168172 req .SSECustomerAlgorithm = scw .StringPtr ("AES256" )
169173 req .SSECustomerKeyMD5 = & digestMD5
170- req .SSECustomerKey = aws . String ( base64 . StdEncoding . EncodeToString ( encryptionKey ))
174+ req .SSECustomerKey = encryption
171175 }
172176
173177 if filePath , hasFile := d .GetOk ("file" ); hasFile {
@@ -214,6 +218,23 @@ func resourceObjectCreate(ctx context.Context, d *schema.ResourceData, m interfa
214218 return resourceObjectRead (ctx , d , m )
215219}
216220
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+
217238func resourceObjectUpdate (ctx context.Context , d * schema.ResourceData , m interface {}) diag.Diagnostics {
218239 s3Client , region , key , bucket , err := s3ClientWithRegionAndNestedName (ctx , d , m , d .Id ())
219240 if err != nil {
@@ -234,7 +255,15 @@ func resourceObjectUpdate(ctx context.Context, d *schema.ResourceData, m interfa
234255 Metadata : types .ExpandMapStringString (d .Get ("metadata" )),
235256 ACL : s3Types .ObjectCannedACL (d .Get ("visibility" ).(string )),
236257 }
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+ }
238267 if filePath , hasFile := d .GetOk ("file" ); hasFile {
239268 file , err := os .Open (filePath .(string ))
240269 if err != nil {
@@ -246,14 +275,24 @@ func resourceObjectUpdate(ctx context.Context, d *schema.ResourceData, m interfa
246275 }
247276 _ , err = s3Client .PutObject (ctx , req )
248277 } else {
249- _ , err = s3Client . CopyObject ( ctx , & s3.CopyObjectInput {
278+ req := & s3.CopyObjectInput {
250279 Bucket : types .ExpandStringPtr (bucketUpdated ),
251280 Key : types .ExpandStringPtr (keyUpdated ),
252281 StorageClass : s3Types .StorageClass (d .Get ("storage_class" ).(string )),
253282 CopySource : scw .StringPtr (fmt .Sprintf ("%s/%s" , bucket , key )),
254283 Metadata : types .ExpandMapStringString (d .Get ("metadata" )),
255284 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 )
257296 }
258297 if err != nil {
259298 return diag .FromErr (err )
@@ -301,6 +340,11 @@ func resourceObjectRead(ctx context.Context, d *schema.ResourceData, m interface
301340 Key : types .ExpandStringPtr (key ),
302341 }
303342
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+
304348 obj , err := s3Client .HeadObject (ctx , req )
305349 if err != nil {
306350 return diag .FromErr (err )
0 commit comments