Loading tor-circmgr/src/lib.rs +4 −1 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ use tor_netdir::{fallback::FallbackDir, NetDir}; use tor_proto::circuit::{CircParameters, ClientCirc, UniqId}; use tor_rtcompat::Runtime; use log::warn; use std::sync::Arc; use std::time::Duration; Loading Loading @@ -109,7 +110,9 @@ impl<'a> DirInfo<'a> { /// code. fn from_netparams(inp: &NetParameters) -> CircParameters { let mut p = CircParameters::default(); p.set_initial_send_window(inp.circuit_window.get() as u16); if let Err(e) = p.set_initial_send_window(inp.circuit_window.get() as u16) { warn!("Invalid parameter in directory: {}", e); } p.set_extend_by_ed25519_id(inp.extend_by_ed25519_id.into()); p } Loading tor-proto/src/channel.rs +18 −5 Original line number Diff line number Diff line Loading @@ -252,21 +252,26 @@ impl Channel { &self.ed25519_id } /// Return the (legacy) RSA identity for the peer of this channel. pub fn peer_rsa_id(&self) -> &RsaIdentity { &self.rsa_id } /// Return an error if this channel is somehow mismatched with the /// given target. pub fn check_match<T: ChanTarget + ?Sized>(&self, target: &T) -> Result<()> { if &self.ed25519_id != target.ed_identity() { if self.peer_ed25519_id() != target.ed_identity() { return Err(Error::ChanMismatch(format!( "Identity {} does not match target {}", self.ed25519_id, self.peer_ed25519_id(), target.ed_identity() ))); } if &self.rsa_id != target.rsa_identity() { if self.peer_rsa_id() != target.rsa_identity() { return Err(Error::ChanMismatch(format!( "Identity {} does not match target {}", self.rsa_id, self.peer_rsa_id(), target.rsa_identity() ))); } Loading @@ -279,7 +284,8 @@ impl Channel { self.closed.load(Ordering::SeqCst) } /// Check whether a cell type is acceptable on an open client channel. /// Check whether a cell type is permissible to be _sent_ on an /// open client channel. fn check_cell(&self, cell: &ChanCell) -> Result<()> { use msg::ChanMsg::*; let msg = cell.msg(); Loading Loading @@ -569,4 +575,11 @@ pub(crate) mod test { assert!(chan.check_match(&t2).is_err()); assert!(chan.check_match(&t3).is_err()); } #[test] fn unique_id() { let (ch1, _handle1) = fake_channel(); let (ch2, _handle2) = fake_channel(); assert!(ch1.unique_id() != ch2.unique_id()); } } tor-proto/src/circuit.rs +23 −4 Original line number Diff line number Diff line Loading @@ -75,7 +75,7 @@ use std::sync::Arc; use rand::{thread_rng, CryptoRng, Rng}; use log::{debug, trace, warn}; use log::{debug, trace}; /// A circuit that we have constructed over the Tor network. pub struct ClientCirc { Loading Loading @@ -131,14 +131,17 @@ impl Default for CircParameters { impl CircParameters { /// Override the default initial send window for these parameters. /// Ignores any value over 1000. /// Gives an error on any value above 1000. /// /// You should probably not call this. pub fn set_initial_send_window(&mut self, v: u16) { pub fn set_initial_send_window(&mut self, v: u16) -> Result<()> { if v <= 1000 { self.initial_send_window = v; Ok(()) } else { warn!("internal error: bad value {}", v); Err(Error::BadConfig( "Tried to set an initial send window over 1000".into(), )) } } /// Override the default decision about whether to use ed25519 Loading Loading @@ -1787,4 +1790,20 @@ mod test { // TODO: check that the circuit is shut down too } #[test] fn basic_params() { use super::CircParameters; let mut p = CircParameters::default(); assert_eq!(p.initial_send_window, 1000); assert!(p.extend_by_ed25519_id); assert!(p.set_initial_send_window(500).is_ok()); p.set_extend_by_ed25519_id(false); assert_eq!(p.initial_send_window, 500); assert!(!p.extend_by_ed25519_id); assert!(p.set_initial_send_window(9000).is_err()); assert_eq!(p.initial_send_window, 500); } } tor-proto/src/crypto/cell.rs +18 −1 Original line number Diff line number Diff line Loading @@ -427,6 +427,9 @@ mod test { let pair = Tor1RelayCrypto::construct(KGen::new(seed3.clone().into())).unwrap(); add_layers(&mut cc_out, &mut cc_in, pair); assert_eq!(cc_in.n_layers(), 3); assert_eq!(cc_out.n_layers(), 3); let mut r1 = Tor1RelayCrypto::construct(KGen::new(seed1.into())).unwrap(); let mut r2 = Tor1RelayCrypto::construct(KGen::new(seed2.into())).unwrap(); let mut r3 = Tor1RelayCrypto::construct(KGen::new(seed3.into())).unwrap(); Loading @@ -439,7 +442,7 @@ mod test { rng.fill_bytes(&mut cell_orig[..]); (&mut cell).copy_from_slice(&cell_orig[..]); let mut cell = cell.into(); let _tag = cc_out.encrypt(&mut cell, 2.into()); let _tag = cc_out.encrypt(&mut cell, 2.into()).unwrap(); assert_ne!(&cell.as_ref()[9..], &cell_orig.as_ref()[9..]); assert_eq!(false, r1.decrypt_outbound(&mut cell)); assert_eq!(false, r2.decrypt_outbound(&mut cell)); Loading @@ -464,6 +467,20 @@ mod test { // TODO: Test tag somehow. } // Try a failure: sending a cell to a nonexistent hop. { let mut cell = [0_u8; 509].into(); let err = cc_out.encrypt(&mut cell, 10.into()); assert!(matches!(err, Err(Error::NoSuchHop))); } // Try a failure: A junk cell with no correct auth from any layer. { let mut cell = [0_u8; 509].into(); let err = cc_in.decrypt(&mut cell); assert!(matches!(err, Err(Error::BadCellAuth))); } } // From tor's test_relaycrypt.c Loading tor-proto/src/util/err.rs +4 −1 Original line number Diff line number Diff line Loading @@ -76,6 +76,9 @@ pub enum Error { /// Channel does not match target #[error("channel mismatch: {0}")] ChanMismatch(String), /// Tried to configure an impossible value #[error("bad configuration value: {0}")] BadConfig(String), } impl From<tor_cell::Error> for Error { Loading Loading @@ -114,7 +117,7 @@ impl From<Error> for std::io::Error { BytesErr(_) | MissingKey | BadCellAuth | BadHandshake | ChanProto(_) | CircProto(_) | CellErr(_) | ChanMismatch(_) | StreamProto(_) => ErrorKind::InvalidData, InternalError(_) | IdRangeFull | CircExtend(_) => ErrorKind::Other, InternalError(_) | IdRangeFull | CircExtend(_) | BadConfig(_) => ErrorKind::Other, }; std::io::Error::new(kind, err) } Loading Loading
tor-circmgr/src/lib.rs +4 −1 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ use tor_netdir::{fallback::FallbackDir, NetDir}; use tor_proto::circuit::{CircParameters, ClientCirc, UniqId}; use tor_rtcompat::Runtime; use log::warn; use std::sync::Arc; use std::time::Duration; Loading Loading @@ -109,7 +110,9 @@ impl<'a> DirInfo<'a> { /// code. fn from_netparams(inp: &NetParameters) -> CircParameters { let mut p = CircParameters::default(); p.set_initial_send_window(inp.circuit_window.get() as u16); if let Err(e) = p.set_initial_send_window(inp.circuit_window.get() as u16) { warn!("Invalid parameter in directory: {}", e); } p.set_extend_by_ed25519_id(inp.extend_by_ed25519_id.into()); p } Loading
tor-proto/src/channel.rs +18 −5 Original line number Diff line number Diff line Loading @@ -252,21 +252,26 @@ impl Channel { &self.ed25519_id } /// Return the (legacy) RSA identity for the peer of this channel. pub fn peer_rsa_id(&self) -> &RsaIdentity { &self.rsa_id } /// Return an error if this channel is somehow mismatched with the /// given target. pub fn check_match<T: ChanTarget + ?Sized>(&self, target: &T) -> Result<()> { if &self.ed25519_id != target.ed_identity() { if self.peer_ed25519_id() != target.ed_identity() { return Err(Error::ChanMismatch(format!( "Identity {} does not match target {}", self.ed25519_id, self.peer_ed25519_id(), target.ed_identity() ))); } if &self.rsa_id != target.rsa_identity() { if self.peer_rsa_id() != target.rsa_identity() { return Err(Error::ChanMismatch(format!( "Identity {} does not match target {}", self.rsa_id, self.peer_rsa_id(), target.rsa_identity() ))); } Loading @@ -279,7 +284,8 @@ impl Channel { self.closed.load(Ordering::SeqCst) } /// Check whether a cell type is acceptable on an open client channel. /// Check whether a cell type is permissible to be _sent_ on an /// open client channel. fn check_cell(&self, cell: &ChanCell) -> Result<()> { use msg::ChanMsg::*; let msg = cell.msg(); Loading Loading @@ -569,4 +575,11 @@ pub(crate) mod test { assert!(chan.check_match(&t2).is_err()); assert!(chan.check_match(&t3).is_err()); } #[test] fn unique_id() { let (ch1, _handle1) = fake_channel(); let (ch2, _handle2) = fake_channel(); assert!(ch1.unique_id() != ch2.unique_id()); } }
tor-proto/src/circuit.rs +23 −4 Original line number Diff line number Diff line Loading @@ -75,7 +75,7 @@ use std::sync::Arc; use rand::{thread_rng, CryptoRng, Rng}; use log::{debug, trace, warn}; use log::{debug, trace}; /// A circuit that we have constructed over the Tor network. pub struct ClientCirc { Loading Loading @@ -131,14 +131,17 @@ impl Default for CircParameters { impl CircParameters { /// Override the default initial send window for these parameters. /// Ignores any value over 1000. /// Gives an error on any value above 1000. /// /// You should probably not call this. pub fn set_initial_send_window(&mut self, v: u16) { pub fn set_initial_send_window(&mut self, v: u16) -> Result<()> { if v <= 1000 { self.initial_send_window = v; Ok(()) } else { warn!("internal error: bad value {}", v); Err(Error::BadConfig( "Tried to set an initial send window over 1000".into(), )) } } /// Override the default decision about whether to use ed25519 Loading Loading @@ -1787,4 +1790,20 @@ mod test { // TODO: check that the circuit is shut down too } #[test] fn basic_params() { use super::CircParameters; let mut p = CircParameters::default(); assert_eq!(p.initial_send_window, 1000); assert!(p.extend_by_ed25519_id); assert!(p.set_initial_send_window(500).is_ok()); p.set_extend_by_ed25519_id(false); assert_eq!(p.initial_send_window, 500); assert!(!p.extend_by_ed25519_id); assert!(p.set_initial_send_window(9000).is_err()); assert_eq!(p.initial_send_window, 500); } }
tor-proto/src/crypto/cell.rs +18 −1 Original line number Diff line number Diff line Loading @@ -427,6 +427,9 @@ mod test { let pair = Tor1RelayCrypto::construct(KGen::new(seed3.clone().into())).unwrap(); add_layers(&mut cc_out, &mut cc_in, pair); assert_eq!(cc_in.n_layers(), 3); assert_eq!(cc_out.n_layers(), 3); let mut r1 = Tor1RelayCrypto::construct(KGen::new(seed1.into())).unwrap(); let mut r2 = Tor1RelayCrypto::construct(KGen::new(seed2.into())).unwrap(); let mut r3 = Tor1RelayCrypto::construct(KGen::new(seed3.into())).unwrap(); Loading @@ -439,7 +442,7 @@ mod test { rng.fill_bytes(&mut cell_orig[..]); (&mut cell).copy_from_slice(&cell_orig[..]); let mut cell = cell.into(); let _tag = cc_out.encrypt(&mut cell, 2.into()); let _tag = cc_out.encrypt(&mut cell, 2.into()).unwrap(); assert_ne!(&cell.as_ref()[9..], &cell_orig.as_ref()[9..]); assert_eq!(false, r1.decrypt_outbound(&mut cell)); assert_eq!(false, r2.decrypt_outbound(&mut cell)); Loading @@ -464,6 +467,20 @@ mod test { // TODO: Test tag somehow. } // Try a failure: sending a cell to a nonexistent hop. { let mut cell = [0_u8; 509].into(); let err = cc_out.encrypt(&mut cell, 10.into()); assert!(matches!(err, Err(Error::NoSuchHop))); } // Try a failure: A junk cell with no correct auth from any layer. { let mut cell = [0_u8; 509].into(); let err = cc_in.decrypt(&mut cell); assert!(matches!(err, Err(Error::BadCellAuth))); } } // From tor's test_relaycrypt.c Loading
tor-proto/src/util/err.rs +4 −1 Original line number Diff line number Diff line Loading @@ -76,6 +76,9 @@ pub enum Error { /// Channel does not match target #[error("channel mismatch: {0}")] ChanMismatch(String), /// Tried to configure an impossible value #[error("bad configuration value: {0}")] BadConfig(String), } impl From<tor_cell::Error> for Error { Loading Loading @@ -114,7 +117,7 @@ impl From<Error> for std::io::Error { BytesErr(_) | MissingKey | BadCellAuth | BadHandshake | ChanProto(_) | CircProto(_) | CellErr(_) | ChanMismatch(_) | StreamProto(_) => ErrorKind::InvalidData, InternalError(_) | IdRangeFull | CircExtend(_) => ErrorKind::Other, InternalError(_) | IdRangeFull | CircExtend(_) | BadConfig(_) => ErrorKind::Other, }; std::io::Error::new(kind, err) } Loading