Skip to content

Commit f46f914

Browse files
authored
feat(example): Use Lombok and Immutable class (#253)
1 parent 6280ba4 commit f46f914

File tree

7 files changed

+646
-0
lines changed

7 files changed

+646
-0
lines changed

Examples/runtimes/java/DynamoDbEncryption/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import org.gradle.api.tasks.testing.logging.TestLogEvent
66
plugins {
77
`java`
88
`java-library`
9+
id("io.freefair.lombok") version "8.1.0"
910
}
1011

1112
group = "software.amazon.cryptography"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package software.amazon.cryptography.examples;
2+
3+
import java.util.Objects;
4+
5+
import software.amazon.cryptography.dbencryptionsdk.dynamodb.DynamoDbEncryptionInterceptor;
6+
import software.amazon.cryptography.dbencryptionsdk.dynamodb.itemencryptor.model.DynamoDbItemEncryptorConfig;
7+
import software.amazon.cryptography.dbencryptionsdk.dynamodb.model.DynamoDbTableEncryptionConfig;
8+
9+
public class ConfigUtils {
10+
public static DynamoDbItemEncryptorConfig fromEncryptionInterceptor(
11+
final DynamoDbEncryptionInterceptor encryptionInterceptor,
12+
final String tableName
13+
) {
14+
DynamoDbTableEncryptionConfig tableEncryptionConfig =
15+
encryptionInterceptor.config().tableEncryptionConfigs().get(tableName);
16+
DynamoDbItemEncryptorConfig.Builder builder = DynamoDbItemEncryptorConfig.builder();
17+
builder.logicalTableName(tableEncryptionConfig.logicalTableName());
18+
builder.partitionKeyName(tableEncryptionConfig.partitionKeyName());
19+
builder.attributeActionsOnEncrypt(tableEncryptionConfig.attributeActionsOnEncrypt());
20+
builder.algorithmSuiteId(tableEncryptionConfig.algorithmSuiteId());
21+
if (Objects.nonNull(tableEncryptionConfig.sortKeyName())) builder.sortKeyName(tableEncryptionConfig.sortKeyName());
22+
if (Objects.nonNull(tableEncryptionConfig.allowedUnsignedAttributes())) builder.allowedUnsignedAttributes(tableEncryptionConfig.allowedUnsignedAttributes());
23+
if (Objects.nonNull(tableEncryptionConfig.allowedUnsignedAttributePrefix())) builder.allowedUnsignedAttributePrefix(tableEncryptionConfig.allowedUnsignedAttributePrefix());
24+
if (Objects.nonNull(tableEncryptionConfig.keyring())) builder.keyring(tableEncryptionConfig.keyring());
25+
if (Objects.nonNull(tableEncryptionConfig.cmm())) builder.cmm(tableEncryptionConfig.cmm());
26+
if (Objects.nonNull(tableEncryptionConfig.legacyOverride())) builder.legacyOverride(tableEncryptionConfig.legacyOverride());
27+
if (Objects.nonNull(tableEncryptionConfig.plaintextOverride())) builder.plaintextOverride(tableEncryptionConfig.plaintextOverride());
28+
return builder.build();
29+
}
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
package software.amazon.cryptography.examples;
2+
3+
import java.io.ByteArrayOutputStream;
4+
import java.io.IOException;
5+
import java.nio.charset.Charset;
6+
import java.util.HashMap;
7+
import java.util.Map;
8+
9+
import software.amazon.awssdk.core.SdkBytes;
10+
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
11+
import software.amazon.awssdk.services.kms.model.InvalidCiphertextException;
12+
import software.amazon.cryptography.dbencryptionsdk.dynamodb.itemencryptor.DynamoDbItemEncryptor;
13+
import software.amazon.cryptography.dbencryptionsdk.dynamodb.itemencryptor.model.DecryptItemInput;
14+
import software.amazon.cryptography.dbencryptionsdk.structuredencryption.model.StructuredEncryptionException;
15+
import software.amazon.cryptography.materialproviders.model.CollectionOfErrors;
16+
17+
public class ManipulationUtils {
18+
19+
public static class ManipulationException extends RuntimeException {
20+
public ManipulationException(String msg) {super(msg);}
21+
public ManipulationException(Throwable throwable){super(throwable);}
22+
public ManipulationException(String msg, Throwable throwable){super(msg, throwable);}
23+
};
24+
25+
public static void assertManipulationProof(
26+
final DynamoDbItemEncryptor itemEncryptor,
27+
final Map<String, AttributeValue> manipulated,
28+
final String attributeName
29+
) {
30+
boolean manipulationProof = false;
31+
try {
32+
itemEncryptor.DecryptItem(DecryptItemInput.builder().encryptedItem(manipulated).build());
33+
} catch (StructuredEncryptionException ex) {
34+
manipulationProof = true;
35+
}
36+
if (!manipulationProof) {
37+
throw new ManipulationException(String.format(
38+
"Attribute Named %s was supposedly manipulated but did not fail Authorization Check!",
39+
attributeName
40+
));
41+
}
42+
}
43+
44+
public static void assertProtectedByEncryptionContext(
45+
final DynamoDbItemEncryptor itemEncryptor,
46+
final Map<String, AttributeValue> manipulated,
47+
final String attributeName
48+
) {
49+
boolean manipulationProof = false;
50+
String exceptionMsg = String.format(
51+
"Attribute Named %s was supposedly manipulated but did not fail Encryption Context Check!" +
52+
" (Or at least it did not fail it as expected!)",
53+
attributeName
54+
);
55+
try {
56+
itemEncryptor.DecryptItem(DecryptItemInput.builder().encryptedItem(manipulated).build());
57+
} catch (CollectionOfErrors ex) {
58+
ex.list().stream().filter(nestedEx -> nestedEx instanceof CollectionOfErrors)
59+
.map(nestedEx -> (CollectionOfErrors) nestedEx)
60+
.map(nestedEx ->
61+
nestedEx.list().stream()
62+
.filter(doubleNestedEx -> doubleNestedEx instanceof InvalidCiphertextException)
63+
.map(doubleNestedEx -> (InvalidCiphertextException) doubleNestedEx)
64+
.findAny().orElseThrow(() -> new ManipulationException(exceptionMsg, ex))
65+
).findAny().orElseThrow(() -> new ManipulationException(exceptionMsg, ex));
66+
manipulationProof = true;
67+
}
68+
if (!manipulationProof) {
69+
throw new ManipulationException(String.format(
70+
"Attribute Named %s was supposedly manipulated but did not fail Authorization Check!",
71+
attributeName
72+
));
73+
}
74+
}
75+
76+
public static void assertNotManipulationProof(
77+
final DynamoDbItemEncryptor itemEncryptor,
78+
final Map<String, AttributeValue> manipulated,
79+
final String attributeName
80+
) {
81+
try {
82+
itemEncryptor.DecryptItem(DecryptItemInput.builder().encryptedItem(manipulated).build());
83+
} catch (StructuredEncryptionException ex) {
84+
throw new ManipulationException(String.format(
85+
"Attribute Named %s was supposedly manipulated and is NOT SIGNED " +
86+
"but it failed Authorization Check!\n" +
87+
"\tAttribute Value: %s",
88+
attributeName, manipulated.get(attributeName)
89+
), ex);
90+
}
91+
}
92+
93+
public static Map<String, AttributeValue> manipulateByteAttribute(
94+
final Map<String, AttributeValue> item,
95+
final String attributeName
96+
) throws IOException {
97+
Map<String, AttributeValue> manipulated = new HashMap<>(item);
98+
ByteArrayOutputStream concatStream = new ByteArrayOutputStream();
99+
concatStream.write(item.get(attributeName).b().asByteArray());
100+
concatStream.write(SdkBytes.fromString("Manipulation!", Charset.defaultCharset()).asByteArray());
101+
manipulated.put(attributeName, AttributeValue.fromB(SdkBytes.fromByteArray(concatStream.toByteArray())));
102+
return manipulated;
103+
}
104+
105+
public static Map<String, AttributeValue> manipulateStringAttribute(
106+
final Map<String, AttributeValue> item,
107+
final String attributeName
108+
) {
109+
Map<String, AttributeValue> manipulated = new HashMap<>(item);
110+
String concatString = item.get(attributeName).s() + "Manipulation!";
111+
manipulated.put(attributeName, AttributeValue.fromS(concatString));
112+
return manipulated;
113+
}
114+
115+
public static Map<String, AttributeValue> manipulateNumberAttribute(
116+
final Map<String, AttributeValue> item,
117+
final String attributeName
118+
) {
119+
Map<String, AttributeValue> manipulated = new HashMap<>(item);
120+
int manipulatedInt = Integer.parseInt(item.get(attributeName).n()) + 1;
121+
manipulated.put(attributeName, AttributeValue.fromN(Integer.toString(manipulatedInt)));
122+
return manipulated;
123+
}
124+
}

0 commit comments

Comments
 (0)