mirror of
https://github.com/tlsnotary/tlsn.git
synced 2026-01-09 21:38:00 -05:00
fix: clippy gh action and linting (#531)
* fix: miscellaneous fixes on documentation, notary-server. * Apply clippy fix. * Apply clippy fix. * Apply clippy fix. * Apply clippy fix. * Apply clippy fix. * Apply clippy fix. * Apply clippy fix. * Apply clippy fix. * Apply clippy fix. * Correct ci.yml and build script. * Apply clippy fix. * Apply fmt. * Correct clippy fix for tls-mpc. * Correct clippy fix for tls-client. * Correct clippy fix for tls-client. * Update ci and local build. * Revert "Merge branch 'fix/misc-fixes' into fix/gh-clippy-action" This reverts commit74bdb4a6f8, reversing changes made toe361a86e6a. * Apply clippy fix. * Correct spacing and extra changes. * Apply fmt. * Change cargo hack install logic. * Revert clippy change client buffer len. * Revert clippy ignore. * remove cargo hack, relax clippy lints * remove unused features and dead tests * appease clippy again * remove dead features --------- Co-authored-by: sinui0 <65924192+sinui0@users.noreply.github.com>
This commit is contained in:
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
@@ -29,8 +29,8 @@ jobs:
|
||||
- components/prf
|
||||
- components/tls
|
||||
- components/tls/tls-mpc
|
||||
- tlsn
|
||||
- notary
|
||||
- tlsn
|
||||
- tlsn/tests-integration
|
||||
include:
|
||||
- package: components/tls/tls-mpc
|
||||
@@ -66,7 +66,7 @@ jobs:
|
||||
components: clippy
|
||||
|
||||
- name: "Clippy"
|
||||
run: cargo clippy --all-features --examples -- -D warnings
|
||||
run: cargo clippy --all-features --all-targets -- -D warnings
|
||||
|
||||
- name: Use caching
|
||||
uses: Swatinem/rust-cache@v2.7.3
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
for package in components/uid-mux components/actors/actor-ot components/cipher components/universal-hash components/aead components/key-exchange components/point-addition components/prf components/tls tlsn; do
|
||||
for package in components/tls components/cipher components/universal-hash components/aead components/key-exchange components/prf tlsn notary; do
|
||||
pushd $package
|
||||
# cargo update
|
||||
cargo clean
|
||||
cargo build
|
||||
cargo test
|
||||
cargo clippy --all-features -- -D warnings || exit
|
||||
cargo build || exit
|
||||
cargo test || exit
|
||||
popd
|
||||
done
|
||||
|
||||
@@ -60,6 +60,7 @@ impl<Ctx: Context> MpcAesGcm<Ctx> {
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
#[allow(clippy::blocks_in_conditions)]
|
||||
impl<Ctx: Context> Aead for MpcAesGcm<Ctx> {
|
||||
type Error = AesGcmError;
|
||||
|
||||
|
||||
@@ -93,6 +93,7 @@ pub(crate) async fn compute_tag<
|
||||
/// Without it, the party which receives the other's tag share first could trivially compute
|
||||
/// a tag share which would cause an invalid message to be accepted.
|
||||
#[instrument(level = "debug", skip_all, err)]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(crate) async fn verify_tag<
|
||||
Ctx: Context,
|
||||
C: StreamCipher<Aes128Ctr> + ?Sized,
|
||||
|
||||
@@ -118,6 +118,7 @@ where
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
#[allow(clippy::blocks_in_conditions)]
|
||||
impl<C, E> BlockCipher<C> for MpcBlockCipher<C, E>
|
||||
where
|
||||
C: BlockCipherCircuit,
|
||||
@@ -138,7 +139,7 @@ where
|
||||
.state
|
||||
.key
|
||||
.clone()
|
||||
.ok_or_else(|| BlockCipherError::key_not_set())?;
|
||||
.ok_or_else(BlockCipherError::key_not_set)?;
|
||||
|
||||
for _ in 0..count {
|
||||
let vars = self.define_block(visibility);
|
||||
@@ -173,7 +174,7 @@ where
|
||||
.state
|
||||
.key
|
||||
.clone()
|
||||
.ok_or_else(|| BlockCipherError::key_not_set())?;
|
||||
.ok_or_else(BlockCipherError::key_not_set)?;
|
||||
|
||||
let BlockVars { msg, ciphertext } =
|
||||
if let Some(vars) = self.state.preprocessed_private.pop_front() {
|
||||
@@ -209,7 +210,7 @@ where
|
||||
.state
|
||||
.key
|
||||
.clone()
|
||||
.ok_or_else(|| BlockCipherError::key_not_set())?;
|
||||
.ok_or_else(BlockCipherError::key_not_set)?;
|
||||
|
||||
let BlockVars { msg, ciphertext } =
|
||||
if let Some(vars) = self.state.preprocessed_private.pop_front() {
|
||||
@@ -248,7 +249,7 @@ where
|
||||
.state
|
||||
.key
|
||||
.clone()
|
||||
.ok_or_else(|| BlockCipherError::key_not_set())?;
|
||||
.ok_or_else(BlockCipherError::key_not_set)?;
|
||||
|
||||
let BlockVars { msg, ciphertext } =
|
||||
if let Some(vars) = self.state.preprocessed_public.pop_front() {
|
||||
|
||||
@@ -55,10 +55,10 @@ pub(crate) enum ExecutionMode {
|
||||
}
|
||||
|
||||
pub(crate) fn is_valid_mode(mode: &ExecutionMode, input_text: &InputText) -> bool {
|
||||
match (mode, input_text) {
|
||||
(ExecutionMode::Mpc, _) => true,
|
||||
(ExecutionMode::Prove, InputText::Private { .. }) => true,
|
||||
(ExecutionMode::Verify, InputText::Blind { .. }) => true,
|
||||
_ => false,
|
||||
}
|
||||
matches!(
|
||||
(mode, input_text),
|
||||
(ExecutionMode::Mpc, _)
|
||||
| (ExecutionMode::Prove, InputText::Private { .. })
|
||||
| (ExecutionMode::Verify, InputText::Blind { .. })
|
||||
)
|
||||
}
|
||||
|
||||
@@ -58,8 +58,8 @@ impl BlockVars {
|
||||
self.blocks
|
||||
.iter()
|
||||
.flat_map(|block| block.iter())
|
||||
.cloned()
|
||||
.take(len)
|
||||
.cloned()
|
||||
.map(|byte| ValueRef::Value { id: byte })
|
||||
.collect()
|
||||
}
|
||||
@@ -132,6 +132,7 @@ impl<C: CtrCircuit> KeyStream<C> {
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip_all, err)]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(crate) async fn compute<T>(
|
||||
&mut self,
|
||||
thread: &mut T,
|
||||
|
||||
@@ -122,7 +122,7 @@ where
|
||||
.state
|
||||
.encoded_key_iv
|
||||
.as_ref()
|
||||
.ok_or_else(|| StreamCipherError::key_not_set())?;
|
||||
.ok_or_else(StreamCipherError::key_not_set)?;
|
||||
|
||||
let keystream = self
|
||||
.state
|
||||
@@ -260,6 +260,7 @@ where
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
#[allow(clippy::blocks_in_conditions)]
|
||||
impl<C, E> StreamCipher<C> for MpcStreamCipher<C, E>
|
||||
where
|
||||
C: CtrCircuit,
|
||||
@@ -275,7 +276,7 @@ where
|
||||
.state
|
||||
.encoded_key_iv
|
||||
.clone()
|
||||
.ok_or_else(|| StreamCipherError::key_not_set())?;
|
||||
.ok_or_else(StreamCipherError::key_not_set)?;
|
||||
|
||||
let [key, iv]: [_; 2] = self
|
||||
.thread
|
||||
@@ -298,7 +299,7 @@ where
|
||||
.state
|
||||
.encoded_key_iv
|
||||
.clone()
|
||||
.ok_or_else(|| StreamCipherError::key_not_set())?;
|
||||
.ok_or_else(StreamCipherError::key_not_set)?;
|
||||
|
||||
self.thread.decode_blind(&[key, iv]).await?;
|
||||
|
||||
@@ -327,7 +328,7 @@ where
|
||||
.state
|
||||
.encoded_key_iv
|
||||
.as_ref()
|
||||
.ok_or_else(|| StreamCipherError::key_not_set())?;
|
||||
.ok_or_else(StreamCipherError::key_not_set)?;
|
||||
|
||||
self.state
|
||||
.keystream
|
||||
@@ -567,7 +568,7 @@ where
|
||||
.state
|
||||
.key_iv
|
||||
.clone()
|
||||
.ok_or_else(|| StreamCipherError::key_not_set())?;
|
||||
.ok_or_else(StreamCipherError::key_not_set)?;
|
||||
|
||||
let plaintext = C::apply_keystream(
|
||||
&key,
|
||||
@@ -643,7 +644,7 @@ where
|
||||
.state
|
||||
.encoded_key_iv
|
||||
.as_ref()
|
||||
.ok_or_else(|| StreamCipherError::key_not_set())?;
|
||||
.ok_or_else(StreamCipherError::key_not_set)?;
|
||||
|
||||
let key_block = self
|
||||
.state
|
||||
|
||||
@@ -200,6 +200,7 @@ where
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
#[allow(clippy::blocks_in_conditions)]
|
||||
impl<Ctx, C0, C1, E> KeyExchange for MpcKeyExchange<Ctx, C0, C1, E>
|
||||
where
|
||||
Ctx: Context,
|
||||
@@ -457,6 +458,7 @@ mod tests {
|
||||
use rand_core::SeedableRng;
|
||||
use serio::channel::MemoryDuplex;
|
||||
|
||||
#[allow(clippy::type_complexity)]
|
||||
fn create_pair() -> (
|
||||
MpcKeyExchange<
|
||||
STExecutor<MemoryDuplex>,
|
||||
|
||||
@@ -222,6 +222,7 @@ where
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
#[allow(clippy::blocks_in_conditions)]
|
||||
impl<E> Prf for MpcPrf<E>
|
||||
where
|
||||
E: Memory + Load + Execute + Decode + Send,
|
||||
|
||||
@@ -142,10 +142,8 @@ pub fn bind_client<T: AsyncRead + AsyncWrite + Send + Unpin + 'static>(
|
||||
tx_recv_fut = tx_receiver.next().fuse();
|
||||
}
|
||||
|
||||
if server_closed && client.plaintext_is_empty() {
|
||||
if client.buffer_len().await? == 0 {
|
||||
break 'conn;
|
||||
}
|
||||
if server_closed && client.plaintext_is_empty() && client.buffer_len().await? == 0 {
|
||||
break 'conn;
|
||||
}
|
||||
|
||||
select_biased! {
|
||||
|
||||
@@ -8,14 +8,10 @@ license = "MIT OR Apache-2.0"
|
||||
version = "0.1.0-alpha.6"
|
||||
edition = "2021"
|
||||
autobenches = false
|
||||
build = "build.rs"
|
||||
|
||||
[lib]
|
||||
name = "tls_client"
|
||||
|
||||
[build-dependencies]
|
||||
rustversion = { version = "1", optional = true }
|
||||
|
||||
[dependencies]
|
||||
tlsn-tls-backend = { path = "../tls-backend" }
|
||||
tlsn-tls-core = { path = "../tls-core" }
|
||||
@@ -37,9 +33,7 @@ web-time.workspace = true
|
||||
[features]
|
||||
default = ["logging", "tls12"]
|
||||
logging = ["log"]
|
||||
dangerous_configuration = []
|
||||
tls12 = []
|
||||
read_buf = ["rustversion"]
|
||||
|
||||
[dev-dependencies]
|
||||
env_logger.workspace = true
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
/// This build script allows us to enable the `read_buf` language feature only
|
||||
/// for Rust Nightly.
|
||||
///
|
||||
/// See the comment in lib.rs to understand why we need this.
|
||||
|
||||
#[cfg_attr(feature = "read_buf", rustversion::not(nightly))]
|
||||
fn main() {}
|
||||
|
||||
#[cfg(feature = "read_buf")]
|
||||
#[rustversion::nightly]
|
||||
fn main() {
|
||||
println!("cargo:rustc-cfg=read_buf");
|
||||
}
|
||||
@@ -26,22 +26,6 @@ impl ConfigBuilder<WantsVerifier> {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "dangerous_configuration")]
|
||||
/// Set a custom certificate verifier.
|
||||
pub fn with_custom_certificate_verifier(
|
||||
self,
|
||||
verifier: Arc<dyn verify::ServerCertVerifier>,
|
||||
) -> ConfigBuilder<WantsClientCert> {
|
||||
ConfigBuilder {
|
||||
state: WantsClientCert {
|
||||
cipher_suites: self.state.cipher_suites,
|
||||
kx_groups: self.state.kx_groups,
|
||||
versions: self.state.versions,
|
||||
verifier,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A config builder state where the caller needs to supply a certificate transparency policy or
|
||||
|
||||
@@ -171,13 +171,6 @@ impl ClientConfig {
|
||||
.any(|cs| cs.version().version == v)
|
||||
}
|
||||
|
||||
/// Access configuration options whose use is dangerous and requires
|
||||
/// extra care.
|
||||
#[cfg(feature = "dangerous_configuration")]
|
||||
pub fn dangerous(&mut self) -> danger::DangerousClientConfig {
|
||||
danger::DangerousClientConfig { cfg: self }
|
||||
}
|
||||
|
||||
pub(super) fn find_cipher_suite(&self, suite: CipherSuite) -> Option<SupportedCipherSuite> {
|
||||
self.cipher_suites
|
||||
.iter()
|
||||
@@ -186,27 +179,6 @@ impl ClientConfig {
|
||||
}
|
||||
}
|
||||
|
||||
/// Container for unsafe APIs
|
||||
#[cfg(feature = "dangerous_configuration")]
|
||||
pub(super) mod danger {
|
||||
use std::sync::Arc;
|
||||
|
||||
use super::{verify::ServerCertVerifier, ClientConfig};
|
||||
|
||||
/// Accessor for dangerous configuration options.
|
||||
pub struct DangerousClientConfig<'a> {
|
||||
/// The underlying ClientConfig
|
||||
pub cfg: &'a mut ClientConfig,
|
||||
}
|
||||
|
||||
impl<'a> DangerousClientConfig<'a> {
|
||||
/// Overrides the default `ServerCertVerifier` with something else.
|
||||
pub fn set_certificate_verifier(&mut self, verifier: Arc<dyn ServerCertVerifier>) {
|
||||
self.cfg.verifier = verifier;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
enum EarlyDataState {
|
||||
Disabled,
|
||||
|
||||
@@ -111,49 +111,6 @@ impl<'a> io::Read for Reader<'a> {
|
||||
|
||||
Ok(len)
|
||||
}
|
||||
|
||||
/// Obtain plaintext data received from the peer over this TLS connection.
|
||||
///
|
||||
/// If the peer closes the TLS session, this returns `Ok(())` without filling
|
||||
/// any more of the buffer once all the pending data has been read. No further
|
||||
/// data can be received on that connection, so the underlying TCP connection
|
||||
/// should be half-closed too.
|
||||
///
|
||||
/// If the peer closes the TLS session uncleanly (a TCP EOF without sending a
|
||||
/// `close_notify` alert) this function returns `Err(ErrorKind::UnexpectedEof.into())`
|
||||
/// once any pending data has been read.
|
||||
///
|
||||
/// Note that support for `close_notify` varies in peer TLS libraries: many do not
|
||||
/// support it and uncleanly close the TCP connection (this might be
|
||||
/// vulnerable to truncation attacks depending on the application protocol).
|
||||
/// This means applications using rustls must both handle EOF
|
||||
/// from this function, *and* unexpected EOF of the underlying TCP connection.
|
||||
///
|
||||
/// If there are no bytes to read, this returns `Err(ErrorKind::WouldBlock.into())`.
|
||||
///
|
||||
/// You may learn the number of bytes available at any time by inspecting
|
||||
/// the return of [`Connection::process_new_packets`].
|
||||
#[cfg(read_buf)]
|
||||
fn read_buf(&mut self, buf: &mut io::ReadBuf<'_>) -> io::Result<()> {
|
||||
let before = buf.filled_len();
|
||||
self.received_plaintext.read_buf(buf)?;
|
||||
let len = buf.filled_len() - before;
|
||||
|
||||
if len == 0 && buf.capacity() > 0 {
|
||||
// No bytes available:
|
||||
match (self.peer_cleanly_closed, self.has_seen_eof) {
|
||||
// cleanly closed; don't care about TCP EOF: express this as Ok(0)
|
||||
(true, _) => {}
|
||||
// unclean closure
|
||||
(false, true) => return Err(io::ErrorKind::UnexpectedEof.into()),
|
||||
// connection still going, but need more data: signal `WouldBlock` so that
|
||||
// the caller knows this
|
||||
(false, false) => return Err(io::ErrorKind::WouldBlock.into()),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq)]
|
||||
|
||||
@@ -252,14 +252,12 @@
|
||||
// Require docs for public APIs, deny unsafe code, etc.
|
||||
#![forbid(unsafe_code)]
|
||||
#![allow(dead_code, unused_imports)]
|
||||
#![cfg_attr(not(read_buf), forbid(unstable_features))]
|
||||
#![deny(
|
||||
clippy::clone_on_ref_ptr,
|
||||
clippy::use_self,
|
||||
trivial_casts,
|
||||
trivial_numeric_casts,
|
||||
missing_docs,
|
||||
//unreachable_pub,
|
||||
unused_import_braces,
|
||||
unused_extern_crates,
|
||||
unused_qualifications
|
||||
@@ -274,24 +272,9 @@
|
||||
// a false positive, https://github.com/rust-lang/rust-clippy/issues/5210
|
||||
// - new_without_default: for internal constructors, the indirection is not
|
||||
// helpful
|
||||
#![allow(
|
||||
clippy::too_many_arguments,
|
||||
clippy::new_ret_no_self,
|
||||
clippy::ptr_arg,
|
||||
clippy::single_component_path_imports,
|
||||
clippy::new_without_default
|
||||
)]
|
||||
#![allow(clippy::all)]
|
||||
// Enable documentation for all features on docs.rs
|
||||
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||
// XXX: Because of https://github.com/rust-lang/rust/issues/54726, we cannot
|
||||
// write `#![rustversion::attr(nightly, feature(read_buf))]` here. Instead,
|
||||
// build.rs set `read_buf` for (only) Rust Nightly to get the same effect.
|
||||
//
|
||||
// All the other conditional logic in the crate could use
|
||||
// `#[rustversion::nightly]` instead of `#[cfg(read_buf)]`; `#[cfg(read_buf)]`
|
||||
// is used to avoid needing `rustversion` to be compiled twice during
|
||||
// cross-compiling.
|
||||
#![cfg_attr(read_buf, feature(read_buf))]
|
||||
|
||||
// log for logging (optional).
|
||||
#[cfg(feature = "logging")]
|
||||
@@ -366,8 +349,6 @@ pub use tls_core::{
|
||||
suites::{SupportedCipherSuite, ALL_CIPHER_SUITES},
|
||||
versions::{SupportedProtocolVersion, ALL_VERSIONS},
|
||||
};
|
||||
//pub use crate::stream::{Stream, StreamOwned};
|
||||
//pub use crate::ticketer::Ticketer;
|
||||
|
||||
/// Items for use in a client.
|
||||
pub mod client {
|
||||
@@ -386,16 +367,6 @@ pub mod client {
|
||||
ResolvesClientCert, ServerName, StoresClientSessions,
|
||||
};
|
||||
pub use handy::{ClientSessionMemoryCache, NoClientSessionStorage};
|
||||
|
||||
#[cfg(feature = "dangerous_configuration")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "dangerous_configuration")))]
|
||||
pub use crate::verify::{
|
||||
CertificateTransparencyPolicy, HandshakeSignatureValid, ServerCertVerified,
|
||||
ServerCertVerifier, WebPkiVerifier,
|
||||
};
|
||||
#[cfg(feature = "dangerous_configuration")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "dangerous_configuration")))]
|
||||
pub use client_conn::danger::DangerousClientConfig;
|
||||
}
|
||||
|
||||
pub use client::{ClientConfig, ClientConnection, ServerName};
|
||||
@@ -422,13 +393,6 @@ pub mod sign;
|
||||
/// This is the rustls manual.
|
||||
pub mod manual;
|
||||
|
||||
/** Type renames. */
|
||||
#[allow(clippy::upper_case_acronyms)]
|
||||
#[cfg(feature = "dangerous_configuration")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "dangerous_configuration")))]
|
||||
#[doc(hidden)]
|
||||
#[deprecated(since = "0.20.0", note = "Use client::WebPkiVerifier")]
|
||||
pub type WebPKIVerifier = client::WebPkiVerifier;
|
||||
#[allow(clippy::upper_case_acronyms)]
|
||||
#[doc(hidden)]
|
||||
#[deprecated(since = "0.20.0", note = "Use Error")]
|
||||
|
||||
@@ -96,19 +96,6 @@ impl ChunkVecBuffer {
|
||||
Ok(offs)
|
||||
}
|
||||
|
||||
#[cfg(read_buf)]
|
||||
/// Read data out of this object, writing it into `buf`.
|
||||
pub(crate) fn read_buf(&mut self, buf: &mut io::ReadBuf<'_>) -> io::Result<()> {
|
||||
while !self.is_empty() && buf.remaining() > 0 {
|
||||
let chunk = self.chunks[0].as_slice();
|
||||
let used = std::cmp::min(chunk.len(), buf.remaining());
|
||||
buf.append(&chunk[..used]);
|
||||
self.consume(used);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn consume(&mut self, mut used: usize) {
|
||||
while let Some(mut buf) = self.chunks.pop_front() {
|
||||
if used < buf.len() {
|
||||
@@ -172,38 +159,4 @@ mod test {
|
||||
assert_eq!(cvb.read(&mut buf).unwrap(), 12);
|
||||
assert_eq!(buf.to_vec(), b"helloworldhe".to_vec());
|
||||
}
|
||||
|
||||
#[cfg(read_buf)]
|
||||
#[test]
|
||||
fn read_buf() {
|
||||
use std::{io::ReadBuf, mem::MaybeUninit};
|
||||
|
||||
{
|
||||
let mut cvb = ChunkVecBuffer::new(None);
|
||||
cvb.append(b"test ".to_vec());
|
||||
cvb.append(b"fixture ".to_vec());
|
||||
cvb.append(b"data".to_vec());
|
||||
|
||||
let mut buf = [MaybeUninit::<u8>::uninit(); 8];
|
||||
let mut buf = ReadBuf::uninit(&mut buf);
|
||||
cvb.read_buf(&mut buf).unwrap();
|
||||
assert_eq!(buf.filled(), b"test fix");
|
||||
buf.clear();
|
||||
cvb.read_buf(&mut buf).unwrap();
|
||||
assert_eq!(buf.filled(), b"ture dat");
|
||||
buf.clear();
|
||||
cvb.read_buf(&mut buf).unwrap();
|
||||
assert_eq!(buf.filled(), b"a");
|
||||
}
|
||||
|
||||
{
|
||||
let mut cvb = ChunkVecBuffer::new(None);
|
||||
cvb.append(b"short message".to_vec());
|
||||
|
||||
let mut buf = [MaybeUninit::<u8>::uninit(); 1024];
|
||||
let mut buf = ReadBuf::uninit(&mut buf);
|
||||
cvb.read_buf(&mut buf).unwrap();
|
||||
assert_eq!(buf.filled(), b"short message");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,8 +14,6 @@ use std::{
|
||||
},
|
||||
};
|
||||
|
||||
#[cfg(feature = "quic")]
|
||||
use tls_client::quic::{self, ClientQuicExt, QuicExt, ServerQuicExt};
|
||||
use tls_client::{
|
||||
client::ResolvesClientCert, sign, CipherSuite, ClientConfig, ClientConnection, Error, KeyLog,
|
||||
ProtocolVersion, RustCryptoBackend, SignatureScheme, SupportedCipherSuite, ALL_CIPHER_SUITES,
|
||||
@@ -42,7 +40,7 @@ async fn alpn_test_error(
|
||||
|
||||
for version in tls_client::ALL_VERSIONS {
|
||||
let mut client_config = make_client_config_with_versions(KeyType::Rsa, &[version]);
|
||||
client_config.alpn_protocols = client_protos.clone();
|
||||
client_config.alpn_protocols.clone_from(&client_protos);
|
||||
|
||||
let (mut client, mut server) =
|
||||
make_pair_for_arc_configs(&Arc::new(client_config), &server_config).await;
|
||||
@@ -889,6 +887,7 @@ async fn client_error_is_sticky() {
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[allow(clippy::no_effect)]
|
||||
async fn client_is_send() {
|
||||
let (client, _) = make_pair(KeyType::Rsa).await;
|
||||
&client as &dyn Send;
|
||||
@@ -1374,32 +1373,6 @@ async fn server_streamowned_read() {
|
||||
}
|
||||
}
|
||||
|
||||
struct FailsWrites {
|
||||
errkind: io::ErrorKind,
|
||||
after: usize,
|
||||
}
|
||||
|
||||
impl io::Read for FailsWrites {
|
||||
fn read(&mut self, _b: &mut [u8]) -> io::Result<usize> {
|
||||
Ok(0)
|
||||
}
|
||||
}
|
||||
|
||||
impl io::Write for FailsWrites {
|
||||
fn write(&mut self, b: &[u8]) -> io::Result<usize> {
|
||||
if self.after > 0 {
|
||||
self.after -= 1;
|
||||
Ok(b.len())
|
||||
} else {
|
||||
Err(io::Error::new(self.errkind, "oops"))
|
||||
}
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
// #[tokio::test]
|
||||
// async fn stream_write_reports_underlying_io_error_before_plaintext_processed() {
|
||||
// let (mut client, mut server) = make_pair(KeyType::Rsa).await;
|
||||
@@ -2345,626 +2318,6 @@ async fn tls13_stateless_resumption() {
|
||||
// assert_eq!(client.is_early_data_accepted(), false);
|
||||
// }
|
||||
|
||||
#[cfg(feature = "quic")]
|
||||
mod test_quic {
|
||||
use super::*;
|
||||
use rustls::Connection;
|
||||
|
||||
// Returns the sender's next secrets to use, or the receiver's error.
|
||||
fn step(
|
||||
send: &mut dyn QuicExt,
|
||||
recv: &mut dyn QuicExt,
|
||||
) -> Result<Option<quic::KeyChange>, Error> {
|
||||
let mut buf = Vec::new();
|
||||
let change = loop {
|
||||
let prev = buf.len();
|
||||
if let Some(x) = send.write_hs(&mut buf) {
|
||||
break Some(x);
|
||||
}
|
||||
if prev == buf.len() {
|
||||
break None;
|
||||
}
|
||||
};
|
||||
if let Err(e) = recv.read_hs(&buf) {
|
||||
return Err(e);
|
||||
} else {
|
||||
assert_eq!(recv.alert(), None);
|
||||
}
|
||||
|
||||
Ok(change)
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
fn test_quic_handshake() {
|
||||
fn equal_packet_keys(x: &quic::PacketKey, y: &quic::PacketKey) -> bool {
|
||||
// Check that these two sets of keys are equal.
|
||||
let mut buf = vec![0; 32];
|
||||
let (header, payload_tag) = buf.split_at_mut(8);
|
||||
let (payload, tag_buf) = payload_tag.split_at_mut(8);
|
||||
let tag = x.encrypt_in_place(42, &*header, payload).unwrap();
|
||||
tag_buf.copy_from_slice(tag.as_ref());
|
||||
|
||||
let result = y.decrypt_in_place(42, &*header, payload_tag);
|
||||
match result {
|
||||
Ok(payload) => payload == &[0; 8],
|
||||
Err(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn compatible_keys(x: &quic::KeyChange, y: &quic::KeyChange) -> bool {
|
||||
fn keys(kc: &quic::KeyChange) -> &quic::Keys {
|
||||
match kc {
|
||||
quic::KeyChange::Handshake { keys } => keys,
|
||||
quic::KeyChange::OneRtt { keys, .. } => keys,
|
||||
}
|
||||
}
|
||||
|
||||
let (x, y) = (keys(x), keys(y));
|
||||
equal_packet_keys(&x.local.packet, &y.remote.packet)
|
||||
&& equal_packet_keys(&x.remote.packet, &y.local.packet)
|
||||
}
|
||||
|
||||
let kt = KeyType::Rsa;
|
||||
let mut client_config = make_client_config_with_versions(kt, &[&rustls::version::TLS13]);
|
||||
client_config.enable_early_data = true;
|
||||
let client_config = Arc::new(client_config);
|
||||
let mut server_config = make_server_config_with_versions(kt, &[&rustls::version::TLS13]);
|
||||
server_config.max_early_data_size = 0xffffffff;
|
||||
let server_config = Arc::new(server_config);
|
||||
let client_params = &b"client params"[..];
|
||||
let server_params = &b"server params"[..];
|
||||
|
||||
// full handshake
|
||||
let mut client = Connection::from(
|
||||
ClientConnection::new_quic(
|
||||
Arc::clone(&client_config),
|
||||
quic::Version::V1,
|
||||
dns_name("localhost"),
|
||||
client_params.into(),
|
||||
)
|
||||
.unwrap(),
|
||||
);
|
||||
|
||||
let mut server = Connection::from(
|
||||
ServerConnection::new_quic(
|
||||
Arc::clone(&server_config),
|
||||
quic::Version::V1,
|
||||
server_params.into(),
|
||||
)
|
||||
.unwrap(),
|
||||
);
|
||||
|
||||
let client_initial = step(&mut client, &mut server).unwrap();
|
||||
assert!(client_initial.is_none());
|
||||
assert!(client.zero_rtt_keys().is_none());
|
||||
assert_eq!(server.quic_transport_parameters(), Some(client_params));
|
||||
let server_hs = step(&mut server, &mut client).unwrap().unwrap();
|
||||
assert!(server.zero_rtt_keys().is_none());
|
||||
let client_hs = step(&mut client, &mut server).unwrap().unwrap();
|
||||
assert!(compatible_keys(&server_hs, &client_hs));
|
||||
assert!(client.is_handshaking());
|
||||
let server_1rtt = step(&mut server, &mut client).unwrap().unwrap();
|
||||
assert!(!client.is_handshaking());
|
||||
assert_eq!(client.quic_transport_parameters(), Some(server_params));
|
||||
assert!(server.is_handshaking());
|
||||
let client_1rtt = step(&mut client, &mut server).unwrap().unwrap();
|
||||
assert!(!server.is_handshaking());
|
||||
assert!(compatible_keys(&server_1rtt, &client_1rtt));
|
||||
assert!(!compatible_keys(&server_hs, &server_1rtt));
|
||||
assert!(step(&mut client, &mut server).unwrap().is_none());
|
||||
assert!(step(&mut server, &mut client).unwrap().is_none());
|
||||
|
||||
// 0-RTT handshake
|
||||
let mut client = ClientConnection::new_quic(
|
||||
Arc::clone(&client_config),
|
||||
quic::Version::V1,
|
||||
dns_name("localhost"),
|
||||
client_params.into(),
|
||||
)
|
||||
.unwrap();
|
||||
assert!(client.negotiated_cipher_suite().is_some());
|
||||
|
||||
let mut server = ServerConnection::new_quic(
|
||||
Arc::clone(&server_config),
|
||||
quic::Version::V1,
|
||||
server_params.into(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
step(&mut client, &mut server).unwrap();
|
||||
assert_eq!(client.quic_transport_parameters(), Some(server_params));
|
||||
{
|
||||
let client_early = client.zero_rtt_keys().unwrap();
|
||||
let server_early = server.zero_rtt_keys().unwrap();
|
||||
assert!(equal_packet_keys(
|
||||
&client_early.packet,
|
||||
&server_early.packet
|
||||
));
|
||||
}
|
||||
step(&mut server, &mut client).unwrap().unwrap();
|
||||
step(&mut client, &mut server).unwrap().unwrap();
|
||||
step(&mut server, &mut client).unwrap().unwrap();
|
||||
assert!(client.is_early_data_accepted());
|
||||
|
||||
// 0-RTT rejection
|
||||
{
|
||||
let client_config = (*client_config).clone();
|
||||
let mut client = ClientConnection::new_quic(
|
||||
Arc::new(client_config),
|
||||
quic::Version::V1,
|
||||
dns_name("localhost"),
|
||||
client_params.into(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let mut server = ServerConnection::new_quic(
|
||||
Arc::clone(&server_config),
|
||||
quic::Version::V1,
|
||||
server_params.into(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
step(&mut client, &mut server).unwrap();
|
||||
assert_eq!(client.quic_transport_parameters(), Some(server_params));
|
||||
assert!(client.zero_rtt_keys().is_some());
|
||||
assert!(server.zero_rtt_keys().is_none());
|
||||
step(&mut server, &mut client).unwrap().unwrap();
|
||||
step(&mut client, &mut server).unwrap().unwrap();
|
||||
step(&mut server, &mut client).unwrap().unwrap();
|
||||
assert!(!client.is_early_data_accepted());
|
||||
}
|
||||
|
||||
// failed handshake
|
||||
let mut client = ClientConnection::new_quic(
|
||||
client_config,
|
||||
quic::Version::V1,
|
||||
dns_name("example.com"),
|
||||
client_params.into(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let mut server =
|
||||
ServerConnection::new_quic(server_config, quic::Version::V1, server_params.into())
|
||||
.unwrap();
|
||||
|
||||
step(&mut client, &mut server).unwrap();
|
||||
step(&mut server, &mut client).unwrap().unwrap();
|
||||
assert!(step(&mut server, &mut client).is_err());
|
||||
assert_eq!(
|
||||
client.alert(),
|
||||
Some(rustls::internal::msgs::enums::AlertDescription::BadCertificate)
|
||||
);
|
||||
|
||||
// Key updates
|
||||
|
||||
let (mut client_secrets, mut server_secrets) = match (client_1rtt, server_1rtt) {
|
||||
(quic::KeyChange::OneRtt { next: c, .. }, quic::KeyChange::OneRtt { next: s, .. }) => {
|
||||
(c, s)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let mut client_next = client_secrets.next_packet_keys();
|
||||
let mut server_next = server_secrets.next_packet_keys();
|
||||
assert!(equal_packet_keys(&client_next.local, &server_next.remote));
|
||||
assert!(equal_packet_keys(&server_next.local, &client_next.remote));
|
||||
|
||||
client_next = client_secrets.next_packet_keys();
|
||||
server_next = server_secrets.next_packet_keys();
|
||||
assert!(equal_packet_keys(&client_next.local, &server_next.remote));
|
||||
assert!(equal_packet_keys(&server_next.local, &client_next.remote));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
fn test_quic_rejects_missing_alpn() {
|
||||
let client_params = &b"client params"[..];
|
||||
let server_params = &b"server params"[..];
|
||||
|
||||
for &kt in ALL_KEY_TYPES.iter() {
|
||||
let client_config = make_client_config_with_versions(kt, &[&rustls::version::TLS13]);
|
||||
let client_config = Arc::new(client_config);
|
||||
|
||||
let mut server_config =
|
||||
make_server_config_with_versions(kt, &[&rustls::version::TLS13]);
|
||||
server_config.alpn_protocols = vec!["foo".into()];
|
||||
let server_config = Arc::new(server_config);
|
||||
|
||||
let mut client = ClientConnection::new_quic(
|
||||
client_config,
|
||||
quic::Version::V1,
|
||||
dns_name("localhost"),
|
||||
client_params.into(),
|
||||
)
|
||||
.unwrap();
|
||||
let mut server =
|
||||
ServerConnection::new_quic(server_config, quic::Version::V1, server_params.into())
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
step(&mut client, &mut server).err().unwrap(),
|
||||
Error::NoApplicationProtocol
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
server.alert(),
|
||||
Some(rustls::internal::msgs::enums::AlertDescription::NoApplicationProtocol)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
fn test_quic_no_tls13_error() {
|
||||
let mut client_config =
|
||||
make_client_config_with_versions(KeyType::Ed25519, &[&rustls::version::TLS12]);
|
||||
client_config.alpn_protocols = vec!["foo".into()];
|
||||
let client_config = Arc::new(client_config);
|
||||
|
||||
assert!(ClientConnection::new_quic(
|
||||
client_config,
|
||||
quic::Version::V1,
|
||||
dns_name("localhost"),
|
||||
b"client params".to_vec(),
|
||||
)
|
||||
.is_err());
|
||||
|
||||
let mut server_config =
|
||||
make_server_config_with_versions(KeyType::Ed25519, &[&rustls::version::TLS12]);
|
||||
server_config.alpn_protocols = vec!["foo".into()];
|
||||
let server_config = Arc::new(server_config);
|
||||
|
||||
assert!(ServerConnection::new_quic(
|
||||
server_config,
|
||||
quic::Version::V1,
|
||||
b"server params".to_vec(),
|
||||
)
|
||||
.is_err());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
fn test_quic_invalid_early_data_size() {
|
||||
let mut server_config =
|
||||
make_server_config_with_versions(KeyType::Ed25519, &[&rustls::version::TLS13]);
|
||||
server_config.alpn_protocols = vec!["foo".into()];
|
||||
|
||||
let cases = [
|
||||
(None, true),
|
||||
(Some(0u32), true),
|
||||
(Some(5), false),
|
||||
(Some(0xffff_ffff), true),
|
||||
];
|
||||
|
||||
for &(size, ok) in cases.iter() {
|
||||
println!("early data size case: {:?}", size);
|
||||
if let Some(new) = size {
|
||||
server_config.max_early_data_size = new;
|
||||
}
|
||||
|
||||
let wrapped = Arc::new(server_config.clone());
|
||||
assert_eq!(
|
||||
ServerConnection::new_quic(wrapped, quic::Version::V1, b"server params".to_vec(),)
|
||||
.is_ok(),
|
||||
ok
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
fn test_quic_server_no_params_received() {
|
||||
let server_config =
|
||||
make_server_config_with_versions(KeyType::Ed25519, &[&rustls::version::TLS13]);
|
||||
let server_config = Arc::new(server_config);
|
||||
|
||||
let mut server =
|
||||
ServerConnection::new_quic(server_config, quic::Version::V1, b"server params".to_vec())
|
||||
.unwrap();
|
||||
|
||||
use ring::rand::SecureRandom;
|
||||
use rustls::internal::msgs::{
|
||||
base::PayloadU16,
|
||||
enums::{CipherSuite, Compression, HandshakeType, NamedGroup, SignatureScheme},
|
||||
handshake::{
|
||||
ClientHelloPayload, HandshakeMessagePayload, KeyShareEntry, Random, SessionID,
|
||||
},
|
||||
message::PlainMessage,
|
||||
};
|
||||
|
||||
let rng = ring::rand::SystemRandom::new();
|
||||
let mut random = [0; 32];
|
||||
rng.fill(&mut random).unwrap();
|
||||
let random = Random::from(random);
|
||||
|
||||
let kx = ring::agreement::EphemeralPrivateKey::generate(&ring::agreement::X25519, &rng)
|
||||
.unwrap()
|
||||
.compute_public_key()
|
||||
.unwrap();
|
||||
|
||||
let client_hello = Message {
|
||||
version: ProtocolVersion::TLSv1_3,
|
||||
payload: MessagePayload::Handshake(HandshakeMessagePayload {
|
||||
typ: HandshakeType::ClientHello,
|
||||
payload: HandshakePayload::ClientHello(ClientHelloPayload {
|
||||
client_version: ProtocolVersion::TLSv1_3,
|
||||
random,
|
||||
session_id: SessionID::random().unwrap(),
|
||||
cipher_suites: vec![CipherSuite::TLS13_AES_128_GCM_SHA256],
|
||||
compression_methods: vec![Compression::Null],
|
||||
extensions: vec![
|
||||
ClientExtension::SupportedVersions(vec![ProtocolVersion::TLSv1_3]),
|
||||
ClientExtension::NamedGroups(vec![NamedGroup::X25519]),
|
||||
ClientExtension::SignatureAlgorithms(vec![SignatureScheme::ED25519]),
|
||||
ClientExtension::KeyShare(vec![KeyShareEntry {
|
||||
group: NamedGroup::X25519,
|
||||
payload: PayloadU16::new(kx.as_ref().to_vec()),
|
||||
}]),
|
||||
],
|
||||
}),
|
||||
}),
|
||||
};
|
||||
|
||||
let buf = PlainMessage::from(client_hello)
|
||||
.into_unencrypted_opaque()
|
||||
.encode();
|
||||
server.read_tls(&mut buf.as_slice()).unwrap();
|
||||
assert_eq!(
|
||||
server.process_new_packets().err(),
|
||||
Some(Error::PeerMisbehavedError(
|
||||
"QUIC transport parameters not found".into(),
|
||||
)),
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
fn test_quic_server_no_tls12() {
|
||||
let mut server_config =
|
||||
make_server_config_with_versions(KeyType::Ed25519, &[&rustls::version::TLS13]);
|
||||
server_config.alpn_protocols = vec!["foo".into()];
|
||||
let server_config = Arc::new(server_config);
|
||||
|
||||
use ring::rand::SecureRandom;
|
||||
use rustls::internal::msgs::{
|
||||
base::PayloadU16,
|
||||
enums::{CipherSuite, Compression, HandshakeType, NamedGroup, SignatureScheme},
|
||||
handshake::{
|
||||
ClientHelloPayload, HandshakeMessagePayload, KeyShareEntry, Random, SessionID,
|
||||
},
|
||||
message::PlainMessage,
|
||||
};
|
||||
|
||||
let rng = ring::rand::SystemRandom::new();
|
||||
let mut random = [0; 32];
|
||||
rng.fill(&mut random).unwrap();
|
||||
let random = Random::from(random);
|
||||
|
||||
let kx = ring::agreement::EphemeralPrivateKey::generate(&ring::agreement::X25519, &rng)
|
||||
.unwrap()
|
||||
.compute_public_key()
|
||||
.unwrap();
|
||||
|
||||
let mut server =
|
||||
ServerConnection::new_quic(server_config, quic::Version::V1, b"server params".to_vec())
|
||||
.unwrap();
|
||||
|
||||
let client_hello = Message {
|
||||
version: ProtocolVersion::TLSv1_2,
|
||||
payload: MessagePayload::Handshake(HandshakeMessagePayload {
|
||||
typ: HandshakeType::ClientHello,
|
||||
payload: HandshakePayload::ClientHello(ClientHelloPayload {
|
||||
client_version: ProtocolVersion::TLSv1_2,
|
||||
random: random.clone(),
|
||||
session_id: SessionID::random().unwrap(),
|
||||
cipher_suites: vec![CipherSuite::TLS13_AES_128_GCM_SHA256],
|
||||
compression_methods: vec![Compression::Null],
|
||||
extensions: vec![
|
||||
ClientExtension::NamedGroups(vec![NamedGroup::X25519]),
|
||||
ClientExtension::SignatureAlgorithms(vec![SignatureScheme::ED25519]),
|
||||
ClientExtension::KeyShare(vec![KeyShareEntry {
|
||||
group: NamedGroup::X25519,
|
||||
payload: PayloadU16::new(kx.as_ref().to_vec()),
|
||||
}]),
|
||||
],
|
||||
}),
|
||||
}),
|
||||
};
|
||||
|
||||
let buf = PlainMessage::from(client_hello)
|
||||
.into_unencrypted_opaque()
|
||||
.encode();
|
||||
server.read_tls(&mut buf.as_slice()).unwrap();
|
||||
assert_eq!(
|
||||
server.process_new_packets().err(),
|
||||
Some(Error::PeerIncompatibleError(
|
||||
"Server requires TLS1.3, but client omitted versions ext".into(),
|
||||
)),
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
fn packet_key_api() {
|
||||
use rustls::quic::{Keys, Version};
|
||||
|
||||
// Test vectors: https://www.rfc-editor.org/rfc/rfc9001.html#name-client-initial
|
||||
const CONNECTION_ID: &[u8] = &[0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08];
|
||||
const PACKET_NUMBER: u64 = 2;
|
||||
const PLAIN_HEADER: &[u8] = &[
|
||||
0xc3, 0x00, 0x00, 0x00, 0x01, 0x08, 0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08,
|
||||
0x00, 0x00, 0x44, 0x9e, 0x00, 0x00, 0x00, 0x02,
|
||||
];
|
||||
|
||||
const PAYLOAD: &[u8] = &[
|
||||
0x06, 0x00, 0x40, 0xf1, 0x01, 0x00, 0x00, 0xed, 0x03, 0x03, 0xeb, 0xf8, 0xfa, 0x56,
|
||||
0xf1, 0x29, 0x39, 0xb9, 0x58, 0x4a, 0x38, 0x96, 0x47, 0x2e, 0xc4, 0x0b, 0xb8, 0x63,
|
||||
0xcf, 0xd3, 0xe8, 0x68, 0x04, 0xfe, 0x3a, 0x47, 0xf0, 0x6a, 0x2b, 0x69, 0x48, 0x4c,
|
||||
0x00, 0x00, 0x04, 0x13, 0x01, 0x13, 0x02, 0x01, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00,
|
||||
0x10, 0x00, 0x0e, 0x00, 0x00, 0x0b, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e,
|
||||
0x63, 0x6f, 0x6d, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06,
|
||||
0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00, 0x10, 0x00, 0x07, 0x00, 0x05, 0x04, 0x61,
|
||||
0x6c, 0x70, 0x6e, 0x00, 0x05, 0x00, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33,
|
||||
0x00, 0x26, 0x00, 0x24, 0x00, 0x1d, 0x00, 0x20, 0x93, 0x70, 0xb2, 0xc9, 0xca, 0xa4,
|
||||
0x7f, 0xba, 0xba, 0xf4, 0x55, 0x9f, 0xed, 0xba, 0x75, 0x3d, 0xe1, 0x71, 0xfa, 0x71,
|
||||
0xf5, 0x0f, 0x1c, 0xe1, 0x5d, 0x43, 0xe9, 0x94, 0xec, 0x74, 0xd7, 0x48, 0x00, 0x2b,
|
||||
0x00, 0x03, 0x02, 0x03, 0x04, 0x00, 0x0d, 0x00, 0x10, 0x00, 0x0e, 0x04, 0x03, 0x05,
|
||||
0x03, 0x06, 0x03, 0x02, 0x03, 0x08, 0x04, 0x08, 0x05, 0x08, 0x06, 0x00, 0x2d, 0x00,
|
||||
0x02, 0x01, 0x01, 0x00, 0x1c, 0x00, 0x02, 0x40, 0x01, 0x00, 0x39, 0x00, 0x32, 0x04,
|
||||
0x08, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x05, 0x04, 0x80, 0x00, 0xff,
|
||||
0xff, 0x07, 0x04, 0x80, 0x00, 0xff, 0xff, 0x08, 0x01, 0x10, 0x01, 0x04, 0x80, 0x00,
|
||||
0x75, 0x30, 0x09, 0x01, 0x10, 0x0f, 0x08, 0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57,
|
||||
0x08, 0x06, 0x04, 0x80, 0x00, 0xff, 0xff,
|
||||
];
|
||||
|
||||
let client_keys = Keys::initial(Version::V1, &CONNECTION_ID, true);
|
||||
assert_eq!(
|
||||
client_keys.local.packet.confidentiality_limit(),
|
||||
2u64.pow(23)
|
||||
);
|
||||
assert_eq!(client_keys.local.packet.integrity_limit(), 2u64.pow(52));
|
||||
assert_eq!(client_keys.local.packet.tag_len(), 16);
|
||||
|
||||
let mut buf = Vec::new();
|
||||
buf.extend(PLAIN_HEADER);
|
||||
buf.extend(PAYLOAD);
|
||||
let header_len = PLAIN_HEADER.len();
|
||||
let tag_len = client_keys.local.packet.tag_len();
|
||||
let padding_len = 1200 - header_len - PAYLOAD.len() - tag_len;
|
||||
buf.extend(std::iter::repeat(0).take(padding_len));
|
||||
let (header, payload) = buf.split_at_mut(header_len);
|
||||
let tag = client_keys
|
||||
.local
|
||||
.packet
|
||||
.encrypt_in_place(PACKET_NUMBER, &*header, payload)
|
||||
.unwrap();
|
||||
|
||||
let sample_len = client_keys.local.header.sample_len();
|
||||
let sample = &payload[..sample_len];
|
||||
let (first, rest) = header.split_at_mut(1);
|
||||
client_keys
|
||||
.local
|
||||
.header
|
||||
.encrypt_in_place(sample, &mut first[0], &mut rest[17..21])
|
||||
.unwrap();
|
||||
buf.extend_from_slice(tag.as_ref());
|
||||
|
||||
const PROTECTED: &[u8] = &[
|
||||
0xc0, 0x00, 0x00, 0x00, 0x01, 0x08, 0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08,
|
||||
0x00, 0x00, 0x44, 0x9e, 0x7b, 0x9a, 0xec, 0x34, 0xd1, 0xb1, 0xc9, 0x8d, 0xd7, 0x68,
|
||||
0x9f, 0xb8, 0xec, 0x11, 0xd2, 0x42, 0xb1, 0x23, 0xdc, 0x9b, 0xd8, 0xba, 0xb9, 0x36,
|
||||
0xb4, 0x7d, 0x92, 0xec, 0x35, 0x6c, 0x0b, 0xab, 0x7d, 0xf5, 0x97, 0x6d, 0x27, 0xcd,
|
||||
0x44, 0x9f, 0x63, 0x30, 0x00, 0x99, 0xf3, 0x99, 0x1c, 0x26, 0x0e, 0xc4, 0xc6, 0x0d,
|
||||
0x17, 0xb3, 0x1f, 0x84, 0x29, 0x15, 0x7b, 0xb3, 0x5a, 0x12, 0x82, 0xa6, 0x43, 0xa8,
|
||||
0xd2, 0x26, 0x2c, 0xad, 0x67, 0x50, 0x0c, 0xad, 0xb8, 0xe7, 0x37, 0x8c, 0x8e, 0xb7,
|
||||
0x53, 0x9e, 0xc4, 0xd4, 0x90, 0x5f, 0xed, 0x1b, 0xee, 0x1f, 0xc8, 0xaa, 0xfb, 0xa1,
|
||||
0x7c, 0x75, 0x0e, 0x2c, 0x7a, 0xce, 0x01, 0xe6, 0x00, 0x5f, 0x80, 0xfc, 0xb7, 0xdf,
|
||||
0x62, 0x12, 0x30, 0xc8, 0x37, 0x11, 0xb3, 0x93, 0x43, 0xfa, 0x02, 0x8c, 0xea, 0x7f,
|
||||
0x7f, 0xb5, 0xff, 0x89, 0xea, 0xc2, 0x30, 0x82, 0x49, 0xa0, 0x22, 0x52, 0x15, 0x5e,
|
||||
0x23, 0x47, 0xb6, 0x3d, 0x58, 0xc5, 0x45, 0x7a, 0xfd, 0x84, 0xd0, 0x5d, 0xff, 0xfd,
|
||||
0xb2, 0x03, 0x92, 0x84, 0x4a, 0xe8, 0x12, 0x15, 0x46, 0x82, 0xe9, 0xcf, 0x01, 0x2f,
|
||||
0x90, 0x21, 0xa6, 0xf0, 0xbe, 0x17, 0xdd, 0xd0, 0xc2, 0x08, 0x4d, 0xce, 0x25, 0xff,
|
||||
0x9b, 0x06, 0xcd, 0xe5, 0x35, 0xd0, 0xf9, 0x20, 0xa2, 0xdb, 0x1b, 0xf3, 0x62, 0xc2,
|
||||
0x3e, 0x59, 0x6d, 0x11, 0xa4, 0xf5, 0xa6, 0xcf, 0x39, 0x48, 0x83, 0x8a, 0x3a, 0xec,
|
||||
0x4e, 0x15, 0xda, 0xf8, 0x50, 0x0a, 0x6e, 0xf6, 0x9e, 0xc4, 0xe3, 0xfe, 0xb6, 0xb1,
|
||||
0xd9, 0x8e, 0x61, 0x0a, 0xc8, 0xb7, 0xec, 0x3f, 0xaf, 0x6a, 0xd7, 0x60, 0xb7, 0xba,
|
||||
0xd1, 0xdb, 0x4b, 0xa3, 0x48, 0x5e, 0x8a, 0x94, 0xdc, 0x25, 0x0a, 0xe3, 0xfd, 0xb4,
|
||||
0x1e, 0xd1, 0x5f, 0xb6, 0xa8, 0xe5, 0xeb, 0xa0, 0xfc, 0x3d, 0xd6, 0x0b, 0xc8, 0xe3,
|
||||
0x0c, 0x5c, 0x42, 0x87, 0xe5, 0x38, 0x05, 0xdb, 0x05, 0x9a, 0xe0, 0x64, 0x8d, 0xb2,
|
||||
0xf6, 0x42, 0x64, 0xed, 0x5e, 0x39, 0xbe, 0x2e, 0x20, 0xd8, 0x2d, 0xf5, 0x66, 0xda,
|
||||
0x8d, 0xd5, 0x99, 0x8c, 0xca, 0xbd, 0xae, 0x05, 0x30, 0x60, 0xae, 0x6c, 0x7b, 0x43,
|
||||
0x78, 0xe8, 0x46, 0xd2, 0x9f, 0x37, 0xed, 0x7b, 0x4e, 0xa9, 0xec, 0x5d, 0x82, 0xe7,
|
||||
0x96, 0x1b, 0x7f, 0x25, 0xa9, 0x32, 0x38, 0x51, 0xf6, 0x81, 0xd5, 0x82, 0x36, 0x3a,
|
||||
0xa5, 0xf8, 0x99, 0x37, 0xf5, 0xa6, 0x72, 0x58, 0xbf, 0x63, 0xad, 0x6f, 0x1a, 0x0b,
|
||||
0x1d, 0x96, 0xdb, 0xd4, 0xfa, 0xdd, 0xfc, 0xef, 0xc5, 0x26, 0x6b, 0xa6, 0x61, 0x17,
|
||||
0x22, 0x39, 0x5c, 0x90, 0x65, 0x56, 0xbe, 0x52, 0xaf, 0xe3, 0xf5, 0x65, 0x63, 0x6a,
|
||||
0xd1, 0xb1, 0x7d, 0x50, 0x8b, 0x73, 0xd8, 0x74, 0x3e, 0xeb, 0x52, 0x4b, 0xe2, 0x2b,
|
||||
0x3d, 0xcb, 0xc2, 0xc7, 0x46, 0x8d, 0x54, 0x11, 0x9c, 0x74, 0x68, 0x44, 0x9a, 0x13,
|
||||
0xd8, 0xe3, 0xb9, 0x58, 0x11, 0xa1, 0x98, 0xf3, 0x49, 0x1d, 0xe3, 0xe7, 0xfe, 0x94,
|
||||
0x2b, 0x33, 0x04, 0x07, 0xab, 0xf8, 0x2a, 0x4e, 0xd7, 0xc1, 0xb3, 0x11, 0x66, 0x3a,
|
||||
0xc6, 0x98, 0x90, 0xf4, 0x15, 0x70, 0x15, 0x85, 0x3d, 0x91, 0xe9, 0x23, 0x03, 0x7c,
|
||||
0x22, 0x7a, 0x33, 0xcd, 0xd5, 0xec, 0x28, 0x1c, 0xa3, 0xf7, 0x9c, 0x44, 0x54, 0x6b,
|
||||
0x9d, 0x90, 0xca, 0x00, 0xf0, 0x64, 0xc9, 0x9e, 0x3d, 0xd9, 0x79, 0x11, 0xd3, 0x9f,
|
||||
0xe9, 0xc5, 0xd0, 0xb2, 0x3a, 0x22, 0x9a, 0x23, 0x4c, 0xb3, 0x61, 0x86, 0xc4, 0x81,
|
||||
0x9e, 0x8b, 0x9c, 0x59, 0x27, 0x72, 0x66, 0x32, 0x29, 0x1d, 0x6a, 0x41, 0x82, 0x11,
|
||||
0xcc, 0x29, 0x62, 0xe2, 0x0f, 0xe4, 0x7f, 0xeb, 0x3e, 0xdf, 0x33, 0x0f, 0x2c, 0x60,
|
||||
0x3a, 0x9d, 0x48, 0xc0, 0xfc, 0xb5, 0x69, 0x9d, 0xbf, 0xe5, 0x89, 0x64, 0x25, 0xc5,
|
||||
0xba, 0xc4, 0xae, 0xe8, 0x2e, 0x57, 0xa8, 0x5a, 0xaf, 0x4e, 0x25, 0x13, 0xe4, 0xf0,
|
||||
0x57, 0x96, 0xb0, 0x7b, 0xa2, 0xee, 0x47, 0xd8, 0x05, 0x06, 0xf8, 0xd2, 0xc2, 0x5e,
|
||||
0x50, 0xfd, 0x14, 0xde, 0x71, 0xe6, 0xc4, 0x18, 0x55, 0x93, 0x02, 0xf9, 0x39, 0xb0,
|
||||
0xe1, 0xab, 0xd5, 0x76, 0xf2, 0x79, 0xc4, 0xb2, 0xe0, 0xfe, 0xb8, 0x5c, 0x1f, 0x28,
|
||||
0xff, 0x18, 0xf5, 0x88, 0x91, 0xff, 0xef, 0x13, 0x2e, 0xef, 0x2f, 0xa0, 0x93, 0x46,
|
||||
0xae, 0xe3, 0x3c, 0x28, 0xeb, 0x13, 0x0f, 0xf2, 0x8f, 0x5b, 0x76, 0x69, 0x53, 0x33,
|
||||
0x41, 0x13, 0x21, 0x19, 0x96, 0xd2, 0x00, 0x11, 0xa1, 0x98, 0xe3, 0xfc, 0x43, 0x3f,
|
||||
0x9f, 0x25, 0x41, 0x01, 0x0a, 0xe1, 0x7c, 0x1b, 0xf2, 0x02, 0x58, 0x0f, 0x60, 0x47,
|
||||
0x47, 0x2f, 0xb3, 0x68, 0x57, 0xfe, 0x84, 0x3b, 0x19, 0xf5, 0x98, 0x40, 0x09, 0xdd,
|
||||
0xc3, 0x24, 0x04, 0x4e, 0x84, 0x7a, 0x4f, 0x4a, 0x0a, 0xb3, 0x4f, 0x71, 0x95, 0x95,
|
||||
0xde, 0x37, 0x25, 0x2d, 0x62, 0x35, 0x36, 0x5e, 0x9b, 0x84, 0x39, 0x2b, 0x06, 0x10,
|
||||
0x85, 0x34, 0x9d, 0x73, 0x20, 0x3a, 0x4a, 0x13, 0xe9, 0x6f, 0x54, 0x32, 0xec, 0x0f,
|
||||
0xd4, 0xa1, 0xee, 0x65, 0xac, 0xcd, 0xd5, 0xe3, 0x90, 0x4d, 0xf5, 0x4c, 0x1d, 0xa5,
|
||||
0x10, 0xb0, 0xff, 0x20, 0xdc, 0xc0, 0xc7, 0x7f, 0xcb, 0x2c, 0x0e, 0x0e, 0xb6, 0x05,
|
||||
0xcb, 0x05, 0x04, 0xdb, 0x87, 0x63, 0x2c, 0xf3, 0xd8, 0xb4, 0xda, 0xe6, 0xe7, 0x05,
|
||||
0x76, 0x9d, 0x1d, 0xe3, 0x54, 0x27, 0x01, 0x23, 0xcb, 0x11, 0x45, 0x0e, 0xfc, 0x60,
|
||||
0xac, 0x47, 0x68, 0x3d, 0x7b, 0x8d, 0x0f, 0x81, 0x13, 0x65, 0x56, 0x5f, 0xd9, 0x8c,
|
||||
0x4c, 0x8e, 0xb9, 0x36, 0xbc, 0xab, 0x8d, 0x06, 0x9f, 0xc3, 0x3b, 0xd8, 0x01, 0xb0,
|
||||
0x3a, 0xde, 0xa2, 0xe1, 0xfb, 0xc5, 0xaa, 0x46, 0x3d, 0x08, 0xca, 0x19, 0x89, 0x6d,
|
||||
0x2b, 0xf5, 0x9a, 0x07, 0x1b, 0x85, 0x1e, 0x6c, 0x23, 0x90, 0x52, 0x17, 0x2f, 0x29,
|
||||
0x6b, 0xfb, 0x5e, 0x72, 0x40, 0x47, 0x90, 0xa2, 0x18, 0x10, 0x14, 0xf3, 0xb9, 0x4a,
|
||||
0x4e, 0x97, 0xd1, 0x17, 0xb4, 0x38, 0x13, 0x03, 0x68, 0xcc, 0x39, 0xdb, 0xb2, 0xd1,
|
||||
0x98, 0x06, 0x5a, 0xe3, 0x98, 0x65, 0x47, 0x92, 0x6c, 0xd2, 0x16, 0x2f, 0x40, 0xa2,
|
||||
0x9f, 0x0c, 0x3c, 0x87, 0x45, 0xc0, 0xf5, 0x0f, 0xba, 0x38, 0x52, 0xe5, 0x66, 0xd4,
|
||||
0x45, 0x75, 0xc2, 0x9d, 0x39, 0xa0, 0x3f, 0x0c, 0xda, 0x72, 0x19, 0x84, 0xb6, 0xf4,
|
||||
0x40, 0x59, 0x1f, 0x35, 0x5e, 0x12, 0xd4, 0x39, 0xff, 0x15, 0x0a, 0xab, 0x76, 0x13,
|
||||
0x49, 0x9d, 0xbd, 0x49, 0xad, 0xab, 0xc8, 0x67, 0x6e, 0xef, 0x02, 0x3b, 0x15, 0xb6,
|
||||
0x5b, 0xfc, 0x5c, 0xa0, 0x69, 0x48, 0x10, 0x9f, 0x23, 0xf3, 0x50, 0xdb, 0x82, 0x12,
|
||||
0x35, 0x35, 0xeb, 0x8a, 0x74, 0x33, 0xbd, 0xab, 0xcb, 0x90, 0x92, 0x71, 0xa6, 0xec,
|
||||
0xbc, 0xb5, 0x8b, 0x93, 0x6a, 0x88, 0xcd, 0x4e, 0x8f, 0x2e, 0x6f, 0xf5, 0x80, 0x01,
|
||||
0x75, 0xf1, 0x13, 0x25, 0x3d, 0x8f, 0xa9, 0xca, 0x88, 0x85, 0xc2, 0xf5, 0x52, 0xe6,
|
||||
0x57, 0xdc, 0x60, 0x3f, 0x25, 0x2e, 0x1a, 0x8e, 0x30, 0x8f, 0x76, 0xf0, 0xbe, 0x79,
|
||||
0xe2, 0xfb, 0x8f, 0x5d, 0x5f, 0xbb, 0xe2, 0xe3, 0x0e, 0xca, 0xdd, 0x22, 0x07, 0x23,
|
||||
0xc8, 0xc0, 0xae, 0xa8, 0x07, 0x8c, 0xdf, 0xcb, 0x38, 0x68, 0x26, 0x3f, 0xf8, 0xf0,
|
||||
0x94, 0x00, 0x54, 0xda, 0x48, 0x78, 0x18, 0x93, 0xa7, 0xe4, 0x9a, 0xd5, 0xaf, 0xf4,
|
||||
0xaf, 0x30, 0x0c, 0xd8, 0x04, 0xa6, 0xb6, 0x27, 0x9a, 0xb3, 0xff, 0x3a, 0xfb, 0x64,
|
||||
0x49, 0x1c, 0x85, 0x19, 0x4a, 0xab, 0x76, 0x0d, 0x58, 0xa6, 0x06, 0x65, 0x4f, 0x9f,
|
||||
0x44, 0x00, 0xe8, 0xb3, 0x85, 0x91, 0x35, 0x6f, 0xbf, 0x64, 0x25, 0xac, 0xa2, 0x6d,
|
||||
0xc8, 0x52, 0x44, 0x25, 0x9f, 0xf2, 0xb1, 0x9c, 0x41, 0xb9, 0xf9, 0x6f, 0x3c, 0xa9,
|
||||
0xec, 0x1d, 0xde, 0x43, 0x4d, 0xa7, 0xd2, 0xd3, 0x92, 0xb9, 0x05, 0xdd, 0xf3, 0xd1,
|
||||
0xf9, 0xaf, 0x93, 0xd1, 0xaf, 0x59, 0x50, 0xbd, 0x49, 0x3f, 0x5a, 0xa7, 0x31, 0xb4,
|
||||
0x05, 0x6d, 0xf3, 0x1b, 0xd2, 0x67, 0xb6, 0xb9, 0x0a, 0x07, 0x98, 0x31, 0xaa, 0xf5,
|
||||
0x79, 0xbe, 0x0a, 0x39, 0x01, 0x31, 0x37, 0xaa, 0xc6, 0xd4, 0x04, 0xf5, 0x18, 0xcf,
|
||||
0xd4, 0x68, 0x40, 0x64, 0x7e, 0x78, 0xbf, 0xe7, 0x06, 0xca, 0x4c, 0xf5, 0xe9, 0xc5,
|
||||
0x45, 0x3e, 0x9f, 0x7c, 0xfd, 0x2b, 0x8b, 0x4c, 0x8d, 0x16, 0x9a, 0x44, 0xe5, 0x5c,
|
||||
0x88, 0xd4, 0xa9, 0xa7, 0xf9, 0x47, 0x42, 0x41, 0xe2, 0x21, 0xaf, 0x44, 0x86, 0x00,
|
||||
0x18, 0xab, 0x08, 0x56, 0x97, 0x2e, 0x19, 0x4c, 0xd9, 0x34,
|
||||
];
|
||||
|
||||
assert_eq!(&buf, PROTECTED);
|
||||
|
||||
let (header, payload) = buf.split_at_mut(header_len);
|
||||
let (first, rest) = header.split_at_mut(1);
|
||||
let sample = &payload[..sample_len];
|
||||
|
||||
let server_keys = Keys::initial(Version::V1, &CONNECTION_ID, false);
|
||||
server_keys
|
||||
.remote
|
||||
.header
|
||||
.decrypt_in_place(sample, &mut first[0], &mut rest[17..21])
|
||||
.unwrap();
|
||||
let payload = server_keys
|
||||
.remote
|
||||
.packet
|
||||
.decrypt_in_place(PACKET_NUMBER, &*header, payload)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(&payload[..PAYLOAD.len()], PAYLOAD);
|
||||
assert_eq!(payload.len(), buf.len() - header_len - tag_len);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
fn test_quic_exporter() {
|
||||
for &kt in ALL_KEY_TYPES.iter() {
|
||||
let client_config = make_client_config_with_versions(kt, &[&rustls::version::TLS13]);
|
||||
let server_config = make_server_config_with_versions(kt, &[&rustls::version::TLS13]);
|
||||
|
||||
do_exporter_test(client_config, server_config);
|
||||
}
|
||||
}
|
||||
} // mod test_quic
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_client_does_not_offer_sha1() {
|
||||
use tls_client::internal::msgs::{
|
||||
|
||||
@@ -1,292 +0,0 @@
|
||||
//! Tests for configuring and using a [`ClientCertVerifier`] for a server.
|
||||
|
||||
#![cfg(feature = "dangerous_configuration")]
|
||||
|
||||
mod common;
|
||||
|
||||
use crate::common::{
|
||||
dns_name, do_handshake_until_both_error, do_handshake_until_error, get_client_root_store,
|
||||
make_client_config_with_versions, make_client_config_with_versions_with_auth,
|
||||
make_pair_for_arc_configs, ErrorFromPeer, KeyType, ALL_KEY_TYPES,
|
||||
};
|
||||
use rustls::{
|
||||
client::WebPkiVerifier,
|
||||
internal::msgs::enums::{AlertDescription, ContentType},
|
||||
server::{ClientCertVerified, ClientCertVerifier},
|
||||
Certificate, ClientConnection, DistinguishedNames, Error, ServerConfig, ServerConnection,
|
||||
SignatureScheme,
|
||||
};
|
||||
use std::sync::Arc;
|
||||
|
||||
// Client is authorized!
|
||||
fn ver_ok() -> Result<ClientCertVerified, Error> {
|
||||
Ok(rustls::server::ClientCertVerified::assertion())
|
||||
}
|
||||
|
||||
// Use when we shouldn't even attempt verification
|
||||
fn ver_unreachable() -> Result<ClientCertVerified, Error> {
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
// Verifier that returns an error that we can expect
|
||||
fn ver_err() -> Result<ClientCertVerified, Error> {
|
||||
Err(Error::General("test err".to_string()))
|
||||
}
|
||||
|
||||
fn server_config_with_verifier(
|
||||
kt: KeyType,
|
||||
client_cert_verifier: MockClientVerifier,
|
||||
) -> ServerConfig {
|
||||
ServerConfig::builder()
|
||||
.with_safe_defaults()
|
||||
.with_client_cert_verifier(Arc::new(client_cert_verifier))
|
||||
.with_single_cert(kt.get_chain(), kt.get_key())
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
// Happy path, we resolve to a root, it is verified OK, should be able to connect
|
||||
fn client_verifier_works() {
|
||||
for kt in ALL_KEY_TYPES.iter() {
|
||||
let client_verifier = MockClientVerifier {
|
||||
verified: ver_ok,
|
||||
subjects: Some(get_client_root_store(*kt).subjects()),
|
||||
mandatory: Some(true),
|
||||
offered_schemes: None,
|
||||
};
|
||||
|
||||
let server_config = server_config_with_verifier(*kt, client_verifier);
|
||||
let server_config = Arc::new(server_config);
|
||||
|
||||
for version in rustls::ALL_VERSIONS {
|
||||
let client_config = make_client_config_with_versions_with_auth(*kt, &[version]);
|
||||
let (mut client, mut server) =
|
||||
make_pair_for_arc_configs(&Arc::new(client_config.clone()), &server_config);
|
||||
let err = do_handshake_until_error(&mut client, &mut server);
|
||||
assert_eq!(err, Ok(()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Server offers no verification schemes
|
||||
#[test]
|
||||
fn client_verifier_no_schemes() {
|
||||
for kt in ALL_KEY_TYPES.iter() {
|
||||
let client_verifier = MockClientVerifier {
|
||||
verified: ver_ok,
|
||||
subjects: Some(get_client_root_store(*kt).subjects()),
|
||||
mandatory: Some(true),
|
||||
offered_schemes: Some(vec![]),
|
||||
};
|
||||
|
||||
let server_config = server_config_with_verifier(*kt, client_verifier);
|
||||
let server_config = Arc::new(server_config);
|
||||
|
||||
for version in rustls::ALL_VERSIONS {
|
||||
let client_config = make_client_config_with_versions_with_auth(*kt, &[version]);
|
||||
let (mut client, mut server) =
|
||||
make_pair_for_arc_configs(&Arc::new(client_config.clone()), &server_config);
|
||||
let err = do_handshake_until_error(&mut client, &mut server);
|
||||
assert_eq!(
|
||||
err,
|
||||
Err(ErrorFromPeer::Client(Error::CorruptMessagePayload(
|
||||
ContentType::Handshake
|
||||
)))
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Common case, we do not find a root store to resolve to
|
||||
#[test]
|
||||
fn client_verifier_no_root() {
|
||||
for kt in ALL_KEY_TYPES.iter() {
|
||||
let client_verifier = MockClientVerifier {
|
||||
verified: ver_ok,
|
||||
subjects: None,
|
||||
mandatory: Some(true),
|
||||
offered_schemes: None,
|
||||
};
|
||||
|
||||
let server_config = server_config_with_verifier(*kt, client_verifier);
|
||||
let server_config = Arc::new(server_config);
|
||||
|
||||
for version in rustls::ALL_VERSIONS {
|
||||
let client_config = make_client_config_with_versions_with_auth(*kt, &[version]);
|
||||
let mut server = ServerConnection::new(Arc::clone(&server_config)).unwrap();
|
||||
let mut client =
|
||||
ClientConnection::new(Arc::new(client_config), dns_name("notlocalhost")).unwrap();
|
||||
let errs = do_handshake_until_both_error(&mut client, &mut server);
|
||||
assert_eq!(
|
||||
errs,
|
||||
Err(vec![
|
||||
ErrorFromPeer::Server(Error::General(
|
||||
"client rejected by client_auth_root_subjects".into()
|
||||
)),
|
||||
ErrorFromPeer::Client(Error::AlertReceived(AlertDescription::AccessDenied))
|
||||
])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we cannot resolve a root, we cannot decide if auth is mandatory
|
||||
#[test]
|
||||
fn client_verifier_no_auth_no_root() {
|
||||
for kt in ALL_KEY_TYPES.iter() {
|
||||
let client_verifier = MockClientVerifier {
|
||||
verified: ver_unreachable,
|
||||
subjects: None,
|
||||
mandatory: Some(true),
|
||||
offered_schemes: None,
|
||||
};
|
||||
|
||||
let server_config = server_config_with_verifier(*kt, client_verifier);
|
||||
let server_config = Arc::new(server_config);
|
||||
|
||||
for version in rustls::ALL_VERSIONS {
|
||||
let client_config = make_client_config_with_versions(*kt, &[version]);
|
||||
let mut server = ServerConnection::new(Arc::clone(&server_config)).unwrap();
|
||||
let mut client =
|
||||
ClientConnection::new(Arc::new(client_config), dns_name("notlocalhost")).unwrap();
|
||||
let errs = do_handshake_until_both_error(&mut client, &mut server);
|
||||
assert_eq!(
|
||||
errs,
|
||||
Err(vec![
|
||||
ErrorFromPeer::Server(Error::General(
|
||||
"client rejected by client_auth_root_subjects".into()
|
||||
)),
|
||||
ErrorFromPeer::Client(Error::AlertReceived(AlertDescription::AccessDenied))
|
||||
])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we do have a root, we must do auth
|
||||
#[test]
|
||||
fn client_verifier_no_auth_yes_root() {
|
||||
for kt in ALL_KEY_TYPES.iter() {
|
||||
let client_verifier = MockClientVerifier {
|
||||
verified: ver_unreachable,
|
||||
subjects: Some(get_client_root_store(*kt).subjects()),
|
||||
mandatory: Some(true),
|
||||
offered_schemes: None,
|
||||
};
|
||||
|
||||
let server_config = server_config_with_verifier(*kt, client_verifier);
|
||||
let server_config = Arc::new(server_config);
|
||||
|
||||
for version in rustls::ALL_VERSIONS {
|
||||
let client_config = make_client_config_with_versions(*kt, &[version]);
|
||||
let mut server = ServerConnection::new(Arc::clone(&server_config)).unwrap();
|
||||
let mut client =
|
||||
ClientConnection::new(Arc::new(client_config), dns_name("localhost")).unwrap();
|
||||
let errs = do_handshake_until_both_error(&mut client, &mut server);
|
||||
assert_eq!(
|
||||
errs,
|
||||
Err(vec![
|
||||
ErrorFromPeer::Server(Error::NoCertificatesPresented),
|
||||
ErrorFromPeer::Client(Error::AlertReceived(
|
||||
AlertDescription::CertificateRequired
|
||||
))
|
||||
])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
// Triple checks we propagate the rustls::Error through
|
||||
fn client_verifier_fails_properly() {
|
||||
for kt in ALL_KEY_TYPES.iter() {
|
||||
let client_verifier = MockClientVerifier {
|
||||
verified: ver_err,
|
||||
subjects: Some(get_client_root_store(*kt).subjects()),
|
||||
mandatory: Some(true),
|
||||
offered_schemes: None,
|
||||
};
|
||||
|
||||
let server_config = server_config_with_verifier(*kt, client_verifier);
|
||||
let server_config = Arc::new(server_config);
|
||||
|
||||
for version in rustls::ALL_VERSIONS {
|
||||
let client_config = make_client_config_with_versions_with_auth(*kt, &[version]);
|
||||
let mut server = ServerConnection::new(Arc::clone(&server_config)).unwrap();
|
||||
let mut client =
|
||||
ClientConnection::new(Arc::new(client_config), dns_name("localhost")).unwrap();
|
||||
let err = do_handshake_until_error(&mut client, &mut server);
|
||||
assert_eq!(
|
||||
err,
|
||||
Err(ErrorFromPeer::Server(Error::General("test err".into())))
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
// If a verifier returns a None on Mandatory-ness, then we error out
|
||||
fn client_verifier_must_determine_client_auth_requirement_to_continue() {
|
||||
for kt in ALL_KEY_TYPES.iter() {
|
||||
let client_verifier = MockClientVerifier {
|
||||
verified: ver_ok,
|
||||
subjects: Some(get_client_root_store(*kt).subjects()),
|
||||
mandatory: None,
|
||||
offered_schemes: None,
|
||||
};
|
||||
|
||||
let server_config = server_config_with_verifier(*kt, client_verifier);
|
||||
let server_config = Arc::new(server_config);
|
||||
|
||||
for version in rustls::ALL_VERSIONS {
|
||||
let client_config = make_client_config_with_versions_with_auth(*kt, &[version]);
|
||||
let mut server = ServerConnection::new(Arc::clone(&server_config)).unwrap();
|
||||
let mut client =
|
||||
ClientConnection::new(Arc::new(client_config), dns_name("localhost")).unwrap();
|
||||
let errs = do_handshake_until_both_error(&mut client, &mut server);
|
||||
assert_eq!(
|
||||
errs,
|
||||
Err(vec![
|
||||
ErrorFromPeer::Server(Error::General(
|
||||
"client rejected by client_auth_mandatory".into()
|
||||
)),
|
||||
ErrorFromPeer::Client(Error::AlertReceived(AlertDescription::AccessDenied))
|
||||
])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MockClientVerifier {
|
||||
pub verified: fn() -> Result<ClientCertVerified, Error>,
|
||||
pub subjects: Option<DistinguishedNames>,
|
||||
pub mandatory: Option<bool>,
|
||||
pub offered_schemes: Option<Vec<SignatureScheme>>,
|
||||
}
|
||||
|
||||
impl ClientCertVerifier for MockClientVerifier {
|
||||
fn client_auth_mandatory(&self) -> Option<bool> {
|
||||
self.mandatory
|
||||
}
|
||||
|
||||
fn client_auth_root_subjects(&self) -> Option<DistinguishedNames> {
|
||||
self.subjects.as_ref().cloned()
|
||||
}
|
||||
|
||||
fn verify_client_cert(
|
||||
&self,
|
||||
_end_entity: &Certificate,
|
||||
_intermediates: &[Certificate],
|
||||
_now: web_time::SystemTime,
|
||||
) -> Result<ClientCertVerified, Error> {
|
||||
(self.verified)()
|
||||
}
|
||||
|
||||
fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
|
||||
if let Some(schemes) = &self.offered_schemes {
|
||||
schemes.clone()
|
||||
} else {
|
||||
WebPkiVerifier::verification_schemes()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
//! Tests of [`tls_client::KeyLogFile`] that require us to set environment variables.
|
||||
//!
|
||||
//! vvvv
|
||||
//! Every test you add to this file MUST execute through `serialized()`.
|
||||
//! ^^^^
|
||||
//!
|
||||
//! See https://github.com/rust-lang/rust/issues/90308; despite not being marked
|
||||
//! `unsafe`, `env::var::set_var` is an unsafe function. These tests are separated
|
||||
//! from the rest of the tests so that their use of `set_ver` is less likely to
|
||||
//! affect them; as of the time these tests were moved to this file, Cargo will
|
||||
//! compile each test suite file to a separate executable, so these will be run
|
||||
//! in a completely separate process. This way, executing every test through
|
||||
//! `serialized()` will cause them to be run one at a time.
|
||||
//!
|
||||
//! Note: If/when we add new constructors to `KeyLogFile` to allow constructing
|
||||
//! one from a path directly (without using an environment variable), then those
|
||||
//! tests SHOULD NOT go in this file.
|
||||
//!
|
||||
//! XXX: These tests don't actually test the functionality; they just ensure
|
||||
//! the code coverage doesn't complain it isn't covered. TODO: Verify that the
|
||||
//! file was created successfully, with the right permissions, etc., and that it
|
||||
//! contains something like what we expect.
|
||||
|
||||
#![allow(dead_code, unused_imports)]
|
||||
|
||||
mod common;
|
||||
|
||||
use crate::common::{
|
||||
do_handshake, make_client_config_with_versions, make_pair_for_arc_configs, make_server_config,
|
||||
receive, send, KeyType,
|
||||
};
|
||||
use std::{
|
||||
env,
|
||||
io::Write,
|
||||
sync::{Arc, Mutex, Once},
|
||||
};
|
||||
|
||||
/// Approximates `#[serial]` from the `serial_test` crate.
|
||||
///
|
||||
/// No attempt is made to recover from a poisoned mutex, which will
|
||||
/// happen when `f` panics. In other words, all the tests that use
|
||||
/// `serialized` will start failing after one test panics.
|
||||
fn serialized(f: impl FnOnce()) {
|
||||
// Ensure every test is run serialized
|
||||
// TODO: Use `std::sync::Lazy` once that is stable.
|
||||
static mut MUTEX: Option<Mutex<()>> = None;
|
||||
static ONCE: Once = Once::new();
|
||||
ONCE.call_once(|| unsafe {
|
||||
MUTEX = Some(Mutex::new(()));
|
||||
});
|
||||
let mutex = unsafe { MUTEX.as_mut() };
|
||||
|
||||
let _guard = mutex.unwrap().lock().unwrap();
|
||||
|
||||
// XXX: NOT thread safe.
|
||||
env::set_var("SSLKEYLOGFILE", "./sslkeylogfile.txt");
|
||||
|
||||
f()
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn exercise_key_log_file_for_client() {
|
||||
// serialized(|| {
|
||||
// let server_config = Arc::new(make_server_config(KeyType::Rsa));
|
||||
// env::set_var("SSLKEYLOGFILE", "./sslkeylogfile.txt");
|
||||
|
||||
// for version in tls_client::ALL_VERSIONS {
|
||||
// let mut client_config = make_client_config_with_versions(KeyType::Rsa, &[version]);
|
||||
// client_config.key_log = Arc::new(tls_client::KeyLogFile::new());
|
||||
|
||||
// let (mut client, mut server) =
|
||||
// make_pair_for_arc_configs(&Arc::new(client_config), &server_config);
|
||||
|
||||
// assert_eq!(5, client.writer().write(b"hello").unwrap());
|
||||
|
||||
// do_handshake(&mut client, &mut server);
|
||||
// send(&mut client, &mut server);
|
||||
// server.process_new_packets().unwrap();
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
|
||||
// #[test]
|
||||
// fn exercise_key_log_file_for_server() {
|
||||
// serialized(|| {
|
||||
// let mut server_config = make_server_config(KeyType::Rsa);
|
||||
|
||||
// env::set_var("SSLKEYLOGFILE", "./sslkeylogfile.txt");
|
||||
// server_config.key_log = Arc::new(rustls::KeyLogFile::new());
|
||||
|
||||
// let server_config = Arc::new(server_config);
|
||||
|
||||
// for version in tls_client::ALL_VERSIONS {
|
||||
// let client_config = make_client_config_with_versions(KeyType::Rsa, &[version]);
|
||||
// let (mut client, mut server) =
|
||||
// make_pair_for_arc_configs(&Arc::new(client_config), &server_config);
|
||||
|
||||
// assert_eq!(5, client.writer().write(b"hello").unwrap());
|
||||
|
||||
// do_handshake(&mut client, &mut server);
|
||||
// send(&mut client, &mut server);
|
||||
// server.process_new_packets().unwrap();
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
@@ -1,266 +0,0 @@
|
||||
//! Tests for configuring and using a [`ServerCertVerifier`] for a client.
|
||||
|
||||
#![cfg(feature = "dangerous_configuration")]
|
||||
|
||||
mod common;
|
||||
use crate::common::{
|
||||
do_handshake, do_handshake_until_both_error, make_client_config_with_versions,
|
||||
make_pair_for_arc_configs, make_server_config, ErrorFromPeer, ALL_KEY_TYPES,
|
||||
};
|
||||
use rustls::{
|
||||
client::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier, WebPkiVerifier},
|
||||
internal::msgs::{enums::AlertDescription, handshake::DigitallySignedStruct},
|
||||
Certificate, Error, SignatureScheme,
|
||||
};
|
||||
use std::sync::Arc;
|
||||
|
||||
#[test]
|
||||
fn client_can_override_certificate_verification() {
|
||||
for kt in ALL_KEY_TYPES.iter() {
|
||||
let verifier = Arc::new(MockServerVerifier::accepts_anything());
|
||||
|
||||
let server_config = Arc::new(make_server_config(*kt));
|
||||
|
||||
for version in rustls::ALL_VERSIONS {
|
||||
let mut client_config = make_client_config_with_versions(*kt, &[version]);
|
||||
client_config
|
||||
.dangerous()
|
||||
.set_certificate_verifier(verifier.clone());
|
||||
|
||||
let (mut client, mut server) =
|
||||
make_pair_for_arc_configs(&Arc::new(client_config), &server_config);
|
||||
do_handshake(&mut client, &mut server);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn client_can_override_certificate_verification_and_reject_certificate() {
|
||||
for kt in ALL_KEY_TYPES.iter() {
|
||||
let verifier = Arc::new(MockServerVerifier::rejects_certificate(
|
||||
Error::CorruptMessage,
|
||||
));
|
||||
|
||||
let server_config = Arc::new(make_server_config(*kt));
|
||||
|
||||
for version in rustls::ALL_VERSIONS {
|
||||
let mut client_config = make_client_config_with_versions(*kt, &[version]);
|
||||
client_config
|
||||
.dangerous()
|
||||
.set_certificate_verifier(verifier.clone());
|
||||
|
||||
let (mut client, mut server) =
|
||||
make_pair_for_arc_configs(&Arc::new(client_config), &server_config);
|
||||
let errs = do_handshake_until_both_error(&mut client, &mut server);
|
||||
assert_eq!(
|
||||
errs,
|
||||
Err(vec![
|
||||
ErrorFromPeer::Client(Error::CorruptMessage),
|
||||
ErrorFromPeer::Server(Error::AlertReceived(AlertDescription::BadCertificate))
|
||||
])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn client_can_override_certificate_verification_and_reject_tls12_signatures() {
|
||||
for kt in ALL_KEY_TYPES.iter() {
|
||||
let mut client_config = make_client_config_with_versions(*kt, &[&rustls::version::TLS12]);
|
||||
let verifier = Arc::new(MockServerVerifier::rejects_tls12_signatures(
|
||||
Error::CorruptMessage,
|
||||
));
|
||||
|
||||
client_config.dangerous().set_certificate_verifier(verifier);
|
||||
|
||||
let server_config = Arc::new(make_server_config(*kt));
|
||||
|
||||
let (mut client, mut server) =
|
||||
make_pair_for_arc_configs(&Arc::new(client_config), &server_config);
|
||||
let errs = do_handshake_until_both_error(&mut client, &mut server);
|
||||
assert_eq!(
|
||||
errs,
|
||||
Err(vec![
|
||||
ErrorFromPeer::Client(Error::CorruptMessage),
|
||||
ErrorFromPeer::Server(Error::AlertReceived(AlertDescription::BadCertificate))
|
||||
])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn client_can_override_certificate_verification_and_reject_tls13_signatures() {
|
||||
for kt in ALL_KEY_TYPES.iter() {
|
||||
let mut client_config = make_client_config_with_versions(*kt, &[&rustls::version::TLS13]);
|
||||
let verifier = Arc::new(MockServerVerifier::rejects_tls13_signatures(
|
||||
Error::CorruptMessage,
|
||||
));
|
||||
|
||||
client_config.dangerous().set_certificate_verifier(verifier);
|
||||
|
||||
let server_config = Arc::new(make_server_config(*kt));
|
||||
|
||||
let (mut client, mut server) =
|
||||
make_pair_for_arc_configs(&Arc::new(client_config), &server_config);
|
||||
let errs = do_handshake_until_both_error(&mut client, &mut server);
|
||||
assert_eq!(
|
||||
errs,
|
||||
Err(vec![
|
||||
ErrorFromPeer::Client(Error::CorruptMessage),
|
||||
ErrorFromPeer::Server(Error::AlertReceived(AlertDescription::BadCertificate))
|
||||
])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn client_can_override_certificate_verification_and_offer_no_signature_schemes() {
|
||||
for kt in ALL_KEY_TYPES.iter() {
|
||||
let verifier = Arc::new(MockServerVerifier::offers_no_signature_schemes());
|
||||
|
||||
let server_config = Arc::new(make_server_config(*kt));
|
||||
|
||||
for version in rustls::ALL_VERSIONS {
|
||||
let mut client_config = make_client_config_with_versions(*kt, &[version]);
|
||||
client_config
|
||||
.dangerous()
|
||||
.set_certificate_verifier(verifier.clone());
|
||||
|
||||
let (mut client, mut server) =
|
||||
make_pair_for_arc_configs(&Arc::new(client_config), &server_config);
|
||||
let errs = do_handshake_until_both_error(&mut client, &mut server);
|
||||
assert_eq!(
|
||||
errs,
|
||||
Err(vec![
|
||||
ErrorFromPeer::Server(Error::PeerIncompatibleError(
|
||||
"no overlapping sigschemes".into()
|
||||
)),
|
||||
ErrorFromPeer::Client(Error::AlertReceived(AlertDescription::HandshakeFailure)),
|
||||
])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MockServerVerifier {
|
||||
cert_rejection_error: Option<Error>,
|
||||
tls12_signature_error: Option<Error>,
|
||||
tls13_signature_error: Option<Error>,
|
||||
wants_scts: bool,
|
||||
signature_schemes: Vec<SignatureScheme>,
|
||||
}
|
||||
|
||||
impl ServerCertVerifier for MockServerVerifier {
|
||||
fn verify_server_cert(
|
||||
&self,
|
||||
end_entity: &rustls::Certificate,
|
||||
intermediates: &[rustls::Certificate],
|
||||
server_name: &rustls::ServerName,
|
||||
scts: &mut dyn Iterator<Item = &[u8]>,
|
||||
oscp_response: &[u8],
|
||||
now: web_time::SystemTime,
|
||||
) -> Result<ServerCertVerified, Error> {
|
||||
let scts: Vec<Vec<u8>> = scts.map(|x| x.to_owned()).collect();
|
||||
println!(
|
||||
"verify_server_cert({:?}, {:?}, {:?}, {:?}, {:?}, {:?})",
|
||||
end_entity, intermediates, server_name, scts, oscp_response, now
|
||||
);
|
||||
if let Some(error) = &self.cert_rejection_error {
|
||||
Err(error.clone())
|
||||
} else {
|
||||
Ok(ServerCertVerified::assertion())
|
||||
}
|
||||
}
|
||||
|
||||
fn verify_tls12_signature(
|
||||
&self,
|
||||
message: &[u8],
|
||||
cert: &Certificate,
|
||||
dss: &DigitallySignedStruct,
|
||||
) -> Result<HandshakeSignatureValid, Error> {
|
||||
println!(
|
||||
"verify_tls12_signature({:?}, {:?}, {:?})",
|
||||
message, cert, dss
|
||||
);
|
||||
if let Some(error) = &self.tls12_signature_error {
|
||||
Err(error.clone())
|
||||
} else {
|
||||
Ok(HandshakeSignatureValid::assertion())
|
||||
}
|
||||
}
|
||||
|
||||
fn verify_tls13_signature(
|
||||
&self,
|
||||
message: &[u8],
|
||||
cert: &Certificate,
|
||||
dss: &DigitallySignedStruct,
|
||||
) -> Result<HandshakeSignatureValid, Error> {
|
||||
println!(
|
||||
"verify_tls13_signature({:?}, {:?}, {:?})",
|
||||
message, cert, dss
|
||||
);
|
||||
if let Some(error) = &self.tls13_signature_error {
|
||||
Err(error.clone())
|
||||
} else {
|
||||
Ok(HandshakeSignatureValid::assertion())
|
||||
}
|
||||
}
|
||||
|
||||
fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
|
||||
self.signature_schemes.clone()
|
||||
}
|
||||
|
||||
fn request_scts(&self) -> bool {
|
||||
println!("request_scts? {:?}", self.wants_scts);
|
||||
self.wants_scts
|
||||
}
|
||||
}
|
||||
|
||||
impl MockServerVerifier {
|
||||
pub fn accepts_anything() -> Self {
|
||||
MockServerVerifier {
|
||||
cert_rejection_error: None,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn rejects_certificate(err: Error) -> Self {
|
||||
MockServerVerifier {
|
||||
cert_rejection_error: Some(err),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn rejects_tls12_signatures(err: Error) -> Self {
|
||||
MockServerVerifier {
|
||||
tls12_signature_error: Some(err),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn rejects_tls13_signatures(err: Error) -> Self {
|
||||
MockServerVerifier {
|
||||
tls13_signature_error: Some(err),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn offers_no_signature_schemes() -> Self {
|
||||
MockServerVerifier {
|
||||
signature_schemes: vec![],
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for MockServerVerifier {
|
||||
fn default() -> Self {
|
||||
MockServerVerifier {
|
||||
cert_rejection_error: None,
|
||||
tls12_signature_error: None,
|
||||
tls13_signature_error: None,
|
||||
wants_scts: false,
|
||||
signature_schemes: WebPkiVerifier::verification_schemes(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ use crate::{MpcTlsCommonConfig, TlsRole};
|
||||
|
||||
/// Builds the components for MPC-TLS.
|
||||
// TODO: Better dependency injection!!
|
||||
#[allow(clippy::too_many_arguments, clippy::type_complexity)]
|
||||
pub fn build_components<Ctx, T, OTS, OTR>(
|
||||
role: TlsRole,
|
||||
config: &MpcTlsCommonConfig,
|
||||
|
||||
@@ -198,9 +198,7 @@ impl MpcTlsFollower {
|
||||
loop {
|
||||
futures::select! {
|
||||
res = &mut remote_fut => {
|
||||
if let Err(e) = res {
|
||||
return Err(e);
|
||||
}
|
||||
res?;
|
||||
},
|
||||
res = &mut actor_fut => return res,
|
||||
}
|
||||
|
||||
@@ -169,10 +169,10 @@ mod tests {
|
||||
);
|
||||
|
||||
// Sum check.
|
||||
for k in 0..message_len {
|
||||
for (k, item) in powers_h.iter().enumerate().take(message_len) {
|
||||
assert_eq!(
|
||||
sender.state().add_shares[k] + receiver.state().add_shares[k],
|
||||
powers_h[k]
|
||||
*item
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,6 +89,7 @@ impl<C, Ctx> Debug for Ghash<C, Ctx> {
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
#[allow(clippy::blocks_in_conditions)]
|
||||
impl<Ctx, C> UniversalHash for Ghash<C, Ctx>
|
||||
where
|
||||
Ctx: Context,
|
||||
|
||||
@@ -26,7 +26,6 @@ axum = { version = "0.7", features = ["ws"] }
|
||||
axum-core = "0.4"
|
||||
axum-macros = "0.4"
|
||||
base64 = "0.21.0"
|
||||
chrono = "0.4.31"
|
||||
csv = "1.3.0"
|
||||
eyre = "0.6.8"
|
||||
futures = "0.3"
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
|
||||
use chrono::{DateTime, Utc};
|
||||
use p256::ecdsa::SigningKey;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::sync::Mutex;
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
use crate::{config::NotarizationProperties, domain::auth::AuthorizationWhitelistRecord};
|
||||
|
||||
@@ -48,7 +48,6 @@ pub enum ClientType {
|
||||
pub struct SessionData {
|
||||
pub max_sent_data: Option<usize>,
|
||||
pub max_recv_data: Option<usize>,
|
||||
pub created_at: DateTime<Utc>,
|
||||
}
|
||||
|
||||
/// Global data that needs to be shared with the axum handlers
|
||||
|
||||
@@ -97,9 +97,6 @@ mod test {
|
||||
#[test]
|
||||
fn test_api_key_is_absent() {
|
||||
let whitelist = get_whitelist_fixture();
|
||||
assert_eq!(
|
||||
api_key_is_valid("test-api-keY-0", &Arc::new(whitelist)),
|
||||
false
|
||||
);
|
||||
assert!(!api_key_is_valid("test-api-keY-0", &Arc::new(whitelist)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ use axum::{
|
||||
response::{IntoResponse, Json, Response},
|
||||
};
|
||||
use axum_macros::debug_handler;
|
||||
use chrono::Utc;
|
||||
use p256::ecdsa::{Signature, SigningKey};
|
||||
use tlsn_verifier::tls::{Verifier, VerifierConfig};
|
||||
use tokio::io::{AsyncRead, AsyncWrite};
|
||||
@@ -153,7 +152,6 @@ pub async fn initialize(
|
||||
SessionData {
|
||||
max_sent_data: payload.max_sent_data,
|
||||
max_recv_data: payload.max_recv_data,
|
||||
created_at: Utc::now(),
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
@@ -29,11 +29,11 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn runtime_vs_latency(all_data: &Vec<Metrics>) -> Result<Chart, Box<dyn std::error::Error>> {
|
||||
fn runtime_vs_latency(all_data: &[Metrics]) -> Result<Chart, Box<dyn std::error::Error>> {
|
||||
const TITLE: &str = "Runtime vs Latency";
|
||||
|
||||
let data: Vec<Vec<f32>> = all_data
|
||||
.into_iter()
|
||||
.iter()
|
||||
.filter(|record| record.name == "latency")
|
||||
.map(|record| {
|
||||
let total_delay = record.upload_delay + record.download_delay; // Calculate the sum of upload and download delays.
|
||||
@@ -83,21 +83,21 @@ fn runtime_vs_latency(all_data: &Vec<Metrics>) -> Result<Chart, Box<dyn std::err
|
||||
Ok(chart)
|
||||
}
|
||||
|
||||
fn runtime_vs_bandwidth(all_data: &Vec<Metrics>) -> Result<Chart, Box<dyn std::error::Error>> {
|
||||
fn runtime_vs_bandwidth(all_data: &[Metrics]) -> Result<Chart, Box<dyn std::error::Error>> {
|
||||
const TITLE: &str = "Runtime vs Bandwidth";
|
||||
|
||||
let download_data: Vec<Vec<f32>> = all_data
|
||||
.into_iter()
|
||||
.iter()
|
||||
.filter(|record| record.name == "download_bandwidth")
|
||||
.map(|record| vec![record.download as f32, record.runtime as f32])
|
||||
.collect();
|
||||
let upload_deferred_data: Vec<Vec<f32>> = all_data
|
||||
.into_iter()
|
||||
.iter()
|
||||
.filter(|record| record.name == "upload_bandwidth" && record.defer_decryption)
|
||||
.map(|record| vec![record.upload as f32, record.runtime as f32])
|
||||
.collect();
|
||||
let upload_non_deferred_data: Vec<Vec<f32>> = all_data
|
||||
.into_iter()
|
||||
.iter()
|
||||
.filter(|record| record.name == "upload_bandwidth" && !record.defer_decryption)
|
||||
.map(|record| vec![record.upload as f32, record.runtime as f32])
|
||||
.collect();
|
||||
|
||||
@@ -35,12 +35,12 @@ pub fn set_up() -> io::Result<()> {
|
||||
set_default_route(
|
||||
PROVER_NAMESPACE,
|
||||
PROVER_INTERFACE,
|
||||
PROVER_SUBNET.split('/').nth(0).unwrap(),
|
||||
PROVER_SUBNET.split('/').next().unwrap(),
|
||||
)?;
|
||||
set_default_route(
|
||||
VERIFIER_NAMESPACE,
|
||||
VERIFIER_INTERFACE,
|
||||
VERIFIER_SUBNET.split('/').nth(0).unwrap(),
|
||||
VERIFIER_SUBNET.split('/').next().unwrap(),
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
@@ -49,7 +49,7 @@ pub fn set_up() -> io::Result<()> {
|
||||
pub fn clean_up() {
|
||||
// Delete interface pair
|
||||
if let Err(e) = Command::new("ip")
|
||||
.args(&[
|
||||
.args([
|
||||
"netns",
|
||||
"exec",
|
||||
PROVER_NAMESPACE,
|
||||
@@ -65,14 +65,14 @@ pub fn clean_up() {
|
||||
|
||||
// Delete namespaces
|
||||
if let Err(e) = Command::new("ip")
|
||||
.args(&["netns", "del", PROVER_NAMESPACE])
|
||||
.args(["netns", "del", PROVER_NAMESPACE])
|
||||
.status()
|
||||
{
|
||||
println!("Error deleting namespace {}: {}", PROVER_NAMESPACE, e);
|
||||
}
|
||||
|
||||
if let Err(e) = Command::new("ip")
|
||||
.args(&["netns", "del", VERIFIER_NAMESPACE])
|
||||
.args(["netns", "del", VERIFIER_NAMESPACE])
|
||||
.status()
|
||||
{
|
||||
println!("Error deleting namespace {}: {}", VERIFIER_NAMESPACE, e);
|
||||
@@ -138,7 +138,7 @@ pub fn set_interface(interface: &str, egress: usize, burst: usize, delay: usize)
|
||||
fn create_network_namespace(name: &str) -> io::Result<()> {
|
||||
// Check if namespace already exists
|
||||
if Command::new("ip")
|
||||
.args(&["netns", "list"])
|
||||
.args(["netns", "list"])
|
||||
.output()?
|
||||
.stdout
|
||||
.windows(name.len())
|
||||
@@ -148,7 +148,7 @@ fn create_network_namespace(name: &str) -> io::Result<()> {
|
||||
return Ok(());
|
||||
} else {
|
||||
println!("Creating namespace {}", name);
|
||||
Command::new("ip").args(&["netns", "add", name]).status()?;
|
||||
Command::new("ip").args(["netns", "add", name]).status()?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -170,7 +170,7 @@ fn create_veth_pair(
|
||||
|
||||
// Create veth pair
|
||||
Command::new("ip")
|
||||
.args(&[
|
||||
.args([
|
||||
"link",
|
||||
"add",
|
||||
left_interface,
|
||||
@@ -196,7 +196,7 @@ fn create_veth_pair(
|
||||
|
||||
fn attach_interface_to_namespace(namespace: &str, interface: &str) -> io::Result<()> {
|
||||
Command::new("ip")
|
||||
.args(&["link", "set", interface, "netns", namespace])
|
||||
.args(["link", "set", interface, "netns", namespace])
|
||||
.status()?;
|
||||
|
||||
println!("Attached {} to namespace {}", interface, namespace);
|
||||
@@ -206,7 +206,7 @@ fn attach_interface_to_namespace(namespace: &str, interface: &str) -> io::Result
|
||||
|
||||
fn set_default_route(namespace: &str, interface: &str, ip: &str) -> io::Result<()> {
|
||||
Command::new("ip")
|
||||
.args(&[
|
||||
.args([
|
||||
"netns", "exec", namespace, "ip", "route", "add", "default", "via", ip, "dev",
|
||||
interface,
|
||||
])
|
||||
@@ -225,7 +225,7 @@ fn is_interface_present_in_namespace(
|
||||
interface: &str,
|
||||
) -> Result<bool, std::io::Error> {
|
||||
Ok(Command::new("ip")
|
||||
.args(&[
|
||||
.args([
|
||||
"netns", "exec", namespace, "ip", "link", "list", "dev", interface,
|
||||
])
|
||||
.output()?
|
||||
@@ -236,7 +236,7 @@ fn is_interface_present_in_namespace(
|
||||
|
||||
fn set_device_up(namespace: &str, interface: &str) -> io::Result<()> {
|
||||
Command::new("ip")
|
||||
.args(&[
|
||||
.args([
|
||||
"netns", "exec", namespace, "ip", "link", "set", interface, "up",
|
||||
])
|
||||
.status()?;
|
||||
@@ -246,7 +246,7 @@ fn set_device_up(namespace: &str, interface: &str) -> io::Result<()> {
|
||||
|
||||
fn assign_ip_to_interface(namespace: &str, interface: &str, ip: &str) -> io::Result<()> {
|
||||
Command::new("ip")
|
||||
.args(&[
|
||||
.args([
|
||||
"netns", "exec", namespace, "ip", "addr", "add", ip, "dev", interface,
|
||||
])
|
||||
.status()?;
|
||||
|
||||
@@ -94,7 +94,7 @@ async fn bytes(
|
||||
.and_then(|size| size.parse::<usize>().ok())
|
||||
.unwrap_or(1);
|
||||
|
||||
if params.get("shutdown").is_some() {
|
||||
if params.contains_key("shutdown") {
|
||||
_ = state.lock().unwrap().shutdown.take().unwrap().send(());
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ async fn json(
|
||||
.and_then(|size| size.parse::<usize>().ok())
|
||||
.unwrap_or(1);
|
||||
|
||||
if params.get("shutdown").is_some() {
|
||||
if params.contains_key("shutdown") {
|
||||
_ = state.lock().unwrap().shutdown.take().unwrap().send(());
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ async fn html(
|
||||
State(state): State<Arc<Mutex<AppState>>>,
|
||||
Query(params): Query<HashMap<String, String>>,
|
||||
) -> Html<&'static str> {
|
||||
if params.get("shutdown").is_some() {
|
||||
if params.contains_key("shutdown") {
|
||||
_ = state.lock().unwrap().shutdown.take().unwrap().send(());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user