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 commit 74bdb4a6f8, reversing
changes made to e361a86e6a.

* 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:
yuroitaki
2024-07-22 11:44:55 +08:00
committed by GitHub
parent b24aea4fad
commit 7377eaf661
33 changed files with 67 additions and 1567 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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,

View File

@@ -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() {

View File

@@ -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 { .. })
)
}

View File

@@ -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,

View File

@@ -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

View File

@@ -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>,

View File

@@ -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,

View File

@@ -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! {

View File

@@ -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

View File

@@ -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");
}

View File

@@ -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

View File

@@ -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,

View File

@@ -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)]

View File

@@ -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")]

View File

@@ -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");
}
}
}

View File

@@ -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::{

View File

@@ -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()
}
}
}

View File

@@ -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();
// }
// })
// }

View File

@@ -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(),
}
}
}

View File

@@ -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,

View File

@@ -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,
}

View File

@@ -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
);
}
}

View File

@@ -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,

View File

@@ -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"

View File

@@ -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

View File

@@ -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)));
}
}

View File

@@ -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(),
},
);

View File

@@ -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();

View File

@@ -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()?;

View File

@@ -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(());
}