-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Update crypto module structure and add enhanced AES-CBC cryptor.
- Loading branch information
Showing
24 changed files
with
1,582 additions
and
185 deletions.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
use pubnub::core::CryptoProvider; | ||
use pubnub::providers::crypto::CryptoModule; | ||
use pubnub::{Keyset, PubNubClientBuilder}; | ||
use std::env; | ||
|
||
#[tokio::main] | ||
async fn main() -> Result<(), Box<dyn snafu::Error>> { | ||
let source_data: Vec<u8> = "Hello world!".into(); | ||
let use_random_iv = true; | ||
let cipher = "enigma"; | ||
|
||
// Crypto module with legacy AES-CBC cryptor (with enhanced AES-CBC decrypt | ||
// support). | ||
let legacy_crypto_module = CryptoModule::new_legacy_module(cipher, use_random_iv)?; | ||
let legacy_encrypt_result = legacy_crypto_module.encrypt(source_data.clone()); | ||
|
||
println!("encrypt with legacy AES-CBC result: {legacy_encrypt_result:?}"); | ||
|
||
// Crypto module with enhanced AES-CBC cryptor (with legacy AES-CBC decrypt | ||
// support). | ||
let crypto_module = CryptoModule::new_aes_cbc_module(cipher, use_random_iv)?; | ||
let encrypt_result = crypto_module.encrypt(source_data.clone()); | ||
|
||
println!("encrypt with enhanced AES-CBC result: {encrypt_result:?}"); | ||
|
||
// Decrypt data created with legacy AES-CBC crypto module. | ||
let legacy_decrypt_result = crypto_module.decrypt(legacy_encrypt_result.ok().unwrap())?; | ||
assert_eq!(legacy_decrypt_result, source_data); | ||
|
||
// Decrypt data created with enhanced AES-CBC crypto module. | ||
let decrypt_result = legacy_crypto_module.decrypt(encrypt_result.ok().unwrap())?; | ||
assert_eq!(decrypt_result, source_data); | ||
|
||
// Setup client with crypto module | ||
let publish_key = env::var("SDK_PUB_KEY")?; | ||
let subscribe_key = env::var("SDK_SUB_KEY")?; | ||
|
||
let client = PubNubClientBuilder::with_reqwest_transport() | ||
.with_keyset(Keyset { | ||
subscribe_key, | ||
publish_key: Some(publish_key), | ||
secret_key: None, | ||
}) | ||
.with_user_id("user_id") | ||
.with_cryptor(crypto_module) | ||
.build()?; | ||
|
||
// publish simple string | ||
let result = client | ||
.publish_message("hello world!") | ||
.channel("my_channel") | ||
.r#type("text-message") | ||
.execute() | ||
.await?; | ||
|
||
println!("publish result: {:?}", result); | ||
|
||
Ok(()) | ||
} |
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,27 @@ | ||
//! # Crypto provider module | ||
//! | ||
//! This module contains the [`CryptoProvider`] trait, which is used to | ||
//! implement a module that can be used to configure [`PubNubClientInstance`] or | ||
//! for manual data encryption and decryption. | ||
use crate::{ | ||
core::PubNubError, | ||
lib::{alloc::vec::Vec, core::fmt::Debug}, | ||
}; | ||
|
||
/// Crypto provider trait. | ||
pub trait CryptoProvider: Debug + Send + Sync { | ||
/// Encrypt provided data. | ||
/// | ||
/// # Errors | ||
/// Should return an [`PubNubError::Encryption`] if provided data can't be | ||
/// _encrypted_ or underlying cryptor misconfigured. | ||
fn encrypt(&self, data: Vec<u8>) -> Result<Vec<u8>, PubNubError>; | ||
|
||
/// Decrypt provided data. | ||
/// | ||
/// # Errors | ||
/// Should return an [`PubNubError::Decryption`] if provided data can't be | ||
/// _decrypted_ or underlying cryptor misconfigured. | ||
fn decrypt(&self, data: Vec<u8>) -> Result<Vec<u8>, PubNubError>; | ||
} |
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,59 +1,98 @@ | ||
//! Cryptor module | ||
//! # Cryptor module | ||
//! | ||
//! This module contains the [`Cryptor`] trait which is used to implement | ||
//! encryption and decryption of published data. | ||
//! This module contains the [`Cryptor`] trait, which is used to implement | ||
//! crypto algorithms that should be used with [`CryptorProvider`] | ||
//! implementation for data _encryption_ and _decryption_. | ||
use crate::core::error::PubNubError; | ||
use crate::lib::{alloc::vec::Vec, core::fmt::Debug}; | ||
use crate::{ | ||
core::PubNubError, | ||
lib::{alloc::vec::Vec, core::fmt::Debug}, | ||
}; | ||
|
||
/// This trait is used to encrypt and decrypt messages sent to the | ||
/// [`PubNub API`]. | ||
/// Encrypted data representation object. | ||
/// | ||
/// It is used by the [`dx`] modules to encrypt messages sent to PubNub and | ||
/// returned by the [`PubNub API`]. | ||
/// Objects contain both encrypted data and additional data created by cryptor | ||
/// that will be required to decrypt the data. | ||
#[derive(Debug)] | ||
pub struct EncryptedData { | ||
/// Cryptor-defined information. | ||
/// | ||
/// Cryptor may provide here any information which will be useful when data | ||
/// should be decrypted. | ||
/// | ||
/// For example `metadata` may contain: | ||
/// * initialization vector | ||
/// * cipher key identifier | ||
/// * encrypted `data` length. | ||
pub metadata: Option<Vec<u8>>, | ||
|
||
/// Encrypted data. | ||
pub data: Vec<u8>, | ||
} | ||
|
||
/// Cryptor trait. | ||
/// | ||
/// Types that implement this trait can be used to configure [`CryptoProvider`] | ||
/// implementations for standalone usage or as part of [`PubNubClientInstance`] | ||
/// for automated data _encryption_ and _decryption_. | ||
/// | ||
/// To implement this trait, you must provide `encrypt` and `decrypt` methods | ||
/// that takes a `&[u8]` and returns a `Result<Vec<u8>, PubNubError>`. | ||
/// that takes a `Vec<u8>` and returns a `Result<EncryptedData, PubNubError>`. | ||
/// | ||
/// You can implement this trait for your own types, or use one of the provided | ||
/// features to use a crypto library. | ||
/// When you use this trait to make your own crypto, make sure that other SDKs | ||
/// use the same encryption and decryption algorithms. | ||
/// features to use a `crypto` library. | ||
/// | ||
/// You can implement this trait for your cryptor types, or use one of the | ||
/// implementations provided by `crypto` feature. | ||
/// When you implement your cryptor for custom encryption and use multiple | ||
/// platforms, make sure that the same logic is implemented for other SDKs. | ||
/// | ||
/// # Examples | ||
/// ``` | ||
/// use pubnub::core::{Cryptor, error::PubNubError}; | ||
/// use pubnub::core::{Cryptor, EncryptedData, error::PubNubError}; | ||
/// | ||
/// #[derive(Debug)] | ||
/// struct MyCryptor; | ||
/// | ||
/// impl Cryptor for MyCryptor { | ||
/// fn encrypt(&self, source: Vec<u8>) -> Result<Vec<u8>, PubNubError> { | ||
/// fn identifier(&self) -> [u8; 4] { | ||
/// *b"MCID" | ||
/// } | ||
/// | ||
/// fn encrypt(&self, source: Vec<u8>) -> Result<EncryptedData, PubNubError> { | ||
/// // Encrypt provided data here | ||
/// Ok(vec![]) | ||
/// Ok(EncryptedData { | ||
/// metadata: None, | ||
/// data: vec![] | ||
/// }) | ||
/// } | ||
/// | ||
/// fn decrypt(&self, source: Vec<u8>) -> Result<Vec<u8>, PubNubError> { | ||
/// fn decrypt(&self, source: EncryptedData) -> Result<Vec<u8>, PubNubError> { | ||
/// // Decrypt provided data here | ||
/// Ok(vec![]) | ||
/// } | ||
/// } | ||
/// ``` | ||
/// | ||
/// [`dx`]: ../dx/index.html | ||
/// [`PubNub API`]: https://www.pubnub.com/docs | ||
pub trait Cryptor: Debug + Send + Sync { | ||
/// Decrypt provided data. | ||
/// Unique cryptor identifier. | ||
/// | ||
/// Identifier will be encoded into cryptor data header and passed along | ||
/// with encrypted data. | ||
/// | ||
/// The identifier **must** be 4 bytes long. | ||
fn identifier(&self) -> [u8; 4]; | ||
|
||
/// Encrypt provided data. | ||
/// | ||
/// # Errors | ||
/// Should return an [`PubNubError::Encryption`] if provided data can't | ||
/// be encrypted or underlying cryptor misconfigured. | ||
fn encrypt(&self, source: Vec<u8>) -> Result<Vec<u8>, PubNubError>; | ||
/// Should return an [`PubNubError::Encryption`] if provided data can't be | ||
/// _encrypted_ or underlying cryptor misconfigured. | ||
fn encrypt(&self, data: Vec<u8>) -> Result<EncryptedData, PubNubError>; | ||
|
||
/// Decrypt provided data. | ||
/// | ||
/// # Errors | ||
/// Should return an [`PubNubError::Decryption`] if provided data can't | ||
/// be decrypted or underlying cryptor misconfigured. | ||
fn decrypt(&self, source: Vec<u8>) -> Result<Vec<u8>, PubNubError>; | ||
/// Should return an [`PubNubError::Decryption`] if provided data can't be | ||
/// _decrypted_ or underlying cryptor misconfigured. | ||
fn decrypt(&self, data: EncryptedData) -> Result<Vec<u8>, PubNubError>; | ||
} |
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
Oops, something went wrong.