Skip to content

build(deps): bump the rustls group across 1 directory with 3 updates #3908

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1450,7 +1450,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667"
dependencies = [
"cfg-if",
"windows-targets 0.52.6",
"windows-targets 0.48.5",
]

[[package]]
Expand Down Expand Up @@ -3754,9 +3754,9 @@ dependencies = [

[[package]]
name = "rustls"
version = "0.23.26"
version = "0.23.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df51b5869f3a441595eac5e8ff14d486ff285f7b8c0df8770e49c3b56351f0f0"
checksum = "7160e3e10bf4535308537f3c4e1641468cd0e485175d6163087c0393c7d46643"
dependencies = [
"aws-lc-rs",
"log",
Expand All @@ -3779,15 +3779,18 @@ dependencies = [

[[package]]
name = "rustls-pki-types"
version = "1.11.0"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c"
checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79"
dependencies = [
"zeroize",
]

[[package]]
name = "rustls-webpki"
version = "0.103.1"
version = "0.103.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fef8b8769aaccf73098557a87cd1816b4f9c7c16811c9c77142aa695c16f2c03"
checksum = "e4a72fe2bcf7a6ac6fd7d0b9e5cb68aeb7d4c0a0271730218b3e92d43b4eb435"
dependencies = [
"aws-lc-rs",
"ring",
Expand Down
143 changes: 110 additions & 33 deletions linkerd/app/outbound/src/tls/logical/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,18 @@ use linkerd_proxy_client_policy::{self as client_policy, tls::sni};
use parking_lot::Mutex;
use std::{
collections::HashMap,
marker::PhantomData,
net::SocketAddr,
sync::Arc,
task::{Context, Poll},
time::Duration,
};
use tokio::sync::watch;
use tokio_rustls::rustls::pki_types::DnsName;
use tokio_rustls::rustls::{
internal::msgs::codec::{Codec, Reader},
pki_types::DnsName,
InvalidMessage,
};

mod basic;

Expand Down Expand Up @@ -170,44 +175,57 @@ fn sni_route(backend: client_policy::Backend, sni: sni::MatchSni) -> client_poli
// generates a sample ClientHello TLS message for testing
fn generate_client_hello(sni: &str) -> Vec<u8> {
use tokio_rustls::rustls::{
internal::msgs::{
base::Payload,
codec::{Codec, Reader},
enums::Compression,
handshake::{
ClientExtension, ClientHelloPayload, HandshakeMessagePayload, HandshakePayload,
Random, ServerName, SessionId,
},
message::{MessagePayload, PlainMessage},
},
CipherSuite, ContentType, HandshakeType, ProtocolVersion,
internal::msgs::{base::Payload, codec::Codec, message::PlainMessage},
ContentType, ProtocolVersion,
};

let sni = DnsName::try_from(sni.to_string()).unwrap();
let sni = trim_hostname_trailing_dot_for_sni(&sni);

let mut server_name_bytes = vec![];
0u8.encode(&mut server_name_bytes); // encode the type first
(sni.as_ref().len() as u16).encode(&mut server_name_bytes); // then the length as u16
server_name_bytes.extend_from_slice(sni.as_ref().as_bytes()); // then the server name itself

let server_name =
ServerName::read(&mut Reader::init(&server_name_bytes)).expect("Server name is valid");

let hs_payload = HandshakeMessagePayload {
typ: HandshakeType::ClientHello,
payload: HandshakePayload::ClientHello(ClientHelloPayload {
client_version: ProtocolVersion::TLSv1_2,
random: Random::from([0; 32]),
session_id: SessionId::read(&mut Reader::init(&[0])).unwrap(),
cipher_suites: vec![CipherSuite::TLS_NULL_WITH_NULL_NULL],
compression_methods: vec![Compression::Null],
extensions: vec![ClientExtension::ServerName(vec![server_name])],
}),
};
// rustls has internal-only types that can encode a ClientHello, but they are mostly
// inaccessible and an unstable part of the public API anyway. Manually encode one here for
// testing only instead.

let mut hs_payload_bytes = vec![];
1u8.encode(&mut hs_payload_bytes); // client hello ID

let client_hello_body = {
let mut payload = LengthPayload::<U24>::empty();

payload.buf.extend_from_slice(&[0x03, 0x03]); // client version, TLSv1.2

payload.buf.extend_from_slice(&[0u8; 32]); // random

0u8.encode(&mut payload.buf); // session ID

LengthPayload::<u16>::from_slice(&[0x00, 0x00] /* TLS_NULL_WITH_NULL_NULL */)
.encode(&mut payload.buf);

let mut hs_payload_bytes = Vec::default();
MessagePayload::handshake(hs_payload).encode(&mut hs_payload_bytes);
LengthPayload::<u8>::from_slice(&[0x00] /* no compression */).encode(&mut payload.buf);

let extensions = {
let mut payload = LengthPayload::<u16>::empty();
0u16.encode(&mut payload.buf); // server name extension ID

let server_name_extension = {
let mut payload = LengthPayload::<u16>::empty();
let server_name = {
let mut payload = LengthPayload::<u16>::empty();
0u8.encode(&mut payload.buf); // DNS hostname ID
LengthPayload::<u16>::from_slice(sni.as_ref().as_bytes())
.encode(&mut payload.buf);
payload
};
server_name.encode(&mut payload.buf);
payload
};
server_name_extension.encode(&mut payload.buf);
payload
};
extensions.encode(&mut payload.buf);
payload
};
client_hello_body.encode(&mut hs_payload_bytes);

let message = PlainMessage {
typ: ContentType::Handshake,
Expand All @@ -218,6 +236,65 @@ fn generate_client_hello(sni: &str) -> Vec<u8> {
message.into_unencrypted_opaque().encode()
}

#[derive(Debug)]
struct LengthPayload<T> {
buf: Vec<u8>,
_boo: PhantomData<fn() -> T>,
}

impl<T> LengthPayload<T> {
fn empty() -> Self {
Self {
buf: vec![],
_boo: PhantomData,
}
}

fn from_slice(s: &[u8]) -> Self {
Self {
buf: s.to_vec(),
_boo: PhantomData,
}
}
}

impl Codec<'_> for LengthPayload<u8> {
fn encode(&self, bytes: &mut Vec<u8>) {
(self.buf.len() as u8).encode(bytes);
bytes.extend_from_slice(&self.buf);
}

fn read(_: &mut Reader<'_>) -> std::result::Result<Self, InvalidMessage> {
unimplemented!()
}
}

impl Codec<'_> for LengthPayload<u16> {
fn encode(&self, bytes: &mut Vec<u8>) {
(self.buf.len() as u16).encode(bytes);
bytes.extend_from_slice(&self.buf);
}

fn read(_: &mut Reader<'_>) -> std::result::Result<Self, InvalidMessage> {
unimplemented!()
}
}

#[derive(Debug)]
struct U24;

impl Codec<'_> for LengthPayload<U24> {
fn encode(&self, bytes: &mut Vec<u8>) {
let len = self.buf.len() as u32;
bytes.extend_from_slice(&len.to_be_bytes()[1..]);
bytes.extend_from_slice(&self.buf);
}

fn read(_: &mut Reader<'_>) -> std::result::Result<Self, InvalidMessage> {
unimplemented!()
}
}

fn trim_hostname_trailing_dot_for_sni(dns_name: &DnsName<'_>) -> DnsName<'static> {
let dns_name_str = dns_name.as_ref();

Expand Down
2 changes: 1 addition & 1 deletion linkerd/meshtls/rustls/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ test-util = ["linkerd-tls-test-util"]
futures = { version = "0.3", default-features = false }
ring = { version = "0.17", features = ["std"] }
rustls-pemfile = "2.2"
rustls-webpki = { version = "0.103.1", default-features = false, features = ["std"] }
rustls-webpki = { version = "0.103.3", default-features = false, features = ["std"] }
thiserror = "2"
tokio = { version = "1", features = ["macros", "rt", "sync"] }
tokio-rustls = { workspace = true }
Expand Down
Loading