diff --git a/tsp/src/async_store.rs b/tsp/src/async_store.rs index 281fa2f..7af575c 100644 --- a/tsp/src/async_store.rs +++ b/tsp/src/async_store.rs @@ -369,18 +369,15 @@ impl AsyncStore { let db_inner = db.clone(); async move { match message { - Ok(mut m) => { - let m_copy = m.clone(); - match db_inner.open_message(&mut m) { - Err(Error::UnverifiedSource(unknown_vid)) => { - Ok(ReceivedTspMessage::PendingMessage { - unknown_vid, - payload: m_copy, - }) - } - maybe_message => maybe_message.map(|msg| msg.into_owned()), + Ok(mut m) => match db_inner.open_message(&mut m) { + Err(Error::UnverifiedSource(unknown_vid, opaque_data)) => { + Ok(ReceivedTspMessage::PendingMessage { + unknown_vid, + payload: opaque_data.unwrap_or(m), + }) } - } + maybe_message => maybe_message.map(|msg| msg.into_owned()), + }, Err(e) => Err(e.into()), } } diff --git a/tsp/src/error.rs b/tsp/src/error.rs index 70b6feb..0157207 100644 --- a/tsp/src/error.rs +++ b/tsp/src/error.rs @@ -32,7 +32,7 @@ pub enum Error { #[error("Error: unresolved vid {0}")] UnverifiedVid(String), #[error("Error: no relation with sender {0}")] - UnverifiedSource(String), + UnverifiedSource(String, Option>), #[error("Error: unresolved next hop {0}")] UnresolvedNextHop(String), #[error("Error: no relation with next hop {0}")] diff --git a/tsp/src/store.rs b/tsp/src/store.rs index 63b44db..25788e6 100644 --- a/tsp/src/store.rs +++ b/tsp/src/store.rs @@ -514,6 +514,14 @@ impl Store { } } + /// Get the sender from a CESR message + fn probe_sender(message: &mut [u8]) -> Result<&str, Error> { + Ok(match crate::cesr::probe(message)? { + EnvelopeType::EncryptedMessage { sender, .. } => std::str::from_utf8(sender)?, + EnvelopeType::SignedMessage { sender, .. } => std::str::from_utf8(sender)?, + }) + } + /// Decode an encrypted `message``, which has to be addressed to one of the VIDs in `receivers`, and has to have /// `verified_vids` as one of the senders. pub fn open_message<'a>( @@ -536,7 +544,7 @@ impl Store { let sender = String::from_utf8(sender.to_vec())?; let Ok(sender_vid) = self.get_verified_vid(&sender) else { - return Err(Error::UnverifiedSource(sender)); + return Err(Error::UnverifiedSource(sender, None)); }; let (nonconfidential_data, payload) = @@ -550,7 +558,19 @@ impl Store { message_type: MessageType::SignedAndEncrypted, }), Payload::NestedMessage(inner) => { + // we must communicate the correct payload to the caller, in case + // the inner vid isn't recognized (which can happen in Routed mode) + // we cannot do this after 'open_message' since 'inner' will be borrowed + let inner_vid = Self::probe_sender(inner)?; + if self.get_verified_vid(inner_vid).is_err() { + return Err(Error::UnverifiedSource( + inner_vid.to_owned(), + Some(inner.to_vec()), + )); + } + let mut received_message = self.open_message(inner)?; + if let ReceivedTspMessage::GenericMessage { ref mut message_type, ..