Skip to content
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

Support FreeBSD #55

Merged
merged 2 commits into from
Jan 5, 2024
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
22 changes: 22 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,28 @@ jobs:

# TODO: Test iOS in CI too.

test-freebsd:
name: Test (FreeBSD)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: test on freebsd
uses: vmactions/freebsd-vm@v1
# Settings adopted from https://github.com/quinn-rs/quinn
with:
usesh: true
mem: 4096
copyback: false
prepare: |
pkg install -y curl
curl https://sh.rustup.rs -sSf --output rustup.sh
sh rustup.sh -y --profile minimal --default-toolchain stable
echo "~~~~ rustc --version ~~~~"
$HOME/.cargo/bin/rustc --version
echo "~~~~ freebsd-version ~~~~"
freebsd-version
run: $HOME/.cargo/bin/cargo test

fmt:
name: Rustfmt
runs-on: ubuntu-latest
Expand Down
6 changes: 5 additions & 1 deletion rustls-platform-verifier/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ base64 = { version = "0.21", optional = true } # Only used when the `cert-loggin
jni = { version = "0.19", default-features = false, optional = true } # Only used during doc generation
once_cell = { version = "1.9", optional = true } # Only used during doc generation.

[target.'cfg(target_os = "linux")'.dependencies]
[target.'cfg(all(unix, not(target_os = "android"), not(target_os = "macos"), not(target_os = "ios")))'.dependencies]
rustls-native-certs = "0.6"
once_cell = "1.9"
webpki = { package = "rustls-webpki", version = "0.101", features = ["alloc", "std"] }
Expand All @@ -51,6 +51,10 @@ android_logger = { version = "0.13", optional = true } # Only used during testin
once_cell = "1.9"
webpki-roots = "0.25"

# BSD targets require webpki-roots for the real-world verification tests.
[target.'cfg(target_os = "freebsd")'.dev-dependencies]
webpki-roots = "0.25"

[target.'cfg(any(target_os = "macos", target_os = "ios"))'.dependencies]
core-foundation = "0.9"
core-foundation-sys = "0.8"
Expand Down
37 changes: 16 additions & 21 deletions rustls-platform-verifier/src/tests/verification_mock/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,7 @@
//! any parts of the system outside of these tests. See the `#![cfg(...)]`
//! immediately below to see which platforms run these tests.

#![cfg(any(
windows,
target_os = "android",
target_os = "macos",
target_os = "linux"
))]
#![cfg(all(any(windows, unix, target_os = "android"), not(target_os = "ios")))]

use super::TestCase;
use crate::tests::{assert_cert_error_eq, verification_time};
Expand Down Expand Up @@ -116,47 +111,47 @@ fn test_verification_without_mock_root() {
// Verifies that our test trust anchor(s) are not trusted when `Verifier::new()`
// is used.
mock_root_test_cases! {
valid_no_stapling_dns [ any(windows, target_os = "android", target_os = "macos", target_os = "linux") ] => TestCase {
valid_no_stapling_dns [ any(windows, unix) ] => TestCase {
complexspaces marked this conversation as resolved.
Show resolved Hide resolved
reference_id: EXAMPLE_COM,
chain: &[ROOT1_INT1_EXAMPLE_COM_GOOD, ROOT1_INT1],
stapled_ocsp: None,
verification_time: verification_time(),
expected_result: Ok(()),
other_error: no_error!(),
},
valid_no_stapling_ipv4 [ any(windows, target_os = "android", target_os = "macos", target_os = "linux") ] => TestCase {
valid_no_stapling_ipv4 [ any(windows, unix) ] => TestCase {
reference_id: LOCALHOST_IPV4,
chain: &[ROOT1_INT1_LOCALHOST_IPV4_GOOD, ROOT1_INT1],
stapled_ocsp: None,
verification_time: verification_time(),
expected_result: Ok(()),
other_error: no_error!(),
},
valid_no_stapling_ipv6 [ any(windows, target_os = "android", target_os = "macos", target_os = "linux") ] => TestCase {
valid_no_stapling_ipv6 [ any(windows, unix) ] => TestCase {
reference_id: LOCALHOST_IPV6,
chain: &[ROOT1_INT1_LOCALHOST_IPV6_GOOD, ROOT1_INT1],
stapled_ocsp: None,
verification_time: verification_time(),
expected_result: Ok(()),
other_error: no_error!(),
},
valid_stapled_good_dns [ any(windows, target_os = "android", target_os = "android", target_os = "macos", target_os = "linux") ] => TestCase {
valid_stapled_good_dns [ any(windows, unix) ] => TestCase {
reference_id: EXAMPLE_COM,
chain: &[ROOT1_INT1_EXAMPLE_COM_GOOD, ROOT1_INT1],
stapled_ocsp: Some(include_bytes!("root1-int1-ee_example.com-good.ocsp")),
verification_time: verification_time(),
expected_result: Ok(()),
other_error: no_error!(),
},
valid_stapled_good_ipv4 [ any(windows, target_os = "android", target_os = "macos", target_os = "linux") ] => TestCase {
valid_stapled_good_ipv4 [ any(windows, unix) ] => TestCase {
reference_id: LOCALHOST_IPV4,
chain: &[ROOT1_INT1_LOCALHOST_IPV4_GOOD, ROOT1_INT1],
stapled_ocsp: Some(include_bytes!("root1-int1-ee_127.0.0.1-good.ocsp")),
verification_time: verification_time(),
expected_result: Ok(()),
other_error: no_error!(),
},
valid_stapled_good_ipv6 [ any(windows, target_os = "android", target_os = "macos", target_os = "linux") ] => TestCase {
valid_stapled_good_ipv6 [ any(windows, unix) ] => TestCase {
reference_id: LOCALHOST_IPV6,
chain: &[ROOT1_INT1_LOCALHOST_IPV6_GOOD, ROOT1_INT1],
stapled_ocsp: Some(include_bytes!("root1-int1-ee_1-good.ocsp")),
Expand Down Expand Up @@ -197,23 +192,23 @@ mock_root_test_cases! {
// (AIA is an extension that allows downloading of missing data,
// like missing certificates, during validation; see
// https://datatracker.ietf.org/doc/html/rfc5280#section-5.2.7).
ee_only_dns [ any(windows, target_os = "android", target_os = "macos", target_os = "linux") ] => TestCase {
ee_only_dns [ any(windows, unix) ] => TestCase {
reference_id: EXAMPLE_COM,
chain: &[ROOT1_INT1_EXAMPLE_COM_GOOD],
stapled_ocsp: None,
verification_time: verification_time(),
expected_result: Err(TlsError::InvalidCertificate(CertificateError::UnknownIssuer)),
other_error: no_error!(),
},
ee_only_ipv4 [ any(windows, target_os = "android", target_os = "macos", target_os = "linux") ] => TestCase {
ee_only_ipv4 [ any(windows, unix) ] => TestCase {
reference_id: LOCALHOST_IPV4,
chain: &[ROOT1_INT1_LOCALHOST_IPV4_GOOD],
stapled_ocsp: None,
verification_time: verification_time(),
expected_result: Err(TlsError::InvalidCertificate(CertificateError::UnknownIssuer)),
other_error: no_error!(),
},
ee_only_ipv6 [ any(windows, target_os = "android", target_os = "macos", target_os = "linux") ] => TestCase {
ee_only_ipv6 [ any(windows, unix) ] => TestCase {
reference_id: LOCALHOST_IPV6,
chain: &[ROOT1_INT1_LOCALHOST_IPV6_GOOD],
stapled_ocsp: None,
Expand All @@ -222,31 +217,31 @@ mock_root_test_cases! {
other_error: no_error!(),
},
// Validation fails when the certificate isn't valid for the reference ID.
domain_mismatch_dns [ any(windows, target_os = "android", target_os = "macos", target_os = "linux") ] => TestCase {
domain_mismatch_dns [ any(windows, unix) ] => TestCase {
reference_id: "example.org",
chain: &[ROOT1_INT1_EXAMPLE_COM_GOOD, ROOT1_INT1],
stapled_ocsp: None,
verification_time: verification_time(),
expected_result: Err(TlsError::InvalidCertificate(CertificateError::NotValidForName)),
other_error: no_error!(),
},
domain_mismatch_ipv4 [ any(windows, target_os = "android", target_os = "macos", target_os = "linux") ] => TestCase {
domain_mismatch_ipv4 [ any(windows, unix) ] => TestCase {
reference_id: "198.168.0.1",
chain: &[ROOT1_INT1_LOCALHOST_IPV4_GOOD, ROOT1_INT1],
stapled_ocsp: None,
verification_time: verification_time(),
expected_result: Err(TlsError::InvalidCertificate(CertificateError::NotValidForName)),
other_error: no_error!(),
},
domain_mismatch_ipv6 [ any(windows, target_os = "android", target_os = "macos", target_os = "linux") ] => TestCase {
domain_mismatch_ipv6 [ any(windows, unix) ] => TestCase {
reference_id: "::ffff:c6a8:1",
chain: &[ROOT1_INT1_LOCALHOST_IPV6_GOOD, ROOT1_INT1],
stapled_ocsp: None,
verification_time: verification_time(),
expected_result: Err(TlsError::InvalidCertificate(CertificateError::NotValidForName)),
other_error: no_error!(),
},
wrong_eku_dns [ any(windows, target_os = "android", target_os = "macos", target_os = "linux") ] => TestCase {
wrong_eku_dns [ any(windows, unix) ] => TestCase {
reference_id: EXAMPLE_COM,
chain: &[include_bytes!("root1-int1-ee_example.com-wrong_eku.crt"), ROOT1_INT1],
stapled_ocsp: None,
Expand All @@ -255,7 +250,7 @@ mock_root_test_cases! {
CertificateError::Other(Arc::from(EkuError)))),
other_error: Some(EkuError),
},
wrong_eku_ipv4 [ any(windows, target_os = "android", target_os = "macos", target_os = "linux") ] => TestCase {
wrong_eku_ipv4 [ any(windows, unix) ] => TestCase {
reference_id: LOCALHOST_IPV4,
chain: &[include_bytes!("root1-int1-ee_127.0.0.1-wrong_eku.crt"), ROOT1_INT1],
stapled_ocsp: None,
Expand All @@ -264,7 +259,7 @@ mock_root_test_cases! {
CertificateError::Other(Arc::from(EkuError)))),
other_error: Some(EkuError),
},
wrong_eku_ipv6 [ any(windows, target_os = "android", target_os = "macos", target_os = "linux") ] => TestCase {
wrong_eku_ipv6 [ any(windows, unix) ] => TestCase {
reference_id: LOCALHOST_IPV6,
chain: &[include_bytes!("root1-int1-ee_1-wrong_eku.crt"), ROOT1_INT1],
stapled_ocsp: None,
Expand Down
17 changes: 17 additions & 0 deletions rustls-platform-verifier/src/tests/verification_real_world/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,23 @@ macro_rules! no_error {
fn real_world_test<E: std::error::Error>(test_case: &TestCase<E>) {
log::info!("verifying {:?}", test_case.expected_result);

// On BSD systems openssl-probe fails to find the system CA bundle,
// so we must provide extra roots from webpki-roots.
#[cfg(target_os = "freebsd")]
let verifier = Verifier::new_with_extra_roots(
webpki_roots::TLS_SERVER_ROOTS
.iter()
.map(|ta| {
rustls::OwnedTrustAnchor::from_subject_spki_name_constraints(
ta.subject,
ta.spki,
ta.name_constraints,
)
})
.collect::<Vec<_>>(),
);

#[cfg(not(target_os = "freebsd"))]
let verifier = Verifier::new();

let mut chain = test_case
Expand Down
14 changes: 12 additions & 2 deletions rustls-platform-verifier/src/verification/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
#[cfg(any(target_os = "linux", target_arch = "wasm32"))]
#[cfg(all(
any(unix, target_arch = "wasm32"),
not(target_os = "android"),
not(target_os = "macos"),
not(target_os = "ios")
))]
mod others;

#[cfg(any(target_os = "linux", target_arch = "wasm32"))]
#[cfg(all(
any(unix, target_arch = "wasm32"),
not(target_os = "android"),
not(target_os = "macos"),
not(target_os = "ios")
))]
pub use others::Verifier;

#[cfg(any(target_os = "macos", target_os = "ios"))]
Expand Down
Loading