Skip to content

Commit

Permalink
Merge branch 'main' into dependabot/github_actions/dot-github/workflo…
Browse files Browse the repository at this point in the history
…ws/actions/checkout-4
  • Loading branch information
dougch authored Nov 20, 2024
2 parents ff15b3f + 5714c3c commit 4b76b85
Show file tree
Hide file tree
Showing 27 changed files with 138 additions and 48 deletions.
1 change: 1 addition & 0 deletions .github/workflows/ci_compliance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ on:
permissions:
contents: read # This is required for actions/checkout
id-token: write # This is required for requesting the JWT/OIDC
statuses: write # Required for dependabot PRs https://github.com/ouzi-dev/commit-status-updater?tab=readme-ov-file#workflow-permissions

jobs:
duvet:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/ci_linting.yml
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: nixbuild/nix-quick-install-action@v21
- uses: nixbuild/nix-quick-install-action@v29
with:
nix_conf: experimental-features = nix-command flakes
- name: nix flake check
Expand All @@ -110,7 +110,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: nixbuild/nix-quick-install-action@v21
- uses: nixbuild/nix-quick-install-action@v29
with:
nix_conf: experimental-features = nix-command flakes
- name: nix fmt
Expand Down
13 changes: 13 additions & 0 deletions .github/workflows/dependencies.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
---
name: dependencies

on:
Expand All @@ -16,6 +17,9 @@ on:
# Run every day at 1800 UTC.
- cron: "0 18 * * *"

env:
ROOT_PATH: bindings/rust

jobs:
audit:
runs-on: ubuntu-latest
Expand All @@ -24,6 +28,15 @@ jobs:
checks: write # Create/update a check run.
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: Generate
run: ${{env.ROOT_PATH}}/generate.sh
- uses: rustsec/[email protected]
with:
token: ${{ secrets.GITHUB_TOKEN }}
working-directory: ${{env.ROOT_PATH}}
2 changes: 1 addition & 1 deletion .github/workflows/team_label.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
team-labeler:
runs-on: ubuntu-latest
steps:
- uses: JulienKode/team-labeler-action@v0.1.1
- uses: JulienKode/team-labeler-action@v1.3
with:
repo-token: "${{ secrets.GITHUB_TOKEN }}"

2 changes: 1 addition & 1 deletion bindings/rust/s2n-tls-hyper/tests/common/echo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ async fn echo(
Ok(Response::new(req.into_body().boxed()))
}

async fn serve_echo<B>(
pub async fn serve_echo<B>(
tcp_listener: TcpListener,
builder: B,
) -> Result<(), Box<dyn Error + Send + Sync>>
Expand Down
5 changes: 2 additions & 3 deletions bindings/rust/s2n-tls-hyper/tests/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@ use s2n_tls::{callbacks::VerifyHostNameCallback, config, error::Error, security:
pub mod echo;

/// NOTE: this certificate and key are used for testing purposes only!
pub static CERT_PEM: &[u8] =
pub const CERT_PEM: &[u8] =
include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/../certs/cert.pem"));
pub static KEY_PEM: &[u8] =
include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/../certs/key.pem"));
pub const KEY_PEM: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/../certs/key.pem"));

pub fn config() -> Result<config::Builder, Error> {
let mut builder = config::Config::builder();
Expand Down
77 changes: 77 additions & 0 deletions bindings/rust/s2n-tls-hyper/tests/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,19 @@

use crate::common::InsecureAcceptAllCertificatesHandler;
use bytes::Bytes;
use common::echo::serve_echo;
use http::{Method, Request, Uri};
use http_body_util::{BodyExt, Empty, Full};
use hyper_util::{client::legacy::Client, rt::TokioExecutor};
use s2n_tls::{
callbacks::{ClientHelloCallback, ConnectionFuture},
config,
connection::Connection,
security::DEFAULT_TLS13,
};
use s2n_tls_hyper::connector::HttpsConnector;
use std::{error::Error, pin::Pin, str::FromStr};
use tokio::{net::TcpListener, task::JoinHandle};

pub mod common;

Expand Down Expand Up @@ -138,3 +142,76 @@ async fn test_sni() -> Result<(), Box<dyn Error + Send + Sync>> {

Ok(())
}

/// This test covers the general customer TLS Error experience. We want to
/// confirm that s2n-tls errors are correctly bubbled up and that details can be
/// extracted/matched on.
#[tokio::test]
async fn error_matching() -> Result<(), Box<dyn Error + Send + Sync>> {
let (server_task, addr) = {
let listener = TcpListener::bind("127.0.0.1:0").await?;
let addr = listener.local_addr()?;
let server_task = tokio::spawn(serve_echo(listener, common::config()?.build()?));
(server_task, addr)
};

let client_task: JoinHandle<Result<(), Box<dyn Error + Send + Sync>>> =
tokio::spawn(async move {
// the client config won't trust the self-signed cert that the server
// uses.
let client_config = {
let mut builder = config::Config::builder();
builder.set_security_policy(&DEFAULT_TLS13)?;
builder.set_max_blinding_delay(0)?;
builder.build()?
};

let connector = HttpsConnector::new(client_config);
let client: Client<_, Empty<Bytes>> =
Client::builder(TokioExecutor::new()).build(connector);

let uri = Uri::from_str(format!("https://localhost:{}", addr.port()).as_str())?;
client.get(uri).await?;

panic!("the client request should fail");
});

// expected error:
// hyper_util::client::legacy::Error(
// Connect,
// TlsError(
// Error {
// code: 335544366,
// name: "S2N_ERR_CERT_UNTRUSTED",
// message: "Certificate is untrusted",
// kind: ProtocolError,
// source: Library,
// debug: "Error encountered in lib/tls/s2n_x509_validator.c:721",
// errno: "No such file or directory",
// },
// ),
// )
let client_response = client_task.await?;
let client_error = client_response.unwrap_err();
let hyper_error: &hyper_util::client::legacy::Error = client_error.downcast_ref().unwrap();

// the error happened when attempting to connect to the endpoint.
assert!(hyper_error.is_connect());

let error_source = hyper_error.source().unwrap();
let s2n_tls_hyper_error: &s2n_tls_hyper::error::Error = error_source.downcast_ref().unwrap();

let s2n_tls_error = match s2n_tls_hyper_error {
s2n_tls_hyper::error::Error::TlsError(s2n_tls_error) => s2n_tls_error,
_ => panic!("unexpected error type"),
};

assert_eq!(
s2n_tls_error.kind(),
s2n_tls::error::ErrorType::ProtocolError
);
assert_eq!(s2n_tls_error.name(), "S2N_ERR_CERT_UNTRUSTED");

server_task.abort();
Ok(())
}
2 changes: 2 additions & 0 deletions docs/usage-guide/topics/ch01-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ are intended to be stable (API and ABI) within major version numbers of s2n-tls
and structures used in s2n-tls internally can not be considered stable and their parameters, names, and
sizes may change.

In general, s2n-tls APIs are not thread safe unless explicitly specified otherwise.

Read [Error Handling](./ch03-error-handling.md) for information on processing API return values safely.

The [VERSIONING.rst](https://github.com/aws/s2n-tls/blob/main/VERSIONING.rst) document contains more details about s2n's approach to versions and API changes.
Expand Down
4 changes: 3 additions & 1 deletion docs/usage-guide/topics/ch04-connection.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# TLS Connections

Users will need to create a `s2n_connection` struct to store all of the state necessary for a TLS connection. Call `s2n_connection_new()` to create a new server or client connection. Call `s2n_connection_free()` to free the memory allocated for this struct when no longer needed.
In general, s2n-tls works by operating on `s2n_connection` structs. A user should first create a connection by calling `s2n_connection_new()`. Then a [TLS handshake can be performed](./ch07-io.md#performing-the-tls-handshake) on the connection. Finally, the connection can be used to [send and receive encrypted data](./ch07-io.md#application-data). An `s2n_config` struct can be associated with a connection to [configure additional options](./ch05-config.md).

Call `s2n_connection_free()` to free the memory allocated for connection when no longer needed.

## Connection Memory

Expand Down
2 changes: 1 addition & 1 deletion docs/usage-guide/topics/ch05-config.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Configuring the Connection

`s2n_config` objects are used to change the default settings of a s2n-tls connection. Use `s2n_config_new()` to create a new config object. To associate a config with a connection call `s2n_connection_set_config()`. A config should not be altered once it is associated with a connection as this will produce undefined behavior. It is not necessary to create a config object per connection; one config object should be used for many connections. Call `s2n_config_free()` to free the object when no longer needed. _Only_ free the config object when all connections using it have been freed.
`s2n_config` objects are used to change the default settings of a s2n-tls connection. Use `s2n_config_new()` to create a new config object. To associate a config with a connection call `s2n_connection_set_config()`. A config should not be altered once it is set on a connection as this will produce undefined behavior. It is not necessary to create a config object per connection; one config object should be used for many connections. Call `s2n_config_free()` to free the object when no longer needed. _Only_ free the config object when all connections using it have been freed.

Calling `s2n_config_new()` can have a performance cost during config creation due to loading
default system certificates into the trust store (see [Configuring the Trust Store](./ch09-certificates.md#configuring-the-trust-store)).
Expand Down
2 changes: 1 addition & 1 deletion docs/usage-guide/topics/ch11-resumption.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ TLS handshake sessions are CPU-heavy due to the calculations involved in authent

## Session Ticket Key

The key that encrypts and decrypts the session state is not related to the keys negotiated as part of the TLS handshake and has to be set by the server by calling `s2n_config_add_ticket_crypto_key()`. See [RFC5077](https://www.rfc-editor.org/rfc/rfc5077#section-5.5) for guidelines on securely generating keys.
The key that encrypts and decrypts the session state is not related to the keys negotiated as part of the TLS handshake and has to be set by the server by calling `s2n_config_add_ticket_crypto_key()`. Unlike other methods that modify `s2n_config` objects, `s2n_config_add_ticket_crypto_key()` can be called after setting an `s2n_config` object on a connection. See [RFC5077](https://www.rfc-editor.org/rfc/rfc5077#section-5.5) for guidelines on securely generating keys.

Each key has two different expiration dates. The first expiration date signifies the time that the key can be used for both encryption and decryption. The second expiration date signifies the time that the key can be used only for decryption. This mechanism is to ensure that a session ticket can be successfully decrypted if it was encrypted by a key that was about to expire. The full lifetime of the key is therefore the encrypt-decrypt lifetime plus the decrypt-only lifetime. To alter the default key lifetime call `s2n_config_set_ticket_encrypt_decrypt_key_lifetime()` and `s2n_config_set_ticket_decrypt_key_lifetime()`.

Expand Down
15 changes: 6 additions & 9 deletions tests/fuzz/s2n_certificate_extensions_parse_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,6 @@ static uint8_t verify_host_accept_everything(const char *host_name, size_t host_
/* This test is for TLS versions 1.3 and up only */
static const uint8_t TLS_VERSIONS[] = {S2N_TLS13};

int s2n_fuzz_init(int *argc, char **argv[])
{
/* Initialize the trust store */
POSIX_GUARD_RESULT(s2n_config_testing_defaults_init_tls13_certs());
POSIX_GUARD(s2n_enable_tls13_in_test());
return S2N_SUCCESS;
}

int s2n_fuzz_test(const uint8_t *buf, size_t len)
{
/* We need at least one byte of input to set parameters */
Expand All @@ -67,8 +59,13 @@ int s2n_fuzz_test(const uint8_t *buf, size_t len)
POSIX_GUARD(s2n_stuffer_alloc(&fuzz_stuffer, len));
POSIX_GUARD(s2n_stuffer_write_bytes(&fuzz_stuffer, buf, len));

DEFER_CLEANUP(struct s2n_config *config = s2n_config_new(), s2n_config_ptr_free);
EXPECT_NOT_NULL(config);
POSIX_GUARD(s2n_config_set_cipher_preferences(config, "20240503"));

struct s2n_connection *client_conn = s2n_connection_new(S2N_CLIENT);
POSIX_ENSURE_REF(client_conn);
POSIX_GUARD(s2n_connection_set_config(client_conn, config));

/* Pull a byte off the libfuzzer input and use it to set parameters */
uint8_t randval = 0;
Expand Down Expand Up @@ -115,4 +112,4 @@ int s2n_fuzz_test(const uint8_t *buf, size_t len)
return S2N_SUCCESS;
}

S2N_FUZZ_TARGET(s2n_fuzz_init, s2n_fuzz_test, NULL)
S2N_FUZZ_TARGET(NULL, s2n_fuzz_test, NULL)
4 changes: 2 additions & 2 deletions tests/unit/s2n_alerts_protocol_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -479,13 +479,13 @@ int main(int argc, char **argv)
s2n_connection_ptr_free);
EXPECT_SUCCESS(s2n_connection_set_blinding(server, S2N_SELF_SERVICE_BLINDING));
EXPECT_SUCCESS(s2n_connection_set_config(server, config));
EXPECT_SUCCESS(s2n_connection_set_cipher_preferences(server, "default"));
EXPECT_SUCCESS(s2n_connection_set_cipher_preferences(server, "20240501"));

DEFER_CLEANUP(struct s2n_connection *client = s2n_connection_new(S2N_CLIENT),
s2n_connection_ptr_free);
EXPECT_SUCCESS(s2n_connection_set_blinding(client, S2N_SELF_SERVICE_BLINDING));
EXPECT_SUCCESS(s2n_connection_set_config(client, config));
EXPECT_SUCCESS(s2n_connection_set_cipher_preferences(client, "default"));
EXPECT_SUCCESS(s2n_connection_set_cipher_preferences(client, "20240501"));

DEFER_CLEANUP(struct s2n_test_io_stuffer_pair io_pair = { 0 }, s2n_io_stuffer_pair_free);
EXPECT_OK(s2n_io_stuffer_pair_init(&io_pair));
Expand Down
6 changes: 3 additions & 3 deletions tests/unit/s2n_client_hello_request_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,13 @@ int main(int argc, char **argv)

DEFER_CLEANUP(struct s2n_config *config = s2n_config_new(), s2n_config_ptr_free);
EXPECT_NOT_NULL(config);
EXPECT_SUCCESS(s2n_config_set_cipher_preferences(config, "default"));
EXPECT_SUCCESS(s2n_config_set_cipher_preferences(config, "20240501"));
EXPECT_SUCCESS(s2n_config_set_unsafe_for_testing(config));
EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(config, chain_and_key));

DEFER_CLEANUP(struct s2n_config *config_with_reneg_cb = s2n_config_new(), s2n_config_ptr_free);
EXPECT_NOT_NULL(config_with_reneg_cb);
EXPECT_SUCCESS(s2n_config_set_cipher_preferences(config_with_reneg_cb, "default"));
EXPECT_SUCCESS(s2n_config_set_cipher_preferences(config_with_reneg_cb, "20240501"));
EXPECT_SUCCESS(s2n_config_set_unsafe_for_testing(config_with_reneg_cb));
EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(config_with_reneg_cb, chain_and_key));
EXPECT_SUCCESS(s2n_config_set_renegotiate_request_cb(config_with_reneg_cb, s2n_test_reneg_req_cb, NULL));
Expand Down Expand Up @@ -167,7 +167,7 @@ int main(int argc, char **argv)
{
DEFER_CLEANUP(struct s2n_config *config_with_warns = s2n_config_new(), s2n_config_ptr_free);
EXPECT_NOT_NULL(config_with_warns);
EXPECT_SUCCESS(s2n_config_set_cipher_preferences(config_with_warns, "default"));
EXPECT_SUCCESS(s2n_config_set_cipher_preferences(config_with_warns, "20240501"));
EXPECT_SUCCESS(s2n_config_set_unsafe_for_testing(config_with_warns));
EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(config_with_warns, chain_and_key));
EXPECT_SUCCESS(s2n_config_set_alert_behavior(config_with_warns, S2N_ALERT_IGNORE_WARNINGS));
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/s2n_client_hello_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -759,7 +759,7 @@ int main(int argc, char **argv)
struct s2n_connection *conn = NULL;
EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT));
EXPECT_SUCCESS(s2n_connection_set_config(conn, config));
EXPECT_SUCCESS(s2n_connection_set_cipher_preferences(conn, "default"));
EXPECT_SUCCESS(s2n_connection_set_cipher_preferences(conn, "20240501"));

const struct s2n_security_policy *security_policy = NULL;
POSIX_GUARD(s2n_connection_get_security_policy(conn, &security_policy));
Expand Down
2 changes: 2 additions & 0 deletions tests/unit/s2n_connection_serialize_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ int main(int argc, char **argv)
S2N_DEFAULT_TEST_CERT_CHAIN, S2N_DEFAULT_TEST_PRIVATE_KEY));

DEFER_CLEANUP(struct s2n_config *tls12_config = s2n_config_new(), s2n_config_ptr_free);
EXPECT_SUCCESS(s2n_config_set_cipher_preferences(tls12_config, "20240501"));
EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(tls12_config, chain_and_key));
EXPECT_SUCCESS(s2n_config_disable_x509_verification(tls12_config));
EXPECT_SUCCESS(s2n_config_set_serialization_version(tls12_config, S2N_SERIALIZED_CONN_V1));
Expand Down Expand Up @@ -594,6 +595,7 @@ int main(int argc, char **argv)
/* Self-talk: Test interaction between TLS1.2 session resumption and serialization */
{
DEFER_CLEANUP(struct s2n_config *resumption_config = s2n_config_new(), s2n_config_ptr_free);
EXPECT_SUCCESS(s2n_config_set_cipher_preferences(resumption_config, "20240501"));
EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(resumption_config, chain_and_key));
EXPECT_SUCCESS(s2n_config_disable_x509_verification(resumption_config));
EXPECT_SUCCESS(s2n_config_set_serialization_version(resumption_config, S2N_SERIALIZED_CONN_V1));
Expand Down
6 changes: 3 additions & 3 deletions tests/unit/s2n_extended_master_secret_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ int main(int argc, char **argv)
EXPECT_NOT_NULL(config);

/* TLS1.2 cipher preferences */
EXPECT_SUCCESS(s2n_config_set_cipher_preferences(config, "default"));
EXPECT_SUCCESS(s2n_config_set_cipher_preferences(config, "20240501"));
EXPECT_SUCCESS(s2n_config_set_unsafe_for_testing(config));
struct s2n_cert_chain_and_key *chain_and_key = NULL;
EXPECT_SUCCESS(s2n_test_cert_chain_and_key_new(&chain_and_key,
Expand Down Expand Up @@ -208,7 +208,7 @@ int main(int argc, char **argv)
struct s2n_config *config = s2n_config_new();
EXPECT_NOT_NULL(config);

EXPECT_SUCCESS(s2n_config_set_cipher_preferences(config, "default"));
EXPECT_SUCCESS(s2n_config_set_cipher_preferences(config, "20240501"));
EXPECT_SUCCESS(s2n_config_set_unsafe_for_testing(config));
struct s2n_cert_chain_and_key *chain_and_key = NULL;
EXPECT_SUCCESS(s2n_test_cert_chain_and_key_new(&chain_and_key,
Expand Down Expand Up @@ -253,7 +253,7 @@ int main(int argc, char **argv)
struct s2n_config *config = s2n_config_new();
EXPECT_NOT_NULL(config);

EXPECT_SUCCESS(s2n_config_set_cipher_preferences(config, "default"));
EXPECT_SUCCESS(s2n_config_set_cipher_preferences(config, "20240501"));
EXPECT_SUCCESS(s2n_config_set_unsafe_for_testing(config));
struct s2n_cert_chain_and_key *chain_and_key = NULL;
EXPECT_SUCCESS(s2n_test_cert_chain_and_key_new(&chain_and_key,
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/s2n_renegotiate_io_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ int main(int argc, char *argv[])
EXPECT_NOT_NULL(config);
EXPECT_SUCCESS(s2n_config_set_unsafe_for_testing(config));
EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(config, chain_and_key));
EXPECT_SUCCESS(s2n_config_set_cipher_preferences(config, "default"));
EXPECT_SUCCESS(s2n_config_set_cipher_preferences(config, "20240501"));

uint8_t app_data[] = "test application data";

Expand Down
Loading

0 comments on commit 4b76b85

Please sign in to comment.