Skip to content

Commit

Permalink
Merge branch 'main' into more-asan
Browse files Browse the repository at this point in the history
  • Loading branch information
jmayclin authored Mar 27, 2024
2 parents 8f85c81 + ba825b8 commit 0b2268e
Show file tree
Hide file tree
Showing 274 changed files with 3,039 additions and 1,942 deletions.
21 changes: 20 additions & 1 deletion .github/workflows/ci_rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ on:
env:
# Pin the nightly toolchain to prevent breakage.
# This should be occasionally updated.
RUST_NIGHTLY_TOOLCHAIN: nightly-2022-08-03
RUST_NIGHTLY_TOOLCHAIN: nightly-2024-01-01
ROOT_PATH: bindings/rust
EXAMPLE_WORKSPACE: bindings/rust-examples

jobs:
generate:
Expand Down Expand Up @@ -78,6 +79,24 @@ jobs:
- name: bench tests
working-directory: ${{env.ROOT_PATH}}/bench
run: cargo test

s2n-tls-binding-examples:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- uses: actions-rs/toolchain@v1
id: toolchain
with:
toolchain: stable
override: true

- 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
Expand Down
13 changes: 6 additions & 7 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,12 @@ if(ASAN)
target_link_options(${PROJECT_NAME} PUBLIC -fsanitize=address)
endif()

if(TSAN OR ASAN)
if (UBSAN)
target_compile_options(${PROJECT_NAME} PUBLIC -fsanitize=undefined -fno-sanitize-recover=all)
target_link_options(${PROJECT_NAME} PUBLIC -fsanitize=undefined -fno-sanitize-recover=all)
endif()

if(TSAN OR ASAN OR UBSAN)
# no-omit-frame-pointer and no-optimize-sibling-calls provide better stack traces
target_compile_options(${PROJECT_NAME} PUBLIC -fno-omit-frame-pointer -fno-optimize-sibling-calls)
endif()
Expand Down Expand Up @@ -493,9 +498,7 @@ if (BUILD_TESTING)
string(REGEX REPLACE ".+\\/(.+)\\.c" "\\1" test_case_name ${test_case})

add_executable(${test_case_name} ${test_case})
target_include_directories(${test_case_name} PRIVATE api)
target_include_directories(${test_case_name} PRIVATE ./)
target_include_directories(${test_case_name} PRIVATE tests)
target_link_libraries(${test_case_name} PRIVATE testss2n)
if (S2N_INTERN_LIBCRYPTO)
# if libcrypto was interned, rewrite libcrypto symbols so use of internal functions will link correctly
Expand All @@ -521,15 +524,11 @@ if (BUILD_TESTING)

add_executable(s2nc "bin/s2nc.c" "bin/echo.c" "bin/https.c" "bin/common.c")
target_link_libraries(s2nc ${PROJECT_NAME})

target_include_directories(s2nc PRIVATE api)
target_compile_options(s2nc PRIVATE -std=gnu99)


add_executable(s2nd "bin/s2nd.c" "bin/echo.c" "bin/https.c" "bin/common.c")
target_link_libraries(s2nd ${PROJECT_NAME})

target_include_directories(s2nd PRIVATE api)
target_compile_options(s2nd PRIVATE -std=gnu99)

if(S2N_LTO)
Expand Down
53 changes: 53 additions & 0 deletions api/s2n.h
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,27 @@ S2N_API extern int s2n_init(void);
*/
S2N_API extern int s2n_cleanup(void);

typedef enum {
S2N_FIPS_MODE_DISABLED = 0,
S2N_FIPS_MODE_ENABLED,
} s2n_fips_mode;

/**
* Determines whether s2n-tls is operating in FIPS mode.
*
* s2n-tls enters FIPS mode on initialization when the linked libcrypto has FIPS mode enabled. Some
* libcryptos, such as AWS-LC-FIPS, have FIPS mode enabled by default. With other libcryptos, such
* as OpenSSL, FIPS mode must be enabled before initialization by calling `FIPS_mode_set()`.
*
* s2n-tls MUST be linked to a FIPS libcrypto and MUST be in FIPS mode in order to comply with FIPS
* requirements. Applications desiring FIPS compliance should use this API to ensure that s2n-tls
* has been properly linked with a FIPS libcrypto and has successfully entered FIPS mode.
*
* @param fips_mode Set to the FIPS mode of s2n-tls.
* @returns S2N_SUCCESS on success. S2N_FAILURE on failure.
*/
S2N_API extern int s2n_get_fips_mode(s2n_fips_mode *fips_mode);

/**
* Creates a new s2n_config object. This object can (and should) be associated with many connection
* objects.
Expand Down Expand Up @@ -3001,6 +3022,38 @@ S2N_API extern int s2n_connection_client_cert_used(struct s2n_connection *conn);
*/
S2N_API extern const char *s2n_connection_get_cipher(struct s2n_connection *conn);

/**
* Provides access to the TLS master secret.
*
* This is a dangerous method and should not be used unless absolutely necessary.
* Mishandling the master secret can compromise both the current connection
* and any past or future connections that use the same master secret due to
* session resumption.
*
* This method is only supported for older TLS versions, and will report an S2N_ERR_INVALID_STATE
* usage error if called for a TLS1.3 connection. TLS1.3 includes a new key schedule
* that derives independent secrets from the master secret for specific purposes,
* such as separate traffic, session ticket, and exporter secrets. Using the master
* secret directly circumvents that security feature, reducing the security of
* the protocol.
*
* If you need cryptographic material tied to the current TLS session, consider
* `s2n_connection_tls_exporter` instead. Although s2n_connection_tls_exporter
* currently only supports TLS1.3, there is also an RFC that describes exporters
* for older TLS versions: https://datatracker.ietf.org/doc/html/rfc5705
* Using the master secret as-is or defining your own exporter is dangerous.
*
* @param conn A pointer to the connection.
* @param secret_bytes Memory to copy the master secret into. The secret
* is always 48 bytes long.
* @param max_size The size of the memory available at `secret_bytes`. Must be
* at least 48 bytes.
* @returns S2N_SUCCESS on success, S2N_FAILURE otherwise. `secret_bytes`
* will be set on success.
*/
S2N_API extern int s2n_connection_get_master_secret(const struct s2n_connection *conn,
uint8_t *secret_bytes, size_t max_size);

/**
* Provides access to the TLS-Exporter functionality.
*
Expand Down
4 changes: 2 additions & 2 deletions bin/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -345,8 +345,8 @@ int s2n_set_common_server_config(int max_early_data, struct s2n_config *config,

if (conn_settings.session_ticket || conn_settings.session_cache) {
/* Key initialization */
uint8_t *st_key;
uint32_t st_key_length;
uint8_t *st_key = NULL;
uint32_t st_key_length = 0;

if (session_ticket_key_file_path) {
int fd = open(session_ticket_key_file_path, O_RDONLY);
Expand Down
10 changes: 5 additions & 5 deletions bin/echo.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,10 +139,10 @@ int early_data_send(struct s2n_connection *conn, uint8_t *data, uint32_t len)

int print_connection_info(struct s2n_connection *conn)
{
int client_hello_version;
int client_protocol_version;
int server_protocol_version;
int actual_protocol_version;
int client_hello_version = 0;
int client_protocol_version = 0;
int server_protocol_version = 0;
int actual_protocol_version = 0;

if ((client_hello_version = s2n_connection_get_client_hello_version(conn)) < 0) {
fprintf(stderr, "Could not get client hello version\n");
Expand Down Expand Up @@ -179,7 +179,7 @@ int print_connection_info(struct s2n_connection *conn)
printf("KEM: %s\n", s2n_connection_get_kem_name(conn));
printf("KEM Group: %s\n", s2n_connection_get_kem_group_name(conn));

uint32_t length;
uint32_t length = 0;
const uint8_t *status = s2n_connection_get_ocsp_response(conn, &length);
if (status && length > 0) {
printf("OCSP response received, length %u\n", length);
Expand Down
4 changes: 2 additions & 2 deletions bin/s2nc.c
Original file line number Diff line number Diff line change
Expand Up @@ -278,8 +278,8 @@ static void setup_s2n_config(struct s2n_config *config, const char *cipher_prefs

int main(int argc, char *const *argv)
{
struct addrinfo hints, *ai_list, *ai;
int r, sockfd = 0;
struct addrinfo hints, *ai_list = NULL, *ai = NULL;
int r = 0, sockfd = 0;
bool session_ticket_recv = 0;
/* Optional args */
const char *alpn_protocols = NULL;
Expand Down
6 changes: 3 additions & 3 deletions bin/s2nd.c
Original file line number Diff line number Diff line change
Expand Up @@ -254,8 +254,8 @@ int handle_connection(int fd, struct s2n_config *config, struct conn_settings se

int main(int argc, char *const *argv)
{
struct addrinfo hints, *ai;
int r, sockfd = 0;
struct addrinfo hints, *ai = NULL;
int r = 0, sockfd = 0;

/* required args */
const char *host = NULL;
Expand Down Expand Up @@ -629,7 +629,7 @@ int main(int argc, char *const *argv)
"Failed to set key log callback");
}

int fd;
int fd = 0;
while ((fd = accept(sockfd, ai->ai_addr, &ai->ai_addrlen)) > 0) {
if (non_blocking) {
int flags = fcntl(sockfd, F_GETFL, 0);
Expand Down
2 changes: 2 additions & 0 deletions bindings/rust-examples/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*target/
*Cargo.lock
12 changes: 12 additions & 0 deletions bindings/rust-examples/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[workspace]
members = [
"client-hello-config-resolution",
]
resolver = "2"

[workspace.package]
version = "0.0.1"
authors = ["AWS s2n"]
publish = false
license = "Apache-2.0"
edition = "2021"
13 changes: 13 additions & 0 deletions bindings/rust-examples/client-hello-config-resolution/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[package]
name = "client-hello-config-resolution"
version.workspace = true
authors.workspace = true
publish.workspace = true
license.workspace = true
edition.workspace = true

[dependencies]
clap = { version = "4", features = ["derive"] }
s2n-tls = { path = "../../rust/s2n-tls" }
s2n-tls-tokio = { path = "../../rust/s2n-tls-tokio" }
tokio = { version = "1", features = ["full"] }
43 changes: 43 additions & 0 deletions bindings/rust-examples/client-hello-config-resolution/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
This example shows how to use the s2n-tls client hello callback to configure different TLS configs based on the Server Name Indication (SNI) in the client hello. The [server](src/bin/server.rs) sets up two configs for two different sni's, `www.wombat.com` and `www.kangaroo.com`. These configs are set up with different cipher preferences so that the allowed TLS versions are dependent on the client SNI.

To run this example, first start the server in one terminal
```
cargo run --bin server
```
Then run the client in another terminal, setting the appropriate SNI.

### Kangaroo SNI
```
cargo run --bin client www.kangaroo.com
```
```
TlsStream {
connection: Connection {
handshake_type: "NEGOTIATED|FULL_HANDSHAKE|MIDDLEBOX_COMPAT",
cipher_suite: "TLS_AES_128_GCM_SHA256",
actual_protocol_version: TLS13,
selected_curve: "x25519",
..
},
}
The server said Hello, you are speaking to www.kangaroo.com
```
We can see that the server successfully responded with the appropriate `www.kangaroo.com` certificate, resulting in a successful handshake.

### Wombat SNI
```
cargo run --bin client www.wombat.com
```
```
TlsStream {
connection: Connection {
handshake_type: "NEGOTIATED|FULL_HANDSHAKE|TLS12_PERFECT_FORWARD_SECRECY",
cipher_suite: "ECDHE-ECDSA-AES128-SHA",
actual_protocol_version: TLS12,
selected_curve: "secp256r1",
..
},
}
The server said Hello, you are speaking to www.wombat.com
```
Once again there is a successful handshake showing that the server responded with the proper certificate. In this case, the config that the server configured for `www.wombat.com` did not support TLS 1.3, so the TLS 1.2 was negotiated instead.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
-----BEGIN CERTIFICATE-----
MIIB3DCCAWKgAwIBAgIUaAjZTaFhJNRyFtFQut1CdrY7RH0wCgYIKoZIzj0EAwMw
HDELMAkGA1UEBhMCVVMxDTALBgNVBAMMBHJvb3QwIBcNMjQwMTI3MDAwODQ4WhgP
MjIwMzA3MDQwMDA4NDhaMBwxCzAJBgNVBAYTAlVTMQ0wCwYDVQQDDARyb290MHYw
EAYHKoZIzj0CAQYFK4EEACIDYgAEclmOmfFLoQR+mupZSc7J3IfZ6OV0IphUHWwv
iH9BvkGh4OX+RZfafa4hw90A5fk0ps520Dt04tHwotLBNkdQcWDJunOhw8ydebIP
TaP0V8OgxFs+P4kpBkMVNB3H+PK6o2MwYTAdBgNVHQ4EFgQU2ic6pZKpiyOr5aPt
YhABB9hJC5QwHwYDVR0jBBgwFoAU2ic6pZKpiyOr5aPtYhABB9hJC5QwDwYDVR0T
AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAgQwCgYIKoZIzj0EAwMDaAAwZQIxAMtZ
+QqC0LGdqUxdr2woMr6pUNAaZYaxm6APPqyKsjVqNaKadiSueNbbbc+seKJXbwIw
Zl0HNHzmoNAMkpgx5BCukjL1v07C571diSW4Z/P96t8tUzi/2rUOoFlJYU0B8cib
-----END CERTIFICATE-----
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#!/usr/bin/env bash

# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0

# immediately bail if any command fails
set -e

echo "generating CA"
openssl req -new -noenc -x509 \
-newkey ec \
-pkeyopt ec_paramgen_curve:P-384 \
-keyout ca-key.pem \
-out ca-cert.pem \
-days 65536 \
-SHA384 \
-subj "/C=US/CN=root" \
-addext "basicConstraints = critical,CA:true" \
-addext "keyUsage = critical,keyCertSign"

echo "generating wombat private key and CSR"
openssl req -new -noenc \
-newkey ec \
-pkeyopt ec_paramgen_curve:P-384 \
-keyout wombat-key.pem \
-out wombat.csr \
-subj "/C=US/CN=wombat" \
-addext "subjectAltName = DNS:www.wombat.com"

echo "generating kangaroo private key and CSR"
openssl req -new -noenc \
-newkey ec \
-pkeyopt ec_paramgen_curve:P-384 \
-keyout kangaroo-key.pem \
-out kangaroo.csr \
-subj "/C=US/CN=kangaroo" \
-addext "subjectAltName = DNS:www.kangaroo.com"

echo "generating wombat server certificate and signing it"
openssl x509 -days 65536 \
-req -in wombat.csr \
-SHA384 \
-CA ca-cert.pem \
-CAkey ca-key.pem \
-CAcreateserial \
-out wombat-cert.pem \
-copy_extensions=copyall

echo "generating kangaroo certificate and signing it"
openssl x509 -days 65536 \
-req -in kangaroo.csr \
-SHA384 \
-CA ca-cert.pem \
-CAkey ca-key.pem \
-CAcreateserial \
-out kangaroo-cert.pem \
-copy_extensions=copyall

touch wombat-chain.pem
cat wombat-cert.pem >> wombat-chain.pem
cat ca-cert.pem >> wombat-chain.pem

touch kangaroo-chain.pem
cat kangaroo-cert.pem >> kangaroo-chain.pem
cat ca-cert.pem >> kangaroo-chain.pem

echo "verifying server certificates"
openssl verify -CAfile ca-cert.pem wombat-cert.pem
openssl verify -CAfile ca-cert.pem kangaroo-cert.pem

# certificate signing requests are never used after the certs are generated
rm wombat.csr
rm kangaroo.csr
rm ca-cert.srl

# the private keys of the CA are never needed after signing
rm ca-key.pem
rm wombat-cert.pem
rm kangaroo-cert.pem

Loading

0 comments on commit 0b2268e

Please sign in to comment.