From 261bbab2295711e1b8b7d8584f7b10f52bf80f58 Mon Sep 17 00:00:00 2001 From: Rudi Floren Date: Tue, 21 Apr 2026 11:18:15 +0200 Subject: [PATCH] refactor: replace time::Duration with std::time::Duration in public API std::time::Duration has less overhead when using the crate, so it makes more sense to stick to Duration in public APIs. time::Duration was used because the time crate is able to run in wasm32-unknown-unknown on Cloudflare Workers. The exact reason is limited to SystemTime/Instant, used in duration_since. We still use the time crate now to work around the issue of duration_since, but merely as an implementation detail. time::Duration implements Sub --- crates/web-bot-auth/src/lib.rs | 13 ++++++++----- crates/web-bot-auth/src/message_signatures.rs | 14 ++++++++------ examples/rust/signing.rs | 4 ++-- .../signature-agent-card-and-registry/src/lib.rs | 4 ++-- 4 files changed, 20 insertions(+), 15 deletions(-) diff --git a/crates/web-bot-auth/src/lib.rs b/crates/web-bot-auth/src/lib.rs index efcf461..07f0355 100644 --- a/crates/web-bot-auth/src/lib.rs +++ b/crates/web-bot-auth/src/lib.rs @@ -310,6 +310,8 @@ impl WebBotAuthVerifier { #[cfg(test)] mod tests { + use std::time::Duration; + use components::DerivedComponent; use indexmap::IndexMap; @@ -363,8 +365,9 @@ mod tests { assert!(advisory.is_expired.unwrap_or(true)); assert!(!advisory.nonce_is_invalid.unwrap_or(true)); let timing = verifier.verify(&keyring, None).unwrap(); - assert!(timing.generation.whole_nanoseconds() > 0); - assert!(timing.verification.whole_nanoseconds() > 0); + + assert!(timing.generation.as_nanos() > 0); + assert!(timing.verification.as_nanos() > 0); } #[test] @@ -446,7 +449,7 @@ mod tests { signer .generate_signature_headers_content( &mut mytest, - time::Duration::seconds(10), + Duration::from_secs(10), Algorithm::Ed25519, &private_key, ) @@ -463,8 +466,8 @@ mod tests { assert!(!advisory.nonce_is_invalid.unwrap_or(true)); let timing = verifier.verify(&keyring, None).unwrap(); - assert!(timing.generation.whole_nanoseconds() > 0); - assert!(timing.verification.whole_nanoseconds() > 0); + assert!(timing.generation.as_nanos() > 0); + assert!(timing.verification.as_nanos() > 0); } #[test] diff --git a/crates/web-bot-auth/src/message_signatures.rs b/crates/web-bot-auth/src/message_signatures.rs index fb3437b..82d02bc 100644 --- a/crates/web-bot-auth/src/message_signatures.rs +++ b/crates/web-bot-auth/src/message_signatures.rs @@ -6,7 +6,8 @@ use regex::bytes::Regex; use sfv::SerializeValue; use std::fmt::Write as _; use std::sync::LazyLock; -use time::{Duration, UtcDateTime}; +use std::time::Duration; +use time::UtcDateTime; static OBSOLETE_LINE_FOLDING: LazyLock = LazyLock::new(|| Regex::new(r"\s*\r\n\s+").unwrap()); @@ -575,7 +576,8 @@ impl MessageVerifier { .ok_or(ImplementationError::NoSuchKey)?; let generation = UtcDateTime::now(); let (base_representation, _) = self.parsed.base.into_ascii()?; - let generation = UtcDateTime::now() - generation; + let generation = (UtcDateTime::now() - generation).unsigned_abs(); + match &keying_material.0 { Algorithm::Ed25519 => { use ed25519_dalek::{Signature, Verifier, VerifyingKey}; @@ -591,7 +593,7 @@ impl MessageVerifier { .map_err(ImplementationError::FailedToVerify) .map(|()| SignatureTiming { generation, - verification: UtcDateTime::now() - verification, + verification: (UtcDateTime::now() - verification).unsigned_abs(), }) } other => Err(ImplementationError::UnsupportedAlgorithm(other.clone())), @@ -659,8 +661,8 @@ mod tests { ); let verifier = MessageVerifier::parse(&test, |(_, _)| true).unwrap(); let timing = verifier.verify(&keyring, None).unwrap(); - assert!(timing.generation.whole_nanoseconds() > 0); - assert!(timing.verification.whole_nanoseconds() > 0); + assert!(timing.generation.as_nanos() > 0); + assert!(timing.verification.as_nanos() > 0); } #[test] @@ -713,7 +715,7 @@ mod tests { signer .generate_signature_headers_content( &mut test, - Duration::seconds(10), + Duration::from_secs(10), Algorithm::Ed25519, &private_key ) diff --git a/examples/rust/signing.rs b/examples/rust/signing.rs index 2bf7297..f674256 100644 --- a/examples/rust/signing.rs +++ b/examples/rust/signing.rs @@ -13,7 +13,7 @@ // limitations under the License. use indexmap::IndexMap; -use time::Duration; +use std::time::Duration; use web_bot_auth::{ components::{ CoveredComponent, DerivedComponent, HTTPField, HTTPFieldParameters, HTTPFieldParametersSet, @@ -71,7 +71,7 @@ fn main() { signer .generate_signature_headers_content( &mut headers, - Duration::seconds(10), + Duration::from_secs(10), Algorithm::Ed25519, &private_key, ) diff --git a/examples/signature-agent-card-and-registry/src/lib.rs b/examples/signature-agent-card-and-registry/src/lib.rs index 38050ae..e3a3216 100644 --- a/examples/signature-agent-card-and-registry/src/lib.rs +++ b/examples/signature-agent-card-and-registry/src/lib.rs @@ -4,7 +4,7 @@ use indexmap::map::IndexMap; use rand::RngCore; use serde::{Deserialize, Serialize}; use sha2::{Digest, Sha256}; -use time::Duration; +use std::time::Duration; use web_bot_auth::{ components::{CoveredComponent, DerivedComponent, HTTPField, HTTPFieldParametersSet}, keyring::{Algorithm, Thumbprintable}, @@ -167,7 +167,7 @@ async fn fetch(req: HttpRequest, env: Env, _ctx: Context) -> Result { signer .generate_signature_headers_content( &mut generator, - Duration::seconds(10), + Duration::from_secs(10), Algorithm::Ed25519, signing_key.as_bytes(), )