diff --git a/examples/src/intermediary.rs b/examples/src/intermediary.rs index 0030b29..53a4272 100644 --- a/examples/src/intermediary.rs +++ b/examples/src/intermediary.rs @@ -68,11 +68,9 @@ async fn new_message( Path(name): Path, body: Bytes, ) -> Response { - let message: Vec = body.to_vec(); - tracing::debug!("{} received message inteded for {name}", state.domain); - let Ok((sender, Some(receiver))) = tsp::cesr::get_sender_receiver(&message) else { + let Ok((sender, Some(receiver))) = tsp::cesr::get_sender_receiver(&body) else { tracing::error!( "{} encountered invalid message, receiver missing", state.domain, diff --git a/examples/src/server.rs b/examples/src/server.rs index e65c54a..c770b34 100644 --- a/examples/src/server.rs +++ b/examples/src/server.rs @@ -278,8 +278,7 @@ struct SendMessageForm { } async fn route_message(State(state): State>, body: Bytes) -> Response { - let message: Vec = body.to_vec(); - let Ok((sender, Some(receiver))) = tsp::cesr::get_sender_receiver(&message) else { + let Ok((sender, Some(receiver))) = tsp::cesr::get_sender_receiver(&body) else { return (StatusCode::BAD_REQUEST, "invalid message").into_response(); }; @@ -289,7 +288,7 @@ async fn route_message(State(state): State>, body: Bytes) -> Respo tracing::debug!("forwarded message {sender} {receiver}"); // insert message in queue - let _ = state.tx.send((sender, receiver, body.to_vec())); + let _ = state.tx.send((sender, receiver, body.into())); StatusCode::OK.into_response() } diff --git a/tsp/src/async_store.rs b/tsp/src/async_store.rs index 786a5db..8356338 100644 --- a/tsp/src/async_store.rs +++ b/tsp/src/async_store.rs @@ -297,17 +297,9 @@ impl AsyncStore { hop_list: &[&str], opaque_message: &[u8], ) -> Result<(), Error> { - let Some(next_hop) = hop_list.first() else { - return Err(Error::InvalidRoute( - "relationship route must not be empty".into(), - )); - }; + let (next_hop, path) = self.inner.resolve_route(hop_list)?; - let next_hop = self.inner.get_verified_vid(next_hop)?; - //TODO: can we avoid the allocation here? - let path = hop_list[1..].iter().map(|x| x.as_bytes()).collect(); - - self.forward_routed_message(next_hop.identifier(), path, opaque_message) + self.forward_routed_message(&next_hop, path, opaque_message) .await?; Ok(()) @@ -352,7 +344,7 @@ impl AsyncStore { Err(Error::UnverifiedSource(unknown_vid)) => { Ok(ReceivedTspMessage::PendingMessage { unknown_vid, - payload: m.to_vec(), + payload: m, }) } maybe_message => maybe_message, diff --git a/tsp/src/crypto/tsp_hpke.rs b/tsp/src/crypto/tsp_hpke.rs index 41c1556..1a9d971 100644 --- a/tsp/src/crypto/tsp_hpke.rs +++ b/tsp/src/crypto/tsp_hpke.rs @@ -158,11 +158,7 @@ where let secret_payload = match crate::cesr::decode_payload(ciphertext)? { crate::cesr::Payload::GenericMessage(data) => Payload::Content(data), crate::cesr::Payload::DirectRelationProposal { hops, .. } => Payload::RequestRelationship { - route: if hops.is_empty() { - None - } else { - Some(hops.to_vec()) - }, + route: if hops.is_empty() { None } else { Some(hops) }, }, crate::cesr::Payload::DirectRelationAffirm { reply: &thread_id } => { Payload::AcceptRelationship { thread_id } @@ -173,9 +169,7 @@ where reply: &thread_id, .. } => Payload::CancelRelationship { thread_id }, crate::cesr::Payload::NestedMessage(data) => Payload::NestedMessage(data), - crate::cesr::Payload::RoutedMessage(hops, data) => { - Payload::RoutedMessage(hops.to_vec(), data) - } + crate::cesr::Payload::RoutedMessage(hops, data) => Payload::RoutedMessage(hops, data), }; Ok((envelope.nonconfidential_data, secret_payload, ciphertext)) diff --git a/tsp/src/store.rs b/tsp/src/store.rs index 34e38c9..2becce4 100644 --- a/tsp/src/store.rs +++ b/tsp/src/store.rs @@ -397,6 +397,23 @@ impl Store { Ok(message) } + /// Resolve a route, extract the next hop and verify the route + pub fn resolve_route<'a>( + &'a self, + hop_list: &'a [&str], + ) -> Result<(String, Vec<&'a [u8]>), Error> { + let Some(next_hop) = hop_list.first() else { + return Err(Error::InvalidRoute( + "relationship route must not be empty".into(), + )); + }; + + let next_hop = self.get_verified_vid(next_hop)?.identifier().to_owned(); + let path = hop_list[1..].iter().map(|x| x.as_bytes()).collect(); + + Ok((next_hop, path)) + } + /// Receive, open and forward a TSP message pub fn route_message( &self, @@ -418,7 +435,7 @@ impl Store { Payload::RoutedMessage(hops, inner_message) => { let next_hop = std::str::from_utf8(hops[0])?; - (next_hop, hops[1..].to_vec(), inner_message) + (next_hop, hops[1..].into(), inner_message) } _ => { return Err(Error::InvalidRoute(format!( @@ -441,16 +458,19 @@ impl Store { ) -> Result<(Url, Vec), Error> { if path.is_empty() { // we are the final delivery point, we should be the 'next_hop' - let sender = self.get_private_vid(next_hop)?; + let sender = self.get_vid(next_hop)?; - //TODO: we cannot user 'sender.relation_vid()', since the relationship status of this cannot be set - let recipient = match self.get_vid(sender.identifier())?.get_relation_vid() { + let Some(sender_private) = &sender.private else { + return Err(Error::MissingPrivateVid(next_hop.to_string())); + }; + + let recipient = match sender.get_relation_vid() { Some(destination) => self.get_verified_vid(destination)?, - None => return Err(Error::MissingDropOff(sender.identifier().to_string())), + None => return Err(Error::MissingDropOff(sender.vid.identifier().to_string())), }; let tsp_message = crate::crypto::seal( - &*sender, + &**sender_private, &*recipient, None, Payload::NestedMessage(opaque_message), @@ -512,7 +532,6 @@ impl Store { message_type: MessageType::SignedAndEncrypted, }), Payload::NestedMessage(message) => { - // TODO: do not allocate let mut inner = message.to_owned(); let mut received_message = self.open_message(&mut inner)?; diff --git a/tsp/src/test.rs b/tsp/src/test.rs index a7642ed..52e7827 100644 --- a/tsp/src/test.rs +++ b/tsp/src/test.rs @@ -248,7 +248,7 @@ async fn test_nested_mode() { panic!("bob did not receive a generic message inner") }; - assert_eq!(message, b"hello nested world".to_vec()); + assert_eq!(&message, b"hello nested world"); } #[tokio::test] diff --git a/tsp/src/vault.rs b/tsp/src/vault.rs index ff43b61..95123e1 100644 --- a/tsp/src/vault.rs +++ b/tsp/src/vault.rs @@ -260,7 +260,7 @@ impl Vault { let decryption_key: [u8; 32] = decryption_key .load_local_key()? .to_secret_bytes()? - .to_vec() + .as_ref() .try_into() .map_err(|_| { Error::DecodeState("could not parse decryption key bytes from storage")