Skip to main content

DefaultCache

Struct DefaultCache 

Source
#[non_exhaustive]
pub struct DefaultCache { pub entry_capacity: Option<i32>, }
Expand description

The best choice for most situations. Probably a StormTrackingCache.

Fields (Non-exhaustive)§

This struct is marked as non-exhaustive
Non-exhaustive structs could have additional fields added in future. Therefore, non-exhaustive structs cannot be constructed in external crates using the traditional Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.
§entry_capacity: Option<i32>

Maximum number of entries cached.

Implementations§

Source§

impl DefaultCache

Source

pub fn entry_capacity(&self) -> &Option<i32>

Maximum number of entries cached.

Source§

impl DefaultCache

Source

pub fn builder() -> DefaultCacheBuilder

Creates a new builder-style object to manufacture DefaultCache.

Examples found in repository?
examples/keyring/aws_kms_hierarchical/shared_cache_across_hierarchical_keyrings_example.rs (line 91)
78pub async fn encrypt_and_decrypt_with_keyring(
79    example_data: &str,
80    key_store_table_name: &str,
81    logical_key_store_name: &str,
82    key_store_kms_key_id: &str,
83) -> Result<(), crate::BoxError> {
84    // 1a. Create the CryptographicMaterialsCache (CMC) to share across multiple Hierarchical Keyrings
85    // using the Material Providers Library
86    //    This CMC takes in:
87    //     - CacheType
88    let mpl_config = MaterialProvidersConfig::builder().build()?;
89    let mpl = mpl_client::Client::from_conf(mpl_config)?;
90
91    let cache: CacheType = CacheType::Default(DefaultCache::builder().entry_capacity(100).build()?);
92
93    let shared_cryptographic_materials_cache: CryptographicMaterialsCacheRef = mpl
94        .create_cryptographic_materials_cache()
95        .cache(cache)
96        .send()
97        .await?;
98
99    // 1b. Create a CacheType object for the shared_cryptographic_materials_cache
100    // Note that the `cache` parameter in the Hierarchical Keyring Input takes a `CacheType` as input
101    // Here, we pass a `Shared` CacheType that passes an already initialized shared cache.
102
103    // If you want to use a Shared Cache, you need to initialize it only once, and
104    // pass the same cache `shared_cache` to different hierarchical keyrings.
105
106    // CryptographicMaterialsCacheRef is an Rc (Reference Counted), so if you clone it to
107    // pass it to different Hierarchical Keyrings, it will still point to the same
108    // underlying cache, and increment the reference count accordingly.
109    let shared_cache: CacheType = CacheType::Shared(shared_cryptographic_materials_cache);
110
111    // 2. Instantiate the encryption SDK client.
112    // This builds the default client with the RequireEncryptRequireDecrypt commitment policy,
113    // which enforces that this client only encrypts using committing algorithm suites and enforces
114    // that this client will only decrypt encrypted messages that were created with a committing
115    // algorithm suite.
116    let esdk_config = AwsEncryptionSdkConfig::builder().build()?;
117    let esdk_client = esdk_client::Client::from_conf(esdk_config)?;
118
119    // 3. Configure your Key Store resource key_store1.
120    //    This SHOULD be the same configuration that you used
121    //    to initially create and populate your physical Key Store.
122    // Note that key_store_table_name is the physical Key Store,
123    // and key_store1 is instances of this physical Key Store.
124    let sdk_config = aws_config::load_defaults(aws_config::BehaviorVersion::latest()).await;
125    let key_store_config = KeyStoreConfig::builder()
126        .kms_client(aws_sdk_kms::Client::new(&sdk_config))
127        .ddb_client(aws_sdk_dynamodb::Client::new(&sdk_config))
128        .ddb_table_name(key_store_table_name)
129        .logical_key_store_name(logical_key_store_name)
130        .kms_configuration(KmsConfiguration::KmsKeyArn(
131            key_store_kms_key_id.to_string(),
132        ))
133        .build()?;
134
135    let key_store1 = keystore_client::Client::from_conf(key_store_config.clone())?;
136
137    // 4. Call create_branch_key_id to create one new active branch key
138    let branch_key_id: String = create_branch_key_id(
139        key_store_table_name,
140        logical_key_store_name,
141        key_store_kms_key_id,
142    )
143    .await?;
144
145    // 5. Create the Hierarchical Keyring HK1 with Key Store instance K1, partition_id,
146    // the shared_cache and the branch_key_id.
147    // Note that we are now providing an already initialized shared cache instead of just mentioning
148    // the cache type and the Hierarchical Keyring initializing a cache at initialization.
149
150    // partition_id for this example is a random UUID
151    let partition_id = "91c1b6a2-6fc3-4539-ad5e-938d597ed730".to_string();
152
153    // Please make sure that you read the guidance on how to set Partition ID, Logical Key Store Name and
154    // Branch Key ID at the top of this example before creating Hierarchical Keyrings with a Shared Cache
155    let keyring1 = mpl
156        .create_aws_kms_hierarchical_keyring()
157        .key_store(key_store1)
158        .branch_key_id(branch_key_id.clone())
159        // CryptographicMaterialsCacheRef is an Rc (Reference Counted), so if you clone it to
160        // pass it to different Hierarchical Keyrings, it will still point to the same
161        // underlying cache, and increment the reference count accordingly.
162        .cache(shared_cache.clone())
163        .ttl_seconds(600)
164        .partition_id(partition_id.clone())
165        .send()
166        .await?;
167
168    // 6. Create encryption context.
169    // Remember that your encryption context is NOT SECRET.
170    // For more information, see
171    // https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context
172    let encryption_context = HashMap::from([
173        ("encryption".to_string(), "context".to_string()),
174        ("is not".to_string(), "secret".to_string()),
175        ("but adds".to_string(), "useful metadata".to_string()),
176        (
177            "that can help you".to_string(),
178            "be confident that".to_string(),
179        ),
180        (
181            "the data you are handling".to_string(),
182            "is what you think it is".to_string(),
183        ),
184    ]);
185
186    // 7. Encrypt the data for encryption_context using keyring1
187    let plaintext = example_data.as_bytes();
188
189    let encryption_response1 = esdk_client
190        .encrypt()
191        .plaintext(plaintext)
192        .keyring(keyring1.clone())
193        .encryption_context(encryption_context.clone())
194        .send()
195        .await?;
196
197    let ciphertext1 = encryption_response1
198        .ciphertext
199        .expect("Unable to unwrap ciphertext from encryption response");
200
201    // 8. Demonstrate that the ciphertexts and plaintext are different.
202    // (This is an example for demonstration; you do not need to do this in your own code.)
203    assert_ne!(
204        ciphertext1,
205        aws_smithy_types::Blob::new(plaintext),
206        "Ciphertext and plaintext data are the same. Invalid encryption"
207    );
208
209    // 9. Decrypt your encrypted data using the same keyring HK1 you used on encrypt.
210    let decryption_response1 = esdk_client
211        .decrypt()
212        .ciphertext(ciphertext1)
213        .keyring(keyring1)
214        // Provide the encryption context that was supplied to the encrypt method
215        .encryption_context(encryption_context.clone())
216        .send()
217        .await?;
218
219    let decrypted_plaintext1 = decryption_response1
220        .plaintext
221        .expect("Unable to unwrap plaintext from decryption response");
222
223    // 10. Demonstrate that the decrypted plaintext is identical to the original plaintext.
224    // (This is an example for demonstration; you do not need to do this in your own code.)
225    assert_eq!(
226        decrypted_plaintext1,
227        aws_smithy_types::Blob::new(plaintext),
228        "Decrypted plaintext should be identical to the original plaintext. Invalid decryption"
229    );
230
231    // 11. Through the above encrypt and decrypt roundtrip, the cache will be populated and
232    // the cache entries can be used by another Hierarchical Keyring with the
233    // - Same Partition ID
234    // - Same Logical Key Store Name of the Key Store for the Hierarchical Keyring
235    // - Same Branch Key ID
236
237    // Configure your Key Store resource key_store2.
238    //    This SHOULD be the same configuration that you used
239    //    to initially create and populate your physical Key Store.
240    // Note that key_store_table_name is the physical Key Store,
241    // and key_store2 is instances of this physical Key Store.
242
243    // Note that for this example, key_store2 is identical to key_store1.
244    // You can optionally change configurations like KMS Client or KMS Key ID based
245    // on your use-case.
246    // Make sure you have the required permissions to use different configurations.
247
248    // - If you want to share cache entries across two keyrings HK1 and HK2,
249    //   you should set the Logical Key Store Names for both
250    //   Key Store instances (K1 and K2) to be the same.
251    // - If you set the Logical Key Store Names for K1 and K2 to be different,
252    //   HK1 (which uses Key Store instance K1) and HK2 (which uses Key Store
253    //   instance K2) will NOT be able to share cache entries.
254    let key_store2 = keystore_client::Client::from_conf(key_store_config.clone())?;
255
256    // 12. Create the Hierarchical Keyring HK2 with Key Store instance K2, the shared_cache
257    // and the same partition_id and branch_key_id used in HK1 because we want to share cache entries
258    // (and experience cache HITS).
259
260    // Please make sure that you read the guidance on how to set Partition ID, Logical Key Store Name and
261    // Branch Key ID at the top of this example before creating Hierarchical Keyrings with a Shared Cache
262    let keyring2 = mpl
263        .create_aws_kms_hierarchical_keyring()
264        .key_store(key_store2)
265        .branch_key_id(branch_key_id)
266        .cache(shared_cache)
267        .ttl_seconds(600)
268        .partition_id(partition_id)
269        .send()
270        .await?;
271
272    // 13. This encrypt-decrypt roundtrip with HK2 will experience Cache HITS from previous HK1 roundtrip
273    // Encrypt the data for encryption_context using keyring2
274    let encryption_response2 = esdk_client
275        .encrypt()
276        .plaintext(plaintext)
277        .keyring(keyring2.clone())
278        .encryption_context(encryption_context.clone())
279        .send()
280        .await?;
281
282    let ciphertext2 = encryption_response2
283        .ciphertext
284        .expect("Unable to unwrap ciphertext from encryption response");
285
286    // 14. Demonstrate that the ciphertexts and plaintext are different.
287    // (This is an example for demonstration; you do not need to do this in your own code.)
288    assert_ne!(
289        ciphertext2,
290        aws_smithy_types::Blob::new(plaintext),
291        "Ciphertext and plaintext data are the same. Invalid encryption"
292    );
293
294    // 15. Decrypt your encrypted data using the same keyring HK2 you used on encrypt.
295    let decryption_response2 = esdk_client
296        .decrypt()
297        .ciphertext(ciphertext2)
298        .keyring(keyring2)
299        // Provide the encryption context that was supplied to the encrypt method
300        .encryption_context(encryption_context)
301        .send()
302        .await?;
303
304    let decrypted_plaintext2 = decryption_response2
305        .plaintext
306        .expect("Unable to unwrap plaintext from decryption response");
307
308    // 10. Demonstrate that the decrypted plaintext is identical to the original plaintext.
309    // (This is an example for demonstration; you do not need to do this in your own code.)
310    assert_eq!(
311        decrypted_plaintext2,
312        aws_smithy_types::Blob::new(plaintext),
313        "Decrypted plaintext should be identical to the original plaintext. Invalid decryption"
314    );
315
316    println!("Shared Cache Across Hierarchical Keyrings Example Completed Successfully");
317
318    Ok(())
319}

Trait Implementations§

Source§

impl Clone for DefaultCache

Source§

fn clone(&self) -> DefaultCache

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for DefaultCache

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl PartialEq for DefaultCache

Source§

fn eq(&self, other: &DefaultCache) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl StructuralPartialEq for DefaultCache

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> AnyRef for T
where T: 'static,

Source§

fn as_any_ref(&self) -> &(dyn Any + 'static)

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<Unshared, Shared> IntoShared<Shared> for Unshared
where Shared: FromUnshared<Unshared>,

Source§

fn into_shared(self) -> Shared

Creates a shared type from an unshared type.
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> Upcast<T> for T
where T: ?Sized,

Source§

fn upcast(&self) -> Ptr<T>

Source§

impl<T> UpcastObject<T> for T
where T: ?Sized,

Source§

fn upcast(&self) -> Object<T>

Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more