Skip to content

Commit 00e41c3

Browse files
author
Bennett Hardwick
committed
HMAC sort key
1 parent 8e260d9 commit 00e41c3

File tree

5 files changed

+38
-15
lines changed

5 files changed

+38
-15
lines changed

cryptonamo-derive/src/encryptable.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ pub(crate) fn derive_encryptable(input: DeriveInput) -> Result<TokenStream, syn:
2424
let ident = settings.ident();
2525

2626
let is_partition_key_encrypted = protected_attributes.contains(&partition_key_field.as_str());
27+
let is_sort_key_encrypted = settings
28+
.sort_key_field
29+
.as_ref()
30+
.map(|x| protected_attributes.contains(&x.as_str()))
31+
.unwrap_or(true);
2732

2833
let into_unsealed_impl = protected_attributes
2934
.iter()
@@ -67,6 +72,7 @@ pub(crate) fn derive_encryptable(input: DeriveInput) -> Result<TokenStream, syn:
6772
impl cryptonamo::traits::Encryptable for #ident {
6873
#primary_key_impl
6974

75+
#[inline]
7076
fn type_name() -> &'static str {
7177
#type_name
7278
}
@@ -75,14 +81,21 @@ pub(crate) fn derive_encryptable(input: DeriveInput) -> Result<TokenStream, syn:
7581
#sort_key_impl
7682
}
7783

84+
#[inline]
7885
fn sort_key_prefix() -> Option<&'static str> {
7986
#sort_key_prefix
8087
}
8188

89+
#[inline]
8290
fn is_partition_key_encrypted() -> bool {
8391
#is_partition_key_encrypted
8492
}
8593

94+
#[inline]
95+
fn is_sort_key_encrypted() -> bool {
96+
#is_sort_key_encrypted
97+
}
98+
8699
fn partition_key(&self) -> String {
87100
self.#partition_key.to_string()
88101
}

src/crypto/sealer.rs

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use super::{encrypt_partition_key, SealError, Sealed, Unsealed, MAX_TERMS_PER_INDEX};
22
use crate::{
33
encrypted_table::{TableAttribute, TableEntry},
4+
traits::PrimaryKeyParts,
45
Searchable,
56
};
67
use cipherstash_client::{
@@ -54,22 +55,28 @@ impl<T> Sealer<T> {
5455
self,
5556
cipher: &Encryption<C>,
5657
term_length: usize, // TODO: SealError
57-
) -> Result<(String, Vec<Sealed>), SealError>
58+
) -> Result<(PrimaryKeyParts, Vec<Sealed>), SealError>
5859
where
5960
C: Credentials<Token = ViturToken>,
6061
T: Searchable,
6162
{
6263
let mut pk = self.inner.partition_key();
64+
let mut sk = self.inner.sort_key();
6365

6466
if T::is_partition_key_encrypted() {
65-
// FIXME
66-
pk = encrypt_partition_key(&self.inner.partition_key(), cipher).unwrap();
67+
pk = encrypt_partition_key(&pk, cipher)?;
6768
}
6869

69-
let sk = self.inner.sort_key();
70+
if T::is_sort_key_encrypted() {
71+
sk = encrypt_partition_key(&sk, cipher)?;
72+
}
7073

71-
let mut table_entry =
72-
TableEntry::new_with_attributes(pk.clone(), sk, None, self.unsealed.unprotected());
74+
let mut table_entry = TableEntry::new_with_attributes(
75+
pk.clone(),
76+
sk.clone(),
77+
None,
78+
self.unsealed.unprotected(),
79+
);
7380

7481
let protected = T::protected_attributes()
7582
.iter()
@@ -91,8 +98,6 @@ impl<T> Sealer<T> {
9198
}
9299
});
93100

94-
let sort_key = self.inner.sort_key();
95-
96101
let protected_indexes = T::protected_indexes();
97102
let terms: Vec<(&&str, Vec<u8>)> = protected_indexes
98103
.iter()
@@ -135,13 +140,13 @@ impl<T> Sealer<T> {
135140
.clone()
136141
.set_term(hex::encode(term))
137142
// TODO: HMAC the sort key, too (users#index_name#pk)
138-
.set_sk(format!("{}#{}#{}", &sort_key, index_name, i)),
143+
.set_sk(format!("{}#{}#{}", &sk, index_name, i)),
139144
)
140145
})
141146
.chain(once(Sealed(table_entry.clone())))
142147
.collect();
143148

144-
Ok((pk, table_entries))
149+
Ok((PrimaryKeyParts { pk, sk }, table_entries))
145150
}
146151

147152
#[allow(dead_code)]

src/encrypted_table/mod.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -120,12 +120,16 @@ impl EncryptedTable {
120120
&self,
121121
k: impl Into<T::PrimaryKey>,
122122
) -> Result<PrimaryKeyParts, EncryptionError> {
123-
let PrimaryKeyParts { mut pk, sk } = k.into().into_parts::<T>();
123+
let PrimaryKeyParts { mut pk, mut sk } = k.into().into_parts::<T>();
124124

125125
if T::is_partition_key_encrypted() {
126126
pk = encrypt_partition_key(&pk, &self.cipher)?;
127127
}
128128

129+
if T::is_sort_key_encrypted() {
130+
sk = encrypt_partition_key(&sk, &self.cipher)?;
131+
}
132+
129133
Ok(PrimaryKeyParts { pk, sk })
130134
}
131135

@@ -160,7 +164,7 @@ impl EncryptedTable {
160164
) -> Result<(), DeleteError> {
161165
let PrimaryKeyParts { pk, sk } = self.get_primary_key_parts::<E>(k)?;
162166

163-
let sk_to_delete = all_index_keys::<E>(&sk).into_iter().into_iter().chain([sk]);
167+
let sk_to_delete = all_index_keys::<E>(&sk).into_iter().chain([sk]);
164168

165169
let transact_items = sk_to_delete.map(|sk| {
166170
TransactWriteItem::builder()
@@ -194,9 +198,8 @@ impl EncryptedTable {
194198
{
195199
let mut seen_sk = HashSet::new();
196200

197-
let sk = record.sort_key();
198201
let sealer: Sealer<T> = record.into_sealer()?;
199-
let (pk, sealed) = sealer.seal(&self.cipher, 12).await?;
202+
let (PrimaryKeyParts { pk, sk }, sealed) = sealer.seal(&self.cipher, 12).await?;
200203

201204
// TODO: Use a combinator
202205
let mut items: Vec<TransactWriteItem> = Vec::with_capacity(sealed.len());

src/traits/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ pub trait Encryptable: Debug + Sized {
3737

3838
fn is_partition_key_encrypted() -> bool;
3939

40+
fn is_sort_key_encrypted() -> bool;
41+
4042
fn sort_key(&self) -> String {
4143
Self::type_name().into()
4244
}

src/traits/primary_key.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::Encryptable;
22

33
pub struct PrimaryKeyParts {
44
pub(crate) pk: String,
5-
pub(crate) sk: String,
5+
pub(crate) sk: String
66
}
77

88
pub trait PrimaryKey: private::Sealed {

0 commit comments

Comments
 (0)