Skip to content

Rust Bindings

Rust Bindings #8498

Workflow file for this run

---
name: Rust Bindings
on:
pull_request:
branches: [main]
merge_group:
types: [checks_requested]
branches: [main]
env:
# Pin the nightly toolchain to prevent breakage.
# This should be occasionally updated.
RUST_NIGHTLY_TOOLCHAIN: nightly-2024-12-01
ROOT_PATH: bindings/rust
EXAMPLE_WORKSPACE: bindings/rust-examples
PCAP_TEST_PATH: tests/pcap
jobs:
generate:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macOS-latest]
steps:
- uses: actions/checkout@v4
- name: Install Rust toolchain
id: toolchain
run: |
rustup toolchain install stable
rustup override set stable
# https://github.com/aws/aws-lc-rs/blob/main/aws-lc-fips-sys/README.md#build-prerequisites
# go required for generate.sh to build aws-lc-rs in FIPS mode
- name: Install go
uses: actions/setup-go@v5
with:
go-version: '>=1.18'
- uses: camshaft/rust-cache@v1
- name: Generate
run: ${{env.ROOT_PATH}}/generate.sh
# Ensure that all tests pass with the default feature set
- name: Default Tests
working-directory: ${{env.ROOT_PATH}}
run: cargo test
- name: "Feature Tests: Fingerprint, kTLS, QUIC, and PQ"
working-directory: ${{env.ROOT_PATH}}
# Test all features except for FIPS, which is tested separately.
run: cargo test --features unstable-fingerprint,unstable-ktls,quic,pq
- name: "Feature Test: Renegotiate"
working-directory: ${{env.ROOT_PATH}}
run: cargo test --features unstable-renegotiate
- name: Network-enabled integration tests
working-directory: ${{env.ROOT_PATH}}/integration
# no-default-features is used because network tests are hidden behind a
# default "negative" feature. This is because we don't want network tests
# invoked on the `cargo test --all-features` pattern.
run: RUST_LOG=TRACE cargo test --no-default-features --features pq
- name: Test external build
# if this test is failing, make sure that api headers are appropriately
# included. For a symbol to be visible in a shared lib, the
# __attribute__((visibility("default"))) label must be on a declaration
# in the same unit of compilation as the definition. Generally this just
# means that if the linker can't resolve foo_method in tls/foo.c, you
# forgot to include api/unstable/foo.h in tls/foo.c
if: ${{ matrix.os == 'ubuntu-latest' }}
run: |
cmake . -Bbuild -DBUILD_SHARED_LIBS=on -DBUILD_TESTING=off
cmake --build build -- -j $(nproc)
export S2N_TLS_LIB_DIR=`pwd`/build/lib
export S2N_TLS_INCLUDE_DIR=`pwd`/api
export LD_LIBRARY_PATH=$S2N_TLS_LIB_DIR:$LD_LIBRARY_PATH
cd ${{env.ROOT_PATH}}
./generate.sh
ldd target/debug/integration | grep libs2n.so
# our benchmark testing includes interop tests between s2n-tls, rustls, and
# openssl
harness-interop-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust toolchain
id: toolchain
run: |
rustup toolchain install stable
rustup override set stable
- name: generate bindings
run: ${{env.ROOT_PATH}}/generate.sh --skip-tests
- name: bench tests
working-directory: ${{env.ROOT_PATH}}/bench
run: cargo test
s2n-tls-binding-examples:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust toolchain
id: toolchain
run: |
rustup toolchain install stable
rustup override set stable
- name: generate bindings
run: ${{env.ROOT_PATH}}/generate.sh --skip-tests
- name: build examples
working-directory: ${{env.EXAMPLE_WORKSPACE}}
run: cargo build
generate-openssl-102:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust toolchain
id: toolchain
run: |
rustup toolchain install stable
rustup override set stable
- uses: camshaft/rust-cache@v1
- name: Cache OpenSSL 1.0.2
id: cache-openssl
uses: actions/cache@v4
with:
path: ~/openssl-102/install
key: ${{ runner.os }}-openssl-102
- if: ${{ steps.cache-openssl.outputs.cache-hit != 'true' }}
name: Install OpenSSL 1.0.2
run: |
mkdir ~/openssl-102
pushd ~/openssl-102
mkdir install
install_dir="$(pwd)"/install
wget https://www.openssl.org/source/old/1.0.2/openssl-1.0.2u.tar.gz
tar -xzvf openssl-1.0.2u.tar.gz
pushd openssl-1.0.2u
./config --prefix="${install_dir}" --openssldir="${install_dir}"/openssl
make
make install
popd
popd
- name: Generate
run: OPENSSL_DIR=~/openssl-102/install ${{env.ROOT_PATH}}/generate.sh
- name: Tests
working-directory: ${{env.ROOT_PATH}}
run: cargo test --all-features
fips:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macOS-latest]
steps:
- uses: actions/checkout@v4
with:
submodules: true
- name: Install Rust toolchain
id: toolchain
run: |
rustup toolchain install stable
rustup override set stable
# https://github.com/aws/aws-lc-rs/blob/main/aws-lc-fips-sys/README.md#build-prerequisites
# go required to build aws-lc-rs in FIPS mode
- name: Install go
uses: actions/setup-go@v5
with:
go-version: '>=1.18'
- uses: camshaft/rust-cache@v1
- name: Generate
run: ./${{env.ROOT_PATH}}/generate.sh
- name: Test fips
working-directory: ${{env.ROOT_PATH}}
run: |
# The doc tests fail to link to AWS-LC in FIPS mode due to
# https://github.com/rust-lang/cargo/issues/8531. The --tests flag is provided to disable
# the doc tests. The doc tests are tested in the generate test, where FIPS is disabled.
cargo test --tests --features fips
# Test all features, including FIPS
- name: Test all
working-directory: ${{env.ROOT_PATH}}
run: |
cargo test --tests --all-features
# Run the rust unit tests under address sanitizer.
#
# Rust is generally memory safe, but our bindings contain a large amount of unsafe
# code. Additionally, "safe" code doesn't guarentee that the code is free of
# memory leaks.
asan-unit-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust toolchain
id: toolchain
run: |
rustup toolchain install ${{env.RUST_NIGHTLY_TOOLCHAIN }} \
--profile minimal \
--component rust-src \
--target x86_64-unknown-linux-gnu
rustup override set ${{ env.RUST_NIGHTLY_TOOLCHAIN }}
- name: Generate
run: ./${{env.ROOT_PATH}}/generate.sh --skip-tests
# asan expects a binary at /usr/bin/llvm-symbolizer but GHA runners include
# multiple versioned binaries, like /usr/bin/llvm-symbolizer-13. This step
# finds the latest symbolizer and use it as the "base" llvm-symbolizer binary.
#
# llvm-symbolizer is necessary to get nice stack traces from asan errors.
# Otherwise the stack trace just contains a hex address like "0x55bc6a28a9b6"
- name: set llvm symbolizer
run: |
sudo ln -s $(find /usr/bin/ -maxdepth 1 -name "llvm-symbolizer-*" | sort -V | tail -n 1) /usr/bin/llvm-symbolizer
- name: Run Unit Tests under ASAN
env:
RUSTDOCFLAGS: -Zsanitizer=address
RUSTFLAGS: -Zsanitizer=address
run: |
cargo test \
-Zbuild-std \
--manifest-path ${{ env.ROOT_PATH}}/Cargo.toml \
--target x86_64-unknown-linux-gnu
rustfmt:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: true
- name: Install Rust toolchain
id: toolchain
run: |
rustup toolchain install ${{ env.RUST_NIGHTLY_TOOLCHAIN }} --profile minimal --component rustfmt
rustup override set ${{ env.RUST_NIGHTLY_TOOLCHAIN }}
- uses: camshaft/rust-cache@v1
# We don't need to format the generated files,
# but if they don't exist other code breaks.
- name: Generate
run: ./${{env.ROOT_PATH}}/generate.sh --skip-tests
- name: Run cargo fmt
run: |
cargo fmt --manifest-path ${{env.ROOT_PATH}}/Cargo.toml --all -- --check
clippy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: true
- name: Install Rust toolchain
id: toolchain
run: |
rustup toolchain install stable --profile minimal --component clippy
rustup override set stable
- uses: camshaft/rust-cache@v1
# Enforce that clippy's msrv matches rust-toolchain
- name: Check MSRV
run: grep $(cat ${{env.ROOT_PATH}}/rust-toolchain) ${{env.ROOT_PATH}}/.clippy.toml
# We don't need to format the generated files,
# but if they don't exist other code breaks.
- name: Generate
run: ${{env.ROOT_PATH}}/generate.sh
# TODO translate json reports to in-action warnings
- name: Run cargo clippy
run: |
cargo clippy --manifest-path ${{env.ROOT_PATH}}/Cargo.toml --all-targets -- -D warnings
cargo clippy --manifest-path ${{env.ROOT_PATH}}/Cargo.toml --all-targets --all-features -- -D warnings
msrv:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: true
# Enforce crate msrv matches rust-toolchain
- name: Check MSRV of s2n-tls
run: grep "rust-version = \"$(cat ${{env.ROOT_PATH}}/rust-toolchain)\"" ${{env.ROOT_PATH}}/s2n-tls/Cargo.toml
- name: Check MSRV of s2n-tls-sys
run: grep "rust-version = \"$(cat ${{env.ROOT_PATH}}/rust-toolchain)\"" ${{env.ROOT_PATH}}/s2n-tls-sys/templates/Cargo.template
- name: Check MSRV of s2n-tokio
run: grep "rust-version = \"$(cat ${{env.ROOT_PATH}}/rust-toolchain)\"" ${{env.ROOT_PATH}}/s2n-tls-tokio/Cargo.toml
pcaps:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
with:
submodules: true
- name: Install Rust toolchain
id: toolchain
run: |
rustup toolchain install stable --component clippy
rustup override set stable
- name: Install tshark
run: |
sudo apt-get install -y tshark
tshark --version
- name: Generate bindings
working-directory: ${{env.ROOT_PATH}}
run: ./generate.sh --skip-tests
- name: Run lints
working-directory: ${{env.PCAP_TEST_PATH}}
run: |
cargo fmt --all -- --check
cargo clippy --all-targets -- -D warnings
- name: Run tests
working-directory: ${{env.PCAP_TEST_PATH}}
run: cargo test --all-features