Skip to content

Commit c023b62

Browse files
authored
feat: add more attributes to encryption context (#719)
* feat: add more attributes to encryption context
1 parent 8c0d4ce commit c023b62

File tree

80 files changed

+3885
-941
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+3885
-941
lines changed

Diff for: .github/workflows/ci_test_vector_net.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ jobs:
5858
- name: Test TestVectors on .NET 6.0
5959
working-directory: ./TestVectors/runtimes/net
6060
run: |
61-
cp ../java/decrypt_java.json ../java/decrypt_dotnet.json .
61+
cp ../java/decrypt_java_*.json ../java/decrypt_dotnet_*.json .
6262
dotnet run
6363
cp ../java/*.json .
6464
dotnet run --framework net6.0

Diff for: DynamoDbEncryption/dafny/DynamoDbEncryption/Model/AwsCryptographyDbEncryptionSdkDynamoDbTypes.dfy

+30-23
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,10 @@ include "../../../../submodules/MaterialProviders/StandardLibrary/src/Index.dfy"
4343
nameonly keyStore: AwsCryptographyKeyStoreTypes.IKeyStoreClient ,
4444
nameonly keySource: BeaconKeySource ,
4545
nameonly standardBeacons: StandardBeaconList ,
46-
nameonly compoundBeacons: Option<CompoundBeaconList> ,
47-
nameonly virtualFields: Option<VirtualFieldList> ,
48-
nameonly encryptedParts: Option<EncryptedPartsList> ,
49-
nameonly signedParts: Option<SignedPartsList>
46+
nameonly compoundBeacons: Option<CompoundBeaconList> := Option.None ,
47+
nameonly virtualFields: Option<VirtualFieldList> := Option.None ,
48+
nameonly encryptedParts: Option<EncryptedPartsList> := Option.None ,
49+
nameonly signedParts: Option<SignedPartsList> := Option.None
5050
)
5151
type BeaconVersionList = x: seq<BeaconVersion> | IsValid_BeaconVersionList(x) witness *
5252
predicate method IsValid_BeaconVersionList(x: seq<BeaconVersion>) {
@@ -59,9 +59,9 @@ include "../../../../submodules/MaterialProviders/StandardLibrary/src/Index.dfy"
5959
datatype CompoundBeacon = | CompoundBeacon (
6060
nameonly name: string ,
6161
nameonly split: Char ,
62-
nameonly encrypted: Option<EncryptedPartsList> ,
63-
nameonly signed: Option<SignedPartsList> ,
64-
nameonly constructors: Option<ConstructorList>
62+
nameonly encrypted: Option<EncryptedPartsList> := Option.None ,
63+
nameonly signed: Option<SignedPartsList> := Option.None ,
64+
nameonly constructors: Option<ConstructorList> := Option.None
6565
)
6666
type CompoundBeaconList = x: seq<CompoundBeacon> | IsValid_CompoundBeaconList(x) witness *
6767
predicate method IsValid_CompoundBeaconList(x: seq<CompoundBeacon>) {
@@ -217,16 +217,16 @@ include "../../../../submodules/MaterialProviders/StandardLibrary/src/Index.dfy"
217217
datatype DynamoDbTableEncryptionConfig = | DynamoDbTableEncryptionConfig (
218218
nameonly logicalTableName: string ,
219219
nameonly partitionKeyName: ComAmazonawsDynamodbTypes.KeySchemaAttributeName ,
220-
nameonly sortKeyName: Option<ComAmazonawsDynamodbTypes.KeySchemaAttributeName> ,
221-
nameonly search: Option<SearchConfig> ,
220+
nameonly sortKeyName: Option<ComAmazonawsDynamodbTypes.KeySchemaAttributeName> := Option.None ,
221+
nameonly search: Option<SearchConfig> := Option.None ,
222222
nameonly attributeActionsOnEncrypt: AttributeActions ,
223-
nameonly allowedUnsignedAttributes: Option<ComAmazonawsDynamodbTypes.AttributeNameList> ,
224-
nameonly allowedUnsignedAttributePrefix: Option<string> ,
225-
nameonly algorithmSuiteId: Option<AwsCryptographyMaterialProvidersTypes.DBEAlgorithmSuiteId> ,
226-
nameonly keyring: Option<AwsCryptographyMaterialProvidersTypes.IKeyring> ,
227-
nameonly cmm: Option<AwsCryptographyMaterialProvidersTypes.ICryptographicMaterialsManager> ,
228-
nameonly legacyOverride: Option<LegacyOverride> ,
229-
nameonly plaintextOverride: Option<PlaintextOverride>
223+
nameonly allowedUnsignedAttributes: Option<ComAmazonawsDynamodbTypes.AttributeNameList> := Option.None ,
224+
nameonly allowedUnsignedAttributePrefix: Option<string> := Option.None ,
225+
nameonly algorithmSuiteId: Option<AwsCryptographyMaterialProvidersTypes.DBEAlgorithmSuiteId> := Option.None ,
226+
nameonly keyring: Option<AwsCryptographyMaterialProvidersTypes.IKeyring> := Option.None ,
227+
nameonly cmm: Option<AwsCryptographyMaterialProvidersTypes.ICryptographicMaterialsManager> := Option.None ,
228+
nameonly legacyOverride: Option<LegacyOverride> := Option.None ,
229+
nameonly plaintextOverride: Option<PlaintextOverride> := Option.None
230230
)
231231
type DynamoDbTableEncryptionConfigList = map<ComAmazonawsDynamodbTypes.TableName, DynamoDbTableEncryptionConfig>
232232
datatype DynamoDbTablesEncryptionConfig = | DynamoDbTablesEncryptionConfig (
@@ -307,7 +307,7 @@ include "../../../../submodules/MaterialProviders/StandardLibrary/src/Index.dfy"
307307
nameonly policy: LegacyPolicy ,
308308
nameonly encryptor: ILegacyDynamoDbEncryptor ,
309309
nameonly attributeActionsOnEncrypt: AttributeActions ,
310-
nameonly defaultAttributeFlag: Option<AwsCryptographyDbEncryptionSdkStructuredEncryptionTypes.CryptoAction>
310+
nameonly defaultAttributeFlag: Option<AwsCryptographyDbEncryptionSdkStructuredEncryptionTypes.CryptoAction> := Option.None
311311
)
312312
datatype LegacyPolicy =
313313
| FORCE_LEGACY_ENCRYPT_ALLOW_LEGACY_DECRYPT
@@ -319,7 +319,7 @@ include "../../../../submodules/MaterialProviders/StandardLibrary/src/Index.dfy"
319319
datatype MultiKeyStore = | MultiKeyStore (
320320
nameonly keyFieldName: string ,
321321
nameonly cacheTTL: int32 ,
322-
nameonly cache: Option<AwsCryptographyMaterialProvidersTypes.CacheType>
322+
nameonly cache: Option<AwsCryptographyMaterialProvidersTypes.CacheType> := Option.None
323323
)
324324
datatype PartOnly = | PartOnly (
325325

@@ -345,7 +345,7 @@ include "../../../../submodules/MaterialProviders/StandardLibrary/src/Index.dfy"
345345
datatype SignedPart = | SignedPart (
346346
nameonly name: string ,
347347
nameonly prefix: Prefix ,
348-
nameonly loc: Option<TerminalLocation>
348+
nameonly loc: Option<TerminalLocation> := Option.None
349349
)
350350
type SignedPartsList = x: seq<SignedPart> | IsValid_SignedPartsList(x) witness *
351351
predicate method IsValid_SignedPartsList(x: seq<SignedPart>) {
@@ -358,8 +358,8 @@ include "../../../../submodules/MaterialProviders/StandardLibrary/src/Index.dfy"
358358
datatype StandardBeacon = | StandardBeacon (
359359
nameonly name: string ,
360360
nameonly length: BeaconBitLength ,
361-
nameonly loc: Option<TerminalLocation> ,
362-
nameonly style: Option<BeaconStyle>
361+
nameonly loc: Option<TerminalLocation> := Option.None ,
362+
nameonly style: Option<BeaconStyle> := Option.None
363363
)
364364
type StandardBeaconList = x: seq<StandardBeacon> | IsValid_StandardBeaconList(x) witness *
365365
predicate method IsValid_StandardBeaconList(x: seq<StandardBeacon>) {
@@ -386,7 +386,7 @@ include "../../../../submodules/MaterialProviders/StandardLibrary/src/Index.dfy"
386386
}
387387
datatype VirtualPart = | VirtualPart (
388388
nameonly loc: TerminalLocation ,
389-
nameonly trans: Option<VirtualTransformList>
389+
nameonly trans: Option<VirtualTransformList> := Option.None
390390
)
391391
type VirtualPartList = x: seq<VirtualPart> | IsValid_VirtualPartList(x) witness *
392392
predicate method IsValid_VirtualPartList(x: seq<VirtualPart>) {
@@ -453,13 +453,20 @@ include "../../../../submodules/MaterialProviders/StandardLibrary/src/Index.dfy"
453453
import Operations : AbstractAwsCryptographyDbEncryptionSdkDynamoDbOperations
454454
function method DefaultDynamoDbEncryptionConfig(): DynamoDbEncryptionConfig
455455
method DynamoDbEncryption(config: DynamoDbEncryptionConfig := DefaultDynamoDbEncryptionConfig())
456-
returns (res: Result<DynamoDbEncryptionClient, Error>)
456+
returns (res: Result<IDynamoDbEncryptionClient, Error>)
457457
ensures res.Success? ==>
458458
&& fresh(res.value)
459459
&& fresh(res.value.Modifies)
460460
&& fresh(res.value.History)
461461
&& res.value.ValidState()
462462

463+
// Helper function for the benefit of native code to create a Success(client) without referring to Dafny internals
464+
function method CreateSuccessOfClient(client: IDynamoDbEncryptionClient): Result<IDynamoDbEncryptionClient, Error> {
465+
Success(client)
466+
} // Helper function for the benefit of native code to create a Failure(error) without referring to Dafny internals
467+
function method CreateFailureOfError(error: Error): Result<IDynamoDbEncryptionClient, Error> {
468+
Failure(error)
469+
}
463470
class DynamoDbEncryptionClient extends IDynamoDbEncryptionClient
464471
{
465472
constructor(config: Operations.InternalConfig)

Diff for: DynamoDbEncryption/dafny/DynamoDbEncryption/Model/DynamoDbEncryption.smithy

+15
Original file line numberDiff line numberDiff line change
@@ -762,33 +762,48 @@ operation GetBranchKeyIdFromDdbKey {
762762
output: GetBranchKeyIdFromDdbKeyOutput
763763
}
764764

765+
//= specification/dynamodb-encryption-client/ddb-encryption-branch-key-id-supplier.md#dynamodbkeybranchkeyidsupplier
766+
//= type=implication
767+
//# This operation MUST take in a DDB `Key` structure (and attribute map containing the partition and sort attributes) as input.
765768
@javadoc("Inputs for getting the Branch Key that should be used for wrapping and unwrapping data keys.")
766769
structure GetBranchKeyIdFromDdbKeyInput {
767770
@required
768771
@javadoc("The partition and sort (if it exists) attributes on the item being read or written.")
769772
ddbKey: Key
770773
}
771774

775+
//= specification/dynamodb-encryption-client/ddb-encryption-branch-key-id-supplier.md#dynamodbkeybranchkeyidsupplier
776+
//= type=implication
777+
//# This operation MUST return a branch key id (string) as output.
772778
@javadoc("Outputs for getting the Branch Key that should be used for wrapping and unwrapping data keys.")
773779
structure GetBranchKeyIdFromDdbKeyOutput {
774780
@required
775781
@javadoc("The ID of the Branch Key that should be used to wrap and unwrap data keys for this item.")
776782
branchKeyId: String
777783
}
778784

785+
//= specification/dynamodb-encryption-client/ddb-encryption-branch-key-id-supplier.md#operation
786+
//= type=implication
787+
//# The `CreateDynamoDbEncryptionBranchKeyIdSupplier` is an operation that MUST be vended alongside the DynamoDb Item Encryptor.
779788
@javadoc("Create a Branch Key Supplier for use with the Hierarchical Keyring that decides what Branch Key to use based on the primary key of the DynamoDB item being read or written.")
780789
operation CreateDynamoDbEncryptionBranchKeyIdSupplier {
781790
input: CreateDynamoDbEncryptionBranchKeyIdSupplierInput,
782791
output: CreateDynamoDbEncryptionBranchKeyIdSupplierOutput
783792
}
784793

794+
//= specification/dynamodb-encryption-client/ddb-encryption-branch-key-id-supplier.md#input
795+
//= type=implication
796+
//# This operation MUST take in a [DynamoDbKeyBranchKeyIdSupplier](#dynamodb-key-branch-key-id-supplier) as input.
785797
@javadoc("Inputs for creating a Branch Key Supplier from a DynamoDB Key Branch Key Id Supplier")
786798
structure CreateDynamoDbEncryptionBranchKeyIdSupplierInput {
787799
@required
788800
@javadoc("An implementation of the DynamoDbKeyBranchKeyIdSupplier interface, which determines what Branch Key to use for data key wrapping/unwrapping based on the DynamoDB item being written/read.")
789801
ddbKeyBranchKeyIdSupplier: DynamoDbKeyBranchKeyIdSupplierReference,
790802
}
791803

804+
//= specification/dynamodb-encryption-client/ddb-encryption-branch-key-id-supplier.md#output
805+
//= type=implication
806+
//# This operation MUST output a BranchKeyIdSupplierReference.
792807
@javadoc("Outputs for creating a Branch Key Supplier from a DynamoDB Key Branch Key Id Supplier")
793808
structure CreateDynamoDbEncryptionBranchKeyIdSupplierOutput {
794809
@required

Diff for: DynamoDbEncryption/dafny/DynamoDbEncryption/src/ConfigToInfo.dfy

+5-1
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ module SearchConfigToInfo {
8888
match outer.attributeActionsOnEncrypt[keyFieldName] {
8989
case DO_NOTHING => Success(true)
9090
case SIGN_ONLY => Success(false)
91+
case SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT => Success(false)
9192
case ENCRYPT_AND_SIGN => Failure(E("Beacon key field name " + keyFieldName + " is configured as ENCRYPT_AND_SIGN which is not allowed."))
9293
}
9394
}
@@ -264,7 +265,10 @@ module SearchConfigToInfo {
264265
{
265266
&& var name := loc[0].key;
266267
&& name in outer.attributeActionsOnEncrypt
267-
&& outer.attributeActionsOnEncrypt[name] == SE.SIGN_ONLY
268+
&& (
269+
|| outer.attributeActionsOnEncrypt[name] == SE.SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT
270+
|| outer.attributeActionsOnEncrypt[name] == SE.SIGN_ONLY
271+
)
268272
}
269273

270274
// is this terminal location encrypted

Diff for: DynamoDbEncryption/dafny/DynamoDbEncryption/src/DynamoDbEncryptionBranchKeyIdSupplier.dfy

+13-67
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,17 @@
11
// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
22
// SPDX-License-Identifier: Apache-2.0
33

4-
include "DynamoToStruct.dfy"
5-
include "Util.dfy"
4+
include "../../DynamoDbItemEncryptor/src/Util.dfy"
65

76
module DynamoDbEncryptionBranchKeyIdSupplier {
87
import opened AwsCryptographyDbEncryptionSdkDynamoDbTypes
9-
import MPL = AwsCryptographyMaterialProvidersTypes
10-
import DDB = ComAmazonawsDynamodbTypes
11-
import opened Seq
128
import opened Wrappers
13-
import opened StandardLibrary.UInt
14-
import DynamoToStruct
15-
import Base64
16-
import DynamoDbEncryptionUtil
17-
18-
const MPL_EC_PARTITION_NAME: UTF8.ValidUTF8Bytes := UTF8.EncodeAscii("aws-crypto-partition-name")
19-
const MPL_EC_SORT_NAME: UTF8.ValidUTF8Bytes := UTF8.EncodeAscii("aws-crypto-sort-name")
9+
import MPL = AwsCryptographyMaterialProvidersTypes
10+
import DynamoDbItemEncryptorUtil
2011

2112
class DynamoDbEncryptionBranchKeyIdSupplier
2213
extends MPL.IBranchKeyIdSupplier
23-
{
14+
{
2415
const ddbKeyBranchKeyIdSupplier: IDynamoDbKeyBranchKeyIdSupplier
2516

2617
predicate ValidState()
@@ -48,76 +39,31 @@ module DynamoDbEncryptionBranchKeyIdSupplier {
4839
{true}
4940

5041
method GetBranchKeyId'(input: MPL.GetBranchKeyIdInput)
51-
returns (output: Result<MPL.GetBranchKeyIdOutput, MPL.Error>)
42+
returns (output: Result<MPL.GetBranchKeyIdOutput, MPL.Error>)
5243
requires ValidState()
5344
modifies Modifies - {History}
5445
decreases Modifies - {History}
5546
ensures ValidState()
5647
ensures GetBranchKeyIdEnsuresPublicly(input, output)
5748
ensures unchanged(History)
5849
{
59-
var context := input.encryptionContext;
60-
var attrMap: DDB.AttributeMap := map[];
50+
var attrMapR := DynamoDbItemEncryptorUtil.ConvertContextForSelector(input.encryptionContext);
51+
var attrMap :- attrMapR.MapFailure(e => MPL.AwsCryptographicMaterialProvidersException(message:=e));
6152

62-
// Add partition key to map
63-
:- Need(MPL_EC_PARTITION_NAME in context.Keys,
64-
MPL.AwsCryptographicMaterialProvidersException(
65-
message := "Invalid encryption context: Missing partition name"));
66-
var partitionName := context[MPL_EC_PARTITION_NAME];
67-
var partitionValueKey := DynamoDbEncryptionUtil.DDBEC_EC_ATTR_PREFIX + partitionName;
68-
:- Need(partitionValueKey in context.Keys,
69-
MPL.AwsCryptographicMaterialProvidersException(
70-
message := "Invalid encryption context: Missing partition value"));
71-
attrMap :- AddAttributeToMap(partitionValueKey, context[partitionValueKey], attrMap);
72-
73-
if MPL_EC_SORT_NAME in context.Keys {
74-
var sortName := context[MPL_EC_SORT_NAME];
75-
var sortValueKey := DynamoDbEncryptionUtil.DDBEC_EC_ATTR_PREFIX + sortName;
76-
:- Need(sortValueKey in context.Keys,
77-
MPL.AwsCryptographicMaterialProvidersException(
78-
message := "Invalid encryption context: Missing sort value"));
79-
attrMap :- AddAttributeToMap(sortValueKey, context[sortValueKey], attrMap);
80-
}
81-
8253
// Get branch key id from these DDB attributes
8354
var branchKeyIdR := ddbKeyBranchKeyIdSupplier.GetBranchKeyIdFromDdbKey(
84-
GetBranchKeyIdFromDdbKeyInput(ddbKey := attrMap)
85-
);
55+
GetBranchKeyIdFromDdbKeyInput(ddbKey := attrMap)
56+
);
57+
//= specification/dynamodb-encryption-client/ddb-encryption-branch-key-id-supplier.md#behavior
58+
//# - Otherwise, this operation MUST fail.
8659
var branchKeyIdOut :- branchKeyIdR.MapFailure(ConvertToMplError);
8760

61+
//= specification/dynamodb-encryption-client/ddb-encryption-branch-key-id-supplier.md#behavior
62+
//# - If successful, the resulting string MUST be outputted by this operation.
8863
return Success(MPL.GetBranchKeyIdOutput(branchKeyId:=branchKeyIdOut.branchKeyId));
8964
}
9065
}
9166

92-
function method AddAttributeToMap(ddbAttrKey: seq<uint8>, encodedAttrValue: seq<uint8>, attrMap: DDB.AttributeMap)
93-
: (res: Result<DDB.AttributeMap, MPL.Error>)
94-
requires |ddbAttrKey| >= |DynamoDbEncryptionUtil.DDBEC_EC_ATTR_PREFIX|
95-
{
96-
// Obtain attribute name from EC kvPair key
97-
var ddbAttrNameBytes := ddbAttrKey[|DynamoDbEncryptionUtil.DDBEC_EC_ATTR_PREFIX|..];
98-
var ddbAttrName :- UTF8.Decode(ddbAttrNameBytes)
99-
.MapFailure(e => MPL.AwsCryptographicMaterialProvidersException(message:=e));
100-
:- Need(DDB.IsValid_AttributeName(ddbAttrName),
101-
MPL.AwsCryptographicMaterialProvidersException(
102-
message := "Invalid serialization of DDB Attribute in encryption context."));
103-
104-
// Obtain attribute value from EC kvPair value
105-
var utf8DecodedVal :- UTF8.Decode(encodedAttrValue)
106-
.MapFailure(e => MPL.AwsCryptographicMaterialProvidersException(message:=e));
107-
var base64DecodedVal :- Base64.Decode(utf8DecodedVal)
108-
.MapFailure(e => MPL.AwsCryptographicMaterialProvidersException(message:=e));
109-
:- Need(|base64DecodedVal| >= 2,
110-
MPL.AwsCryptographicMaterialProvidersException(
111-
message := "Invalid serialization of DDB Attribute in encryption context."));
112-
var typeId := base64DecodedVal[..2];
113-
var serializedValue := base64DecodedVal[2..];
114-
var ddbAttrValue :- DynamoToStruct.BytesToAttr(serializedValue, typeId, false)
115-
.MapFailure(e => MPL.AwsCryptographicMaterialProvidersException(message:=e));
116-
117-
// Add to our AttributeMap
118-
Success(attrMap[ddbAttrName := ddbAttrValue.val])
119-
}
120-
12167
function method ConvertToMplError(err: Error)
12268
:(ret: MPL.Error)
12369
{

0 commit comments

Comments
 (0)