Skip to content

Commit c713d44

Browse files
committed
chore(test): add tests for attribute names that seem structured
1 parent 3ca15af commit c713d44

File tree

4 files changed

+201
-5
lines changed

4 files changed

+201
-5
lines changed

DynamoDbEncryption/dafny/DynamoDbItemEncryptor/test/DynamoDBItemEncryptorTest.dfy

+144-2
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,8 @@ module DynamoDbItemEncryptorTest {
139139
print "\n", decryptRes.error, "\n";
140140
}
141141
expect decryptRes.Success?;
142-
if decryptRes.value.plaintextItem != inputItem {
143-
print "\nInput Item :\n", inputItem, "\n";
142+
if decryptRes.value.plaintextItem != expectedOutputItem {
143+
print "\nexpectedOutputItem :\n", expectedOutputItem, "\n";
144144
print "\nOutput Item :\n", decryptRes.value.plaintextItem, "\n";
145145
}
146146
expect decryptRes.value.plaintextItem == expectedOutputItem;
@@ -406,6 +406,148 @@ module DynamoDbItemEncryptorTest {
406406
];
407407
}
408408

409+
method {:test} TestV2RoundTripSpecial() {
410+
var actions : DDBE.AttributeActions :=
411+
map [
412+
"bar" := CSE.SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT,
413+
"a.b" := CSE.SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT,
414+
".a" := CSE.SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT,
415+
"a." := CSE.SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT,
416+
".a." := CSE.SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT,
417+
"a[2]" := CSE.SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT,
418+
"a#b" := CSE.SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT,
419+
"$" := CSE.SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT,
420+
"$a" := CSE.SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT,
421+
"$a.b" := CSE.SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT,
422+
"$[a]" := CSE.SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT,
423+
"$['a']" := CSE.SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT,
424+
"$[\"a\"]" := CSE.SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT,
425+
"(a)" := CSE.SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT,
426+
"$['" := CSE.SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT,
427+
"$'a'" := CSE.SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT,
428+
"$\"a\"" := CSE.SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT,
429+
"$(a)" := CSE.SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT,
430+
"$(a" := CSE.SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT
431+
432+
];
433+
var config := TestFixtures.GetEncryptorConfigFromActions(actions);
434+
var encryptor := TestFixtures.GetDynamoDbItemEncryptorFrom(config);
435+
436+
var inputItem := map[
437+
"bar" := DDBS("key"),
438+
"a.b" := DDBS("aaa"),
439+
".a" := DDBS("bbb"),
440+
"a." := DDBS("ccc"),
441+
".a." := DDBS("ddd"),
442+
"a[2]" := DDBS("eee"),
443+
"a#b" := DDBS("fff"),
444+
"$" := DDBS("ggg"),
445+
"$a" := DDBS("hhh"),
446+
"$a.b" := DDBS("iii"),
447+
"$[a]" := DDBS("jjj"),
448+
"$['a']" := DDBS("kkk"),
449+
"$[\"a\"]" := DDBS("lll"),
450+
"(a)" := DDBS("mmm"),
451+
"$['" := DDBS("nnn"),
452+
"$'a'" := DDBS("ooo"),
453+
"$\"a\"" := DDBS("ppp"),
454+
"$(a)" := DDBS("qqq"),
455+
"$(a" := DDBS("rrr")
456+
];
457+
458+
var encryptRes := encryptor.EncryptItem(
459+
Types.EncryptItemInput(
460+
plaintextItem:=inputItem
461+
)
462+
);
463+
464+
if encryptRes.Failure? {
465+
print "\n\n", encryptRes, "\n\n";
466+
}
467+
expect encryptRes.Success?;
468+
expect encryptRes.value.encryptedItem.Keys == inputItem.Keys + {SE.HeaderField, SE.FooterField};
469+
var smallEncrypted := encryptRes.value.encryptedItem - {SE.HeaderField, SE.FooterField};
470+
expect smallEncrypted == inputItem;
471+
472+
var decryptRes := encryptor.DecryptItem(
473+
Types.DecryptItemInput(
474+
encryptedItem:=encryptRes.value.encryptedItem
475+
)
476+
);
477+
478+
if decryptRes.Failure? {
479+
print "\n", decryptRes.error, "\n";
480+
}
481+
expect decryptRes.Success?;
482+
if decryptRes.value.plaintextItem != inputItem {
483+
print "\nInput Item :\n", inputItem, "\n";
484+
print "\nOutput Item :\n", decryptRes.value.plaintextItem, "\n";
485+
}
486+
expect decryptRes.value.plaintextItem == inputItem;
487+
488+
var parsedHeader := decryptRes.value.parsedHeader;
489+
expect parsedHeader.Some?;
490+
expect parsedHeader.value.algorithmSuiteId == AlgorithmSuites.DBE_ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384_SYMSIG_HMAC_SHA384.id.DBE;
491+
expect parsedHeader.value.attributeActionsOnEncrypt == actions - {"nothing"};
492+
// Expect the verification key in the context
493+
expect |parsedHeader.value.storedEncryptionContext| == 1;
494+
expect PublicKeyUtf8 in parsedHeader.value.storedEncryptionContext.Keys;
495+
expect |parsedHeader.value.encryptedDataKeys| == 1;
496+
497+
var strEC := SE.EcAsString(parsedHeader.value.encryptionContext);
498+
expect "aws-crypto-public-key" in strEC.Keys;
499+
strEC := strEC - {"aws-crypto-public-key"};
500+
expect strEC ==
501+
map[
502+
"aws-crypto-legend" := "SSSSSSSSSSSSSSSSSSS",
503+
"aws-crypto-attr.bar" := "key",
504+
"aws-crypto-attr.a.b" := "aaa",
505+
"aws-crypto-attr..a" := "bbb",
506+
"aws-crypto-attr.a." := "ccc",
507+
"aws-crypto-attr..a." := "ddd",
508+
"aws-crypto-attr.a[2]" := "eee",
509+
"aws-crypto-attr.a#b" := "fff",
510+
"aws-crypto-attr.$" := "ggg",
511+
"aws-crypto-attr.$a" := "hhh",
512+
"aws-crypto-attr.$a.b" := "iii",
513+
"aws-crypto-attr.$[a]" := "jjj",
514+
"aws-crypto-attr.$['a']" := "kkk",
515+
"aws-crypto-attr.$[\"a\"]" := "lll",
516+
"aws-crypto-attr.(a)" := "mmm",
517+
"aws-crypto-attr.$['" := "nnn",
518+
"aws-crypto-attr.$'a'" := "ooo",
519+
"aws-crypto-attr.$\"a\"" := "ppp",
520+
"aws-crypto-attr.$(a)" := "qqq",
521+
"aws-crypto-attr.$(a" := "rrr",
522+
"aws-crypto-partition-name" := "bar",
523+
"aws-crypto-table-name" := "foo"
524+
];
525+
expect parsedHeader.value.selectorContext ==
526+
map[
527+
"bar" := DDBS("key"),
528+
"a.b" := DDBS("aaa"),
529+
".a" := DDBS("bbb"),
530+
"a." := DDBS("ccc"),
531+
".a." := DDBS("ddd"),
532+
"a[2]" := DDBS("eee"),
533+
"a#b" := DDBS("fff"),
534+
"$" := DDBS("ggg"),
535+
"$a" := DDBS("hhh"),
536+
"$a.b" := DDBS("iii"),
537+
"$[a]" := DDBS("jjj"),
538+
"$['a']" := DDBS("kkk"),
539+
"$[\"a\"]" := DDBS("lll"),
540+
"(a)" := DDBS("mmm"),
541+
"$['" := DDBS("nnn"),
542+
"$'a'" := DDBS("ooo"),
543+
"$\"a\"" := DDBS("ppp"),
544+
"$(a)" := DDBS("qqq"),
545+
"$(a" := DDBS("rrr"),
546+
"aws_dbe_table_name" := DDB.AttributeValue.S("foo"),
547+
"aws_dbe_partition_name" := DDB.AttributeValue.S("bar")
548+
];
549+
}
550+
409551
method {:test} TestRoundTrip() {
410552
var encryptor := TestFixtures.GetDynamoDbItemEncryptor();
411553
var inputItem := map[

TestVectors/dafny/DDBEncryption/src/WriteManifest.dfy

+55-1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,35 @@ module {:options "-functionSyntax:4"} WriteManifest {
3535
""Junk"": ""ENCRYPT_AND_SIGN""
3636
}
3737
}"
38+
39+
// Attribute names with special characters that seem likely to break
40+
// when we introduce structured encryption
41+
const SpecialConfig := @"{
42+
""attributeActionsOnEncrypt"": {
43+
""RecNum"": ""SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT"",
44+
""a.b"": ""SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT"",
45+
""a[2]"": ""SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT"",
46+
""a#b"": ""SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT"",
47+
""'a'"": ""SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT"",
48+
""'a"": ""SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT"",
49+
""a'"": ""SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT"",
50+
""'a.b'"": ""SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT"",
51+
""$'a'"": ""SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT"",
52+
""$.a"": ""SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT"",
53+
""$.[a]"": ""SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT"",
54+
""$.['a']"": ""SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT"",
55+
""$.['a"": ""SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT"",
56+
""\""a\"""": ""SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT"",
57+
""\""a"": ""SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT"",
58+
""a\"""": ""SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT"",
59+
""\""a.b\"""": ""SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT"",
60+
""$\""a\"""": ""SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT"",
61+
""$.a"": ""SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT"",
62+
""$.[a]"": ""SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT"",
63+
""$.[\""a\""]"": ""SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT"",
64+
""$.[\""a"": ""SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT""
65+
}
66+
}"
3867
const BasicV2Config := @"{
3968
""attributeActionsOnEncrypt"": {
4069
""RecNum"": ""SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT"",
@@ -121,6 +150,30 @@ module {:options "-functionSyntax:4"} WriteManifest {
121150
""Stuff"": ""StuffData"",
122151
""Junk"": ""JunkData""
123152
}"
153+
const SpecialRecord := @"{
154+
""RecNum"": 1,
155+
""a.b"": ""aaa"",
156+
""a[2]"": ""bbb"",
157+
""a#b"": ""ccc"",
158+
""'a'"": ""ddd"",
159+
""'a"": ""eee"",
160+
""a'"": ""fff"",
161+
""'a.b'"": ""ggg"",
162+
""$'a'"": ""hhh"",
163+
""$.a"": ""iii"",
164+
""$.[a]"": ""jjj"",
165+
""$.['a']"": ""kkk"",
166+
""$.['a"": ""lll"",
167+
""\""a\"""": ""mmm"",
168+
""\""a"": ""nnn"",
169+
""a\"""": ""ooo"",
170+
""\""a.b\"""": ""ppp"",
171+
""$\""a\"""": ""qqq"",
172+
""$.a"": ""rrr"",
173+
""$.[a]"": ""sss"",
174+
""$.[\""a\""]"": ""ttt"",
175+
""$.[\""a"": ""uuu""
176+
}"
124177
const BadRecord := @"{
125178
""Stuff"": ""StuffData"",
126179
""Junk"": ""JunkData""
@@ -342,8 +395,9 @@ module {:options "-functionSyntax:4"} WriteManifest {
342395
var test11 := MakeTest("11", "positive-encrypt", "Basic encrypt V2", BasicV2Config, BasicRecord);
343396
var test12 := MakeTest("12", "positive-encrypt", "Basic encrypt V2 switching1", LongerV2Config1, BasicRecord, Some(LongerV2Config2));
344397
var test13 := MakeTest("13", "positive-encrypt", "Basic encrypt V2 switching2", LongerV2Config2, BasicRecord, Some(LongerV2Config1));
398+
var test14 := MakeTest("14", "positive-encrypt", "Special characters in attribute names", SpecialConfig, SpecialRecord);
345399
var configTests := MakeConfigTests();
346-
var tests : seq<(string, JSON)> := [test1, test2, test3, test4, test5, test6, test7, test8, test9, test10, test11, test12, test13] + configTests;
400+
var tests : seq<(string, JSON)> := [test1, test2, test3, test4, test5, test6, test7, test8, test9, test10, test11, test12, test13, test14] + configTests;
347401
var final := Object(result + [("tests", Object(tests))]);
348402

349403
var jsonBytes :- expect API.Serialize(final);

TestVectors/runtimes/java/decrypt_dotnet_33a.json

+1-1
Large diffs are not rendered by default.

TestVectors/runtimes/java/decrypt_java_33a.json

+1-1
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)