chore: change auth v2 timestamp skew and allow values from the future (#5604)

* chore: change auth v2 timestamp skew and allow values from the future

* made the if statement more readable
This commit is contained in:
Jędrzej Stuczyński
2025-03-12 11:02:19 +00:00
committed by GitHub
parent eca88b0fa4
commit 7d59a2477a
9 changed files with 70 additions and 21 deletions
+7 -6
View File
@@ -10,6 +10,7 @@ use nym_sphinx::params::packet_sizes::PacketSize;
use serde::{Deserialize, Serialize};
use std::string::FromUtf8Error;
use thiserror::Error;
use time::OffsetDateTime;
// specific errors (that should not be nested!!) for clients to match on
#[derive(Debug, Copy, Clone, Error, Serialize, Deserialize)]
@@ -112,15 +113,15 @@ pub enum AuthenticationFailure {
#[error("failed to verify request signature")]
InvalidSignature(#[from] SignatureError),
#[error("provided request timestamp is in the future")]
RequestTimestampInFuture,
#[error("the client is not registered")]
NotRegistered,
#[error("the provided request is too stale to process")]
StaleRequest,
#[error("the provided request timestamp is excessively skewed. got {received} whilst the server time is {server}")]
ExcessiveTimestampSkew {
received: OffsetDateTime,
server: OffsetDateTime,
},
#[error("the provided request timestamp is smaller or equal to a one previously used")]
#[error("the provided request timestamp is smaller or equal to one previously used")]
RequestReuse,
}
@@ -38,13 +38,22 @@ impl AuthenticateRequest {
})
}
pub fn verify_timestamp(&self, max_request_age: Duration) -> Result<(), AuthenticationFailure> {
pub fn verify_timestamp(
&self,
max_request_timestamp_skew: Duration,
) -> Result<(), AuthenticationFailure> {
let now = OffsetDateTime::now_utc();
if self.content.request_timestamp() + max_request_age < now {
return Err(AuthenticationFailure::StaleRequest);
if self.content.request_timestamp() < now - max_request_timestamp_skew {
return Err(AuthenticationFailure::ExcessiveTimestampSkew {
received: self.content.request_timestamp(),
server: now,
});
}
if self.content.request_timestamp() > now {
return Err(AuthenticationFailure::RequestTimestampInFuture);
if self.content.request_timestamp() - max_request_timestamp_skew > now {
return Err(AuthenticationFailure::ExcessiveTimestampSkew {
received: self.content.request_timestamp(),
server: now,
});
}
Ok(())
}
+38
View File
@@ -1185,6 +1185,7 @@ name = "nym-pemstore"
version = "0.3.0"
dependencies = [
"pem",
"tracing",
]
[[package]]
@@ -1251,6 +1252,12 @@ dependencies = [
"regex",
]
[[package]]
name = "pin-project-lite"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
[[package]]
name = "pkcs8"
version = "0.9.0"
@@ -1840,6 +1847,37 @@ dependencies = [
"winnow",
]
[[package]]
name = "tracing"
version = "0.1.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
dependencies = [
"pin-project-lite",
"tracing-attributes",
"tracing-core",
]
[[package]]
name = "tracing-attributes"
version = "0.1.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.98",
]
[[package]]
name = "tracing-core"
version = "0.1.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c"
dependencies = [
"once_cell",
]
[[package]]
name = "typenum"
version = "1.18.0"
+2 -2
View File
@@ -102,8 +102,8 @@ pub struct Debug {
pub zk_nym_tickets: ZkNymTicketHandlerDebug,
/// Defines the maximum age of a signed authentication request before it's deemed too stale to process.
pub maximum_auth_request_age: Duration,
/// Defines the timestamp skew of a signed authentication request before it's deemed too excessive to process.
pub max_request_timestamp_skew: Duration,
}
#[derive(Debug, Clone)]
@@ -14,7 +14,7 @@ use std::time::Duration;
#[derive(Clone)]
pub(crate) struct Config {
pub(crate) enforce_zk_nym: bool,
pub(crate) max_auth_request_age: Duration,
pub(crate) max_request_timestamp_skew: Duration,
pub(crate) bandwidth: BandwidthFlushingBehaviourConfig,
}
@@ -641,7 +641,7 @@ impl<R, S> FreshHandler<R, S> {
// do cheap checks first
// is the provided timestamp relatively recent (and not in the future?)
request.verify_timestamp(self.shared_state.cfg.max_auth_request_age)?;
request.verify_timestamp(self.shared_state.cfg.max_request_timestamp_skew)?;
// does the message signature verify?
request.verify_signature()?;
+1 -1
View File
@@ -251,7 +251,7 @@ impl GatewayTasksBuilder {
let shared_state = websocket::CommonHandlerState {
cfg: websocket::Config {
enforce_zk_nym: self.config.gateway.enforce_zk_nyms,
max_auth_request_age: self.config.debug.maximum_auth_request_age,
max_request_timestamp_skew: self.config.debug.max_request_timestamp_skew,
bandwidth: (&self.config).into(),
},
ecash_verifier: self.ecash_manager().await?,
+5 -4
View File
@@ -54,8 +54,9 @@ pub struct Debug {
/// of the services providers
pub minimum_mix_performance: u8,
/// Defines the maximum age of a signed authentication request before it's deemed too stale to process.
pub maximum_auth_request_age: Duration,
/// Defines the timestamp skew of a signed authentication request before it's deemed too excessive to process.
#[serde(alias = "maximum_auth_request_age")]
pub max_request_timestamp_skew: Duration,
pub stale_messages: StaleMessageDebug,
@@ -67,7 +68,7 @@ pub struct Debug {
impl Debug {
pub const DEFAULT_MESSAGE_RETRIEVAL_LIMIT: i64 = 100;
pub const DEFAULT_MINIMUM_MIX_PERFORMANCE: u8 = 50;
pub const DEFAULT_MAXIMUM_AUTH_REQUEST_AGE: Duration = Duration::from_secs(30);
pub const DEFAULT_MAXIMUM_AUTH_REQUEST_TIMESTAMP_SKEW: Duration = Duration::from_secs(120);
pub const DEFAULT_MAXIMUM_OPEN_CONNECTIONS: usize = 8192;
}
@@ -76,7 +77,7 @@ impl Default for Debug {
Debug {
message_retrieval_limit: Self::DEFAULT_MESSAGE_RETRIEVAL_LIMIT,
maximum_open_connections: Self::DEFAULT_MAXIMUM_OPEN_CONNECTIONS,
maximum_auth_request_age: Self::DEFAULT_MAXIMUM_AUTH_REQUEST_AGE,
max_request_timestamp_skew: Self::DEFAULT_MAXIMUM_AUTH_REQUEST_TIMESTAMP_SKEW,
minimum_mix_performance: Self::DEFAULT_MINIMUM_MIX_PERFORMANCE,
stale_messages: Default::default(),
client_bandwidth: Default::default(),
+1 -1
View File
@@ -60,7 +60,7 @@ fn ephemeral_gateway_config(config: &Config) -> nym_gateway::config::Config {
.zk_nym_tickets
.maximum_time_between_redemption,
},
maximum_auth_request_age: config.gateway_tasks.debug.maximum_auth_request_age,
max_request_timestamp_skew: config.gateway_tasks.debug.max_request_timestamp_skew,
},
)
}