tor-netdoc: extract fingerprint logic from routerdesc.rs
This commit is contained in:
parent
84fd65fb85
commit
8f20c273cf
|
@ -8,6 +8,7 @@
|
|||
pub use b64impl::*;
|
||||
pub use curve25519impl::*;
|
||||
pub use edcert::*;
|
||||
pub use fingerprint::*;
|
||||
pub use rsa::*;
|
||||
pub use timeimpl::*;
|
||||
|
||||
|
@ -200,3 +201,55 @@ mod edcert {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod fingerprint {
|
||||
use crate::{Error, Pos, Result};
|
||||
use tor_llcrypto::pk::rsa::RSAIdentity;
|
||||
|
||||
// A hex-encoded fingerprint with spaces in it.
|
||||
pub struct SpFingerprint(RSAIdentity);
|
||||
|
||||
// A "long identity" in the format used for Family members.
|
||||
pub struct LongIdent(RSAIdentity);
|
||||
|
||||
impl From<SpFingerprint> for RSAIdentity {
|
||||
fn from(f: SpFingerprint) -> RSAIdentity {
|
||||
f.0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<LongIdent> for RSAIdentity {
|
||||
fn from(f: LongIdent) -> RSAIdentity {
|
||||
f.0
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_hex_ident(s: &str) -> Result<RSAIdentity> {
|
||||
let bytes = hex::decode(s)
|
||||
.map_err(|_| Error::BadArgument(Pos::at(s), "invalid hexadecimal in family".into()))?;
|
||||
RSAIdentity::from_bytes(&bytes)
|
||||
.ok_or_else(|| Error::BadArgument(Pos::at(s), "wrong length on fingerprint".into()))
|
||||
}
|
||||
|
||||
impl std::str::FromStr for SpFingerprint {
|
||||
type Err = Error;
|
||||
fn from_str(s: &str) -> Result<SpFingerprint> {
|
||||
let ident = parse_hex_ident(&s.replace(' ', "")).map_err(|e| e.at_pos(Pos::at(s)))?;
|
||||
Ok(SpFingerprint(ident))
|
||||
}
|
||||
}
|
||||
|
||||
impl std::str::FromStr for LongIdent {
|
||||
type Err = Error;
|
||||
fn from_str(mut s: &str) -> Result<LongIdent> {
|
||||
if s.starts_with('$') {
|
||||
s = &s[1..];
|
||||
}
|
||||
if let Some(idx) = s.find(|ch| ch == '=' || ch == '~') {
|
||||
s = &s[..idx];
|
||||
}
|
||||
let ident = parse_hex_ident(s)?;
|
||||
Ok(LongIdent(ident))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ use crate::parse::{Section, SectionRules};
|
|||
use crate::policy::*;
|
||||
use crate::rules::Keyword;
|
||||
use crate::version::TorVersion;
|
||||
use crate::{Error, Pos, Result};
|
||||
use crate::{Error, Result};
|
||||
|
||||
use lazy_static::lazy_static;
|
||||
use std::{net, time};
|
||||
|
@ -99,26 +99,12 @@ impl std::str::FromStr for RelayFamily {
|
|||
fn from_str(s: &str) -> Result<Self> {
|
||||
let v: Result<Vec<RSAIdentity>> = s
|
||||
.split(crate::tokenize::is_sp)
|
||||
.map(parse_family_ent)
|
||||
.map(|e| e.parse::<LongIdent>().map(|v| v.into()))
|
||||
.collect();
|
||||
Ok(RelayFamily(v?))
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse a single family entry from a string.
|
||||
fn parse_family_ent(mut s: &str) -> Result<RSAIdentity> {
|
||||
if s.starts_with('$') {
|
||||
s = &s[1..];
|
||||
}
|
||||
if let Some(idx) = s.find(|ch| ch == '=' || ch == '~') {
|
||||
s = &s[..idx];
|
||||
}
|
||||
let bytes = hex::decode(s)
|
||||
.map_err(|_| Error::BadArgument(Pos::at(s), "invalid hexadecimal in family".into()))?;
|
||||
RSAIdentity::from_bytes(&bytes)
|
||||
.ok_or_else(|| Error::BadArgument(Pos::at(s), "wrong length on fingerprint".into()))
|
||||
}
|
||||
|
||||
/// Description of the software a relay is running.
|
||||
pub enum RelayPlatform {
|
||||
/// Software advertised to be some version of Tor, on some platform.
|
||||
|
@ -485,10 +471,8 @@ impl RouterDesc {
|
|||
|
||||
// fingerprint: check for consistency with RSA identity.
|
||||
if let Some(fp_tok) = body.get(FINGERPRINT) {
|
||||
let fp_val = fp_tok.args_as_str().replace(' ', "");
|
||||
let bytes = hex::decode(&fp_val)
|
||||
.map_err(|e| Error::BadArgument(fp_tok.pos(), e.to_string()))?;
|
||||
if bytes != rsa_identity.to_rsa_identity().as_bytes() {
|
||||
let fp: RSAIdentity = fp_tok.args_as_str().parse::<SpFingerprint>()?.into();
|
||||
if fp != rsa_identity.to_rsa_identity() {
|
||||
return Err(Error::BadArgument(
|
||||
fp_tok.pos(),
|
||||
"fingerprint does not match RSA identity".into(),
|
||||
|
|
Loading…
Reference in New Issue