Skip to content

Commit 89bae50

Browse files
committed
m
1 parent f1cb45d commit 89bae50

27 files changed

+697
-919
lines changed

releases/rust/db_esdk/Cargo.toml

+11-8
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,25 @@
22
name = "aws-db-esdk"
33
version = "0.1.0"
44
edition = "2021"
5+
rust-version = "1.80.0"
6+
keywords = ["crypto", "cryptography", "security", "dynamodb", "ddb", "encryption", "client-side", "clientside"]
7+
license = "ISC AND (Apache-2.0 OR ISC)"
8+
description = "aws-db-esdk is a library for implementing client side encryption with DynamoDB."
9+
homepage = "https://github.com/aws/aws-database-encryption-sdk-dynamodb/tree/main/releases/rust/db_esdk"
10+
repository = "https://github.com/aws/aws-database-encryption-sdk-dynamodb/tree/main/releases/rust/db_esdk"
11+
authors = ["AWS-CryptoTools"]
12+
documentation = "https://docs.rs/crate/aws-db-esdk"
513

614
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
715

816
[dependencies]
917
aws-config = "1.5.6"
1018
aws-lc-rs = "1.9.0"
11-
aws-lc-sys = "0.21.1"
12-
aws-sdk-dynamodb = "1.45.0"
13-
aws-sdk-kms = "1.43.0"
14-
aws-smithy-runtime = {version = "1.7.1", features = ["client"] }
19+
aws-lc-sys = "0.21.2"
20+
aws-sdk-dynamodb = "1.47.0"
21+
aws-sdk-kms = "1.44.0"
1522
aws-smithy-runtime-api = {version = "1.7.2", features = ["client"] }
1623
aws-smithy-types = "1.2.6"
17-
aws-types = "1.3.3"
1824
chrono = "0.4.38"
1925
dafny_runtime = { path = "dafny_runtime_rust"}
2026
dashmap = "6.1.0"
@@ -24,6 +30,3 @@ uuid = { version = "1.10.0", features = ["v4"] }
2430

2531
[lib]
2632
path = "src/implementation_from_dafny.rs"
27-
28-
[dev-dependencies]
29-
aws-sdk-sts = "1.43.0"

releases/rust/db_esdk/dafny_runtime_rust/Cargo.toml

-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,5 @@ edition = "2021"
55

66
[dependencies]
77
once_cell = "1.18.0"
8-
paste = "1.0"
98
num = "0.4"
109
itertools = "0.11.0"
11-
as-any = "0.3.1"

releases/rust/db_esdk/examples/basic_get_put_example.rs

+10-15
Original file line numberDiff line numberDiff line change
@@ -28,22 +28,21 @@ use aws_db_esdk::types::dynamo_db_tables_encryption_config::DynamoDbTablesEncryp
2828
- Sort key is named "sort_key" with type (N)
2929
*/
3030

31-
pub async fn put_item_get_item() {
31+
pub async fn put_item_get_item() -> Result<(), crate::BoxError> {
3232
let kms_key_id = test_utils::TEST_KMS_KEY_ID;
3333
let ddb_table_name = test_utils::TEST_DDB_TABLE_NAME;
3434

3535
// 1. Create a Keyring. This Keyring will be responsible for protecting the data keys that protect your data.
3636
// For this example, we will create a AWS KMS Keyring with the AWS KMS Key we want to use.
3737
// We will use the `CreateMrkMultiKeyring` method to create this keyring,
3838
// as it will correctly handle both single region and Multi-Region KMS Keys.
39-
let provider_config = MaterialProvidersConfig::builder().build().unwrap();
40-
let mat_prov = client::Client::from_conf(provider_config).unwrap();
39+
let provider_config = MaterialProvidersConfig::builder().build()?;
40+
let mat_prov = client::Client::from_conf(provider_config)?;
4141
let kms_keyring = mat_prov
4242
.create_aws_kms_mrk_multi_keyring()
4343
.generator(kms_key_id)
4444
.send()
45-
.await
46-
.unwrap();
45+
.await?;
4746

4847
// 2. Configure which attributes are encrypted and/or signed when writing new items.
4948
// For each attribute that may exist on the items we plan to write to our DynamoDbTable,
@@ -108,13 +107,11 @@ pub async fn put_item_get_item() {
108107
.algorithm_suite_id(
109108
DbeAlgorithmSuiteId::AlgAes256GcmHkdfSha512CommitKeyEcdsaP384SymsigHmacSha384,
110109
)
111-
.build()
112-
.unwrap();
110+
.build()?;
113111

114112
let table_configs = DynamoDbTablesEncryptionConfig::builder()
115113
.table_encryption_configs(HashMap::from([(ddb_table_name.to_string(), table_config)]))
116-
.build()
117-
.unwrap();
114+
.build()?;
118115

119116
// 5. Create a new AWS SDK DynamoDb client using the TableEncryptionConfigs
120117
let sdk_config = aws_config::load_defaults(aws_config::BehaviorVersion::latest()).await;
@@ -146,13 +143,11 @@ pub async fn put_item_get_item() {
146143
),
147144
]);
148145

149-
let _resp = ddb
150-
.put_item()
146+
ddb.put_item()
151147
.table_name(ddb_table_name)
152148
.set_item(Some(item.clone()))
153149
.send()
154-
.await
155-
.unwrap();
150+
.await?;
156151

157152
// 7. Get the item back from our table using the same client.
158153
// The client will decrypt the item client-side, and return
@@ -176,9 +171,9 @@ pub async fn put_item_get_item() {
176171
// https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.ReadConsistency.html
177172
.consistent_read(true)
178173
.send()
179-
.await
180-
.unwrap();
174+
.await?;
181175

182176
assert_eq!(resp.item, Some(item));
183177
println!("put_item_get_item successful.");
178+
Ok(())
184179
}

releases/rust/db_esdk/examples/clientsupplier/client_supplier_example.rs

+16-26
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ use std::collections::HashMap;
3232
- Partition key is named "partition_key" with type (S)
3333
- Sort key is named "sort_key" with type (S)
3434
*/
35-
pub async fn put_item_get_item() {
35+
pub async fn put_item_get_item() -> Result<(), crate::BoxError> {
3636
let ddb_table_name = test_utils::TEST_DDB_TABLE_NAME;
3737
// Note that we pass in an MRK in us-east-1...
3838
let key_arn = test_utils::TEST_MRK_REPLICA_KEY_ID_US_EAST_1.to_string();
@@ -47,24 +47,23 @@ pub async fn put_item_get_item() {
4747
// 2) the key must be an MRK with a replica defined
4848
// in a region in the regions list, and the client
4949
// must have the correct permissions to access the replica.
50-
let mpl_config = MaterialProvidersConfig::builder().build().unwrap();
51-
let mpl = mpl_client::Client::from_conf(mpl_config).unwrap();
50+
let mpl_config = MaterialProvidersConfig::builder().build()?;
51+
let mpl = mpl_client::Client::from_conf(mpl_config)?;
5252

5353
// Create the multi-keyring using our custom client supplier
5454
// defined in the RegionalRoleClientSupplier class in this directory.
5555
// Note: RegionalRoleClientSupplier will internally use the key_arn's region
5656
// to retrieve the correct IAM role.
5757
let supplier_ref = ClientSupplierRef {
58-
inner: std::rc::Rc::new(std::cell::RefCell::new(RegionalRoleClientSupplier::new())),
58+
inner: std::rc::Rc::new(std::cell::RefCell::new(RegionalRoleClientSupplier {})),
5959
};
6060

6161
let mrk_keyring_with_client_supplier = mpl
6262
.create_aws_kms_mrk_multi_keyring()
6363
.client_supplier(supplier_ref.clone())
6464
.generator(key_arn)
6565
.send()
66-
.await
67-
.unwrap();
66+
.await?;
6867

6968
// 2. Configure which attributes are encrypted and/or signed when writing new items.
7069
// For each attribute that may exist on the items we plan to write to our DynamoDbTable,
@@ -116,13 +115,11 @@ pub async fn put_item_get_item() {
116115
.attribute_actions_on_encrypt(attribute_actions_on_encrypt.clone())
117116
.keyring(mrk_keyring_with_client_supplier)
118117
.allowed_unsigned_attribute_prefix(UNSIGNED_ATTR_PREFIX)
119-
.build()
120-
.unwrap();
118+
.build()?;
121119

122120
let table_configs = DynamoDbTablesEncryptionConfig::builder()
123121
.table_encryption_configs(HashMap::from([(ddb_table_name.to_string(), table_config)]))
124-
.build()
125-
.unwrap();
122+
.build()?;
126123

127124
// 5. Create a new AWS SDK DynamoDb client using the DynamoDb Config above
128125
let sdk_config = aws_config::load_defaults(aws_config::BehaviorVersion::latest()).await;
@@ -149,13 +146,11 @@ pub async fn put_item_get_item() {
149146
),
150147
]);
151148

152-
let _resp = ddb
153-
.put_item()
149+
ddb.put_item()
154150
.table_name(ddb_table_name)
155151
.set_item(Some(item.clone()))
156152
.send()
157-
.await
158-
.unwrap();
153+
.await?;
159154

160155
// 7. Get the item back from our table using the same keyring.
161156
// The client will decrypt the item client-side using the MRK
@@ -174,8 +169,7 @@ pub async fn put_item_get_item() {
174169
.set_key(Some(key_to_get.clone()))
175170
.consistent_read(true)
176171
.send()
177-
.await
178-
.unwrap();
172+
.await?;
179173

180174
assert_eq!(
181175
resp.item.unwrap()["sensitive_data"],
@@ -193,17 +187,15 @@ pub async fn put_item_get_item() {
193187
let discovery_filter = DiscoveryFilter::builder()
194188
.partition("aws")
195189
.account_ids(account_ids)
196-
.build()
197-
.unwrap();
190+
.build()?;
198191

199192
let mrk_discovery_client_supplier_keyring = mpl
200193
.create_aws_kms_mrk_discovery_multi_keyring()
201194
.client_supplier(supplier_ref.clone())
202195
.discovery_filter(discovery_filter)
203196
.regions(regions)
204197
.send()
205-
.await
206-
.unwrap();
198+
.await?;
207199

208200
// 9. Create a new config and client using the discovery keyring.
209201
// This is the same setup as above, except we provide the discovery keyring to the config.
@@ -214,16 +206,14 @@ pub async fn put_item_get_item() {
214206
.attribute_actions_on_encrypt(attribute_actions_on_encrypt)
215207
.keyring(mrk_discovery_client_supplier_keyring)
216208
.allowed_unsigned_attribute_prefix(UNSIGNED_ATTR_PREFIX)
217-
.build()
218-
.unwrap();
209+
.build()?;
219210

220211
let only_replica_table_configs = DynamoDbTablesEncryptionConfig::builder()
221212
.table_encryption_configs(HashMap::from([(
222213
ddb_table_name.to_string(),
223214
only_replica_table_config,
224215
)]))
225-
.build()
226-
.unwrap();
216+
.build()?;
227217

228218
let only_replica_dynamo_config = aws_sdk_dynamodb::config::Builder::from(&sdk_config)
229219
.interceptor(DbEsdkInterceptor::new(only_replica_table_configs))
@@ -245,13 +235,13 @@ pub async fn put_item_get_item() {
245235
.set_key(Some(key_to_get))
246236
.consistent_read(true)
247237
.send()
248-
.await
249-
.unwrap();
238+
.await?;
250239

251240
assert_eq!(
252241
resp.item.unwrap()["sensitive_data"],
253242
AttributeValue::S("encrypt and sign me!".to_string())
254243
);
255244

256245
println!("client_supplier_example successful.");
246+
Ok(())
257247
}

releases/rust/db_esdk/examples/clientsupplier/regional_role_client_supplier.rs

+11-53
Original file line numberDiff line numberDiff line change
@@ -3,69 +3,40 @@ use aws_db_esdk::aws_cryptography_materialProviders::types::ClientSupplier;
33
use aws_db_esdk::deps::aws_cryptography_materialProviders::operation::get_client::GetClientInput;
44
use aws_db_esdk::deps::aws_cryptography_materialProviders::types::error::Error;
55
use aws_db_esdk::deps::com_amazonaws_kms::client::Client as kms_client;
6-
use aws_sdk_sts::Client as sts_client;
76

87
/*
98
Example class demonstrating an implementation of a custom client supplier.
109
This particular implementation will create KMS clients with different IAM roles,
1110
depending on the region passed.
1211
*/
1312

14-
pub struct RegionalRoleClientSupplier {
15-
sts_client: sts_client, // private readonly AmazonSecurityTokenServiceClient _stsClient = new AmazonSecurityTokenServiceClient();
16-
}
17-
18-
impl RegionalRoleClientSupplier {
19-
pub fn new() -> Self {
20-
let sdk_config = tokio::task::block_in_place(|| {
21-
tokio::runtime::Handle::current().block_on(async {
22-
aws_config::load_defaults(aws_config::BehaviorVersion::v2024_03_28()).await
23-
})
24-
});
25-
Self {
26-
sts_client: sts_client::new(&sdk_config),
27-
}
28-
}
29-
}
13+
pub struct RegionalRoleClientSupplier {}
3014

3115
impl ClientSupplier for RegionalRoleClientSupplier {
3216
fn get_client(&mut self, input: GetClientInput) -> Result<kms_client, Error> {
3317
let region = input.region.unwrap();
3418
let arn =
3519
super::regional_role_client_supplier_config::region_iam_role_map()[&region].clone();
36-
let creds = tokio::task::block_in_place(|| {
20+
21+
use aws_config::sts::AssumeRoleProvider;
22+
23+
let provider = tokio::task::block_in_place(|| {
3724
tokio::runtime::Handle::current().block_on(async {
38-
self.sts_client
39-
.assume_role()
40-
.role_arn(arn)
41-
.duration_seconds(900)
42-
.role_session_name("Rust-Client-Supplier-Example-Session")
43-
.send()
25+
AssumeRoleProvider::builder(arn)
26+
.region(Region::new(region.clone()))
27+
.session_name("Rust-Client-Supplier-Example-Session")
28+
.build()
4429
.await
4530
})
46-
})
47-
.unwrap();
48-
49-
let types_cred = creds.credentials.unwrap();
50-
let config_creds = aws_sdk_sts::config::Credentials::new(
51-
types_cred.access_key_id(),
52-
types_cred.secret_access_key(),
53-
Some(types_cred.session_token().to_string()),
54-
Some(
55-
std::time::SystemTime::UNIX_EPOCH
56-
+ std::time::Duration::from_secs(types_cred.expiration().secs() as u64),
57-
),
58-
"SomeProvider",
59-
);
60-
let cred_prov = aws_sdk_kms::config::SharedCredentialsProvider::new(config_creds);
31+
});
6132

6233
let sdk_config = tokio::task::block_in_place(|| {
6334
tokio::runtime::Handle::current().block_on(async {
6435
aws_config::load_defaults(aws_config::BehaviorVersion::v2024_03_28()).await
6536
})
6637
});
6738
let kms_config = aws_sdk_kms::config::Builder::from(&sdk_config)
68-
.credentials_provider(cred_prov)
39+
.credentials_provider(provider)
6940
.region(Region::new(region))
7041
.build();
7142

@@ -75,16 +46,3 @@ impl ClientSupplier for RegionalRoleClientSupplier {
7546
})
7647
}
7748
}
78-
// protected override IAmazonKeyManagementService _GetClient(GetClientInput getClientInput)
79-
// {
80-
// String arn = _config.regionIamRoleMap[getClientInput.Region];
81-
// Credentials creds = _stsClient.AssumeRoleAsync(new AssumeRoleRequest
82-
// {
83-
// RoleArn = arn,
84-
// DurationSeconds = 900, // 15 minutes is the minimum value
85-
// RoleSessionName = "Java-Client-Supplier-Example-Session"
86-
// }
87-
// ).Result.Credentials;
88-
89-
// return new AmazonKeyManagementServiceClient(creds, RegionEndpoint.GetBySystemName(getClientInput.Region));
90-
// }

releases/rust/db_esdk/examples/create_keystore_key.rs

+5-6
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use aws_db_esdk::aws_cryptography_keyStore::types::KmsConfiguration;
2222
2323
This key creation should occur within your control plane.
2424
*/
25-
pub async fn keystore_create_key() -> String {
25+
pub async fn keystore_create_key() -> Result<String, crate::BoxError> {
2626
let key_store_table_name = test_utils::TEST_KEYSTORE_NAME;
2727
let logical_key_store_name = test_utils::TEST_LOGICAL_KEYSTORE_NAME;
2828
let kms_key_arn = test_utils::TEST_KEYSTORE_KMS_KEY_ID;
@@ -37,15 +37,14 @@ pub async fn keystore_create_key() -> String {
3737
.ddb_table_name(key_store_table_name)
3838
.logical_key_store_name(logical_key_store_name)
3939
.kms_configuration(KmsConfiguration::KmsKeyArn(kms_key_arn.to_string()))
40-
.build()
41-
.unwrap();
40+
.build()?;
4241

43-
let keystore = keystore_client::Client::from_conf(key_store_config).unwrap();
42+
let keystore = keystore_client::Client::from_conf(key_store_config)?;
4443

4544
// 2. Create a new branch key and beacon key in our KeyStore.
4645
// Both the branch key and the beacon key will share an Id.
4746
// This creation is eventually consistent.
4847

49-
let new_key = keystore.create_key().send().await.unwrap();
50-
new_key.branch_key_identifier.unwrap()
48+
let new_key = keystore.create_key().send().await?;
49+
Ok(new_key.branch_key_identifier.unwrap())
5150
}

0 commit comments

Comments
 (0)