From bb01a55a8c1b2792801ba48a5f79ae15b1164dd5 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Fri, 4 Dec 2020 13:17:24 -0500 Subject: [PATCH] authcert: move location into UncheckedAuthCert. This lets us make AuthCert Send and Sync. --- tor-netdoc/src/doc/authcert.rs | 61 ++++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 22 deletions(-) diff --git a/tor-netdoc/src/doc/authcert.rs b/tor-netdoc/src/doc/authcert.rs index 4f5ec984e..50a7ac5a0 100644 --- a/tor-netdoc/src/doc/authcert.rs +++ b/tor-netdoc/src/doc/authcert.rs @@ -70,11 +70,6 @@ lazy_static! { #[allow(dead_code)] #[derive(Clone, Debug)] pub struct AuthCert { - /// Where we found this AuthCert within the string containing it. - /// - /// (Perhaps this field should be within some other wrapper type?) - location: Option, - /// An IPv4 address for this authority. address: Option, /// The long-term RSA identity key for this authority @@ -115,7 +110,29 @@ impl PartialOrd for AuthCertKeyIds { /// An authority certificate whose signature and validity time we /// haven't checked. -pub type UncheckedAuthCert = signed::SignatureGated>; +pub struct UncheckedAuthCert { + /// Where we found this AuthCert within the string containing it. + location: Option, + + /// The actual unchecked certificate. + c: signed::SignatureGated>, +} + +impl UncheckedAuthCert { + /// If this AuthCert was originally parsed from `haystack`, return its + /// text. + /// + /// TODO: This is a pretty bogus interface; there should be a + /// better way to remember where to look for this thing if we want + /// it without keeping the input alive forever. We should + /// refactor. + pub fn within<'a>(&self, haystack: &'a str) -> Option<&'a str> { + self.location + .as_ref() + .map(|ext| ext.reconstruct(haystack)) + .flatten() + } +} impl AuthCert { /// Parse an authority certificate from a string. @@ -171,20 +188,6 @@ impl AuthCert { self.expires } - /// If this AuthCert was originally parsed from `haystack`, return its - /// text. - /// - /// TODO: This is a pretty bogus interface; there should be a - /// better way to remember where to look for this thing if we want - /// it without keeping the input alive forever. We should - /// refactor. - pub fn within<'a>(&self, haystack: &'a str) -> Option<&'a str> { - self.location - .as_ref() - .map(|ext| ext.reconstruct(haystack)) - .flatten() - } - /// Parse an authority certificate from a reader. fn take_from_reader(reader: &mut NetDocReader<'_, AuthCertKW>) -> Result { use AuthCertKW::*; @@ -325,7 +328,6 @@ impl AuthCert { }; let authcert = AuthCert { - location, address, identity_key, signing_key, @@ -340,7 +342,11 @@ impl AuthCert { let timed = timed::TimerangeBound::new(authcert, published..expires); let signed = signed::SignatureGated::new(timed, signatures); - Ok(signed) + let unchecked = UncheckedAuthCert { + location, + c: signed, + }; + Ok(unchecked) } /// Skip tokens from the reader until the next token (if any) is @@ -361,6 +367,17 @@ impl AuthCert { /// string. struct AuthCertIterator<'a>(NetDocReader<'a, AuthCertKW>); +impl tor_checkable::SelfSigned> for UncheckedAuthCert { + type Error = signature::Error; + + fn dangerously_assume_wellsigned(self) -> timed::TimerangeBound { + self.c.dangerously_assume_wellsigned() + } + fn is_well_signed(&self) -> std::result::Result<(), Self::Error> { + self.c.is_well_signed() + } +} + impl<'a> Iterator for AuthCertIterator<'a> { type Item = Result; fn next(&mut self) -> Option> {