Skip to main content

obfs4/
lib.rs

1#![deny(missing_docs)]
2#![doc = include_str!("../README.md")]
3
4/// obfs4 client types.
5pub mod client;
6// Internal cryptographic primitives. Kept `pub` only so the crate's own
7// benches and integration tests can reach them; not part of the stable API.
8#[doc(hidden)]
9pub mod common;
10/// obfs4 server types.
11pub mod server;
12
13// Internal framing codec and message types. Kept `pub` only for the crate's
14// own benches and integration tests; not part of the stable API.
15#[doc(hidden)]
16pub mod framing;
17// Internal stream and timeout machinery. The public-facing types it defines
18// (`Obfs4Stream`, `IAT`) are re-exported from the crate root below; the module
19// itself stays `pub` only so benches/tests can address it by path.
20#[doc(hidden)]
21pub mod proto;
22pub use client::{Client, ClientBuilder};
23pub use proto::{Obfs4Stream, IAT};
24pub use server::{Server, ServerBuilder};
25
26pub(crate) mod constants;
27pub(crate) mod handshake;
28pub(crate) mod sessions;
29
30#[cfg(test)]
31mod testing;
32
33mod pt;
34pub use pt::{Obfs4PT, Transport};
35
36mod error;
37pub use error::{Error, Result};
38
39/// The transport name string.
40pub const OBFS4_NAME: &str = "obfs4";
41
42#[cfg(test)]
43pub(crate) mod test_utils;
44
45// Pre-generated key material and argument strings for the crate's own tests.
46// Gated to `test` so these never enter the published API or release binaries.
47#[cfg(test)]
48#[allow(missing_docs)]
49pub(crate) mod dev {
50    /// Pre-generated / shared key for use while running in debug mode.
51    pub const DEV_PRIV_KEY: &[u8; 32] = b"0123456789abcdeffedcba9876543210";
52
53    /// Client obfs4 arguments based on pre-generated dev key `DEV_PRIV_KEY`.
54    pub const CLIENT_ARGS: &str =
55        "cert=AAAAAAAAAAAAAAAAAAAAAAAAAADTSFvsGKxNFPBcGdOCBSgpEtJInG9zCYZezBPVBuBWag;iat-mode=0";
56
57    /// Server obfs4 arguments based on pre-generated dev key `DEV_PRIV_KEY`.
58    pub const SERVER_ARGS: &str = "drbg-seed=0a0b0c0d0e0f0a0b0c0d0e0f0a0b0c0d0e0f0a0b0c0d0e0f;node-id=0000000000000000000000000000000000000000;private-key=3031323334353637383961626364656666656463626139383736353433323130;iat-mode=0";
59
60    #[cfg(test)]
61    mod test {
62        use super::*;
63        use crate::common::x25519_elligator2::StaticSecret;
64        use crate::constants::*;
65        use crate::handshake::Obfs4NtorSecretKey;
66        use crate::{ClientBuilder, ServerBuilder};
67        use ptrs::ServerBuilder as _;
68
69        use ptrs::args::Args;
70        use ptrs::trace;
71        use tokio::net::TcpStream;
72        use tor_llcrypto::pk::rsa::RsaIdentity;
73
74        pub fn trace_print_dev_args() {
75            let static_secret = StaticSecret::from(*DEV_PRIV_KEY);
76            let sk =
77                Obfs4NtorSecretKey::new(static_secret, RsaIdentity::from([0u8; NODE_ID_LENGTH]));
78            let mut client_args = Args::new();
79            client_args.insert(CERT_ARG.into(), vec![sk.pk.to_string()]);
80            client_args.insert(IAT_ARG.into(), vec!["0".into()]);
81            trace!("{}", client_args.encode_smethod_args());
82        }
83
84        #[test]
85        fn test_parse() {
86            trace_print_dev_args();
87
88            let args = Args::parse_client_parameters(CLIENT_ARGS).unwrap();
89            let mut builder = ClientBuilder::default();
90            <ClientBuilder as ptrs::ClientBuilder<TcpStream>>::options(&mut builder, &args)
91                .unwrap();
92
93            let server_params = Args::parse_client_parameters(SERVER_ARGS).unwrap();
94            let mut server_builder = ServerBuilder::<TcpStream>::default();
95            server_builder.options(&server_params).unwrap();
96        }
97    }
98}