Skip to content

Commit 1f5dab0

Browse files
authored
test(integration): add BoringSSL cohort to expand mTLS coverage (#5659)
1 parent 253e1ab commit 1f5dab0

File tree

7 files changed

+501
-7
lines changed

7 files changed

+501
-7
lines changed

bindings/rust/standard/integration/Cargo.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ no-sensitive-tests = []
1818
# can be disabled by turning off this feature.
1919
pq = [ "s2n-tls/pq" ]
2020

21+
boringssl = ["tls-harness/boringssl"]
22+
2123
[dependencies]
2224
s2n-tls = { path = "../../extended/s2n-tls", features = ["unstable-testing", "unstable-crl"]}
2325
s2n-tls-hyper = { path = "../s2n-tls-hyper" }
@@ -48,6 +50,12 @@ hyper-util = "0.1"
4850
dhat = "0.3.3"
4951
tabled = "0.20.0"
5052

53+
# NOTE: BoringSSL is disabled on macOS to avoid symbol collisions with
54+
# OpenSSL; see https://github.com/aws/s2n-tls/pull/5659 for details.
55+
[target.'cfg(not(target_os = "macos"))'.dev-dependencies.boring]
56+
git = "https://github.com/kaukabrizvi/boring.git"
57+
features = ["prefix-symbols"]
58+
5159
[build-dependencies]
5260
# The ML-DSA tests require the ML-DSA support added in Openssl-3.5
5361
# Since this overrides the dependency from the openssl-src crate,

bindings/rust/standard/integration/src/mtls/mod.rs

Lines changed: 249 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ use std::{
2525
},
2626
};
2727

28+
// NOTE: BoringSSL tests are disabled on macOS to avoid symbol collisions with
29+
// OpenSSL; see https://github.com/aws/s2n-tls/pull/5659 for details.
30+
#[cfg(all(feature = "boringssl", not(target_os = "macos")))]
31+
use boring::ssl::SslVersion;
2832
use rustls::ClientConfig;
2933

3034
use s2n_tls::{
@@ -46,6 +50,9 @@ use tls_harness::{
4650
PemType, SigType, TlsConnPair, TlsConnection,
4751
};
4852

53+
#[cfg(all(feature = "boringssl", not(target_os = "macos")))]
54+
use tls_harness::cohort::{BoringSslConfig, BoringSslConnection};
55+
4956
const APP_DATA_SIZE: usize = 100_000;
5057

5158
/// A wrapper around a raw pointer to `s2n_cert_validation_info` that can be sent across threads.
@@ -210,6 +217,58 @@ fn rustls_mtls_server(
210217
server.into()
211218
}
212219

220+
#[cfg(all(feature = "boringssl", not(target_os = "macos")))]
221+
fn boringssl_mtls_client(sig_type: SigType, version: SslVersion) -> BoringSslConfig {
222+
use tls_harness::harness::{Mode, TlsConfigBuilder};
223+
224+
let mut builder = boring::ssl::SslContextBuilder::new_test_config(Mode::Client);
225+
builder.set_trust(sig_type);
226+
227+
builder
228+
.set_certificate_chain_file(tls_harness::get_cert_path(
229+
PemType::ClientCertChain,
230+
sig_type,
231+
))
232+
.unwrap();
233+
builder
234+
.set_private_key_file(
235+
tls_harness::get_cert_path(PemType::ClientKey, sig_type),
236+
boring::ssl::SslFiletype::PEM,
237+
)
238+
.unwrap();
239+
builder.set_verify(boring::ssl::SslVerifyMode::PEER);
240+
241+
// Pin the protocol version
242+
builder.set_min_proto_version(Some(version)).unwrap();
243+
builder.set_max_proto_version(Some(version)).unwrap();
244+
245+
BoringSslConfig {
246+
config: builder.build(),
247+
session_ticket_storage: Default::default(),
248+
}
249+
}
250+
251+
#[cfg(all(feature = "boringssl", not(target_os = "macos")))]
252+
fn boringssl_mtls_server(sig_type: SigType, version: SslVersion) -> BoringSslConfig {
253+
use tls_harness::harness::{Mode, TlsConfigBuilder};
254+
255+
let mut builder = boring::ssl::SslContextBuilder::new_test_config(Mode::Server);
256+
builder.set_chain(sig_type);
257+
builder.set_trust(sig_type);
258+
builder.set_verify(
259+
boring::ssl::SslVerifyMode::PEER | boring::ssl::SslVerifyMode::FAIL_IF_NO_PEER_CERT,
260+
);
261+
262+
// Pin the protocol version
263+
builder.set_min_proto_version(Some(version)).unwrap();
264+
builder.set_max_proto_version(Some(version)).unwrap();
265+
266+
BoringSslConfig {
267+
config: builder.build(),
268+
session_ticket_storage: Default::default(),
269+
}
270+
}
271+
213272
// ============================================================================
214273
// Basic mTLS tests
215274
// ============================================================================
@@ -227,7 +286,7 @@ where
227286

228287
// s2n client, rustls server
229288
#[test]
230-
fn s2n_client_basic() {
289+
fn rustls_server_basic() {
231290
// TLS 1.2
232291
let client = {
233292
let builder = s2n_mtls_base_builder(SigType::Rsa2048);
@@ -252,7 +311,7 @@ fn s2n_client_basic() {
252311

253312
// rustls client, s2n server
254313
#[test]
255-
fn s2n_server_basic() {
314+
fn rustls_client_basic() {
256315
// TLS 1.2
257316
let client = rustls_mtls_client(SigType::Rsa2048, &rustls::version::TLS12);
258317
let server = {
@@ -275,6 +334,58 @@ fn s2n_server_basic() {
275334
);
276335
}
277336

337+
// s2n client, boringssl server
338+
#[cfg(all(feature = "boringssl", not(target_os = "macos")))]
339+
#[test]
340+
fn boringssl_server_basic() {
341+
// TLS 1.2
342+
let client = {
343+
let builder = s2n_mtls_base_builder(SigType::Rsa2048);
344+
S2NConfig::from(builder.build().unwrap())
345+
};
346+
let server = boringssl_mtls_server(SigType::Rsa2048, SslVersion::TLS1_2);
347+
test_basic::<S2NConnection, BoringSslConnection>(&client, &server);
348+
349+
// TLS 1.3
350+
crate::capability_check::required_capability(
351+
&[crate::capability_check::Capability::Tls13],
352+
|| {
353+
let client = {
354+
let builder = s2n_mtls_base_builder(SigType::Rsa2048);
355+
S2NConfig::from(builder.build().unwrap())
356+
};
357+
let server = boringssl_mtls_server(SigType::Rsa2048, SslVersion::TLS1_3);
358+
test_basic::<S2NConnection, BoringSslConnection>(&client, &server);
359+
},
360+
);
361+
}
362+
363+
// boringssl client, s2n server
364+
#[cfg(all(feature = "boringssl", not(target_os = "macos")))]
365+
#[test]
366+
fn boringssl_client_basic() {
367+
// TLS 1.2
368+
let client = boringssl_mtls_client(SigType::Rsa2048, SslVersion::TLS1_2);
369+
let server = {
370+
let builder = s2n_mtls_base_builder(SigType::Rsa2048);
371+
S2NConfig::from(builder.build().unwrap())
372+
};
373+
test_basic::<BoringSslConnection, S2NConnection>(&client, &server);
374+
375+
// TLS 1.3
376+
crate::capability_check::required_capability(
377+
&[crate::capability_check::Capability::Tls13],
378+
|| {
379+
let client = boringssl_mtls_client(SigType::Rsa2048, SslVersion::TLS1_3);
380+
let server = {
381+
let builder = s2n_mtls_base_builder(SigType::Rsa2048);
382+
S2NConfig::from(builder.build().unwrap())
383+
};
384+
test_basic::<BoringSslConnection, S2NConnection>(&client, &server);
385+
},
386+
);
387+
}
388+
278389
// ============================================================================
279390
// Sync callback tests
280391
// ============================================================================
@@ -294,7 +405,7 @@ where
294405

295406
// s2n client with sync callback, rustls server
296407
#[test]
297-
fn s2n_client_sync_callback() {
408+
fn rustls_server_sync_callback() {
298409
// TLS 1.2
299410
let (client, handle) = {
300411
let mut builder = s2n_mtls_base_builder(SigType::Rsa2048);
@@ -326,7 +437,7 @@ fn s2n_client_sync_callback() {
326437

327438
// rustls client, s2n server with sync callback
328439
#[test]
329-
fn s2n_server_sync_callback() {
440+
fn rustls_client_sync_callback() {
330441
// TLS 1.2
331442
let client = rustls_mtls_client(SigType::Rsa2048, &rustls::version::TLS12);
332443
let (server, handle) = {
@@ -357,6 +468,70 @@ fn s2n_server_sync_callback() {
357468
);
358469
}
359470

471+
// s2n client with sync callback, boringssl server
472+
#[cfg(all(feature = "boringssl", not(target_os = "macos")))]
473+
#[test]
474+
fn boringssl_server_sync_callback() {
475+
// TLS 1.2
476+
let (client, handle) = {
477+
let mut builder = s2n_mtls_base_builder(SigType::Rsa2048);
478+
let cb = TestCertValidationCallback::new_sync();
479+
let invoked = Arc::clone(cb.invoked_count());
480+
builder.set_cert_validation_callback_sync(cb).unwrap();
481+
(S2NConfig::from(builder.build().unwrap()), invoked)
482+
};
483+
let server = boringssl_mtls_server(SigType::Rsa2048, SslVersion::TLS1_2);
484+
test_sync_callback::<S2NConnection, BoringSslConnection>(&client, &server, handle);
485+
486+
// TLS 1.3
487+
crate::capability_check::required_capability(
488+
&[crate::capability_check::Capability::Tls13],
489+
|| {
490+
let (client, handle) = {
491+
let mut builder = s2n_mtls_base_builder(SigType::Rsa2048);
492+
let cb = TestCertValidationCallback::new_sync();
493+
let invoked = Arc::clone(cb.invoked_count());
494+
builder.set_cert_validation_callback_sync(cb).unwrap();
495+
(S2NConfig::from(builder.build().unwrap()), invoked)
496+
};
497+
let server = boringssl_mtls_server(SigType::Rsa2048, SslVersion::TLS1_3);
498+
test_sync_callback::<S2NConnection, BoringSslConnection>(&client, &server, handle);
499+
},
500+
);
501+
}
502+
503+
// boringssl client, s2n server with sync callback
504+
#[cfg(all(feature = "boringssl", not(target_os = "macos")))]
505+
#[test]
506+
fn boringssl_client_sync_callback() {
507+
// TLS 1.2
508+
let client = boringssl_mtls_client(SigType::Rsa2048, SslVersion::TLS1_2);
509+
let (server, handle) = {
510+
let mut builder = s2n_mtls_base_builder(SigType::Rsa2048);
511+
let cb = TestCertValidationCallback::new_sync();
512+
let invoked = Arc::clone(cb.invoked_count());
513+
builder.set_cert_validation_callback_sync(cb).unwrap();
514+
(S2NConfig::from(builder.build().unwrap()), invoked)
515+
};
516+
test_sync_callback::<BoringSslConnection, S2NConnection>(&client, &server, handle);
517+
518+
// TLS 1.3
519+
crate::capability_check::required_capability(
520+
&[crate::capability_check::Capability::Tls13],
521+
|| {
522+
let client = boringssl_mtls_client(SigType::Rsa2048, SslVersion::TLS1_3);
523+
let (server, handle) = {
524+
let mut builder = s2n_mtls_base_builder(SigType::Rsa2048);
525+
let cb = TestCertValidationCallback::new_sync();
526+
let invoked = Arc::clone(cb.invoked_count());
527+
builder.set_cert_validation_callback_sync(cb).unwrap();
528+
(S2NConfig::from(builder.build().unwrap()), invoked)
529+
};
530+
test_sync_callback::<BoringSslConnection, S2NConnection>(&client, &server, handle);
531+
},
532+
);
533+
}
534+
360535
// ============================================================================
361536
// Async callback tests
362537
// ============================================================================
@@ -430,7 +605,7 @@ where
430605

431606
// s2n client with async callback, rustls server
432607
#[test]
433-
fn s2n_client_async_callback() {
608+
fn rustls_server_async_callback() {
434609
// TLS 1.2
435610
let (client, handle, rx) = {
436611
let builder = s2n_mtls_base_builder(SigType::Rsa2048);
@@ -462,7 +637,7 @@ fn s2n_client_async_callback() {
462637

463638
// rustls client, s2n server with async callback
464639
#[test]
465-
fn s2n_server_async_callback() {
640+
fn rustls_client_async_callback() {
466641
// TLS 1.2
467642
let client = rustls_mtls_client(SigType::Rsa2048, &rustls::version::TLS12);
468643
let (server, handle, rx) = {
@@ -493,6 +668,74 @@ fn s2n_server_async_callback() {
493668
);
494669
}
495670

671+
// s2n client with async callback, boringssl server
672+
#[cfg(all(feature = "boringssl", not(target_os = "macos")))]
673+
#[test]
674+
fn boringssl_server_async_callback() {
675+
// TLS 1.2
676+
let (client, handle, rx) = {
677+
let builder = s2n_mtls_base_builder(SigType::Rsa2048);
678+
let mut s2n_cfg = S2NConfig::from(builder.build().unwrap());
679+
let (invoked, rx) = register_async_cert_callback(&mut s2n_cfg);
680+
(s2n_cfg, invoked, rx)
681+
};
682+
let server = boringssl_mtls_server(SigType::Rsa2048, SslVersion::TLS1_2);
683+
let _pair = test_async_client_callback::<S2NConnection, BoringSslConnection>(
684+
&client, &server, handle, rx,
685+
);
686+
687+
// TLS 1.3
688+
crate::capability_check::required_capability(
689+
&[crate::capability_check::Capability::Tls13],
690+
|| {
691+
let (client, handle, rx) = {
692+
let builder = s2n_mtls_base_builder(SigType::Rsa2048);
693+
let mut s2n_cfg = S2NConfig::from(builder.build().unwrap());
694+
let (invoked, rx) = register_async_cert_callback(&mut s2n_cfg);
695+
(s2n_cfg, invoked, rx)
696+
};
697+
let server = boringssl_mtls_server(SigType::Rsa2048, SslVersion::TLS1_3);
698+
let _pair = test_async_client_callback::<S2NConnection, BoringSslConnection>(
699+
&client, &server, handle, rx,
700+
);
701+
},
702+
);
703+
}
704+
705+
// boringssl client, s2n server with async callback
706+
#[cfg(all(feature = "boringssl", not(target_os = "macos")))]
707+
#[test]
708+
fn boringssl_client_async_callback() {
709+
// TLS 1.2
710+
let client = boringssl_mtls_client(SigType::Rsa2048, SslVersion::TLS1_2);
711+
let (server, handle, rx) = {
712+
let builder = s2n_mtls_base_builder(SigType::Rsa2048);
713+
let mut s2n_cfg = S2NConfig::from(builder.build().unwrap());
714+
let (invoked, rx) = register_async_cert_callback(&mut s2n_cfg);
715+
(s2n_cfg, invoked, rx)
716+
};
717+
let _pair = test_async_server_callback::<BoringSslConnection, S2NConnection>(
718+
&client, &server, handle, rx,
719+
);
720+
721+
// TLS 1.3
722+
crate::capability_check::required_capability(
723+
&[crate::capability_check::Capability::Tls13],
724+
|| {
725+
let client = boringssl_mtls_client(SigType::Rsa2048, SslVersion::TLS1_3);
726+
let (server, handle, rx) = {
727+
let builder = s2n_mtls_base_builder(SigType::Rsa2048);
728+
let mut s2n_cfg = S2NConfig::from(builder.build().unwrap());
729+
let (invoked, rx) = register_async_cert_callback(&mut s2n_cfg);
730+
(s2n_cfg, invoked, rx)
731+
};
732+
let _pair = test_async_server_callback::<BoringSslConnection, S2NConnection>(
733+
&client, &server, handle, rx,
734+
);
735+
},
736+
);
737+
}
738+
496739
// s2n client, s2n server with async callback
497740
#[test]
498741
fn s2n_s2n_mtls_async_callback() {

bindings/rust/standard/tls-harness/Cargo.toml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
[features]
2+
default = []
3+
boringssl = ["dep:boring"]
4+
15
[package]
26
name = "tls-harness"
37
version = "0.1.0"
@@ -14,11 +18,18 @@ rustls-pemfile = "2.2.0"
1418
openssl = { version = "0.10.73", features = ["vendored"] }
1519
openssl-sys = "0.9.109"
1620
byteorder = "1.5.0"
21+
boring = { git = "https://github.com/kaukabrizvi/boring.git", features = ["prefix-symbols"], optional = true }
1722

1823
brass-aphid-wire-decryption = "0.0.2"
1924
brass-aphid-wire-messages = "0.0.2"
2025
tracing = "0.1.43"
2126

27+
# NOTE: BoringSSL is disabled on macOS to avoid symbol collisions with
28+
# OpenSSL; see https://github.com/aws/s2n-tls/pull/5659 for details.
29+
[target.'cfg(not(target_os = "macos"))'.dependencies.boring]
30+
git = "https://github.com/kaukabrizvi/boring.git"
31+
features = ["prefix-symbols"]
32+
2233
[dev-dependencies]
2334
# env_logger and log are used to enable logging for rustls, which can help with
2435
# debugging interop failures

0 commit comments

Comments
 (0)