diff --git a/cmd/encryption-v1.go b/cmd/encryption-v1.go index 49271803f..36857851c 100644 --- a/cmd/encryption-v1.go +++ b/cmd/encryption-v1.go @@ -356,9 +356,9 @@ func rotateKey(ctx context.Context, oldKey []byte, newKeyID string, newKey []byt } // checkSSECCopySourceKey authenticates the SSE-C copy source key against the -// sealed object key held in metadata. GetObjectNInfo builds no decryptor for a -// zero byte object, so a copy whose data path never decrypts anything has to -// verify the source key explicitly. Mirrors the errors rotateKey reports. +// sealed object key held in metadata. This keeps the diverted rotation safe on +// its own and remains defense in depth when the read path also authenticates +// zero-byte objects. Mirrors the errors rotateKey reports. func checkSSECCopySourceKey(h http.Header, metadata map[string]string, bucket, object string, newKey []byte) error { oldKey, err := ParseSSECopyCustomerRequest(h, metadata) if err != nil { diff --git a/cmd/object-copy-metadata_test.go b/cmd/object-copy-metadata_test.go index 53cb3ff3f..4c123676e 100644 --- a/cmd/object-copy-metadata_test.go +++ b/cmd/object-copy-metadata_test.go @@ -508,10 +508,9 @@ func testAPICopyObjectSSECKeyRotationNullVersionWithCompression(obj ObjectLayer, } } -// TestAPICopyObjectSSECKeyRotationNullVersionWrongKey pins the source key -// authentication of the re-encrypting fallback. A zero byte source has no data -// to decrypt, so the copy would otherwise reach the destination write without -// ever proving the caller holds the current key. +// TestAPICopyObjectSSECKeyRotationNullVersionWrongKey pins source-key +// authentication in both the standalone rotation fix and the later zero-byte +// read hardening. func TestAPICopyObjectSSECKeyRotationNullVersionWrongKey(t *testing.T) { defer DetectTestLeak(t)() ExecObjectLayerAPITest(ExecObjectLayerAPITestArgs{