Skip to content

Commit bef0ffb

Browse files
committed
Add ALPN protocol negotiation
1 parent 03b9f86 commit bef0ffb

File tree

2 files changed

+55
-9
lines changed

2 files changed

+55
-9
lines changed

src/lib.rs

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ use tokio_rustls::{
2929

3030
use crate::attestation::{AttesationPayload, AttestationVerifier};
3131

32+
/// This makes it possible to add breaking protocol changes and provide backwards compatibility.
33+
/// When adding more supported versions, note that ordering is important. ALPN will pick the first
34+
/// protocol which both parties support - so newer supported versions should come first.
35+
pub const SUPPORTED_ALPN_PROTOCOL_VERSIONS: [&[u8]; 1] = [b"flashbots-ratls/1"];
36+
3237
/// The label used when exporting key material from a TLS session
3338
const EXPORTER_LABEL: &[u8; 24] = b"EXPORTER-Channel-Binding";
3439

@@ -84,7 +89,7 @@ impl ProxyServer {
8489
return Err(ProxyError::NoClientAuth);
8590
}
8691

87-
let server_config = if client_auth {
92+
let mut server_config = if client_auth {
8893
let root_store =
8994
RootCertStore::from_iter(webpki_roots::TLS_SERVER_ROOTS.iter().cloned());
9095
let verifier = WebPkiClientVerifier::builder(Arc::new(root_store)).build()?;
@@ -98,6 +103,11 @@ impl ProxyServer {
98103
.with_single_cert(cert_and_key.cert_chain.clone(), cert_and_key.key)?
99104
};
100105

106+
server_config.alpn_protocols = SUPPORTED_ALPN_PROTOCOL_VERSIONS
107+
.into_iter()
108+
.map(|p| p.to_vec())
109+
.collect();
110+
101111
Self::new_with_tls_config(
102112
cert_and_key.cert_chain,
103113
server_config.into(),
@@ -178,6 +188,9 @@ impl ProxyServer {
178188
let mut tls_stream = acceptor.accept(inbound).await?;
179189
let (_io, connection) = tls_stream.get_ref();
180190

191+
// Ensure that we agreed a protocol
192+
let _negotiated_protocol = connection.alpn_protocol().ok_or(ProxyError::AlpnFailed)?;
193+
181194
// Compute an exporter unique to the session
182195
let mut exporter = [0u8; 32];
183196
connection.export_keying_material(
@@ -351,7 +364,7 @@ impl ProxyClient {
351364
};
352365

353366
// Setup TLS client configuration, with or without client auth
354-
let client_config = if let Some(ref cert_and_key) = cert_and_key {
367+
let mut client_config = if let Some(ref cert_and_key) = cert_and_key {
355368
ClientConfig::builder()
356369
.with_root_certificates(root_store)
357370
.with_client_auth_cert(
@@ -364,6 +377,11 @@ impl ProxyClient {
364377
.with_no_client_auth()
365378
};
366379

380+
client_config.alpn_protocols = SUPPORTED_ALPN_PROTOCOL_VERSIONS
381+
.into_iter()
382+
.map(|p| p.to_vec())
383+
.collect();
384+
367385
Self::new_with_tls_config(
368386
client_config.into(),
369387
address,
@@ -577,6 +595,11 @@ impl ProxyClient {
577595

578596
let (_io, server_connection) = tls_stream.get_ref();
579597

598+
// Ensure that we agreed a protocol
599+
let _negotiated_protocol = server_connection
600+
.alpn_protocol()
601+
.ok_or(ProxyError::AlpnFailed)?;
602+
580603
// Compute an exporter unique to the channel
581604
let mut exporter = [0u8; 32];
582605
server_connection.export_keying_material(
@@ -736,6 +759,8 @@ pub enum ProxyError {
736759
MpscSend,
737760
#[error("Serialization: {0}")]
738761
Serialization(#[from] parity_scale_codec::Error),
762+
#[error("Protocol negotiation failed - remote peer does not support this protocol")]
763+
AlpnFailed,
739764
}
740765

741766
impl From<mpsc::error::SendError<RequestWithResponseSender>> for ProxyError {

src/test_helpers.rs

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use tokio_rustls::rustls::{
1313

1414
use crate::{
1515
attestation::measurements::{CvmImageMeasurements, Measurements, PlatformMeasurements},
16-
MEASUREMENT_HEADER,
16+
MEASUREMENT_HEADER, SUPPORTED_ALPN_PROTOCOL_VERSIONS,
1717
};
1818

1919
/// Helper to generate a self-signed certificate for testing
@@ -42,18 +42,27 @@ pub fn generate_tls_config(
4242
certificate_chain: Vec<CertificateDer<'static>>,
4343
key: PrivateKeyDer<'static>,
4444
) -> (Arc<ServerConfig>, Arc<ClientConfig>) {
45-
let server_config = ServerConfig::builder()
45+
let supported_protocols: Vec<_> = SUPPORTED_ALPN_PROTOCOL_VERSIONS
46+
.into_iter()
47+
.map(|p| p.to_vec())
48+
.collect();
49+
50+
let mut server_config = ServerConfig::builder()
4651
.with_no_client_auth()
4752
.with_single_cert(certificate_chain.clone(), key)
4853
.expect("Failed to create rustls server config");
4954

55+
server_config.alpn_protocols = supported_protocols.clone();
56+
5057
let mut root_store = RootCertStore::empty();
5158
root_store.add(certificate_chain[0].clone()).unwrap();
5259

53-
let client_config = ClientConfig::builder()
60+
let mut client_config = ClientConfig::builder()
5461
.with_root_certificates(root_store)
5562
.with_no_client_auth();
5663

64+
client_config.alpn_protocols = supported_protocols;
65+
5766
(Arc::new(server_config), Arc::new(client_config))
5867
}
5968

@@ -67,32 +76,44 @@ pub fn generate_tls_config_with_client_auth(
6776
(Arc<ServerConfig>, Arc<ClientConfig>),
6877
(Arc<ServerConfig>, Arc<ClientConfig>),
6978
) {
79+
let supported_protocols: Vec<_> = SUPPORTED_ALPN_PROTOCOL_VERSIONS
80+
.into_iter()
81+
.map(|p| p.to_vec())
82+
.collect();
83+
7084
let (alice_client_verifier, alice_root_store) =
7185
client_verifier_from_remote_cert(bob_certificate_chain[0].clone());
7286

73-
let alice_server_config = ServerConfig::builder()
87+
let mut alice_server_config = ServerConfig::builder()
7488
.with_client_cert_verifier(alice_client_verifier)
7589
.with_single_cert(alice_certificate_chain.clone(), alice_key.clone_key())
7690
.expect("Failed to create rustls server config");
7791

78-
let alice_client_config = ClientConfig::builder()
92+
alice_server_config.alpn_protocols = supported_protocols.clone();
93+
94+
let mut alice_client_config = ClientConfig::builder()
7995
.with_root_certificates(alice_root_store)
8096
.with_client_auth_cert(alice_certificate_chain.clone(), alice_key)
8197
.unwrap();
8298

99+
alice_client_config.alpn_protocols = supported_protocols.clone();
100+
83101
let (bob_client_verifier, bob_root_store) =
84102
client_verifier_from_remote_cert(alice_certificate_chain[0].clone());
85103

86-
let bob_server_config = ServerConfig::builder()
104+
let mut bob_server_config = ServerConfig::builder()
87105
.with_client_cert_verifier(bob_client_verifier)
88106
.with_single_cert(bob_certificate_chain.clone(), bob_key.clone_key())
89107
.expect("Failed to create rustls server config");
90108

91-
let bob_client_config = ClientConfig::builder()
109+
bob_server_config.alpn_protocols = supported_protocols.clone();
110+
111+
let mut bob_client_config = ClientConfig::builder()
92112
.with_root_certificates(bob_root_store)
93113
.with_client_auth_cert(bob_certificate_chain, bob_key)
94114
.unwrap();
95115

116+
bob_client_config.alpn_protocols = supported_protocols;
96117
(
97118
(Arc::new(alice_server_config), Arc::new(alice_client_config)),
98119
(Arc::new(bob_server_config), Arc::new(bob_client_config)),

0 commit comments

Comments
 (0)