fix signing and validation
add timestamp to signed node info
This commit is contained in:
parent
912869d329
commit
d7ba221b48
@ -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 {
|
||||||
|
@ -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) {
|
||||||
|
@ -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);
|
||||||
})?;
|
})?;
|
||||||
|
@ -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))
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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!())
|
||||||
}
|
}
|
||||||
|
@ -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(×tamp).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(×tamp).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(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user