Skip to content

Commit

Permalink
Merge branch 'main' into client-hello-config-resolution
Browse files Browse the repository at this point in the history
  • Loading branch information
jmayclin authored Mar 26, 2024
2 parents 9417de0 + 30a4901 commit 1f756d4
Show file tree
Hide file tree
Showing 343 changed files with 6,307 additions and 2,967 deletions.
9 changes: 5 additions & 4 deletions .github/workflows/ci_openbsd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,18 @@ on:

jobs:
testopenbsd:
runs-on: macos-12
runs-on: ubuntu-latest
name: CI OpenBSD
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Build and test in OpenBSD
id: test
uses: cross-platform-actions/action@v0.21.1
uses: cross-platform-actions/action@v0.23.0
with:
operating_system: openbsd
architecture: x86-64
version: '7.2'
version: '7.4'
cpu_count: 4
shell: bash
run: |
sudo pkg_add ninja cmake
Expand Down
26 changes: 17 additions & 9 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ otherwise a crypto target needs to be defined." ON)
option(UNSAFE_TREAT_WARNINGS_AS_ERRORS "Compiler warnings are treated as errors. Warnings may
indicate danger points where you should verify with the S2N-TLS developers that the security of
the library is not compromised. Turn this OFF to ignore warnings." ON)
option(S2N_WERROR_ALL "This option will cause all artifacts linked to libs2n to use the
-Werror setting." OFF)
option(S2N_INTERN_LIBCRYPTO "This ensures that s2n-tls is compiled and deployed with a specific
version of libcrypto by interning the code and hiding symbols. This also enables s2n-tls to be
loaded in an application with an otherwise conflicting libcrypto version." OFF)
Expand All @@ -34,6 +36,7 @@ option(COVERAGE "Enable profiling collection for code coverage calculation" OFF)
option(S2N_INTEG_TESTS "Enable the integrationv2 tests" OFF)
option(S2N_FAST_INTEG_TESTS "Enable the integrationv2 with more parallelism, only has effect if S2N_INTEG_TESTS=ON" ON)
option(S2N_INSTALL_S2NC_S2ND "Install the binaries s2nc and s2nd" OFF)
option(S2N_USE_CRYPTO_SHARED_LIBS "For S2N to use shared libs in Findcrypto" OFF)
option(TSAN "Enable ThreadSanitizer to test thread safety" OFF)
option(ASAN "Enable AddressSanitizer to test memory safety" OFF)

Expand Down Expand Up @@ -136,7 +139,9 @@ target_compile_options(${PROJECT_NAME} PRIVATE -pedantic -std=gnu99 -Wall -Wimpl
-Wno-missing-braces -Wsign-compare -Wno-strict-prototypes -Wa,--noexecstack
)

if (UNSAFE_TREAT_WARNINGS_AS_ERRORS)
if (S2N_WERROR_ALL)
target_compile_options(${PROJECT_NAME} PUBLIC -Werror)
elseif (UNSAFE_TREAT_WARNINGS_AS_ERRORS)
target_compile_options(${PROJECT_NAME} PRIVATE -Werror )
endif ()

Expand Down Expand Up @@ -192,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 @@ -488,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 @@ -500,7 +508,11 @@ if (BUILD_TESTING)
find . -name '${test_case_name}.c.o' -exec objcopy --redefine-syms libcrypto.symbols {} \\\;
)
endif()
target_compile_options(${test_case_name} PRIVATE -Wno-implicit-function-declaration -Wno-deprecated -D_POSIX_C_SOURCE=200809L -std=gnu99)
target_compile_options(${test_case_name} PRIVATE
-Wall -Wimplicit -Wunused -Wcomment -Wchar-subscripts -Wuninitialized
-Wshadow -Wcast-align -Wwrite-strings -Wformat-security
-Wno-deprecated-declarations -Wno-unknown-pragmas -Wno-deprecated
-fPIC -D_POSIX_C_SOURCE=200809L -std=gnu99)
if (S2N_LTO)
target_compile_options(${test_case_name} PRIVATE -flto)
endif()
Expand All @@ -512,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
127 changes: 123 additions & 4 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 @@ -1559,6 +1580,47 @@ S2N_API extern int s2n_client_hello_get_session_id_length(struct s2n_client_hell
*/
S2N_API extern int s2n_client_hello_get_session_id(struct s2n_client_hello *ch, uint8_t *out, uint32_t *out_length, uint32_t max_length);

/**
* Get the length of the compression methods list sent in the Client Hello.
*
* @param ch A pointer to the Client Hello
* @param out_length An out pointer. Will be set to the length of the compression methods list in bytes.
* @returns S2N_SUCCESS on success. S2N_FAILURE on failure
*/
S2N_API extern int s2n_client_hello_get_compression_methods_length(struct s2n_client_hello *ch, uint32_t *out_length);

/**
* Retrieves the list of compression methods sent in the Client Hello.
*
* Use `s2n_client_hello_get_compression_methods_length()`
* to retrieve how much memory should be allocated for the buffer in advance.
*
* @note Compression methods were removed in TLS1.3 and therefore the only valid value in this list is the
* "null" compression method when TLS1.3 is negotiated.
*
* @note s2n-tls has never supported compression methods in any TLS version and therefore a
* compression method will never be negotiated or used.
*
* @param ch A pointer to the Client Hello
* @param list A pointer to some memory that s2n will write the compression methods to. This memory MUST be the size of `list_length`
* @param list_length The size of `list`.
* @param out_length An out pointer. s2n will set its value to the size of the compression methods list in bytes.
* @returns S2N_SUCCESS on success. S2N_FAILURE on failure
*/
S2N_API extern int s2n_client_hello_get_compression_methods(struct s2n_client_hello *ch, uint8_t *list, uint32_t list_length, uint32_t *out_length);

/**
* Access the Client Hello protocol version
*
* @note This field is a legacy field in TLS1.3 and is no longer used to negotiate the
* protocol version of the connection. It will be set to TLS1.2 even if TLS1.3 is negotiated.
* Therefore this method should only be used for logging or fingerprinting.
*
* @param ch A pointer to the client hello struct
* @param out The protocol version in the client hello.
*/
S2N_API extern int s2n_client_hello_get_legacy_protocol_version(struct s2n_client_hello *ch, uint8_t *out);

/**
* Retrieves the supported groups received from the client in the supported groups extension.
*
Expand All @@ -1584,6 +1646,26 @@ S2N_API extern int s2n_client_hello_get_session_id(struct s2n_client_hello *ch,
S2N_API extern int s2n_client_hello_get_supported_groups(struct s2n_client_hello *ch, uint16_t *groups,
uint16_t groups_count_max, uint16_t *groups_count);

/**
* Gets the length of the first server name in a Client Hello.
*
* @param ch A pointer to the ClientHello
* @param length A pointer which will be populated with the length of the server name
*/
S2N_API extern int s2n_client_hello_get_server_name_length(struct s2n_client_hello *ch, uint16_t *length);

/**
* Gets the first server name in a Client Hello.
*
* Use `s2n_client_hello_get_server_name_length()` to get the amount of memory needed for the buffer.
*
* @param ch A pointer to the ClientHello
* @param server_name A pointer to the memory which will be populated with the server name
* @param length The maximum amount of data that can be written to `server_name`
* @param out_length A pointer which will be populated with the size of the server name
*/
S2N_API extern int s2n_client_hello_get_server_name(struct s2n_client_hello *ch, uint8_t *server_name, uint16_t length, uint16_t *out_length);

/**
* Sets the file descriptor for a s2n connection.
*
Expand Down Expand Up @@ -1821,6 +1903,30 @@ S2N_API extern uint64_t s2n_connection_get_delay(struct s2n_connection *conn);
*/
S2N_API extern int s2n_connection_set_cipher_preferences(struct s2n_connection *conn, const char *version);

/**
* Used to indicate the type of key update that is being requested. For further
* information refer to `s2n_connection_request_key_update`.
*/
typedef enum {
S2N_KEY_UPDATE_NOT_REQUESTED = 0,
S2N_KEY_UPDATE_REQUESTED
} s2n_peer_key_update;

/**
* Signals the connection to do a key_update at the next possible opportunity. Note that the resulting key update message
* will not be sent until `s2n_send` is called.
*
* @param conn The connection object to trigger the key update on.
* @param peer_request Indicates if a key update should also be requested
* of the peer. When set to `S2N_KEY_UPDATE_NOT_REQUESTED`, then only the sending
* key of `conn` will be updated. If set to `S2N_KEY_UPDATE_REQUESTED`, then
* the sending key of conn will be updated AND the peer will be requested to
* update their sending key. Note that s2n-tls currently only supports
* `peer_request` being set to `S2N_KEY_UPDATE_NOT_REQUESTED` and will return
* S2N_FAILURE if any other value is used.
* @returns S2N_SUCCESS on success. S2N_FAILURE on failure
*/
S2N_API extern int s2n_connection_request_key_update(struct s2n_connection *conn, s2n_peer_key_update peer_request);
/**
* Appends the provided application protocol to the preference list
*
Expand Down Expand Up @@ -1947,7 +2053,7 @@ S2N_API extern int s2n_negotiate(struct s2n_connection *conn, s2n_blocked_status
* @param buf A pointer to a buffer that s2n will write data from
* @param size The size of buf
* @param blocked A pointer which will be set to the blocked status if an `S2N_ERR_T_BLOCKED` error is returned.
* @returns The number of bytes written, and may indicate a partial write
* @returns The number of bytes written on success, which may indicate a partial write. S2N_FAILURE on failure.
*/
S2N_API extern ssize_t s2n_send(struct s2n_connection *conn, const void *buf, ssize_t size, s2n_blocked_status *blocked);

Expand All @@ -1960,7 +2066,7 @@ S2N_API extern ssize_t s2n_send(struct s2n_connection *conn, const void *buf, ss
* @param bufs A pointer to a vector of buffers that s2n will write data from.
* @param count The number of buffers in `bufs`
* @param blocked A pointer which will be set to the blocked status if an `S2N_ERR_T_BLOCKED` error is returned.
* @returns The number of bytes written, and may indicate a partial write.
* @returns The number of bytes written on success, which may indicate a partial write. S2N_FAILURE on failure.
*/
S2N_API extern ssize_t s2n_sendv(struct s2n_connection *conn, const struct iovec *bufs, ssize_t count, s2n_blocked_status *blocked);

Expand All @@ -1979,7 +2085,7 @@ S2N_API extern ssize_t s2n_sendv(struct s2n_connection *conn, const struct iovec
* @param count The number of buffers in `bufs`
* @param offs The write cursor offset. This should be updated as data is written. See the example code.
* @param blocked A pointer which will be set to the blocked status if an `S2N_ERR_T_BLOCKED` error is returned.
* @returns The number of bytes written, and may indicate a partial write.
* @returns The number of bytes written on success, which may indicate a partial write. S2N_FAILURE on failure.
*/
S2N_API extern ssize_t s2n_sendv_with_offset(struct s2n_connection *conn, const struct iovec *bufs, ssize_t count, ssize_t offs, s2n_blocked_status *blocked);

Expand All @@ -1996,7 +2102,7 @@ S2N_API extern ssize_t s2n_sendv_with_offset(struct s2n_connection *conn, const
* @param buf A pointer to a buffer that s2n will place read data into.
* @param size Size of `buf`
* @param blocked A pointer which will be set to the blocked status if an `S2N_ERR_T_BLOCKED` error is returned.
* @returns number of bytes read. 0 if the connection was shutdown by peer.
* @returns The number of bytes read on success. 0 if the connection was shutdown by the peer. S2N_FAILURE on failure.
*/
S2N_API extern ssize_t s2n_recv(struct s2n_connection *conn, void *buf, ssize_t size, s2n_blocked_status *blocked);

Expand Down Expand Up @@ -2879,6 +2985,19 @@ S2N_API extern int s2n_connection_get_actual_protocol_version(struct s2n_connect
*/
S2N_API extern int s2n_connection_get_client_hello_version(struct s2n_connection *conn);

/**
* Access the protocol version from the header of the first record that contained the ClientHello message.
*
* @note This field has been deprecated and should not be confused with the client hello
* version. It is often set very low, usually to TLS1.0 for compatibility reasons,
* and should never be set higher than TLS1.2. Therefore this method should only be used
* for logging or fingerprinting.
*
* @param conn A pointer to the client hello struct
* @param out The protocol version in the record header containing the Client Hello.
*/
S2N_API extern int s2n_client_hello_get_legacy_record_version(struct s2n_client_hello *ch, uint8_t *out);

/**
* Check if Client Auth was used for a connection.
*
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
3 changes: 3 additions & 0 deletions bindings/rust/bench/benches/resumption.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

use bench::{
harness::TlsBenchConfig, CipherSuite, CryptoConfig, HandshakeType, KXGroup, S2NConnection,
SigType, TlsConnPair, TlsConnection,
Expand Down
3 changes: 3 additions & 0 deletions bindings/rust/bench/src/bin/graph_memory.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

use plotters::{
prelude::{
ChartBuilder, IntoDrawingArea, IntoSegmentedCoord, LabelAreaPosition, Rectangle,
Expand Down
Loading

0 comments on commit 1f756d4

Please sign in to comment.