-
Notifications
You must be signed in to change notification settings - Fork 49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add sensitive types to SymmetricCryptoKey #672
Merged
Merged
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
d2de7d6
Add sensitive types to SymmetricCryptoKey
dani-garcia a5a8097
Add uniffi support
dani-garcia 2c1ff1c
Make sure the uniffi type is generated correctly
dani-garcia 9eccf0e
Add reallocation note
dani-garcia fee97ec
Review comments
dani-garcia 2a354b5
Use sensitivestring in ClientState and payload
dani-garcia f61e85a
Merge branch 'main' into ps/sensitive
dani-garcia c57d6ef
Missed new change
dani-garcia File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
@@ -1,13 +1,13 @@ | ||||||||
use std::{pin::Pin, str::FromStr}; | ||||||||
use std::pin::Pin; | ||||||||
|
||||||||
use aes::cipher::typenum::U32; | ||||||||
use base64::{engine::general_purpose::STANDARD, Engine}; | ||||||||
use base64::engine::general_purpose::STANDARD; | ||||||||
use generic_array::GenericArray; | ||||||||
use rand::Rng; | ||||||||
use zeroize::{Zeroize, Zeroizing}; | ||||||||
use zeroize::Zeroize; | ||||||||
|
||||||||
use super::key_encryptable::CryptoKey; | ||||||||
use crate::CryptoError; | ||||||||
use crate::{CryptoError, SensitiveString, SensitiveVec}; | ||||||||
|
||||||||
/// A symmetric encryption key. Used to encrypt and decrypt [`EncString`](crate::EncString) | ||||||||
pub struct SymmetricCryptoKey { | ||||||||
|
@@ -59,31 +59,35 @@ impl SymmetricCryptoKey { | |||||||
self.key.len() + self.mac_key.as_ref().map_or(0, |mac| mac.len()) | ||||||||
} | ||||||||
|
||||||||
pub fn to_base64(&self) -> String { | ||||||||
let mut buf = self.to_vec(); | ||||||||
|
||||||||
let result = STANDARD.encode(&buf); | ||||||||
buf.zeroize(); | ||||||||
result | ||||||||
pub fn to_base64(&self) -> SensitiveString { | ||||||||
self.to_vec().encode_base64(STANDARD) | ||||||||
} | ||||||||
|
||||||||
pub fn to_vec(&self) -> Zeroizing<Vec<u8>> { | ||||||||
let mut buf = Vec::with_capacity(self.total_len()); | ||||||||
pub fn to_vec(&self) -> SensitiveVec { | ||||||||
let mut buf = SensitiveVec::new(Box::new(Vec::with_capacity(self.total_len()))); | ||||||||
|
||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe add a comment why it's important to allocate the full length. It could be seen as an optimization method otherwise.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||||||||
buf.extend_from_slice(&self.key); | ||||||||
buf.expose_mut().extend_from_slice(&self.key); | ||||||||
if let Some(mac) = &self.mac_key { | ||||||||
buf.extend_from_slice(mac); | ||||||||
buf.expose_mut().extend_from_slice(mac); | ||||||||
} | ||||||||
Zeroizing::new(buf) | ||||||||
buf | ||||||||
} | ||||||||
} | ||||||||
|
||||||||
impl FromStr for SymmetricCryptoKey { | ||||||||
type Err = CryptoError; | ||||||||
impl TryFrom<SensitiveString> for SymmetricCryptoKey { | ||||||||
type Error = CryptoError; | ||||||||
|
||||||||
fn from_str(s: &str) -> Result<Self, Self::Err> { | ||||||||
let mut bytes = STANDARD.decode(s).map_err(|_| CryptoError::InvalidKey)?; | ||||||||
SymmetricCryptoKey::try_from(bytes.as_mut_slice()) | ||||||||
fn try_from(value: SensitiveString) -> Result<Self, Self::Error> { | ||||||||
SymmetricCryptoKey::try_from(value.decode_base64(STANDARD)?) | ||||||||
} | ||||||||
} | ||||||||
|
||||||||
impl TryFrom<SensitiveVec> for SymmetricCryptoKey { | ||||||||
type Error = CryptoError; | ||||||||
|
||||||||
fn try_from(mut value: SensitiveVec) -> Result<Self, Self::Error> { | ||||||||
let val = value.expose_mut(); | ||||||||
SymmetricCryptoKey::try_from(val.as_mut_slice()) | ||||||||
} | ||||||||
} | ||||||||
|
||||||||
|
@@ -138,19 +142,18 @@ pub fn derive_symmetric_key(name: &str) -> SymmetricCryptoKey { | |||||||
|
||||||||
#[cfg(test)] | ||||||||
mod tests { | ||||||||
use std::str::FromStr; | ||||||||
|
||||||||
use super::{derive_symmetric_key, SymmetricCryptoKey}; | ||||||||
use crate::SensitiveString; | ||||||||
|
||||||||
#[test] | ||||||||
fn test_symmetric_crypto_key() { | ||||||||
let key = derive_symmetric_key("test"); | ||||||||
let key2 = SymmetricCryptoKey::from_str(&key.to_base64()).unwrap(); | ||||||||
let key2 = SymmetricCryptoKey::try_from(key.to_base64()).unwrap(); | ||||||||
assert_eq!(key.key, key2.key); | ||||||||
assert_eq!(key.mac_key, key2.mac_key); | ||||||||
|
||||||||
let key = "UY4B5N4DA4UisCNClgZtRr6VLy9ZF5BXXC7cDZRqourKi4ghEMgISbCsubvgCkHf5DZctQjVot11/vVvN9NNHQ=="; | ||||||||
let key2 = SymmetricCryptoKey::from_str(key).unwrap(); | ||||||||
let key = SensitiveString::test("UY4B5N4DA4UisCNClgZtRr6VLy9ZF5BXXC7cDZRqourKi4ghEMgISbCsubvgCkHf5DZctQjVot11/vVvN9NNHQ=="); | ||||||||
let key2 = SymmetricCryptoKey::try_from(key.clone()).unwrap(); | ||||||||
assert_eq!(key, key2.to_base64()); | ||||||||
} | ||||||||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
use zeroize::Zeroize; | ||
|
||
use crate::{CryptoError, CryptoKey, KeyEncryptable, Sensitive}; | ||
|
||
/// Type alias for a [`Sensitive`] value to denote decrypted data. | ||
pub type Decrypted<V> = Sensitive<V>; | ||
pub type DecryptedVec = Decrypted<Vec<u8>>; | ||
pub type DecryptedString = Decrypted<String>; | ||
|
||
impl<T: KeyEncryptable<Key, Output> + Zeroize + Clone, Key: CryptoKey, Output> | ||
KeyEncryptable<Key, Output> for Decrypted<T> | ||
{ | ||
fn encrypt_with_key(self, key: &Key) -> Result<Output, CryptoError> { | ||
self.value.clone().encrypt_with_key(key) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
#[allow(clippy::module_inception)] | ||
mod sensitive; | ||
pub use sensitive::{Sensitive, SensitiveString, SensitiveVec}; | ||
mod decrypted; | ||
pub use decrypted::{Decrypted, DecryptedString, DecryptedVec}; |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we look into if the encrypt methods should accept sensitive values?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Definitely, but it needs to be updated at the same time as the KeyEncryptable impls, as they use this function and we don't want to be boxing/unboxing all the time.