use super::*;
ns_do_variety_vote! {}
const NETSTATUS_DOCTYPE_FOR_ERROR: &str = "network status vote";
pub type VarietyKeyword = NoMoreArguments;
impl NetworkStatusUnverified {
pub fn verify(
self,
trusted: &[RsaIdentity],
) -> Result<TimerangeBound<NetworkStatus>, VoteVerifyFailed> {
use VoteVerifyFailed as VVF;
let (mut body, sigs) = self.unwrap_unverified();
let authcert = {
let input = parse2::ParseInput::new(
body.authority.cert.raw_unverified().as_ref(),
"<authcert>",
);
let authcert = parse2::parse_netdoc::<AuthCertUnverified>(&input)
.map_err(VVF::AuthCertParseError)?;
let authcert = authcert.verify(trusted).map_err(VVF::InvalidSignature)?;
let test_validity_at = |t| authcert.is_valid_at(&t).map_err(VVF::AuthCertWrongValidity);
test_validity_at(*body.preamble.lifetime.valid_after)?;
test_validity_at(*body.preamble.lifetime.fresh_until)?;
test_validity_at(*body.preamble.lifetime.valid_until)?;
authcert.dangerously_assume_timely() };
if body.authority.authority.dir_source.identity != authcert.fingerprint {
return Err(VVF::AuthCertWrongAuthority);
}
SignatureGroup {
hashes: sigs.hashes,
signatures: vec![sigs.sigs.directory_signature],
}
.verify_general(
VerifyGeneralTrustedAuthorities::AnyOneOfThese { trusted },
slice::from_ref(&authcert),
|tv| tv.verify().map_err(VVF::InvalidSignature),
)?;
body.authority.cert.set_verified(authcert);
let time_range = body.preamble.validity_time_range();
Ok(TimerangeBound::new(body, time_range))
}
pub fn peek_alleged_authority(&self) -> RsaIdentity {
*self
.inspect_unverified()
.0
.authority
.authority
.dir_source
.identity
}
}
impl From<ConsensusVerifiabilityError> for VoteVerifyFailed {
fn from(cve: ConsensusVerifiabilityError) -> VoteVerifyFailed {
use ConsensusVerifiabilityError as CVE;
use VerifyFailed as VF;
use VoteVerifyFailed as VVF;
match cve {
CVE::InsufficientTrustedSigners => {
VVF::InvalidSignature(VF::InsufficientTrustedSigners)
}
CVE::MissingAuthCerts { .. } => {
VVF::AuthCertWrongAuthority
}
}
}
}