-
Notifications
You must be signed in to change notification settings - Fork 18
MaterialsDescription Support for Keyrings #467
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…eys for reEncryptInstructionFile feature. I also included simple test cases to verify that the builder for the MaterialsDescription class is working as well as validation checks to ensure that MaterialsDescription is provided in the case that reEncryptInstructionFile is true
kessplas
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Either in this PR, or in a follow up, we need to add this to the ContentMetadata such that it gets written to object metadata/instruction file on PutObject and also returned on GetObject. We need to this before implementing the reEncrypt API as it can't work without the MatDesc actually being present in the metadata.
| * This will be useful during re-encryption of instruction file. | ||
| * The stored Materials Description are immutable once created. | ||
| */ | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| import java.util.HashMap; | ||
| import java.util.Map; | ||
| /** | ||
| * This class is used to store and manage key-value pairs that describe keyring,specifically for AES and RSA Keyring. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| * This class is used to store and manage key-value pairs that describe keyring,specifically for AES and RSA Keyring. | |
| * This class is used to provide key-value pairs that describe key material used with the Keyring, specifically for AES and RSA Keyrings. |
| public static Builder builder() { | ||
| return new Builder(); | ||
| } | ||
| public Map<String, String> getDescription() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| public Map<String, String> getDescription() { | |
| public Map<String, String> getMaterialsDescription() { |
| _wrappingKey = wrappingKey; | ||
| return builder(); | ||
| } | ||
| public Builder reEncryptInstructionFile(boolean reEncryptInstructionFile) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Discussed offline: since the "from" keyring can have a null matdesc, we can't enforce this check until the reEncrypt API is called, so we'll need to remove this.
| assertEquals(1, materialsDescription.getDescription().size()); | ||
| try { | ||
| materialsDescription.getDescription().put("version", "2.0"); | ||
| throw new RuntimeException("Expected UnsupportedOperationException"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| throw new RuntimeException("Expected UnsupportedOperationException"); | |
| fail("Expected UnsupportedOperationException"); |
| * The stored Materials Description are immutable once created. | ||
| */ | ||
|
|
||
| public class MaterialsDescription { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can have this be a Map<String, String> extension, meaning:
implements Map<String, String>
We'll need to implement a bunch of other methods, but they can all be deferred to the "inner" map pretty easily. This is a nicer customer experience as customers can use all of the usual Map API and aren't limited to the things we chose to implement.
…RSA Keyrings will extend from and I also moved the warnIfEncryptionContextIsPresent() method from S3Keyring to RawKeyring since the method really only targets AES + RSA keyrings which will extend this class
…extending the abstract builder from RawKeyring
…bstract builder from the RawKeyring
… transferred it over to RawKeyring class which AES + RSA extend from (note: this method is only for AES + RSA Keyrings)
…ty between sub-classes AES + RSA Keyrings
…ill already be inherited from RawKeyring class
…nt MaterialsDescription (note: MaterialsDescription and Encryption Context are stored in the same field, but you will never have both at the same time (one of them will always be empty
…context and materials description will be treated as different
…DataKeyContext to _encryptionContextOrMatDesc bc in V2 both encryption context and materials description were treated the same (backwards compatability)
…tion Materials in putObject by first creating a helper method in the RawKeyring class that both AES + RSA keyrings will call in the override modifyMaterials method to return materials description instead of empty encryption materials
…ject's metadata correctly
…account null case
src/main/java/software/amazon/encryption/s3/internal/ContentMetadata.java
Show resolved
Hide resolved
| jsonWriter.writeStartObject(); | ||
| for (Map.Entry<String, String> entry : materials.encryptionContext().entrySet()) { | ||
| jsonWriter.writeFieldName(entry.getKey()).writeValue(entry.getValue()); | ||
| if (!materials.encryptionContext().isEmpty() && materials.materialsDescription().isEmpty()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should add a test which passes both a MatDesc on keyring initialization and an EC on PutObject for AES and RSA keyrings. While this is not a good idea (the EC will be dropped and a warning will be logged) we should add a test to make sure that we store the MatDesc and not the EC.
src/main/java/software/amazon/encryption/s3/materials/EncryptionMaterials.java
Show resolved
Hide resolved
src/main/java/software/amazon/encryption/s3/materials/MaterialsDescription.java
Outdated
Show resolved
Hide resolved
src/main/java/software/amazon/encryption/s3/materials/MaterialsDescription.java
Outdated
Show resolved
Hide resolved
src/test/java/software/amazon/encryption/s3/materials/MaterialsDescriptionTest.java
Outdated
Show resolved
Hide resolved
| AesKeyring aesKeyring = AesKeyring.builder() | ||
| .wrappingKey(AES_KEY) | ||
| .reEncryptInstructionFile(true) | ||
| .secureRandom(new SecureRandom()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: this is superfluous
| .keyring(aesKeyring) | ||
| .build(); | ||
| final String input = "Testing Materials Description in Object Metadata!"; | ||
| final String objectKey = "test-aes-materials-description-in-object-metadata"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| final String objectKey = "test-aes-materials-description-in-object-metadata"; | |
| final String objectKey = appendTestSuffix("test-aes-materials-description-in-object-metadata"); |
| .key(objectKey) | ||
| .build()); | ||
| assertEquals(input, responseBytes.asUtf8String()); | ||
| assertEquals("{\"admin\":\"yes\",\"version\":\"1.0\"}", responseBytes.response().metadata().get("x-amz-matdesc")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is fine for one key, but I'd prefer using a parser here, as I'm not sure if the order is guaranteed.
| .build(); | ||
|
|
||
| final String input = "Testing Materials Description in Instruction File!"; | ||
| final String objectKey = "test-rsa-materials-description-in-instruction-file"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto appendTestSuffix (here and everywhere else)
kessplas
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See comment about Encryption Context
| .serverSideEncryption(ServerSideEncryption.AWS_KMS) | ||
| .ssekmsEncryptionContext(Base64.getEncoder().encodeToString(encryptionContext.getBytes(StandardCharsets.UTF_8))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not how EncryptionContext is passed to S3EC.
Refer to e.g. KmsContextV2toV3 in the compatibility tests for an example of S3EC EncryptionContext.
| .serverSideEncryption(ServerSideEncryption.AWS_KMS) | ||
| .ssekmsEncryptionContext(Base64.getEncoder().encodeToString(encryptionContext.getBytes(StandardCharsets.UTF_8))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
| } | ||
|
|
||
| @Test | ||
| public void testMaterialsDescriptionRsaKeyring() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test and the one above it should be moved to the unit test class (MaterialsDescriptionTest)
kessplas
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
Issue #, if available:
Description of changes:
Added configuration of MaterialsDescription for Keyrings
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
Check any applicable: