fix(e2e): send SSE-C key MD5 in Base64 per S3 spec#4
Open
andybrown668 wants to merge 15 commits intomainfrom
Open
fix(e2e): send SSE-C key MD5 in Base64 per S3 spec#4andybrown668 wants to merge 15 commits intomainfrom
andybrown668 wants to merge 15 commits intomainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Fixes SSE-C E2E test failures by generating the x-amz-server-side-encryption-customer-key-MD5 header as Base64 of the raw 16-byte MD5 digest (per S3 spec), instead of hex encoding.
Changes:
- Replace hex-formatted MD5 (
format!("{:x}", ...)) with Base64-encoded digest bytes (...encode(..., md5::compute(key).0)/compute(key).0) across SSE-C test flows. - Add/adjust inline comments clarifying the S3 SSE-C MD5 header requirements.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| crates/e2e_test/src/kms/multipart_encryption_test.rs | Updates SSE-C multipart helper to send Base64 MD5 digest bytes. |
| crates/e2e_test/src/kms/kms_vault_test.rs | Fixes Vault SSE-C key isolation test to send Base64 MD5 digest bytes. |
| crates/e2e_test/src/kms/kms_local_test.rs | Fixes Local KMS SSE-C MD5 headers and adds clarifying comments. |
| crates/e2e_test/src/kms/kms_edge_cases_test.rs | Fixes multiple SSE-C edge-case scenarios to use Base64 MD5 digest bytes. |
| crates/e2e_test/src/kms/kms_comprehensive_test.rs | Fixes comprehensive SSE-C isolation/wrong-key flows to use Base64 MD5 digest bytes. |
| crates/e2e_test/src/kms/common.rs | Fixes shared SSE-C helpers/config to use Base64 MD5 digest bytes. |
You can also share your feedback on Copilot code review. Take the survey.
E2E tests sent x-amz-server-side-encryption-customer-key-MD5 in hex while server expects Base64-encoded 128-bit MD5. Fix all SSE-C usages across kms_local_test, kms_vault_test, kms_edge_cases_test, kms_comprehensive_test, multipart_encryption_test, and common. Made-with: Cursor
- In common.rs: when CARGO_BIN_EXE_rustfs is unset, always build rustfs once per process via Once (remove 'use existing binary if present' path) so the e2e harness uses a single, consistent binary. - Document in tests.mak that e2e setup builds rustfs once and only once. - Add e2e-test make target; RUSTFS_BUILD_FEATURES=ftps for protocol tests. Made-with: Cursor
Extract async test bodies into run_test_* functions callable from both #[tokio::test] and the unified test runner. Fixes E0277 'not a future' and '() is not a future' by having the runner await real async futures instead of #[tokio::test] sync wrappers. - kms_local_test: run_test_local_kms_key_isolation, run_test_local_kms_multipart_upload - multipart_encryption_test: run_test_step1..step5 - kms_edge_cases_test: run_test_kms_* (6 tests) - kms_fault_recovery_test: run_test_kms_* (4 tests) - kms_comprehensive_test: run_test_comprehensive_* (5 tests) - test_runner: dispatch to all run_test_* functions Made-with: Cursor
- Add check-awscurl, install-awscurl, ensure-awscurl in .config/make/check.mak
- Prefer pipx install to avoid externally-managed-environment; fallback to pip --user
- Use ${AWSCURL_PATH:-} so unset var is safe with set -u
- Make e2e-server and probe-e2e depend on ensure-awscurl in tests.mak
- In common.rs, surface clearer errors when rustfs binary or awscurl is missing
Made-with: Cursor
…tion Errors if stream ends before expected bytes to avoid IncompleteBody when decryption produces fewer bytes than Content-Length. Made-with: Cursor
- Add zoned_now_utc() and ZonedUtcCompatible for consistent serialization - Pass encryption_context into decrypt_sse_dek for envelope verification - Add decrypt_data_key_with_context; trim base64 in headers_to_metadata - SSE-S3: do not store KMS key ID in metadata; key_id fallback to 'default' - Skip DEK cache when encryption_context is set (context-bound DEKs) Made-with: Cursor
…lter - Use ExactLengthReader in decryption path to avoid IncompleteBody - Persist S3 SSE type (AES256/aws:kms) and bucket/object_key in context - decrypt_sse_dek takes optional encryption_context for envelope verification - Add filter_object_metadata_with_options to include x-rustfs-encryption-* for Head/Get - Only store x-amz-server-side-encryption-aws-kms-key-id for aws:kms - Add in-process SSE-S3 roundtrip test with global KMS Made-with: Cursor
…ypted GET - Do not expose ssekms_key_id for SSE-S3 (AES256) in Put/Get/Multipart responses - Use filter_object_metadata_with_options(..., true) for Get/Head to include encryption metadata - PutObject: return VersionId when versioning enabled or suspended; use 'null' for null version - GetObject: set decryption part_number=1 for single-part multipart encrypted objects - Preload small encrypted GET bodies (<=8MB) to validate decryption before sending Made-with: Cursor
Made-with: Cursor
Made-with: Cursor
- Add start_rustfs_server_with_env for extra env (e.g. RUSTFS_SCANNER_SPEED) - Run server in own process group to avoid signal propagation to test runner - Local KMS: store encrypted_key_material as base64 in key JSON - Vault: ensure KV v2 at secret, seed default key in KV for backend Made-with: Cursor
- Data usage: poll for scanner, RUSTFS_SCANNER_SPEED=fastest, 200 objects - Group delete: un-ignore, retry on connection reset for set-policy - Policy: spawn RustFS via RustFSTestEnvironment, use dynamic address - Reliant/ftps: use common env and dynamic endpoint, un-ignore Made-with: Cursor
409838f to
7470016
Compare
Compute build matrix in build-check; upstream keeps full matrix, forks only build x86_64-unknown-linux-gnu. Format matrix JSON multiline for readability. Made-with: Cursor
7470016 to
277a584
Compare
Avoid GitHub API timeouts and Node.js 20 deprecation by downloading protoc 33.1 from protocolbuffers/protobuf releases for Linux, macOS, and Windows. Made-with: Cursor
99a837e to
2ca6d5e
Compare
Check for cargo-nextest 0.2.30 before installing to avoid redundant reinstall when cached. Made-with: Cursor
2ca6d5e to
d80eeb5
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Type of Change
Related Issues
N/A
Summary of Changes
E2E tests were sending the SSE-C key MD5 header in hex format (
format!("{:x}", md5::compute(key))), while the server and S3 API expect Base64-encoded 128-bit MD5 digest of the encryption key. This causedtest_local_kms_key_isolationand any SSE-C flow to fail with "The calculated MD5 hash of the key did not match the hash that was provided."Updated all e2e tests that use SSE-C to send the key MD5 in Base64:
base64::Engine::encode(..., md5::compute(key).0)(or equivalent with existingcomputeimport).Files touched:
kms_local_test.rs,multipart_encryption_test.rs,kms_vault_test.rs,kms_edge_cases_test.rs,kms_comprehensive_test.rs,common.rs.Checklist
make pre-commitImpact
Additional Notes
Verification:
cargo test -p e2e_test kms::kms_local_test::test_local_kms_key_isolationpasses. Requesting review from Copilot.