fix signing and validation

add timestamp to signed node info
This commit is contained in:
John Smith 2022-05-11 09:37:54 -04:00
parent 912869d329
commit d7ba221b48
7 changed files with 51 additions and 4 deletions

View File

@ -224,6 +224,7 @@ struct NodeInfo {
struct SignedNodeInfo { struct SignedNodeInfo {
nodeInfo @0 :NodeInfo; # node info nodeInfo @0 :NodeInfo; # node info
signature @1 :Signature; # signature signature @1 :Signature; # signature
timestamp @2 :UInt64; # when signed node info was generated
} }
struct SenderInfo { struct SenderInfo {

View File

@ -108,6 +108,15 @@ impl BucketEntry {
} }
pub fn update_node_info(&mut self, signed_node_info: SignedNodeInfo) { pub fn update_node_info(&mut self, signed_node_info: SignedNodeInfo) {
// Don't update with older node info, or something less valid
if let Some(current_sni) = &self.opt_signed_node_info {
if current_sni.signature.valid && !signed_node_info.signature.valid {
return;
}
if signed_node_info.timestamp < current_sni.timestamp {
return;
}
}
self.opt_signed_node_info = Some(signed_node_info); self.opt_signed_node_info = Some(signed_node_info);
} }
pub fn update_local_node_info(&mut self, local_node_info: LocalNodeInfo) { pub fn update_local_node_info(&mut self, local_node_info: LocalNodeInfo) {

View File

@ -487,6 +487,16 @@ impl RoutingTable {
node_id: DHTKey, node_id: DHTKey,
signed_node_info: SignedNodeInfo, signed_node_info: SignedNodeInfo,
) -> Result<NodeRef, String> { ) -> Result<NodeRef, String> {
// validate signed node info is not something malicious
if node_id == self.node_id() {
return Err("can't register own node id in routing table".to_owned());
}
if let Some(rpi) = &signed_node_info.node_info.relay_peer_info {
if rpi.node_id.key == node_id {
return Err("node can not be its own relay".to_owned());
}
}
let nr = self.create_node_ref(node_id, |e| { let nr = self.create_node_ref(node_id, |e| {
e.update_node_info(signed_node_info); e.update_node_info(signed_node_info);
})?; })?;

View File

@ -81,6 +81,13 @@ impl NodeRef {
pub fn relay(&self) -> Option<NodeRef> { pub fn relay(&self) -> Option<NodeRef> {
let target_rpi = self.operate(|e| e.node_info().map(|n| n.relay_peer_info))?; let target_rpi = self.operate(|e| e.node_info().map(|n| n.relay_peer_info))?;
target_rpi.and_then(|t| { target_rpi.and_then(|t| {
// If relay is ourselves, then return None, because we can't relay through ourselves
// and to contact this node we should have had an existing inbound connection
if t.node_id.key == self.routing_table.node_id() {
return None;
}
// Register relay node and return noderef
self.routing_table self.routing_table
.register_node_with_signed_node_info(t.node_id.key, t.signed_node_info) .register_node_with_signed_node_info(t.node_id.key, t.signed_node_info)
.map_err(logthru_rtab!(error)) .map_err(logthru_rtab!(error))

View File

@ -5,7 +5,7 @@ pub fn encode_signature(
sig: &DHTSignature, sig: &DHTSignature,
builder: &mut veilid_capnp::ed25519_signature::Builder, builder: &mut veilid_capnp::ed25519_signature::Builder,
) { ) {
if sig.valid { if !sig.valid {
panic!("don't encode invalid signatures"); panic!("don't encode invalid signatures");
} }

View File

@ -12,6 +12,8 @@ pub fn encode_signed_node_info(
let mut sig_builder = builder.reborrow().init_signature(); let mut sig_builder = builder.reborrow().init_signature();
encode_signature(&signed_node_info.signature, &mut sig_builder); encode_signature(&signed_node_info.signature, &mut sig_builder);
builder.reborrow().set_timestamp(signed_node_info.timestamp);
Ok(()) Ok(())
} }
@ -32,5 +34,8 @@ pub fn decode_signed_node_info(
.map_err(map_error_capnp_error!())?; .map_err(map_error_capnp_error!())?;
let signature = decode_signature(&sig_reader); let signature = decode_signature(&sig_reader);
SignedNodeInfo::new(node_info, NodeId::new(*node_id), signature).map_err(map_error_string!()) let timestamp = reader.reborrow().get_timestamp();
SignedNodeInfo::new(node_info, NodeId::new(*node_id), signature, timestamp)
.map_err(map_error_string!())
} }

View File

@ -989,6 +989,7 @@ impl Default for PeerScope {
pub struct SignedNodeInfo { pub struct SignedNodeInfo {
pub node_info: NodeInfo, pub node_info: NodeInfo,
pub signature: DHTSignature, pub signature: DHTSignature,
pub timestamp: u64,
} }
impl SignedNodeInfo { impl SignedNodeInfo {
@ -996,12 +997,18 @@ impl SignedNodeInfo {
node_info: NodeInfo, node_info: NodeInfo,
node_id: NodeId, node_id: NodeId,
signature: DHTSignature, signature: DHTSignature,
timestamp: u64,
) -> Result<Self, String> { ) -> Result<Self, String> {
let node_info_bytes = serde_cbor::to_vec(&node_info).map_err(map_to_string)?; let mut node_info_bytes = serde_cbor::to_vec(&node_info).map_err(map_to_string)?;
let mut timestamp_bytes = serde_cbor::to_vec(&timestamp).map_err(map_to_string)?;
node_info_bytes.append(&mut timestamp_bytes);
verify(&node_id.key, &node_info_bytes, &signature)?; verify(&node_id.key, &node_info_bytes, &signature)?;
Ok(Self { Ok(Self {
node_info, node_info,
signature, signature,
timestamp,
}) })
} }
@ -1010,11 +1017,18 @@ impl SignedNodeInfo {
node_id: NodeId, node_id: NodeId,
secret: &DHTKeySecret, secret: &DHTKeySecret,
) -> Result<Self, String> { ) -> Result<Self, String> {
let node_info_bytes = serde_cbor::to_vec(&node_info).map_err(map_to_string)?; let timestamp = intf::get_timestamp();
let mut node_info_bytes = serde_cbor::to_vec(&node_info).map_err(map_to_string)?;
let mut timestamp_bytes = serde_cbor::to_vec(&timestamp).map_err(map_to_string)?;
node_info_bytes.append(&mut timestamp_bytes);
let signature = sign(&node_id.key, secret, &node_info_bytes)?; let signature = sign(&node_id.key, secret, &node_info_bytes)?;
Ok(Self { Ok(Self {
node_info, node_info,
signature, signature,
timestamp,
}) })
} }
@ -1022,6 +1036,7 @@ impl SignedNodeInfo {
Self { Self {
node_info, node_info,
signature: DHTSignature::default(), signature: DHTSignature::default(),
timestamp: intf::get_timestamp(),
} }
} }
} }