diff --git a/crates/common_utils/src/crypto.rs b/crates/common_utils/src/crypto.rs index 27d941b323..0540bfe19d 100644 --- a/crates/common_utils/src/crypto.rs +++ b/crates/common_utils/src/crypto.rs @@ -2,6 +2,7 @@ use std::ops::Deref; use error_stack::{IntoReport, ResultExt}; +use masking::{ExposeInterface, Secret}; use md5; use ring::{ aead::{self, BoundKey, OpeningKey, SealingKey, UnboundKey}, @@ -10,7 +11,7 @@ use ring::{ use crate::{ errors::{self, CustomResult}, - pii, + pii::{self, EncryptionStratergy}, }; #[derive(Clone, Debug)] @@ -103,7 +104,7 @@ pub trait DecodeMessage { fn decode_message( &self, _secret: &[u8], - _msg: Vec, + _msg: Secret, EncryptionStratergy>, ) -> CustomResult, errors::CryptoError>; } @@ -147,9 +148,9 @@ impl DecodeMessage for NoAlgorithm { fn decode_message( &self, _secret: &[u8], - msg: Vec, + msg: Secret, EncryptionStratergy>, ) -> CustomResult, errors::CryptoError> { - Ok(msg.to_vec()) + Ok(msg.expose()) } } @@ -242,8 +243,9 @@ impl DecodeMessage for GcmAes256 { fn decode_message( &self, secret: &[u8], - msg: Vec, + msg: Secret, EncryptionStratergy>, ) -> CustomResult, errors::CryptoError> { + let msg = msg.expose(); let key = UnboundKey::new(&aead::AES_256_GCM, secret) .into_report() .change_context(errors::CryptoError::DecodingFailed)?; @@ -264,7 +266,7 @@ impl DecodeMessage for GcmAes256 { .into_report() .change_context(errors::CryptoError::DecodingFailed)?; - Ok(result.into()) + Ok(result.to_vec()) } } @@ -380,14 +382,17 @@ pub fn generate_cryptographically_secure_random_bytes() -> [u8; #[derive(Debug, Clone)] pub struct Encryptable { inner: T, - encrypted: Vec, + encrypted: Secret, EncryptionStratergy>, } -impl> Encryptable> { +impl> Encryptable> { /// /// constructor function to be used by the encryptor and decryptor to generate the data type /// - pub fn new(masked_data: masking::Secret, encrypted_data: Vec) -> Self { + pub fn new( + masked_data: Secret, + encrypted_data: Secret, EncryptionStratergy>, + ) -> Self { Self { inner: masked_data, encrypted: encrypted_data, @@ -405,13 +410,13 @@ impl Encryptable { /// /// Get the inner encrypted data while consuming self /// - pub fn into_encrypted(self) -> Vec { + pub fn into_encrypted(self) -> Secret, EncryptionStratergy> { self.encrypted } } -impl Deref for Encryptable> { - type Target = masking::Secret; +impl Deref for Encryptable> { + type Target = Secret; fn deref(&self) -> &Self::Target { &self.inner } @@ -439,18 +444,17 @@ where } /// Type alias for `Option>>` -pub type OptionalEncryptableSecretString = Option>>; +pub type OptionalEncryptableSecretString = Option>>; /// Type alias for `Option>>` used for `name` field -pub type OptionalEncryptableName = Option>>; +pub type OptionalEncryptableName = Option>>; /// Type alias for `Option>>` used for `email` field -pub type OptionalEncryptableEmail = - Option>>; +pub type OptionalEncryptableEmail = Option>>; /// Type alias for `Option>>` used for `phone` field -pub type OptionalEncryptablePhone = Option>>; +pub type OptionalEncryptablePhone = Option>>; /// Type alias for `Option>>` used for `phone` field -pub type OptionalEncryptableValue = Option>>; +pub type OptionalEncryptableValue = Option>>; /// Type alias for `Option>` used for `phone` field -pub type OptionalSecretValue = Option>; +pub type OptionalSecretValue = Option>; #[cfg(test)] mod crypto_tests { @@ -572,7 +576,7 @@ mod crypto_tests { assert_eq!( algorithm - .decode_message(&secret, encoded_message) + .decode_message(&secret, encoded_message.into()) .expect("Decode Failed"), message ); @@ -594,12 +598,12 @@ mod crypto_tests { }; let decoded = algorithm - .decode_message(&right_secret, message.clone()) + .decode_message(&right_secret, message.clone().into()) .expect("Decoded message"); assert_eq!(decoded, r#"{"type":"PAYMENT"}"#.as_bytes()); - let err_decoded = algorithm.decode_message(&wrong_secret, message); + let err_decoded = algorithm.decode_message(&wrong_secret, message.into()); assert!(err_decoded.is_err()); } diff --git a/crates/common_utils/src/pii.rs b/crates/common_utils/src/pii.rs index c4d4d8b7a0..fddbdcdab8 100644 --- a/crates/common_utils/src/pii.rs +++ b/crates/common_utils/src/pii.rs @@ -142,6 +142,19 @@ where } */ +/// Strategy for Encryption +#[derive(Debug)] +pub struct EncryptionStratergy; + +impl Strategy for EncryptionStratergy +where + T: AsRef<[u8]>, +{ + fn fmt(value: &T, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(fmt, "*** Encrypted {} of bytes ***", value.as_ref().len()) + } +} + /// Client secret #[derive(Debug)] pub struct ClientSecret; diff --git a/crates/router/src/types/api/webhooks.rs b/crates/router/src/types/api/webhooks.rs index a14b9ba044..cdc57c98d4 100644 --- a/crates/router/src/types/api/webhooks.rs +++ b/crates/router/src/types/api/webhooks.rs @@ -60,7 +60,7 @@ pub trait IncomingWebhook: ConnectorCommon + Sync { .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; algorithm - .decode_message(&secret, message) + .decode_message(&secret, message.into()) .change_context(errors::ConnectorError::WebhookBodyDecodingFailed) } diff --git a/crates/router/src/types/domain/types.rs b/crates/router/src/types/domain/types.rs index d159b63164..82dd32bcfd 100644 --- a/crates/router/src/types/domain/types.rs +++ b/crates/router/src/types/domain/types.rs @@ -45,7 +45,7 @@ impl< ) -> CustomResult { let encrypted_data = crypt_algo.encode_message(key, masked_data.peek().as_bytes())?; - Ok(Self::new(masked_data, encrypted_data)) + Ok(Self::new(masked_data, encrypted_data.into())) } #[instrument(skip_all)] @@ -84,7 +84,7 @@ impl< .change_context(errors::CryptoError::DecodingFailed)?; let encrypted_data = crypt_algo.encode_message(key, &data)?; - Ok(Self::new(masked_data, encrypted_data)) + Ok(Self::new(masked_data, encrypted_data.into())) } #[instrument(skip_all)] @@ -118,7 +118,7 @@ impl< ) -> CustomResult { let encrypted_data = crypt_algo.encode_message(key, masked_data.peek())?; - Ok(Self::new(masked_data, encrypted_data)) + Ok(Self::new(masked_data, encrypted_data.into())) } #[instrument(skip_all)] diff --git a/crates/storage_models/src/encryption.rs b/crates/storage_models/src/encryption.rs index 2790eaf668..604a69e4d3 100644 --- a/crates/storage_models/src/encryption.rs +++ b/crates/storage_models/src/encryption.rs @@ -1,15 +1,17 @@ +use common_utils::pii::EncryptionStratergy; use diesel::{ backend::Backend, deserialize::{self, FromSql, Queryable}, serialize::ToSql, sql_types, AsExpression, }; +use masking::Secret; #[derive(Debug, AsExpression, Clone, serde::Serialize, serde::Deserialize)] #[diesel(sql_type = diesel::sql_types::Binary)] #[repr(transparent)] pub struct Encryption { - inner: Vec, + inner: Secret, EncryptionStratergy>, } impl From> for Encryption { @@ -19,17 +21,17 @@ impl From> for Encryption { } impl Encryption { - pub fn new(item: Vec) -> Self { + pub fn new(item: Secret, EncryptionStratergy>) -> Self { Self { inner: item } } #[inline] - pub fn into_inner(self) -> Vec { + pub fn into_inner(self) -> Secret, EncryptionStratergy> { self.inner } #[inline] - pub fn get_inner(&self) -> &Vec { + pub fn get_inner(&self) -> &Secret, EncryptionStratergy> { &self.inner } } @@ -37,17 +39,17 @@ impl Encryption { impl FromSql for Encryption where DB: Backend, - Vec: FromSql, + Secret, EncryptionStratergy>: FromSql, { fn from_sql(bytes: DB::RawValue<'_>) -> diesel::deserialize::Result { - >::from_sql(bytes).map(Self::new) + , EncryptionStratergy>>::from_sql(bytes).map(Self::new) } } impl ToSql for Encryption where DB: Backend, - Vec: ToSql, + Secret, EncryptionStratergy>: ToSql, { fn to_sql<'b>( &'b self, @@ -60,9 +62,9 @@ where impl Queryable for Encryption where DB: Backend, - Vec: FromSql, + Secret, EncryptionStratergy>: FromSql, { - type Row = Vec; + type Row = Secret, EncryptionStratergy>; fn build(row: Self::Row) -> deserialize::Result { Ok(Self { inner: row }) }