diff options
Diffstat (limited to 'atuin-client/src/record/encryption.rs')
-rw-r--r-- | atuin-client/src/record/encryption.rs | 48 |
1 files changed, 37 insertions, 11 deletions
diff --git a/atuin-client/src/record/encryption.rs b/atuin-client/src/record/encryption.rs index 3074a9c2..9d5378d6 100644 --- a/atuin-client/src/record/encryption.rs +++ b/atuin-client/src/record/encryption.rs @@ -1,3 +1,5 @@ +use std::marker::PhantomData; + use atuin_common::record::{ AdditionalData, DecryptedData, EncryptedData, Encryption, HostId, RecordId, }; @@ -11,7 +13,11 @@ use serde::{Deserialize, Serialize}; /// Use PASETO V4 Local encryption using the additional data as an implicit assertion. #[allow(non_camel_case_types)] -pub struct PASETO_V4; +pub struct PASETO_V4_ENVELOPE<KE>(PhantomData<KE>); + +/// Use PASETO V4 Local encryption using the additional data as an implicit assertion. +#[allow(non_camel_case_types)] +pub type PASETO_V4 = PASETO_V4_ENVELOPE<Wrap>; /* Why do we use a random content-encryption key? @@ -51,19 +57,22 @@ will need the HSM. This allows the encryption path to still be extremely fast (n that happens in the background can make the network calls to the HSM */ -impl Encryption for PASETO_V4 { +impl<KE: KeyEncapsulation> Encryption for PASETO_V4_ENVELOPE<KE> { + type DecryptionKey = KE::DecryptionKey; + type EncryptionKey = KE::EncryptionKey; + fn re_encrypt( mut data: EncryptedData, _ad: AdditionalData, - old_key: &[u8; 32], - new_key: &[u8; 32], + old_key: &KE::DecryptionKey, + new_key: &KE::EncryptionKey, ) -> Result<EncryptedData> { - let cek = Self::decrypt_cek(data.content_encryption_key, old_key)?; - data.content_encryption_key = Self::encrypt_cek(cek, new_key); + let cek = KE::decrypt_cek(data.content_encryption_key, old_key)?; + data.content_encryption_key = KE::encrypt_cek(cek, new_key); Ok(data) } - fn encrypt(data: DecryptedData, ad: AdditionalData, key: &[u8; 32]) -> EncryptedData { + fn encrypt(data: DecryptedData, ad: AdditionalData, key: &KE::EncryptionKey) -> EncryptedData { // generate a random key for this entry // aka content-encryption-key (CEK) let random_key = Key::<V4, Local>::new_os_random(); @@ -87,13 +96,17 @@ impl Encryption for PASETO_V4 { EncryptedData { data: token, - content_encryption_key: Self::encrypt_cek(random_key, key), + content_encryption_key: KE::encrypt_cek(random_key, key), } } - fn decrypt(data: EncryptedData, ad: AdditionalData, key: &[u8; 32]) -> Result<DecryptedData> { + fn decrypt( + data: EncryptedData, + ad: AdditionalData, + key: &KE::DecryptionKey, + ) -> Result<DecryptedData> { let token = data.data; - let cek = Self::decrypt_cek(data.content_encryption_key, key)?; + let cek = KE::decrypt_cek(data.content_encryption_key, key)?; // encode the implicit assertions let assertions = Assertions::from(ad).encode(); @@ -113,7 +126,20 @@ impl Encryption for PASETO_V4 { } } -impl PASETO_V4 { +pub trait KeyEncapsulation { + type DecryptionKey; + type EncryptionKey; + + fn decrypt_cek(wrapped_cek: String, key: &Self::DecryptionKey) -> Result<Key<V4, Local>>; + fn encrypt_cek(cek: Key<V4, Local>, key: &Self::EncryptionKey) -> String; +} + +pub struct Wrap; + +impl KeyEncapsulation for Wrap { + type DecryptionKey = [u8; 32]; + type EncryptionKey = [u8; 32]; + fn decrypt_cek(wrapped_cek: String, key: &[u8; 32]) -> Result<Key<V4, Local>> { let wrapping_key = Key::<V4, Local>::from_bytes(*key); |