chore: add test server test for RSA wrapping keys #195
Merged
Conversation
There was a problem hiding this comment.
Pull request overview
This PR expands the test-server Java integration test suite to cover additional RSA legacy-decryption scenarios and introduces a new cross-runtime test intended to validate Bleichenbacher padding-oracle mitigations, while also updating the .NET v4 test-server submodule branch to track development.
Changes:
- Add a shared
LANGUAGES_WITH_SECURITY_PROFILEruntime set toTestUtilsto handle clients that use a unified security-profile toggle. - Extend RSA V1 legacy decrypt tests with a “legacy disabled” negative test case and runtime-specific error assertions.
- Add
BleichenbacherOracleTeststo compare decryption error behavior for valid vs invalid PKCS#1 v1.5 padding across runtimes/config matrices. - Update
.gitmodulesto point the .NET v4 improved test-server submodule at thedevbranch.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
test-server/java-tests/src/it/java/software/amazon/encryption/s3/TestUtils.java |
Adds a language set used to branch test behavior for unified security-profile runtimes. |
test-server/java-tests/src/it/java/software/amazon/encryption/s3/RsaV1LegacyDecryptTests.java |
Adds a negative test verifying V1 RSA objects fail to decrypt when legacy wrapping is disabled, with runtime-specific expected messages. |
test-server/java-tests/src/it/java/software/amazon/encryption/s3/BleichenbacherOracleTests.java |
Introduces a new parameterized test suite intended to detect padding-oracle distinguishability across RSA-supporting runtimes and configurations. |
.gitmodules |
Switches the .NET v4 improved server submodule from main to dev. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+237
to
+245
| private void uploadV1Object(String key, byte[] body, String wrappedKey, String iv, String matdesc) { | ||
| Map<String, String> metadata = new HashMap<>(); | ||
| metadata.put("x-amz-key", wrappedKey); | ||
| metadata.put("x-amz-iv", iv); | ||
| metadata.put("x-amz-matdesc", matdesc != null ? matdesc : "{}"); | ||
|
|
||
| plaintextS3.putObject(b -> b.bucket(BUCKET).key(key).metadata(metadata).contentLength((long) body.length), | ||
| RequestBody.fromBytes(body)); | ||
| } |
Comment on lines
+262
to
+275
| private void uploadV1InstructionFileObject(String key, byte[] body, String wrappedKey, String iv, String matdesc) throws Exception { | ||
| // Upload body with NO encryption metadata in object metadata | ||
| plaintextS3.putObject(b -> b.bucket(BUCKET).key(key).contentLength((long) body.length), | ||
| RequestBody.fromBytes(body)); | ||
|
|
||
| // Upload .instruction file with V1 metadata as JSON | ||
| Map<String, String> instructionMap = new HashMap<>(); | ||
| instructionMap.put("x-amz-key", wrappedKey); | ||
| instructionMap.put("x-amz-iv", iv); | ||
| instructionMap.put("x-amz-matdesc", matdesc != null ? matdesc : "{}"); | ||
| String instructionJson = MAPPER.writeValueAsString(instructionMap); | ||
| plaintextS3.putObject(b -> b.bucket(BUCKET).key(key + ".instruction"), | ||
| RequestBody.fromString(instructionJson)); | ||
| createdKeys.add(key + ".instruction"); |
Comment on lines
+66
to
+74
| @AfterAll | ||
| public static void cleanup() { | ||
| for (String key : createdKeys) { | ||
| try { | ||
| plaintextS3.deleteObject(b -> b.bucket(BUCKET).key(key)); | ||
| } catch (Exception ignored) { | ||
| } | ||
| } | ||
| } |
Comment on lines
+192
to
+195
| // Use random bytes for the invalid PKCS#1 padding | ||
| String wrappedKey = Base64.getEncoder().encodeToString(new byte[256]); | ||
| String iv = Base64.getEncoder().encodeToString(new byte[16]); | ||
| String matdesc = "{}"; |
Comment on lines
+14
to
+16
| import java.security.KeyPair; | ||
| import java.security.KeyPairGenerator; | ||
| import java.util.ArrayList; |
| .enableLegacyUnauthenticatedModes(false) | ||
| .enableLegacyWrappingAlgorithms(false) | ||
| .build()) | ||
| .build()).getClientId(); |
lucasmcdonald3
approved these changes
Jun 18, 2026
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.
Issue #, if available:
Description of changes:
Adds new test cases for v1 object decryption with RSA wrapping key. Update the submodule to development branch. In S3EC .NET, code is staged at dev branch then moved to main when releasing.
bringing commits from following PR from private repo to public:
https://github.com/aws/private-amazon-s3-encryption-client-java-staging/pull/94
https://github.com/aws/private-amazon-s3-encryption-client-java-staging/pull/98
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.