Skip to content

Commit

Permalink
Merge branch 'main' into entropy-invalid-fd
Browse files Browse the repository at this point in the history
  • Loading branch information
goatgoose committed Jan 19, 2024
2 parents a711295 + 54fbc3c commit 7245fdf
Show file tree
Hide file tree
Showing 40 changed files with 855 additions and 300 deletions.
9 changes: 9 additions & 0 deletions .github/s2n_osx.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,12 @@ cmake . -Bbuild -GNinja \

cmake --build ./build -j $(nproc)
time CTEST_PARALLEL_LEVEL=$(nproc) ninja -C build test

# Build shared library
cmake . -Bbuild -GNinja \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_PREFIX_PATH=${OPENSSL_1_1_1_INSTALL_DIR} .. \
-DBUILD_SHARED_LIBS=ON

cmake --build ./build -j $(nproc)
time CTEST_PARALLEL_LEVEL=$(nproc) ninja -C build test
73 changes: 73 additions & 0 deletions .github/workflows/usage_guide.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
name: Publish Usage Guide
on:
push:
branches:
- main
pull_request:
branches:
- main

env:
CDN: https://d3fqnyekunr9xg.cloudfront.net

# By default dependabot only receives read permissions. Explicitly give it write
# permissions which is needed by the ouzi-dev/commit-status-updater task.
#
# Updating status is relatively safe (doesnt modify source code) and caution
# should be taken before adding more permissions.
permissions:
contents: write
statuses: write

jobs:
build-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout s2n-tls repo
uses: actions/checkout@v4

- uses: dtolnay/rust-toolchain@stable

- name: Set override
run: rustup override set stable

- uses: camshaft/install@v1
with:
crate: mdbook

- name: Build book
run: |
cd docs/usage-guide
mdbook build
- name: Deploy documentation to gh-pages
uses: JamesIves/[email protected]
if: github.event_name == 'push'
with:
target-folder: usage-guide
folder: docs/usage-guide/book

- name: Configure AWS credentials
uses: aws-actions/[email protected]
if: github.event_name == 'push' || github.repository == github.event.pull_request.head.repo.full_name
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-west-1

- name: Upload to S3
if: github.event_name == 'push' || github.repository == github.event.pull_request.head.repo.full_name
id: s3
run: |
TARGET="${{ github.sha }}/book"
aws s3 sync docs/usage-guide/book "s3://s2n-tls-ci-artifacts/$TARGET" --acl private --follow-symlinks
URL="$CDN/$TARGET/index.html"
echo "URL=$URL" >> $GITHUB_OUTPUT
- name: Output mdbook url
uses: ouzi-dev/[email protected]
if: github.event_name == 'push' || github.repository == github.event.pull_request.head.repo.full_name
with:
name: "book / url"
status: "success"
url: "${{ steps.s3.outputs.URL }}"
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ If you have any questions about submitting PRs, s2n-tls API usage, or something

## Documentation

s2n-tls uses [Doxygen](https://doxygen.nl/index.html) to document its public API. The latest s2n-tls documentation can be found on [GitHub pages](https://aws.github.io/s2n-tls/doxygen/). The [Usage Guide](docs/usage-guide/) explains how different TLS features can be configured and used.
s2n-tls uses [Doxygen](https://doxygen.nl/index.html) to document its public API. The latest s2n-tls documentation can be found on [GitHub pages](https://aws.github.io/s2n-tls/doxygen/). The [Usage Guide](https://aws.github.io/s2n-tls/usage-guide/) explains how different TLS features can be configured and used.

Documentation for older versions or branches of s2n-tls can be generated locally. To generate the documentation, install doxygen and run `doxygen docs/doxygen/Doxyfile`. The doxygen documentation can now be found at `docs/doxygen/output/html/index.html`.

Expand Down Expand Up @@ -77,7 +77,7 @@ int bytes_written;
bytes_written = s2n_send(conn, "Hello World", sizeof("Hello World"), &blocked);
```

For details on building the s2n-tls library and how to use s2n-tls in an application you are developing, see the [usage guide][Usage Guide](docs/usage-guide).
For details on building the s2n-tls library and how to use s2n-tls in an application you are developing, see the [Usage Guide](https://aws.github.io/s2n-tls/usage-guide).

## s2n-tls features

Expand Down
29 changes: 29 additions & 0 deletions api/s2n.h
Original file line number Diff line number Diff line change
Expand Up @@ -1393,6 +1393,35 @@ struct s2n_client_hello;
*/
S2N_API extern struct s2n_client_hello *s2n_connection_get_client_hello(struct s2n_connection *conn);

/**
* Creates an s2n_client_hello from bytes representing a ClientHello message.
*
* The input bytes should include the message header (message type and length),
* but not the record header.
*
* Unlike s2n_connection_get_client_hello, the s2n_client_hello returned by this
* method is owned by the application and must be freed with s2n_client_hello_free.
*
* This method does not support SSLv2 ClientHellos.
*
* @param bytes The raw bytes representing the ClientHello.
* @param size The size of raw_message.
* @returns A new s2n_client_hello on success, or NULL on failure.
*/
S2N_API extern struct s2n_client_hello *s2n_client_hello_parse_message(const uint8_t *bytes, uint32_t size);

/**
* Frees an s2n_client_hello structure.
*
* This method should be called to free s2n_client_hellos returned by
* s2n_client_hello_parse_message. It will error if passed an s2n_client_hello
* returned by s2n_connection_get_client_hello and owned by the connection.
*
* @param ch The structure to be freed.
* @returns S2N_SUCCESS on success, S2N_FAILURE on failure.
*/
S2N_API extern int s2n_client_hello_free(struct s2n_client_hello **ch);

/**
* Function to determine the size of the raw Client Hello buffer.
*
Expand Down
26 changes: 0 additions & 26 deletions api/unstable/fingerprint.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,29 +74,3 @@ S2N_API int s2n_client_hello_get_fingerprint_hash(struct s2n_client_hello *ch,
S2N_API int s2n_client_hello_get_fingerprint_string(struct s2n_client_hello *ch,
s2n_fingerprint_type type, uint32_t max_size,
uint8_t *output, uint32_t *output_size);

/**
* Creates an s2n_client_hello from bytes representing a ClientHello message.
*
* Unlike s2n_connection_get_client_hello, the s2n_client_hello returned by this
* method is owned by the application and must be freed with s2n_client_hello_free.
*
* This method does not support SSLv2 ClientHellos.
*
* @param bytes The raw bytes representing the ClientHello.
* @param size The size of raw_message.
* @returns A new s2n_client_hello on success, or NULL on failure.
*/
S2N_API struct s2n_client_hello *s2n_client_hello_parse_message(const uint8_t *bytes, uint32_t size);

/**
* Frees an s2n_client_hello structure.
*
* This method should be called to free s2n_client_hellos returned by
* s2n_client_hello_parse_message. It will error if passed an s2n_client_hello
* returned by s2n_connection_get_client_hello and owned by the connection.
*
* @param ch The structure to be freed.
* @returns S2N_SUCCESS on success, S2N_FAILURE on failure.
*/
S2N_API int s2n_client_hello_free(struct s2n_client_hello **ch);
24 changes: 22 additions & 2 deletions api/unstable/ktls.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@
* Enables sending using kTLS on a given connection.
*
* See above for the limitations on when kTLS can be enabled. Additionally,
* s2n_connection_ktls_enable_send must be called after the handshake completes.
* s2n_connection_ktls_enable_send must be called after the handshake completes
* but before the handshake is freed with s2n_connection_free_handshake.
* It may be called after some application data is sent and received without kTLS,
* but there must be no pending application data that requires flushing. If these
* requirements are not met, enabling kTLS will fail with an error.
Expand Down Expand Up @@ -74,7 +75,8 @@ S2N_API int s2n_connection_ktls_enable_send(struct s2n_connection *conn);
* Enables receiving using kTLS on a given connection.
*
* See above for the limitations on when kTLS can be enabled. Additionally,
* s2n_connection_ktls_enable_recv must be called after the handshake completes.
* s2n_connection_ktls_enable_recv must be called after the handshake completes
* but before the handshake is freed with s2n_connection_free_handshake.
* It may be called after some application data is sent and received without kTLS,
* but there must be no buffered application data that requires draining. If these
* requirements are not met, enabling kTLS will fail with an error.
Expand All @@ -100,6 +102,8 @@ S2N_API int s2n_connection_ktls_enable_recv(struct s2n_connection *conn);
*
* Enabling TLS1.3 with this method is considered "unsafe" because the kernel
* currently doesn't support updating encryption keys, which is required in TLS1.3.
* s2n_connection_get_key_update_counts can be used to gather metrics on whether
* key updates are occurring on your connections before enabling TLS1.3.
*
* In order to safely enable TLS1.3, an application must ensure that its peer will
* not send any KeyUpdate messages. If s2n-tls receives a KeyUpdate message while
Expand All @@ -117,6 +121,22 @@ S2N_API int s2n_connection_ktls_enable_recv(struct s2n_connection *conn);
*/
S2N_API int s2n_config_ktls_enable_unsafe_tls13(struct s2n_config *config);

/**
* Reports the number of times sending and receiving keys have been updated.
*
* This only applies to TLS1.3. Earlier versions do not support key updates.
*
* @warning s2n-tls only tracks up to UINT8_MAX (255) key updates. If this method
* reports 255 updates, then more than 255 updates may have occurred.
*
* @param conn A pointer to the connection.
* @param send_key_updates Number of times the sending key was updated.
* @param recv_key_updates Number of times the receiving key was updated.
* @returns S2N_SUCCESS if successful, S2N_FAILURE otherwise.
*/
S2N_API int s2n_connection_get_key_update_counts(struct s2n_connection *conn,
uint8_t *send_key_updates, uint8_t *recv_key_updates);

/**
* Sends the contents of a file as application data.
*
Expand Down
22 changes: 9 additions & 13 deletions bindings/rust/bench/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,21 @@ All benchmarks are run in an idealized environment, using only a single thread a
../generate.sh
# set up bench crate
scripts/generate-certs.sh
scripts/install-aws-lc.sh
./scripts/generate-certs.sh
# run all benchmarks (s2n-tls with AWS-LC)
mkdir .cargo
cat aws-lc-config/s2n.toml > .cargo/config.toml
# run all benchmarks
cargo bench
scripts/bench-memory.sh
cargo bench --bench handshake --bench throughput -- --profile-time 5
rm -rf .cargo
```

## Setup
The benchmarked TLS implementations will be
- s2n-tls using AWS-LC for a cryptographic backend.
- rustls using Ring for a cryptographic backend
- OpenSSL - libssl & libcrypto

Setup is easy! Just have OpenSSL installed, generate Rust bindings for s2n-tls using `../generate.sh`, and generate certs using `scripts/generate-certs.sh`.
All of the cryptographic backends, including AWS-LC and OpenSSL libcrypto are consumed as vendored builds from crates.io, and do not need to be installed on the benchmarking host. Note that the `aws-lc-sys` crate depends on CMake in its buildscript, so CMake must be installed on the benchmarking host.

Dependencies are the same as with s2n-tls. Currently, this crate has only been tested on Ubuntu (both x86 and ARM), but we expect everything to work with other Unix environments.

To bench with AWS-LC, Amazon's custom libcrypto implementation, first run `scripts/install-aws-lc.sh` to install AWS-LC for the bench crate. To then run the benchmarks with AWS-LC, use Cargo with either the flag `--config aws-lc-config/s2n.toml` or `--config aws-lc-config/rustls.toml` (or both). You can also append these configs to `.cargo/config.toml` to let Cargo automatically detect the settings without specifying the flags each time.
Currently, this crate has only been tested on Ubuntu (both x86 and ARM), but we expect everything to work with other Unix environments.

### Features

Expand Down Expand Up @@ -93,7 +89,7 @@ To do historical benchmarks, run `scripts/bench-past.sh`. This will checkout old

The last version benched is v1.3.16, since before that, the s2n-tls Rust bindings have a different API and would thus require a different bench harness to test.

v1.3.30-1.3.37 are not benched because of depedency issues when generating the Rust bindings. However, versions before and after are benched, so the overall trend in performance can still be seen without the data from these versions.
v1.3.30-1.3.37 are not benched because of dependency issues when generating the Rust bindings. However, versions before and after are benched, so the overall trend in performance can still be seen without the data from these versions.

### Sample output

Expand Down
2 changes: 0 additions & 2 deletions bindings/rust/bench/aws-lc-config/rustls.toml

This file was deleted.

3 changes: 0 additions & 3 deletions bindings/rust/bench/aws-lc-config/s2n.toml

This file was deleted.

79 changes: 1 addition & 78 deletions bindings/rust/s2n-tls-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,6 @@ fn main() {
if external.is_enabled() {
external.link();
} else {
#[cfg(feature = "cmake")]
{
// branch on a runtime value so we don't get unused code warnings
if option_env("CARGO_FEATURE_CMAKE").is_some() {
build_cmake();
} else {
build_vendored();
}
}

#[cfg(not(feature = "cmake"))]
build_vendored();
}
}
Expand Down Expand Up @@ -93,26 +82,7 @@ fn build_vendored() {

let mut build = builder(&libcrypto);

// TODO: update rust bindings to handle no pq-crypto dir

let pq = option_env("CARGO_FEATURE_PQ").is_some();

// TODO each pq section needs to be built separately since it
// has its own relative include paths
assert!(!pq, "pq builds are not currently supported without cmake");

build.files(include!("./files.rs").iter().copied().filter(|file| {
// the pq entry file is still needed
if *file == "lib/pq-crypto/s2n_pq.c" {
return true;
}

if file.starts_with("lib/pq-crypto/") {
return pq;
}

true
}));
build.files(include!("./files.rs"));

if env("PROFILE") == "release" {
// fortify source is only available in release mode
Expand All @@ -127,10 +97,6 @@ fn build_vendored() {
}
}

if !pq {
build.define("S2N_NO_PQ", "1");
}

let out_dir = PathBuf::from(env("OUT_DIR"));

let features = FeatureDetector::new(&out_dir, &libcrypto);
Expand Down Expand Up @@ -214,49 +180,6 @@ fn builder(libcrypto: &Libcrypto) -> cc::Build {
build
}

#[cfg(feature = "cmake")]
fn build_cmake() {
let mut config = cmake::Config::new("lib");

let libcrypto = Libcrypto::default();

config
.register_dep(&format!("aws_lc_{}", libcrypto.version))
.configure_arg("-DBUILD_TESTING=off");

if option_env("CARGO_FEATURE_PQ").is_none() {
config.configure_arg("-DS2N_NO_PQ=on");
}

let dst = config.build();

let lib = search(dst.join("lib64"))
.or_else(|| search(dst.join("lib")))
.or_else(|| search(dst.join("build").join("lib")))
.expect("could not build libs2n");

// link the built artifact
if lib.join("libs2n.a").exists() {
println!("cargo:rustc-link-lib=static=s2n");
} else {
println!("cargo:rustc-link-lib=s2n");
}

println!("cargo:include={}", dst.join("include").display());

// tell rust we're linking with libcrypto
println!("cargo:rustc-link-lib={}", libcrypto.link);

fn search(path: PathBuf) -> Option<PathBuf> {
if path.exists() {
println!("cargo:rustc-link-search={}", path.display());
Some(path)
} else {
None
}
}
}

#[derive(PartialEq, Eq, PartialOrd, Ord)]
struct Libcrypto {
version: String,
Expand Down
5 changes: 3 additions & 2 deletions bindings/rust/s2n-tls-sys/templates/Cargo.template
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ include = [

[features]
default = []
# preserve the cmake feature in case any consumers had it enabled before
cmake = []
quic = []
pq = ["cmake"] # the pq build logic is complicated so just use cmake instead
pq = []
internal = []
stacktrace = []
<TOKEN_REPLACED_WITH_UNSTABLE_FEATURES>
Expand All @@ -38,7 +40,6 @@ libc = "0.2"

[build-dependencies]
cc = { version = "1.0", features = ["parallel"] }
cmake = { version = "0.1", optional = true }

[dev-dependencies]
jobserver = "=0.1.26" # newer versions require rust 1.66, see https://github.com/aws/s2n-tls/issues/4241
Loading

0 comments on commit 7245fdf

Please sign in to comment.