hsdesc: Use an IntegerMinutes<u16> to hold lifetime.

This commit is contained in:
Nick Mathewson 2023-02-08 13:33:07 -05:00
parent 39f5f90f3f
commit 0a80c468df
4 changed files with 21 additions and 10 deletions

1
Cargo.lock generated
View File

@ -4100,6 +4100,7 @@ dependencies = [
"tor-linkspec", "tor-linkspec",
"tor-llcrypto", "tor-llcrypto",
"tor-protover", "tor-protover",
"tor-units",
"visibility", "visibility",
"visible", "visible",
"weak-table", "weak-table",

View File

@ -32,7 +32,7 @@ ns_consensus = []
# TODO hs: mark these as part of "full" once they are done and stable. # TODO hs: mark these as part of "full" once they are done and stable.
onion-client = ["onion-common"] onion-client = ["onion-common"]
onion-service = ["onion-common", "rand"] 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. # 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-linkspec = { path = "../tor-linkspec", version = "0.6.0", optional = true }
tor-llcrypto = { path = "../tor-llcrypto", version = "0.4.1" } tor-llcrypto = { path = "../tor-llcrypto", version = "0.4.1" }
tor-protover = { path = "../tor-protover", version = "0.4.0" } 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 } visibility = { version = "0.0.1", optional = true }
visible = { version = "0.0.1", optional = true } visible = { version = "0.0.1", optional = true }
weak-table = "0.3.0" weak-table = "0.3.0"

View File

@ -30,6 +30,7 @@ use tor_hscrypto::{
}; };
use tor_linkspec::LinkSpec; use tor_linkspec::LinkSpec;
use tor_llcrypto::pk::curve25519; use tor_llcrypto::pk::curve25519;
use tor_units::IntegerMinutes;
/// Metadata about an onion service descriptor, as stored at an HsDir. /// Metadata about an onion service descriptor, as stored at an HsDir.
/// ///
@ -60,7 +61,7 @@ pub type UncheckedStoredHsDescMeta =
struct IndexInfo { struct IndexInfo {
/// The lifetime in minutes that this descriptor should be held after it is /// The lifetime in minutes that this descriptor should be held after it is
/// received. /// received.
lifetime_minutes: u16, lifetime: IntegerMinutes<u16>,
/// The expiration time on the `descriptor-signing-key-cert` included in this /// The expiration time on the `descriptor-signing-key-cert` included in this
/// descriptor. /// descriptor.
signing_cert_expires: SystemTime, signing_cert_expires: SystemTime,
@ -275,7 +276,7 @@ impl IndexInfo {
/// Create a new `IndexInfo` from the outer part of an onion service descriptor. /// Create a new `IndexInfo` from the outer part of an onion service descriptor.
fn from_outer_doc(outer: &outer::HsDescOuter) -> Self { fn from_outer_doc(outer: &outer::HsDescOuter) -> Self {
IndexInfo { IndexInfo {
lifetime_minutes: outer.lifetime_minutes, lifetime: outer.lifetime,
signing_cert_expires: outer.desc_signing_key_cert.expiry(), signing_cert_expires: outer.desc_signing_key_cert.expiry(),
revision: outer.revision_counter, revision: outer.revision_counter,
} }
@ -311,6 +312,8 @@ mod test {
#![allow(clippy::unwrap_used)] #![allow(clippy::unwrap_used)]
#![allow(clippy::unchecked_duration_subtraction)] #![allow(clippy::unchecked_duration_subtraction)]
//! <!-- @@ end test lint list maintained by maint/add_warning @@ --> //! <!-- @@ end test lint list maintained by maint/add_warning @@ -->
use std::time::Duration;
use super::*; use super::*;
use hex_literal::hex; use hex_literal::hex;
use tor_checkable::{SelfSigned, Timebound}; use tor_checkable::{SelfSigned, Timebound};
@ -330,7 +333,10 @@ mod test {
meta.blinded_id.as_ref(), meta.blinded_id.as_ref(),
&hex!("43cc0d62fc6252f578705ca645a46109e265290343b1137e90189744b20b3f2d") &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!( assert_eq!(
meta.idx_info.signing_cert_expires, meta.idx_info.signing_cert_expires,
humantime::parse_rfc3339("2023-01-26T03:00:00Z").unwrap() humantime::parse_rfc3339("2023-01-26T03:00:00Z").unwrap()
@ -353,7 +359,10 @@ mod test {
.unwrap() .unwrap()
.decrypt(&TEST_SUBCREDENTIAL.into(), None)?; .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!( assert_eq!(
desc.idx_info.signing_cert_expires, desc.idx_info.signing_cert_expires,
humantime::parse_rfc3339("2023-01-26T03:00:00Z").unwrap() humantime::parse_rfc3339("2023-01-26T03:00:00Z").unwrap()

View File

@ -8,6 +8,7 @@ use tor_checkable::Timebound;
use tor_hscrypto::pk::HsBlindId; use tor_hscrypto::pk::HsBlindId;
use tor_hscrypto::{RevisionCounter, Subcredential}; use tor_hscrypto::{RevisionCounter, Subcredential};
use tor_llcrypto::pk::ed25519::{self, ValidatableEd25519Signature}; use tor_llcrypto::pk::ed25519::{self, ValidatableEd25519Signature};
use tor_units::IntegerMinutes;
use crate::parse::{keyword::Keyword, parser::SectionRules, tokenize::NetDocReader}; use crate::parse::{keyword::Keyword, parser::SectionRules, tokenize::NetDocReader};
use crate::types::misc::{UnvalidatedEdCert, B64}; 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 /// 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 /// descriptor: presumably, because we didn't want to leak the onion
/// service's view of the wallclock. /// service's view of the wallclock.
// TODO HS: Use IntegerMinutes, and rename to `Lifetime`. pub(super) lifetime: IntegerMinutes<u16>,
pub(super) lifetime_minutes: u16,
/// A certificate containing the descriptor-signing-key for this onion /// A certificate containing the descriptor-signing-key for this onion
/// service (`KP_hs_desc_sign`) signed by the blinded ed25519 identity /// service (`KP_hs_desc_sign`) signed by the blinded ed25519 identity
/// (`HS_blind_id`) for this onion service. /// (`HS_blind_id`) for this onion service.
@ -185,7 +185,7 @@ impl HsDescOuter {
} }
// Parse `descryptor-lifetime`. // Parse `descryptor-lifetime`.
let lifetime_minutes = { let lifetime: IntegerMinutes<u16> = {
let tok = body.required(DESCRIPTOR_LIFETIME)?; let tok = body.required(DESCRIPTOR_LIFETIME)?;
let lifetime_minutes: u16 = tok.parse_arg(0)?; let lifetime_minutes: u16 = tok.parse_arg(0)?;
if !(30..=720).contains(&lifetime_minutes) { if !(30..=720).contains(&lifetime_minutes) {
@ -193,7 +193,7 @@ impl HsDescOuter {
.with_msg(format!("Invalid HsDesc lifetime {}", lifetime_minutes)) .with_msg(format!("Invalid HsDesc lifetime {}", lifetime_minutes))
.at_pos(tok.pos())); .at_pos(tok.pos()));
} }
lifetime_minutes lifetime_minutes.into()
}; };
// Parse `descriptor-signing-key-cert`. This certificate is signed with // Parse `descriptor-signing-key-cert`. This certificate is signed with
@ -249,7 +249,7 @@ impl HsDescOuter {
// Build our return value. // Build our return value.
let desc = HsDescOuter { let desc = HsDescOuter {
lifetime_minutes, lifetime,
desc_signing_key_cert, desc_signing_key_cert,
revision_counter, revision_counter,
superencrypted: encrypted_body, superencrypted: encrypted_body,