Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 0f9a45f

Browse files
committedSep 21, 2024··
m
1 parent dd1a953 commit 0f9a45f

File tree

3 files changed

+139
-118
lines changed

3 files changed

+139
-118
lines changed
 

‎DynamoDbEncryption/runtimes/rust/src/bin/example/keyring/hierarchical_keyring.rs

Lines changed: 116 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,21 @@
22
// SPDX-License-Identifier: Apache-2.0
33

44
use crate::test_utils;
5-
use aws_db_esdk::aws_cryptography_dbEncryptionSdk_dynamoDb::types::DynamoDbTableEncryptionConfig;
6-
use aws_db_esdk::aws_cryptography_dbEncryptionSdk_structuredEncryption::types::CryptoAction;
5+
use aws_db_esdk::aws_cryptography_keyStore::types::KmsConfiguration;
6+
use aws_db_esdk::aws_cryptography_keyStore::types::key_store_config::KeyStoreConfig;
77
use aws_db_esdk::aws_cryptography_materialProviders::client as mpl_client;
8+
use aws_db_esdk::aws_cryptography_dbEncryptionSdk_dynamoDb::client as dbesdk_client;
9+
use aws_db_esdk::aws_cryptography_keyStore::client as keystore_client;
10+
use aws_db_esdk::aws_cryptography_dbEncryptionSdk_dynamoDb::types::dynamo_db_encryption_config::DynamoDbEncryptionConfig;
11+
use super::branch_key_id_supplier::ExampleBranchKeyIdSupplier;
812
use aws_db_esdk::aws_cryptography_materialProviders::types::material_providers_config::MaterialProvidersConfig;
9-
use aws_db_esdk::aws_cryptography_materialProviders::types::PaddingScheme;
10-
use aws_db_esdk::intercept::DbEsdkInterceptor;
13+
use aws_db_esdk::aws_cryptography_dbEncryptionSdk_dynamoDb::types::dynamo_db_key_branch_key_id_supplier::DynamoDbKeyBranchKeyIdSupplierRef;
14+
use aws_db_esdk::aws_cryptography_dbEncryptionSdk_structuredEncryption::types::CryptoAction;
15+
use std::collections::HashMap;
16+
use aws_db_esdk::aws_cryptography_dbEncryptionSdk_dynamoDb::types::DynamoDbTableEncryptionConfig;
1117
use aws_db_esdk::DynamoDbTablesEncryptionConfig;
18+
use aws_db_esdk::intercept::DbEsdkInterceptor;
1219
use aws_sdk_dynamodb::types::AttributeValue;
13-
use std::collections::HashMap;
14-
use std::fs::File;
15-
use std::io::Read;
16-
use std::io::Write;
17-
use std::path::Path;
1820

1921
/*
2022
This example sets up DynamoDb Encryption for the AWS SDK client
@@ -59,13 +61,13 @@ use std::path::Path;
5961
- GenerateDataKeyWithoutPlaintext
6062
- Decrypt
6163
*/
62-
pub async fn HierarchicalKeyringGetItemPutItem(String tenant1BranchKeyId, String tenant2BranchKeyId)
64+
pub async fn put_item_get_item(tenant1_branch_key_id : &str, tenant2_branch_key_id : &str)
6365
{
64-
/*
65-
var ddbTableName = TestUtils.TEST_DDB_TABLE_NAME;
66-
var keyStoreTableName = TestUtils.TEST_KEYSTORE_NAME;
67-
var logicalKeyStoreName = TestUtils.TEST_LOGICAL_KEYSTORE_NAME;
68-
var kmsKeyId = TestUtils.TEST_KEYSTORE_KMS_KEY_ID;
66+
let ddb_table_name = test_utils::TEST_DDB_TABLE_NAME;
67+
68+
let keystore_table_name = test_utils::TEST_KEYSTORE_NAME;
69+
let logical_keystore_name = test_utils::TEST_LOGICAL_KEYSTORE_NAME;
70+
let kms_key_id = test_utils::TEST_KEYSTORE_KMS_KEY_ID;
6971

7072
// Initial KeyStore Setup: This example requires that you have already
7173
// created your KeyStore, and have populated it with two new branch keys.
@@ -75,55 +77,64 @@ use std::path::Path;
7577
// 1. Configure your KeyStore resource.
7678
// This SHOULD be the same configuration that you used
7779
// to initially create and populate your KeyStore.
78-
var keystore = new KeyStore(new KeyStoreConfig
79-
{
80-
DdbClient = new AmazonDynamoDBClient(),
81-
DdbTableName = keyStoreTableName,
82-
LogicalKeyStoreName = logicalKeyStoreName,
83-
KmsClient = new AmazonKeyManagementServiceClient(),
84-
KmsConfiguration = new KMSConfiguration { KmsKeyArn = kmsKeyId }
85-
});
86-
80+
let sdk_config = aws_config::load_defaults(aws_config::BehaviorVersion::latest()).await;
81+
let key_store_config = KeyStoreConfig::builder()
82+
.kms_client(aws_sdk_kms::Client::new(&sdk_config))
83+
.ddb_client(aws_sdk_dynamodb::Client::new(&sdk_config))
84+
.ddb_table_name(keystore_table_name)
85+
.logical_key_store_name(logical_keystore_name)
86+
.kms_configuration(KmsConfiguration::KmsKeyArn(
87+
kms_key_id.to_string(),
88+
))
89+
.build()
90+
.unwrap();
91+
92+
let key_store = keystore_client::Client::from_conf(key_store_config).unwrap();
8793

8894
// 2. Create a Branch Key ID Supplier. See ExampleBranchKeyIdSupplier in this directory.
89-
var ddbEnc = new DynamoDbEncryption(new DynamoDbEncryptionConfig());
90-
var branchKeyIdSupplier = ddbEnc.CreateDynamoDbEncryptionBranchKeyIdSupplier(
91-
new CreateDynamoDbEncryptionBranchKeyIdSupplierInput
92-
{
93-
DdbKeyBranchKeyIdSupplier = new ExampleBranchKeyIdSupplier(tenant1BranchKeyId, tenant2BranchKeyId)
94-
}).BranchKeyIdSupplier;
95+
let dbesdk_config = DynamoDbEncryptionConfig::builder().build().unwrap();
96+
let dbesdk = dbesdk_client::Client::from_conf(dbesdk_config).unwrap();
97+
let supplier = ExampleBranchKeyIdSupplier::new(tenant1_branch_key_id, tenant2_branch_key_id);
98+
let supplier_ref = DynamoDbKeyBranchKeyIdSupplierRef {
99+
inner: ::std::rc::Rc::new(std::cell::RefCell::new(supplier))
100+
};
101+
let branch_key_id_supplier = dbesdk.create_dynamo_db_encryption_branch_key_id_supplier()
102+
.ddb_key_branch_key_id_supplier(supplier_ref)
103+
.send()
104+
.await
105+
.unwrap()
106+
.branch_key_id_supplier.unwrap();
107+
95108

96109
// 3. Create the Hierarchical Keyring, using the Branch Key ID Supplier above.
97110
// With this configuration, the AWS SDK Client ultimately configured will be capable
98111
// of encrypting or decrypting items for either tenant (assuming correct KMS access).
99112
// If you want to restrict the client to only encrypt or decrypt for a single tenant,
100113
// configure this Hierarchical Keyring using `.branchKeyId(tenant1BranchKeyId)` instead
101114
// of `.branchKeyIdSupplier(branchKeyIdSupplier)`.
102-
var matProv = new MaterialProviders(new MaterialProvidersConfig());
103-
var keyringInput = new CreateAwsKmsHierarchicalKeyringInput
104-
{
105-
KeyStore = keystore,
106-
BranchKeyIdSupplier = branchKeyIdSupplier,
107-
TtlSeconds = 600, // This dictates how often we call back to KMS to authorize use of the branch keys
108-
Cache = new CacheType
109-
{
110-
Default = new DefaultCache { EntryCapacity = 100 }
111-
}
112-
};
113-
var hierarchicalKeyring = matProv.CreateAwsKmsHierarchicalKeyring(keyringInput);
115+
let mpl_config = MaterialProvidersConfig::builder().build().unwrap();
116+
let mpl = mpl_client::Client::from_conf(mpl_config).unwrap();
117+
118+
let hierarchical_keyring = mpl
119+
.create_aws_kms_hierarchical_keyring()
120+
.branch_key_id_supplier(branch_key_id_supplier)
121+
.key_store(key_store)
122+
.ttl_seconds(600)
123+
.send()
124+
.await
125+
.unwrap();
114126

115127
// 4. Configure which attributes are encrypted and/or signed when writing new items.
116128
// For each attribute that may exist on the items we plan to write to our DynamoDbTable,
117129
// we must explicitly configure how they should be treated during item encryption:
118130
// - ENCRYPT_AND_SIGN: The attribute is encrypted and included in the signature
119131
// - SIGN_ONLY: The attribute not encrypted, but is still included in the signature
120132
// - DO_NOTHING: The attribute is not encrypted and not included in the signature
121-
var attributeActionsOnEncrypt = new Dictionary<String, CryptoAction>
122-
{
123-
["partition_key"] = CryptoAction.SIGN_ONLY, // Our partition attribute must be SIGN_ONLY
124-
["sort_key"] = CryptoAction.SIGN_ONLY, // Our sort attribute must be SIGN_ONLY
125-
["tenant_sensitive_data"] = CryptoAction.ENCRYPT_AND_SIGN
126-
};
133+
let attribute_actions_on_encrypt = HashMap::from([
134+
("partition_key".to_string(), CryptoAction::SignOnly), // Our partition attribute must be SIGN_ONLY
135+
("sort_key".to_string(), CryptoAction::SignOnly), // Our sort attribute must be SIGN_ONLY
136+
("tenant_sensitive_data".to_string(), CryptoAction::EncryptAndSign),
137+
]);
127138

128139
// 5. Configure which attributes we expect to be included in the signature
129140
// when reading items. There are two options for configuring this:
@@ -153,72 +164,82 @@ use std::path::Path;
153164
//
154165
// For this example, we currently authenticate all attributes. To make it easier to
155166
// add unauthenticated attributes in the future, we define a prefix ":" for such attributes.
156-
const String unsignAttrPrefix = ":";
167+
const UNSIGNED_ATTR_PREFIX: &str = ":";
157168

158169
// 6. Create the DynamoDb Encryption configuration for the table we will be writing to.
159-
var tableConfigs = new Dictionary<String, DynamoDbTableEncryptionConfig>
160-
{
161-
[ddbTableName] = new DynamoDbTableEncryptionConfig
162-
{
163-
LogicalTableName = ddbTableName,
164-
PartitionKeyName = "partition_key",
165-
SortKeyName = "sort_key",
166-
AttributeActionsOnEncrypt = attributeActionsOnEncrypt,
167-
Keyring = hierarchicalKeyring,
168-
AllowedUnsignedAttributePrefix = unsignAttrPrefix
169-
}
170-
};
170+
let table_config = DynamoDbTableEncryptionConfig::builder()
171+
.logical_table_name(ddb_table_name)
172+
.partition_key_name("partition_key")
173+
.sort_key_name("sort_key")
174+
.attribute_actions_on_encrypt(attribute_actions_on_encrypt)
175+
.keyring(hierarchical_keyring)
176+
.allowed_unsigned_attribute_prefix(UNSIGNED_ATTR_PREFIX)
177+
.build()
178+
.unwrap();
179+
180+
let table_configs = DynamoDbTablesEncryptionConfig::builder()
181+
.table_encryption_configs(HashMap::from([(ddb_table_name.to_string(), table_config)]))
182+
.build()
183+
.unwrap();
171184

172185
// 7. Create a new AWS SDK DynamoDb client using the DynamoDb Encryption Interceptor above
173-
var ddb = new Client.DynamoDbClient(
174-
new DynamoDbTablesEncryptionConfig { TableEncryptionConfigs = tableConfigs });
186+
let sdk_config = aws_config::load_defaults(aws_config::BehaviorVersion::latest()).await;
187+
let dynamo_config = aws_sdk_dynamodb::config::Builder::from(&sdk_config)
188+
.interceptor(DbEsdkInterceptor::new(table_configs))
189+
.build();
190+
let ddb = aws_sdk_dynamodb::Client::from_conf(dynamo_config);
175191

176192
// 8. Put an item into our table using the above client.
177193
// Before the item gets sent to DynamoDb, it will be encrypted
178194
// client-side, according to our configuration.
179195
// Because the item we are writing uses "tenantId1" as our partition value,
180196
// based on the code we wrote in the ExampleBranchKeySupplier,
181197
// `tenant1BranchKeyId` will be used to encrypt this item.
182-
var item = new Dictionary<String, AttributeValue>
183-
{
184-
["partition_key"] = new AttributeValue("tenant1Id"),
185-
["sort_key"] = new AttributeValue { N = "0" },
186-
["tenant_sensitive_data"] = new AttributeValue("encrypt and sign me!")
187-
};
188-
var putRequest = new PutItemRequest
189-
{
190-
TableName = ddbTableName,
191-
Item = item
192-
};
193-
194-
var putResponse = await ddb.PutItemAsync(putRequest);
198+
let item = HashMap::from([
199+
(
200+
"partition_key".to_string(),
201+
AttributeValue::S("tenant1Id".to_string()),
202+
),
203+
("sort_key".to_string(), AttributeValue::N("0".to_string())),
204+
(
205+
"tenant_sensitive_data".to_string(),
206+
AttributeValue::S("encrypt and sign me!".to_string()),
207+
),
208+
]);
209+
210+
let _resp = ddb
211+
.put_item()
212+
.table_name(ddb_table_name)
213+
.set_item(Some(item.clone()))
214+
.send()
215+
.await
216+
.unwrap();
195217

196-
// Demonstrate that PutItem succeeded
197-
Debug.Assert(putResponse.HttpStatusCode == HttpStatusCode.OK);
198218

199219
// 10. Get the item back from our table using the same client.
200220
// The client will decrypt the item client-side, and return
201221
// back the original item.
202222
// Because the returned item's partition value is "tenantId1",
203223
// based on the code we wrote in the ExampleBranchKeySupplier,
204224
// `tenant1BranchKeyId` will be used to decrypt this item.
205-
var keyToGet = new Dictionary<String, AttributeValue>
206-
{
207-
["partition_key"] = new AttributeValue("tenant1Id"),
208-
["sort_key"] = new AttributeValue { N = "0" }
209-
};
210-
var getRequest = new GetItemRequest
211-
{
212-
Key = keyToGet,
213-
TableName = ddbTableName
214-
};
215-
var getResponse = await ddb.GetItemAsync(getRequest);
216-
217-
// Demonstrate that GetItem succeeded and returned the decrypted item
218-
Debug.Assert(getResponse.HttpStatusCode == HttpStatusCode.OK);
219-
var returnedItem = getResponse.Item;
220-
Debug.Assert(returnedItem["tenant_sensitive_data"].S.Equals("encrypt and sign me!"));
221-
*/
225+
let key_to_get = HashMap::from([
226+
(
227+
"partition_key".to_string(),
228+
AttributeValue::S("tenant1Id".to_string()),
229+
),
230+
("sort_key".to_string(), AttributeValue::N("0".to_string())),
231+
]);
232+
233+
let resp = ddb
234+
.get_item()
235+
.table_name(ddb_table_name)
236+
.set_key(Some(key_to_get))
237+
.consistent_read(true)
238+
.send()
239+
.await
240+
.unwrap();
241+
242+
assert_eq!(resp.item, Some(item));
222243
println!("hierarchical_keyring successful.");
223244

224245
}

‎DynamoDbEncryption/runtimes/rust/src/bin/example/keyring/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
pub mod branch_key_id_supplier;
2-
// pub mod hierarchical_keyring;
2+
pub mod hierarchical_keyring;
33
// pub mod kms_rsa_keyring;
44
// pub mod mrk_discovery_multi_keyring;
55
// pub mod multi_keyring;

‎DynamoDbEncryption/runtimes/rust/src/bin/example/main.rs

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -21,31 +21,31 @@ pub async fn main() {
2121
get_encrypted_data_key_description::get_encrypted_data_key_description().await;
2222
multi_get_put_example::multi_put_get().await;
2323
keyring::raw_rsa_keyring::put_item_get_item().await;
24-
25-
// let key_id = create_keystore_key::keystore_create_key().await;
26-
// // let key_id2 = create_keystore_key::keystore_create_key().await;
27-
// // Key creation is eventually consistent, so wait 5 seconds to decrease the likelihood
28-
// // our test fails due to eventual consistency issues.
29-
// std::thread::sleep(std::time::Duration::from_secs(5));
30-
31-
// searchableencryption::basic_searchable_encryption::put_and_query_with_beacon(&key_id).await;
24+
25+
let key_id = create_keystore_key::keystore_create_key().await;
26+
let key_id2 = create_keystore_key::keystore_create_key().await;
27+
// Key creation is eventually consistent, so wait 5 seconds to decrease the likelihood
28+
// our test fails due to eventual consistency issues.
29+
println!("Key Store Keys created. Waiting 5 seconds for consistency.\n");
30+
std::thread::sleep(std::time::Duration::from_secs(5));
31+
32+
searchableencryption::basic_searchable_encryption::put_and_query_with_beacon(&key_id).await;
33+
keyring::hierarchical_keyring::put_item_get_item(&key_id, &key_id2).await;
3234
// // FIXME : ScanError will have to wait until we have a reasonable error message strategy
3335

3436
/*
35-
await ClientSupplierExample.ClientSupplierPutItemGetItem();
36-
await MultiMrkKeyringExample.MultiMrkKeyringGetItemPutItem();
37-
await RawAesKeyringExample.RawAesKeyringGetItemPutItem();
38-
await MrkDiscoveryMultiKeyringExample.MultiMrkDiscoveryKeyringGetItemPutItem();
39-
await MultiKeyringExample.MultiKeyringGetItemPutItem();
40-
await RawRsaKeyringExample.RawRsaKeyringGetItemPutItem();
41-
await KmsRsaKeyringExample.KmsRsaKeyringGetItemPutItem();
42-
43-
44-
await HierarchicalKeyringExample.HierarchicalKeyringGetItemPutItem(keyId, keyId2);
45-
await CompoundBeaconSearchableEncryptionExample.PutItemQueryItemWithCompoundBeacon(keyId);
46-
await VirtualBeaconSearchableEncryptionExample.PutItemQueryItemWithVirtualBeacon(keyId);
47-
await BeaconStylesSearchableEncryptionExample.PutItemQueryItemWithBeaconStyles(keyId);
48-
await ComplexSearchableEncryptionExample.RunExample(keyId);
37+
await ClientSupplierExample.ClientSupplierPutItemGetItem();
38+
await MultiMrkKeyringExample.MultiMrkKeyringGetItemPutItem();
39+
await RawAesKeyringExample.RawAesKeyringGetItemPutItem();
40+
await MrkDiscoveryMultiKeyringExample.MultiMrkDiscoveryKeyringGetItemPutItem();
41+
await MultiKeyringExample.MultiKeyringGetItemPutItem();
42+
await RawRsaKeyringExample.RawRsaKeyringGetItemPutItem();
43+
await KmsRsaKeyringExample.KmsRsaKeyringGetItemPutItem();
44+
45+
await CompoundBeaconSearchableEncryptionExample.PutItemQueryItemWithCompoundBeacon(keyId);
46+
await VirtualBeaconSearchableEncryptionExample.PutItemQueryItemWithVirtualBeacon(keyId);
47+
await BeaconStylesSearchableEncryptionExample.PutItemQueryItemWithBeaconStyles(keyId);
48+
await ComplexSearchableEncryptionExample.RunExample(keyId);
4949
*/
5050
println!("All examples completed successfully.\n");
5151
}

0 commit comments

Comments
 (0)
Please sign in to comment.