Skip to content

Commit a331844

Browse files
authored
feat: improve error message for missing key (#398)
1 parent 81cd84a commit a331844

File tree

3 files changed

+46
-12
lines changed

3 files changed

+46
-12
lines changed

DynamoDbEncryption/dafny/DynamoDbItemEncryptor/src/AwsCryptographyDbEncryptionSdkDynamoDbItemEncryptorOperations.dfy

+37-5
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ module AwsCryptographyDbEncryptionSdkDynamoDbItemEncryptorOperations refines Abs
227227
//# If this item does not have a sort key attribute,
228228
//# the DynamoDB Item Context MUST NOT contain the key `aws-crypto-sort-name`.
229229
ensures ret.Success? && config.sortKeyName.None? ==>
230-
SORT_NAME !in ret.value
230+
SORT_NAME !in ret.value
231231
{
232232
UTF8.EncodeAsciiUnique();
233233
:- Need(config.partitionKeyName in item, DDBError("Partition key " + config.partitionKeyName + " not found in Item to be encrypted or decrypted"));
@@ -514,15 +514,47 @@ module AwsCryptographyDbEncryptionSdkDynamoDbItemEncryptorOperations refines Abs
514514
{
515515
// We can formally verify these properties, but it is too resource intensive
516516
:- Need(forall k <- schema.content.SchemaMap :: InSignatureScope(config, k),
517-
DynamoDbItemEncryptorException( message := "Recieved unexpected Crypto Schema: mismatch with signature scope"));
517+
DynamoDbItemEncryptorException( message := "Received unexpected Crypto Schema: mismatch with signature scope"));
518518
:- Need(forall k <- schema.content.SchemaMap :: ComAmazonawsDynamodbTypes.IsValid_AttributeName(k),
519-
DynamoDbItemEncryptorException( message := "Recieved unexpected Crypto Schema: Invalid attribute names"));
519+
DynamoDbItemEncryptorException( message := "Received unexpected Crypto Schema: Invalid attribute names"));
520520
Success(map k <- schema.content.SchemaMap :: k := schema.content.SchemaMap[k].content.Action)
521521
}
522522

523523
predicate EncryptItemEnsuresPublicly(input: EncryptItemInput, output: Result<EncryptItemOutput, Error>)
524524
{true}
525525

526+
function method GetItemNames(item : ComAmazonawsDynamodbTypes.AttributeMap) : string
527+
{
528+
var keys := SortedSets.ComputeSetToOrderedSequence2(item.Keys, CharLess);
529+
if |keys| == 0 then
530+
"item is empty"
531+
else
532+
Join(keys, " ")
533+
}
534+
535+
function method KeyMissingMsg(
536+
config: InternalConfig,
537+
item : ComAmazonawsDynamodbTypes.AttributeMap,
538+
tag : string)
539+
: string
540+
{
541+
"On " + tag + " : "
542+
+
543+
(if config.partitionKeyName !in item then
544+
"Partition key '" + config.partitionKeyName + "' does not exist in item. "
545+
else
546+
"")
547+
548+
+
549+
(if config.sortKeyName.Some? && config.sortKeyName.value !in item then
550+
"Sort key '" + config.sortKeyName.value + "' does not exist in item. "
551+
else
552+
"")
553+
554+
+ "Item contains these attributes : "
555+
+ GetItemNames(item) + "."
556+
}
557+
526558
// public Encrypt method
527559
method {:vcs_split_on_every_assert} EncryptItem(config: InternalConfig, input: EncryptItemInput)
528560
returns (output: Result<EncryptItemOutput, Error>)
@@ -621,7 +653,7 @@ module AwsCryptographyDbEncryptionSdkDynamoDbItemEncryptorOperations refines Abs
621653
:- Need(
622654
&& config.partitionKeyName in input.plaintextItem
623655
&& (config.sortKeyName.None? || config.sortKeyName.value in input.plaintextItem)
624-
, DynamoDbItemEncryptorException( message := "Configuration mismatch partition or sort key does not exist in item."));
656+
, E(KeyMissingMsg(config, input.plaintextItem, "Encrypt")));
625657

626658
if |input.plaintextItem| > MAX_ATTRIBUTE_COUNT {
627659
var actCount := String.Base10Int2String(|input.plaintextItem|);
@@ -839,7 +871,7 @@ module AwsCryptographyDbEncryptionSdkDynamoDbItemEncryptorOperations refines Abs
839871
:- Need(
840872
&& config.partitionKeyName in input.encryptedItem
841873
&& (config.sortKeyName.None? || config.sortKeyName.value in input.encryptedItem)
842-
, DynamoDbItemEncryptorException( message := "Configuration mismatch partition or sort key does not exist in item."));
874+
, DynamoDbItemEncryptorException( message := KeyMissingMsg(config, input.encryptedItem, "Decrypt")));
843875

844876
//= specification/dynamodb-encryption-client/decrypt-item.md#behavior
845877
//# If a [Legacy Policy](./ddb-table-encryption-config.md#legacy-policy) of

DynamoDbEncryption/dafny/DynamoDbItemEncryptor/test/DynamoDBItemEncryptorTest.dfy

+7-5
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,15 @@ module DynamoDbItemEncryptorTest {
3939
);
4040
expect encryptRes.Failure?;
4141
expect encryptRes.error == Types.AwsCryptographyDbEncryptionSdkDynamoDb(
42-
DDBE.DynamoDbEncryptionException(message := "No Crypto Action configured for attribute unknown"));
42+
DDBE.DynamoDbEncryptionException(message := "No Crypto Action configured for attribute unknown"));
4343
}
4444

4545
method {:test} TestMissingSortKey() {
4646
var config := TestFixtures.GetEncryptorConfig();
4747
var inputItem := map["bar" := DDBS("key"), "encrypt" := DDBS("foo"), "sign" := DDBS("bar"), "nothing" := DDBS("baz")];
4848
var config2 := config.(
49-
sortKeyName := Some("sort"),
50-
attributeActionsOnEncrypt := config.attributeActionsOnEncrypt["sort" := CSE.SIGN_ONLY]
49+
sortKeyName := Some("sort"),
50+
attributeActionsOnEncrypt := config.attributeActionsOnEncrypt["sort" := CSE.SIGN_ONLY]
5151
);
5252
var encryptor := TestFixtures.GetDynamoDbItemEncryptorFrom(config2);
5353
var encryptRes := encryptor.EncryptItem(
@@ -56,7 +56,9 @@ module DynamoDbItemEncryptorTest {
5656
)
5757
);
5858
expect encryptRes.Failure?;
59-
expect encryptRes.error == Types.DynamoDbItemEncryptorException(message := "Configuration mismatch partition or sort key does not exist in item.");
59+
expect encryptRes.error == Types.DynamoDbItemEncryptorException(
60+
message := "On Encrypt : Sort key 'sort' does not exist in item. Item contains these attributes : bar encrypt nothing sign."
61+
);
6062
}
6163

6264
method {:test} TestRoundTrip() {
@@ -148,7 +150,7 @@ module DynamoDbItemEncryptorTest {
148150
expect |parsedHeader.value.encryptedDataKeys| == 1;
149151
}
150152

151-
method {:test} TestTooManyAttributes() {
153+
method {:test} TestTooManyAttributes() {
152154
var inputItem : DDB.AttributeMap := map["bar" := DDBS("key")];
153155
var actions : DDBE.AttributeActions := map["bar" := CSE.SIGN_ONLY];
154156
for i := 0 to MAX_ATTRIBUTE_COUNT {

DynamoDbEncryption/runtimes/java/src/test/java/software/amazon/cryptography/dbencryptionsdk/dynamodb/DynamoDbEncryptionInterceptorTest.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,7 @@ public void TestPutWithInvalidCryptoAction() {
506506

507507
@Test(
508508
expectedExceptions = DynamoDbItemEncryptorException.class,
509-
expectedExceptionsMessageRegExp = "Configuration mismatch partition or sort key does not exist in item."
509+
expectedExceptionsMessageRegExp = "On Encrypt : Partition key 'partition_key' does not exist in item. Item contains these attributes : attr1 attr2 sort_key."
510510
)
511511
public void TestPutMissingPartition() {
512512
Map<String, AttributeValue> item = createTestItem("foo", "10", "bar", "awol");
@@ -530,7 +530,7 @@ public void TestPutMissingPartition() {
530530

531531
@Test(
532532
expectedExceptions = DynamoDbItemEncryptorException.class,
533-
expectedExceptionsMessageRegExp = "Configuration mismatch partition or sort key does not exist in item."
533+
expectedExceptionsMessageRegExp = "On Encrypt : Sort key 'sort_key' does not exist in item. Item contains these attributes : attr1 attr2 partition_key."
534534
)
535535
public void TestPutMissingSort() {
536536
Map<String, AttributeValue> item = createTestItem("foo", "10", "bar", "awol");

0 commit comments

Comments
 (0)