Skip to content

Commit

Permalink
feat(rust): added zeroize on LocalMessage
Browse files Browse the repository at this point in the history
  • Loading branch information
davide-baldo committed Dec 23, 2024
1 parent 59ff67a commit 098958d
Show file tree
Hide file tree
Showing 21 changed files with 322 additions and 63 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 5 additions & 2 deletions implementations/rust/ockam/ockam_api/src/echoer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ impl Worker for Echoer {
async fn handle_message(&mut self, ctx: &mut Context, msg: Routed<Any>) -> Result<()> {
log::debug!(src = %msg.src_addr(), from = %msg.sender()?, to = %msg.return_route().next()?, "echoing back");
let msg = msg.into_local_message();
ctx.send(msg.return_route, NeutralMessage::from(msg.payload))
.await
ctx.send(
msg.return_route,
NeutralMessage::from(msg.payload.discard_zeroize()),
)
.await
}
}
27 changes: 15 additions & 12 deletions implementations/rust/ockam/ockam_api/src/proxy_vault/protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ use minicbor::{CborLen, Decode, Encode};
use ockam::identity::{utils, TimestampInSeconds, Vault};
use ockam_core::errcode::{Kind, Origin};
use ockam_core::{
async_trait, cbor_encode_preallocate, route, Address, NeutralMessage, Route, Routed, Worker,
async_trait, cbor_encode_preallocate, route, Address, NeutralMessage, OnDrop, Route, Routed,
Worker,
};
use ockam_multiaddr::MultiAddr;
use ockam_node::Context;
use ockam_node::{Context, MessageSendReceiveOptions};
use std::sync::Arc;
use tokio::sync::Mutex as AsyncMutex;

Expand Down Expand Up @@ -245,11 +246,13 @@ impl SpecificClient {
let response: NeutralMessage = self
.client
.context
.send_and_receive(
.send_and_receive_extended(
route![route, self.destination.clone()],
NeutralMessage::from(encoded),
MessageSendReceiveOptions::new().with_on_drop(OnDrop::Zeroize),
)
.await?;
.await?
.into_body()?;

Ok(minicbor::decode::<RS>(&response.into_vec())?)
}
Expand All @@ -258,7 +261,7 @@ impl SpecificClient {
mod vault_for_signing {
use crate::proxy_vault::protocol::{ProxyError, SpecificClient};
use minicbor::{CborLen, Decode, Encode};
use ockam_core::{async_trait, cbor_encode_preallocate};
use ockam_core::{async_trait, cbor_encode_preallocate, MaybeZeroizeOnDrop};
use ockam_vault::{
Signature, SigningKeyType, SigningSecretKeyHandle, VaultForSigning, VerifyingPublicKey,
};
Expand Down Expand Up @@ -296,7 +299,7 @@ mod vault_for_signing {

pub(super) async fn handle_request(
vault: &dyn VaultForSigning,
request: Vec<u8>,
request: MaybeZeroizeOnDrop<Vec<u8>>,
) -> ockam_core::Result<Vec<u8>> {
let request: Request = minicbor::decode(&request)?;
let response = match request {
Expand Down Expand Up @@ -480,15 +483,15 @@ mod vault_for_signing {
pub mod vault_for_secure_channels {
use crate::proxy_vault::protocol::{ProxyError, SpecificClient};
use minicbor::{CborLen, Decode, Encode};
use ockam_core::{async_trait, cbor_encode_preallocate};
use ockam_core::{async_trait, cbor_encode_preallocate, MaybeZeroizeOnDrop};
use ockam_vault::{
AeadSecretKeyHandle, HKDFNumberOfOutputs, HashOutput, HkdfOutput, SecretBufferHandle,
VaultForSecureChannels, X25519PublicKey, X25519SecretKeyHandle,
};

pub(super) async fn handle_request(
vault: &dyn VaultForSecureChannels,
request: Vec<u8>,
request: MaybeZeroizeOnDrop<Vec<u8>>,
) -> ockam_core::Result<Vec<u8>> {
let request: Request = minicbor::decode(&request)?;
let response = match request {
Expand Down Expand Up @@ -1084,12 +1087,12 @@ pub mod vault_for_secure_channels {
pub mod vault_for_verify_signatures {
use crate::proxy_vault::protocol::{ProxyError, SpecificClient};
use minicbor::{CborLen, Decode, Encode};
use ockam_core::{async_trait, cbor_encode_preallocate};
use ockam_core::{async_trait, cbor_encode_preallocate, MaybeZeroizeOnDrop};
use ockam_vault::{Sha256Output, Signature, VaultForVerifyingSignatures, VerifyingPublicKey};

pub(super) async fn handle_request(
vault: &dyn VaultForVerifyingSignatures,
request: Vec<u8>,
request: MaybeZeroizeOnDrop<Vec<u8>>,
) -> ockam_core::Result<Vec<u8>> {
let request: Request = minicbor::decode(&request)?;
let response = match request {
Expand Down Expand Up @@ -1179,12 +1182,12 @@ pub mod vault_for_verify_signatures {
pub mod vault_for_encryption_at_rest {
use crate::proxy_vault::protocol::{ProxyError, SpecificClient};
use minicbor::{CborLen, Decode, Encode};
use ockam_core::{async_trait, cbor_encode_preallocate};
use ockam_core::{async_trait, cbor_encode_preallocate, MaybeZeroizeOnDrop};
use ockam_vault::{AeadSecretKeyHandle, VaultForEncryptionAtRest};

pub(super) async fn handle_request(
vault: &dyn VaultForEncryptionAtRest,
request: Vec<u8>,
request: MaybeZeroizeOnDrop<Vec<u8>>,
) -> ockam_core::Result<Vec<u8>> {
let request: Request = minicbor::decode(&request)?;
let response = match request {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ impl Worker for MockEchoer {

ctx.send(
msg.return_route().clone(),
NeutralMessage::from(msg.into_payload()),
NeutralMessage::from(msg.into_payload().discard_zeroize()),
)
.await?;
info!("Echo message back");
Expand Down
1 change: 1 addition & 0 deletions implementations/rust/ockam/ockam_core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ tracing-opentelemetry = { version = "0.27.0", optional = true }
tracing-subscriber = { version = "0.3", features = ["fmt", "env-filter"], optional = true }
# Wasn't tested on no_std
utcnow = { version = "0.2.5", default-features = false, features = ["fallback"], optional = true }
zeroize = { version = "1.8", default-features = false }

[dev-dependencies]
cddl-cat = { version = "0.6.2" }
Expand Down
15 changes: 15 additions & 0 deletions implementations/rust/ockam/ockam_core/src/cbor/cow_bytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::compat::vec::Vec;
use core::ops::Deref;
use minicbor::{CborLen, Decode, Encode};
use serde::{Deserialize, Serialize};
use zeroize::Zeroize;

/// A new type around `Cow<'_, [u8]>` that borrows from input.
///
Expand Down Expand Up @@ -79,3 +80,17 @@ impl<'a> Deref for CowBytes<'a> {
&self.0
}
}

impl Default for CowBytes<'_> {
fn default() -> Self {
CowBytes(Cow::Borrowed(&[]))
}
}

impl Zeroize for CowBytes<'_> {
fn zeroize(&mut self) {
if !self.is_borrowed() {
self.0.to_mut().zeroize();
}
}
}
2 changes: 2 additions & 0 deletions implementations/rust/ockam/ockam_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ mod processor;
mod routing;
mod uint;
mod worker;
mod zeroize;

pub use access_control::*;
pub use cbor::*;
Expand All @@ -96,6 +97,7 @@ pub use processor::*;
pub use routing::*;
pub use uint::*;
pub use worker::*;
pub use zeroize::*;

#[cfg(all(not(feature = "std"), feature = "alloc"))]
#[doc(hidden)]
Expand Down
5 changes: 3 additions & 2 deletions implementations/rust/ockam/ockam_core/src/message.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::zeroize::MaybeZeroizeOnDrop;
use crate::{
compat::{
string::{String, ToString},
Expand Down Expand Up @@ -244,7 +245,7 @@ impl<M: Message> Routed<M> {
/// Consume the message wrapper and return the original message.
#[inline]
pub fn into_body(self) -> Result<M> {
M::decode(&self.into_payload())
M::decode(self.payload())
}

/// Consume the message wrapper and return the underlying local message.
Expand All @@ -267,7 +268,7 @@ impl<M: Message> Routed<M> {

/// Consume the message wrapper and return the underlying transport message's binary payload.
#[inline]
pub fn into_payload(self) -> Vec<u8> {
pub fn into_payload(self) -> MaybeZeroizeOnDrop<Vec<u8>> {
self.local_msg.into_payload()
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#[cfg(feature = "std")]
use crate::OpenTelemetryContext;
use crate::{compat::vec::Vec, route, Address, Message, Route, TransportMessage};
use crate::{compat::vec::Vec, route, Address, Message, OnDrop, Route, TransportMessage};

use crate::zeroize::MaybeZeroizeOnDrop;
use crate::{LocalInfo, Result};
use cfg_if::cfg_if;
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -46,7 +47,7 @@ pub struct LocalMessage {
/// Return message route. This field must be populated by routers handling this message along the way.
pub return_route: Route,
/// The message payload.
pub payload: Vec<u8>,
pub payload: MaybeZeroizeOnDrop<Vec<u8>>,
/// Local information added by workers to give additional context to the message
/// independently of its payload. For example this can be used to store the identifier that
/// was used to encrypt the payload
Expand Down Expand Up @@ -142,7 +143,7 @@ impl LocalMessage {
}

/// Return the message payload
pub fn into_payload(self) -> Vec<u8> {
pub fn into_payload(self) -> MaybeZeroizeOnDrop<Vec<u8>> {
self.payload
}

Expand All @@ -153,12 +154,12 @@ impl LocalMessage {

/// Return a mutable reference to the message payload
pub fn payload_mut(&mut self) -> &mut Vec<u8> {
&mut self.payload
self.payload.as_mut()
}

/// Set the message payload
pub fn set_payload(mut self, payload: Vec<u8>) -> Self {
self.payload = payload;
self.payload = MaybeZeroizeOnDrop::new(payload, OnDrop::NoZeroize);
self
}

Expand Down Expand Up @@ -213,7 +214,7 @@ impl LocalMessage {
1,
self.onward_route,
self.return_route,
self.payload,
self.payload.discard_zeroize(),
None,
);

Expand Down Expand Up @@ -285,7 +286,7 @@ impl LocalMessage {
LocalMessage {
onward_route,
return_route,
payload,
payload: MaybeZeroizeOnDrop::new(payload, OnDrop::NoZeroize),
local_info,
#[cfg(feature = "std")]
tracing_context: OpenTelemetryContext::current(),
Expand Down Expand Up @@ -316,7 +317,18 @@ impl LocalMessage {

/// Specify the payload for the message
pub fn with_payload(self, payload: Vec<u8>) -> Self {
Self { payload, ..self }
Self {
payload: MaybeZeroizeOnDrop::new(payload, OnDrop::NoZeroize),
..self
}
}

/// Specify the payload for the message with zeroization
pub fn with_payload_on_drop(self, payload: Vec<u8>, on_drop: OnDrop) -> Self {
Self {
payload: MaybeZeroizeOnDrop::new(payload, on_drop),
..self
}
}

/// Specify the local information for the message
Expand Down
Loading

0 comments on commit 098958d

Please sign in to comment.