diff --git a/Cargo.lock b/Cargo.lock index d8342286d..60ba2f0b1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4100,6 +4100,7 @@ dependencies = [ "tor-linkspec", "tor-llcrypto", "tor-protover", + "tor-units", "visibility", "visible", "weak-table", diff --git a/crates/tor-netdoc/Cargo.toml b/crates/tor-netdoc/Cargo.toml index ac77fd2d4..f361e49d2 100644 --- a/crates/tor-netdoc/Cargo.toml +++ b/crates/tor-netdoc/Cargo.toml @@ -32,7 +32,7 @@ ns_consensus = [] # TODO hs: mark these as part of "full" once they are done and stable. onion-client = ["onion-common"] onion-service = ["onion-common", "rand"] -onion-common = ["tor-hscrypto", "tor-linkspec"] +onion-common = ["tor-hscrypto", "tor-linkspec", "tor-units"] # Enable experimental APIs that are not yet officially supported. # @@ -80,6 +80,7 @@ tor-hscrypto = { path = "../tor-hscrypto", version = "0.1.0", optional = true } tor-linkspec = { path = "../tor-linkspec", version = "0.6.0", optional = true } tor-llcrypto = { path = "../tor-llcrypto", version = "0.4.1" } tor-protover = { path = "../tor-protover", version = "0.4.0" } +tor-units = { version = "0.4.1", path = "../tor-units", optional = true } visibility = { version = "0.0.1", optional = true } visible = { version = "0.0.1", optional = true } weak-table = "0.3.0" diff --git a/crates/tor-netdoc/src/doc/hsdesc.rs b/crates/tor-netdoc/src/doc/hsdesc.rs index 5d9789c30..aaf572c84 100644 --- a/crates/tor-netdoc/src/doc/hsdesc.rs +++ b/crates/tor-netdoc/src/doc/hsdesc.rs @@ -30,6 +30,7 @@ use tor_hscrypto::{ }; use tor_linkspec::LinkSpec; use tor_llcrypto::pk::curve25519; +use tor_units::IntegerMinutes; /// Metadata about an onion service descriptor, as stored at an HsDir. /// @@ -60,7 +61,7 @@ pub type UncheckedStoredHsDescMeta = struct IndexInfo { /// The lifetime in minutes that this descriptor should be held after it is /// received. - lifetime_minutes: u16, + lifetime: IntegerMinutes, /// The expiration time on the `descriptor-signing-key-cert` included in this /// descriptor. signing_cert_expires: SystemTime, @@ -275,7 +276,7 @@ impl IndexInfo { /// Create a new `IndexInfo` from the outer part of an onion service descriptor. fn from_outer_doc(outer: &outer::HsDescOuter) -> Self { IndexInfo { - lifetime_minutes: outer.lifetime_minutes, + lifetime: outer.lifetime, signing_cert_expires: outer.desc_signing_key_cert.expiry(), revision: outer.revision_counter, } @@ -311,6 +312,8 @@ mod test { #![allow(clippy::unwrap_used)] #![allow(clippy::unchecked_duration_subtraction)] //! + use std::time::Duration; + use super::*; use hex_literal::hex; use tor_checkable::{SelfSigned, Timebound}; @@ -330,7 +333,10 @@ mod test { meta.blinded_id.as_ref(), &hex!("43cc0d62fc6252f578705ca645a46109e265290343b1137e90189744b20b3f2d") ); - assert_eq!(meta.idx_info.lifetime_minutes, 180); + assert_eq!( + Duration::try_from(meta.idx_info.lifetime).unwrap(), + Duration::from_secs(60 * 180) + ); assert_eq!( meta.idx_info.signing_cert_expires, humantime::parse_rfc3339("2023-01-26T03:00:00Z").unwrap() @@ -353,7 +359,10 @@ mod test { .unwrap() .decrypt(&TEST_SUBCREDENTIAL.into(), None)?; - assert_eq!(desc.idx_info.lifetime_minutes, 180); + assert_eq!( + Duration::try_from(desc.idx_info.lifetime).unwrap(), + Duration::from_secs(60 * 180) + ); assert_eq!( desc.idx_info.signing_cert_expires, humantime::parse_rfc3339("2023-01-26T03:00:00Z").unwrap() diff --git a/crates/tor-netdoc/src/doc/hsdesc/outer.rs b/crates/tor-netdoc/src/doc/hsdesc/outer.rs index b0660e3c5..03a08328c 100644 --- a/crates/tor-netdoc/src/doc/hsdesc/outer.rs +++ b/crates/tor-netdoc/src/doc/hsdesc/outer.rs @@ -8,6 +8,7 @@ use tor_checkable::Timebound; use tor_hscrypto::pk::HsBlindId; use tor_hscrypto::{RevisionCounter, Subcredential}; use tor_llcrypto::pk::ed25519::{self, ValidatableEd25519Signature}; +use tor_units::IntegerMinutes; use crate::parse::{keyword::Keyword, parser::SectionRules, tokenize::NetDocReader}; use crate::types::misc::{UnvalidatedEdCert, B64}; @@ -24,8 +25,7 @@ pub(super) struct HsDescOuter { /// This doesn't actually list the starting time or the end time for the /// descriptor: presumably, because we didn't want to leak the onion /// service's view of the wallclock. - // TODO HS: Use IntegerMinutes, and rename to `Lifetime`. - pub(super) lifetime_minutes: u16, + pub(super) lifetime: IntegerMinutes, /// A certificate containing the descriptor-signing-key for this onion /// service (`KP_hs_desc_sign`) signed by the blinded ed25519 identity /// (`HS_blind_id`) for this onion service. @@ -185,7 +185,7 @@ impl HsDescOuter { } // Parse `descryptor-lifetime`. - let lifetime_minutes = { + let lifetime: IntegerMinutes = { let tok = body.required(DESCRIPTOR_LIFETIME)?; let lifetime_minutes: u16 = tok.parse_arg(0)?; if !(30..=720).contains(&lifetime_minutes) { @@ -193,7 +193,7 @@ impl HsDescOuter { .with_msg(format!("Invalid HsDesc lifetime {}", lifetime_minutes)) .at_pos(tok.pos())); } - lifetime_minutes + lifetime_minutes.into() }; // Parse `descriptor-signing-key-cert`. This certificate is signed with @@ -249,7 +249,7 @@ impl HsDescOuter { // Build our return value. let desc = HsDescOuter { - lifetime_minutes, + lifetime, desc_signing_key_cert, revision_counter, superencrypted: encrypted_body,