Skip to content

Commit c7b461b

Browse files
authored
Merge pull request #90 from cipherstash/reintroduce-object-safe-sub-functionality
Reintroduce `fn unseal` and `fn unseal_all` on `EncryptedTable` + mak…
2 parents 16d202a + 7082dbe commit c7b461b

File tree

1 file changed

+54
-19
lines changed

1 file changed

+54
-19
lines changed

src/encrypted_table/mod.rs

Lines changed: 54 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ use std::{
3434
};
3535
use uuid::Uuid;
3636

37+
pub type DatasetId = Uuid;
38+
3739
pub struct Headless;
3840

3941
pub struct Dynamo {
@@ -276,17 +278,33 @@ impl<D> EncryptedTable<D> {
276278
pub async fn decrypt_all<T>(
277279
&self,
278280
items: impl IntoIterator<Item = HashMap<String, AttributeValue>>,
279-
) -> Result<Vec<T>, SealError>
281+
) -> Result<Vec<T>, DecryptError>
280282
where
281283
T: Decryptable + Identifiable,
282284
{
283-
decrypt_all(&self.cipher, items).await
285+
Ok(decrypt_all(&self.cipher, items).await?)
286+
}
287+
288+
pub async fn unseal<'a>(
289+
&self,
290+
spec: UnsealSpec<'a>,
291+
item: HashMap<String, AttributeValue>,
292+
) -> Result<Unsealed, DecryptError> {
293+
unseal(&self.cipher, spec, item).await
294+
}
295+
296+
pub async fn unseal_all<'a>(
297+
&self,
298+
spec: UnsealSpec<'a>,
299+
items: Vec<HashMap<String, AttributeValue>>,
300+
) -> Result<Vec<Unsealed>, DecryptError> {
301+
Ok(unseal_all(&self.cipher, spec, items).await?)
284302
}
285303

286304
pub async fn create_delete_patch(
287305
&self,
288306
delete: PreparedDelete,
289-
dataset_id: Option<Uuid>,
307+
dataset_id: Option<DatasetId>,
290308
) -> Result<DynamoRecordPatch, DeleteError> {
291309
let scoped_cipher = ScopedZeroKmsCipher::init(self.cipher.clone(), dataset_id).await?;
292310

@@ -322,7 +340,7 @@ impl<D> EncryptedTable<D> {
322340
pub async fn create_put_patch(
323341
&self,
324342
record: PreparedRecord,
325-
dataset_id: Option<Uuid>,
343+
dataset_id: Option<DatasetId>,
326344
// TODO: Make sure the index_predicate is used correctly
327345
index_predicate: impl FnMut(&AttributeName, &TableAttribute) -> bool,
328346
) -> Result<DynamoRecordPatch, PutError> {
@@ -407,7 +425,7 @@ impl EncryptedTable<Dynamo> {
407425
pub async fn get_via<T>(
408426
&self,
409427
k: impl Into<T::PrimaryKey>,
410-
dataset_id: Uuid,
428+
dataset_id: DatasetId,
411429
) -> Result<Option<T>, GetError>
412430
where
413431
T: Decryptable + Identifiable,
@@ -418,7 +436,7 @@ impl EncryptedTable<Dynamo> {
418436
async fn get_inner<T>(
419437
&self,
420438
k: impl Into<T::PrimaryKey>,
421-
dataset_id: Option<Uuid>,
439+
dataset_id: Option<DatasetId>,
422440
) -> Result<Option<T>, GetError>
423441
where
424442
T: Decryptable + Identifiable,
@@ -457,15 +475,15 @@ impl EncryptedTable<Dynamo> {
457475
pub async fn delete_via<E: Searchable + Identifiable>(
458476
&self,
459477
k: impl Into<E::PrimaryKey>,
460-
dataset_id: Uuid,
478+
dataset_id: DatasetId,
461479
) -> Result<(), DeleteError> {
462480
self.delete_inner::<E>(k.into(), Some(dataset_id)).await
463481
}
464482

465483
async fn delete_inner<E: Searchable + Identifiable>(
466484
&self,
467485
k: E::PrimaryKey,
468-
dataset_id: Option<Uuid>,
486+
dataset_id: Option<DatasetId>,
469487
) -> Result<(), DeleteError> {
470488
let transact_items = self
471489
.create_delete_patch(PreparedDelete::new::<E>(k), dataset_id)
@@ -494,14 +512,14 @@ impl EncryptedTable<Dynamo> {
494512
}
495513

496514
/// Put a record into the table using a specific dataset.
497-
pub async fn put_via<T>(&self, record: T, dataset_id: Uuid) -> Result<(), PutError>
515+
pub async fn put_via<T>(&self, record: T, dataset_id: DatasetId) -> Result<(), PutError>
498516
where
499517
T: Searchable + Identifiable,
500518
{
501519
self.put_inner(record, Some(dataset_id)).await
502520
}
503521

504-
async fn put_inner<T>(&self, record: T, dataset_id: Option<Uuid>) -> Result<(), PutError>
522+
async fn put_inner<T>(&self, record: T, dataset_id: Option<DatasetId>) -> Result<(), PutError>
505523
where
506524
T: Searchable + Identifiable,
507525
{
@@ -532,7 +550,7 @@ impl EncryptedTable<Dynamo> {
532550

533551
/// Take a prepared primary key and encrypt it to get the [`PrimaryKeyParts`] which can be used
534552
/// for retrieval.
535-
fn encrypt_primary_key_parts(
553+
pub fn encrypt_primary_key_parts(
536554
scoped_cipher: &ScopedZeroKmsCipher,
537555
prepared_primary_key: PreparedPrimaryKey,
538556
) -> Result<PrimaryKeyParts, PrimaryKeyError> {
@@ -550,32 +568,49 @@ fn encrypt_primary_key_parts(
550568
}
551569

552570
async fn decrypt<T>(
553-
scoped_cipher: &ZeroKmsCipher,
571+
cipher: &ZeroKmsCipher,
554572
item: HashMap<String, AttributeValue>,
555573
) -> Result<T, DecryptError>
556574
where
557575
T: Decryptable + Identifiable,
558576
{
559-
let uspec = UnsealSpec::new_for_decryptable::<T>();
577+
let spec = UnsealSpec::new_for_decryptable::<T>();
578+
579+
Ok(unseal(cipher, spec, item).await?.into_value::<T>()?)
580+
}
581+
582+
async fn unseal<'a>(
583+
cipher: &ZeroKmsCipher,
584+
spec: UnsealSpec<'a>,
585+
item: HashMap<String, AttributeValue>,
586+
) -> Result<Unsealed, DecryptError> {
560587
let table_entry = SealedTableEntry::try_from(item)?;
561-
let result = table_entry.unseal(uspec, scoped_cipher).await?;
562588

563-
Ok(result.into_value()?)
589+
Ok(table_entry.unseal(spec, cipher).await?)
590+
}
591+
592+
async fn unseal_all<'a>(
593+
cipher: &ZeroKmsCipher,
594+
spec: UnsealSpec<'a>,
595+
items: impl IntoIterator<Item = HashMap<String, AttributeValue>>,
596+
) -> Result<Vec<Unsealed>, SealError> {
597+
let table_entries = SealedTableEntry::vec_from(items)?;
598+
599+
SealedTableEntry::unseal_all(table_entries, spec, cipher).await
564600
}
565601

566602
async fn decrypt_all<T>(
567-
scoped_cipher: &ZeroKmsCipher,
603+
cipher: &ZeroKmsCipher,
568604
items: impl IntoIterator<Item = HashMap<String, AttributeValue>>,
569605
) -> Result<Vec<T>, SealError>
570606
where
571607
T: Decryptable + Identifiable,
572608
{
573609
let spec = UnsealSpec::new_for_decryptable::<T>();
574-
let table_entries = SealedTableEntry::vec_from(items)?;
575610

576-
SealedTableEntry::unseal_all(table_entries, spec, scoped_cipher)
611+
unseal_all(cipher, spec, items)
577612
.await?
578613
.into_iter()
579614
.map(|x| x.into_value::<T>())
580-
.collect()
615+
.collect::<Result<_, _>>()
581616
}

0 commit comments

Comments
 (0)