Skip to content

Commit 79bd721

Browse files
author
Bennett Hardwick
committed
Don't panic on chunks exact
1 parent 0cb8db1 commit 79bd721

File tree

2 files changed

+57
-46
lines changed

2 files changed

+57
-46
lines changed

src/crypto/sealed.rs

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::{
66
use aws_sdk_dynamodb::{primitives::Blob, types::AttributeValue};
77
use cipherstash_client::{
88
credentials::{service_credentials::ServiceToken, Credentials},
9-
encryption::Encryption,
9+
encryption::{Encryption, Plaintext},
1010
};
1111
use std::{borrow::Cow, collections::HashMap, ops::Deref};
1212

@@ -66,21 +66,28 @@ impl SealedTableEntry {
6666
let mut decryptable_items = Vec::with_capacity(items.len() * protected_attributes.len());
6767

6868
for item in items.iter() {
69-
let ciphertexts = protected_attributes
70-
.iter()
71-
.map(|name| {
72-
let attribute = item.inner().attributes.get(match name.deref() {
73-
"pk" => "__pk",
74-
"sk" => "__sk",
75-
_ => name,
76-
});
77-
78-
attribute
79-
.ok_or_else(|| SealError::MissingAttribute(name.to_string()))?
80-
.as_encrypted_record()
81-
.ok_or_else(|| SealError::InvalidCiphertext(name.to_string()))
82-
})
83-
.collect::<Result<Vec<_>, _>>()?;
69+
if !protected_attributes.is_empty() {
70+
let ciphertexts = protected_attributes
71+
.iter()
72+
.map(|name| {
73+
let attribute = item.inner().attributes.get(match name.deref() {
74+
"pk" => "__pk",
75+
"sk" => "__sk",
76+
_ => name,
77+
});
78+
79+
attribute
80+
.ok_or_else(|| SealError::MissingAttribute(name.to_string()))?
81+
.as_encrypted_record()
82+
.ok_or_else(|| SealError::InvalidCiphertext(name.to_string()))
83+
})
84+
.collect::<Result<Vec<_>, _>>()?;
85+
86+
// Create a list of all ciphertexts so that they can all be decrypted in one go.
87+
// The decrypted version of this list will be chunked up and zipped with the plaintext
88+
// fields once the decryption succeeds.
89+
decryptable_items.extend(ciphertexts);
90+
}
8491

8592
let unprotected = plaintext_attributes
8693
.iter()
@@ -98,17 +105,18 @@ impl SealedTableEntry {
98105
.collect::<Result<Vec<&TableAttribute>, SealError>>()?;
99106

100107
plaintext_items.push(unprotected);
101-
102-
// Create a list of all ciphertexts so that they can all be decrypted in one go.
103-
// The decrypted version of this list will be chunked up and zipped with the plaintext
104-
// fields once the decryption succeeds.
105-
decryptable_items.extend(ciphertexts);
106108
}
107109

108110
let decrypted = cipher.decrypt(decryptable_items).await?;
109111

110-
let unsealed = decrypted
111-
.chunks_exact(protected_attributes.len())
112+
let decrypted_iter: &mut dyn Iterator<Item = &[Plaintext]> =
113+
if protected_attributes.len() > 0 {
114+
&mut decrypted.chunks_exact(protected_attributes.len())
115+
} else {
116+
&mut std::iter::repeat_with::<&[Plaintext], _>(|| &[]).take(plaintext_items.len())
117+
};
118+
119+
let unsealed = decrypted_iter
112120
.zip(plaintext_items)
113121
.map(|(decrypted_plaintext, plaintext_items)| {
114122
let mut unsealed = Unsealed::new();

src/crypto/sealer.rs

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -218,29 +218,32 @@ impl Sealer {
218218
));
219219
}
220220

221-
let encrypted = cipher
222-
.encrypt(protected.iter().map(|(a, b)| (a, b.as_str())))
223-
.await?;
224-
225-
for (encrypted, (_, attributes, _)) in encrypted
226-
.chunks_exact(protected_attributes.len())
227-
.zip(table_entries.iter_mut())
228-
{
229-
for (enc, name) in encrypted.iter().zip(protected_attributes.iter()) {
230-
let name: &str = name.deref();
231-
232-
attributes.insert(
233-
String::from(match name {
234-
"pk" => "__pk",
235-
"sk" => "__sk",
236-
_ => name,
237-
}),
238-
TableAttribute::Bytes(enc.to_vec().map_err(|_| {
239-
SealError::InvalidCiphertext(
240-
"Failed to serialize encrypted record as bytes".into(),
241-
)
242-
})?),
243-
);
221+
// Only encrypt if there are actually protected attributes
222+
if !protected_attributes.is_empty() {
223+
let encrypted = cipher
224+
.encrypt(protected.iter().map(|(a, b)| (a, b.as_str())))
225+
.await?;
226+
227+
for (encrypted, (_, attributes, _)) in encrypted
228+
.chunks_exact(protected_attributes.len())
229+
.zip(table_entries.iter_mut())
230+
{
231+
for (enc, name) in encrypted.iter().zip(protected_attributes.iter()) {
232+
let name: &str = name.deref();
233+
234+
attributes.insert(
235+
String::from(match name {
236+
"pk" => "__pk",
237+
"sk" => "__sk",
238+
_ => name,
239+
}),
240+
TableAttribute::Bytes(enc.to_vec().map_err(|_| {
241+
SealError::InvalidCiphertext(
242+
"Failed to serialize encrypted record as bytes".into(),
243+
)
244+
})?),
245+
);
246+
}
244247
}
245248
}
246249

0 commit comments

Comments
 (0)