Skip to content
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

Move business logic from async store to store #16

Merged
merged 1 commit into from
Jun 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions examples/src/intermediary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,9 @@ async fn new_message(
Path(name): Path<String>,
body: Bytes,
) -> Response {
let message: Vec<u8> = 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,
Expand Down
5 changes: 2 additions & 3 deletions examples/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,8 +278,7 @@ struct SendMessageForm {
}

async fn route_message(State(state): State<Arc<AppState>>, body: Bytes) -> Response {
let message: Vec<u8> = 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();
};

Expand All @@ -289,7 +288,7 @@ async fn route_message(State(state): State<Arc<AppState>>, 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()
}
Expand Down
14 changes: 3 additions & 11 deletions tsp/src/async_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,17 +299,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(())
Expand Down Expand Up @@ -354,7 +346,7 @@ impl AsyncStore {
Err(Error::UnverifiedSource(unknown_vid)) => {
Ok(ReceivedTspMessage::PendingMessage {
unknown_vid,
payload: m.to_vec(),
payload: m,
})
}
maybe_message => maybe_message,
Expand Down
10 changes: 2 additions & 8 deletions tsp/src/crypto/tsp_hpke.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand All @@ -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))
Expand Down
33 changes: 26 additions & 7 deletions tsp/src/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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!(
Expand All @@ -441,16 +458,19 @@ impl Store {
) -> Result<(Url, Vec<u8>), 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),
Expand Down Expand Up @@ -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)?;
Expand Down
2 changes: 1 addition & 1 deletion tsp/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
2 changes: 1 addition & 1 deletion tsp/src/vault.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
Loading