Check timestamp
This commit is contained in:
Generated
+1
@@ -4826,6 +4826,7 @@ dependencies = [
|
||||
"serde_json",
|
||||
"tap",
|
||||
"thiserror",
|
||||
"time",
|
||||
"tokio",
|
||||
"tokio-tun",
|
||||
"tokio-util",
|
||||
|
||||
@@ -257,6 +257,10 @@ impl SignedRequest for SignedStaticConnectRequest {
|
||||
fn signature(&self) -> Option<&Vec<u8>> {
|
||||
self.signature.as_ref()
|
||||
}
|
||||
|
||||
fn timestamp(&self) -> OffsetDateTime {
|
||||
self.request.timestamp
|
||||
}
|
||||
}
|
||||
|
||||
// A dynamic connect request is when the client does not provide the internal IP address it will use
|
||||
@@ -314,6 +318,10 @@ impl SignedRequest for SignedDynamicConnectRequest {
|
||||
fn signature(&self) -> Option<&Vec<u8>> {
|
||||
self.signature.as_ref()
|
||||
}
|
||||
|
||||
fn timestamp(&self) -> OffsetDateTime {
|
||||
self.request.timestamp
|
||||
}
|
||||
}
|
||||
|
||||
// A disconnect request is when the client wants to disconnect from the ip packet router and free
|
||||
@@ -359,6 +367,10 @@ impl SignedRequest for SignedDisconnectRequest {
|
||||
fn signature(&self) -> Option<&Vec<u8>> {
|
||||
self.signature.as_ref()
|
||||
}
|
||||
|
||||
fn timestamp(&self) -> OffsetDateTime {
|
||||
self.request.timestamp
|
||||
}
|
||||
}
|
||||
|
||||
// A data request is when the client wants to send an IP packet to a destination.
|
||||
|
||||
@@ -277,6 +277,8 @@ pub enum StaticConnectFailureReason {
|
||||
RequestedIpAlreadyInUse,
|
||||
#[error("requested nym-address is already in use")]
|
||||
RequestedNymAddressAlreadyInUse,
|
||||
#[error("request timestamp is out of date")]
|
||||
OutOfDateTimestamp,
|
||||
#[error("{0}")]
|
||||
Other(String),
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use std::time::Duration;
|
||||
|
||||
use nym_crypto::asymmetric::{ed25519::Ed25519RecoveryError, identity};
|
||||
|
||||
#[derive(thiserror::Error, Debug)]
|
||||
@@ -17,6 +19,9 @@ pub enum SignatureError {
|
||||
error: Box<bincode::ErrorKind>,
|
||||
},
|
||||
|
||||
#[error("signature verification failed: request out of date")]
|
||||
RequestOutOfDate,
|
||||
|
||||
#[error("signature verification failed")]
|
||||
VerificationFailed {
|
||||
message: String,
|
||||
@@ -31,8 +36,15 @@ pub trait SignedRequest {
|
||||
|
||||
fn signature(&self) -> Option<&Vec<u8>>;
|
||||
|
||||
fn timestamp(&self) -> time::OffsetDateTime;
|
||||
|
||||
fn verify(&self) -> Result<(), SignatureError> {
|
||||
if let Some(signature) = self.signature() {
|
||||
// First check that the request is recent enough
|
||||
if time::OffsetDateTime::now_utc() - self.timestamp() > Duration::from_secs(10) {
|
||||
return Err(SignatureError::RequestOutOfDate);
|
||||
}
|
||||
|
||||
let request_as_bytes = self.request()?;
|
||||
let signature = identity::Signature::from_bytes(signature).map_err(|error| {
|
||||
SignatureError::SignatureParseError {
|
||||
|
||||
@@ -22,6 +22,7 @@ nym-client-core = { path = "../../common/client-core" }
|
||||
nym-config = { path = "../../common/config" }
|
||||
nym-crypto = { path = "../../common/crypto" }
|
||||
nym-exit-policy = { path = "../../common/exit-policy" }
|
||||
nym-id = { path = "../../common/nym-id" }
|
||||
nym-ip-packet-requests = { path = "../../common/ip-packet-requests" }
|
||||
nym-network-defaults = { path = "../../common/network-defaults" }
|
||||
nym-network-requester = { path = "../network-requester" }
|
||||
@@ -33,13 +34,13 @@ nym-tun = { path = "../../common/tun" }
|
||||
nym-types = { path = "../../common/types" }
|
||||
nym-wireguard = { path = "../../common/wireguard" }
|
||||
nym-wireguard-types = { path = "../../common/wireguard-types" }
|
||||
nym-id = { path = "../../common/nym-id" }
|
||||
rand = "0.8.5"
|
||||
reqwest.workspace = true
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
serde_json = { workspace = true }
|
||||
tap.workspace = true
|
||||
thiserror = { workspace = true }
|
||||
time = { workspace = true }
|
||||
tokio = { workspace = true, features = ["rt-multi-thread", "net", "io-util"] }
|
||||
tokio-util = { workspace = true, features = ["codec"] }
|
||||
url.workspace = true
|
||||
|
||||
@@ -575,29 +575,17 @@ impl MixnetListener {
|
||||
|
||||
match request.data {
|
||||
IpPacketRequestData::StaticConnect(signed_connect_request) => {
|
||||
if let Err(err) = signed_connect_request.verify() {
|
||||
if !matches!(err, SignatureError::MissingSignature) {
|
||||
return Err(IpPacketRouterError::FailedToVerifyRequest { source: err });
|
||||
}
|
||||
}
|
||||
verify_signed_request(&signed_connect_request)?;
|
||||
let connect_request = signed_connect_request.request;
|
||||
Ok(vec![self.on_static_connect_request(connect_request).await])
|
||||
}
|
||||
IpPacketRequestData::DynamicConnect(signed_connect_request) => {
|
||||
if let Err(err) = signed_connect_request.verify() {
|
||||
if !matches!(err, SignatureError::MissingSignature) {
|
||||
return Err(IpPacketRouterError::FailedToVerifyRequest { source: err });
|
||||
}
|
||||
}
|
||||
verify_signed_request(&signed_connect_request)?;
|
||||
let connect_request = signed_connect_request.request;
|
||||
Ok(vec![self.on_dynamic_connect_request(connect_request).await])
|
||||
}
|
||||
IpPacketRequestData::Disconnect(signed_disconnect_request) => {
|
||||
if let Err(err) = signed_disconnect_request.verify() {
|
||||
if !matches!(err, SignatureError::MissingSignature) {
|
||||
return Err(IpPacketRouterError::FailedToVerifyRequest { source: err });
|
||||
}
|
||||
}
|
||||
verify_signed_request(&signed_disconnect_request)?;
|
||||
let disconnect_request = signed_disconnect_request.request;
|
||||
Ok(vec![self.on_disconnect_request(disconnect_request)])
|
||||
}
|
||||
@@ -715,6 +703,15 @@ impl MixnetListener {
|
||||
}
|
||||
}
|
||||
|
||||
fn verify_signed_request(request: &impl SignedRequest) -> Result<()> {
|
||||
if let Err(err) = request.verify() {
|
||||
if !matches!(err, SignatureError::MissingSignature) {
|
||||
return Err(IpPacketRouterError::FailedToVerifyRequest { source: err });
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) enum ConnectedClientEvent {
|
||||
Disconnect(DisconnectEvent),
|
||||
Connect(Box<ConnectEvent>),
|
||||
|
||||
Reference in New Issue
Block a user