fixes
This commit is contained in:
parent
bb4dbb7c4a
commit
584ce05a10
@ -21,6 +21,43 @@ pub enum RouteNode {
|
|||||||
PeerInfo(PeerInfo),
|
PeerInfo(PeerInfo),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl RouteNode {
|
||||||
|
pub fn node_ref(
|
||||||
|
&self,
|
||||||
|
routing_table: RoutingTable,
|
||||||
|
crypto_kind: CryptoKind,
|
||||||
|
) -> Option<NodeRef> {
|
||||||
|
match self {
|
||||||
|
RouteNode::NodeId(id) => {
|
||||||
|
//
|
||||||
|
routing_table.lookup_node_ref(TypedKey::new(crypto_kind, id))
|
||||||
|
}
|
||||||
|
RouteNode::PeerInfo(pi) => {
|
||||||
|
//
|
||||||
|
routing_table.register_node_with_peer_info(
|
||||||
|
RoutingDomain::PublicInternet,
|
||||||
|
pi.clone(),
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn describe(&self, crypto_kind: CryptoKind) -> String {
|
||||||
|
match self {
|
||||||
|
RouteNode::NodeId(id) => {
|
||||||
|
format!("{}", TypedKey::new(crypto_kind, id))
|
||||||
|
}
|
||||||
|
RouteNode::PeerInfo(pi) => match pi.node_ids.get(crypto_kind) {
|
||||||
|
Some(id) => format!("{}", TypedKey::new(crypto_kind, id)),
|
||||||
|
None => {
|
||||||
|
format!("({})?{}", crypto_kind, pi.node_ids)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// An unencrypted private/safety route hop
|
/// An unencrypted private/safety route hop
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct RouteHop {
|
pub struct RouteHop {
|
||||||
|
@ -870,7 +870,7 @@ impl RouteSpecStore {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let opt_first_hop = match pr_first_hop_node {
|
let opt_first_hop = match pr_first_hop_node {
|
||||||
RouteNode::NodeId(id) => rti.lookup_any_node_ref(routing_table.clone(), id),
|
RouteNode::NodeId(id) => rti.lookup_node_ref(routing_table.clone(), TypedKey::new(crypto_kind, id)),
|
||||||
RouteNode::PeerInfo(pi) => rti.register_node_with_peer_info(
|
RouteNode::PeerInfo(pi) => rti.register_node_with_peer_info(
|
||||||
routing_table.clone(),
|
routing_table.clone(),
|
||||||
RoutingDomain::PublicInternet,
|
RoutingDomain::PublicInternet,
|
||||||
|
@ -52,6 +52,8 @@ struct RPCMessageHeaderDetailDirect {
|
|||||||
/// Header details for rpc messages received over only a safety route but not a private route
|
/// Header details for rpc messages received over only a safety route but not a private route
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct RPCMessageHeaderDetailSafetyRouted {
|
struct RPCMessageHeaderDetailSafetyRouted {
|
||||||
|
/// Direct header
|
||||||
|
direct: RPCMessageHeaderDetailDirect,
|
||||||
/// Remote safety route used
|
/// Remote safety route used
|
||||||
remote_safety_route: PublicKey,
|
remote_safety_route: PublicKey,
|
||||||
/// The sequencing used for this route
|
/// The sequencing used for this route
|
||||||
@ -61,6 +63,8 @@ struct RPCMessageHeaderDetailSafetyRouted {
|
|||||||
/// Header details for rpc messages received over a private route
|
/// Header details for rpc messages received over a private route
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct RPCMessageHeaderDetailPrivateRouted {
|
struct RPCMessageHeaderDetailPrivateRouted {
|
||||||
|
/// Direct header
|
||||||
|
direct: RPCMessageHeaderDetailDirect,
|
||||||
/// Remote safety route used (or possibly node id the case of no safety route)
|
/// Remote safety route used (or possibly node id the case of no safety route)
|
||||||
remote_safety_route: PublicKey,
|
remote_safety_route: PublicKey,
|
||||||
/// The private route we received the rpc over
|
/// The private route we received the rpc over
|
||||||
@ -92,8 +96,8 @@ impl RPCMessageHeader {
|
|||||||
pub fn crypto_kind(&self) -> CryptoKind {
|
pub fn crypto_kind(&self) -> CryptoKind {
|
||||||
match &self.detail {
|
match &self.detail {
|
||||||
RPCMessageHeaderDetail::Direct(d) => d.envelope.get_crypto_kind(),
|
RPCMessageHeaderDetail::Direct(d) => d.envelope.get_crypto_kind(),
|
||||||
RPCMessageHeaderDetail::SafetyRouted(s) => s.remote_safety_route.,
|
RPCMessageHeaderDetail::SafetyRouted(s) => s.direct.envelope.get_crypto_kind(),
|
||||||
RPCMessageHeaderDetail::PrivateRouted(p) => todo!(),
|
RPCMessageHeaderDetail::PrivateRouted(p) => p.direct.envelope.get_crypto_kind(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -528,7 +532,8 @@ impl RPCProcessor {
|
|||||||
let dh_secret = vcrypto
|
let dh_secret = vcrypto
|
||||||
.cached_dh(&pr_pubkey, &compiled_route.secret)
|
.cached_dh(&pr_pubkey, &compiled_route.secret)
|
||||||
.map_err(RPCError::map_internal("dh failed"))?;
|
.map_err(RPCError::map_internal("dh failed"))?;
|
||||||
let enc_msg_data = vcrypto.encrypt_aead(&message_data, &nonce, &dh_secret, None)
|
let enc_msg_data = vcrypto
|
||||||
|
.encrypt_aead(&message_data, &nonce, &dh_secret, None)
|
||||||
.map_err(RPCError::map_internal("encryption failed"))?;
|
.map_err(RPCError::map_internal("encryption failed"))?;
|
||||||
|
|
||||||
// Make the routed operation
|
// Make the routed operation
|
||||||
@ -541,8 +546,8 @@ impl RPCProcessor {
|
|||||||
safety_route: compiled_route.safety_route,
|
safety_route: compiled_route.safety_route,
|
||||||
operation,
|
operation,
|
||||||
};
|
};
|
||||||
let ssni_route = self
|
let ssni_route =
|
||||||
.get_sender_peer_info(&Destination::direct(compiled_route.first_hop.clone()))?;
|
self.get_sender_peer_info(&Destination::direct(compiled_route.first_hop.clone()))?;
|
||||||
let operation = RPCOperation::new_statement(
|
let operation = RPCOperation::new_statement(
|
||||||
RPCStatement::new(RPCStatementDetail::Route(route_operation)),
|
RPCStatement::new(RPCStatementDetail::Route(route_operation)),
|
||||||
ssni_route,
|
ssni_route,
|
||||||
@ -653,7 +658,8 @@ impl RPCProcessor {
|
|||||||
// No private route was specified for the request
|
// No private route was specified for the request
|
||||||
// but we are using a safety route, so we must create an empty private route
|
// but we are using a safety route, so we must create an empty private route
|
||||||
// Destination relay is ignored for safety routed operations
|
// Destination relay is ignored for safety routed operations
|
||||||
let peer_info = match destination_node_ref.make_peer_info(RoutingDomain::PublicInternet)
|
let peer_info = match destination_node_ref
|
||||||
|
.make_peer_info(RoutingDomain::PublicInternet)
|
||||||
{
|
{
|
||||||
None => {
|
None => {
|
||||||
return Ok(NetworkResult::no_connection_other(
|
return Ok(NetworkResult::no_connection_other(
|
||||||
@ -662,8 +668,10 @@ impl RPCProcessor {
|
|||||||
}
|
}
|
||||||
Some(pi) => pi,
|
Some(pi) => pi,
|
||||||
};
|
};
|
||||||
let private_route =
|
let private_route = PrivateRoute::new_stub(
|
||||||
PrivateRoute::new_stub(destination_node_ref.best_node_id(), RouteNode::PeerInfo(peer_info));
|
destination_node_ref.best_node_id(),
|
||||||
|
RouteNode::PeerInfo(peer_info),
|
||||||
|
);
|
||||||
|
|
||||||
// Wrap with safety route
|
// Wrap with safety route
|
||||||
out = self.wrap_with_route(
|
out = self.wrap_with_route(
|
||||||
@ -749,10 +757,7 @@ impl RPCProcessor {
|
|||||||
return Ok(SenderPeerInfo::new_no_peer_info(target_node_info_ts));
|
return Ok(SenderPeerInfo::new_no_peer_info(target_node_info_ts));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(SenderPeerInfo::new(
|
Ok(SenderPeerInfo::new(own_peer_info, target_node_info_ts))
|
||||||
own_peer_info,
|
|
||||||
target_node_info_ts,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Record failure to send to node or route
|
/// Record failure to send to node or route
|
||||||
@ -1194,7 +1199,10 @@ impl RPCProcessor {
|
|||||||
let routing_domain = detail.routing_domain;
|
let routing_domain = detail.routing_domain;
|
||||||
|
|
||||||
// Decode the operation
|
// Decode the operation
|
||||||
let sender_node_id = TypedKey::new(detail.envelope.get_crypto_kind(), detail.envelope.get_sender_id());
|
let sender_node_id = TypedKey::new(
|
||||||
|
detail.envelope.get_crypto_kind(),
|
||||||
|
detail.envelope.get_sender_id(),
|
||||||
|
);
|
||||||
|
|
||||||
// Decode the RPC message
|
// Decode the RPC message
|
||||||
let operation = {
|
let operation = {
|
||||||
@ -1386,6 +1394,7 @@ impl RPCProcessor {
|
|||||||
#[instrument(level = "trace", skip(self, body), err)]
|
#[instrument(level = "trace", skip(self, body), err)]
|
||||||
pub fn enqueue_safety_routed_message(
|
pub fn enqueue_safety_routed_message(
|
||||||
&self,
|
&self,
|
||||||
|
direct: RPCMessageHeaderDetailDirect,
|
||||||
remote_safety_route: PublicKey,
|
remote_safety_route: PublicKey,
|
||||||
sequencing: Sequencing,
|
sequencing: Sequencing,
|
||||||
body: Vec<u8>,
|
body: Vec<u8>,
|
||||||
@ -1393,6 +1402,7 @@ impl RPCProcessor {
|
|||||||
let msg = RPCMessageEncoded {
|
let msg = RPCMessageEncoded {
|
||||||
header: RPCMessageHeader {
|
header: RPCMessageHeader {
|
||||||
detail: RPCMessageHeaderDetail::SafetyRouted(RPCMessageHeaderDetailSafetyRouted {
|
detail: RPCMessageHeaderDetail::SafetyRouted(RPCMessageHeaderDetailSafetyRouted {
|
||||||
|
direct,
|
||||||
remote_safety_route,
|
remote_safety_route,
|
||||||
sequencing,
|
sequencing,
|
||||||
}),
|
}),
|
||||||
@ -1415,6 +1425,7 @@ impl RPCProcessor {
|
|||||||
#[instrument(level = "trace", skip(self, body), err)]
|
#[instrument(level = "trace", skip(self, body), err)]
|
||||||
pub fn enqueue_private_routed_message(
|
pub fn enqueue_private_routed_message(
|
||||||
&self,
|
&self,
|
||||||
|
direct: RPCMessageHeaderDetailDirect,
|
||||||
remote_safety_route: PublicKey,
|
remote_safety_route: PublicKey,
|
||||||
private_route: PublicKey,
|
private_route: PublicKey,
|
||||||
safety_spec: SafetySpec,
|
safety_spec: SafetySpec,
|
||||||
@ -1424,6 +1435,7 @@ impl RPCProcessor {
|
|||||||
header: RPCMessageHeader {
|
header: RPCMessageHeader {
|
||||||
detail: RPCMessageHeaderDetail::PrivateRouted(
|
detail: RPCMessageHeaderDetail::PrivateRouted(
|
||||||
RPCMessageHeaderDetailPrivateRouted {
|
RPCMessageHeaderDetailPrivateRouted {
|
||||||
|
direct,
|
||||||
remote_safety_route,
|
remote_safety_route,
|
||||||
private_route,
|
private_route,
|
||||||
safety_spec,
|
safety_spec,
|
||||||
|
@ -26,31 +26,11 @@ impl RPCProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get next hop node ref
|
// Get next hop node ref
|
||||||
let mut next_hop_nr = match route_hop.node {
|
let Some(mut next_hop_nr) = route_hop.node.node_ref(self.routing_table.clone(), safety_route.public_key.kind) else {
|
||||||
RouteNode::NodeId(id) => {
|
return Err(RPCError::network(format!(
|
||||||
//
|
"could not get route node hop ref: {}",
|
||||||
let Some(nr) = self.routing_table.lookup_node_ref(id.key) else {
|
route_hop.node.describe(safety_route.public_key.kind)
|
||||||
return Ok(NetworkResult::invalid_message(format!("node hop {} not found", id.key)));
|
)));
|
||||||
};
|
|
||||||
nr
|
|
||||||
}
|
|
||||||
RouteNode::PeerInfo(pi) => {
|
|
||||||
//
|
|
||||||
let Some(nr) = self.routing_table
|
|
||||||
.register_node_with_peer_info(
|
|
||||||
RoutingDomain::PublicInternet,
|
|
||||||
pi.node_id.key,
|
|
||||||
pi.signed_node_info,
|
|
||||||
false,
|
|
||||||
) else
|
|
||||||
{
|
|
||||||
return Ok(NetworkResult::invalid_message(format!(
|
|
||||||
"node hop {} could not be registered",
|
|
||||||
pi.node_id.key
|
|
||||||
)));
|
|
||||||
};
|
|
||||||
nr
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Apply sequencing preference
|
// Apply sequencing preference
|
||||||
@ -88,30 +68,12 @@ impl RPCProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get next hop node ref
|
// Get next hop node ref
|
||||||
let mut next_hop_nr = match &next_route_node {
|
let Some(mut next_hop_nr) = next_route_node.node_ref(self.routing_table.clone(), safety_route_public_key.kind) else {
|
||||||
RouteNode::NodeId(id) => {
|
return Err(RPCError::network(format!(
|
||||||
//
|
"could not get route node hop ref: {}",
|
||||||
self.routing_table
|
next_route_node.describe(safety_route_public_key.kind)
|
||||||
.lookup_node_ref(id.key)
|
)));
|
||||||
.ok_or_else(|| RPCError::network(format!("node hop {} not found", id.key)))
|
};
|
||||||
}
|
|
||||||
RouteNode::PeerInfo(pi) => {
|
|
||||||
//
|
|
||||||
self.routing_table
|
|
||||||
.register_node_with_peer_info(
|
|
||||||
RoutingDomain::PublicInternet,
|
|
||||||
pi.node_id.key,
|
|
||||||
pi.signed_node_info.clone(),
|
|
||||||
false,
|
|
||||||
)
|
|
||||||
.ok_or_else(|| {
|
|
||||||
RPCError::network(format!(
|
|
||||||
"node hop {} could not be registered",
|
|
||||||
pi.node_id.key
|
|
||||||
))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}?;
|
|
||||||
|
|
||||||
// Apply sequencing preference
|
// Apply sequencing preference
|
||||||
next_hop_nr.set_sequencing(routed_operation.sequencing);
|
next_hop_nr.set_sequencing(routed_operation.sequencing);
|
||||||
@ -140,19 +102,18 @@ impl RPCProcessor {
|
|||||||
#[instrument(level = "trace", skip_all, err)]
|
#[instrument(level = "trace", skip_all, err)]
|
||||||
fn process_safety_routed_operation(
|
fn process_safety_routed_operation(
|
||||||
&self,
|
&self,
|
||||||
_detail: RPCMessageHeaderDetailDirect,
|
detail: RPCMessageHeaderDetailDirect,
|
||||||
|
vcrypto: CryptoSystemVersion,
|
||||||
routed_operation: RoutedOperation,
|
routed_operation: RoutedOperation,
|
||||||
remote_sr_pubkey: TypedKey,
|
remote_sr_pubkey: TypedKey,
|
||||||
) -> Result<NetworkResult<()>, RPCError> {
|
) -> Result<NetworkResult<()>, RPCError> {
|
||||||
|
|
||||||
// Now that things are valid, decrypt the routed operation with DEC(nonce, DH(the SR's public key, the PR's (or node's) secret)
|
// Now that things are valid, decrypt the routed operation with DEC(nonce, DH(the SR's public key, the PR's (or node's) secret)
|
||||||
// xxx: punish nodes that send messages that fail to decrypt eventually? How to do this for safety routes?
|
// xxx: punish nodes that send messages that fail to decrypt eventually? How to do this for safety routes?
|
||||||
let node_id_secret = self.routing_table.node_id_secret();
|
let node_id_secret = self.routing_table.node_id_secret(remote_sr_pubkey.kind);
|
||||||
let dh_secret = self
|
let dh_secret = vcrypto
|
||||||
.crypto
|
.cached_dh(&remote_sr_pubkey.key, &node_id_secret)
|
||||||
.cached_dh(&remote_sr_pubkey, &node_id_secret)
|
|
||||||
.map_err(RPCError::protocol)?;
|
.map_err(RPCError::protocol)?;
|
||||||
let body = match Crypto::decrypt_aead(
|
let body = match vcrypto.decrypt_aead(
|
||||||
&routed_operation.data,
|
&routed_operation.data,
|
||||||
&routed_operation.nonce,
|
&routed_operation.nonce,
|
||||||
&dh_secret,
|
&dh_secret,
|
||||||
@ -160,13 +121,21 @@ impl RPCProcessor {
|
|||||||
) {
|
) {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return Ok(NetworkResult::invalid_message(format!("decryption of routed operation failed: {}", e)));
|
return Ok(NetworkResult::invalid_message(format!(
|
||||||
|
"decryption of routed operation failed: {}",
|
||||||
|
e
|
||||||
|
)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Pass message to RPC system
|
// Pass message to RPC system
|
||||||
self.enqueue_safety_routed_message(remote_sr_pubkey, routed_operation.sequencing, body)
|
self.enqueue_safety_routed_message(
|
||||||
.map_err(RPCError::internal)?;
|
detail,
|
||||||
|
remote_sr_pubkey.key,
|
||||||
|
routed_operation.sequencing,
|
||||||
|
body,
|
||||||
|
)
|
||||||
|
.map_err(RPCError::internal)?;
|
||||||
|
|
||||||
Ok(NetworkResult::value(()))
|
Ok(NetworkResult::value(()))
|
||||||
}
|
}
|
||||||
@ -176,6 +145,7 @@ impl RPCProcessor {
|
|||||||
fn process_private_routed_operation(
|
fn process_private_routed_operation(
|
||||||
&self,
|
&self,
|
||||||
detail: RPCMessageHeaderDetailDirect,
|
detail: RPCMessageHeaderDetailDirect,
|
||||||
|
vcrypto: CryptoSystemVersion,
|
||||||
routed_operation: RoutedOperation,
|
routed_operation: RoutedOperation,
|
||||||
remote_sr_pubkey: TypedKey,
|
remote_sr_pubkey: TypedKey,
|
||||||
pr_pubkey: TypedKey,
|
pr_pubkey: TypedKey,
|
||||||
@ -196,7 +166,7 @@ impl RPCProcessor {
|
|||||||
(
|
(
|
||||||
rsd.secret_key,
|
rsd.secret_key,
|
||||||
SafetySpec {
|
SafetySpec {
|
||||||
preferred_route: rss.get_route_id_for_key(&pr_pubkey),
|
preferred_route: rss.get_route_id_for_key(&pr_pubkey.key),
|
||||||
hop_count: rssd.hop_count(),
|
hop_count: rssd.hop_count(),
|
||||||
stability: rssd.get_stability(),
|
stability: rssd.get_stability(),
|
||||||
sequencing: routed_operation.sequencing,
|
sequencing: routed_operation.sequencing,
|
||||||
@ -208,26 +178,31 @@ impl RPCProcessor {
|
|||||||
return Ok(NetworkResult::invalid_message("signatures did not validate for private route"));
|
return Ok(NetworkResult::invalid_message("signatures did not validate for private route"));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Now that things are valid, decrypt the routed operation with DEC(nonce, DH(the SR's public key, the PR's (or node's) secret)
|
// Now that things are valid, decrypt the routed operation with DEC(nonce, DH(the SR's public key, the PR's (or node's) secret)
|
||||||
// xxx: punish nodes that send messages that fail to decrypt eventually. How to do this for private routes?
|
// xxx: punish nodes that send messages that fail to decrypt eventually. How to do this for private routes?
|
||||||
let dh_secret = self
|
let dh_secret = vcrypto
|
||||||
.crypto
|
.cached_dh(&remote_sr_pubkey.key, &secret_key)
|
||||||
.cached_dh(&remote_sr_pubkey, &secret_key)
|
|
||||||
.map_err(RPCError::protocol)?;
|
.map_err(RPCError::protocol)?;
|
||||||
let body = Crypto::decrypt_aead(
|
let body = vcrypto
|
||||||
&routed_operation.data,
|
.decrypt_aead(
|
||||||
&routed_operation.nonce,
|
&routed_operation.data,
|
||||||
&dh_secret,
|
&routed_operation.nonce,
|
||||||
None,
|
&dh_secret,
|
||||||
)
|
None,
|
||||||
.map_err(RPCError::map_internal(
|
)
|
||||||
"decryption of routed operation failed",
|
.map_err(RPCError::map_internal(
|
||||||
))?;
|
"decryption of routed operation failed",
|
||||||
|
))?;
|
||||||
|
|
||||||
// Pass message to RPC system
|
// Pass message to RPC system
|
||||||
self.enqueue_private_routed_message(remote_sr_pubkey, pr_pubkey, safety_spec, body)
|
self.enqueue_private_routed_message(
|
||||||
.map_err(RPCError::internal)?;
|
detail,
|
||||||
|
remote_sr_pubkey.key,
|
||||||
|
pr_pubkey.key,
|
||||||
|
safety_spec,
|
||||||
|
body,
|
||||||
|
)
|
||||||
|
.map_err(RPCError::internal)?;
|
||||||
|
|
||||||
Ok(NetworkResult::value(()))
|
Ok(NetworkResult::value(()))
|
||||||
}
|
}
|
||||||
@ -236,20 +211,26 @@ impl RPCProcessor {
|
|||||||
fn process_routed_operation(
|
fn process_routed_operation(
|
||||||
&self,
|
&self,
|
||||||
detail: RPCMessageHeaderDetailDirect,
|
detail: RPCMessageHeaderDetailDirect,
|
||||||
|
vcrypto: CryptoSystemVersion,
|
||||||
routed_operation: RoutedOperation,
|
routed_operation: RoutedOperation,
|
||||||
remote_sr_pubkey: TypedKey,
|
remote_sr_pubkey: TypedKey,
|
||||||
pr_pubkey: TypedKey,
|
pr_pubkey: TypedKey,
|
||||||
) -> Result<NetworkResult<()>, RPCError> {
|
) -> Result<NetworkResult<()>, RPCError> {
|
||||||
|
|
||||||
// If the private route public key is our node id, then this was sent via safety route to our node directly
|
// If the private route public key is our node id, then this was sent via safety route to our node directly
|
||||||
// so there will be no signatures to validate
|
// so there will be no signatures to validate
|
||||||
if self.routing_table.node_ids().contains(&pr_pubkey) {
|
if self.routing_table.node_ids().contains(&pr_pubkey) {
|
||||||
// The private route was a stub
|
// The private route was a stub
|
||||||
self.process_safety_routed_operation(detail, routed_operation, remote_sr_pubkey)
|
self.process_safety_routed_operation(
|
||||||
|
detail,
|
||||||
|
vcrypto,
|
||||||
|
routed_operation,
|
||||||
|
remote_sr_pubkey,
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
// Both safety and private routes used, should reply with a safety route
|
// Both safety and private routes used, should reply with a safety route
|
||||||
self.process_private_routed_operation(
|
self.process_private_routed_operation(
|
||||||
detail,
|
detail,
|
||||||
|
vcrypto,
|
||||||
routed_operation,
|
routed_operation,
|
||||||
remote_sr_pubkey,
|
remote_sr_pubkey,
|
||||||
pr_pubkey,
|
pr_pubkey,
|
||||||
@ -275,7 +256,11 @@ impl RPCProcessor {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Decrypt route hop data
|
// Decrypt route hop data
|
||||||
let route_hop = network_result_try!(self.decrypt_private_route_hop_data(&route_hop_data, &private_route.public_key, &mut routed_operation)?);
|
let route_hop = network_result_try!(self.decrypt_private_route_hop_data(
|
||||||
|
&route_hop_data,
|
||||||
|
&private_route.public_key,
|
||||||
|
&mut routed_operation
|
||||||
|
)?);
|
||||||
|
|
||||||
// Ensure hop count > 0
|
// Ensure hop count > 0
|
||||||
if private_route.hop_count == 0 {
|
if private_route.hop_count == 0 {
|
||||||
@ -285,20 +270,21 @@ impl RPCProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Make next PrivateRoute and pass it on
|
// Make next PrivateRoute and pass it on
|
||||||
return self.process_route_private_route_hop(
|
return self
|
||||||
routed_operation,
|
.process_route_private_route_hop(
|
||||||
route_hop.node,
|
routed_operation,
|
||||||
sr_pubkey,
|
route_hop.node,
|
||||||
PrivateRoute {
|
sr_pubkey,
|
||||||
public_key: private_route.public_key,
|
PrivateRoute {
|
||||||
hop_count: private_route.hop_count - 1,
|
public_key: private_route.public_key,
|
||||||
hops: route_hop
|
hop_count: private_route.hop_count - 1,
|
||||||
.next_hop
|
hops: route_hop
|
||||||
.map(|rhd| PrivateRouteHops::Data(rhd))
|
.next_hop
|
||||||
.unwrap_or(PrivateRouteHops::Empty),
|
.map(|rhd| PrivateRouteHops::Data(rhd))
|
||||||
},
|
.unwrap_or(PrivateRouteHops::Empty),
|
||||||
)
|
},
|
||||||
.await;
|
)
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Switching to private route from safety route
|
// Switching to private route from safety route
|
||||||
@ -312,8 +298,12 @@ impl RPCProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Decrypt route hop data and sign routed operation
|
/// Decrypt route hop data and sign routed operation
|
||||||
pub(crate) fn decrypt_private_route_hop_data(&self, route_hop_data: &RouteHopData, pr_pubkey: &TypedKey, route_operation: &mut RoutedOperation) -> Result<NetworkResult<RouteHop>, RPCError>
|
pub(crate) fn decrypt_private_route_hop_data(
|
||||||
{
|
&self,
|
||||||
|
route_hop_data: &RouteHopData,
|
||||||
|
pr_pubkey: &TypedKey,
|
||||||
|
route_operation: &mut RoutedOperation,
|
||||||
|
) -> Result<NetworkResult<RouteHop>, RPCError> {
|
||||||
// Get crypto kind
|
// Get crypto kind
|
||||||
let crypto_kind = pr_pubkey.kind;
|
let crypto_kind = pr_pubkey.kind;
|
||||||
let Some(vcrypto) = self.crypto.get(crypto_kind) else {
|
let Some(vcrypto) = self.crypto.get(crypto_kind) else {
|
||||||
@ -335,7 +325,10 @@ impl RPCProcessor {
|
|||||||
) {
|
) {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return Ok(NetworkResult::invalid_message(format!("unable to decrypt private route hop data: {}", e)));
|
return Ok(NetworkResult::invalid_message(format!(
|
||||||
|
"unable to decrypt private route hop data: {}",
|
||||||
|
e
|
||||||
|
)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let dec_blob_reader = RPCMessageData::new(dec_blob_data).get_reader()?;
|
let dec_blob_reader = RPCMessageData::new(dec_blob_data).get_reader()?;
|
||||||
@ -353,7 +346,8 @@ impl RPCProcessor {
|
|||||||
if route_hop.next_hop.is_some() {
|
if route_hop.next_hop.is_some() {
|
||||||
let node_id = self.routing_table.node_id(crypto_kind);
|
let node_id = self.routing_table.node_id(crypto_kind);
|
||||||
let node_id_secret = self.routing_table.node_id_secret(crypto_kind);
|
let node_id_secret = self.routing_table.node_id_secret(crypto_kind);
|
||||||
let sig = vcrypto.sign(&node_id.key, &node_id_secret, &route_operation.data)
|
let sig = vcrypto
|
||||||
|
.sign(&node_id.key, &node_id_secret, &route_operation.data)
|
||||||
.map_err(RPCError::internal)?;
|
.map_err(RPCError::internal)?;
|
||||||
route_operation.signatures.push(sig);
|
route_operation.signatures.push(sig);
|
||||||
}
|
}
|
||||||
@ -402,7 +396,13 @@ impl RPCProcessor {
|
|||||||
let dh_secret = vcrypto
|
let dh_secret = vcrypto
|
||||||
.cached_dh(&route.safety_route.public_key.key, &node_id_secret)
|
.cached_dh(&route.safety_route.public_key.key, &node_id_secret)
|
||||||
.map_err(RPCError::protocol)?;
|
.map_err(RPCError::protocol)?;
|
||||||
let mut dec_blob_data = vcrypto.decrypt_aead(&route_hop_data.blob, &route_hop_data.nonce, &dh_secret, None)
|
let mut dec_blob_data = vcrypto
|
||||||
|
.decrypt_aead(
|
||||||
|
&route_hop_data.blob,
|
||||||
|
&route_hop_data.nonce,
|
||||||
|
&dh_secret,
|
||||||
|
None,
|
||||||
|
)
|
||||||
.map_err(RPCError::protocol)?;
|
.map_err(RPCError::protocol)?;
|
||||||
|
|
||||||
// See if this is last hop in safety route, if so, we're decoding a PrivateRoute not a RouteHop
|
// See if this is last hop in safety route, if so, we're decoding a PrivateRoute not a RouteHop
|
||||||
@ -423,12 +423,14 @@ impl RPCProcessor {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Switching from full safety route to private route first hop
|
// Switching from full safety route to private route first hop
|
||||||
network_result_try!(self.process_private_route_first_hop(
|
network_result_try!(
|
||||||
route.operation,
|
self.process_private_route_first_hop(
|
||||||
route.safety_route.public_key,
|
route.operation,
|
||||||
private_route,
|
route.safety_route.public_key,
|
||||||
)
|
private_route,
|
||||||
.await?);
|
)
|
||||||
|
.await?
|
||||||
|
);
|
||||||
} else if dec_blob_tag == 0 {
|
} else if dec_blob_tag == 0 {
|
||||||
// RouteHop
|
// RouteHop
|
||||||
let route_hop = {
|
let route_hop = {
|
||||||
@ -439,8 +441,14 @@ impl RPCProcessor {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Continue the full safety route with another hop
|
// Continue the full safety route with another hop
|
||||||
network_result_try!(self.process_route_safety_route_hop(route.operation, route_hop, route.safety_route)
|
network_result_try!(
|
||||||
.await?);
|
self.process_route_safety_route_hop(
|
||||||
|
route.operation,
|
||||||
|
route_hop,
|
||||||
|
route.safety_route
|
||||||
|
)
|
||||||
|
.await?
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
return Ok(NetworkResult::invalid_message("invalid blob tag"));
|
return Ok(NetworkResult::invalid_message("invalid blob tag"));
|
||||||
}
|
}
|
||||||
@ -451,17 +459,22 @@ impl RPCProcessor {
|
|||||||
match private_route.hops {
|
match private_route.hops {
|
||||||
PrivateRouteHops::FirstHop(_) => {
|
PrivateRouteHops::FirstHop(_) => {
|
||||||
// Safety route was a stub, start with the beginning of the private route
|
// Safety route was a stub, start with the beginning of the private route
|
||||||
network_result_try!(self.process_private_route_first_hop(
|
network_result_try!(
|
||||||
route.operation,
|
self.process_private_route_first_hop(
|
||||||
route.safety_route.public_key,
|
route.operation,
|
||||||
private_route,
|
route.safety_route.public_key,
|
||||||
)
|
private_route,
|
||||||
.await?);
|
)
|
||||||
|
.await?
|
||||||
|
);
|
||||||
}
|
}
|
||||||
PrivateRouteHops::Data(route_hop_data) => {
|
PrivateRouteHops::Data(route_hop_data) => {
|
||||||
|
|
||||||
// Decrypt route hop data
|
// Decrypt route hop data
|
||||||
let route_hop = network_result_try!(self.decrypt_private_route_hop_data(&route_hop_data, &private_route.public_key, &mut route.operation)?);
|
let route_hop = network_result_try!(self.decrypt_private_route_hop_data(
|
||||||
|
&route_hop_data,
|
||||||
|
&private_route.public_key,
|
||||||
|
&mut route.operation
|
||||||
|
)?);
|
||||||
|
|
||||||
// Ensure hop count > 0
|
// Ensure hop count > 0
|
||||||
if private_route.hop_count == 0 {
|
if private_route.hop_count == 0 {
|
||||||
@ -471,20 +484,22 @@ impl RPCProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Make next PrivateRoute and pass it on
|
// Make next PrivateRoute and pass it on
|
||||||
network_result_try!(self.process_route_private_route_hop(
|
network_result_try!(
|
||||||
route.operation,
|
self.process_route_private_route_hop(
|
||||||
route_hop.node,
|
route.operation,
|
||||||
route.safety_route.public_key,
|
route_hop.node,
|
||||||
PrivateRoute {
|
route.safety_route.public_key,
|
||||||
public_key: private_route.public_key,
|
PrivateRoute {
|
||||||
hop_count: private_route.hop_count - 1,
|
public_key: private_route.public_key,
|
||||||
hops: route_hop
|
hop_count: private_route.hop_count - 1,
|
||||||
.next_hop
|
hops: route_hop
|
||||||
.map(|rhd| PrivateRouteHops::Data(rhd))
|
.next_hop
|
||||||
.unwrap_or(PrivateRouteHops::Empty),
|
.map(|rhd| PrivateRouteHops::Data(rhd))
|
||||||
},
|
.unwrap_or(PrivateRouteHops::Empty),
|
||||||
)
|
},
|
||||||
.await?);
|
)
|
||||||
|
.await?
|
||||||
|
);
|
||||||
}
|
}
|
||||||
PrivateRouteHops::Empty => {
|
PrivateRouteHops::Empty => {
|
||||||
// Ensure hop count == 0
|
// Ensure hop count == 0
|
||||||
@ -502,6 +517,7 @@ impl RPCProcessor {
|
|||||||
// No hops left, time to process the routed operation
|
// No hops left, time to process the routed operation
|
||||||
network_result_try!(self.process_routed_operation(
|
network_result_try!(self.process_routed_operation(
|
||||||
detail,
|
detail,
|
||||||
|
vcrypto,
|
||||||
route.operation,
|
route.operation,
|
||||||
route.safety_route.public_key,
|
route.safety_route.public_key,
|
||||||
private_route.public_key,
|
private_route.public_key,
|
||||||
|
Loading…
Reference in New Issue
Block a user