Skip to content

Commit

Permalink
Use spawn_blocking to increase request throughput (#243)
Browse files Browse the repository at this point in the history
  • Loading branch information
giarc3 authored Jul 20, 2021
1 parent 05ff0e9 commit 12e77df
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 23 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## 0.26.0

- [[#243](https://github.com/IronCoreLabs/ironoxide/pull/243)] Add `#[non_exhaustive]` to IronOxideErr.
- [[#243](https://github.com/IronCoreLabs/ironoxide/pull/243)] Increase throughput of document decrypt calls.

## 0.25.2

- [[#222](https://github.com/IronCoreLabs/ironoxide/pull/222)] Loosen version requirements for dependencies.
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ironoxide"
version = "0.25.2"
version = "0.26.0"
authors = [ "IronCore Labs <[email protected]>" ]
readme = "README.md"
license = "AGPL-3.0-only"
Expand Down
2 changes: 1 addition & 1 deletion src/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ impl DocumentOps for crate::IronOxide {
add_optional_timeout(
document_api::decrypt_document(
self.device.auth(),
&self.recrypt,
self.recrypt.clone(),
self.device.device_private_key(),
encrypted_document,
),
Expand Down
10 changes: 10 additions & 0 deletions src/internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ impl std::fmt::Display for SdkOperation {
quick_error! {
/// Errors generated by IronOxide SDK operations
#[derive(Debug)]
#[non_exhaustive]
pub enum IronOxideErr {
ValidationError(field_name: String, err: String) {
display("'{}' failed validation with the error '{}'", field_name, err)
Expand Down Expand Up @@ -195,6 +196,9 @@ quick_error! {
OperationTimedOut{operation: SdkOperation, duration: std::time::Duration} {
display("Operation {} timed out after {}ms", operation, duration.as_millis())
}
JoinError(msg: String) {
display("{}", msg)
}
}
}

Expand Down Expand Up @@ -230,6 +234,12 @@ impl From<recrypt::nonemptyvec::NonEmptyVecError> for IronOxideErr {
}
}

impl From<tokio::task::JoinError> for IronOxideErr {
fn from(e: tokio::task::JoinError) -> Self {
IronOxideErr::JoinError(e.to_string())
}
}

const NAME_AND_ID_MAX_LEN: usize = 100;

/// Validate that the provided id is valid for our user/document/group IDs. Validates that the
Expand Down
40 changes: 22 additions & 18 deletions src/internal/document_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1055,31 +1055,35 @@ pub async fn document_update_bytes<

/// Decrypt the provided document with the provided device private key. Return metadata about the document
/// that was decrypted along with its decrypted bytes.
pub async fn decrypt_document<CR: rand::CryptoRng + rand::RngCore>(
pub async fn decrypt_document<CR: rand::CryptoRng + rand::RngCore + Send + Sync + 'static>(
auth: &RequestAuth,
recrypt: &Recrypt<Sha256, Ed25519, RandomBytes<CR>>,
recrypt: std::sync::Arc<Recrypt<Sha256, Ed25519, RandomBytes<CR>>>,
device_private_key: &PrivateKey,
encrypted_doc: &[u8],
) -> Result<DocumentDecryptResult, IronOxideErr> {
let (doc_header, mut enc_doc) = parse_document_parts(encrypted_doc)?;
let doc_meta = document_get_metadata(auth, &doc_header.document_id).await?;
let sym_key = transform::decrypt_as_symmetric_key(
recrypt,
doc_meta.0.encrypted_symmetric_key.clone().try_into()?,
device_private_key.recrypt_key(),
)?;
let device_private_key = device_private_key.clone();
tokio::task::spawn_blocking(move || {
let sym_key = transform::decrypt_as_symmetric_key(
&recrypt,
doc_meta.0.encrypted_symmetric_key.clone().try_into()?,
device_private_key.recrypt_key(),
)?;

Ok(
aes::decrypt(&mut enc_doc, *sym_key.bytes()).map(move |decrypted_doc| {
DocumentDecryptResult {
id: doc_meta.0.id,
name: doc_meta.0.name,
created: doc_meta.0.created,
updated: doc_meta.0.updated,
decrypted_data: decrypted_doc.to_vec(),
}
})?,
)
Ok(
aes::decrypt(&mut enc_doc, *sym_key.bytes()).map(move |decrypted_doc| {
DocumentDecryptResult {
id: doc_meta.0.id,
name: doc_meta.0.name,
created: doc_meta.0.created,
updated: doc_meta.0.updated,
decrypted_data: decrypted_doc.to_vec(),
}
})?,
)
})
.await?
}

/// Decrypt the unmanaged document. The caller must provide both the encrypted data as well as the
Expand Down
10 changes: 7 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,11 @@ use rand::{
};
use rand_chacha::ChaChaCore;
use recrypt::api::{Ed25519, RandomBytes, Recrypt, Sha256};
use std::{convert::TryInto, fmt, sync::Mutex};
use std::{
convert::TryInto,
fmt,
sync::{Arc, Mutex},
};
use vec1::Vec1;

/// A `Result` alias where the Err case is `IronOxideErr`
Expand Down Expand Up @@ -259,7 +263,7 @@ pub mod config {
/// performed in the context of the account provided.
pub struct IronOxide {
pub(crate) config: IronOxideConfig,
pub(crate) recrypt: Recrypt<Sha256, Ed25519, RandomBytes<recrypt::api::DefaultRng>>,
pub(crate) recrypt: Arc<Recrypt<Sha256, Ed25519, RandomBytes<recrypt::api::DefaultRng>>>,
/// Master public key for the user identified by `account_id`
pub(crate) user_master_pub_key: PublicKey,
pub(crate) device: DeviceContext,
Expand Down Expand Up @@ -431,7 +435,7 @@ impl IronOxide {
) -> IronOxide {
IronOxide {
config: config.clone(),
recrypt: Recrypt::new(),
recrypt: Arc::new(Recrypt::new()),
device: device_context.clone(),
user_master_pub_key: curr_user.user_public_key().to_owned(),
rng: Mutex::new(ReseedingRng::new(
Expand Down

0 comments on commit 12e77df

Please sign in to comment.