diff --git a/.github/workflows/ci_openbsd.yml b/.github/workflows/ci_openbsd.yml index 9b5876f25fc..3bd2292a762 100644 --- a/.github/workflows/ci_openbsd.yml +++ b/.github/workflows/ci_openbsd.yml @@ -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 diff --git a/CMakeLists.txt b/CMakeLists.txt index ac12886c7a9..5713558d349 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) @@ -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) @@ -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 () @@ -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() @@ -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 @@ -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() @@ -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) diff --git a/api/s2n.h b/api/s2n.h index 84e3cf01fb7..15f6dbf9c7e 100644 --- a/api/s2n.h +++ b/api/s2n.h @@ -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. @@ -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. * @@ -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. * @@ -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 * @@ -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); @@ -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); @@ -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); @@ -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); @@ -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. * diff --git a/bin/common.c b/bin/common.c index 35295753394..9e4a1f739a8 100644 --- a/bin/common.c +++ b/bin/common.c @@ -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); diff --git a/bin/echo.c b/bin/echo.c index 4b7cc1db969..e3f5b31d5c1 100644 --- a/bin/echo.c +++ b/bin/echo.c @@ -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"); @@ -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); diff --git a/bin/s2nc.c b/bin/s2nc.c index a7fcfc1ac01..3afd29ea78b 100644 --- a/bin/s2nc.c +++ b/bin/s2nc.c @@ -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; diff --git a/bin/s2nd.c b/bin/s2nd.c index c34ffbc740c..6e6d29a9e70 100644 --- a/bin/s2nd.c +++ b/bin/s2nd.c @@ -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; @@ -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); diff --git a/bindings/rust/bench/benches/resumption.rs b/bindings/rust/bench/benches/resumption.rs index e98887521e0..3a7aaa32579 100644 --- a/bindings/rust/bench/benches/resumption.rs +++ b/bindings/rust/bench/benches/resumption.rs @@ -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, diff --git a/bindings/rust/bench/src/bin/graph_memory.rs b/bindings/rust/bench/src/bin/graph_memory.rs index 0a28f6a284f..c633e69d7b9 100644 --- a/bindings/rust/bench/src/bin/graph_memory.rs +++ b/bindings/rust/bench/src/bin/graph_memory.rs @@ -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, diff --git a/bindings/rust/generate.sh b/bindings/rust/generate.sh index 5890e97fa7d..47f2e1ef043 100755 --- a/bindings/rust/generate.sh +++ b/bindings/rust/generate.sh @@ -2,7 +2,7 @@ # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 -set -e +set -xe # cd into the script directory so it can be executed from anywhere pushd "$(dirname "${BASH_SOURCE[0]}")" @@ -52,19 +52,6 @@ cargo publish --dry-run --allow-dirty cargo publish --dry-run --allow-dirty --all-features popd -# if this version has already been published we can run -# additional validation to ensure there won't be build -# problems when a new version is published -if ! ./scripts/detect-new-release; then - pushd s2n-tls - cargo publish --dry-run --allow-dirty - popd - - pushd s2n-tls-tokio - cargo publish --dry-run --allow-dirty - popd -fi - pushd integration cargo run popd diff --git a/bindings/rust/generate/Cargo.toml b/bindings/rust/generate/Cargo.toml index 09a63c0da1d..5fc71eff738 100644 --- a/bindings/rust/generate/Cargo.toml +++ b/bindings/rust/generate/Cargo.toml @@ -11,4 +11,4 @@ publish = false bindgen = "0.65" glob = "0.3" regex = "=1.9.6" # newer versions require rust 1.65, see https://github.com/aws/s2n-tls/issues/4242 -home = "=0.5.5" # newer versions require rust 1.70 +home = "=0.5.5" # newer versions require rust 1.70, see https://github.com/aws/s2n-tls/issues/4395 diff --git a/bindings/rust/s2n-tls-sys/build.rs b/bindings/rust/s2n-tls-sys/build.rs index 0ee83cfe68c..34889e6abed 100644 --- a/bindings/rust/s2n-tls-sys/build.rs +++ b/bindings/rust/s2n-tls-sys/build.rs @@ -13,7 +13,8 @@ fn main() { } fn env>(name: N) -> String { - option_env(name).expect("missing env var") + let name = name.as_ref(); + option_env(name).unwrap_or_else(|| panic!("missing env var {name:?}")) } fn option_env>(name: N) -> Option { @@ -197,9 +198,9 @@ impl Default for Libcrypto { eprintln!("cargo:rerun-if-env-changed={}", name); - let link = format!("aws_lc_{version}_crypto"); let include = value; let root = env(format!("DEP_AWS_LC_{version}_ROOT")); + let link = env(format!("DEP_AWS_LC_{version}_LIBCRYPTO")); return Self { version, diff --git a/bindings/rust/s2n-tls-sys/src/lib.rs b/bindings/rust/s2n-tls-sys/src/lib.rs index 1135d8e6b74..957167c6ac3 100644 --- a/bindings/rust/s2n-tls-sys/src/lib.rs +++ b/bindings/rust/s2n-tls-sys/src/lib.rs @@ -7,6 +7,8 @@ mod api; pub use api::*; mod features; + +#[allow(unused_imports)] pub use features::*; // Additional defines that don't get imported with bindgen diff --git a/bindings/rust/s2n-tls-sys/templates/Cargo.template b/bindings/rust/s2n-tls-sys/templates/Cargo.template index 531556bad6f..8a7fe3b59b8 100644 --- a/bindings/rust/s2n-tls-sys/templates/Cargo.template +++ b/bindings/rust/s2n-tls-sys/templates/Cargo.template @@ -1,7 +1,7 @@ [package] name = "s2n-tls-sys" description = "A C99 implementation of the TLS/SSL protocols" -version = "0.1.2" +version = "0.2.0" authors = ["AWS s2n"] edition = "2021" rust-version = "1.63.0" @@ -35,7 +35,7 @@ stacktrace = [] # unstable-foo = [] [dependencies] -aws-lc-sys = { version = "0.12" } +aws-lc-rs = { version = "1.6.2" } libc = "0.2" [build-dependencies] @@ -43,3 +43,5 @@ cc = { version = "1.0", features = ["parallel"] } [dev-dependencies] jobserver = "=0.1.26" # newer versions require rust 1.66, see https://github.com/aws/s2n-tls/issues/4241 +home = "=0.5.5" # newer versions require rust 1.70, see https://github.com/aws/s2n-tls/issues/4395 +regex = "=1.9.6" # newer versions require rust 1.65, see https://github.com/aws/s2n-tls/issues/4242 diff --git a/bindings/rust/s2n-tls-tokio/Cargo.toml b/bindings/rust/s2n-tls-tokio/Cargo.toml index f9f2e1d60cf..b0437e624f9 100644 --- a/bindings/rust/s2n-tls-tokio/Cargo.toml +++ b/bindings/rust/s2n-tls-tokio/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "s2n-tls-tokio" description = "An implementation of TLS streams for Tokio built on top of s2n-tls" -version = "0.1.2" +version = "0.2.0" authors = ["AWS s2n"] edition = "2021" rust-version = "1.63.0" @@ -15,7 +15,7 @@ default = [] errno = { version = "0.3" } libc = { version = "0.2" } pin-project-lite = { version = "0.2" } -s2n-tls = { version = "=0.1.2", path = "../s2n-tls" } +s2n-tls = { version = "=0.2.0", path = "../s2n-tls" } tokio = { version = "1", features = ["net", "time"] } [dev-dependencies] @@ -26,4 +26,4 @@ tokio = { version = "1", features = [ "io-std", "io-util", "macros", "net", "rt- # this version pin is only needed to prevent verification failures when using # cargo package / cargo publish, as those commands do not respect the version pin # in downstream dev-dependencies (in s2n-tls-sys, in this case) -jobserver = "=0.1.26" +jobserver = "=0.1.26" diff --git a/bindings/rust/s2n-tls-tokio/src/lib.rs b/bindings/rust/s2n-tls-tokio/src/lib.rs index 3e6d60e687b..4d78b88236d 100644 --- a/bindings/rust/s2n-tls-tokio/src/lib.rs +++ b/bindings/rust/s2n-tls-tokio/src/lib.rs @@ -112,10 +112,11 @@ where let result = match self.error.take() { Some(err) => Err(err), None => { - ready!(self.tls.with_io(ctx, |context| { + let handshake_poll = self.tls.with_io(ctx, |context| { let conn = context.get_mut().as_mut(); conn.poll_negotiate().map(|r| r.map(|_| ())) - })) + }); + ready!(handshake_poll) } }; // If the result isn't a fatal error, return it immediately. @@ -363,15 +364,19 @@ where fn poll_shutdown(mut self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll> { ready!(self.as_mut().poll_blinding(ctx))?; - // s2n_shutdown must not be called again if it errors + // s2n_shutdown_send must not be called again if it errors if self.shutdown_error.is_none() { let result = ready!(self.as_mut().with_io(ctx, |mut context| { - context.conn.as_mut().poll_shutdown().map(|r| r.map(|_| ())) + context + .conn + .as_mut() + .poll_shutdown_send() + .map(|r| r.map(|_| ())) })); if let Err(error) = result { self.shutdown_error = Some(error); - // s2n_shutdown reading might have triggered blinding again - ready!(self.as_mut().poll_blinding(ctx))?; + // s2n_shutdown_send only writes, so will never trigger blinding again. + // So we do not need to poll_blinding again after this error. } }; diff --git a/bindings/rust/s2n-tls-tokio/tests/shutdown.rs b/bindings/rust/s2n-tls-tokio/tests/shutdown.rs index e67b87599dd..e9bf8aff81f 100644 --- a/bindings/rust/s2n-tls-tokio/tests/shutdown.rs +++ b/bindings/rust/s2n-tls-tokio/tests/shutdown.rs @@ -16,10 +16,6 @@ use tokio::{ pub mod common; -// An arbitrary but very long timeout. -// No valid single IO operation should take anywhere near 10 minutes. -pub const LONG_TIMEOUT: time::Duration = time::Duration::from_secs(600); - async fn read_until_shutdown( stream: &mut TlsStream, ) -> Result<(), std::io::Error> { @@ -166,18 +162,6 @@ async fn shutdown_with_blinding() -> Result<(), Box> { let (mut client, mut server) = common::run_negotiate(&client, client_stream, &server, server_stream).await?; - // Attempt to shutdown the client. This will eventually fail because the - // server has not written the close_notify message yet, but it will at least - // write the close_notify message that the server needs. - // - // Because this test begins paused and relies on auto-advancing, this does - // not actually require waiting LONG_TIMEOUT. See the tokio `pause()` docs: - // https://docs.rs/tokio/latest/tokio/time/fn.pause.html - // - // TODO: replace this with a half-close once the bindings support half-close. - let timeout = time::timeout(LONG_TIMEOUT, client.shutdown()).await; - assert!(timeout.is_err()); - // Setup a bad record for the next read overrides.next_read(Some(Box::new(|_, _, buf| { // Parsing the header is one of the blinded operations @@ -202,53 +186,9 @@ async fn shutdown_with_blinding() -> Result<(), Box> { // Server MUST eventually successfully shutdown assert!(result.is_ok()); - // Shutdown MUST have sent the close_notify message needed by the peer - // to also shutdown successfully. - client.shutdown().await?; - - Ok(()) -} - -#[tokio::test(start_paused = true)] -async fn shutdown_with_blinding_bad_close_record() -> Result<(), Box> { - let clock = common::TokioTime::default(); - let mut server_config = common::server_config()?; - server_config.set_monotonic_clock(clock)?; - - let client = TlsConnector::new(common::client_config()?.build()?); - let server = TlsAcceptor::new(server_config.build()?); - - let (server_stream, client_stream) = common::get_streams().await?; - let server_stream = common::TestStream::new(server_stream); - let overrides = server_stream.overrides(); - let (mut client, mut server) = - common::run_negotiate(&client, client_stream, &server, server_stream).await?; - - // Setup a bad record for the next read - overrides.next_read(Some(Box::new(|_, _, buf| { - // Parsing the header is one of the blinded operations - // in s2n_shutdown, so provide a malformed header. - let zeroed_header = [23, 0, 0, 0, 0]; - buf.put_slice(&zeroed_header); - Ok(()).into() - }))); - - let time_start = time::Instant::now(); - let result = server.shutdown().await; - let time_elapsed = time_start.elapsed(); - - // Shutdown MUST NOT complete faster than minimal blinding time. - assert!(time_elapsed > common::MIN_BLINDING_SECS); - - // Shutdown MUST eventually complete with the correct error after blinding. - let io_error = result.unwrap_err(); - let error: error::Error = io_error.try_into()?; - assert!(error.kind() == error::ErrorType::ProtocolError); - assert!(error.name() == "S2N_ERR_BAD_MESSAGE"); - - // Shutdown MUST have sent the close_notify message needed by the peer - // to also shutdown successfully. - client.shutdown().await?; + // Shutdown MUST have sent the close_notify message needed for EOF. + let mut received = [0; 1]; + assert!(client.read(&mut received).await? == 0); Ok(()) } @@ -295,7 +235,7 @@ async fn shutdown_with_poll_blinding() -> Result<(), Box> Ok(()) } -#[tokio::test(start_paused = true)] +#[tokio::test] async fn shutdown_with_tcp_error() -> Result<(), Box> { let client = TlsConnector::new(common::client_config()?.build()?); let server = TlsAcceptor::new(common::server_config()?.build()?); @@ -304,20 +244,9 @@ async fn shutdown_with_tcp_error() -> Result<(), Box> { let server_stream = common::TestStream::new(server_stream); let overrides = server_stream.overrides(); - let (mut client, mut server) = + let (_, mut server) = common::run_negotiate(&client, client_stream, &server, server_stream).await?; - // Attempt to shutdown the client. This will eventually fail because the - // server has not written the close_notify message yet, but it will at least - // write the close_notify message that the server needs. - // - // Because this test begins paused and relies on auto-advancing, this does - // not actually require waiting LONG_TIMEOUT. See the tokio `pause()` docs: - // https://docs.rs/tokio/latest/tokio/time/fn.pause.html - // - // TODO: replace this with a half-close once the bindings support half-close. - _ = time::timeout(time::Duration::from_secs(600), client.shutdown()).await; - // The underlying stream should return a unique error on shutdown overrides.next_shutdown(Some(Box::new(|_, _| { Ready(Err(io::Error::new(io::ErrorKind::Other, common::TEST_STR))) @@ -343,22 +272,22 @@ async fn shutdown_with_tls_error_and_tcp_error() -> Result<(), Box Result<(), Box Result<(), Box, connection: &mut Connection, diff --git a/bindings/rust/s2n-tls/src/callbacks/client_hello.rs b/bindings/rust/s2n-tls/src/callbacks/client_hello.rs index d4d382196a2..524620d9100 100644 --- a/bindings/rust/s2n-tls/src/callbacks/client_hello.rs +++ b/bindings/rust/s2n-tls/src/callbacks/client_hello.rs @@ -48,7 +48,7 @@ impl>> ConfigResolver< } } -impl>> ConnectionFuture +impl>> ConnectionFuture for ConfigResolver { fn poll( diff --git a/bindings/rust/s2n-tls/src/cert_chain.rs b/bindings/rust/s2n-tls/src/cert_chain.rs new file mode 100644 index 00000000000..007657d15f5 --- /dev/null +++ b/bindings/rust/s2n-tls/src/cert_chain.rs @@ -0,0 +1,154 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +use crate::error::{Error, Fallible}; +use s2n_tls_sys::*; +use std::{ + marker::PhantomData, + ptr::{self, NonNull}, +}; + +/// A CertificateChain represents a chain of X.509 certificates. +pub struct CertificateChain<'a> { + ptr: NonNull, + is_owned: bool, + _lifetime: PhantomData<&'a s2n_cert_chain_and_key>, +} + +impl CertificateChain<'_> { + /// This allocates a new certificate chain from s2n. + pub(crate) fn new() -> Result, Error> { + unsafe { + let ptr = s2n_cert_chain_and_key_new().into_result()?; + Ok(CertificateChain { + ptr, + is_owned: true, + _lifetime: PhantomData, + }) + } + } + + pub(crate) unsafe fn from_ptr_reference<'a>( + ptr: NonNull, + ) -> CertificateChain<'a> { + CertificateChain { + ptr, + is_owned: false, + _lifetime: PhantomData, + } + } + + pub fn iter(&self) -> CertificateChainIter<'_> { + CertificateChainIter { + idx: 0, + // Cache the length as it's O(n) to compute it, the chain is stored as a linked list. + // It shouldn't change while we have access to the iterator. + len: self.len(), + chain: self, + } + } + + /// Return the length of this certificate chain. + /// + /// Note that the underyling API currently traverses a linked list, so this is a relatively + /// expensive API to call. + pub fn len(&self) -> usize { + let mut length: u32 = 0; + let res = + unsafe { s2n_cert_chain_get_length(self.ptr.as_ptr(), &mut length).into_result() }; + if res.is_err() { + // Errors should only happen on empty chains (we guarantee that `ptr` is a valid chain). + return 0; + } + // u32 should always fit into usize on the platforms we support. + length.try_into().unwrap() + } + + /// Check if the certificate chain has any certificates. + /// + /// Note that the underyling API currently traverses a linked list, so this is a relatively + /// expensive API to call. + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + + pub(crate) fn as_mut_ptr(&mut self) -> NonNull { + self.ptr + } +} + +// # Safety +// +// s2n_cert_chain_and_key objects can be sent across threads. +unsafe impl Send for CertificateChain<'_> {} + +impl Drop for CertificateChain<'_> { + fn drop(&mut self) { + if self.is_owned { + // ignore failures since there's not much we can do about it + unsafe { + let _ = s2n_cert_chain_and_key_free(self.ptr.as_ptr()).into_result(); + } + } + } +} + +pub struct CertificateChainIter<'a> { + idx: u32, + len: usize, + chain: &'a CertificateChain<'a>, +} + +impl<'a> Iterator for CertificateChainIter<'a> { + type Item = Result, Error>; + + fn next(&mut self) -> Option { + let idx = self.idx; + // u32 fits into usize on platforms we support. + if usize::try_from(idx).unwrap() >= self.len { + return None; + } + self.idx += 1; + let mut out = ptr::null_mut(); + unsafe { + if let Err(e) = + s2n_cert_chain_get_cert(self.chain.ptr.as_ptr(), &mut out, idx).into_result() + { + return Some(Err(e)); + } + } + let out = match NonNull::new(out) { + Some(out) => out, + None => return Some(Err(Error::INVALID_INPUT)), + }; + Some(Ok(Certificate { + chain: PhantomData, + certificate: out, + })) + } +} + +pub struct Certificate<'a> { + // The chain owns the memory for this certificate. + chain: PhantomData<&'a CertificateChain<'a>>, + + certificate: NonNull, +} + +impl<'a> Certificate<'a> { + pub fn der(&self) -> Result<&[u8], Error> { + unsafe { + let mut buffer = ptr::null(); + let mut length = 0; + s2n_cert_get_der(self.certificate.as_ptr(), &mut buffer, &mut length).into_result()?; + let length = usize::try_from(length).map_err(|_| Error::INVALID_INPUT)?; + + Ok(std::slice::from_raw_parts(buffer, length)) + } + } +} + +// # Safety +// +// Certificates just reference data in the chain, so share the Send-ness of the chain. +unsafe impl Send for Certificate<'_> {} diff --git a/bindings/rust/s2n-tls/src/client_hello.rs b/bindings/rust/s2n-tls/src/client_hello.rs index 4391190d736..dab6e2444db 100644 --- a/bindings/rust/s2n-tls/src/client_hello.rs +++ b/bindings/rust/s2n-tls/src/client_hello.rs @@ -168,6 +168,27 @@ impl ClientHello { Ok(session_id) } + fn server_name(&self) -> Result, Error> { + let mut server_name_length = 0; + unsafe { + s2n_client_hello_get_server_name_length(self.deref_mut_ptr(), &mut server_name_length) + .into_result()?; + } + + let mut server_name = vec![0; server_name_length as usize]; + let mut out_length = 0; + unsafe { + s2n_client_hello_get_server_name( + self.deref_mut_ptr(), + server_name.as_mut_ptr(), + server_name_length, + &mut out_length, + ) + .into_result()?; + } + Ok(server_name) + } + fn raw_message(&self) -> Result, Error> { let message_length = unsafe { s2n_client_hello_get_raw_message_length(self.deref_mut_ptr()).into_result()? }; diff --git a/bindings/rust/s2n-tls/src/config.rs b/bindings/rust/s2n-tls/src/config.rs index 3137a9d248d..9c42ad2b532 100644 --- a/bindings/rust/s2n-tls/src/config.rs +++ b/bindings/rust/s2n-tls/src/config.rs @@ -151,7 +151,6 @@ impl Drop for Config { } } -#[derive(Default)] pub struct Builder { config: Config, load_system_certs: bool, @@ -743,6 +742,12 @@ impl Builder { } } +impl Default for Builder { + fn default() -> Self { + Self::new() + } +} + pub(crate) struct Context { refcount: AtomicUsize, pub(crate) client_hello_callback: Option>, diff --git a/bindings/rust/s2n-tls/src/connection.rs b/bindings/rust/s2n-tls/src/connection.rs index 071de8e4916..90126ed4cc5 100644 --- a/bindings/rust/s2n-tls/src/connection.rs +++ b/bindings/rust/s2n-tls/src/connection.rs @@ -5,6 +5,7 @@ use crate::{ callbacks::*, + cert_chain::CertificateChain, config::Config, enums::*, error::{Error, Fallible, Pollable}, @@ -63,6 +64,21 @@ impl fmt::Debug for Connection { /// s2n_connection objects can be sent across threads unsafe impl Send for Connection {} +/// # Sync +/// +/// Although NonNull isn't Sync and allows access to mutable pointers even from +/// immutable references, the Connection interface enforces that all mutating +/// methods correctly require &mut self. +/// +/// Developers and reviewers MUST ensure that new methods correctly use +/// either &self or &mut self depending on their behavior. No mechanism enforces this. +/// +/// Note: Although non-mutating methods like getters should be thread-safe by definition, +/// technically the only thread safety guarantee provided by the underlying C library +/// is that s2n_send and s2n_recv can be called concurrently. +/// +unsafe impl Sync for Connection {} + impl Connection { pub fn new(mode: Mode) -> Self { crate::init::init(); @@ -553,6 +569,22 @@ impl Connection { } } + /// Attempts a graceful shutdown of the write side of a TLS connection. + /// + /// Unlike Self::poll_shutdown, no reponse from the peer is necessary. + /// If using TLS1.3, the connection can continue to be used for reading afterwards. + pub fn poll_shutdown_send(&mut self) -> Poll> { + if !self.remaining_blinding_delay()?.is_zero() { + return Poll::Pending; + } + let mut blocked = s2n_blocked_status::NOT_BLOCKED; + unsafe { + s2n_shutdown_send(self.connection.as_ptr(), &mut blocked) + .into_poll() + .map_ok(|_| self) + } + } + /// Returns the TLS alert code, if any pub fn alert(&self) -> Option { let alert = @@ -837,6 +869,44 @@ impl Connection { .map(|_| ()) } } + + /// Returns the validated peer certificate chain. + // 'static lifetime is because this copies the certificate chain from the connection into a new + // chain, so the lifetime is independent of the connection. + pub fn peer_cert_chain(&self) -> Result, Error> { + unsafe { + let mut chain = CertificateChain::new()?; + s2n_connection_get_peer_cert_chain( + self.connection.as_ptr(), + chain.as_mut_ptr().as_ptr(), + ) + .into_result() + .map(|_| ())?; + Ok(chain) + } + } + + /// Get the certificate used during the TLS handshake + /// + /// - If `self` is a server connection, the certificate selected will depend on the + /// ServerName sent by the client and supported ciphers. + /// - If `self` is a client connection, the certificate sent in response to a CertificateRequest + /// message is returned. Currently s2n-tls supports loading only one certificate in client mode. Note that + /// not all TLS endpoints will request a certificate. + pub fn selected_cert(&self) -> Option> { + unsafe { + // The API only returns null, no error is actually set. + // Clippy doesn't realize from_ptr_reference is unsafe. + #[allow(clippy::manual_map)] + if let Some(ptr) = + NonNull::new(s2n_connection_get_selected_cert(self.connection.as_ptr())) + { + Some(CertificateChain::from_ptr_reference(ptr)) + } else { + None + } + } + } } struct Context { @@ -962,4 +1032,11 @@ mod tests { fn assert_send() {} assert_send::(); } + + // ensure the connection context is sync + #[test] + fn context_sync_test() { + fn assert_sync() {} + assert_sync::(); + } } diff --git a/bindings/rust/s2n-tls/src/lib.rs b/bindings/rust/s2n-tls/src/lib.rs index b09c8fe5b30..78b4e81c572 100644 --- a/bindings/rust/s2n-tls/src/lib.rs +++ b/bindings/rust/s2n-tls/src/lib.rs @@ -14,6 +14,7 @@ static ALLOCATOR: checkers::Allocator = checkers::Allocator::system(); pub mod error; pub mod callbacks; +pub mod cert_chain; #[cfg(feature = "unstable-fingerprint")] pub mod client_hello; pub mod config; diff --git a/bindings/rust/s2n-tls/src/testing.rs b/bindings/rust/s2n-tls/src/testing.rs index 78e9d14dd8a..015ba9b6152 100644 --- a/bindings/rust/s2n-tls/src/testing.rs +++ b/bindings/rust/s2n-tls/src/testing.rs @@ -258,11 +258,7 @@ pub fn config_builder(cipher_prefs: &security::Policy) -> Result Result<(), Error> { + use crate::enums::ClientAuthType; + + let config = { + let mut config = config_builder(&security::DEFAULT_TLS13)?; + config.set_client_auth_type(ClientAuthType::Optional)?; + config.build()? + }; + + let server = { + let mut server = crate::connection::Connection::new_server(); + server.set_config(config.clone())?; + Harness::new(server) + }; + + let client = { + let mut client = crate::connection::Connection::new_client(); + client.set_config(config)?; + Harness::new(client) + }; + + let pair = Pair::new(server, client); + let pair = poll_tls_pair(pair); + let server = pair.server.0.connection; + let client = pair.client.0.connection; + + for conn in [server, client] { + let chain = conn.peer_cert_chain()?; + assert_eq!(chain.len(), 1); + for cert in chain.iter() { + let cert = cert?; + let cert = cert.der()?; + assert!(!cert.is_empty()); + } + } + + Ok(()) + } + + #[test] + fn selected_cert() -> Result<(), Error> { + use crate::enums::ClientAuthType; + + let config = { + let mut config = config_builder(&security::DEFAULT_TLS13)?; + config.set_client_auth_type(ClientAuthType::Required)?; + config.build()? + }; + + let server = { + let mut server = crate::connection::Connection::new_server(); + server.set_config(config.clone())?; + Harness::new(server) + }; + + let client = { + let mut client = crate::connection::Connection::new_client(); + client.set_config(config)?; + Harness::new(client) + }; + + // None before handshake... + assert!(server.connection.selected_cert().is_none()); + assert!(client.connection.selected_cert().is_none()); + + let pair = Pair::new(server, client); + + let pair = poll_tls_pair(pair); + let server = pair.server.0.connection; + let client = pair.client.0.connection; + + for conn in [&server, &client] { + let chain = conn.selected_cert().unwrap(); + assert_eq!(chain.len(), 1); + for cert in chain.iter() { + let cert = cert?; + let cert = cert.der()?; + assert!(!cert.is_empty()); + } + } + + // Same config is used for both and we are doing mTLS, so both should select the same + // certificate. + assert_eq!( + server + .selected_cert() + .unwrap() + .iter() + .next() + .unwrap()? + .der()?, + client + .selected_cert() + .unwrap() + .iter() + .next() + .unwrap()? + .der()? + ); + + Ok(()) + } } diff --git a/bindings/rust/scripts/detect-new-release b/bindings/rust/scripts/detect-new-release deleted file mode 100755 index 482f7ad5041..00000000000 --- a/bindings/rust/scripts/detect-new-release +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env bash - -# -# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -# SPDX-License-Identifier: Apache-2.0 -# - -set -e - -# cd into the script directory so it can be executed from anywhere -pushd "$(dirname "${BASH_SOURCE[0]}")" - -LOCAL_VERSION=$(cargo metadata --manifest-path ../Cargo.toml --no-deps --format-version 1 | jq --raw-output -c '.packages[] | select(.name == "s2n-tls").version') -CRATES_IO_VERSION=$(cargo search "s2n-tls" --limit 1 | head -n 1 | cut -d'"' -f2) - -# Exits with 0 if the local version has not been published to crates.io yet, otherwise exits with 1 -[[ "$LOCAL_VERSION" != "$CRATES_IO_VERSION" ]] diff --git a/cmake/modules/Findcrypto.cmake b/cmake/modules/Findcrypto.cmake index dac74350781..1ac4d9a619b 100644 --- a/cmake/modules/Findcrypto.cmake +++ b/cmake/modules/Findcrypto.cmake @@ -56,7 +56,7 @@ else() ) if (NOT crypto_LIBRARY) - if (BUILD_SHARED_LIBS) + if (BUILD_SHARED_LIBS OR S2N_USE_CRYPTO_SHARED_LIBS) if (crypto_SHARED_LIBRARY) set(crypto_LIBRARY ${crypto_SHARED_LIBRARY}) else() diff --git a/codebuild/bin/copyright_mistake_scanner.sh b/codebuild/bin/copyright_mistake_scanner.sh index 662d7a0236f..0d3e1b1688c 100755 --- a/codebuild/bin/copyright_mistake_scanner.sh +++ b/codebuild/bin/copyright_mistake_scanner.sh @@ -20,12 +20,14 @@ S2N_FILES+=" " S2N_FILES+=$(find "$PWD"/codebuild/ -type f -name "*.sh") S2N_FILES+=" " S2N_FILES+=$(find "$PWD"/tests/ -type f -name "*.sh") +S2N_FILES+=" " +S2N_FILES+=$(find "$PWD" -type f -name "*.rs" | grep -v target) FAILED=0 for file in $S2N_FILES; do - # The word "Copyright" should appear at least once in the first 3 lines of every file - COUNT=`head -3 $file | grep "Copyright" | wc -l`; + # The word "Copyright" should appear at least once in the first 4 lines of every file + COUNT=`head -4 $file | grep "Copyright" | wc -l`; if [ "$COUNT" == "0" ]; then FAILED=1; diff --git a/codebuild/bin/install_default_dependencies.sh b/codebuild/bin/install_default_dependencies.sh index 72f42593e82..02ed7b75a88 100755 --- a/codebuild/bin/install_default_dependencies.sh +++ b/codebuild/bin/install_default_dependencies.sh @@ -99,18 +99,6 @@ if [[ "$TESTS" == "integrationv2" || "$TESTS" == "ALL" ]]; then fi fi - if [[ ! -x "$OPENSSL_0_9_8_INSTALL_DIR/bin/openssl" ]]; then - # Download and Install Openssl 0.9.8 - mkdir -p "$OPENSSL_0_9_8_INSTALL_DIR"||true - codebuild/bin/install_openssl_0_9_8.sh "$(mktemp -d)" "$OPENSSL_0_9_8_INSTALL_DIR" "$OS_NAME" > /dev/null ; - fi - - if [[ ! -x "$GNUTLS_INSTALL_DIR/bin/gnutls-cli" ]]; then - # Download and Install GnuTLS for integration tests - mkdir -p "$GNUTLS_INSTALL_DIR"||true - codebuild/bin/install_gnutls.sh "$(mktemp -d)" "$GNUTLS_INSTALL_DIR" > /dev/null ; - fi - if [[ ! -x "$GNUTLS37_INSTALL_DIR/bin/gnutls-cli" ]]; then # Download and Install GnuTLS for integration tests mkdir -p "$GNUTLS37_INSTALL_DIR"||true diff --git a/codebuild/bin/install_gnutls.sh b/codebuild/bin/install_gnutls.sh deleted file mode 100755 index c7f0a8a820f..00000000000 --- a/codebuild/bin/install_gnutls.sh +++ /dev/null @@ -1,78 +0,0 @@ -#!/bin/bash -# -# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"). -# You may not use this file except in compliance with the License. -# A copy of the License is located at -# -# http://aws.amazon.com/apache2.0 -# -# or in the "license" file accompanying this file. This file is distributed -# on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either -# express or implied. See the License for the specific language governing -# permissions and limitations under the License. -# - -set -e -source codebuild/bin/s2n_setup_env.sh - -usage() { - echo "install_gnutls.sh build_dir install_dir os_name" - exit 1 -} - -if [ "$#" -ne "2" ]; then - usage -fi - -GNUTLS_BUILD_DIR=$1 -GNUTLS_INSTALL_DIR=$2 - -source codebuild/bin/jobs.sh - -# libgmp is needed for libnettle -case "$DISTRO" in - "ubuntu") - sudo apt-get -qq install libgmp3-dev -y - ;; - "amazon linux") - sudo yum install -y gmp-devel - ;; -"darwin" ) - # Installing an existing package is a "failure" in brew - brew install gmp || true - ;; -*) - echo "Invalid platform! $OS_NAME" - usage - ;; -esac - -cd "$GNUTLS_BUILD_DIR" - -# libnettle is a dependency of GnuTLS -# Originally from: https://ftp.gnu.org/gnu/nettle/nettle-3.3.tar.gz -curl --retry 3 https://s3-us-west-2.amazonaws.com/s2n-public-test-dependencies/2017-08-29_nettle-3.3.tar.gz --output nettle-3.3.tar.gz -tar -xzf nettle-3.3.tar.gz -cd nettle-3.3 -./configure --prefix="$GNUTLS_INSTALL_DIR"/nettle -make -j $JOBS -make -j $JOBS install -cd .. - -# Install GnuTLS -# Originally from: ftp://ftp.gnutls.org/gcrypt/gnutls/v3.5/gnutls-3.5.5.tar.xz -curl --retry 3 https://s3-us-west-2.amazonaws.com/s2n-public-test-dependencies/2017-08-29_gnutls-3.5.5.tar.xz --output gnutls-3.5.5.tar.xz -tar -xJf gnutls-3.5.5.tar.xz -cd gnutls-3.5.5 -./configure LD_FLAGS="-R$GNUTLS_INSTALL_DIR/nettle/lib -L$GNUTLS_INSTALL_DIR/nettle/lib -lnettle -lhogweed" \ - NETTLE_LIBS="-R$GNUTLS_INSTALL_DIR/nettle/lib -L$GNUTLS_INSTALL_DIR/nettle/lib -lnettle" \ - NETTLE_CFLAGS="-I$GNUTLS_INSTALL_DIR/nettle/include" \ - HOGWEED_LIBS="-R$GNUTLS_INSTALL_DIR/nettle/lib -L$GNUTLS_INSTALL_DIR/nettle/lib -lhogweed" \ - HOGWEED_CFLAGS="-I$GNUTLS_INSTALL_DIR/nettle/include" \ - --without-p11-kit \ - --with-included-libtasn1 \ - --prefix="$GNUTLS_INSTALL_DIR" -make -j $JOBS -make -j $JOBS install diff --git a/codebuild/bin/install_openssl_0_9_8.sh b/codebuild/bin/install_openssl_0_9_8.sh deleted file mode 100755 index 141b21bfad4..00000000000 --- a/codebuild/bin/install_openssl_0_9_8.sh +++ /dev/null @@ -1,55 +0,0 @@ -#!/bin/bash -# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"). -# You may not use this file except in compliance with the License. -# A copy of the License is located at -# -# http://aws.amazon.com/apache2.0 -# -# or in the "license" file accompanying this file. This file is distributed -# on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either -# express or implied. See the License for the specific language governing -# permissions and limitations under the License. -# - -set -ex -pushd "$(pwd)" - -usage() { - echo "install_openssl_0_9_8.sh build_dir install_dir os_name" - exit 1 -} - -if [ "$#" -ne "3" ]; then - usage -fi - -BUILD_DIR=$1 -INSTALL_DIR=$2 -PLATFORM=$3 - -cd "$BUILD_DIR" -wget https://www.openssl.org/source/old/0.9.x/openssl-0.9.8zh.tar.gz -tar xzvf openssl-0.9.8zh.tar.gz -cd openssl-0.9.8zh - -if [ "$PLATFORM" == "linux" ]; then - CONFIGURE="./config -d" -elif [ "$PLATFORM" == "osx" ]; then - CONFIGURE="./Configure darwin64-x86_64-cc" -else - echo "Invalid platform! $PLATFORM" - usage -fi - -$CONFIGURE --prefix="$INSTALL_DIR" - -make depend -make -j8 -make install - -popd - -exit 0 - diff --git a/codebuild/bin/s2n_codebuild.sh b/codebuild/bin/s2n_codebuild.sh index ab68fd6a9b8..c06d62b213b 100755 --- a/codebuild/bin/s2n_codebuild.sh +++ b/codebuild/bin/s2n_codebuild.sh @@ -49,7 +49,7 @@ if [[ "$OS_NAME" == "linux" && "$TESTS" == "valgrind" ]]; then # and will not produce any output while sleep 9m; do echo "=====[ $SECONDS seconds still running ]====="; done & - if [[ "$S2N_LIBCRYPTO" == "openssl-1.1.1" || "$S2N_LIBCRYPTO" == "awslc" ]]; then + if [[ "$S2N_LIBCRYPTO" == "openssl-1.1.1" ]]; then # https://github.com/aws/s2n-tls/issues/3758 # Run valgrind in pedantic mode (--errors-for-leak-kinds=all) echo "running task pedantic_valgrind" diff --git a/codebuild/bin/s2n_override_paths.sh b/codebuild/bin/s2n_override_paths.sh index 456a55666ef..7939dfa6c53 100755 --- a/codebuild/bin/s2n_override_paths.sh +++ b/codebuild/bin/s2n_override_paths.sh @@ -16,6 +16,6 @@ set -ex # Add all of our test dependencies to the PATH. Use Openssl 1.1.1 so the latest openssl is used for s_client # integration tests. -export PATH=$PYTHON_INSTALL_DIR/bin:$OPENSSL_1_1_1_INSTALL_DIR/bin:$GNUTLS_INSTALL_DIR/bin:$SAW_INSTALL_DIR/bin:$Z3_INSTALL_DIR/bin:$SCAN_BUILD_INSTALL_DIR/bin:$PRLIMIT_INSTALL_DIR/bin:$LATEST_CLANG_INSTALL_DIR/bin:`pwd`/codebuild/bin:~/.local/bin:$PATH +export PATH=$PYTHON_INSTALL_DIR/bin:$OPENSSL_1_1_1_INSTALL_DIR/bin:$SAW_INSTALL_DIR/bin:$Z3_INSTALL_DIR/bin:$SCAN_BUILD_INSTALL_DIR/bin:$PRLIMIT_INSTALL_DIR/bin:$LATEST_CLANG_INSTALL_DIR/bin:`pwd`/codebuild/bin:~/.local/bin:$PATH export LD_LIBRARY_PATH=$OPENSSL_1_1_1_INSTALL_DIR/lib:$LD_LIBRARY_PATH; -export DYLD_LIBRARY_PATH=$OPENSSL_1_1_1_INSTALL_DIR/lib:$LD_LIBRARY_PATH; \ No newline at end of file +export DYLD_LIBRARY_PATH=$OPENSSL_1_1_1_INSTALL_DIR/lib:$LD_LIBRARY_PATH; diff --git a/codebuild/bin/s2n_setup_env.sh b/codebuild/bin/s2n_setup_env.sh index c0d3593b326..9f78662db33 100755 --- a/codebuild/bin/s2n_setup_env.sh +++ b/codebuild/bin/s2n_setup_env.sh @@ -31,7 +31,6 @@ source codebuild/bin/s2n_set_build_preset.sh : "${BASE_S2N_DIR:=$(pwd)}" : "${TEST_DEPS_DIR:=$BASE_S2N_DIR/test-deps}" : "${PYTHON_INSTALL_DIR:=$TEST_DEPS_DIR/python}" -: "${GNUTLS_INSTALL_DIR:=$TEST_DEPS_DIR/gnutls}" : "${GNUTLS37_INSTALL_DIR:=$TEST_DEPS_DIR/gnutls37}" : "${PRLIMIT_INSTALL_DIR:=$TEST_DEPS_DIR/prlimit}" : "${SAW_INSTALL_DIR:=$TEST_DEPS_DIR/saw}" @@ -39,7 +38,6 @@ source codebuild/bin/s2n_set_build_preset.sh : "${LIBFUZZER_INSTALL_DIR:=$TEST_DEPS_DIR/libfuzzer}" : "${LATEST_CLANG_INSTALL_DIR:=$TEST_DEPS_DIR/clang}" : "${SCAN_BUILD_INSTALL_DIR:=$TEST_DEPS_DIR/scan-build}" -: "${OPENSSL_0_9_8_INSTALL_DIR:=$TEST_DEPS_DIR/openssl-0.9.8}" : "${OPENSSL_1_1_1_INSTALL_DIR:=$TEST_DEPS_DIR/openssl-1.1.1}" : "${OPENSSL_3_0_INSTALL_DIR:=$TEST_DEPS_DIR/openssl-3.0}" : "${OPENSSL_1_0_2_INSTALL_DIR:=$TEST_DEPS_DIR/openssl-1.0.2}" @@ -91,7 +89,6 @@ export TESTS export BASE_S2N_DIR export TEST_DEPS_DIR export PYTHON_INSTALL_DIR -export GNUTLS_INSTALL_DIR export GNUTLS37_INSTALL_DIR export PRLIMIT_INSTALL_DIR export SAW_INSTALL_DIR @@ -99,7 +96,6 @@ export Z3_INSTALL_DIR export LIBFUZZER_INSTALL_DIR export LATEST_CLANG_INSTALL_DIR export SCAN_BUILD_INSTALL_DIR -export OPENSSL_0_9_8_INSTALL_DIR export OPENSSL_1_1_1_INSTALL_DIR export OPENSSL_3_0_INSTALL_DIR export OPENSSL_1_0_2_INSTALL_DIR @@ -163,7 +159,6 @@ export LIBFUZZER_ROOT=$LIBFUZZER_INSTALL_DIR #check if the path contains test dep X, if not and X exists, add to path path_overrides="$PYTHON_INSTALL_DIR/bin $OPENSSL_1_1_1_INSTALL_DIR/bin -$GNUTLS_INSTALL_DIR/bin $SAW_INSTALL_DIR/bin $Z3_INSTALL_DIR/bin $SCAN_BUILD_INSTALL_DIR/bin diff --git a/crypto/s2n_certificate.c b/crypto/s2n_certificate.c index 71650a62638..77629baf9b4 100644 --- a/crypto/s2n_certificate.c +++ b/crypto/s2n_certificate.c @@ -358,6 +358,7 @@ int s2n_cert_chain_and_key_load(struct s2n_cert_chain_and_key *chain_and_key) DEFER_CLEANUP(X509 *leaf_cert = NULL, X509_free_pointer); POSIX_GUARD_RESULT(s2n_openssl_x509_parse(&head->raw, &leaf_cert)); + POSIX_GUARD_RESULT(s2n_openssl_x509_get_cert_info(leaf_cert, &head->info)); /* Parse the leaf cert for the public key and certificate type */ DEFER_CLEANUP(struct s2n_pkey public_key = { 0 }, s2n_pkey_free); @@ -375,12 +376,14 @@ int s2n_cert_chain_and_key_load(struct s2n_cert_chain_and_key *chain_and_key) /* Populate name information from the SAN/CN for the leaf certificate */ POSIX_GUARD(s2n_cert_chain_and_key_set_names(chain_and_key, leaf_cert)); - /* Populate ec curve libcrypto nid */ - if (pkey_type == S2N_PKEY_TYPE_ECDSA) { - int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(public_key.key.ecdsa_key.ec_key)); - POSIX_ENSURE(nid > 0, S2N_ERR_CERT_TYPE_UNSUPPORTED); - POSIX_ENSURE(nid < UINT16_MAX, S2N_ERR_CERT_TYPE_UNSUPPORTED); - head->ec_curve_nid = nid; + /* populate libcrypto nid's required for cert restrictions */ + struct s2n_cert *current = head->next; + while (current != NULL) { + DEFER_CLEANUP(X509 *parsed_cert = NULL, X509_free_pointer); + POSIX_GUARD_RESULT(s2n_openssl_x509_parse(¤t->raw, &parsed_cert)); + POSIX_GUARD_RESULT(s2n_openssl_x509_get_cert_info(parsed_cert, ¤t->info)); + + current = current->next; } return S2N_SUCCESS; diff --git a/crypto/s2n_certificate.h b/crypto/s2n_certificate.h index db4be5c2ae7..87217640f46 100644 --- a/crypto/s2n_certificate.h +++ b/crypto/s2n_certificate.h @@ -24,10 +24,22 @@ #define S2N_CERT_TYPE_COUNT S2N_PKEY_TYPE_SENTINEL +struct s2n_cert_info { + int signature_nid; + /* This field is not populated for RSA_PSS signatures */ + int signature_digest_nid; + /* For EC certs this field is the curve (e.g. NID_secp521r1) and not the generic + * EC key NID (NID_X9_62_id_ecPublicKey) + */ + int public_key_nid; + int public_key_bits; + bool self_signed; +}; + struct s2n_cert { s2n_pkey_type pkey_type; - uint16_t ec_curve_nid; s2n_cert_public_key public_key; + struct s2n_cert_info info; struct s2n_blob raw; struct s2n_cert *next; }; diff --git a/crypto/s2n_dhe.c b/crypto/s2n_dhe.c index da8f845e3ba..d2da1da1125 100644 --- a/crypto/s2n_dhe.c +++ b/crypto/s2n_dhe.c @@ -34,7 +34,7 @@ */ static const BIGNUM *s2n_get_Ys_dh_param(struct s2n_dh_params *dh_params) { - const BIGNUM *Ys; + const BIGNUM *Ys = NULL; /* DH made opaque in Openssl 1.1.0 */ #if S2N_OPENSSL_VERSION_AT_LEAST(1, 1, 0) @@ -48,7 +48,7 @@ static const BIGNUM *s2n_get_Ys_dh_param(struct s2n_dh_params *dh_params) static const BIGNUM *s2n_get_p_dh_param(struct s2n_dh_params *dh_params) { - const BIGNUM *p; + const BIGNUM *p = NULL; #if S2N_OPENSSL_VERSION_AT_LEAST(1, 1, 0) DH_get0_pqg(dh_params->dh, &p, NULL, NULL); #else @@ -60,7 +60,7 @@ static const BIGNUM *s2n_get_p_dh_param(struct s2n_dh_params *dh_params) static const BIGNUM *s2n_get_g_dh_param(struct s2n_dh_params *dh_params) { - const BIGNUM *g; + const BIGNUM *g = NULL; #if S2N_OPENSSL_VERSION_AT_LEAST(1, 1, 0) DH_get0_pqg(dh_params->dh, NULL, NULL, &g); #else diff --git a/crypto/s2n_ecc_evp.c b/crypto/s2n_ecc_evp.c index c101b96242a..80c9b637986 100644 --- a/crypto/s2n_ecc_evp.c +++ b/crypto/s2n_ecc_evp.c @@ -23,6 +23,8 @@ #include +#include "crypto/s2n_fips.h" +#include "crypto/s2n_libcrypto.h" #include "tls/s2n_connection.h" #include "tls/s2n_ecc_preferences.h" #include "tls/s2n_tls_parameters.h" @@ -118,6 +120,15 @@ int s2n_is_evp_apis_supported() return EVP_APIS_SUPPORTED; } +bool s2n_ecc_evp_supports_fips_check() +{ +#ifdef S2N_LIBCRYPTO_SUPPORTS_EC_KEY_CHECK_FIPS + return true; +#else + return false; +#endif +} + #if EVP_APIS_SUPPORTED static int s2n_ecc_evp_generate_key_x25519(const struct s2n_ecc_named_curve *named_curve, EVP_PKEY **evp_pkey) { @@ -163,27 +174,50 @@ static int s2n_ecc_evp_generate_own_key(const struct s2n_ecc_named_curve *named_ return named_curve->generate_key(named_curve, evp_pkey); } +static S2N_RESULT s2n_ecc_check_key(EC_KEY *ec_key) +{ + RESULT_ENSURE_REF(ec_key); + +#ifdef S2N_LIBCRYPTO_SUPPORTS_EC_KEY_CHECK_FIPS + if (s2n_is_in_fips_mode()) { + RESULT_GUARD_OSSL(EC_KEY_check_fips(ec_key), S2N_ERR_ECDHE_INVALID_PUBLIC_KEY_FIPS); + return S2N_RESULT_OK; + } +#endif + + RESULT_GUARD_OSSL(EC_KEY_check_key(ec_key), S2N_ERR_ECDHE_INVALID_PUBLIC_KEY); + + return S2N_RESULT_OK; +} + static int s2n_ecc_evp_compute_shared_secret(EVP_PKEY *own_key, EVP_PKEY *peer_public, uint16_t iana_id, struct s2n_blob *shared_secret) { POSIX_ENSURE_REF(peer_public); POSIX_ENSURE_REF(own_key); - /* From RFC 8446(TLS1.3) Section 4.2.8.2: For the curves secp256r1, secp384r1, and secp521r1, peers MUST validate - * each other's public value Q by ensuring that the point is a valid point on the elliptic curve. - * For the curve x25519 and x448 the peer public-key validation check doesn't apply. - * From RFC 8422(TLS1.2) Section 5.11: With the NIST curves, each party MUST validate the public key sent by its peer - * in the ClientKeyExchange and ServerKeyExchange messages. A receiving party MUST check that the x and y parameters from - * the peer's public value satisfy the curve equation, y^2 = x^3 + ax + b mod p. - * Note that the `EC_KEY_check_key` validation is a MUST for only NIST curves, if a non-NIST curve is added to s2n-tls - * this is an additional validation step that increases security but decreases performance. + /** + *= https://tools.ietf.org/rfc/rfc8446#section-4.2.8.2 + *# For the curves secp256r1, secp384r1, and secp521r1, peers MUST + *# validate each other's public value Q by ensuring that the point is a + *# valid point on the elliptic curve. + * + *= https://tools.ietf.org/rfc/rfc8422#section-5.11 + *# With the NIST curves, each party MUST validate the public key sent by + *# its peer in the ClientKeyExchange and ServerKeyExchange messages. A + *# receiving party MUST check that the x and y parameters from the + *# peer's public value satisfy the curve equation, y^2 = x^3 + ax + b + *# mod p. + * + * The validation requirement for the public key value only applies to NIST curves. The + * validation is skipped with non-NIST curves for increased performance. */ if (iana_id != TLS_EC_CURVE_ECDH_X25519 && iana_id != TLS_EC_CURVE_ECDH_X448) { DEFER_CLEANUP(EC_KEY *ec_key = EVP_PKEY_get1_EC_KEY(peer_public), EC_KEY_free_pointer); - S2N_ERROR_IF(ec_key == NULL, S2N_ERR_ECDHE_UNSUPPORTED_CURVE); - POSIX_GUARD_OSSL(EC_KEY_check_key(ec_key), S2N_ERR_ECDHE_SHARED_SECRET); + POSIX_ENSURE(ec_key, S2N_ERR_ECDHE_UNSUPPORTED_CURVE); + POSIX_GUARD_RESULT(s2n_ecc_check_key(ec_key)); } - size_t shared_secret_size; + size_t shared_secret_size = 0; DEFER_CLEANUP(EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(own_key, NULL), EVP_PKEY_CTX_free_pointer); S2N_ERROR_IF(ctx == NULL, S2N_ERR_ECDHE_SHARED_SECRET); @@ -233,7 +267,7 @@ int s2n_ecc_evp_compute_shared_secret_as_server(struct s2n_ecc_evp_params *ecc_e POSIX_ENSURE_REF(ecc_evp_params->evp_pkey); POSIX_ENSURE_REF(Yc_in); - uint8_t client_public_len; + uint8_t client_public_len = 0; struct s2n_blob client_public_blob = { 0 }; DEFER_CLEANUP(EVP_PKEY *peer_key = EVP_PKEY_new(), EVP_PKEY_free_pointer); @@ -345,8 +379,8 @@ int s2n_ecc_evp_read_params(struct s2n_stuffer *in, struct s2n_blob *data_to_ver struct s2n_ecdhe_raw_server_params *raw_server_ecc_params) { POSIX_ENSURE_REF(in); - uint8_t curve_type; - uint8_t point_length; + uint8_t curve_type = 0; + uint8_t point_length = 0; /* Remember where we started reading the data */ data_to_verify->data = s2n_stuffer_raw_read(in, 0); @@ -507,7 +541,7 @@ int s2n_ecc_evp_find_supported_curve(struct s2n_connection *conn, struct s2n_blo for (size_t i = 0; i < ecc_prefs->count; i++) { const struct s2n_ecc_named_curve *supported_curve = ecc_prefs->ecc_curves[i]; for (uint32_t j = 0; j < iana_ids->size / 2; j++) { - uint16_t iana_id; + uint16_t iana_id = 0; POSIX_GUARD(s2n_stuffer_read_uint16(&iana_ids_in, &iana_id)); if (supported_curve->iana_id == iana_id) { *found = supported_curve; diff --git a/crypto/s2n_ecc_evp.h b/crypto/s2n_ecc_evp.h index cd76417770f..6cc38f10cc4 100644 --- a/crypto/s2n_ecc_evp.h +++ b/crypto/s2n_ecc_evp.h @@ -85,3 +85,4 @@ int s2n_ecc_evp_parse_params(struct s2n_connection *conn, int s2n_ecc_evp_find_supported_curve(struct s2n_connection *conn, struct s2n_blob *iana_ids, const struct s2n_ecc_named_curve **found); int s2n_ecc_evp_params_free(struct s2n_ecc_evp_params *ecc_evp_params); int s2n_is_evp_apis_supported(); +bool s2n_ecc_evp_supports_fips_check(); diff --git a/crypto/s2n_ecdsa.c b/crypto/s2n_ecdsa.c index 5ab9a45f721..36558f75345 100644 --- a/crypto/s2n_ecdsa.c +++ b/crypto/s2n_ecdsa.c @@ -118,7 +118,7 @@ static int s2n_ecdsa_verify(const struct s2n_pkey *pub, s2n_signature_algorithm const s2n_ecdsa_public_key *key = &pub->key.ecdsa_key; POSIX_ENSURE_REF(key->ec_key); - uint8_t digest_length; + uint8_t digest_length = 0; POSIX_GUARD(s2n_hash_digest_size(digest->alg, &digest_length)); POSIX_ENSURE_LTE(digest_length, S2N_MAX_DIGEST_LEN); diff --git a/crypto/s2n_fips.c b/crypto/s2n_fips.c index 29229dd607d..ff73433a6ce 100644 --- a/crypto/s2n_fips.c +++ b/crypto/s2n_fips.c @@ -17,11 +17,14 @@ #include +#include "utils/s2n_init.h" +#include "utils/s2n_safety.h" + #if defined(S2N_INTERN_LIBCRYPTO) && defined(OPENSSL_FIPS) #error "Interning with OpenSSL fips-validated libcrypto is not currently supported. See https://github.com/aws/s2n-tls/issues/2741" #endif -static int s2n_fips_mode = 0; +static bool s2n_fips_mode_enabled = false; /* FIPS mode can be checked if OpenSSL was configured and built for FIPS which then defines OPENSSL_FIPS. * @@ -46,17 +49,25 @@ bool s2n_libcrypto_is_fips(void) int s2n_fips_init(void) { - s2n_fips_mode = 0; - - if (s2n_libcrypto_is_fips()) { - s2n_fips_mode = 1; - } - - return 0; + s2n_fips_mode_enabled = s2n_libcrypto_is_fips(); + return S2N_SUCCESS; } /* Return 1 if FIPS mode is enabled, 0 otherwise. FIPS mode must be enabled prior to calling s2n_init(). */ -int s2n_is_in_fips_mode(void) +bool s2n_is_in_fips_mode(void) +{ + return s2n_fips_mode_enabled; +} + +int s2n_get_fips_mode(s2n_fips_mode *fips_mode) { - return s2n_fips_mode; + POSIX_ENSURE_REF(fips_mode); + *fips_mode = S2N_FIPS_MODE_DISABLED; + POSIX_ENSURE(s2n_is_initialized(), S2N_ERR_NOT_INITIALIZED); + + if (s2n_is_in_fips_mode()) { + *fips_mode = S2N_FIPS_MODE_ENABLED; + } + + return S2N_SUCCESS; } diff --git a/crypto/s2n_fips.h b/crypto/s2n_fips.h index f1047d52ae6..a353589199d 100644 --- a/crypto/s2n_fips.h +++ b/crypto/s2n_fips.h @@ -21,7 +21,7 @@ #pragma once int s2n_fips_init(void); -int s2n_is_in_fips_mode(void); +bool s2n_is_in_fips_mode(void); bool s2n_libcrypto_is_fips(void); struct s2n_cipher_suite; diff --git a/crypto/s2n_hash.c b/crypto/s2n_hash.c index e42a1091d8a..f249cd63088 100644 --- a/crypto/s2n_hash.c +++ b/crypto/s2n_hash.c @@ -621,7 +621,7 @@ int s2n_hash_const_time_get_currently_in_hash_block(struct s2n_hash_state *state POSIX_PRECONDITION(s2n_hash_state_validate(state)); POSIX_ENSURE(S2N_MEM_IS_WRITABLE_CHECK(out, sizeof(*out)), S2N_ERR_PRECONDITION_VIOLATION); POSIX_ENSURE(state->is_ready_for_input, S2N_ERR_HASH_NOT_READY); - uint64_t hash_block_size; + uint64_t hash_block_size = 0; POSIX_GUARD(s2n_hash_block_size(state->alg, &hash_block_size)); /* Requires that hash_block_size is a power of 2. This is true for all hashes we currently support diff --git a/crypto/s2n_hkdf.c b/crypto/s2n_hkdf.c index c5cb1874fd6..7f8af07e6fe 100644 --- a/crypto/s2n_hkdf.c +++ b/crypto/s2n_hkdf.c @@ -76,7 +76,7 @@ static int s2n_custom_hkdf_expand(struct s2n_hmac_state *hmac, s2n_hmac_algorith POSIX_ENSURE(total_rounds <= MAX_HKDF_ROUNDS, S2N_ERR_HKDF_OUTPUT_SIZE); for (uint32_t curr_round = 1; curr_round <= total_rounds; curr_round++) { - uint32_t cat_len; + uint32_t cat_len = 0; POSIX_GUARD(s2n_hmac_init(hmac, alg, pseudo_rand_key->data, pseudo_rand_key->size)); if (curr_round != 1) { POSIX_GUARD(s2n_hmac_update(hmac, prev, hash_len)); diff --git a/crypto/s2n_hmac.c b/crypto/s2n_hmac.c index 1a1b1f270c3..96466708194 100644 --- a/crypto/s2n_hmac.c +++ b/crypto/s2n_hmac.c @@ -332,7 +332,7 @@ int s2n_hmac_reset(struct s2n_hmac_state *state) POSIX_ENSURE(state->hash_block_size != 0, S2N_ERR_PRECONDITION_VIOLATION); POSIX_GUARD(s2n_hash_copy(&state->inner, &state->inner_just_key)); - uint64_t bytes_in_hash; + uint64_t bytes_in_hash = 0; POSIX_GUARD(s2n_hash_get_currently_in_hash_total(&state->inner, &bytes_in_hash)); bytes_in_hash %= state->hash_block_size; POSIX_ENSURE(bytes_in_hash <= UINT32_MAX, S2N_ERR_INTEGER_OVERFLOW); diff --git a/crypto/s2n_openssl_x509.c b/crypto/s2n_openssl_x509.c index 81eb04c6ef5..bcc3bbe02d1 100644 --- a/crypto/s2n_openssl_x509.c +++ b/crypto/s2n_openssl_x509.c @@ -17,6 +17,9 @@ #include "api/s2n.h" +DEFINE_POINTER_CLEANUP_FUNC(EVP_PKEY *, EVP_PKEY_free); +DEFINE_POINTER_CLEANUP_FUNC(EC_KEY *, EC_KEY_free); + S2N_CLEANUP_RESULT s2n_openssl_x509_stack_pop_free(STACK_OF(X509) **cert_chain) { RESULT_ENSURE_REF(*cert_chain); @@ -83,3 +86,53 @@ S2N_RESULT s2n_openssl_x509_parse(struct s2n_blob *asn1der, X509 **cert_out) return S2N_RESULT_OK; } + +S2N_RESULT s2n_openssl_x509_get_cert_info(X509 *cert, struct s2n_cert_info *info) +{ + RESULT_ENSURE_REF(cert); + RESULT_ENSURE_REF(info); + + X509_NAME *issuer_name = X509_get_issuer_name(cert); + RESULT_ENSURE_REF(issuer_name); + + X509_NAME *subject_name = X509_get_subject_name(cert); + RESULT_ENSURE_REF(subject_name); + + if (X509_NAME_cmp(issuer_name, subject_name) == 0) { + info->self_signed = true; + } else { + info->self_signed = false; + } + +#if defined(LIBRESSL_VERSION_NUMBER) && (LIBRESSL_VERSION_NUMBER < 0x02070000f) + RESULT_ENSURE_REF(cert->sig_alg); + info->signature_nid = OBJ_obj2nid(cert->sig_alg->algorithm); +#else + info->signature_nid = X509_get_signature_nid(cert); +#endif + /* These is no method to directly retrieve that signature digest from the X509* + * that is available in all libcryptos, so instead we use find_sigid_algs. For + * a signature NID_ecdsa_with_SHA256 this will return NID_SHA256 + */ + RESULT_GUARD_OSSL(OBJ_find_sigid_algs(info->signature_nid, &info->signature_digest_nid, NULL), + S2N_ERR_CERT_TYPE_UNSUPPORTED); + + DEFER_CLEANUP(EVP_PKEY *pubkey = X509_get_pubkey(cert), EVP_PKEY_free_pointer); + RESULT_ENSURE(pubkey != NULL, S2N_ERR_DECODE_CERTIFICATE); + + info->public_key_bits = EVP_PKEY_bits(pubkey); + RESULT_ENSURE(info->public_key_bits > 0, S2N_ERR_CERT_TYPE_UNSUPPORTED); + + if (EVP_PKEY_base_id(pubkey) == EVP_PKEY_EC) { + DEFER_CLEANUP(EC_KEY *ec_key = EVP_PKEY_get1_EC_KEY(pubkey), EC_KEY_free_pointer); + RESULT_ENSURE_REF(ec_key); + const EC_GROUP *ec_group = EC_KEY_get0_group(ec_key); + RESULT_ENSURE_REF(ec_group); + info->public_key_nid = EC_GROUP_get_curve_name(ec_group); + } else { + info->public_key_nid = EVP_PKEY_id(pubkey); + } + RESULT_ENSURE(info->public_key_nid != NID_undef, S2N_ERR_CERT_TYPE_UNSUPPORTED); + + return S2N_RESULT_OK; +} diff --git a/crypto/s2n_openssl_x509.h b/crypto/s2n_openssl_x509.h index 33b78453277..ce77634ee3e 100644 --- a/crypto/s2n_openssl_x509.h +++ b/crypto/s2n_openssl_x509.h @@ -19,6 +19,7 @@ #include #include +#include "crypto/s2n_certificate.h" #include "utils/s2n_blob.h" #include "utils/s2n_safety.h" @@ -44,3 +45,5 @@ S2N_RESULT s2n_openssl_x509_parse(struct s2n_blob *asn1der, X509 **cert_out); * compatability with previous permissive parsing behavior. */ S2N_RESULT s2n_openssl_x509_parse_without_length_validation(struct s2n_blob *asn1der, X509 **cert_out); + +S2N_RESULT s2n_openssl_x509_get_cert_info(X509 *cert, struct s2n_cert_info *info); diff --git a/crypto/s2n_pkey.c b/crypto/s2n_pkey.c index 190c73e303a..bcc57c42422 100644 --- a/crypto/s2n_pkey.c +++ b/crypto/s2n_pkey.c @@ -115,7 +115,11 @@ int s2n_pkey_match(const struct s2n_pkey *pub_key, const struct s2n_pkey *priv_k int s2n_pkey_free(struct s2n_pkey *key) { - if (key != NULL && key->free != NULL) { + if (key == NULL) { + return S2N_SUCCESS; + } + + if (key->free != NULL) { POSIX_GUARD(key->free(key)); } diff --git a/crypto/s2n_rsa_signing.c b/crypto/s2n_rsa_signing.c index 25096a3e1ac..9bec1616c13 100644 --- a/crypto/s2n_rsa_signing.c +++ b/crypto/s2n_rsa_signing.c @@ -96,8 +96,8 @@ int s2n_rsa_pkcs1v15_sign(const struct s2n_pkey *priv, struct s2n_hash_state *di int s2n_rsa_pkcs1v15_verify(const struct s2n_pkey *pub, struct s2n_hash_state *digest, struct s2n_blob *signature) { - uint8_t digest_length; - int digest_NID_type; + uint8_t digest_length = 0; + int digest_NID_type = 0; POSIX_GUARD(s2n_hash_digest_size(digest->alg, &digest_length)); POSIX_GUARD(s2n_hash_NID_type(digest->alg, &digest_NID_type)); POSIX_ENSURE_LTE(digest_length, S2N_MAX_DIGEST_LEN); @@ -186,7 +186,7 @@ int s2n_rsa_pss_verify(const struct s2n_pkey *pub, struct s2n_hash_state *digest { POSIX_ENSURE_REF(pub); - uint8_t digest_length; + uint8_t digest_length = 0; uint8_t digest_data[S2N_MAX_DIGEST_LEN]; POSIX_GUARD(s2n_hash_digest_size(digest->alg, &digest_length)); POSIX_GUARD(s2n_hash_digest(digest, digest_data, digest_length)); diff --git a/error/s2n_errno.c b/error/s2n_errno.c index eee14d72825..7b770681758 100644 --- a/error/s2n_errno.c +++ b/error/s2n_errno.c @@ -88,6 +88,8 @@ static const char *no_such_error = "Internal s2n error"; ERR_ENTRY(S2N_ERR_ECDHE_GEN_KEY, "Failed to generate an ECDHE key") \ ERR_ENTRY(S2N_ERR_ECDHE_SHARED_SECRET, "Error computing ECDHE shared secret") \ ERR_ENTRY(S2N_ERR_ECDHE_UNSUPPORTED_CURVE, "Unsupported EC curve was presented during an ECDHE handshake") \ + ERR_ENTRY(S2N_ERR_ECDHE_INVALID_PUBLIC_KEY, "Failed to validate the peer's point on the elliptic curve") \ + ERR_ENTRY(S2N_ERR_ECDHE_INVALID_PUBLIC_KEY_FIPS, "Failed to validate the peer's point on the elliptic curve, per FIPS requirements") \ ERR_ENTRY(S2N_ERR_ECDSA_UNSUPPORTED_CURVE, "Unsupported EC curve was presented during an ECDSA SignatureScheme handshake") \ ERR_ENTRY(S2N_ERR_ECDHE_SERIALIZING, "Error serializing ECDHE public") \ ERR_ENTRY(S2N_ERR_KEM_UNSUPPORTED_PARAMS, "Unsupported KEM params was presented during a handshake that uses a KEM") \ @@ -103,6 +105,7 @@ static const char *no_such_error = "Internal s2n error"; ERR_ENTRY(S2N_ERR_CERT_INVALID, "Certificate is invalid") \ ERR_ENTRY(S2N_ERR_CERT_MAX_CHAIN_DEPTH_EXCEEDED, "The maximum certificate chain depth has been exceeded") \ ERR_ENTRY(S2N_ERR_CERT_REJECTED, "Certificate failed custom application validation") \ + ERR_ENTRY(S2N_ERR_SECURITY_POLICY_INCOMPATIBLE_CERT, "Incompatibility found between loaded certificates and chosen security policy") \ ERR_ENTRY(S2N_ERR_CRL_LOOKUP_FAILED, "No CRL could be found for the corresponding certificate") \ ERR_ENTRY(S2N_ERR_CRL_SIGNATURE, "The signature of the CRL is invalid") \ ERR_ENTRY(S2N_ERR_CRL_ISSUER, "Unable to get the CRL issuer certificate") \ diff --git a/error/s2n_errno.h b/error/s2n_errno.h index cb883d3e46f..fa16387839d 100644 --- a/error/s2n_errno.h +++ b/error/s2n_errno.h @@ -103,6 +103,8 @@ typedef enum { S2N_ERR_ECDHE_GEN_KEY, S2N_ERR_ECDHE_SHARED_SECRET, S2N_ERR_ECDHE_UNSUPPORTED_CURVE, + S2N_ERR_ECDHE_INVALID_PUBLIC_KEY, + S2N_ERR_ECDHE_INVALID_PUBLIC_KEY_FIPS, S2N_ERR_ECDSA_UNSUPPORTED_CURVE, S2N_ERR_ECDHE_SERIALIZING, S2N_ERR_KEM_UNSUPPORTED_PARAMS, @@ -322,6 +324,7 @@ typedef enum { S2N_ERR_KTLS_RENEG, S2N_ERR_ATOMIC, S2N_ERR_KTLS_KEY_LIMIT, + S2N_ERR_SECURITY_POLICY_INCOMPATIBLE_CERT, S2N_ERR_T_USAGE_END, } s2n_error; diff --git a/nix/openssl_0_9_8.nix b/nix/openssl_0_9_8.nix deleted file mode 100644 index d9869f3bd83..00000000000 --- a/nix/openssl_0_9_8.nix +++ /dev/null @@ -1,27 +0,0 @@ -# Present as a historical record. -# Only needed if https://github.com/aws/s2n-tls/issues/3810 is resolved. -{ pkgs }: -pkgs.stdenv.mkDerivation rec { - pname = "openssl"; - version = "0.9.8"; - - src = fetchTarball { - url = "https://www.openssl.org/source/old/0.9.x/openssl-0.9.8zh.tar.gz"; - sha256 = "sha256:0h451dgk2pws957cjidjhwb2qlr0qx73klzb0n0l3x601jmw27ih"; - }; - - buildInputs = [ pkgs.gnumake pkgs.perl534 ]; - - configurePhase = '' - ./config --prefix=$out - ''; - - buildPhase = '' - make depend -j $(nproc) - make -j $(nproc) - ''; - - installPhase = '' - make install - ''; -} diff --git a/scripts/s2n_safety_macros.py b/scripts/s2n_safety_macros.py index fbd5a5d977b..9ca973eeca8 100644 --- a/scripts/s2n_safety_macros.py +++ b/scripts/s2n_safety_macros.py @@ -539,7 +539,7 @@ def cmp_check(op): * The size of the data pointed to by both the `destination` and `source` parameters, shall be at least `len` bytes. ''', - impl='__S2N_ENSURE_SAFE_MEMCPY((destination), (source), (len), {prefix}ENSURE_REF)', + impl='__S2N_ENSURE_SAFE_MEMMOVE((destination), (source), (len), {prefix}ENSURE_REF)', harness=''' static {ret} {prefix}CHECKED_MEMCPY_harness(uint32_t* dest, uint32_t* source, size_t len) {{ diff --git a/stuffer/s2n_stuffer.c b/stuffer/s2n_stuffer.c index 32a9acb9299..6e6814cd54a 100644 --- a/stuffer/s2n_stuffer.c +++ b/stuffer/s2n_stuffer.c @@ -432,3 +432,15 @@ int s2n_stuffer_extract_blob(struct s2n_stuffer *stuffer, struct s2n_blob *out) POSIX_POSTCONDITION(s2n_blob_validate(out)); return S2N_SUCCESS; } + +int s2n_stuffer_shift(struct s2n_stuffer *stuffer) +{ + POSIX_ENSURE_REF(stuffer); + struct s2n_stuffer copy = *stuffer; + POSIX_GUARD(s2n_stuffer_rewrite(©)); + uint8_t *data = stuffer->blob.data + stuffer->read_cursor; + uint32_t data_size = s2n_stuffer_data_available(stuffer); + POSIX_GUARD(s2n_stuffer_write_bytes(©, data, data_size)); + *stuffer = copy; + return S2N_SUCCESS; +} diff --git a/stuffer/s2n_stuffer.h b/stuffer/s2n_stuffer.h index 0e8950c2ed0..33acc471f0d 100644 --- a/stuffer/s2n_stuffer.h +++ b/stuffer/s2n_stuffer.h @@ -65,10 +65,10 @@ struct s2n_stuffer { S2N_RESULT s2n_stuffer_validate(const struct s2n_stuffer *stuffer); /* Initialize and destroying stuffers */ -int s2n_stuffer_init(struct s2n_stuffer *stuffer, struct s2n_blob *in); -int s2n_stuffer_init_written(struct s2n_stuffer *stuffer, struct s2n_blob *in); -int s2n_stuffer_alloc(struct s2n_stuffer *stuffer, const uint32_t size); -int s2n_stuffer_growable_alloc(struct s2n_stuffer *stuffer, const uint32_t size); +int S2N_RESULT_MUST_USE s2n_stuffer_init(struct s2n_stuffer *stuffer, struct s2n_blob *in); +int S2N_RESULT_MUST_USE s2n_stuffer_init_written(struct s2n_stuffer *stuffer, struct s2n_blob *in); +int S2N_RESULT_MUST_USE s2n_stuffer_alloc(struct s2n_stuffer *stuffer, const uint32_t size); +int S2N_RESULT_MUST_USE s2n_stuffer_growable_alloc(struct s2n_stuffer *stuffer, const uint32_t size); int s2n_stuffer_free(struct s2n_stuffer *stuffer); /** * Frees the stuffer without zeroizing the contained data. @@ -76,30 +76,31 @@ int s2n_stuffer_free(struct s2n_stuffer *stuffer); * This should only be used in scenarios where the data is encrypted or has been * cleared with `s2n_stuffer_erase_and_read`. In most cases, prefer `s2n_stuffer_free`. */ -int s2n_stuffer_free_without_wipe(struct s2n_stuffer *stuffer); -int s2n_stuffer_resize(struct s2n_stuffer *stuffer, const uint32_t size); -int s2n_stuffer_resize_if_empty(struct s2n_stuffer *stuffer, const uint32_t size); -int s2n_stuffer_rewind_read(struct s2n_stuffer *stuffer, const uint32_t size); -int s2n_stuffer_reread(struct s2n_stuffer *stuffer); -int s2n_stuffer_rewrite(struct s2n_stuffer *stuffer); +int S2N_RESULT_MUST_USE s2n_stuffer_free_without_wipe(struct s2n_stuffer *stuffer); +int S2N_RESULT_MUST_USE s2n_stuffer_resize(struct s2n_stuffer *stuffer, const uint32_t size); +int S2N_RESULT_MUST_USE s2n_stuffer_resize_if_empty(struct s2n_stuffer *stuffer, const uint32_t size); +int S2N_RESULT_MUST_USE s2n_stuffer_rewind_read(struct s2n_stuffer *stuffer, const uint32_t size); +int S2N_RESULT_MUST_USE s2n_stuffer_reread(struct s2n_stuffer *stuffer); +int S2N_RESULT_MUST_USE s2n_stuffer_rewrite(struct s2n_stuffer *stuffer); +int S2N_RESULT_MUST_USE s2n_stuffer_shift(struct s2n_stuffer *stuffer); int s2n_stuffer_wipe(struct s2n_stuffer *stuffer); int s2n_stuffer_wipe_n(struct s2n_stuffer *stuffer, const uint32_t n); bool s2n_stuffer_is_consumed(struct s2n_stuffer *stuffer); /* Basic read and write */ -int s2n_stuffer_read(struct s2n_stuffer *stuffer, struct s2n_blob *out); -int s2n_stuffer_erase_and_read(struct s2n_stuffer *stuffer, struct s2n_blob *out); -int s2n_stuffer_write(struct s2n_stuffer *stuffer, const struct s2n_blob *in); -int s2n_stuffer_read_bytes(struct s2n_stuffer *stuffer, uint8_t *out, uint32_t n); -int s2n_stuffer_erase_and_read_bytes(struct s2n_stuffer *stuffer, uint8_t *data, uint32_t size); -int s2n_stuffer_write_bytes(struct s2n_stuffer *stuffer, const uint8_t *in, const uint32_t n); -int s2n_stuffer_writev_bytes(struct s2n_stuffer *stuffer, const struct iovec *iov, size_t iov_count, +int S2N_RESULT_MUST_USE s2n_stuffer_read(struct s2n_stuffer *stuffer, struct s2n_blob *out); +int S2N_RESULT_MUST_USE s2n_stuffer_erase_and_read(struct s2n_stuffer *stuffer, struct s2n_blob *out); +int S2N_RESULT_MUST_USE s2n_stuffer_write(struct s2n_stuffer *stuffer, const struct s2n_blob *in); +int S2N_RESULT_MUST_USE s2n_stuffer_read_bytes(struct s2n_stuffer *stuffer, uint8_t *out, uint32_t n); +int S2N_RESULT_MUST_USE s2n_stuffer_erase_and_read_bytes(struct s2n_stuffer *stuffer, uint8_t *data, uint32_t size); +int S2N_RESULT_MUST_USE s2n_stuffer_write_bytes(struct s2n_stuffer *stuffer, const uint8_t *in, const uint32_t n); +int S2N_RESULT_MUST_USE s2n_stuffer_writev_bytes(struct s2n_stuffer *stuffer, const struct iovec *iov, size_t iov_count, uint32_t offs, uint32_t size); -int s2n_stuffer_skip_read(struct s2n_stuffer *stuffer, uint32_t n); -int s2n_stuffer_skip_write(struct s2n_stuffer *stuffer, const uint32_t n); +int S2N_RESULT_MUST_USE s2n_stuffer_skip_read(struct s2n_stuffer *stuffer, uint32_t n); +int S2N_RESULT_MUST_USE s2n_stuffer_skip_write(struct s2n_stuffer *stuffer, const uint32_t n); /* Tries to reserve enough space to write n additional bytes into the stuffer.*/ -int s2n_stuffer_reserve_space(struct s2n_stuffer *stuffer, uint32_t n); +int S2N_RESULT_MUST_USE s2n_stuffer_reserve_space(struct s2n_stuffer *stuffer, uint32_t n); /* Raw read/write move the cursor along and give you a pointer you can * read/write data_len bytes from/to in-place. @@ -113,17 +114,17 @@ int s2n_stuffer_recv_from_fd(struct s2n_stuffer *stuffer, const int rfd, const u int s2n_stuffer_send_to_fd(struct s2n_stuffer *stuffer, const int wfd, const uint32_t len, uint32_t *bytes_sent); /* Read and write integers in network order */ -int s2n_stuffer_read_uint8(struct s2n_stuffer *stuffer, uint8_t *u); -int s2n_stuffer_read_uint16(struct s2n_stuffer *stuffer, uint16_t *u); -int s2n_stuffer_read_uint24(struct s2n_stuffer *stuffer, uint32_t *u); -int s2n_stuffer_read_uint32(struct s2n_stuffer *stuffer, uint32_t *u); -int s2n_stuffer_read_uint64(struct s2n_stuffer *stuffer, uint64_t *u); - -int s2n_stuffer_write_uint8(struct s2n_stuffer *stuffer, const uint8_t u); -int s2n_stuffer_write_uint16(struct s2n_stuffer *stuffer, const uint16_t u); -int s2n_stuffer_write_uint24(struct s2n_stuffer *stuffer, const uint32_t u); -int s2n_stuffer_write_uint32(struct s2n_stuffer *stuffer, const uint32_t u); -int s2n_stuffer_write_uint64(struct s2n_stuffer *stuffer, const uint64_t u); +int S2N_RESULT_MUST_USE s2n_stuffer_read_uint8(struct s2n_stuffer *stuffer, uint8_t *u); +int S2N_RESULT_MUST_USE s2n_stuffer_read_uint16(struct s2n_stuffer *stuffer, uint16_t *u); +int S2N_RESULT_MUST_USE s2n_stuffer_read_uint24(struct s2n_stuffer *stuffer, uint32_t *u); +int S2N_RESULT_MUST_USE s2n_stuffer_read_uint32(struct s2n_stuffer *stuffer, uint32_t *u); +int S2N_RESULT_MUST_USE s2n_stuffer_read_uint64(struct s2n_stuffer *stuffer, uint64_t *u); + +int S2N_RESULT_MUST_USE s2n_stuffer_write_uint8(struct s2n_stuffer *stuffer, const uint8_t u); +int S2N_RESULT_MUST_USE s2n_stuffer_write_uint16(struct s2n_stuffer *stuffer, const uint16_t u); +int S2N_RESULT_MUST_USE s2n_stuffer_write_uint24(struct s2n_stuffer *stuffer, const uint32_t u); +int S2N_RESULT_MUST_USE s2n_stuffer_write_uint32(struct s2n_stuffer *stuffer, const uint32_t u); +int S2N_RESULT_MUST_USE s2n_stuffer_write_uint64(struct s2n_stuffer *stuffer, const uint64_t u); /* Allocate space now for network order integers that will be written later. * These are primarily intended to handle the vector type defined in the RFC: @@ -135,10 +136,10 @@ struct s2n_stuffer_reservation { }; /* Check basic validity constraints on the s2n_stuffer_reservation: e.g. stuffer validity. */ S2N_RESULT s2n_stuffer_reservation_validate(const struct s2n_stuffer_reservation *reservation); -int s2n_stuffer_reserve_uint8(struct s2n_stuffer *stuffer, struct s2n_stuffer_reservation *reservation); -int s2n_stuffer_reserve_uint16(struct s2n_stuffer *stuffer, struct s2n_stuffer_reservation *reservation); -int s2n_stuffer_reserve_uint24(struct s2n_stuffer *stuffer, struct s2n_stuffer_reservation *reservation); -int s2n_stuffer_write_vector_size(struct s2n_stuffer_reservation *reservation); +int S2N_RESULT_MUST_USE s2n_stuffer_reserve_uint8(struct s2n_stuffer *stuffer, struct s2n_stuffer_reservation *reservation); +int S2N_RESULT_MUST_USE s2n_stuffer_reserve_uint16(struct s2n_stuffer *stuffer, struct s2n_stuffer_reservation *reservation); +int S2N_RESULT_MUST_USE s2n_stuffer_reserve_uint24(struct s2n_stuffer *stuffer, struct s2n_stuffer_reservation *reservation); +int S2N_RESULT_MUST_USE s2n_stuffer_write_vector_size(struct s2n_stuffer_reservation *reservation); /* Copy one stuffer to another */ int s2n_stuffer_copy(struct s2n_stuffer *from, struct s2n_stuffer *to, uint32_t len); @@ -153,18 +154,18 @@ int s2n_stuffer_write_base64(struct s2n_stuffer *stuffer, struct s2n_stuffer *in #define s2n_stuffer_write_str(stuffer, c) s2n_stuffer_write_bytes((stuffer), (const uint8_t *) (c), strlen((c))) #define s2n_stuffer_write_text(stuffer, c, n) s2n_stuffer_write_bytes((stuffer), (const uint8_t *) (c), (n)) #define s2n_stuffer_read_text(stuffer, c, n) s2n_stuffer_read_bytes((stuffer), (uint8_t *) (c), (n)) -int s2n_stuffer_read_expected_str(struct s2n_stuffer *stuffer, const char *expected); -int s2n_stuffer_peek_char(struct s2n_stuffer *stuffer, char *c); -int s2n_stuffer_read_token(struct s2n_stuffer *stuffer, struct s2n_stuffer *token, char delim); -int s2n_stuffer_read_line(struct s2n_stuffer *stuffer, struct s2n_stuffer *token); -int s2n_stuffer_peek_check_for_str(struct s2n_stuffer *s2n_stuffer, const char *expected); -int s2n_stuffer_skip_whitespace(struct s2n_stuffer *stuffer, uint32_t *skipped); -int s2n_stuffer_skip_to_char(struct s2n_stuffer *stuffer, char target); -int s2n_stuffer_skip_expected_char(struct s2n_stuffer *stuffer, const char expected, const uint32_t min, +int S2N_RESULT_MUST_USE s2n_stuffer_read_expected_str(struct s2n_stuffer *stuffer, const char *expected); +int S2N_RESULT_MUST_USE s2n_stuffer_peek_char(struct s2n_stuffer *stuffer, char *c); +int S2N_RESULT_MUST_USE s2n_stuffer_read_token(struct s2n_stuffer *stuffer, struct s2n_stuffer *token, char delim); +int S2N_RESULT_MUST_USE s2n_stuffer_read_line(struct s2n_stuffer *stuffer, struct s2n_stuffer *token); +int S2N_RESULT_MUST_USE s2n_stuffer_peek_check_for_str(struct s2n_stuffer *s2n_stuffer, const char *expected); +int S2N_RESULT_MUST_USE s2n_stuffer_skip_whitespace(struct s2n_stuffer *stuffer, uint32_t *skipped); +int S2N_RESULT_MUST_USE s2n_stuffer_skip_to_char(struct s2n_stuffer *stuffer, char target); +int S2N_RESULT_MUST_USE s2n_stuffer_skip_expected_char(struct s2n_stuffer *stuffer, const char expected, const uint32_t min, const uint32_t max, uint32_t *skipped); -int s2n_stuffer_skip_read_until(struct s2n_stuffer *stuffer, const char *target); -int s2n_stuffer_alloc_ro_from_string(struct s2n_stuffer *stuffer, const char *str); -int s2n_stuffer_init_ro_from_string(struct s2n_stuffer *stuffer, uint8_t *data, uint32_t length); +int S2N_RESULT_MUST_USE s2n_stuffer_skip_read_until(struct s2n_stuffer *stuffer, const char *target); +int S2N_RESULT_MUST_USE s2n_stuffer_alloc_ro_from_string(struct s2n_stuffer *stuffer, const char *str); +int S2N_RESULT_MUST_USE s2n_stuffer_init_ro_from_string(struct s2n_stuffer *stuffer, uint8_t *data, uint32_t length); /* Stuffer versions of sprintf methods, except: * - They write bytes, not strings. They do not write a final '\0'. Unfortunately, @@ -173,20 +174,20 @@ int s2n_stuffer_init_ro_from_string(struct s2n_stuffer *stuffer, uint8_t *data, * - vprintf does not consume the vargs. It calls va_copy before using * the varg argument, so can be called repeatedly with the same vargs. */ -int s2n_stuffer_printf(struct s2n_stuffer *stuffer, const char *format, ...); -int s2n_stuffer_vprintf(struct s2n_stuffer *stuffer, const char *format, va_list vargs); +int S2N_RESULT_MUST_USE s2n_stuffer_printf(struct s2n_stuffer *stuffer, const char *format, ...); +int S2N_RESULT_MUST_USE s2n_stuffer_vprintf(struct s2n_stuffer *stuffer, const char *format, va_list vargs); /* Read a private key from a PEM encoded stuffer to an ASN1/DER encoded one */ -int s2n_stuffer_private_key_from_pem(struct s2n_stuffer *pem, struct s2n_stuffer *asn1, int *type); +int S2N_RESULT_MUST_USE s2n_stuffer_private_key_from_pem(struct s2n_stuffer *pem, struct s2n_stuffer *asn1, int *type); /* Read a certificate from a PEM encoded stuffer to an ASN1/DER encoded one */ -int s2n_stuffer_certificate_from_pem(struct s2n_stuffer *pem, struct s2n_stuffer *asn1); +int S2N_RESULT_MUST_USE s2n_stuffer_certificate_from_pem(struct s2n_stuffer *pem, struct s2n_stuffer *asn1); /* Read a CRL from a PEM encoded stuffer to an ASN1/DER encoded one */ -int s2n_stuffer_crl_from_pem(struct s2n_stuffer *pem, struct s2n_stuffer *asn1); +int S2N_RESULT_MUST_USE s2n_stuffer_crl_from_pem(struct s2n_stuffer *pem, struct s2n_stuffer *asn1); /* Read DH parameters om a PEM encoded stuffer to a PKCS3 encoded one */ -int s2n_stuffer_dhparams_from_pem(struct s2n_stuffer *pem, struct s2n_stuffer *pkcs3); +int S2N_RESULT_MUST_USE s2n_stuffer_dhparams_from_pem(struct s2n_stuffer *pem, struct s2n_stuffer *pkcs3); bool s2n_is_base64_char(unsigned char c); @@ -194,4 +195,4 @@ bool s2n_is_base64_char(unsigned char c); * The old blob "out" pointed to is freed. * It is the responsibility of the caller to free the free "out". */ -int s2n_stuffer_extract_blob(struct s2n_stuffer *stuffer, struct s2n_blob *out); +int S2N_RESULT_MUST_USE s2n_stuffer_extract_blob(struct s2n_stuffer *stuffer, struct s2n_blob *out); diff --git a/stuffer/s2n_stuffer_network_order.c b/stuffer/s2n_stuffer_network_order.c index 9db807a60cb..88927091eb2 100644 --- a/stuffer/s2n_stuffer_network_order.c +++ b/stuffer/s2n_stuffer_network_order.c @@ -21,10 +21,14 @@ /* Writes length bytes of input to stuffer, in network order, starting from the smallest byte of input. */ int s2n_stuffer_write_network_order(struct s2n_stuffer *stuffer, const uint64_t input, const uint8_t length) { + if (length == 0) { + return S2N_SUCCESS; + } + POSIX_ENSURE_REF(stuffer); POSIX_ENSURE(length <= sizeof(input), S2N_ERR_SAFETY); POSIX_GUARD(s2n_stuffer_skip_write(stuffer, length)); - uint8_t *data = (stuffer->blob.data) ? (stuffer->blob.data + stuffer->write_cursor - length) : NULL; - + POSIX_ENSURE_REF(stuffer->blob.data); + uint8_t *data = stuffer->blob.data + stuffer->write_cursor - length; for (int i = 0; i < length; i++) { S2N_INVARIANT(i <= length); uint8_t shift = (length - i - 1) * CHAR_BIT; diff --git a/stuffer/s2n_stuffer_pem.c b/stuffer/s2n_stuffer_pem.c index 546f1f189ff..cf8ae838353 100644 --- a/stuffer/s2n_stuffer_pem.c +++ b/stuffer/s2n_stuffer_pem.c @@ -139,8 +139,8 @@ int s2n_stuffer_private_key_from_pem(struct s2n_stuffer *pem, struct s2n_stuffer return S2N_SUCCESS; } - s2n_stuffer_reread(pem); - s2n_stuffer_reread(asn1); + POSIX_GUARD(s2n_stuffer_reread(pem)); + POSIX_GUARD(s2n_stuffer_reread(asn1)); /* By default, OpenSSL tools always generate both "EC PARAMETERS" and "EC PRIVATE * KEY" PEM objects in the keyfile. Skip the first "EC PARAMETERS" object so that we're @@ -148,9 +148,9 @@ int s2n_stuffer_private_key_from_pem(struct s2n_stuffer *pem, struct s2n_stuffer * only needed for non-standard curves that aren't currently supported. */ if (s2n_stuffer_data_from_pem(pem, asn1, S2N_PEM_EC_PARAMETERS) != S2N_SUCCESS) { - s2n_stuffer_reread(pem); + POSIX_GUARD(s2n_stuffer_reread(pem)); } - s2n_stuffer_wipe(asn1); + POSIX_GUARD(s2n_stuffer_wipe(asn1)); if (s2n_stuffer_data_from_pem(pem, asn1, S2N_PEM_PKCS1_EC_PRIVATE_KEY) == S2N_SUCCESS) { *type = EVP_PKEY_EC; @@ -158,8 +158,8 @@ int s2n_stuffer_private_key_from_pem(struct s2n_stuffer *pem, struct s2n_stuffer } /* If it does not match either format, try PKCS#8 */ - s2n_stuffer_reread(pem); - s2n_stuffer_reread(asn1); + POSIX_GUARD(s2n_stuffer_reread(pem)); + POSIX_GUARD(s2n_stuffer_reread(asn1)); if (s2n_stuffer_data_from_pem(pem, asn1, S2N_PEM_PKCS8_PRIVATE_KEY) == S2N_SUCCESS) { *type = EVP_PKEY_RSA; return S2N_SUCCESS; diff --git a/tests/cbmc/proofs/s2n_alloc/Makefile b/tests/cbmc/proofs/s2n_alloc/Makefile index 92c2fd07206..7b6c5821968 100644 --- a/tests/cbmc/proofs/s2n_alloc/Makefile +++ b/tests/cbmc/proofs/s2n_alloc/Makefile @@ -40,7 +40,7 @@ PROJECT_SOURCES += $(SRCDIR)/utils/s2n_result.c # We abstract these functions because manual inspection demonstrates they are unreachable. REMOVE_FUNCTION_BODY += __CPROVER_file_local_s2n_mem_c_s2n_mem_cleanup_impl REMOVE_FUNCTION_BODY += s2n_blob_slice -REMOVE_FUNCTION_BODY += s2n_ensure_memcpy_trace +REMOVE_FUNCTION_BODY += s2n_ensure_memmove_trace UNWINDSET += diff --git a/tests/cbmc/proofs/s2n_array_init/Makefile b/tests/cbmc/proofs/s2n_array_init/Makefile index 8f740b51045..48477fd21be 100644 --- a/tests/cbmc/proofs/s2n_array_init/Makefile +++ b/tests/cbmc/proofs/s2n_array_init/Makefile @@ -35,7 +35,7 @@ PROJECT_SOURCES += $(SRCDIR)/utils/s2n_safety.c # We abstract these functions because manual inspection demonstrates they are unreachable. REMOVE_FUNCTION_BODY += s2n_blob_slice -REMOVE_FUNCTION_BODY += s2n_ensure_memcpy_trace +REMOVE_FUNCTION_BODY += s2n_ensure_memmove_trace REMOVE_FUNCTION_BODY += __CPROVER_file_local_s2n_mem_c_s2n_mem_cleanup_impl UNWINDSET += diff --git a/tests/cbmc/proofs/s2n_array_new/Makefile b/tests/cbmc/proofs/s2n_array_new/Makefile index 389c7f0192c..6cd64107a73 100644 --- a/tests/cbmc/proofs/s2n_array_new/Makefile +++ b/tests/cbmc/proofs/s2n_array_new/Makefile @@ -38,7 +38,7 @@ PROJECT_SOURCES += $(SRCDIR)/utils/s2n_safety.c # We abstract these functions because manual inspection demonstrates they are unreachable. REMOVE_FUNCTION_BODY += s2n_blob_slice -REMOVE_FUNCTION_BODY += s2n_ensure_memcpy_trace +REMOVE_FUNCTION_BODY += s2n_ensure_memmove_trace REMOVE_FUNCTION_BODY += __CPROVER_file_local_s2n_mem_c_s2n_mem_cleanup_impl UNWINDSET += diff --git a/tests/cbmc/proofs/s2n_dh_compute_shared_secret_as_client/Makefile b/tests/cbmc/proofs/s2n_dh_compute_shared_secret_as_client/Makefile index ec8ef4fc519..cb7a239897c 100644 --- a/tests/cbmc/proofs/s2n_dh_compute_shared_secret_as_client/Makefile +++ b/tests/cbmc/proofs/s2n_dh_compute_shared_secret_as_client/Makefile @@ -39,7 +39,7 @@ PROJECT_SOURCES += $(SRCDIR)/utils/s2n_mem.c PROJECT_SOURCES += $(SRCDIR)/utils/s2n_result.c PROJECT_SOURCES += $(SRCDIR)/utils/s2n_safety.c -UNWINDSET += s2n_stuffer_write_network_order.4:9 +UNWINDSET += s2n_stuffer_write_network_order.10:9 # We abstract this function because manual inspection demonstrates it is unreachable. REMOVE_FUNCTION_BODY += __CPROVER_file_local_s2n_mem_c_s2n_mem_cleanup_impl diff --git a/tests/cbmc/proofs/s2n_dh_params_to_p_g_Ys/Makefile b/tests/cbmc/proofs/s2n_dh_params_to_p_g_Ys/Makefile index 94ca0745414..33bba982d1f 100644 --- a/tests/cbmc/proofs/s2n_dh_params_to_p_g_Ys/Makefile +++ b/tests/cbmc/proofs/s2n_dh_params_to_p_g_Ys/Makefile @@ -42,6 +42,6 @@ REMOVE_FUNCTION_BODY += s2n_free REMOVE_FUNCTION_BODY += s2n_realloc REMOVE_FUNCTION_BODY += s2n_stuffer_wipe -UNWINDSET += s2n_stuffer_write_network_order.4:9 +UNWINDSET += s2n_stuffer_write_network_order.10:9 include ../Makefile.common diff --git a/tests/cbmc/proofs/s2n_set_new/Makefile b/tests/cbmc/proofs/s2n_set_new/Makefile index 6322ae4ce0e..5cf2f575ea5 100644 --- a/tests/cbmc/proofs/s2n_set_new/Makefile +++ b/tests/cbmc/proofs/s2n_set_new/Makefile @@ -42,7 +42,7 @@ PROJECT_SOURCES += $(SRCDIR)/utils/s2n_set.c # We abstract these functions because manual inspection demonstrates they are unreachable. REMOVE_FUNCTION_BODY += s2n_blob_slice -REMOVE_FUNCTION_BODY += s2n_ensure_memcpy_trace +REMOVE_FUNCTION_BODY += s2n_ensure_memmove_trace REMOVE_FUNCTION_BODY += __CPROVER_file_local_s2n_mem_c_s2n_mem_cleanup_impl UNWINDSET += diff --git a/tests/cbmc/proofs/s2n_stuffer_alloc/Makefile b/tests/cbmc/proofs/s2n_stuffer_alloc/Makefile index 59795b1e168..db954284f82 100644 --- a/tests/cbmc/proofs/s2n_stuffer_alloc/Makefile +++ b/tests/cbmc/proofs/s2n_stuffer_alloc/Makefile @@ -40,7 +40,7 @@ PROJECT_SOURCES += $(SRCDIR)/utils/s2n_safety.c # We abstract these functions because manual inspection demonstrates they are unreachable. REMOVE_FUNCTION_BODY += __CPROVER_file_local_s2n_mem_c_s2n_mem_cleanup_impl REMOVE_FUNCTION_BODY += s2n_blob_slice -REMOVE_FUNCTION_BODY += s2n_ensure_memcpy_trace +REMOVE_FUNCTION_BODY += s2n_ensure_memmove_trace UNWINDSET += diff --git a/tests/cbmc/proofs/s2n_stuffer_growable_alloc/Makefile b/tests/cbmc/proofs/s2n_stuffer_growable_alloc/Makefile index 48ca5bebc0a..4a11bcc8189 100644 --- a/tests/cbmc/proofs/s2n_stuffer_growable_alloc/Makefile +++ b/tests/cbmc/proofs/s2n_stuffer_growable_alloc/Makefile @@ -38,7 +38,7 @@ PROJECT_SOURCES += $(SRCDIR)/utils/s2n_safety.c # We abstract these functions because manual inspection demonstrates they are unreachable. REMOVE_FUNCTION_BODY += __CPROVER_file_local_s2n_mem_c_s2n_mem_cleanup_impl REMOVE_FUNCTION_BODY += s2n_blob_slice -REMOVE_FUNCTION_BODY += s2n_ensure_memcpy_trace +REMOVE_FUNCTION_BODY += s2n_ensure_memmove_trace UNWINDSET += diff --git a/tests/cbmc/proofs/s2n_stuffer_resize_if_empty/Makefile b/tests/cbmc/proofs/s2n_stuffer_resize_if_empty/Makefile index daac401569b..41b69d86b55 100644 --- a/tests/cbmc/proofs/s2n_stuffer_resize_if_empty/Makefile +++ b/tests/cbmc/proofs/s2n_stuffer_resize_if_empty/Makefile @@ -35,7 +35,7 @@ PROJECT_SOURCES += $(SRCDIR)/utils/s2n_result.c # We abstract these functions because manual inspection demonstrates they are unreachable. REMOVE_FUNCTION_BODY += s2n_calculate_stacktrace REMOVE_FUNCTION_BODY += s2n_blob_slice -REMOVE_FUNCTION_BODY += s2n_ensure_memcpy_trace +REMOVE_FUNCTION_BODY += s2n_ensure_memmove_trace REMOVE_FUNCTION_BODY += __CPROVER_file_local_s2n_mem_c_s2n_mem_cleanup_impl UNWINDSET += diff --git a/tests/cbmc/proofs/s2n_stuffer_shift/Makefile b/tests/cbmc/proofs/s2n_stuffer_shift/Makefile new file mode 100644 index 00000000000..b744029ce30 --- /dev/null +++ b/tests/cbmc/proofs/s2n_stuffer_shift/Makefile @@ -0,0 +1,41 @@ +# +# +# Licensed under the Apache License, Version 2.0 (the "License"). You may not use +# this file except in compliance with the License. A copy of the License is +# located at +# +# http://aws.amazon.com/apache2.0/ +# +# or in the "license" file accompanying this file. This file is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. See the License for the specific language governing permissions and +# limitations under the License. + +# Expected runtime is 10 seconds. + +MAX_BLOB_SIZE = 20 +DEFINES += -DMAX_BLOB_SIZE=$(MAX_BLOB_SIZE) + +CBMCFLAGS += + +PROOF_UID = s2n_stuffer_shift +HARNESS_ENTRY = $(PROOF_UID)_harness +HARNESS_FILE = $(HARNESS_ENTRY).c + +PROOF_SOURCES += $(PROOFDIR)/$(HARNESS_FILE) +PROOF_SOURCES += $(PROOF_SOURCE)/cbmc_utils.c +PROOF_SOURCES += $(PROOF_SOURCE)/make_common_datastructures.c +PROOF_SOURCES += $(PROOF_STUB)/memmove_simple.c + +PROJECT_SOURCES += $(SRCDIR)/error/s2n_errno.c +PROJECT_SOURCES += $(SRCDIR)/stuffer/s2n_stuffer.c +PROJECT_SOURCES += $(SRCDIR)/utils/s2n_blob.c +PROJECT_SOURCES += $(SRCDIR)/utils/s2n_ensure.c +PROJECT_SOURCES += $(SRCDIR)/utils/s2n_mem.c +PROJECT_SOURCES += $(SRCDIR)/utils/s2n_result.c +PROJECT_SOURCES += $(SRCDIR)/utils/s2n_safety.c + +UNWINDSET += memmove_impl.0:$(call addone,$(MAX_BLOB_SIZE)) +UNWINDSET += memmove_impl.1:$(call addone,$(MAX_BLOB_SIZE)) + +include ../Makefile.common diff --git a/tests/cbmc/proofs/s2n_stuffer_shift/cbmc-proof.txt b/tests/cbmc/proofs/s2n_stuffer_shift/cbmc-proof.txt new file mode 100644 index 00000000000..6ed46f1258c --- /dev/null +++ b/tests/cbmc/proofs/s2n_stuffer_shift/cbmc-proof.txt @@ -0,0 +1 @@ +# This file marks this directory as containing a CBMC proof. diff --git a/tests/cbmc/proofs/s2n_stuffer_shift/s2n_stuffer_shift_harness.c b/tests/cbmc/proofs/s2n_stuffer_shift/s2n_stuffer_shift_harness.c new file mode 100644 index 00000000000..a499d7ff53c --- /dev/null +++ b/tests/cbmc/proofs/s2n_stuffer_shift/s2n_stuffer_shift_harness.c @@ -0,0 +1,46 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +#include +#include +#include + +#include "api/s2n.h" +#include "stuffer/s2n_stuffer.h" + +void s2n_stuffer_shift_harness() +{ + struct s2n_stuffer *stuffer = cbmc_allocate_s2n_stuffer(); + __CPROVER_assume(s2n_result_is_ok(s2n_stuffer_validate(stuffer))); + __CPROVER_assume(s2n_blob_is_bounded(&stuffer->blob, MAX_BLOB_SIZE)); + + /* Save previous state from stuffer. */ + struct s2n_stuffer old_stuffer = *stuffer; + uint32_t shift = old_stuffer.read_cursor; + struct store_byte_from_buffer old_byte = { 0 }; + save_byte_from_blob(&old_stuffer.blob, &old_byte); + __CPROVER_assume(old_byte.idx >= old_stuffer.read_cursor); + __CPROVER_assume(old_byte.idx < old_stuffer.write_cursor); + + int result = s2n_stuffer_shift(stuffer); + assert(s2n_result_is_ok(s2n_stuffer_validate(stuffer))); + + if (result == S2N_SUCCESS) { + old_byte.idx -= shift; + old_stuffer.write_cursor -= shift; + old_stuffer.read_cursor = 0; + } + assert_stuffer_equivalence(stuffer, &old_stuffer, &old_byte); +} diff --git a/tests/cbmc/proofs/s2n_stuffer_write_network_order/Makefile b/tests/cbmc/proofs/s2n_stuffer_write_network_order/Makefile index 4c8f38b8e79..ba093b9041a 100644 --- a/tests/cbmc/proofs/s2n_stuffer_write_network_order/Makefile +++ b/tests/cbmc/proofs/s2n_stuffer_write_network_order/Makefile @@ -38,7 +38,7 @@ REMOVE_FUNCTION_BODY += __CPROVER_file_local_s2n_mem_c_s2n_mem_cleanup_impl REMOVE_FUNCTION_BODY += s2n_blob_slice REMOVE_FUNCTION_BODY += s2n_stuffer_wipe -UNWINDSET += s2n_stuffer_write_network_order.4:9 +UNWINDSET += s2n_stuffer_write_network_order.10:9 UNWINDSET += s2n_stuffer_write_network_order_harness.0:9 include ../Makefile.common diff --git a/tests/cbmc/proofs/s2n_stuffer_write_reservation/Makefile b/tests/cbmc/proofs/s2n_stuffer_write_reservation/Makefile index fe8370b37f7..bc921b1d3ee 100644 --- a/tests/cbmc/proofs/s2n_stuffer_write_reservation/Makefile +++ b/tests/cbmc/proofs/s2n_stuffer_write_reservation/Makefile @@ -48,13 +48,6 @@ REMOVE_FUNCTION_BODY += s2n_stuffer_wipe REMOVE_FUNCTION_BODY += s2n_stuffer_wipe_n REMOVE_FUNCTION_BODY += __CPROVER_file_local_s2n_mem_c_s2n_mem_cleanup_impl -UNWINDSET += s2n_stuffer_write_network_order.0:$(MAX_WRITE_NETWORK_ORDER) -UNWINDSET += s2n_stuffer_write_network_order.1:$(MAX_WRITE_NETWORK_ORDER) -UNWINDSET += s2n_stuffer_write_network_order.2:$(MAX_WRITE_NETWORK_ORDER) -UNWINDSET += s2n_stuffer_write_network_order.3:$(MAX_WRITE_NETWORK_ORDER) -UNWINDSET += s2n_stuffer_write_network_order.4:$(MAX_WRITE_NETWORK_ORDER) -UNWINDSET += s2n_stuffer_write_network_order.5:$(MAX_WRITE_NETWORK_ORDER) -UNWINDSET += s2n_stuffer_write_network_order.6:$(MAX_WRITE_NETWORK_ORDER) -UNWINDSET += s2n_stuffer_write_network_order.7:$(MAX_WRITE_NETWORK_ORDER) +UNWINDSET += s2n_stuffer_write_network_order.10:$(MAX_WRITE_NETWORK_ORDER) include ../Makefile.common diff --git a/tests/cbmc/proofs/s2n_stuffer_write_uint16/Makefile b/tests/cbmc/proofs/s2n_stuffer_write_uint16/Makefile index 73c61bcecad..de513abf4e9 100644 --- a/tests/cbmc/proofs/s2n_stuffer_write_uint16/Makefile +++ b/tests/cbmc/proofs/s2n_stuffer_write_uint16/Makefile @@ -36,6 +36,6 @@ PROJECT_SOURCES += $(SRCDIR)/utils/s2n_result.c REMOVE_FUNCTION_BODY += s2n_blob_slice REMOVE_FUNCTION_BODY += s2n_stuffer_wipe -UNWINDSET += s2n_stuffer_write_network_order.4:$(shell echo $$((1 + $(SIZEOF_UINT16)))) +UNWINDSET += s2n_stuffer_write_network_order.10:$(shell echo $$((1 + $(SIZEOF_UINT16)))) include ../Makefile.common diff --git a/tests/cbmc/proofs/s2n_stuffer_write_uint24/Makefile b/tests/cbmc/proofs/s2n_stuffer_write_uint24/Makefile index acba5cf7b1e..0ee330db573 100644 --- a/tests/cbmc/proofs/s2n_stuffer_write_uint24/Makefile +++ b/tests/cbmc/proofs/s2n_stuffer_write_uint24/Makefile @@ -36,6 +36,6 @@ PROJECT_SOURCES += $(SRCDIR)/utils/s2n_result.c REMOVE_FUNCTION_BODY += s2n_blob_slice REMOVE_FUNCTION_BODY += s2n_stuffer_wipe -UNWINDSET += s2n_stuffer_write_network_order.4:$(shell echo $$((1 + $(SIZEOF_UINT24)))) +UNWINDSET += s2n_stuffer_write_network_order.10:$(shell echo $$((1 + $(SIZEOF_UINT24)))) include ../Makefile.common diff --git a/tests/cbmc/proofs/s2n_stuffer_write_uint32/Makefile b/tests/cbmc/proofs/s2n_stuffer_write_uint32/Makefile index aece6e2f0d0..bec46adf7eb 100644 --- a/tests/cbmc/proofs/s2n_stuffer_write_uint32/Makefile +++ b/tests/cbmc/proofs/s2n_stuffer_write_uint32/Makefile @@ -36,6 +36,6 @@ PROJECT_SOURCES += $(SRCDIR)/utils/s2n_result.c REMOVE_FUNCTION_BODY += s2n_blob_slice REMOVE_FUNCTION_BODY += s2n_stuffer_wipe -UNWINDSET += s2n_stuffer_write_network_order.4:$(shell echo $$((1 + $(SIZEOF_UINT32)))) +UNWINDSET += s2n_stuffer_write_network_order.10:$(shell echo $$((1 + $(SIZEOF_UINT32)))) include ../Makefile.common diff --git a/tests/cbmc/proofs/s2n_stuffer_write_uint64/Makefile b/tests/cbmc/proofs/s2n_stuffer_write_uint64/Makefile index 04f1c6b5aae..8e339851469 100644 --- a/tests/cbmc/proofs/s2n_stuffer_write_uint64/Makefile +++ b/tests/cbmc/proofs/s2n_stuffer_write_uint64/Makefile @@ -36,6 +36,6 @@ PROJECT_SOURCES += $(SRCDIR)/utils/s2n_result.c REMOVE_FUNCTION_BODY += s2n_blob_slice REMOVE_FUNCTION_BODY += s2n_stuffer_wipe -UNWINDSET += s2n_stuffer_write_network_order.4:$(shell echo $$((1 + $(SIZEOF_UINT64)))) +UNWINDSET += s2n_stuffer_write_network_order.10:$(shell echo $$((1 + $(SIZEOF_UINT64)))) include ../Makefile.common diff --git a/tests/cbmc/proofs/s2n_stuffer_write_vector_size/Makefile b/tests/cbmc/proofs/s2n_stuffer_write_vector_size/Makefile index cf3fc56cd15..350684a0681 100644 --- a/tests/cbmc/proofs/s2n_stuffer_write_vector_size/Makefile +++ b/tests/cbmc/proofs/s2n_stuffer_write_vector_size/Makefile @@ -44,13 +44,6 @@ REMOVE_FUNCTION_BODY += s2n_stuffer_resize REMOVE_FUNCTION_BODY += s2n_stuffer_wipe_n REMOVE_FUNCTION_BODY += __CPROVER_file_local_s2n_mem_c_s2n_mem_cleanup_impl -UNWINDSET += s2n_stuffer_write_network_order.0:$(MAX_WRITE_NETWORK_ORDER) -UNWINDSET += s2n_stuffer_write_network_order.1:$(MAX_WRITE_NETWORK_ORDER) -UNWINDSET += s2n_stuffer_write_network_order.2:$(MAX_WRITE_NETWORK_ORDER) -UNWINDSET += s2n_stuffer_write_network_order.3:$(MAX_WRITE_NETWORK_ORDER) -UNWINDSET += s2n_stuffer_write_network_order.4:$(MAX_WRITE_NETWORK_ORDER) -UNWINDSET += s2n_stuffer_write_network_order.5:$(MAX_WRITE_NETWORK_ORDER) -UNWINDSET += s2n_stuffer_write_network_order.6:$(MAX_WRITE_NETWORK_ORDER) -UNWINDSET += s2n_stuffer_write_network_order.7:$(MAX_WRITE_NETWORK_ORDER) +UNWINDSET += s2n_stuffer_write_network_order.10:$(MAX_WRITE_NETWORK_ORDER) include ../Makefile.common diff --git a/tests/cbmc/stubs/memmove_simple.c b/tests/cbmc/stubs/memmove_simple.c new file mode 100644 index 00000000000..612f3cd9beb --- /dev/null +++ b/tests/cbmc/stubs/memmove_simple.c @@ -0,0 +1,65 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use + * this file except in compliance with the License. A copy of the License is + * located at + * + * http://aws.amazon.com/apache2.0/ + * + * or in the "license" file accompanying this file. This file is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. See the License for the specific language governing permissions and + * limitations under the License. + */ + +#undef memmove + +#include +#include +#include +#include + +/** + * CBMC can struggle to model memmove. + * If a proof needs real memmove behavior without paying its high cost, + * that proof can use this simple looping based solution. + */ +void *memmove_impl(void *dest, const void *src, size_t n) { + __CPROVER_HIDE:; + if (n > 0) { + assert(dest); + assert(src); + } + + uint8_t *dest_bytes = (uint8_t*) dest; + uint8_t *src_bytes = (uint8_t*) src; + + /* src and dst can overlap, so we need to save a copy of src + * in case modifying dst modifies src */ + uint8_t *src_copy = malloc(n); + if (src_copy == NULL) { + return NULL; + } + for (size_t i = 0; i < n; i++) { + src_copy[i] = src_bytes[i]; + } + + for (size_t i = 0; i < n; i++) { + dest_bytes[i] = src_copy[i]; + } + + free(src_copy); + return dest; +} + +void *memmove(void *dest, const void *src, size_t n) { + __CPROVER_HIDE:; + return memmove_impl(dest, src, n); +} + +void *__builtin___memmove_chk(void *dest, const void *src, size_t n, size_t size) { + __CPROVER_HIDE:; + (void)size; + return memmove_impl(dest, src, n); +} diff --git a/tests/cbmc/stubs/s2n_ensure.c b/tests/cbmc/stubs/s2n_ensure.c index 01ff888062f..ae0e5a82c47 100644 --- a/tests/cbmc/stubs/s2n_ensure.c +++ b/tests/cbmc/stubs/s2n_ensure.c @@ -15,7 +15,7 @@ #include "utils/s2n_safety.h" -void* s2n_ensure_memcpy_trace(void *restrict to, const void *restrict from, size_t size) +void* s2n_ensure_memmove_trace(void *to, const void *from, size_t size) { if (to == NULL || from == NULL) { return NULL; diff --git a/tests/cbmc/stubs/s2n_is_in_fips_mode.c b/tests/cbmc/stubs/s2n_is_in_fips_mode.c index 8a76d11bc6d..7ee61b05510 100644 --- a/tests/cbmc/stubs/s2n_is_in_fips_mode.c +++ b/tests/cbmc/stubs/s2n_is_in_fips_mode.c @@ -17,18 +17,18 @@ #include "crypto/s2n_fips.h" -static int flag = 0; -static int s2n_fips_mode = 0; +static bool flag = 0; +static bool s2n_fips_mode_enabled = 0; /** * Return 1 if FIPS mode is set, 0 otherwise, * where FIPS mode is set nondeterministically on first call. */ -int s2n_is_in_fips_mode() +bool s2n_is_in_fips_mode() { if (flag == 0) { - s2n_fips_mode = nondet_bool() ? 1 : 0; - flag = 1; + s2n_fips_mode_enabled = nondet_bool() ? 1 : 0; + flag = 1; } - return s2n_fips_mode; + return s2n_fips_mode_enabled; } diff --git a/tests/features/S2N_LIBCRYPTO_SUPPORTS_EC_KEY_CHECK_FIPS.c b/tests/features/S2N_LIBCRYPTO_SUPPORTS_EC_KEY_CHECK_FIPS.c new file mode 100644 index 00000000000..8ef8342e7e6 --- /dev/null +++ b/tests/features/S2N_LIBCRYPTO_SUPPORTS_EC_KEY_CHECK_FIPS.c @@ -0,0 +1,23 @@ +/* +* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"). +* You may not use this file except in compliance with the License. +* A copy of the License is located at +* +* http://aws.amazon.com/apache2.0 +* +* or in the "license" file accompanying this file. This file is distributed +* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +* express or implied. See the License for the specific language governing +* permissions and limitations under the License. +*/ + +#include + +int main() +{ + EC_KEY *ec_key = NULL; + EC_KEY_check_fips(ec_key); + return 0; +} diff --git a/tests/features/S2N_LIBCRYPTO_SUPPORTS_EC_KEY_CHECK_FIPS.flags b/tests/features/S2N_LIBCRYPTO_SUPPORTS_EC_KEY_CHECK_FIPS.flags new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/features/S2N___RESTRICT__SUPPORTED.c b/tests/features/S2N___RESTRICT__SUPPORTED.c deleted file mode 100644 index b29c32ef9ad..00000000000 --- a/tests/features/S2N___RESTRICT__SUPPORTED.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -void swap(int *__restrict__ left, int *__restrict__ right) { - int temp = *left; - *left = *right; - *right = temp; -} - -int main() { - int a = 1, b = 2; - swap(&a, &b); - return 0; -} - diff --git a/tests/features/S2N___RESTRICT__SUPPORTED.flags b/tests/features/S2N___RESTRICT__SUPPORTED.flags deleted file mode 100644 index 2f41be663b2..00000000000 --- a/tests/features/S2N___RESTRICT__SUPPORTED.flags +++ /dev/null @@ -1 +0,0 @@ --Werror diff --git a/tests/fuzz/Makefile b/tests/fuzz/Makefile index 0658600c241..266fa280e87 100644 --- a/tests/fuzz/Makefile +++ b/tests/fuzz/Makefile @@ -39,7 +39,9 @@ include ../../s2n.mk CRUFT += $(wildcard *_test) $(wildcard fuzz-*.log) $(wildcard *_test_output.txt) $(wildcard *_test_results.txt) $(wildcard LD_PRELOAD/*.so) $(wildcard *.prof*) -CFLAGS += -Wno-unreachable-code -O0 -I$(LIBCRYPTO_ROOT)/include/ -I../ +# We do not warn on unused results (-Wno-unused-result) because we expect that +# many of the fuzz test inputs will not be valid and operations will not succeed. +CFLAGS += -Wno-unreachable-code -Wno-unused-result -O0 -I$(LIBCRYPTO_ROOT)/include/ -I../ LIBS += -L../testlib/ -ltests2n -L../../lib/ -ls2n LDFLAGS += $(LIBFUZZER_ROOT)/lib/libFuzzer.a -lstdc++ LDFLAGS += ${CRYPTO_LDFLAGS} ${LIBS} ${CRYPTO_LIBS} -lm -ldl -lrt -pthread diff --git a/tests/fuzz/s2n_certificate_extensions_parse_test.c b/tests/fuzz/s2n_certificate_extensions_parse_test.c index 901b5641a86..bf9d8a13fe2 100644 --- a/tests/fuzz/s2n_certificate_extensions_parse_test.c +++ b/tests/fuzz/s2n_certificate_extensions_parse_test.c @@ -25,6 +25,7 @@ #include "api/s2n.h" #include "stuffer/s2n_stuffer.h" #include "tls/extensions/s2n_extension_list.h" +#include "tls/s2n_config.h" #include "tls/s2n_connection.h" #include "tls/s2n_tls.h" #include "utils/s2n_safety.h" @@ -50,6 +51,8 @@ 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; } diff --git a/tests/pems/mixed_chains/README.md b/tests/pems/mixed_chains/README.md new file mode 100644 index 00000000000..6d24cb17fa4 --- /dev/null +++ b/tests/pems/mixed_chains/README.md @@ -0,0 +1,16 @@ +This folder contains "mixed key" cert chains. + +The `ecdsa` cert chain contains intermediate and leaf certs that are issued from a CA with a smaller key. +``` + leaf: P-384 key + â–² + │ signature: ECDSA with SHA384 + │ + intermediate: P-384 key + â–² + │ signature: ECDSA with SHA384 + │ + root: P-256 key + â–² + signature:ECDSA with SHA384 +``` diff --git a/tests/pems/mixed_chains/ecdsa/ca-cert.pem b/tests/pems/mixed_chains/ecdsa/ca-cert.pem new file mode 100644 index 00000000000..829f62e9204 --- /dev/null +++ b/tests/pems/mixed_chains/ecdsa/ca-cert.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBnzCCAUWgAwIBAgIUXI8F6k7vlX97S4ZpnR59noZbxrowCgYIKoZIzj0EAwMw +HDELMAkGA1UEBhMCVVMxDTALBgNVBAMMBHJvb3QwIBcNMjQwMjIxMDQzMzA3WhgP +MjIwMzA3MjkwNDMzMDdaMBwxCzAJBgNVBAYTAlVTMQ0wCwYDVQQDDARyb290MFkw +EwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAED9Xh6MZhQGw+p0V7rLGzBF3YPgwJFP+f +Ee5D/XSaS76v/RiEWzqOGJ7hxUrsxvoNJUXPJJMASDwDRVvx8iB5kKNjMGEwHQYD +VR0OBBYEFLLjtcK+eccZErEbdrRBGyjjyYc3MB8GA1UdIwQYMBaAFLLjtcK+eccZ +ErEbdrRBGyjjyYc3MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgIEMAoG +CCqGSM49BAMDA0gAMEUCID6Svg9A9LmGqK5vJPguEsV0EggHPRmUT27bEPaO57Qh +AiEAnmgHw9d3qWOGGVhkYEpb/tKnVU6wFyRLd4qOZn0vgnM= +-----END CERTIFICATE----- diff --git a/tests/pems/mixed_chains/ecdsa/server-chain.pem b/tests/pems/mixed_chains/ecdsa/server-chain.pem new file mode 100644 index 00000000000..aa5c3791922 --- /dev/null +++ b/tests/pems/mixed_chains/ecdsa/server-chain.pem @@ -0,0 +1,35 @@ +-----BEGIN CERTIFICATE----- +MIIB1DCCAVmgAwIBAgIUIqQpkU80sEjH8mxl5O46jWU3IskwCgYIKoZIzj0EAwMw +HjELMAkGA1UEBhMCVVMxDzANBgNVBAMMBmJyYW5jaDAgFw0yNDAyMjEwNDMzMDda +GA8yMjAzMDcyOTA0MzMwN1owHDELMAkGA1UEBhMCVVMxDTALBgNVBAMMBGxlYWYw +djAQBgcqhkjOPQIBBgUrgQQAIgNiAAQIl3I7/xURYZY4mIYhQujKAv3W4me4QKnB +0oinYiVzMpZ7/+I8YoeiOtzeuWER1TuoZ551mMTTSzPCfvgTwCyvbJdsWYIvcUD2 +afa/+z5mWhq0rYkvH0fOwTP7BiJh5bCjWDBWMBQGA1UdEQQNMAuCCWxvY2FsaG9z +dDAdBgNVHQ4EFgQUtyazibNdyEtNQl26ufEuq0Xi59AwHwYDVR0jBBgwFoAU4Adk +/yc9lPlh8XfREeXYXnp/wxwwCgYIKoZIzj0EAwMDaQAwZgIxAJlqGLkZCoOCU+xu +K6EAQBrcidmNaBqO5A+1hQnmJrGcZ9D7N5GigKQ5Tf1+RlLgkAIxANmxOoFKoaD6 +7mSckr7+XN/s8IcZPJ/ZUvM5jeLT8qugb4lOm4d/9jJfECJPcHDNBg== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIBvzCCAWSgAwIBAgIUQnk97VcKbYR3+vC1kvJW4WxMDk4wCgYIKoZIzj0EAwMw +HDELMAkGA1UEBhMCVVMxDTALBgNVBAMMBHJvb3QwIBcNMjQwMjIxMDQzMzA3WhgP +MjIwMzA3MjkwNDMzMDdaMB4xCzAJBgNVBAYTAlVTMQ8wDQYDVQQDDAZicmFuY2gw +djAQBgcqhkjOPQIBBgUrgQQAIgNiAAThrJeng+kFLIMSVqzMMgK9z4+H7LzVfnau +YtjU86NtFxwfFFVu4H5IS4sC+LV7bQXiGSWzptzmxHZLZBI6Os8hGG5BLqkMBFyp +KfqzyjuTAYiIp/qIMOkzY/yHtIEnDm6jYzBhMA8GA1UdEwEB/wQFMAMBAf8wDgYD +VR0PAQH/BAQDAgIEMB0GA1UdDgQWBBTgB2T/Jz2U+WHxd9ER5dheen/DHDAfBgNV +HSMEGDAWgBSy47XCvnnHGRKxG3a0QRso48mHNzAKBggqhkjOPQQDAwNJADBGAiEA +3y/BPqbHkj+7TWv2+9d/FREZX/sk9k7b/MKowj3LHZACIQDbeGLk0TVpdElzVYLl +HBcgqJegl/ptFbAlNB36KqpYYA== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIBnzCCAUWgAwIBAgIUXI8F6k7vlX97S4ZpnR59noZbxrowCgYIKoZIzj0EAwMw +HDELMAkGA1UEBhMCVVMxDTALBgNVBAMMBHJvb3QwIBcNMjQwMjIxMDQzMzA3WhgP +MjIwMzA3MjkwNDMzMDdaMBwxCzAJBgNVBAYTAlVTMQ0wCwYDVQQDDARyb290MFkw +EwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAED9Xh6MZhQGw+p0V7rLGzBF3YPgwJFP+f +Ee5D/XSaS76v/RiEWzqOGJ7hxUrsxvoNJUXPJJMASDwDRVvx8iB5kKNjMGEwHQYD +VR0OBBYEFLLjtcK+eccZErEbdrRBGyjjyYc3MB8GA1UdIwQYMBaAFLLjtcK+eccZ +ErEbdrRBGyjjyYc3MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgIEMAoG +CCqGSM49BAMDA0gAMEUCID6Svg9A9LmGqK5vJPguEsV0EggHPRmUT27bEPaO57Qh +AiEAnmgHw9d3qWOGGVhkYEpb/tKnVU6wFyRLd4qOZn0vgnM= +-----END CERTIFICATE----- diff --git a/tests/pems/mixed_chains/ecdsa/server-key.pem b/tests/pems/mixed_chains/ecdsa/server-key.pem new file mode 100644 index 00000000000..c3bd7f9626f --- /dev/null +++ b/tests/pems/mixed_chains/ecdsa/server-key.pem @@ -0,0 +1,6 @@ +-----BEGIN PRIVATE KEY----- +MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDCosm1okl1Efmyz4wtv +paXDecqqo/7P7l6AE1+357MBHB1us6CM677L66a6rS1YcRKhZANiAAQIl3I7/xUR +YZY4mIYhQujKAv3W4me4QKnB0oinYiVzMpZ7/+I8YoeiOtzeuWER1TuoZ551mMTT +SzPCfvgTwCyvbJdsWYIvcUD2afa/+z5mWhq0rYkvH0fOwTP7BiJh5bA= +-----END PRIVATE KEY----- diff --git a/tests/pems/mixed_chains/generate-certs.sh b/tests/pems/mixed_chains/generate-certs.sh new file mode 100755 index 00000000000..3b534f20b68 --- /dev/null +++ b/tests/pems/mixed_chains/generate-certs.sh @@ -0,0 +1,119 @@ +#!/usr/bin/env bash + +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 + +# Usage: ./generate_certs.sh [clean] +# Generates mixed-chain certs for testing +# Use argument "clean" to remove all generated certs + +# immediately bail if any command fails +set -e + +# Generates certs with given algorithms and bits in $1$2/, ex. ec384/ +# $1: rsa or ec +# $2: size of the key used by the leaf and intermediate +# $3: size of the key used by the issuing CA +# $4: digest using in the certificate signatures +# $5: name of the output directory +cert-gen () { + key_family=$1 + key_size=$2 + ca_key_size=$3 + digest=$4 + dir_name=$5 + + echo -e "\n----- generating certs for ec $key_size with $digest $signature -----\n" + + # make directory for certs + mkdir -p $dir_name + cd $dir_name + + echo "generating CA private key and certificate" + openssl req -new -noenc -x509 \ + -newkey ec \ + -pkeyopt ec_paramgen_curve:P-$ca_key_size \ + -keyout ca-key.pem \ + -out ca-cert.pem \ + -days 65536 \ + -$digest \ + -subj "/C=US/CN=root" \ + -addext "basicConstraints = critical,CA:true" \ + -addext "keyUsage = critical,keyCertSign" + + echo "generating intermediate private key and CSR" + openssl req -new -noenc \ + -newkey ec \ + -pkeyopt ec_paramgen_curve:P-$key_size \ + -keyout intermediate-key.pem \ + -out intermediate.csr \ + -subj "/C=US/CN=branch" \ + -addext "basicConstraints = critical,CA:true" \ + -addext "keyUsage = critical,keyCertSign" + + echo "generating server private key and CSR" + openssl req -new -noenc \ + -newkey ec \ + -pkeyopt ec_paramgen_curve:P-$key_size \ + -keyout server-key.pem \ + -out server.csr \ + -subj "/C=US/CN=leaf" \ + -addext "subjectAltName = DNS:localhost" + + echo "generating intermediate certificate and signing it" + openssl x509 -days 65536 \ + -req -in intermediate.csr \ + -$digest \ + -CA ca-cert.pem \ + -CAkey ca-key.pem \ + -CAcreateserial \ + -out intermediate-cert.pem \ + -copy_extensions=copyall + + echo "generating server certificate and signing it" + openssl x509 -days 65536 \ + -req -in server.csr \ + -$digest \ + -CA intermediate-cert.pem \ + -CAkey intermediate-key.pem \ + -CAcreateserial -out server-cert.pem \ + -copy_extensions=copyall + + touch server-chain.pem + cat server-cert.pem >> server-chain.pem + cat intermediate-cert.pem >> server-chain.pem + cat ca-cert.pem >> server-chain.pem + + echo "verifying server certificates" + openssl verify -CAfile ca-cert.pem intermediate-cert.pem + openssl verify -CAfile ca-cert.pem -untrusted intermediate-cert.pem server-cert.pem + + # certificate signing requests are never used after the certs are generated + rm server.csr + rm intermediate.csr + + # serial files are generated during the signing process, but are not used + rm ca-cert.srl + rm intermediate-cert.srl + + # the private keys of the CA and the intermediate CA are never needed after + # signing + rm ca-key.pem + rm intermediate-key.pem + + # the intermediate and server certs are included in server-chain.pem, so + # the individual files can be deleted + rm intermediate-cert.pem + rm server-cert.pem + + cd .. +} + +if [[ $1 != "clean" ]] +then + # key key_size ca_key_size digest directory + cert-gen ec 384 256 SHA384 ecdsa +else + echo "cleaning certs" + rm -rf ecdsa* +fi diff --git a/tests/s2n_test.h b/tests/s2n_test.h index 24ae0dca31a..7b79981355d 100644 --- a/tests/s2n_test.h +++ b/tests/s2n_test.h @@ -61,17 +61,12 @@ int test_count; * not initialise at the start of the test. Useful for tests that e.g spawn a * number of independent childs at the start of a unit test and where you want * each child to have its own independently initialised s2n. - * - * BEGIN_TEST() prints unit test information to stdout. But this often gets - * buffered by the kernel and will then be flushed in each child spawned. The - * result is a number of repeated messages being send to stdout and, in turn, - * appear in the logs. At the moment, we think this is better than risking not - * having any printing at all. */ #define BEGIN_TEST_NO_INIT() \ do { \ test_count = 0; \ fprintf(stdout, "Running %-50s ... ", __FILE__); \ + fflush(stdout); \ EXPECT_SUCCESS_WITHOUT_COUNT(s2n_in_unit_test_set(true)); \ S2N_TEST_OPTIONALLY_ENABLE_FIPS_MODE(); \ } while(0) diff --git a/tests/saw/spec/handshake/handshake_io_lowlevel.saw b/tests/saw/spec/handshake/handshake_io_lowlevel.saw index 90b6ad2aecd..32a89af0866 100644 --- a/tests/saw/spec/handshake/handshake_io_lowlevel.saw +++ b/tests/saw/spec/handshake/handshake_io_lowlevel.saw @@ -154,8 +154,13 @@ let setup_connection_common chosen_psk_null = do { cork_val <- crucible_fresh_var "corked" (llvm_int 2); crucible_ghost_value corked cork_val; + // We assume that the client_cert_auth_type_overridden flag in s2n_connection is set. + // If that flag is not set, auth_type / "cca_type" could be determined by the config + // or just set to a default value. Since we're primarily interested in the handshake + // here and the end result is the same, just consider the connection auth_type. cca_ov <- crucible_fresh_var "cca_ov" (llvm_int 8); crucible_points_to (cca_type_ov pconn) (crucible_term cca_ov); + crucible_equal (crucible_term cca_ov) (crucible_term {{1 : [8]}}); cca <- crucible_fresh_var "cca" (llvm_int 32); crucible_points_to (cca_type pconn) (crucible_term cca); @@ -175,9 +180,6 @@ let setup_connection_common chosen_psk_null = do { config <- crucible_alloc (llvm_struct "struct.s2n_config"); crucible_points_to (conn_config pconn) config; - config_cca <- crucible_fresh_var "config_cca" (llvm_int 32); - crucible_points_to (config_cca_type config) (crucible_term config_cca); - cak <- crucible_alloc (llvm_struct "struct.s2n_cert_chain_and_key"); crucible_points_to (conn_chain_and_key pconn) cak; @@ -226,8 +228,6 @@ let setup_connection_common chosen_psk_null = do { no_client_cert <- crucible_fresh_var "no_client_cert" (llvm_int 8); - let client_cert_auth_type = {{ if cca_ov != 0 then cca else config_cca }}; - npn_negotiated <- llvm_fresh_var "npn_negotiated" (llvm_int 1); llvm_points_to_bitfield pconn "npn_negotiated" (llvm_term npn_negotiated); let npn_negotiated_bit = {{ bv1_to_bit npn_negotiated }}; @@ -246,8 +246,8 @@ let setup_connection_common chosen_psk_null = do { ((ocsp_flag == 1) && (status_size > 0)) || ((mode == 1) && (ocsp_flag == 1)) ,resume_from_cache = False - ,client_auth_flag = if mode == S2N_CLIENT then client_cert_auth_type == S2N_CERT_AUTH_REQUIRED else - if mode == S2N_SERVER then client_cert_auth_type != S2N_CERT_AUTH_NONE else False + ,client_auth_flag = if mode == S2N_CLIENT then cca == S2N_CERT_AUTH_REQUIRED else + if mode == S2N_SERVER then cca != S2N_CERT_AUTH_NONE else False ,no_client_cert = no_client_cert != zero ,actual_protocol_version = version ,early_data_state = early_data_state @@ -292,9 +292,7 @@ let s2n_allowed_to_cache_connection_spec = do { crucible_return (crucible_term {{ 0 : [32] }}); }; - -let s2n_connection_get_client_auth_type_spec = do{ - +let s2n_connection_get_client_auth_type_spec = do { pconn <- crucible_alloc_readonly (llvm_struct "struct.s2n_connection"); auth_type <- crucible_alloc (llvm_int 32); @@ -304,18 +302,28 @@ let s2n_connection_get_client_auth_type_spec = do{ config <- crucible_alloc_readonly (llvm_struct "struct.s2n_config"); crucible_points_to (conn_config pconn) config; + config_cca_ov <- llvm_fresh_var "config_cca_ov" (llvm_int 8); + crucible_points_to (crucible_field config "client_cert_auth_type_overridden") (crucible_term config_cca_ov); + config_cca <- crucible_fresh_var "config_cca" (llvm_int 32); crucible_points_to (config_cca_type config) (crucible_term config_cca); cca <- crucible_fresh_var "cca" (llvm_int 32); crucible_points_to (cca_type pconn) (crucible_term cca); + mode <- crucible_fresh_var "mode" (llvm_int 32); + crucible_points_to (conn_mode pconn) (crucible_term mode); + crucible_execute_func [pconn, auth_type]; - crucible_points_to (auth_type) (crucible_term {{if cca_ov != zero then cca else config_cca}}); + crucible_points_to (auth_type) (crucible_term {{ + if cca_ov != zero then cca else + if config_cca_ov != zero then config_cca else + if mode == S2N_CLIENT then S2N_CERT_AUTH_OPTIONAL else + S2N_CERT_AUTH_NONE + }}); crucible_return (crucible_term {{ 0 : [32] }}); - }; // Specification for s2n_conn_set_handshake_type that sets up simulation of it diff --git a/tests/saw/spec/handshake/s2n_handshake_io.cry b/tests/saw/spec/handshake/s2n_handshake_io.cry index 46fe869ddd3..91faf76f05a 100644 --- a/tests/saw/spec/handshake/s2n_handshake_io.cry +++ b/tests/saw/spec/handshake/s2n_handshake_io.cry @@ -1112,6 +1112,7 @@ S2N_CLIENT = 1 //S2N cert auth types S2N_CERT_AUTH_NONE = 0 S2N_CERT_AUTH_REQUIRED = 1 +S2N_CERT_AUTH_OPTIONAL = 2 //S2N early data states S2N_EARLY_DATA_ACCEPTED = 3 diff --git a/tests/sidetrail/working/patches/cbc.patch b/tests/sidetrail/working/patches/cbc.patch index 2af00d6b356..b47f10eb776 100644 --- a/tests/sidetrail/working/patches/cbc.patch +++ b/tests/sidetrail/working/patches/cbc.patch @@ -35,7 +35,7 @@ index 401ab760..f39cc7e2 100644 */ int s2n_verify_cbc(struct s2n_connection *conn, struct s2n_hmac_state *hmac, struct s2n_blob *decrypted) { -- uint8_t mac_digest_size; +- uint8_t mac_digest_size = 0; - POSIX_GUARD(s2n_hmac_digest_size(hmac->alg, &mac_digest_size)); + uint8_t mac_digest_size = DIGEST_SIZE; + //POSIX_GUARD(s2n_hmac_digest_size(hmac->alg, &mac_digest_size)); diff --git a/tests/sidetrail/working/stubs/s2n_ensure.h b/tests/sidetrail/working/stubs/s2n_ensure.h index 521e3e56f55..179f5a52b19 100644 --- a/tests/sidetrail/working/stubs/s2n_ensure.h +++ b/tests/sidetrail/working/stubs/s2n_ensure.h @@ -31,7 +31,10 @@ void *s2n_sidetrail_memset(void * ptr, int value, size_t num); #define __S2N_ENSURE_PRECONDITION( result ) S2N_RESULT_OK #define __S2N_ENSURE_POSTCONDITION( result ) S2N_RESULT_OK -#define __S2N_ENSURE_SAFE_MEMCPY( d , s , n , guard ) do { memcpy((d), (s), (n)); } while(0) +/* memmove isn't supported, so use memcpy instead. + * For the purposes of these proofs, there should be no useful difference. + */ +#define __S2N_ENSURE_SAFE_MEMMOVE( d , s , n , guard ) do { memcpy((d), (s), (n)); } while(0) #define __S2N_ENSURE_SAFE_MEMSET( d , c , n , guard ) \ do { \ diff --git a/tests/testlib/s2n_connection_test_utils.c b/tests/testlib/s2n_connection_test_utils.c index 546665d45fa..1da0b61e10c 100644 --- a/tests/testlib/s2n_connection_test_utils.c +++ b/tests/testlib/s2n_connection_test_utils.c @@ -36,8 +36,9 @@ int s2n_fd_set_non_blocking(int fd) static int buffer_read(void *io_context, uint8_t *buf, uint32_t len) { - struct s2n_stuffer *in_buf; - int n_read, n_avail; + struct s2n_stuffer *in_buf = NULL; + int n_read = 0, n_avail = 0; + errno = EIO; if (buf == NULL) { return 0; @@ -58,13 +59,13 @@ static int buffer_read(void *io_context, uint8_t *buf, uint32_t len) return -1; } - s2n_stuffer_read_bytes(in_buf, buf, n_read); + POSIX_GUARD(s2n_stuffer_read_bytes(in_buf, buf, n_read)); return n_read; } static int buffer_write(void *io_context, const uint8_t *buf, uint32_t len) { - struct s2n_stuffer *out; + struct s2n_stuffer *out = NULL; if (buf == NULL) { return 0; diff --git a/tests/testlib/s2n_key_schedule_testlib.c b/tests/testlib/s2n_key_schedule_testlib.c index 4041081bd9e..273f8b8b3cc 100644 --- a/tests/testlib/s2n_key_schedule_testlib.c +++ b/tests/testlib/s2n_key_schedule_testlib.c @@ -18,10 +18,7 @@ S2N_RESULT s2n_connection_set_test_transcript_hash(struct s2n_connection *conn, message_type_t message_type, const struct s2n_blob *digest) { - conn->handshake.handshake_type = conn->handshake.handshake_type & NEGOTIATED; - while (s2n_conn_get_current_message_type(conn) != message_type) { - conn->handshake.message_number++; - } + RESULT_GUARD(s2n_connection_set_test_message_type(conn, message_type)); RESULT_CHECKED_MEMCPY(conn->handshake.hashes->transcript_hash_digest, digest->data, digest->size); return S2N_RESULT_OK; @@ -59,3 +56,23 @@ S2N_RESULT s2n_connection_set_test_master_secret(struct s2n_connection *conn, conn->secrets.extract_secret_type = S2N_MASTER_SECRET; return S2N_RESULT_OK; } + +/* This function will iterate over all rows and columns of the handshake state + * machine until it finds a valid (handshake_type, handshake_number) such that + * the active message is `expected_message_type`. If callers need to depend on a + * specific `message_number` or `handshake_type` this function should not be + * used. + */ +S2N_RESULT s2n_connection_set_test_message_type(struct s2n_connection *conn, message_type_t expected_message_type) +{ + for (uint32_t handshake = 0; handshake < S2N_HANDSHAKES_COUNT; handshake++) { + for (int message = 0; message < S2N_MAX_HANDSHAKE_LENGTH; message++) { + conn->handshake.handshake_type = handshake; + conn->handshake.message_number = message; + if (s2n_conn_get_current_message_type(conn) == expected_message_type) { + return S2N_RESULT_OK; + } + } + } + RESULT_BAIL(S2N_ERR_HANDSHAKE_UNREACHABLE); +} diff --git a/tests/testlib/s2n_stuffer_hex.c b/tests/testlib/s2n_stuffer_hex.c index 18d31ec993d..c09f4fe584f 100644 --- a/tests/testlib/s2n_stuffer_hex.c +++ b/tests/testlib/s2n_stuffer_hex.c @@ -59,7 +59,7 @@ int s2n_stuffer_read_hex(struct s2n_stuffer *stuffer, struct s2n_stuffer *out, u POSIX_ENSURE_GTE(s2n_stuffer_space_remaining(out), n); for (size_t i = 0; i < n; i++) { - uint8_t c; + uint8_t c = 0; POSIX_GUARD(s2n_stuffer_read_uint8_hex(stuffer, &c)); POSIX_GUARD(s2n_stuffer_write_uint8(out, c)); } @@ -72,7 +72,7 @@ int s2n_stuffer_write_hex(struct s2n_stuffer *stuffer, struct s2n_stuffer *in, u POSIX_ENSURE_GTE(s2n_stuffer_space_remaining(stuffer), n * 2); for (size_t i = 0; i < n; i++) { - uint8_t c; + uint8_t c = 0; POSIX_GUARD(s2n_stuffer_read_uint8(in, &c)); POSIX_GUARD(s2n_stuffer_write_uint8_hex(stuffer, c)); } @@ -87,7 +87,7 @@ int s2n_stuffer_read_uint64_hex(struct s2n_stuffer *stuffer, uint64_t *u) int s2n_stuffer_read_uint32_hex(struct s2n_stuffer *stuffer, uint32_t *u) { - uint64_t u64; + uint64_t u64 = 0; POSIX_GUARD(s2n_stuffer_read_n_bits_hex(stuffer, 32, &u64)); @@ -98,7 +98,7 @@ int s2n_stuffer_read_uint32_hex(struct s2n_stuffer *stuffer, uint32_t *u) int s2n_stuffer_read_uint16_hex(struct s2n_stuffer *stuffer, uint16_t *u) { - uint64_t u64; + uint64_t u64 = 0; POSIX_GUARD(s2n_stuffer_read_n_bits_hex(stuffer, 16, &u64)); @@ -109,7 +109,7 @@ int s2n_stuffer_read_uint16_hex(struct s2n_stuffer *stuffer, uint16_t *u) int s2n_stuffer_read_uint8_hex(struct s2n_stuffer *stuffer, uint8_t *u) { - uint64_t u64; + uint64_t u64 = 0; POSIX_GUARD(s2n_stuffer_read_n_bits_hex(stuffer, 8, &u64)); diff --git a/tests/testlib/s2n_test_certs.c b/tests/testlib/s2n_test_certs.c index 03b46dc7171..926796f6e8e 100644 --- a/tests/testlib/s2n_test_certs.c +++ b/tests/testlib/s2n_test_certs.c @@ -63,6 +63,14 @@ int s2n_test_cert_permutation_get_ca_path(char *output, const char *type, const return S2N_SUCCESS; } +S2N_RESULT s2n_test_cert_permutation_get_server_chain_path(char *output, const char *type, + const char *signature, const char *size, const char *digest) +{ + sprintf(output, "../pems/permutations/%s_%s_%s_%s/server-chain.pem", type, signature, size, + digest); + return S2N_RESULT_OK; +} + int s2n_read_test_pem(const char *pem_path, char *pem_out, long int max_size) { uint32_t pem_len = 0; diff --git a/tests/testlib/s2n_test_server_client.c b/tests/testlib/s2n_test_server_client.c index 0e83e208d24..f4a04e5cdb2 100644 --- a/tests/testlib/s2n_test_server_client.c +++ b/tests/testlib/s2n_test_server_client.c @@ -45,10 +45,9 @@ int s2n_negotiate_test_server_and_client(struct s2n_connection *server_conn, str { bool server_done = false, client_done = false; s2n_blocked_status blocked = S2N_NOT_BLOCKED; - bool rc = false; do { - rc = (s2n_negotiate(client_conn, &blocked) >= S2N_SUCCESS); + bool rc = (s2n_negotiate(client_conn, &blocked) >= S2N_SUCCESS); POSIX_GUARD_RESULT(s2n_validate_negotiate_result(rc, server_done, &client_done)); rc = (s2n_negotiate(server_conn, &blocked) >= S2N_SUCCESS); @@ -105,10 +104,9 @@ S2N_RESULT s2n_negotiate_test_server_and_client_until_message(struct s2n_connect { bool server_done = false, client_done = false; s2n_blocked_status blocked = S2N_NOT_BLOCKED; - bool rc = false; do { - rc = s2n_result_is_ok(s2n_negotiate_until_message(client_conn, &blocked, message_type)); + bool rc = s2n_result_is_ok(s2n_negotiate_until_message(client_conn, &blocked, message_type)); RESULT_GUARD(s2n_validate_negotiate_result(rc, server_done, &client_done)); rc = s2n_result_is_ok(s2n_negotiate_until_message(server_conn, &blocked, message_type)); diff --git a/tests/testlib/s2n_testlib.h b/tests/testlib/s2n_testlib.h index ff02ef95cb1..113cd2e1b5b 100644 --- a/tests/testlib/s2n_testlib.h +++ b/tests/testlib/s2n_testlib.h @@ -76,6 +76,7 @@ int s2n_connection_allow_all_response_extensions(struct s2n_connection *conn); int s2n_connection_set_all_protocol_versions(struct s2n_connection *conn, uint8_t version); S2N_RESULT s2n_set_all_mutually_supported_groups(struct s2n_connection *conn); S2N_RESULT s2n_skip_handshake(struct s2n_connection *conn); +S2N_RESULT s2n_connection_set_test_message_type(struct s2n_connection *conn, message_type_t expected_message_type); S2N_RESULT s2n_connection_set_secrets(struct s2n_connection *conn); @@ -186,6 +187,11 @@ S2N_RESULT s2n_connection_set_test_master_secret(struct s2n_connection *conn, co * that our certificate validation code does not fail a root certificate signed with SHA-1. */ #define S2N_SHA1_ROOT_SIGNATURE_CA_CERT "../pems/rsa_1024_sha1_CA_cert.pem" +/* The leaf and intermediate have larger key sizes than the root. */ +#define S2N_MIXED_CHAIN_CERTS "../pems/mixed_chains/ecdsa/server-chain.pem" +#define S2N_MIXED_CHAIN_KEY "../pems/mixed_chains/ecdsa/server-key.pem" +#define S2N_MIXED_CHAIN_CA "../pems/mixed_chains/ecdsa/ca-cert.pem" + #define S2N_DEFAULT_TEST_CERT_CHAIN S2N_RSA_2048_PKCS1_CERT_CHAIN #define S2N_DEFAULT_TEST_PRIVATE_KEY S2N_RSA_2048_PKCS1_KEY @@ -213,6 +219,8 @@ int s2n_test_cert_permutation_load_server_chain(struct s2n_cert_chain_and_key ** int s2n_test_cert_permutation_get_ca_path(char *output, const char *type, const char *siganture, const char *size, const char *digest); +S2N_RESULT s2n_test_cert_permutation_get_server_chain_path(char *output, const char *type, + const char *siganture, const char *size, const char *digest); S2N_RESULT s2n_test_cert_chain_data_from_pem(struct s2n_connection *conn, const char *pem_path, struct s2n_stuffer *cert_chain_stuffer); diff --git a/tests/unit/Makefile b/tests/unit/Makefile index d25d7fe865a..b4d4feaa8f5 100644 --- a/tests/unit/Makefile +++ b/tests/unit/Makefile @@ -60,7 +60,17 @@ $(VALGRIND_TESTS):: @DYLD_LIBRARY_PATH="$(LIBCRYPTO_ROOT)/lib:$$DYLD_LIBRARY_PATH" \ LD_LIBRARY_PATH="$(LIBCRYPTO_ROOT)/lib:$$LD_LIBRARY_PATH" \ S2N_VALGRIND=1 \ - valgrind --leak-check=full --run-libc-freeres=no -q --error-exitcode=9 --gen-suppressions=all --log-fd=2 --num-callers=40 --leak-resolution=high --undef-value-errors=no --trace-children=yes --suppressions=valgrind.suppressions \ + valgrind \ + --leak-check=full \ + --leak-resolution=high \ + --trace-children=yes \ + --run-libc-freeres=no \ + -q --error-exitcode=123 \ + --error-limit=no \ + --num-callers=40 \ + --undef-value-errors=no \ + --log-fd=2 \ + --suppressions=valgrind.suppressions \ ./$(@:.valgrind=) $(PEDANTIC_VALGRIND_TESTS):: @@ -68,7 +78,18 @@ $(PEDANTIC_VALGRIND_TESTS):: @DYLD_LIBRARY_PATH="$(LIBCRYPTO_ROOT)/lib:$$DYLD_LIBRARY_PATH" \ LD_LIBRARY_PATH="$(LIBCRYPTO_ROOT)/lib:$$LD_LIBRARY_PATH" \ S2N_VALGRIND=1 \ - valgrind --leak-check=full --show-leak-kinds=all --errors-for-leak-kinds=all --run-libc-freeres=yes -q --error-exitcode=9 --gen-suppressions=all --num-callers=40 --leak-resolution=high --undef-value-errors=no --trace-children=yes --suppressions=valgrind.suppressions \ + valgrind \ + --leak-check=full \ + --leak-resolution=high \ + --trace-children=yes \ + --run-libc-freeres=yes \ + -q --error-exitcode=123 \ + --error-limit=no \ + --num-callers=40 \ + --undef-value-errors=no \ + --show-leak-kinds=all \ + --errors-for-leak-kinds=all \ + --suppressions=valgrind.suppressions \ ./$(@:.pedantic_valgrind=) .PHONY : valgrind diff --git a/tests/unit/s2n_3des_test.c b/tests/unit/s2n_3des_test.c index c28d2a786f7..a7ccca4c904 100644 --- a/tests/unit/s2n_3des_test.c +++ b/tests/unit/s2n_3des_test.c @@ -29,7 +29,7 @@ int main(int argc, char **argv) { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; uint8_t mac_key[] = "sample mac key"; uint8_t des3_key[] = "12345678901234567890123"; struct s2n_blob des3 = { 0 }; @@ -61,7 +61,7 @@ int main(int argc, char **argv) for (int i = 0; i <= S2N_DEFAULT_FRAGMENT_LENGTH + 1; i++) { struct s2n_blob in = { 0 }; EXPECT_SUCCESS(s2n_blob_init(&in, random_data, i)); - int bytes_written; + int bytes_written = 0; EXPECT_SUCCESS(s2n_stuffer_wipe(&conn->out)); @@ -96,8 +96,8 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_stuffer_copy(&conn->out, &conn->in, s2n_stuffer_data_available(&conn->out))); /* Let's decrypt it */ - uint8_t content_type; - uint16_t fragment_length; + uint8_t content_type = 0; + uint16_t fragment_length = 0; EXPECT_SUCCESS(s2n_record_header_parse(conn, &content_type, &fragment_length)); EXPECT_SUCCESS(s2n_record_parse(conn)); EXPECT_EQUAL(content_type, TLS_APPLICATION_DATA); diff --git a/tests/unit/s2n_aead_aes_test.c b/tests/unit/s2n_aead_aes_test.c index 84ffe8a5a7f..ad2347f9a2d 100644 --- a/tests/unit/s2n_aead_aes_test.c +++ b/tests/unit/s2n_aead_aes_test.c @@ -47,7 +47,7 @@ static int setup_server_keys(struct s2n_connection *server_conn, struct s2n_blob int main(int argc, char **argv) { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; uint8_t random_data[S2N_SMALL_FRAGMENT_LENGTH + 1]; uint8_t aes128_key[] = "123456789012345"; uint8_t aes256_key[] = "1234567890123456789012345678901"; @@ -76,7 +76,7 @@ int main(int argc, char **argv) for (size_t i = 0; i <= max_fragment + 1; i++) { struct s2n_blob in = { 0 }; EXPECT_SUCCESS(s2n_blob_init(&in, random_data, i)); - int bytes_written; + int bytes_written = 0; /* TLS packet on the wire using AES-GCM: * https://tools.ietf.org/html/rfc5246#section-6.2.3.3 @@ -135,8 +135,8 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_stuffer_copy(&conn->out, &conn->in, s2n_stuffer_data_available(&conn->out))); /* Let's decrypt it */ - uint8_t content_type; - uint16_t fragment_length; + uint8_t content_type = 0; + uint16_t fragment_length = 0; EXPECT_SUCCESS(s2n_record_header_parse(conn, &content_type, &fragment_length)); EXPECT_SUCCESS(s2n_record_parse(conn)); EXPECT_EQUAL(content_type, TLS_APPLICATION_DATA); @@ -274,7 +274,7 @@ int main(int argc, char **argv) for (size_t i = 0; i <= max_fragment + 1; i++) { struct s2n_blob in = { 0 }; EXPECT_SUCCESS(s2n_blob_init(&in, random_data, i)); - int bytes_written; + int bytes_written = 0; EXPECT_SUCCESS(s2n_connection_wipe(conn)); /* Set prefer low latency for S2N_SMALL_FRAGMENT_LENGTH for */ @@ -323,8 +323,8 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_stuffer_copy(&conn->out, &conn->in, s2n_stuffer_data_available(&conn->out))); /* Let's decrypt it */ - uint8_t content_type; - uint16_t fragment_length; + uint8_t content_type = 0; + uint16_t fragment_length = 0; EXPECT_SUCCESS(s2n_record_header_parse(conn, &content_type, &fragment_length)); EXPECT_SUCCESS(s2n_record_parse(conn)); EXPECT_EQUAL(content_type, TLS_APPLICATION_DATA); diff --git a/tests/unit/s2n_aead_chacha20_poly1305_test.c b/tests/unit/s2n_aead_chacha20_poly1305_test.c index 1043b814d29..5f4aaf667cc 100644 --- a/tests/unit/s2n_aead_chacha20_poly1305_test.c +++ b/tests/unit/s2n_aead_chacha20_poly1305_test.c @@ -48,7 +48,7 @@ static int setup_server_keys(struct s2n_connection *server_conn, struct s2n_blob int main(int argc, char **argv) { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; uint8_t random_data[S2N_SMALL_FRAGMENT_LENGTH + 1]; uint8_t chacha20_poly1305_key_data[] = "1234567890123456789012345678901"; struct s2n_blob chacha20_poly1305_key = { 0 }; @@ -79,7 +79,7 @@ int main(int argc, char **argv) for (size_t i = 0; i <= max_fragment + 1; i++) { struct s2n_blob in = { 0 }; EXPECT_SUCCESS(s2n_blob_init(&in, random_data, i)); - int bytes_written; + int bytes_written = 0; /* TLS packet on the wire using ChaCha20-Poly1305: * https://tools.ietf.org/html/rfc5246#section-6.2.3.3 @@ -135,8 +135,8 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_stuffer_copy(&conn->out, &conn->in, s2n_stuffer_data_available(&conn->out))); /* Let's decrypt it */ - uint8_t content_type; - uint16_t fragment_length; + uint8_t content_type = 0; + uint16_t fragment_length = 0; EXPECT_SUCCESS(s2n_record_header_parse(conn, &content_type, &fragment_length)); EXPECT_SUCCESS(s2n_record_parse(conn)); EXPECT_EQUAL(content_type, TLS_APPLICATION_DATA); diff --git a/tests/unit/s2n_aes_sha_composite_test.c b/tests/unit/s2n_aes_sha_composite_test.c index e6dd9e01358..a8b8d5b6aaf 100644 --- a/tests/unit/s2n_aes_sha_composite_test.c +++ b/tests/unit/s2n_aes_sha_composite_test.c @@ -47,7 +47,7 @@ static int ensure_explicit_iv_is_unique(uint8_t existing_explicit_ivs[S2N_DEFAUL int main(int argc, char **argv) { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; uint8_t random_data[S2N_DEFAULT_FRAGMENT_LENGTH + 1]; uint8_t mac_key_sha[20] = "server key shaserve"; uint8_t mac_key_sha256[32] = "server key sha256server key sha"; @@ -93,7 +93,7 @@ int main(int argc, char **argv) for (size_t i = 0; i <= max_aligned_fragment + 1; i++) { struct s2n_blob in = { 0 }; EXPECT_SUCCESS(s2n_blob_init(&in, random_data, i)); - int bytes_written; + int bytes_written = 0; EXPECT_SUCCESS(s2n_connection_wipe(conn)); @@ -105,7 +105,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_stuffer_wipe(&conn->out)); conn->actual_protocol_version = proto_versions[j]; - int explicit_iv_len; + int explicit_iv_len = 0; if (conn->actual_protocol_version > S2N_TLS10) { explicit_iv_len = 16; } else { @@ -151,8 +151,8 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_stuffer_copy(&conn->out, &conn->in, s2n_stuffer_data_available(&conn->out))); /* Let's decrypt it */ - uint8_t content_type; - uint16_t fragment_length; + uint8_t content_type = 0; + uint16_t fragment_length = 0; EXPECT_SUCCESS(s2n_record_header_parse(conn, &content_type, &fragment_length)); EXPECT_SUCCESS(s2n_record_parse(conn)); EXPECT_EQUAL(content_type, TLS_APPLICATION_DATA); @@ -169,7 +169,7 @@ int main(int argc, char **argv) for (int i = 0; i <= max_aligned_fragment + 1; i++) { struct s2n_blob in = { 0 }; EXPECT_SUCCESS(s2n_blob_init(&in, random_data, i)); - int bytes_written; + int bytes_written = 0; EXPECT_SUCCESS(s2n_connection_wipe(conn)); @@ -181,7 +181,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_stuffer_wipe(&conn->out)); conn->actual_protocol_version = proto_versions[j]; - int explicit_iv_len; + int explicit_iv_len = 0; if (conn->actual_protocol_version > S2N_TLS10) { explicit_iv_len = 16; } else { @@ -227,8 +227,8 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_stuffer_copy(&conn->out, &conn->in, s2n_stuffer_data_available(&conn->out))); /* Let's decrypt it */ - uint8_t content_type; - uint16_t fragment_length; + uint8_t content_type = 0; + uint16_t fragment_length = 0; EXPECT_SUCCESS(s2n_record_header_parse(conn, &content_type, &fragment_length)); EXPECT_SUCCESS(s2n_record_parse(conn)); EXPECT_EQUAL(content_type, TLS_APPLICATION_DATA); @@ -245,7 +245,7 @@ int main(int argc, char **argv) for (int i = 0; i < max_aligned_fragment + 1; i++) { struct s2n_blob in = { 0 }; EXPECT_SUCCESS(s2n_blob_init(&in, random_data, i)); - int bytes_written; + int bytes_written = 0; EXPECT_SUCCESS(s2n_connection_wipe(conn)); @@ -257,7 +257,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_stuffer_wipe(&conn->out)); conn->actual_protocol_version = proto_versions[j]; - int explicit_iv_len; + int explicit_iv_len = 0; if (conn->actual_protocol_version > S2N_TLS10) { explicit_iv_len = 16; } else { @@ -303,8 +303,8 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_stuffer_copy(&conn->out, &conn->in, s2n_stuffer_data_available(&conn->out))); /* Let's decrypt it */ - uint8_t content_type; - uint16_t fragment_length; + uint8_t content_type = 0; + uint16_t fragment_length = 0; EXPECT_SUCCESS(s2n_record_header_parse(conn, &content_type, &fragment_length)); EXPECT_SUCCESS(s2n_record_parse(conn)); EXPECT_EQUAL(content_type, TLS_APPLICATION_DATA); @@ -321,7 +321,7 @@ int main(int argc, char **argv) for (int i = 0; i <= max_aligned_fragment + 1; i++) { struct s2n_blob in = { 0 }; EXPECT_SUCCESS(s2n_blob_init(&in, random_data, i)); - int bytes_written; + int bytes_written = 0; EXPECT_SUCCESS(s2n_connection_wipe(conn)); @@ -333,7 +333,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_stuffer_wipe(&conn->out)); conn->actual_protocol_version = proto_versions[j]; - int explicit_iv_len; + int explicit_iv_len = 0; if (conn->actual_protocol_version > S2N_TLS10) { explicit_iv_len = 16; } else { @@ -379,8 +379,8 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_stuffer_copy(&conn->out, &conn->in, s2n_stuffer_data_available(&conn->out))); /* Let's decrypt it */ - uint8_t content_type; - uint16_t fragment_length; + uint8_t content_type = 0; + uint16_t fragment_length = 0; EXPECT_SUCCESS(s2n_record_header_parse(conn, &content_type, &fragment_length)); EXPECT_SUCCESS(s2n_record_parse(conn)); EXPECT_EQUAL(content_type, TLS_APPLICATION_DATA); diff --git a/tests/unit/s2n_aes_test.c b/tests/unit/s2n_aes_test.c index 1005bbb3a7b..9585fdf5de7 100644 --- a/tests/unit/s2n_aes_test.c +++ b/tests/unit/s2n_aes_test.c @@ -29,7 +29,7 @@ int main(int argc, char **argv) { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; uint8_t mac_key[] = "sample mac key"; uint8_t aes128_key[] = "123456789012345"; uint8_t aes256_key[] = "1234567890123456789012345678901"; @@ -64,7 +64,7 @@ int main(int argc, char **argv) for (size_t i = 0; i <= S2N_DEFAULT_FRAGMENT_LENGTH + 1; i++) { struct s2n_blob in = { 0 }; EXPECT_SUCCESS(s2n_blob_init(&in, random_data, i)); - int bytes_written; + int bytes_written = 0; EXPECT_SUCCESS(s2n_stuffer_wipe(&conn->out)); @@ -99,8 +99,8 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_stuffer_copy(&conn->out, &conn->in, s2n_stuffer_data_available(&conn->out))); /* Let's decrypt it */ - uint8_t content_type; - uint16_t fragment_length; + uint8_t content_type = 0; + uint16_t fragment_length = 0; EXPECT_SUCCESS(s2n_record_header_parse(conn, &content_type, &fragment_length)); EXPECT_SUCCESS(s2n_record_parse(conn)); EXPECT_EQUAL(content_type, TLS_APPLICATION_DATA); @@ -130,7 +130,7 @@ int main(int argc, char **argv) for (size_t i = 0; i <= S2N_DEFAULT_FRAGMENT_LENGTH + 1; i++) { struct s2n_blob in = { 0 }; EXPECT_SUCCESS(s2n_blob_init(&in, random_data, i)); - int bytes_written; + int bytes_written = 0; EXPECT_SUCCESS(s2n_stuffer_wipe(&conn->out)); @@ -165,8 +165,8 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_stuffer_copy(&conn->out, &conn->in, s2n_stuffer_data_available(&conn->out))); /* Let's decrypt it */ - uint8_t content_type; - uint16_t fragment_length; + uint8_t content_type = 0; + uint16_t fragment_length = 0; EXPECT_SUCCESS(s2n_record_header_parse(conn, &content_type, &fragment_length)); EXPECT_SUCCESS(s2n_record_parse(conn)); EXPECT_EQUAL(content_type, TLS_APPLICATION_DATA); diff --git a/tests/unit/s2n_alerts_test.c b/tests/unit/s2n_alerts_test.c index 9131ee57a1c..cf2eeb3d992 100644 --- a/tests/unit/s2n_alerts_test.c +++ b/tests/unit/s2n_alerts_test.c @@ -53,9 +53,8 @@ int main(int argc, char **argv) /* Test S2N_ERR_T_PROTO */ { /* Test all protocol errors are handled */ - int ret_val; for (size_t i = S2N_ERR_T_PROTO_START; i < S2N_ERR_T_PROTO_END; i++) { - ret_val = s2n_error_get_alert(i, &alert); + int ret_val = s2n_error_get_alert(i, &alert); if (ret_val != S2N_SUCCESS && s2n_errno == S2N_ERR_UNIMPLEMENTED) { fprintf(stdout, "\n\nNo alert mapping for protocol error %s\n\n", s2n_strerror_name(i)); FAIL_MSG("Missing alert mapping for protocol error."); @@ -102,7 +101,7 @@ int main(int argc, char **argv) /* Don't mark close_notify_received = true if we receive an alert other than close_notify alert */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); /* Verify state prior to alert */ @@ -122,7 +121,7 @@ int main(int argc, char **argv) /* Mark close_notify_received = true if we receive a close_notify alert */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); /* Verify state prior to alert */ @@ -146,10 +145,10 @@ int main(int argc, char **argv) /* Fails if alerts not supported */ if (s2n_is_tls13_fully_supported()) { - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); @@ -183,7 +182,7 @@ int main(int argc, char **argv) /* Warnings treated as errors by default in TLS1.2 */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_EQUAL(conn->config->alert_behavior, S2N_ALERT_FAIL_ON_WARNINGS); conn->actual_protocol_version = S2N_TLS12; @@ -198,7 +197,7 @@ int main(int argc, char **argv) /* Warnings treated as errors by default in TLS1.3 */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_EQUAL(conn->config->alert_behavior, S2N_ALERT_FAIL_ON_WARNINGS); conn->actual_protocol_version = S2N_TLS13; @@ -213,11 +212,11 @@ int main(int argc, char **argv) /* Warnings ignored in TLS1.2 if alert_behavior == S2N_ALERT_IGNORE_WARNINGS */ { - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_set_alert_behavior(config, S2N_ALERT_IGNORE_WARNINGS)); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); conn->actual_protocol_version = S2N_TLS12; @@ -233,11 +232,11 @@ int main(int argc, char **argv) /* Warnings treated as errors in TLS1.3 if alert_behavior == S2N_ALERT_IGNORE_WARNINGS */ { - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_set_alert_behavior(config, S2N_ALERT_IGNORE_WARNINGS)); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); conn->actual_protocol_version = S2N_TLS13; @@ -253,10 +252,10 @@ int main(int argc, char **argv) /* user_canceled ignored in TLS1.3 by default */ { - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); conn->actual_protocol_version = S2N_TLS13; diff --git a/tests/unit/s2n_async_pkey_test.c b/tests/unit/s2n_async_pkey_test.c index 2b8cc041ac6..c2cefd6dc6d 100644 --- a/tests/unit/s2n_async_pkey_test.c +++ b/tests/unit/s2n_async_pkey_test.c @@ -403,7 +403,7 @@ int main(int argc, char **argv) /* Test: apply while invoking callback */ { - struct s2n_config *server_config, *client_config; + struct s2n_config *server_config = NULL, *client_config = NULL; EXPECT_NOT_NULL(server_config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(server_config, chain_and_key)); EXPECT_SUCCESS(s2n_config_add_dhparams(server_config, dhparams_pem)); @@ -444,7 +444,7 @@ int main(int argc, char **argv) /* Test: wipe connection and then perform and apply pkey op */ { - struct s2n_config *server_config, *client_config; + struct s2n_config *server_config = NULL, *client_config = NULL; EXPECT_NOT_NULL(server_config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(server_config, chain_and_key)); EXPECT_SUCCESS(s2n_config_add_dhparams(server_config, dhparams_pem)); @@ -485,7 +485,7 @@ int main(int argc, char **argv) /* Test: free the pkey op and try s2n_negotiate again */ { - struct s2n_config *server_config, *client_config; + struct s2n_config *server_config = NULL, *client_config = NULL; EXPECT_NOT_NULL(server_config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(server_config, chain_and_key)); EXPECT_SUCCESS(s2n_config_add_dhparams(server_config, dhparams_pem)); @@ -527,7 +527,7 @@ int main(int argc, char **argv) /* Test: Apply invalid signature */ { - struct s2n_config *server_config, *client_config; + struct s2n_config *server_config = NULL, *client_config = NULL; EXPECT_NOT_NULL(server_config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(server_config, chain_and_key)); EXPECT_SUCCESS(s2n_config_add_dhparams(server_config, dhparams_pem)); diff --git a/tests/unit/s2n_auth_selection_test.c b/tests/unit/s2n_auth_selection_test.c index 96263b754d5..79c5772ca15 100644 --- a/tests/unit/s2n_auth_selection_test.c +++ b/tests/unit/s2n_auth_selection_test.c @@ -47,7 +47,7 @@ static int s2n_test_auth_combo(struct s2n_connection *conn, struct s2n_cipher_suite *cipher_suite, const struct s2n_signature_scheme *sig_scheme, struct s2n_cert_chain_and_key *expected_cert_chain) { - struct s2n_cert_chain_and_key *actual_cert_chain; + struct s2n_cert_chain_and_key *actual_cert_chain = NULL; POSIX_GUARD(s2n_is_cipher_suite_valid_for_auth(conn, cipher_suite)); conn->secure->cipher_suite = cipher_suite; @@ -65,11 +65,11 @@ int main(int argc, char **argv) BEGIN_TEST(); EXPECT_SUCCESS(s2n_disable_tls13_in_test()); - struct s2n_cert_chain_and_key *rsa_cert_chain; + struct s2n_cert_chain_and_key *rsa_cert_chain = NULL; EXPECT_SUCCESS(s2n_test_cert_chain_and_key_new(&rsa_cert_chain, S2N_RSA_2048_PKCS1_CERT_CHAIN, S2N_RSA_2048_PKCS1_KEY)); - struct s2n_cert_chain_and_key *ecdsa_cert_chain; + struct s2n_cert_chain_and_key *ecdsa_cert_chain = NULL; EXPECT_SUCCESS(s2n_test_cert_chain_and_key_new(&ecdsa_cert_chain, S2N_ECDSA_P384_PKCS1_CERT_CHAIN, S2N_ECDSA_P384_PKCS1_KEY)); @@ -181,7 +181,7 @@ int main(int argc, char **argv) /* Test: If signature algorithm specifies curve, must match cert curve */ { - struct s2n_cert_chain_and_key *ecdsa_cert_chain_for_other_curve; + struct s2n_cert_chain_and_key *ecdsa_cert_chain_for_other_curve = NULL; EXPECT_SUCCESS(s2n_test_cert_chain_and_key_new(&ecdsa_cert_chain_for_other_curve, S2N_ECDSA_P256_PKCS1_CERT_CHAIN, S2N_ECDSA_P256_PKCS1_KEY)); @@ -298,7 +298,7 @@ int main(int argc, char **argv) /* s2n_select_certs_for_server_auth */ { struct s2n_connection *conn = s2n_connection_new(S2N_SERVER); - struct s2n_cert_chain_and_key *chosen_certs; + struct s2n_cert_chain_and_key *chosen_certs = NULL; /* Requested cert chain exists */ s2n_connection_set_config(conn, all_certs_config); diff --git a/tests/unit/s2n_build_test.c b/tests/unit/s2n_build_test.c index 7e707954df4..e7f40949d15 100644 --- a/tests/unit/s2n_build_test.c +++ b/tests/unit/s2n_build_test.c @@ -23,6 +23,8 @@ #include "crypto/s2n_openssl.h" #include "s2n_test.h" +#define MAX_LIBCRYPTO_NAME_LEN 100 + int tokenize_s2n_libcrypto(char *s2n_libcrypto, char **name, char **version) { if (name == NULL || version == NULL || s2n_libcrypto == NULL) { @@ -44,6 +46,19 @@ int tokenize_s2n_libcrypto(char *s2n_libcrypto, char **name, char **version) return S2N_SUCCESS; } +S2N_RESULT s2n_test_lowercase_copy(const char *input, char *destination, size_t max_len) +{ + RESULT_ENSURE_REF(input); + RESULT_ENSURE_REF(destination); + + for (size_t i = 0; i < strlen(input); i++) { + RESULT_ENSURE_LT(i, max_len); + destination[i] = tolower(input[i]); + } + + return S2N_RESULT_OK; +} + int main() { BEGIN_TEST(); @@ -69,8 +84,21 @@ int main() END_TEST(); } - char s2n_libcrypto_copy[100] = { 0 }; - strncpy(s2n_libcrypto_copy, s2n_libcrypto, 99); + /* Ensure that FIPS mode is enabled when linked to AWS-LC-FIPS, and disabled when linked to AWS-LC */ + if (strstr(s2n_libcrypto, "awslc") != NULL) { + s2n_fips_mode fips_mode = S2N_FIPS_MODE_DISABLED; + EXPECT_SUCCESS(s2n_get_fips_mode(&fips_mode)); + + if (strstr(s2n_libcrypto, "fips") != NULL) { + EXPECT_EQUAL(fips_mode, S2N_FIPS_MODE_ENABLED); + } else { + EXPECT_EQUAL(fips_mode, S2N_FIPS_MODE_DISABLED); + } + } + + char s2n_libcrypto_copy[MAX_LIBCRYPTO_NAME_LEN] = { 0 }; + EXPECT_TRUE(strlen(s2n_libcrypto) < MAX_LIBCRYPTO_NAME_LEN); + EXPECT_OK(s2n_test_lowercase_copy(s2n_libcrypto, &s2n_libcrypto_copy[0], s2n_array_len(s2n_libcrypto_copy))); char *name = NULL; char *version = NULL; EXPECT_SUCCESS(tokenize_s2n_libcrypto(s2n_libcrypto_copy, &name, &version)); @@ -83,8 +111,9 @@ int main() EXPECT_TRUE(s2n_libcrypto_is_awslc()); } else { /* Any other library should have the name of the library (modulo case) in its version string. */ - const char *ssleay_version_text = SSLeay_version(SSLEAY_VERSION); - EXPECT_NOT_NULL(strcasestr(ssleay_version_text, name)); + char ssleay_version_text[MAX_LIBCRYPTO_NAME_LEN] = { 0 }; + EXPECT_OK(s2n_test_lowercase_copy(SSLeay_version(SSLEAY_VERSION), &ssleay_version_text[0], MAX_LIBCRYPTO_NAME_LEN)); + EXPECT_NOT_NULL(strstr(ssleay_version_text, name)); } }; diff --git a/tests/unit/s2n_cert_chain_and_key_test.c b/tests/unit/s2n_cert_chain_and_key_test.c index f299ebc7b95..ae6ca42792e 100644 --- a/tests/unit/s2n_cert_chain_and_key_test.c +++ b/tests/unit/s2n_cert_chain_and_key_test.c @@ -45,14 +45,14 @@ static struct s2n_cert_chain_and_key *test_cert_tiebreak_cb(struct s2n_cert_chai int main(int argc, char **argv) { - struct s2n_config *server_config; - struct s2n_config *client_config; - struct s2n_connection *server_conn; - struct s2n_connection *client_conn; - char *alligator_cert; - char *alligator_key; - char *cert_chain; - char *private_key; + struct s2n_config *server_config = NULL; + struct s2n_config *client_config = NULL; + struct s2n_connection *server_conn = NULL; + struct s2n_connection *client_conn = NULL; + char *alligator_cert = NULL; + char *alligator_key = NULL; + char *cert_chain = NULL; + char *private_key = NULL; BEGIN_TEST(); EXPECT_SUCCESS(s2n_disable_tls13_in_test()); @@ -75,7 +75,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_config_disable_x509_verification(client_config)); /* Create config with s2n_config_add_cert_chain_and_key_to_store API with multiple certs */ { - struct s2n_cert_chain_and_key *default_cert; + struct s2n_cert_chain_and_key *default_cert = NULL; /* Associated data to attach to each certificate to use in the tiebreak callback. */ int tiebreak_priorites[NUM_TIED_CERTS] = { 0 }; /* Collection of certs with the same domain name that need to have ties resolved. */ @@ -188,6 +188,34 @@ int main(int argc, char **argv) }; }; + /* s2n_cert_chain_and_key_load_pem */ + { + /* when loading a chain, all certs have a info associated with them and root is self-signed */ + { + DEFER_CLEANUP(struct s2n_cert_chain_and_key *chain = NULL, + s2n_cert_chain_and_key_ptr_free); + EXPECT_SUCCESS(s2n_test_cert_permutation_load_server_chain(&chain, "ec", "ecdsa", + "p384", "sha256")); + struct s2n_cert *leaf = chain->cert_chain->head; + EXPECT_EQUAL(leaf->info.self_signed, false); + EXPECT_EQUAL(leaf->info.signature_nid, NID_ecdsa_with_SHA256); + EXPECT_EQUAL(leaf->info.signature_digest_nid, NID_sha256); + + struct s2n_cert *intermediate = leaf->next; + EXPECT_NOT_NULL(intermediate); + EXPECT_EQUAL(intermediate->info.self_signed, false); + EXPECT_EQUAL(intermediate->info.signature_nid, NID_ecdsa_with_SHA256); + EXPECT_EQUAL(intermediate->info.signature_digest_nid, NID_sha256); + + struct s2n_cert *root = intermediate->next; + EXPECT_NOT_NULL(intermediate); + EXPECT_NULL(root->next); + EXPECT_EQUAL(root->info.self_signed, true); + EXPECT_EQUAL(root->info.signature_nid, NID_ecdsa_with_SHA256); + EXPECT_EQUAL(root->info.signature_digest_nid, NID_sha256); + }; + }; + EXPECT_SUCCESS(s2n_io_pair_close(&io_pair)); EXPECT_SUCCESS(s2n_config_free(client_config)); diff --git a/tests/unit/s2n_cert_status_extension_test.c b/tests/unit/s2n_cert_status_extension_test.c index e49fc814abe..6bae421d76a 100644 --- a/tests/unit/s2n_cert_status_extension_test.c +++ b/tests/unit/s2n_cert_status_extension_test.c @@ -38,10 +38,10 @@ int main(int argc, char **argv) /* should_send */ { - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); @@ -78,7 +78,7 @@ int main(int argc, char **argv) /* Test send */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_test_enable_sending_extension(conn, chain_and_key)); @@ -87,16 +87,16 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_cert_status_extension.send(conn, &stuffer)); - uint8_t request_type; + uint8_t request_type = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint8(&stuffer, &request_type)); EXPECT_EQUAL(request_type, S2N_STATUS_REQUEST_OCSP); - uint32_t ocsp_size; + uint32_t ocsp_size = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint24(&stuffer, &ocsp_size)); EXPECT_EQUAL(ocsp_size, s2n_stuffer_data_available(&stuffer)); EXPECT_EQUAL(ocsp_size, s2n_array_len(ocsp_data)); - uint8_t *actual_ocsp_data; + uint8_t *actual_ocsp_data = NULL; EXPECT_NOT_NULL(actual_ocsp_data = s2n_stuffer_raw_read(&stuffer, ocsp_size)); EXPECT_BYTEARRAY_EQUAL(actual_ocsp_data, ocsp_data, ocsp_size); @@ -108,7 +108,7 @@ int main(int argc, char **argv) /* Test recv */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_test_enable_sending_extension(conn, chain_and_key)); @@ -129,7 +129,7 @@ int main(int argc, char **argv) /* Test recv - not ocsp */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_test_enable_sending_extension(conn, chain_and_key)); diff --git a/tests/unit/s2n_cert_status_response_extension_test.c b/tests/unit/s2n_cert_status_response_extension_test.c index 160fa7f5f24..12e73d7c157 100644 --- a/tests/unit/s2n_cert_status_response_extension_test.c +++ b/tests/unit/s2n_cert_status_response_extension_test.c @@ -39,10 +39,10 @@ int main(int argc, char **argv) /* should_send */ { - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); @@ -82,7 +82,7 @@ int main(int argc, char **argv) /* Test send and recv */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_cert_status_response_extension.send(conn, NULL)); diff --git a/tests/unit/s2n_certificate_extensions_test.c b/tests/unit/s2n_certificate_extensions_test.c index ef8de874779..4f3681e7c40 100644 --- a/tests/unit/s2n_certificate_extensions_test.c +++ b/tests/unit/s2n_certificate_extensions_test.c @@ -32,7 +32,7 @@ s2n_pkey_type actual_cert_pkey_type; static int s2n_skip_cert_chain_size(struct s2n_stuffer *stuffer) { - uint32_t cert_chain_size; + uint32_t cert_chain_size = 0; POSIX_GUARD(s2n_stuffer_read_uint24(stuffer, &cert_chain_size)); POSIX_ENSURE_EQ(cert_chain_size, s2n_stuffer_data_available(stuffer)); return S2N_SUCCESS; @@ -40,7 +40,7 @@ static int s2n_skip_cert_chain_size(struct s2n_stuffer *stuffer) static int s2n_skip_cert(struct s2n_stuffer *stuffer) { - uint32_t cert_size; + uint32_t cert_size = 0; POSIX_GUARD(s2n_stuffer_read_uint24(stuffer, &cert_size)); POSIX_GUARD(s2n_stuffer_skip_read(stuffer, cert_size)); return S2N_SUCCESS; @@ -51,7 +51,7 @@ static int s2n_x509_validator_validate_cert_chain_test(struct s2n_connection *co POSIX_GUARD(s2n_skip_cert_chain_size(stuffer)); uint32_t cert_chain_size = s2n_stuffer_data_available(stuffer); - uint8_t *cert_chain_data; + uint8_t *cert_chain_data = NULL; POSIX_ENSURE_REF(cert_chain_data = s2n_stuffer_raw_read(stuffer, cert_chain_size)); POSIX_GUARD_RESULT(s2n_x509_validator_validate_cert_chain(&conn->x509_validator, conn, @@ -71,7 +71,7 @@ static int s2n_write_test_cert(struct s2n_stuffer *stuffer, struct s2n_cert_chai static int s2n_setup_connection_for_ocsp_validate_test(struct s2n_connection **conn, struct s2n_cert_chain_and_key *chain_and_key) { - struct s2n_connection *nconn; + struct s2n_connection *nconn = NULL; POSIX_ENSURE_REF(nconn = s2n_connection_new(S2N_SERVER)); nconn->actual_protocol_version = S2N_TLS13; @@ -90,13 +90,13 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_enable_tls13_in_test()); - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); EXPECT_SUCCESS(s2n_pkey_zero_init(&public_key)); /* Initialize cert chain */ - struct s2n_cert_chain_and_key *chain_and_key; + struct s2n_cert_chain_and_key *chain_and_key = NULL; EXPECT_SUCCESS(s2n_test_cert_chain_and_key_new(&chain_and_key, S2N_DEFAULT_TEST_CERT_CHAIN, S2N_DEFAULT_TEST_PRIVATE_KEY)); EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(config, chain_and_key)); @@ -110,7 +110,7 @@ int main(int argc, char **argv) { /* Test: extensions only sent for >= TLS1.3 */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); conn->handshake_params.our_chain_and_key = chain_and_key; @@ -154,7 +154,7 @@ int main(int argc, char **argv) /* Test: extensions only sent on first certificate */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); conn->handshake_params.our_chain_and_key = chain_and_key; @@ -190,7 +190,7 @@ int main(int argc, char **argv) { /* Test: with no extensions */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); conn->actual_protocol_version = S2N_TLS13; conn->handshake_params.our_chain_and_key = chain_and_key; @@ -206,7 +206,7 @@ int main(int argc, char **argv) /* Test: with extensions */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); conn->actual_protocol_version = S2N_TLS13; conn->handshake_params.our_chain_and_key = chain_and_key; @@ -237,7 +237,7 @@ int main(int argc, char **argv) { /* Test: extensions only processed for >= TLS1.3 */ { - struct s2n_connection *setup_conn; + struct s2n_connection *setup_conn = NULL; POSIX_GUARD(s2n_setup_connection_for_ocsp_validate_test(&setup_conn, chain_and_key)); DEFER_CLEANUP(struct s2n_stuffer stuffer, s2n_stuffer_free); @@ -251,7 +251,7 @@ int main(int argc, char **argv) /* TLS1.2 does NOT process extensions */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; POSIX_GUARD(s2n_setup_connection_for_ocsp_validate_test(&conn, chain_and_key)); EXPECT_SUCCESS(s2n_stuffer_reread(&stuffer)); @@ -267,7 +267,7 @@ int main(int argc, char **argv) /* TLS1.3 DOES process extensions */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; POSIX_GUARD(s2n_setup_connection_for_ocsp_validate_test(&conn, chain_and_key)); EXPECT_SUCCESS(s2n_stuffer_reread(&stuffer)); @@ -290,7 +290,7 @@ int main(int argc, char **argv) /* Extensions on second cert ignored */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; POSIX_GUARD(s2n_setup_connection_for_ocsp_validate_test(&conn, chain_and_key)); DEFER_CLEANUP(struct s2n_stuffer stuffer, s2n_stuffer_free); @@ -313,7 +313,7 @@ int main(int argc, char **argv) /* Extensions on first cert processed */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; POSIX_GUARD(s2n_setup_connection_for_ocsp_validate_test(&conn, chain_and_key)); DEFER_CLEANUP(struct s2n_stuffer stuffer, s2n_stuffer_free); diff --git a/tests/unit/s2n_change_cipher_spec_test.c b/tests/unit/s2n_change_cipher_spec_test.c index 3d95e00b61e..9f579eb06ab 100644 --- a/tests/unit/s2n_change_cipher_spec_test.c +++ b/tests/unit/s2n_change_cipher_spec_test.c @@ -28,12 +28,12 @@ int main(int argc, char **argv) /* Test s2n_ccs_send */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_ccs_send(conn)); - uint8_t result; + uint8_t result = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint8(&conn->handshake.io, &result)); /* Always 0x01: https://tools.ietf.org/html/rfc5246#section-7.1 */ EXPECT_EQUAL(result, 0x01); @@ -43,7 +43,7 @@ int main(int argc, char **argv) /* Test that s2n_basic_ccs_recv can parse the output of s2n_change_cipher_spec_send */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_ccs_send(conn)); @@ -54,7 +54,7 @@ int main(int argc, char **argv) /* Test that s2n_basic_ccs_recv errors on wrong change cipher spec types */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_stuffer_write_uint8(&conn->handshake.io, 0)); @@ -65,7 +65,7 @@ int main(int argc, char **argv) /* Test that s2n_client_ccs_recv errors on wrong change cipher spec types */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_stuffer_write_uint8(&conn->handshake.io, 0)); @@ -76,7 +76,7 @@ int main(int argc, char **argv) /* Test that s2n_server_ccs_recv errors on wrong change cipher spec types */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_stuffer_write_uint8(&conn->handshake.io, 0)); @@ -87,7 +87,7 @@ int main(int argc, char **argv) /* Test s2n_client_ccs_recv */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); /* Needed to not break prf */ @@ -136,7 +136,7 @@ int main(int argc, char **argv) /* Test s2n_server_ccs_recv */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); /* Needed to not break prf */ diff --git a/tests/unit/s2n_cipher_suite_match_test.c b/tests/unit/s2n_cipher_suite_match_test.c index 8353210a65b..d4501f5f2b7 100644 --- a/tests/unit/s2n_cipher_suite_match_test.c +++ b/tests/unit/s2n_cipher_suite_match_test.c @@ -152,10 +152,10 @@ int main(int argc, char **argv) /* Test server cipher selection and scsv detection */ { - struct s2n_connection *conn; - struct s2n_config *server_config; - char *rsa_cert_chain_pem, *rsa_private_key_pem, *ecdsa_cert_chain_pem, *ecdsa_private_key_pem; - struct s2n_cert_chain_and_key *rsa_cert, *ecdsa_cert; + struct s2n_connection *conn = NULL; + struct s2n_config *server_config = NULL; + char *rsa_cert_chain_pem = NULL, *rsa_private_key_pem = NULL, *ecdsa_cert_chain_pem = NULL, *ecdsa_private_key_pem = NULL; + struct s2n_cert_chain_and_key *rsa_cert = NULL, *ecdsa_cert = NULL; /* Allocate all of the objects and PEMs we'll need for this test. */ EXPECT_NOT_NULL(rsa_cert_chain_pem = malloc(S2N_MAX_TEST_PEM_SIZE)); EXPECT_NOT_NULL(rsa_private_key_pem = malloc(S2N_MAX_TEST_PEM_SIZE)); @@ -433,6 +433,7 @@ int main(int argc, char **argv) EXPECT_NOT_NULL(server_config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(server_config, rsa_cert)); EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(server_config, ecdsa_cert)); + EXPECT_SUCCESS(s2n_connection_set_config(conn, server_config)); /* Client sends RSA and ECDSA ciphers, server prioritizes ECDSA, ECDSA + RSA cert is configured */ { @@ -550,6 +551,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(server_config, ecdsa_cert)); /* Override auto-chosen defaults with only RSA cert default. ECDSA still loaded, but not default. */ EXPECT_SUCCESS(s2n_config_set_cert_chain_and_key_defaults(server_config, &rsa_cert, 1)); + EXPECT_SUCCESS(s2n_connection_set_config(conn, server_config)); /* Client sends RSA and ECDSA ciphers, server prioritizes ECDSA, ECDSA + RSA cert is configured, * only RSA is default. Expect default RSA used instead of previous test that expects ECDSA for this case. */ diff --git a/tests/unit/s2n_cipher_suites_test.c b/tests/unit/s2n_cipher_suites_test.c index 0731fbf855b..a4dee37bab4 100644 --- a/tests/unit/s2n_cipher_suites_test.c +++ b/tests/unit/s2n_cipher_suites_test.c @@ -30,7 +30,7 @@ int main() /* Test: all cipher suites in s2n_all_cipher_suites are in IANA order */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); const uint8_t cipher_suite_count = cipher_preferences_test_all.count; diff --git a/tests/unit/s2n_cleanup_with_no_init_test.c b/tests/unit/s2n_cleanup_with_no_init_test.c index 9ef2eb2db51..d8b77732e7e 100644 --- a/tests/unit/s2n_cleanup_with_no_init_test.c +++ b/tests/unit/s2n_cleanup_with_no_init_test.c @@ -28,7 +28,7 @@ int main(int argc, char **argv) { BEGIN_TEST_NO_INIT(); - pthread_key_t my_key; + pthread_key_t my_key = 0; /* Init the pthread key */ EXPECT_SUCCESS(pthread_key_create(&my_key, my_destructor)); diff --git a/tests/unit/s2n_client_alpn_extension_test.c b/tests/unit/s2n_client_alpn_extension_test.c index 0cb2cf0f9f8..f9197b4d636 100644 --- a/tests/unit/s2n_client_alpn_extension_test.c +++ b/tests/unit/s2n_client_alpn_extension_test.c @@ -26,7 +26,7 @@ int main(int argc, char **argv) /* Test should_send */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_protocol_preferences(conn, NULL, 0)); @@ -40,7 +40,7 @@ int main(int argc, char **argv) /* Test send */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_protocol_preferences(conn, protocols, protocols_count)); @@ -50,7 +50,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_client_alpn_extension.send(conn, &stuffer)); /* Should have correct size */ - uint16_t actual_size; + uint16_t actual_size = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint16(&stuffer, &actual_size)); EXPECT_EQUAL(actual_size, s2n_stuffer_data_available(&stuffer)); EXPECT_EQUAL(actual_size, conn->application_protocols_overridden.size); @@ -66,7 +66,7 @@ int main(int argc, char **argv) /* Test receive can accept the output of send */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_protocol_preferences(conn, protocols, protocols_count)); @@ -86,7 +86,7 @@ int main(int argc, char **argv) /* Test receive does nothing if no protocol preferences configured */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); struct s2n_stuffer stuffer = { 0 }; @@ -104,7 +104,7 @@ int main(int argc, char **argv) /* Test receive does nothing if extension malformed */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); struct s2n_stuffer stuffer = { 0 }; diff --git a/tests/unit/s2n_client_auth_handshake_test.c b/tests/unit/s2n_client_auth_handshake_test.c index 64b994104b8..3b29c02604c 100644 --- a/tests/unit/s2n_client_auth_handshake_test.c +++ b/tests/unit/s2n_client_auth_handshake_test.c @@ -37,8 +37,8 @@ int s2n_test_client_auth_negotiation(struct s2n_config *server_config, struct s2n_config *client_config, struct s2n_cert_chain_and_key *ecdsa_cert, bool no_cert) { /* Set up client and server connections */ - struct s2n_connection *client_conn; - struct s2n_connection *server_conn; + struct s2n_connection *client_conn = NULL; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); @@ -101,10 +101,10 @@ int s2n_test_client_auth_negotiation(struct s2n_config *server_config, struct s2 */ int s2n_test_client_auth_message_by_message(bool no_cert) { - struct s2n_connection *client_conn; - struct s2n_connection *server_conn; + struct s2n_connection *client_conn = NULL; + struct s2n_connection *server_conn = NULL; - struct s2n_config *server_config, *client_config; + struct s2n_config *server_config = NULL, *client_config = NULL; EXPECT_NOT_NULL(server_config = s2n_config_new()); EXPECT_NOT_NULL(client_config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_set_unsafe_for_testing(client_config)); @@ -119,7 +119,7 @@ int s2n_test_client_auth_message_by_message(bool no_cert) EXPECT_SUCCESS(s2n_read_test_pem(S2N_ECDSA_P384_PKCS1_CERT_CHAIN, cert_chain, S2N_MAX_TEST_PEM_SIZE)); EXPECT_SUCCESS(s2n_read_test_pem(S2N_ECDSA_P384_PKCS1_KEY, private_key, S2N_MAX_TEST_PEM_SIZE)); - struct s2n_cert_chain_and_key *default_cert; + struct s2n_cert_chain_and_key *default_cert = NULL; EXPECT_NOT_NULL(default_cert = s2n_cert_chain_and_key_new()); EXPECT_SUCCESS(s2n_cert_chain_and_key_load_pem(default_cert, cert_chain, private_key)); EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(server_config, default_cert)); @@ -316,12 +316,12 @@ int main(int argc, char **argv) /* client_auth handshake negotiation */ { - struct s2n_config *server_config, *client_config; + struct s2n_config *server_config = NULL, *client_config = NULL; uint8_t *cert_chain_pem = NULL; uint8_t *private_key_pem = NULL; uint32_t cert_chain_len = 0; uint32_t private_key_len = 0; - struct s2n_cert_chain_and_key *ecdsa_cert; + struct s2n_cert_chain_and_key *ecdsa_cert = NULL; EXPECT_NOT_NULL(cert_chain_pem = malloc(S2N_MAX_TEST_PEM_SIZE)); EXPECT_NOT_NULL(private_key_pem = malloc(S2N_MAX_TEST_PEM_SIZE)); @@ -379,6 +379,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_connection_set_config(server, config)); /* Enable client auth on the server, but not on the client */ + EXPECT_SUCCESS(s2n_connection_set_client_auth_type(client, S2N_CERT_AUTH_NONE)); EXPECT_SUCCESS(s2n_connection_set_client_auth_type(server, S2N_CERT_AUTH_OPTIONAL)); DEFER_CLEANUP(struct s2n_test_io_pair io_pair = { 0 }, s2n_io_pair_close); @@ -389,5 +390,31 @@ int main(int argc, char **argv) S2N_ERR_UNEXPECTED_CERT_REQUEST); }; + /* By default, client accepts certificate requests */ + { + DEFER_CLEANUP(struct s2n_config *client_config = s2n_config_new(), s2n_config_ptr_free); + EXPECT_SUCCESS(s2n_config_set_unsafe_for_testing(client_config)); + DEFER_CLEANUP(struct s2n_connection *client = s2n_connection_new(S2N_CLIENT), + s2n_connection_ptr_free); + EXPECT_NOT_NULL(client); + EXPECT_SUCCESS(s2n_connection_set_config(client, client_config)); + + DEFER_CLEANUP(struct s2n_config *server_config = s2n_config_new(), s2n_config_ptr_free); + EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(server_config, chain_and_key)); + DEFER_CLEANUP(struct s2n_connection *server = s2n_connection_new(S2N_SERVER), + s2n_connection_ptr_free); + EXPECT_NOT_NULL(server); + EXPECT_SUCCESS(s2n_connection_set_config(server, server_config)); + + /* Enable client auth on the server */ + EXPECT_SUCCESS(s2n_connection_set_client_auth_type(server, S2N_CERT_AUTH_OPTIONAL)); + + DEFER_CLEANUP(struct s2n_test_io_pair io_pair = { 0 }, s2n_io_pair_close); + EXPECT_SUCCESS(s2n_io_pair_init_non_blocking(&io_pair)); + EXPECT_SUCCESS(s2n_connections_set_io_pair(client, server, &io_pair)); + + EXPECT_SUCCESS(s2n_negotiate_test_server_and_client(server, client)); + }; + END_TEST(); } diff --git a/tests/unit/s2n_client_cert_request_context_test.c b/tests/unit/s2n_client_cert_request_context_test.c index cccfca9a542..5cc72db9818 100644 --- a/tests/unit/s2n_client_cert_request_context_test.c +++ b/tests/unit/s2n_client_cert_request_context_test.c @@ -32,10 +32,10 @@ int main(int argc, char **argv) /* Test certificate_request_context sent/recv only when TLS 1.3 enabled */ { - struct s2n_config *client_config; + struct s2n_config *client_config = NULL; EXPECT_NOT_NULL(client_config = s2n_config_new()); - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(client_conn, client_config)); EXPECT_SUCCESS(s2n_connection_set_client_auth_type(client_conn, S2N_CERT_AUTH_OPTIONAL)); @@ -65,10 +65,10 @@ int main(int argc, char **argv) /* Test certificate_request_context is zero-length as currently * only used for handshake authentication */ { - struct s2n_config *client_config; + struct s2n_config *client_config = NULL; EXPECT_NOT_NULL(client_config = s2n_config_new()); - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(client_conn, client_config)); EXPECT_SUCCESS(s2n_connection_set_client_auth_type(client_conn, S2N_CERT_AUTH_OPTIONAL)); @@ -78,7 +78,7 @@ int main(int argc, char **argv) EXPECT_EQUAL(s2n_stuffer_data_available(&client_conn->handshake.io), empty_cert_len + certificate_context_len); uint8_t expected_certificate_request_context_len = 0; - uint8_t actual_certificate_request_context_len; + uint8_t actual_certificate_request_context_len = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint8(&client_conn->handshake.io, &actual_certificate_request_context_len)); EXPECT_EQUAL(expected_certificate_request_context_len, actual_certificate_request_context_len); @@ -89,10 +89,10 @@ int main(int argc, char **argv) /* Test failure case of non-zero certificate_request_context */ { - struct s2n_config *server_config; + struct s2n_config *server_config = NULL; EXPECT_NOT_NULL(server_config = s2n_config_new()); - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_config(server_conn, server_config)); EXPECT_SUCCESS(s2n_connection_set_client_auth_type(server_conn, S2N_CERT_AUTH_OPTIONAL)); diff --git a/tests/unit/s2n_client_cert_status_request_extension_test.c b/tests/unit/s2n_client_cert_status_request_extension_test.c index 508a1c080fb..69cea15c24d 100644 --- a/tests/unit/s2n_client_cert_status_request_extension_test.c +++ b/tests/unit/s2n_client_cert_status_request_extension_test.c @@ -54,7 +54,7 @@ int main(int argc, char **argv) /* Test send */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); @@ -63,11 +63,11 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_client_cert_status_request_extension.send(conn, &stuffer)); - uint8_t request_type; + uint8_t request_type = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint8(&stuffer, &request_type)); EXPECT_EQUAL(request_type, S2N_STATUS_REQUEST_OCSP); - uint32_t unused_values; + uint32_t unused_values = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint32(&stuffer, &unused_values)); EXPECT_EQUAL(unused_values, 0); @@ -79,7 +79,7 @@ int main(int argc, char **argv) /* Test recv */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); @@ -98,7 +98,7 @@ int main(int argc, char **argv) /* Test recv - malformed length, ignore */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); diff --git a/tests/unit/s2n_client_cert_verify_test.c b/tests/unit/s2n_client_cert_verify_test.c index be643702642..80170a4646e 100644 --- a/tests/unit/s2n_client_cert_verify_test.c +++ b/tests/unit/s2n_client_cert_verify_test.c @@ -171,7 +171,7 @@ int main(int argc, char **argv) /* Set any signature scheme. Our test pkey methods ignore it. */ conn->handshake_params.client_cert_sig_scheme = &s2n_rsa_pkcs1_md5_sha1; - struct s2n_cert_chain_and_key *chain_and_key; + struct s2n_cert_chain_and_key *chain_and_key = NULL; EXPECT_SUCCESS(s2n_test_cert_chain_and_key_new(&chain_and_key, S2N_DEFAULT_ECDSA_TEST_CERT_CHAIN, S2N_DEFAULT_ECDSA_TEST_PRIVATE_KEY)); chain_and_key->private_key->size = test_size; @@ -180,11 +180,11 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_client_cert_verify_send(conn)); - uint16_t signature_scheme_iana; + uint16_t signature_scheme_iana = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint16(&conn->handshake.io, &signature_scheme_iana)); EXPECT_EQUAL(signature_scheme_iana, s2n_rsa_pkcs1_md5_sha1.iana_value); - uint16_t signature_size; + uint16_t signature_size = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint16(&conn->handshake.io, &signature_size)); EXPECT_NOT_EQUAL(signature_size, test_max_signature_size); EXPECT_EQUAL(signature_size, test_signature_size); @@ -200,11 +200,11 @@ int main(int argc, char **argv) /* Test: async private key operations. */ { - struct s2n_cert_chain_and_key *chain_and_key; + struct s2n_cert_chain_and_key *chain_and_key = NULL; EXPECT_SUCCESS(s2n_test_cert_chain_and_key_new(&chain_and_key, S2N_DEFAULT_TEST_CERT_CHAIN, S2N_DEFAULT_TEST_PRIVATE_KEY)); - struct s2n_config *client_config; + struct s2n_config *client_config = NULL; EXPECT_NOT_NULL(client_config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(client_config, chain_and_key)); EXPECT_SUCCESS(s2n_config_set_async_pkey_callback(client_config, s2n_async_pkey_store_op)); @@ -220,7 +220,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_connection_set_config(client_conn, client_config)); EXPECT_SUCCESS(s2n_connection_set_client_auth_type(client_conn, S2N_CERT_AUTH_REQUIRED)); - struct s2n_config *server_config; + struct s2n_config *server_config = NULL; EXPECT_NOT_NULL(server_config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(server_config, chain_and_key)); EXPECT_SUCCESS(s2n_config_set_unsafe_for_testing(server_config)); @@ -259,11 +259,11 @@ int main(int argc, char **argv) /* Test: Apply with invalid signature */ { - struct s2n_cert_chain_and_key *chain_and_key; + struct s2n_cert_chain_and_key *chain_and_key = NULL; EXPECT_SUCCESS(s2n_test_cert_chain_and_key_new(&chain_and_key, S2N_DEFAULT_TEST_CERT_CHAIN, S2N_DEFAULT_TEST_PRIVATE_KEY)); - struct s2n_config *client_config; + struct s2n_config *client_config = NULL; EXPECT_NOT_NULL(client_config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(client_config, chain_and_key)); EXPECT_SUCCESS(s2n_config_set_async_pkey_callback(client_config, s2n_async_pkey_store_op)); @@ -278,7 +278,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_connection_set_config(client_conn, client_config)); EXPECT_SUCCESS(s2n_connection_set_client_auth_type(client_conn, S2N_CERT_AUTH_REQUIRED)); - struct s2n_config *server_config; + struct s2n_config *server_config = NULL; EXPECT_NOT_NULL(server_config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(server_config, chain_and_key)); EXPECT_SUCCESS(s2n_config_set_unsafe_for_testing(server_config)); diff --git a/tests/unit/s2n_client_empty_cert_test.c b/tests/unit/s2n_client_empty_cert_test.c index 1a1be1d71a8..c8d1d636a99 100644 --- a/tests/unit/s2n_client_empty_cert_test.c +++ b/tests/unit/s2n_client_empty_cert_test.c @@ -34,7 +34,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_send_empty_cert_chain(&out)); EXPECT_EQUAL(s2n_stuffer_data_available(&out), 3); - uint32_t cert_len; + uint32_t cert_len = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint24(&out, &cert_len)); EXPECT_EQUAL(cert_len, 0); @@ -43,10 +43,10 @@ int main(int argc, char **argv) /* Client sends the empty cert when no client default chain and key */ { - struct s2n_config *client_config; + struct s2n_config *client_config = NULL; EXPECT_NOT_NULL(client_config = s2n_config_new()); - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(client_conn, client_config)); EXPECT_SUCCESS(s2n_connection_set_client_auth_type(client_conn, S2N_CERT_AUTH_OPTIONAL)); @@ -59,7 +59,7 @@ int main(int argc, char **argv) /* Magic number 3 is the length of the certificate_length field */ EXPECT_EQUAL(s2n_stuffer_data_available(&client_conn->handshake.io), 3); - uint32_t cert_len; + uint32_t cert_len = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint24(&client_conn->handshake.io, &cert_len)); EXPECT_EQUAL(cert_len, 0); @@ -69,10 +69,10 @@ int main(int argc, char **argv) /* Client fails to send empty cert when S2N_CERT_AUTH_REQUIRED */ { - struct s2n_config *client_config; + struct s2n_config *client_config = NULL; EXPECT_NOT_NULL(client_config = s2n_config_new()); - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(client_conn, client_config)); EXPECT_SUCCESS(s2n_connection_set_client_auth_type(client_conn, S2N_CERT_AUTH_REQUIRED)); @@ -86,15 +86,15 @@ int main(int argc, char **argv) /* Server receives empty cert */ { - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(client_conn, config)); EXPECT_SUCCESS(s2n_connection_set_client_auth_type(client_conn, S2N_CERT_AUTH_OPTIONAL)); - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config)); EXPECT_SUCCESS(s2n_connection_set_client_auth_type(server_conn, S2N_CERT_AUTH_OPTIONAL)); diff --git a/tests/unit/s2n_client_extensions_test.c b/tests/unit/s2n_client_extensions_test.c index 456021f3f51..1d215f4e110 100644 --- a/tests/unit/s2n_client_extensions_test.c +++ b/tests/unit/s2n_client_extensions_test.c @@ -69,17 +69,17 @@ static int negotiate_kem(const uint8_t client_extensions[], const size_t client_ const uint8_t client_hello_message[], const size_t client_hello_len, const char cipher_pref_version[], const int expected_kem_id, struct s2n_test_io_pair *io_pair) { - char *cert_chain; - char *private_key; + char *cert_chain = NULL; + char *private_key = NULL; POSIX_GUARD_PTR(cert_chain = malloc(S2N_MAX_TEST_PEM_SIZE)); POSIX_GUARD_PTR(private_key = malloc(S2N_MAX_TEST_PEM_SIZE)); POSIX_GUARD(setenv("S2N_DONT_MLOCK", "1", 0)); - struct s2n_connection *server_conn; - struct s2n_config *server_config; + struct s2n_connection *server_conn = NULL; + struct s2n_config *server_config = NULL; s2n_blocked_status server_blocked; - struct s2n_cert_chain_and_key *chain_and_key; + struct s2n_cert_chain_and_key *chain_and_key = NULL; size_t body_len = client_hello_len + client_extensions_len; uint8_t message_header[] = { @@ -130,7 +130,7 @@ static int negotiate_kem(const uint8_t client_extensions[], const size_t client_ return S2N_FAILURE; } - int negotiated_kem_id; + int negotiated_kem_id = 0; if (server_conn->kex_params.kem_params.kem != NULL) { negotiated_kem_id = server_conn->kex_params.kem_params.kem->kem_extension_id; @@ -168,12 +168,12 @@ int main(int argc, char **argv) /* Client doesn't use the server name extension. */ { - struct s2n_connection *client_conn; - struct s2n_connection *server_conn; - struct s2n_config *server_config; - struct s2n_cert_chain_and_key *chain_and_key; + struct s2n_connection *client_conn = NULL; + struct s2n_connection *server_conn = NULL; + struct s2n_config *server_config = NULL; + struct s2n_cert_chain_and_key *chain_and_key = NULL; - struct s2n_config *client_config; + struct s2n_config *client_config = NULL; EXPECT_NOT_NULL(client_config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_set_check_stapled_ocsp_response(client_config, 0)); EXPECT_SUCCESS(s2n_config_disable_x509_verification(client_config)); @@ -215,15 +215,15 @@ int main(int argc, char **argv) /* Client uses the server name extension. */ { - struct s2n_connection *client_conn; - struct s2n_connection *server_conn; - struct s2n_config *server_config; - struct s2n_cert_chain_and_key *chain_and_key; + struct s2n_connection *client_conn = NULL; + struct s2n_connection *server_conn = NULL; + struct s2n_config *server_config = NULL; + struct s2n_cert_chain_and_key *chain_and_key = NULL; const char *sent_server_name = "www.alligator.com"; - const char *received_server_name; + const char *received_server_name = NULL; - struct s2n_config *client_config; + struct s2n_config *client_config = NULL; EXPECT_NOT_NULL(client_config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_set_check_stapled_ocsp_response(client_config, 0)); EXPECT_SUCCESS(s2n_config_disable_x509_verification(client_config)); @@ -271,12 +271,12 @@ int main(int argc, char **argv) /* Client sends multiple server names. */ { - struct s2n_connection *server_conn; - struct s2n_config *server_config; + struct s2n_connection *server_conn = NULL; + struct s2n_config *server_config = NULL; s2n_blocked_status server_blocked; const char *sent_server_name = "svr"; - const char *received_server_name; - struct s2n_cert_chain_and_key *chain_and_key; + const char *received_server_name = NULL; + struct s2n_cert_chain_and_key *chain_and_key = NULL; uint32_t cert_chain_len = 0; uint32_t private_key_len = 0; @@ -397,10 +397,10 @@ int main(int argc, char **argv) /* Client sends duplicate server name extension */ { - struct s2n_connection *server_conn; - struct s2n_config *server_config; + struct s2n_connection *server_conn = NULL; + struct s2n_config *server_config = NULL; s2n_blocked_status server_blocked; - struct s2n_cert_chain_and_key *chain_and_key; + struct s2n_cert_chain_and_key *chain_and_key = NULL; uint8_t client_extensions[] = { /* Extension type TLS_EXTENSION_SERVER_NAME */ @@ -532,10 +532,10 @@ int main(int argc, char **argv) /* Client sends a valid initial renegotiation_info */ { - struct s2n_connection *server_conn; - struct s2n_config *server_config; + struct s2n_connection *server_conn = NULL; + struct s2n_config *server_config = NULL; s2n_blocked_status server_blocked; - struct s2n_cert_chain_and_key *chain_and_key; + struct s2n_cert_chain_and_key *chain_and_key = NULL; uint8_t client_extensions[] = { /* Extension type TLS_EXTENSION_RENEGOTIATION_INFO */ @@ -632,10 +632,10 @@ int main(int argc, char **argv) /* Client sends a non-empty initial renegotiation_info */ { - struct s2n_connection *server_conn; - struct s2n_config *server_config; + struct s2n_connection *server_conn = NULL; + struct s2n_config *server_config = NULL; s2n_blocked_status server_blocked; - struct s2n_cert_chain_and_key *chain_and_key; + struct s2n_cert_chain_and_key *chain_and_key = NULL; uint8_t buf[5120]; uint8_t client_extensions[] = { @@ -728,12 +728,12 @@ int main(int argc, char **argv) /* Client doesn't use the OCSP extension. */ { - struct s2n_connection *client_conn; - struct s2n_connection *server_conn; - struct s2n_config *server_config; - uint32_t length; + struct s2n_connection *client_conn = NULL; + struct s2n_connection *server_conn = NULL; + struct s2n_config *server_config = NULL; + uint32_t length = 0; - struct s2n_config *client_config; + struct s2n_config *client_config = NULL; EXPECT_NOT_NULL(client_config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_set_check_stapled_ocsp_response(client_config, 0)); EXPECT_SUCCESS(s2n_config_disable_x509_verification(client_config)); @@ -779,7 +779,7 @@ int main(int argc, char **argv) /* Cannot enable OCSP stapling if there's no support for it */ if (!s2n_x509_ocsp_stapling_supported()) { - struct s2n_config *client_config; + struct s2n_config *client_config = NULL; EXPECT_NOT_NULL(client_config = s2n_config_new()); EXPECT_FAILURE(s2n_config_set_check_stapled_ocsp_response(client_config, 1)); EXPECT_SUCCESS(s2n_config_free(client_config)); @@ -787,12 +787,12 @@ int main(int argc, char **argv) /* Server doesn't support the OCSP extension. We can't run this test if ocsp isn't supported by the client. */ if (s2n_x509_ocsp_stapling_supported()) { - struct s2n_connection *client_conn; - struct s2n_connection *server_conn; - struct s2n_config *server_config; - struct s2n_config *client_config; - uint32_t length; - struct s2n_cert_chain_and_key *chain_and_key; + struct s2n_connection *client_conn = NULL; + struct s2n_connection *server_conn = NULL; + struct s2n_config *server_config = NULL; + struct s2n_config *client_config = NULL; + uint32_t length = 0; + struct s2n_cert_chain_and_key *chain_and_key = NULL; EXPECT_NOT_NULL(client_config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_set_check_stapled_ocsp_response(client_config, 0)); @@ -844,12 +844,12 @@ int main(int argc, char **argv) /* Test with s2n_config_set_extension_data(). Can be removed once API is deprecated */ if (s2n_x509_ocsp_stapling_supported()) { - struct s2n_connection *client_conn; - struct s2n_connection *server_conn; - struct s2n_config *server_config; - struct s2n_config *client_config; - const uint8_t *server_ocsp_reply; - uint32_t length; + struct s2n_connection *client_conn = NULL; + struct s2n_connection *server_conn = NULL; + struct s2n_config *server_config = NULL; + struct s2n_config *client_config = NULL; + const uint8_t *server_ocsp_reply = NULL; + uint32_t length = 0; EXPECT_NOT_NULL(client_config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_set_check_stapled_ocsp_response(client_config, 0)); @@ -895,12 +895,12 @@ int main(int argc, char **argv) /* Server and client support the OCSP extension. Test only runs if ocsp stapled responses are supported by the client */ if (s2n_x509_ocsp_stapling_supported()) { - struct s2n_connection *client_conn; - struct s2n_connection *server_conn; - struct s2n_config *server_config; - struct s2n_config *client_config; - const uint8_t *server_ocsp_reply; - uint32_t length; + struct s2n_connection *client_conn = NULL; + struct s2n_connection *server_conn = NULL; + struct s2n_config *server_config = NULL; + struct s2n_config *client_config = NULL; + const uint8_t *server_ocsp_reply = NULL; + uint32_t length = 0; EXPECT_NOT_NULL(client_config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_set_check_stapled_ocsp_response(client_config, 0)); @@ -953,12 +953,12 @@ int main(int argc, char **argv) /* Server and client support the OCSP extension. Test Behavior for TLS 1.3 */ if (s2n_x509_ocsp_stapling_supported() && s2n_is_tls13_fully_supported()) { - struct s2n_connection *client_conn; - struct s2n_connection *server_conn; - struct s2n_config *server_config; - struct s2n_config *client_config; - const uint8_t *server_ocsp_reply; - uint32_t length; + struct s2n_connection *client_conn = NULL; + struct s2n_connection *server_conn = NULL; + struct s2n_config *server_config = NULL; + struct s2n_config *client_config = NULL; + const uint8_t *server_ocsp_reply = NULL; + uint32_t length = 0; EXPECT_SUCCESS(s2n_enable_tls13_in_test()); @@ -1018,13 +1018,13 @@ int main(int argc, char **argv) /* Client does not request SCT, but server is configured to serve them. */ { - struct s2n_connection *client_conn; - struct s2n_connection *server_conn; - struct s2n_config *server_config; + struct s2n_connection *client_conn = NULL; + struct s2n_connection *server_conn = NULL; + struct s2n_config *server_config = NULL; - uint32_t length; + uint32_t length = 0; - struct s2n_config *client_config; + struct s2n_config *client_config = NULL; EXPECT_NOT_NULL(client_config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_set_check_stapled_ocsp_response(client_config, 0)); EXPECT_SUCCESS(s2n_config_disable_x509_verification(client_config)); @@ -1066,12 +1066,12 @@ int main(int argc, char **argv) /* Client requests SCT and server does have it. */ { - struct s2n_connection *client_conn; - struct s2n_connection *server_conn; - struct s2n_config *client_config; - struct s2n_config *server_config; + struct s2n_connection *client_conn = NULL; + struct s2n_connection *server_conn = NULL; + struct s2n_config *client_config = NULL; + struct s2n_config *server_config = NULL; - uint32_t length; + uint32_t length = 0; EXPECT_NOT_NULL(client_config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_set_check_stapled_ocsp_response(client_config, 0)); @@ -1118,13 +1118,13 @@ int main(int argc, char **argv) /* Client requests SCT and server does *not* have it. */ { - struct s2n_connection *client_conn; - struct s2n_connection *server_conn; - struct s2n_config *client_config; - struct s2n_config *server_config; - struct s2n_cert_chain_and_key *chain_and_key; + struct s2n_connection *client_conn = NULL; + struct s2n_connection *server_conn = NULL; + struct s2n_config *client_config = NULL; + struct s2n_config *server_config = NULL; + struct s2n_cert_chain_and_key *chain_and_key = NULL; - uint32_t length; + uint32_t length = 0; EXPECT_NOT_NULL(client_config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_set_check_stapled_ocsp_response(client_config, 0)); @@ -1173,11 +1173,11 @@ int main(int argc, char **argv) /* Client requests 512, 1024, 2048, and 4096 maximum fragment lengths */ for (uint8_t mfl_code = S2N_TLS_MAX_FRAG_LEN_512; mfl_code <= S2N_TLS_MAX_FRAG_LEN_4096; mfl_code++) { - struct s2n_connection *client_conn; - struct s2n_connection *server_conn; - struct s2n_config *server_config; - struct s2n_config *client_config; - struct s2n_cert_chain_and_key *chain_and_key; + struct s2n_connection *client_conn = NULL; + struct s2n_connection *server_conn = NULL; + struct s2n_config *server_config = NULL; + struct s2n_config *client_config = NULL; + struct s2n_cert_chain_and_key *chain_and_key = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); client_conn->actual_protocol_version = S2N_TLS12; @@ -1226,11 +1226,11 @@ int main(int argc, char **argv) /* Client requests invalid maximum fragment length */ { - struct s2n_connection *client_conn; - struct s2n_connection *server_conn; - struct s2n_config *server_config; - struct s2n_config *client_config; - struct s2n_cert_chain_and_key *chain_and_key; + struct s2n_connection *client_conn = NULL; + struct s2n_connection *server_conn = NULL; + struct s2n_config *server_config = NULL; + struct s2n_config *client_config = NULL; + struct s2n_cert_chain_and_key *chain_and_key = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); client_conn->actual_protocol_version = S2N_TLS12; @@ -1276,11 +1276,11 @@ int main(int argc, char **argv) /* Server ignores client's request of S2N_TLS_MAX_FRAG_LEN_2048 maximum fragment length when accept_mfl is not set*/ { - struct s2n_connection *client_conn; - struct s2n_connection *server_conn; - struct s2n_config *server_config; - struct s2n_config *client_config; - struct s2n_cert_chain_and_key *chain_and_key; + struct s2n_connection *client_conn = NULL; + struct s2n_connection *server_conn = NULL; + struct s2n_config *server_config = NULL; + struct s2n_config *client_config = NULL; + struct s2n_cert_chain_and_key *chain_and_key = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); client_conn->actual_protocol_version = S2N_TLS12; diff --git a/tests/unit/s2n_client_hello_recv_test.c b/tests/unit/s2n_client_hello_recv_test.c index a0698945ee8..6ad7a37baf0 100644 --- a/tests/unit/s2n_client_hello_recv_test.c +++ b/tests/unit/s2n_client_hello_recv_test.c @@ -33,17 +33,17 @@ int main(int argc, char **argv) { - struct s2n_connection *server_conn; - struct s2n_connection *client_conn; - struct s2n_stuffer *hello_stuffer; - struct s2n_config *tls12_config; - struct s2n_config *tls13_config; - struct s2n_cert_chain_and_key *chain_and_key; - struct s2n_cert_chain_and_key *tls13_chain_and_key; - char *cert_chain; - char *tls13_cert_chain; - char *private_key; - char *tls13_private_key; + struct s2n_connection *server_conn = NULL; + struct s2n_connection *client_conn = NULL; + struct s2n_stuffer *hello_stuffer = NULL; + struct s2n_config *tls12_config = NULL; + struct s2n_config *tls13_config = NULL; + struct s2n_cert_chain_and_key *chain_and_key = NULL; + struct s2n_cert_chain_and_key *tls13_chain_and_key = NULL; + char *cert_chain = NULL; + char *tls13_cert_chain = NULL; + char *private_key = NULL; + char *tls13_private_key = NULL; BEGIN_TEST(); EXPECT_SUCCESS(s2n_disable_tls13_in_test()); @@ -389,7 +389,7 @@ int main(int argc, char **argv) const size_t test_session_id_len = 10; - struct s2n_config *quic_config; + struct s2n_config *quic_config = NULL; EXPECT_NOT_NULL(quic_config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_enable_quic(quic_config)); EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(quic_config, tls13_chain_and_key)); @@ -509,6 +509,45 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_disable_tls13_in_test()); }; + /* Test: Parse fragmented sslv2 client hello. + * + * Even if the sslv2 client hello is sent in one packet, there is no requirement + * that our first call to conn->recv returns the whole message. sslv2 uses separate + * record parsing code, so we need to ensure that those paths can handle partial reads. + */ + { + DEFER_CLEANUP(struct s2n_connection *server = s2n_connection_new(S2N_SERVER), + s2n_connection_ptr_free); + EXPECT_SUCCESS(s2n_connection_set_config(server, tls12_config)); + + struct s2n_stuffer server_in = { 0 }; + uint8_t sslv2_client_hello[] = { + SSLv2_CLIENT_HELLO_HEADER, + SSLv2_CLIENT_HELLO_PREFIX, + SSLv2_CLIENT_HELLO_CIPHER_SUITES, + SSLv2_CLIENT_HELLO_CHALLENGE, + }; + EXPECT_SUCCESS(s2n_blob_init(&server_in.blob, + sslv2_client_hello, sizeof(sslv2_client_hello))); + EXPECT_SUCCESS(s2n_connection_set_recv_io_stuffer(&server_in, server)); + + /* Read message one byte at a time */ + s2n_blocked_status blocked = S2N_NOT_BLOCKED; + for (size_t i = 0; i < sizeof(sslv2_client_hello); i++) { + EXPECT_ERROR_WITH_ERRNO( + s2n_negotiate_until_message(server, &blocked, SERVER_HELLO), + S2N_ERR_IO_BLOCKED); + EXPECT_EQUAL(blocked, S2N_BLOCKED_ON_READ); + EXPECT_SUCCESS(s2n_stuffer_skip_write(&server_in, 1)); + } + + /* Successfully read the full message */ + EXPECT_OK(s2n_negotiate_until_message(server, &blocked, SERVER_HELLO)); + EXPECT_EQUAL(server->client_protocol_version, S2N_TLS12); + EXPECT_EQUAL(server->client_hello_version, S2N_SSLv2); + EXPECT_TRUE(server->client_hello.sslv2); + }; + s2n_config_free(tls12_config); s2n_config_free(tls13_config); s2n_cert_chain_and_key_free(chain_and_key); diff --git a/tests/unit/s2n_client_hello_retry_test.c b/tests/unit/s2n_client_hello_retry_test.c index 077d6e36bcd..6ab9ec67272 100644 --- a/tests/unit/s2n_client_hello_retry_test.c +++ b/tests/unit/s2n_client_hello_retry_test.c @@ -40,6 +40,8 @@ #define HELLO_RETRY_MSG_NO 1 #define SERVER_HELLO_MSG_NO 5 +int s2n_parse_client_hello(struct s2n_connection *conn); + static int s2n_client_hello_cb_with_get_server_name(struct s2n_connection *conn, void *ctx) { const char *expected_server_name = (const char *) ctx; @@ -62,8 +64,8 @@ int main(int argc, char **argv) { /* s2n_server_hello_retry_recv must fail when a keyshare for a matching curve was already present */ { - struct s2n_config *config; - struct s2n_connection *conn; + struct s2n_config *config = NULL; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); @@ -89,8 +91,8 @@ int main(int argc, char **argv) /* s2n_server_hello_retry_recv must fail for a connection with actual protocol version less than TLS13 */ { - struct s2n_config *config; - struct s2n_connection *conn; + struct s2n_config *config = NULL; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); @@ -106,13 +108,13 @@ int main(int argc, char **argv) /* Test ECC success case for s2n_server_hello_retry_recv */ { - struct s2n_config *server_config; - struct s2n_config *client_config; + struct s2n_config *server_config = NULL; + struct s2n_config *client_config = NULL; - struct s2n_connection *server_conn; - struct s2n_connection *client_conn; + struct s2n_connection *server_conn = NULL; + struct s2n_connection *client_conn = NULL; - struct s2n_cert_chain_and_key *tls13_chain_and_key; + struct s2n_cert_chain_and_key *tls13_chain_and_key = NULL; char tls13_cert_chain[S2N_MAX_TEST_PEM_SIZE] = { 0 }; char tls13_private_key[S2N_MAX_TEST_PEM_SIZE] = { 0 }; @@ -177,7 +179,7 @@ int main(int argc, char **argv) }; if (!s2n_pq_is_enabled()) { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); conn->actual_protocol_version = S2N_TLS13; conn->security_policy_override = &test_security_policy; @@ -195,7 +197,7 @@ int main(int argc, char **argv) } else { /* s2n_server_hello_retry_recv must fail when a keyshare for a matching PQ KEM was already present */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); conn->actual_protocol_version = S2N_TLS13; conn->security_policy_override = &test_security_policy; @@ -233,7 +235,7 @@ int main(int argc, char **argv) }; /* Test failure if exactly one of {named_curve, kem_group} isn't non-null */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); conn->actual_protocol_version = S2N_TLS13; conn->security_policy_override = &test_security_policy; @@ -255,10 +257,10 @@ int main(int argc, char **argv) uint32_t available_groups = 0; EXPECT_OK(s2n_kem_preferences_groups_available(test_security_policy.kem_preferences, &available_groups)); if (available_groups >= 2) { - struct s2n_config *config; - struct s2n_connection *conn; + struct s2n_config *config = NULL; + struct s2n_connection *conn = NULL; - struct s2n_cert_chain_and_key *tls13_chain_and_key; + struct s2n_cert_chain_and_key *tls13_chain_and_key = NULL; char tls13_cert_chain[S2N_MAX_TEST_PEM_SIZE] = { 0 }; char tls13_private_key[S2N_MAX_TEST_PEM_SIZE] = { 0 }; @@ -309,13 +311,13 @@ int main(int argc, char **argv) * hash, and generates a synthetic message. This test verifies that transcript hash recreated is the same * on both the server and client side. */ { - struct s2n_config *server_config; - struct s2n_config *client_config; + struct s2n_config *server_config = NULL; + struct s2n_config *client_config = NULL; - struct s2n_connection *server_conn; - struct s2n_connection *client_conn; + struct s2n_connection *server_conn = NULL; + struct s2n_connection *client_conn = NULL; - struct s2n_cert_chain_and_key *tls13_chain_and_key; + struct s2n_cert_chain_and_key *tls13_chain_and_key = NULL; char tls13_cert_chain[S2N_MAX_TEST_PEM_SIZE] = { 0 }; char tls13_private_key[S2N_MAX_TEST_PEM_SIZE] = { 0 }; @@ -409,13 +411,13 @@ int main(int argc, char **argv) *# HelloRetryRequest and send a second updated ClientHello. **/ { - struct s2n_config *server_config; - struct s2n_config *client_config; + struct s2n_config *server_config = NULL; + struct s2n_config *client_config = NULL; - struct s2n_connection *server_conn; - struct s2n_connection *client_conn; + struct s2n_connection *server_conn = NULL; + struct s2n_connection *client_conn = NULL; - struct s2n_cert_chain_and_key *tls13_chain_and_key; + struct s2n_cert_chain_and_key *tls13_chain_and_key = NULL; char tls13_cert_chain[S2N_MAX_TEST_PEM_SIZE] = { 0 }; char tls13_private_key[S2N_MAX_TEST_PEM_SIZE] = { 0 }; @@ -474,13 +476,13 @@ int main(int argc, char **argv) *# server MUST respond with a HelloRetryRequest (Section 4.1.4) message. **/ if (s2n_is_evp_apis_supported()) { - struct s2n_config *server_config; - struct s2n_config *client_config; + struct s2n_config *server_config = NULL; + struct s2n_config *client_config = NULL; - struct s2n_connection *server_conn; - struct s2n_connection *client_conn; + struct s2n_connection *server_conn = NULL; + struct s2n_connection *client_conn = NULL; - struct s2n_cert_chain_and_key *tls13_chain_and_key; + struct s2n_cert_chain_and_key *tls13_chain_and_key = NULL; char tls13_cert_chain[S2N_MAX_TEST_PEM_SIZE] = { 0 }; char tls13_private_key[S2N_MAX_TEST_PEM_SIZE] = { 0 }; @@ -545,13 +547,13 @@ int main(int argc, char **argv) *# handshake with an "unexpected_message" alert. **/ { - struct s2n_config *server_config; - struct s2n_config *client_config; + struct s2n_config *server_config = NULL; + struct s2n_config *client_config = NULL; - struct s2n_connection *server_conn; - struct s2n_connection *client_conn; + struct s2n_connection *server_conn = NULL; + struct s2n_connection *client_conn = NULL; - struct s2n_cert_chain_and_key *tls13_chain_and_key; + struct s2n_cert_chain_and_key *tls13_chain_and_key = NULL; char tls13_cert_chain[S2N_MAX_TEST_PEM_SIZE] = { 0 }; char tls13_private_key[S2N_MAX_TEST_PEM_SIZE] = { 0 }; @@ -625,7 +627,7 @@ int main(int argc, char **argv) *# it as described in Section 4.1.4). **/ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); const uint8_t not_hello_retry_request_random[S2N_TLS_RANDOM_DATA_LEN] = { 0 }; EXPECT_MEMCPY_SUCCESS(conn->handshake_params.server_random, not_hello_retry_request_random, @@ -648,8 +650,8 @@ int main(int argc, char **argv) *# otherwise abort the handshake with an "illegal_parameter" alert. **/ { - struct s2n_connection *server_conn; - struct s2n_connection *client_conn; + struct s2n_connection *server_conn = NULL; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); @@ -725,7 +727,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_negotiate_test_server_and_client(server_conn, client_conn)); }; - /* Test: The server rejects a second ClientHello with changed message fields */ + /* Test: The server rejects a second ClientHello with a changed legacy version */ { DEFER_CLEANUP(struct s2n_connection *server_conn = s2n_connection_new(S2N_SERVER), s2n_connection_ptr_free); @@ -746,12 +748,15 @@ int main(int argc, char **argv) /* Force the HRR path */ client_conn->security_policy_override = &security_policy_test_tls13_retry; - /* Send ClientHello */ + /* Skip to before the client sends the second ClientHello. */ s2n_blocked_status blocked = 0; EXPECT_OK(s2n_negotiate_until_message(client_conn, &blocked, SERVER_HELLO)); + EXPECT_OK(s2n_negotiate_until_message(server_conn, &blocked, HELLO_RETRY_MSG)); + EXPECT_OK(s2n_negotiate_until_message(server_conn, &blocked, CLIENT_HELLO)); + EXPECT_OK(s2n_negotiate_until_message(client_conn, &blocked, CLIENT_HELLO)); - /* Change session id */ - client_conn->session_id[0]++; + /* Change the legacy version. */ + client_conn->client_protocol_version = S2N_TLS11; /* Expect failure because second client hello doesn't match */ EXPECT_FAILURE_WITH_ERRNO(s2n_negotiate_test_server_and_client(server_conn, client_conn), @@ -791,7 +796,7 @@ int main(int argc, char **argv) S2N_ERR_BAD_MESSAGE); }; - /* Test: outside of testing, the server accepts an incorrectly updated ClientHello */ + /* Test: Outside of testing, the server accepts a second ClientHello with a changed client random */ { DEFER_CLEANUP(struct s2n_connection *server_conn = s2n_connection_new(S2N_SERVER), s2n_connection_ptr_free); @@ -825,6 +830,346 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_in_unit_test_set(true)); } + /* Test: The server accepts a second ClientHello with a changed session ID */ + for (size_t test_in_test_mode = 0; test_in_test_mode <= 1; test_in_test_mode++) { + DEFER_CLEANUP(struct s2n_connection *server_conn = s2n_connection_new(S2N_SERVER), + s2n_connection_ptr_free); + EXPECT_NOT_NULL(server_conn); + EXPECT_SUCCESS(s2n_connection_set_blinding(server_conn, S2N_SELF_SERVICE_BLINDING)); + EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config)); + + DEFER_CLEANUP(struct s2n_connection *client_conn = s2n_connection_new(S2N_CLIENT), + s2n_connection_ptr_free); + EXPECT_NOT_NULL(client_conn); + EXPECT_SUCCESS(s2n_connection_set_blinding(client_conn, S2N_SELF_SERVICE_BLINDING)); + EXPECT_SUCCESS(s2n_connection_set_config(client_conn, config)); + + struct s2n_test_io_pair io_pair = { 0 }; + EXPECT_SUCCESS(s2n_io_pair_init_non_blocking(&io_pair)); + EXPECT_SUCCESS(s2n_connections_set_io_pair(client_conn, server_conn, &io_pair)); + + /* Force the HRR path. */ + client_conn->security_policy_override = &security_policy_test_tls13_retry; + + /* Skip to before the client sends the second ClientHello. */ + s2n_blocked_status blocked = 0; + EXPECT_OK(s2n_negotiate_until_message(client_conn, &blocked, SERVER_HELLO)); + EXPECT_OK(s2n_negotiate_until_message(server_conn, &blocked, HELLO_RETRY_MSG)); + EXPECT_OK(s2n_negotiate_until_message(server_conn, &blocked, CLIENT_HELLO)); + EXPECT_OK(s2n_negotiate_until_message(client_conn, &blocked, CLIENT_HELLO)); + + /* Change session id */ + client_conn->session_id[0]++; + + if (test_in_test_mode) { + /* Ensure that validation fails in test mode to prevent regressions. */ + EXPECT_FAILURE_WITH_ERRNO(s2n_negotiate_test_server_and_client(server_conn, client_conn), + S2N_ERR_BAD_MESSAGE); + } else { + EXPECT_SUCCESS(s2n_in_unit_test_set(false)); + EXPECT_SUCCESS(s2n_negotiate_test_server_and_client(server_conn, client_conn)); + EXPECT_SUCCESS(s2n_in_unit_test_set(true)); + } + }; + + /* Test: The server accepts a second ClientHello with a changed cipher suite list */ + for (size_t test_in_test_mode = 0; test_in_test_mode <= 1; test_in_test_mode++) { + DEFER_CLEANUP(struct s2n_connection *server_conn = s2n_connection_new(S2N_SERVER), + s2n_connection_ptr_free); + EXPECT_NOT_NULL(server_conn); + EXPECT_SUCCESS(s2n_connection_set_blinding(server_conn, S2N_SELF_SERVICE_BLINDING)); + EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config)); + + DEFER_CLEANUP(struct s2n_connection *client_conn = s2n_connection_new(S2N_CLIENT), + s2n_connection_ptr_free); + EXPECT_NOT_NULL(client_conn); + EXPECT_SUCCESS(s2n_connection_set_blinding(client_conn, S2N_SELF_SERVICE_BLINDING)); + EXPECT_SUCCESS(s2n_connection_set_config(client_conn, config)); + + struct s2n_test_io_pair io_pair = { 0 }; + EXPECT_SUCCESS(s2n_io_pair_init_non_blocking(&io_pair)); + EXPECT_SUCCESS(s2n_connections_set_io_pair(client_conn, server_conn, &io_pair)); + + struct s2n_security_policy test_policy = security_policy_test_tls13_retry; + struct s2n_cipher_suite *test_cipher_suites[] = { + &s2n_tls13_aes_128_gcm_sha256, + &s2n_tls13_aes_256_gcm_sha384 + }; + struct s2n_cipher_preferences test_cipher_preferences = { + .count = s2n_array_len(test_cipher_suites), + .suites = test_cipher_suites, + }; + test_policy.cipher_preferences = &test_cipher_preferences; + + /* Force the HRR path. */ + client_conn->security_policy_override = &test_policy; + + /* Skip to before the client sends the second ClientHello. */ + s2n_blocked_status blocked = 0; + EXPECT_OK(s2n_negotiate_until_message(client_conn, &blocked, SERVER_HELLO)); + EXPECT_OK(s2n_negotiate_until_message(server_conn, &blocked, HELLO_RETRY_MSG)); + EXPECT_OK(s2n_negotiate_until_message(server_conn, &blocked, CLIENT_HELLO)); + EXPECT_OK(s2n_negotiate_until_message(client_conn, &blocked, CLIENT_HELLO)); + + /* Modify a cipher suite. */ + test_cipher_suites[1] = &s2n_tls13_chacha20_poly1305_sha256; + + if (test_in_test_mode) { + /* Ensure that validation fails in test mode to prevent regressions. */ + EXPECT_FAILURE_WITH_ERRNO(s2n_negotiate_test_server_and_client(server_conn, client_conn), + S2N_ERR_BAD_MESSAGE); + } else { + EXPECT_SUCCESS(s2n_in_unit_test_set(false)); + EXPECT_SUCCESS(s2n_negotiate_test_server_and_client(server_conn, client_conn)); + EXPECT_SUCCESS(s2n_in_unit_test_set(true)); + } + }; + + /* Test: Ensure that the connection fails if the cipher suite list changes such that the + * server cannot negotiate its original selection from the first ClientHello + * + *= https://tools.ietf.org/rfc/rfc8446#4.1.4 + *= type=test + *# Servers MUST ensure that they negotiate the + *# same cipher suite when receiving a conformant updated ClientHello (if + *# the server selects the cipher suite as the first step in the + *# negotiation, then this will happen automatically). + **/ + { + DEFER_CLEANUP(struct s2n_connection *server_conn = s2n_connection_new(S2N_SERVER), + s2n_connection_ptr_free); + EXPECT_NOT_NULL(server_conn); + EXPECT_SUCCESS(s2n_connection_set_blinding(server_conn, S2N_SELF_SERVICE_BLINDING)); + EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config)); + + DEFER_CLEANUP(struct s2n_connection *client_conn = s2n_connection_new(S2N_CLIENT), + s2n_connection_ptr_free); + EXPECT_NOT_NULL(client_conn); + EXPECT_SUCCESS(s2n_connection_set_blinding(client_conn, S2N_SELF_SERVICE_BLINDING)); + EXPECT_SUCCESS(s2n_connection_set_config(client_conn, config)); + + struct s2n_test_io_pair io_pair = { 0 }; + EXPECT_SUCCESS(s2n_io_pair_init_non_blocking(&io_pair)); + EXPECT_SUCCESS(s2n_connections_set_io_pair(client_conn, server_conn, &io_pair)); + + struct s2n_security_policy test_policy = security_policy_test_tls13_retry; + struct s2n_cipher_suite *test_cipher_suites[] = { + &s2n_tls13_aes_128_gcm_sha256, + &s2n_tls13_aes_256_gcm_sha384 + }; + struct s2n_cipher_preferences test_cipher_preferences = { + .count = s2n_array_len(test_cipher_suites), + .suites = test_cipher_suites, + }; + test_policy.cipher_preferences = &test_cipher_preferences; + + /* Force the HRR path. */ + client_conn->security_policy_override = &test_policy; + + /* Skip to before the client sends the second ClientHello. */ + s2n_blocked_status blocked = 0; + EXPECT_OK(s2n_negotiate_until_message(client_conn, &blocked, SERVER_HELLO)); + EXPECT_OK(s2n_negotiate_until_message(server_conn, &blocked, HELLO_RETRY_MSG)); + EXPECT_OK(s2n_negotiate_until_message(server_conn, &blocked, CLIENT_HELLO)); + EXPECT_OK(s2n_negotiate_until_message(client_conn, &blocked, CLIENT_HELLO)); + + /* Replace the most preferred cipher suite, forcing the server to select a different + * cipher suite when processing the second ClientHello. + */ + test_cipher_suites[0] = &s2n_tls13_chacha20_poly1305_sha256; + + /* Test mode is disabled to skip the failing ClientHello comparison check due to a + * changed cipher suite list. + */ + EXPECT_SUCCESS(s2n_in_unit_test_set(false)); + EXPECT_FAILURE_WITH_ERRNO(s2n_negotiate_test_server_and_client(server_conn, client_conn), + S2N_ERR_BAD_MESSAGE); + EXPECT_SUCCESS(s2n_in_unit_test_set(true)); + }; + + /* The server rejects a second ClientHello with a changed compression methods field */ + for (uint8_t test_compression_method = 0; test_compression_method <= 1; test_compression_method++) { + DEFER_CLEANUP(struct s2n_connection *server_conn = s2n_connection_new(S2N_SERVER), + s2n_connection_ptr_free); + EXPECT_NOT_NULL(server_conn); + EXPECT_SUCCESS(s2n_connection_set_blinding(server_conn, S2N_SELF_SERVICE_BLINDING)); + EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config)); + + DEFER_CLEANUP(struct s2n_connection *client_conn = s2n_connection_new(S2N_CLIENT), + s2n_connection_ptr_free); + EXPECT_NOT_NULL(client_conn); + EXPECT_SUCCESS(s2n_connection_set_blinding(client_conn, S2N_SELF_SERVICE_BLINDING)); + EXPECT_SUCCESS(s2n_connection_set_config(client_conn, config)); + + struct s2n_test_io_pair io_pair = { 0 }; + EXPECT_SUCCESS(s2n_io_pair_init_non_blocking(&io_pair)); + EXPECT_SUCCESS(s2n_connections_set_io_pair(client_conn, server_conn, &io_pair)); + + /* Force the HRR path. */ + client_conn->security_policy_override = &security_policy_test_tls13_retry; + + /* Skip to before the client sends the second ClientHello. */ + s2n_blocked_status blocked = 0; + EXPECT_OK(s2n_negotiate_until_message(client_conn, &blocked, SERVER_HELLO)); + EXPECT_OK(s2n_negotiate_until_message(server_conn, &blocked, HELLO_RETRY_MSG)); + EXPECT_OK(s2n_negotiate_until_message(server_conn, &blocked, CLIENT_HELLO)); + EXPECT_OK(s2n_negotiate_until_message(client_conn, &blocked, CLIENT_HELLO)); + + /* Send the second ClientHello. */ + EXPECT_SUCCESS(s2n_client_hello_send(client_conn)); + EXPECT_SUCCESS(s2n_stuffer_wipe(&server_conn->handshake.io)); + EXPECT_SUCCESS(s2n_stuffer_copy(&client_conn->handshake.io, &server_conn->handshake.io, + s2n_stuffer_data_available(&client_conn->handshake.io))); + + struct s2n_stuffer client_hello_stuffer = { 0 }; + EXPECT_SUCCESS(s2n_stuffer_init_written(&client_hello_stuffer, &server_conn->handshake.io.blob)); + + /* Read up to the single null compression method byte */ + EXPECT_SUCCESS(s2n_stuffer_skip_read(&client_hello_stuffer, S2N_TLS_PROTOCOL_VERSION_LEN)); + EXPECT_SUCCESS(s2n_stuffer_skip_read(&client_hello_stuffer, S2N_TLS_RANDOM_DATA_LEN)); + uint8_t session_id_len = 0; + EXPECT_SUCCESS(s2n_stuffer_read_uint8(&client_hello_stuffer, &session_id_len)); + EXPECT_SUCCESS(s2n_stuffer_skip_read(&client_hello_stuffer, session_id_len)); + uint16_t cipher_suites_len = 0; + EXPECT_SUCCESS(s2n_stuffer_read_uint16(&client_hello_stuffer, &cipher_suites_len)); + EXPECT_SUCCESS(s2n_stuffer_skip_read(&client_hello_stuffer, cipher_suites_len)); + uint8_t compression_methods_len = 0; + EXPECT_SUCCESS(s2n_stuffer_read_uint8(&client_hello_stuffer, &compression_methods_len)); + EXPECT_EQUAL(compression_methods_len, 1); + uint32_t compression_method_pos = client_hello_stuffer.read_cursor; + + /* Overwrite the compression method in the second ClientHello. */ + EXPECT_SUCCESS(s2n_stuffer_rewrite(&client_hello_stuffer)); + EXPECT_SUCCESS(s2n_stuffer_skip_write(&client_hello_stuffer, compression_method_pos)); + EXPECT_SUCCESS(s2n_stuffer_write_uint8(&client_hello_stuffer, test_compression_method)); + + if (test_compression_method == 0) { + /* A second ClientHello with a compression method of 0 shouldn't be different from + * the first ClientHello, so validation should succeed. + */ + EXPECT_SUCCESS(s2n_client_hello_recv(server_conn)); + } else { + EXPECT_FAILURE_WITH_ERRNO(s2n_client_hello_recv(server_conn), S2N_ERR_BAD_MESSAGE); + } + }; + + /* The server accepts a second ClientHello with a changed supported versions extension */ + { + DEFER_CLEANUP(struct s2n_connection *server_conn = s2n_connection_new(S2N_SERVER), + s2n_connection_ptr_free); + EXPECT_NOT_NULL(server_conn); + EXPECT_SUCCESS(s2n_connection_set_blinding(server_conn, S2N_SELF_SERVICE_BLINDING)); + EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config)); + + DEFER_CLEANUP(struct s2n_connection *client_conn = s2n_connection_new(S2N_CLIENT), + s2n_connection_ptr_free); + EXPECT_NOT_NULL(client_conn); + EXPECT_SUCCESS(s2n_connection_set_blinding(client_conn, S2N_SELF_SERVICE_BLINDING)); + EXPECT_SUCCESS(s2n_connection_set_config(client_conn, config)); + + struct s2n_test_io_pair io_pair = { 0 }; + EXPECT_SUCCESS(s2n_io_pair_init_non_blocking(&io_pair)); + EXPECT_SUCCESS(s2n_connections_set_io_pair(client_conn, server_conn, &io_pair)); + + struct s2n_security_policy test_policy = security_policy_test_tls13_retry; + test_policy.minimum_protocol_version = S2N_TLS10; + + /* Force the HRR path. */ + client_conn->security_policy_override = &test_policy; + + /* Skip to after the first ClientHello is received. */ + s2n_blocked_status blocked = 0; + EXPECT_OK(s2n_negotiate_until_message(client_conn, &blocked, SERVER_HELLO)); + EXPECT_OK(s2n_negotiate_until_message(server_conn, &blocked, HELLO_RETRY_MSG)); + + struct s2n_client_hello *client_hello = s2n_connection_get_client_hello(server_conn); + EXPECT_NOT_NULL(client_hello); + ssize_t first_supported_versions_length = s2n_client_hello_get_extension_length(client_hello, + S2N_EXTENSION_SUPPORTED_VERSIONS); + + /* Skip to before the client sends the second ClientHello. */ + EXPECT_OK(s2n_negotiate_until_message(server_conn, &blocked, CLIENT_HELLO)); + EXPECT_OK(s2n_negotiate_until_message(client_conn, &blocked, CLIENT_HELLO)); + + /* Increase the minimum protocol version for the security policy to send fewer + * supported versions in the second ClientHello. + */ + test_policy.minimum_protocol_version = S2N_TLS11; + + EXPECT_SUCCESS(s2n_negotiate_test_server_and_client(server_conn, client_conn)); + + /* Ensure that the supported versions extension changed. */ + ssize_t second_supported_versions_length = s2n_client_hello_get_extension_length(client_hello, + S2N_EXTENSION_SUPPORTED_VERSIONS); + EXPECT_TRUE(first_supported_versions_length != second_supported_versions_length); + } + + /* Test: The server rejects a supported versions extension with < TLS 1.3 in the second ClientHello */ + for (uint8_t test_version = S2N_TLS10; test_version <= S2N_TLS13; test_version++) { + DEFER_CLEANUP(struct s2n_connection *server_conn = s2n_connection_new(S2N_SERVER), + s2n_connection_ptr_free); + EXPECT_NOT_NULL(server_conn); + EXPECT_SUCCESS(s2n_connection_set_blinding(server_conn, S2N_SELF_SERVICE_BLINDING)); + EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config)); + + DEFER_CLEANUP(struct s2n_connection *client_conn = s2n_connection_new(S2N_CLIENT), + s2n_connection_ptr_free); + EXPECT_NOT_NULL(client_conn); + EXPECT_SUCCESS(s2n_connection_set_blinding(client_conn, S2N_SELF_SERVICE_BLINDING)); + EXPECT_SUCCESS(s2n_connection_set_config(client_conn, config)); + + struct s2n_test_io_pair io_pair = { 0 }; + EXPECT_SUCCESS(s2n_io_pair_init_non_blocking(&io_pair)); + EXPECT_SUCCESS(s2n_connections_set_io_pair(client_conn, server_conn, &io_pair)); + + /* Force the HRR path. */ + client_conn->security_policy_override = &security_policy_test_tls13_retry; + + /* Skip to before the client sends the second ClientHello. */ + s2n_blocked_status blocked = 0; + EXPECT_OK(s2n_negotiate_until_message(client_conn, &blocked, SERVER_HELLO)); + EXPECT_OK(s2n_negotiate_until_message(server_conn, &blocked, HELLO_RETRY_MSG)); + EXPECT_OK(s2n_negotiate_until_message(server_conn, &blocked, CLIENT_HELLO)); + EXPECT_OK(s2n_negotiate_until_message(client_conn, &blocked, CLIENT_HELLO)); + + /* Send the second ClientHello. */ + EXPECT_SUCCESS(s2n_client_hello_send(client_conn)); + EXPECT_SUCCESS(s2n_stuffer_wipe(&server_conn->handshake.io)); + EXPECT_SUCCESS(s2n_stuffer_copy(&client_conn->handshake.io, &server_conn->handshake.io, + s2n_stuffer_data_available(&client_conn->handshake.io))); + + /* Parse the ClientHello, but don't process the extensions yet. */ + EXPECT_SUCCESS(s2n_parse_client_hello(server_conn)); + server_conn->client_hello.parsed = true; + + uint8_t extension_data[3] = { 0 }; + struct s2n_blob extension_blob = { 0 }; + EXPECT_SUCCESS(s2n_blob_init(&extension_blob, extension_data, sizeof(extension_data))); + struct s2n_stuffer extension_stuffer = { 0 }; + EXPECT_SUCCESS(s2n_stuffer_init(&extension_stuffer, &extension_blob)); + + /* Overwrite the received supported versions extension with only the test version. */ + uint8_t extension_length = 2; + EXPECT_SUCCESS(s2n_stuffer_write_uint8(&extension_stuffer, extension_length)); + EXPECT_SUCCESS(s2n_stuffer_write_uint8(&extension_stuffer, test_version / 10)); + EXPECT_SUCCESS(s2n_stuffer_write_uint8(&extension_stuffer, test_version % 10)); + + struct s2n_client_hello *second_client_hello = s2n_connection_get_client_hello(server_conn); + EXPECT_NOT_NULL(second_client_hello); + s2n_extension_type_id supported_versions_id = 0; + EXPECT_SUCCESS(s2n_extension_supported_iana_value_to_id(S2N_EXTENSION_SUPPORTED_VERSIONS, &supported_versions_id)); + s2n_parsed_extension *extension = &second_client_hello->extensions.parsed_extensions[supported_versions_id]; + extension->extension_type = S2N_EXTENSION_SUPPORTED_VERSIONS; + extension->extension = extension_blob; + + int ret = s2n_client_hello_recv(server_conn); + if (test_version == S2N_TLS13) { + EXPECT_SUCCESS(ret); + } else { + EXPECT_FAILURE_WITH_ERRNO(ret, S2N_ERR_PROTOCOL_VERSION_UNSUPPORTED); + } + } + /* Test: The server rejects a second ClientHello with a changed extension */ { DEFER_CLEANUP(struct s2n_connection *server_conn = s2n_connection_new(S2N_SERVER), diff --git a/tests/unit/s2n_client_hello_test.c b/tests/unit/s2n_client_hello_test.c index c1197809102..e0e864b6448 100644 --- a/tests/unit/s2n_client_hello_test.c +++ b/tests/unit/s2n_client_hello_test.c @@ -25,7 +25,6 @@ #include "s2n_test.h" #include "testlib/s2n_sslv2_client_hello.h" #include "testlib/s2n_testlib.h" -#include "tls/s2n_client_hello.c" #include "tls/s2n_connection.h" #include "tls/s2n_handshake.h" #include "tls/s2n_quic_support.h" @@ -42,11 +41,16 @@ #define TLS12_LENGTH_TO_CIPHER_LIST (LENGTH_TO_SESSION_ID + 1) #define TLS13_LENGTH_TO_CIPHER_LIST (TLS12_LENGTH_TO_CIPHER_LIST + S2N_TLS_SESSION_ID_MAX_LEN) +#define COMPRESSION_METHODS 0x00, 0x01, 0x02, 0x03, 0x04 +#define COMPRESSION_METHODS_LEN 0x05 + int s2n_parse_client_hello(struct s2n_connection *conn); +S2N_RESULT s2n_client_hello_get_raw_extension(uint16_t extension_iana, + struct s2n_blob *raw_extensions, struct s2n_blob *extension); int main(int argc, char **argv) { - struct s2n_cert_chain_and_key *chain_and_key, *ecdsa_chain_and_key; + struct s2n_cert_chain_and_key *chain_and_key = NULL, *ecdsa_chain_and_key = NULL; BEGIN_TEST(); EXPECT_SUCCESS(s2n_disable_tls13_in_test()); @@ -62,12 +66,12 @@ int main(int argc, char **argv) { /* Test with invalid parsed extensions */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); s2n_tls_extension_type test_extension_type = S2N_EXTENSION_SERVER_NAME; - s2n_extension_type_id test_extension_type_id; + s2n_extension_type_id test_extension_type_id = 0; EXPECT_SUCCESS(s2n_extension_supported_iana_value_to_id(test_extension_type, &test_extension_type_id)); uint8_t data[] = "data"; @@ -93,7 +97,7 @@ int main(int argc, char **argv) /* Test s2n_client_hello_has_extension */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); uint8_t data[] = { @@ -210,12 +214,12 @@ int main(int argc, char **argv) /* Test setting cert chain on recv */ { s2n_enable_tls13_in_test(); - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); /* TLS13 fails to parse client hello when no certs set */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); conn->client_protocol_version = conn->server_protocol_version; @@ -232,7 +236,7 @@ int main(int argc, char **argv) /* TLS13 successfully sets certs */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); conn->client_protocol_version = conn->server_protocol_version; @@ -307,7 +311,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_enable_tls13_in_test()); } - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); struct s2n_stuffer *hello_stuffer = &conn->handshake.io; @@ -321,7 +325,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_stuffer_read_uint8(hello_stuffer, &session_id_length)); EXPECT_EQUAL(session_id_length, S2N_TLS_SESSION_ID_MAX_LEN); - uint8_t *session_id; + uint8_t *session_id = NULL; EXPECT_NOT_NULL(session_id = s2n_stuffer_raw_read(hello_stuffer, S2N_TLS_SESSION_ID_MAX_LEN)); EXPECT_BYTEARRAY_EQUAL(session_id, test_session_id, S2N_TLS_SESSION_ID_MAX_LEN); @@ -335,7 +339,7 @@ int main(int argc, char **argv) /* Generate a session id by default */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); struct s2n_stuffer *hello_stuffer = &conn->handshake.io; @@ -353,11 +357,11 @@ int main(int argc, char **argv) * For now, middlebox compatibility mode is only disabled by QUIC. */ { - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_enable_quic(config)); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); struct s2n_stuffer *hello_stuffer = &conn->handshake.io; @@ -417,7 +421,7 @@ int main(int argc, char **argv) { /* Do NOT generate a session id by default */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); struct s2n_stuffer *hello_stuffer = &conn->handshake.io; @@ -433,11 +437,11 @@ int main(int argc, char **argv) /* Generate a session id if using tickets */ { - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_set_session_tickets_onoff(config, true)); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); struct s2n_stuffer *hello_stuffer = &conn->handshake.io; @@ -461,7 +465,7 @@ int main(int argc, char **argv) { /* TLS 1.3 cipher suites NOT written by client by default */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); struct s2n_stuffer *hello_stuffer = &conn->handshake.io; @@ -474,7 +478,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_stuffer_read_uint16(hello_stuffer, &list_length)); EXPECT_NOT_EQUAL(list_length, 0); - uint8_t first_cipher_byte; + uint8_t first_cipher_byte = 0; for (int i = 0; i < list_length; i++) { EXPECT_SUCCESS(s2n_stuffer_read_uint8(hello_stuffer, &first_cipher_byte)); EXPECT_NOT_EQUAL(first_cipher_byte, 0x13); @@ -486,7 +490,7 @@ int main(int argc, char **argv) /* TLS 1.3 cipher suites NOT written by client even if included in security policy */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_cipher_preferences(conn, "default_tls13")); @@ -500,7 +504,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_stuffer_read_uint16(hello_stuffer, &list_length)); EXPECT_NOT_EQUAL(list_length, 0); - uint8_t first_cipher_byte; + uint8_t first_cipher_byte = 0; for (int i = 0; i < list_length; i++) { EXPECT_SUCCESS(s2n_stuffer_read_uint8(hello_stuffer, &first_cipher_byte)); EXPECT_NOT_EQUAL(first_cipher_byte, 0x13); @@ -515,13 +519,13 @@ int main(int argc, char **argv) if (s2n_is_tls13_fully_supported()) { EXPECT_SUCCESS(s2n_enable_tls13_in_test()); - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); s2n_config_set_session_tickets_onoff(config, 0); /* TLS 1.3 cipher suites written by client */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); @@ -536,7 +540,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_stuffer_read_uint16(hello_stuffer, &list_length)); EXPECT_NOT_EQUAL(list_length, 0); - uint8_t first_cipher_byte; + uint8_t first_cipher_byte = 0; int tls13_ciphers_found = 0; for (int i = 0; i < list_length; i++) { EXPECT_SUCCESS(s2n_stuffer_read_uint8(hello_stuffer, &first_cipher_byte)); @@ -701,13 +705,13 @@ int main(int argc, char **argv) { EXPECT_SUCCESS(s2n_enable_tls13_in_test()); - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); { /* TLS 1.3 client cipher preference uses TLS13 version */ - struct s2n_connection *conn; - const struct s2n_security_policy *security_policy; + struct s2n_connection *conn = NULL; + const struct s2n_security_policy *security_policy = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); EXPECT_SUCCESS(s2n_config_set_cipher_preferences(config, "default_tls13")); @@ -724,12 +728,12 @@ int main(int argc, char **argv) { /* TLS 1.2 client cipher preference uses TLS12 version */ - struct s2n_connection *conn; + 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")); - const struct s2n_security_policy *security_policy; + const struct s2n_security_policy *security_policy = NULL; POSIX_GUARD(s2n_connection_get_security_policy(conn, &security_policy)); EXPECT_FALSE(s2n_security_policy_supports_tls13(security_policy)); @@ -743,8 +747,8 @@ int main(int argc, char **argv) { /* TLS 1.3 client cipher preference uses TLS13 version */ - struct s2n_connection *client_conn, *server_conn; - const struct s2n_security_policy *security_policy; + struct s2n_connection *client_conn = NULL, *server_conn = NULL; + const struct s2n_security_policy *security_policy = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(client_conn, config)); @@ -761,7 +765,7 @@ int main(int argc, char **argv) /* Server configured with TLS 1.2 negotiates TLS12 version */ EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); - struct s2n_config *server_config; + struct s2n_config *server_config = NULL; EXPECT_NOT_NULL(server_config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(server_config, chain_and_key)); EXPECT_SUCCESS(s2n_connection_set_config(server_conn, server_config)); @@ -790,8 +794,8 @@ int main(int argc, char **argv) /* SSlv2 client hello */ { - struct s2n_connection *server_conn; - struct s2n_config *server_config; + struct s2n_connection *server_conn = NULL; + struct s2n_config *server_config = NULL; s2n_blocked_status server_blocked; uint8_t sslv2_client_hello[] = { @@ -879,7 +883,7 @@ int main(int argc, char **argv) EXPECT_EQUAL(s2n_client_hello_get_extensions_length(client_hello), 0); /* Verify s2n_client_hello_get_session_id_length correct */ - uint32_t ch_session_id_length; + uint32_t ch_session_id_length = 0; EXPECT_SUCCESS(s2n_client_hello_get_session_id_length(client_hello, &ch_session_id_length)); EXPECT_EQUAL(ch_session_id_length, 0); @@ -913,11 +917,11 @@ int main(int argc, char **argv) /* Minimal TLS 1.2 client hello. */ { - struct s2n_connection *server_conn; - struct s2n_config *server_config; + struct s2n_connection *server_conn = NULL; + struct s2n_config *server_config = NULL; s2n_blocked_status server_blocked; - uint8_t *sent_client_hello; - uint8_t *expected_client_hello; + uint8_t *sent_client_hello = NULL; + uint8_t *expected_client_hello = NULL; uint8_t client_extensions[] = { /* Extension type TLS_EXTENSION_SERVER_NAME */ @@ -1026,7 +1030,7 @@ int main(int argc, char **argv) /* Verify s2n_connection_get_client_hello returns null if client hello not yet processed */ EXPECT_NULL(s2n_connection_get_client_hello(server_conn)); - uint8_t *ext_data; + uint8_t *ext_data = NULL; EXPECT_NOT_NULL(ext_data = malloc(server_name_extension_len)); /* Verify we don't get extension and it's length when client hello is not yet processed */ EXPECT_FAILURE(s2n_client_hello_get_extension_length(s2n_connection_get_client_hello(server_conn), S2N_EXTENSION_SERVER_NAME)); @@ -1072,7 +1076,7 @@ int main(int argc, char **argv) /* Verify s2n_client_hello_get_raw_message_length correct */ EXPECT_EQUAL(s2n_client_hello_get_raw_message_length(client_hello), sent_client_hello_len); - uint8_t *raw_ch_out; + uint8_t *raw_ch_out = NULL; /* Verify s2n_client_hello_get_raw_message retrieves the full message when its len <= max_len */ EXPECT_TRUE(collected_client_hello_len < S2N_LARGE_RECORD_LENGTH); @@ -1103,7 +1107,7 @@ int main(int argc, char **argv) EXPECT_EQUAL(s2n_client_hello_get_cipher_suites_length(client_hello), sizeof(expected_cs)); /* Verify s2n_client_hello_get_cipher_suites correct */ - uint8_t *cs_out; + uint8_t *cs_out = NULL; /* Verify s2n_client_hello_get_cipher_suites retrieves the full cipher_suites when its len <= max_len */ EXPECT_TRUE(client_hello->cipher_suites.size < S2N_LARGE_RECORD_LENGTH); @@ -1133,7 +1137,7 @@ int main(int argc, char **argv) EXPECT_EQUAL(s2n_client_hello_get_extensions_length(client_hello), client_extensions_len); /* Verify s2n_client_hello_get_extensions correct */ - uint8_t *extensions_out; + uint8_t *extensions_out = NULL; /* Verify s2n_client_hello_get_extensions retrieves the full cipher_suites when its len <= max_len */ EXPECT_TRUE(client_hello->extensions.raw.size < S2N_LARGE_RECORD_LENGTH); @@ -1189,7 +1193,7 @@ int main(int argc, char **argv) /* Verify s2n_client_hello_get_session_id is what we received in ClientHello */ uint8_t expected_ch_session_id[] = { ZERO_TO_THIRTY_ONE }; uint8_t ch_session_id[sizeof(expected_ch_session_id)]; - uint32_t ch_session_id_length; + uint32_t ch_session_id_length = 0; EXPECT_SUCCESS(s2n_client_hello_get_session_id_length(client_hello, &ch_session_id_length)); EXPECT_EQUAL(ch_session_id_length, sizeof(ch_session_id)); EXPECT_SUCCESS(s2n_client_hello_get_session_id(client_hello, ch_session_id, &ch_session_id_length, sizeof(ch_session_id))); @@ -1268,7 +1272,7 @@ int main(int argc, char **argv) /* Client hello api with NULL inputs */ { uint32_t len = 128; - uint8_t *out; + uint8_t *out = NULL; EXPECT_NOT_NULL(out = malloc(len)); EXPECT_FAILURE(s2n_client_hello_get_raw_message_length(NULL)); @@ -1289,10 +1293,10 @@ int main(int argc, char **argv) /* test_weird_client_hello_version() */ { - struct s2n_connection *server_conn; - struct s2n_config *server_config; + struct s2n_connection *server_conn = NULL; + struct s2n_config *server_config = NULL; s2n_blocked_status server_blocked; - uint8_t *sent_client_hello; + uint8_t *sent_client_hello = NULL; uint8_t client_extensions[] = { /* Extension type TLS_EXTENSION_SERVER_NAME */ @@ -1434,14 +1438,14 @@ int main(int argc, char **argv) EXPECT_TRUE(client_cipher_suites[0]->available); - struct s2n_cert_chain_and_key *ecdsa_cert_chain; + struct s2n_cert_chain_and_key *ecdsa_cert_chain = NULL; EXPECT_SUCCESS(s2n_test_cert_chain_and_key_new(&ecdsa_cert_chain, S2N_ECDSA_P384_PKCS1_CERT_CHAIN, S2N_ECDSA_P384_PKCS1_KEY)); char dhparams_pem[S2N_MAX_TEST_PEM_SIZE]; EXPECT_SUCCESS(s2n_read_test_pem(S2N_DEFAULT_TEST_DHPARAMS, dhparams_pem, S2N_MAX_TEST_PEM_SIZE)); /* Create Configs */ - struct s2n_config *server_config, *client_config; + struct s2n_config *server_config = NULL, *client_config = NULL; EXPECT_NOT_NULL(server_config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(server_config, ecdsa_cert_chain)); @@ -1682,6 +1686,244 @@ int main(int argc, char **argv) }; }; + /* s2n_client_hello_get_compression_methods */ + { + /* Safety */ + { + uint32_t length = 0; + struct s2n_client_hello client_hello = { 0 }; + EXPECT_FAILURE_WITH_ERRNO(s2n_client_hello_get_compression_methods_length(NULL, &length), S2N_ERR_NULL); + EXPECT_FAILURE_WITH_ERRNO(s2n_client_hello_get_compression_methods_length(&client_hello, NULL), S2N_ERR_NULL); + + uint8_t list = 0; + uint32_t list_length = 0; + uint32_t out_length = 0; + EXPECT_FAILURE_WITH_ERRNO(s2n_client_hello_get_compression_methods(NULL, &list, list_length, &out_length), S2N_ERR_NULL); + EXPECT_FAILURE_WITH_ERRNO(s2n_client_hello_get_compression_methods(&client_hello, NULL, list_length, &out_length), S2N_ERR_NULL); + EXPECT_FAILURE_WITH_ERRNO(s2n_client_hello_get_compression_methods(&client_hello, &list, list_length, NULL), S2N_ERR_NULL); + + /* User did not provide a large enough buffer to write the compression methods */ + uint8_t data[] = { 1, 2, 3, 4, 5 }; + EXPECT_SUCCESS(s2n_blob_init(&client_hello.compression_methods, data, sizeof(data))); + EXPECT_FAILURE_WITH_ERRNO(s2n_client_hello_get_compression_methods(&client_hello, &list, list_length, &out_length), + S2N_ERR_INSUFFICIENT_MEM_SIZE); + }; + + /* Retrieves the compression methods list */ + { + DEFER_CLEANUP(struct s2n_connection *client_conn = s2n_connection_new(S2N_CLIENT), + s2n_connection_ptr_free); + DEFER_CLEANUP(struct s2n_connection *server_conn = s2n_connection_new(S2N_SERVER), + s2n_connection_ptr_free); + EXPECT_NOT_NULL(server_conn); + EXPECT_NOT_NULL(client_conn); + + DEFER_CLEANUP(struct s2n_config *config = s2n_config_new(), + s2n_config_ptr_free); + EXPECT_NOT_NULL(config); + + EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(config, chain_and_key)); + EXPECT_SUCCESS(s2n_connection_set_config(client_conn, config)); + EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config)); + + EXPECT_SUCCESS(s2n_client_hello_send(client_conn)); + EXPECT_SUCCESS(s2n_stuffer_copy(&client_conn->handshake.io, &server_conn->handshake.io, + s2n_stuffer_data_available(&client_conn->handshake.io))); + EXPECT_SUCCESS(s2n_client_hello_recv(server_conn)); + + struct s2n_client_hello *client_hello = s2n_connection_get_client_hello(server_conn); + EXPECT_NOT_NULL(client_hello); + + uint32_t length = 0; + EXPECT_SUCCESS(s2n_client_hello_get_compression_methods_length(client_hello, &length)); + EXPECT_EQUAL(length, 1); + uint8_t list = 0; + uint32_t out_length = 0; + EXPECT_SUCCESS(s2n_client_hello_get_compression_methods(client_hello, &list, sizeof(list), &out_length)); + EXPECT_EQUAL(out_length, 1); + }; + + /* Retrieves compression methods list longer than one byte */ + { + /* Compression methods were deprecated in TLS13 and s2n has never + * supported them. However, it is conceivable that a client could send + * us a list that contains more than the "null" byte. Therefore, we construct + * a fake Client Hello that contains a longer list of compression methods + * for testing. + */ + uint8_t client_hello_message[] = { + /* Protocol version TLS 1.2 */ + 0x03, 0x03, + /* Client random */ + ZERO_TO_THIRTY_ONE, + /* SessionID len - 32 bytes */ + 0x20, + /* Session ID */ + ZERO_TO_THIRTY_ONE, + /* Cipher suites len */ + 0x00, 0x02, + /* Cipher suite - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 */ + 0xC0, 0x2F, + COMPRESSION_METHODS_LEN, + COMPRESSION_METHODS, + /* Extensions len */ + 0x00, 0x00 + }; + + DEFER_CLEANUP(struct s2n_connection *server_conn = s2n_connection_new(S2N_SERVER), + s2n_connection_ptr_free); + EXPECT_NOT_NULL(server_conn); + + DEFER_CLEANUP(struct s2n_config *config = s2n_config_new(), + s2n_config_ptr_free); + EXPECT_NOT_NULL(config); + + EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(config, chain_and_key)); + EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config)); + + EXPECT_SUCCESS(s2n_stuffer_write_bytes(&server_conn->handshake.io, client_hello_message, sizeof(client_hello_message))); + EXPECT_SUCCESS(s2n_client_hello_recv(server_conn)); + + struct s2n_client_hello *client_hello = s2n_connection_get_client_hello(server_conn); + EXPECT_NOT_NULL(client_hello); + + uint32_t length = 0; + EXPECT_SUCCESS(s2n_client_hello_get_compression_methods_length(client_hello, &length)); + EXPECT_EQUAL(length, COMPRESSION_METHODS_LEN); + uint8_t list[5] = { 0 }; + uint32_t out_length = 0; + EXPECT_SUCCESS(s2n_client_hello_get_compression_methods(client_hello, list, sizeof(list), &out_length)); + EXPECT_EQUAL(out_length, COMPRESSION_METHODS_LEN); + + uint8_t compression_data[] = { COMPRESSION_METHODS }; + EXPECT_BYTEARRAY_EQUAL(list, compression_data, out_length); + } + }; + + /* s2n_client_hello_get_legacy_protocol_version */ + { + /* Safety */ + { + uint8_t out = 0; + struct s2n_client_hello client_hello = { 0 }; + EXPECT_FAILURE_WITH_ERRNO(s2n_client_hello_get_legacy_protocol_version(NULL, &out), S2N_ERR_NULL); + EXPECT_FAILURE_WITH_ERRNO(s2n_client_hello_get_legacy_protocol_version(&client_hello, NULL), S2N_ERR_NULL); + }; + + /* Retrieves the Client Hello protocol version */ + { + DEFER_CLEANUP(struct s2n_connection *client_conn = s2n_connection_new(S2N_CLIENT), + s2n_connection_ptr_free); + DEFER_CLEANUP(struct s2n_connection *server_conn = s2n_connection_new(S2N_SERVER), + s2n_connection_ptr_free); + EXPECT_NOT_NULL(server_conn); + EXPECT_NOT_NULL(client_conn); + + DEFER_CLEANUP(struct s2n_config *config = s2n_config_new(), + s2n_config_ptr_free); + EXPECT_NOT_NULL(config); + + EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(config, chain_and_key)); + EXPECT_SUCCESS(s2n_connection_set_config(client_conn, config)); + EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config)); + + EXPECT_SUCCESS(s2n_client_hello_send(client_conn)); + EXPECT_SUCCESS(s2n_stuffer_copy(&client_conn->handshake.io, &server_conn->handshake.io, + s2n_stuffer_data_available(&client_conn->handshake.io))); + EXPECT_SUCCESS(s2n_client_hello_recv(server_conn)); + + struct s2n_client_hello *client_hello = s2n_connection_get_client_hello(server_conn); + EXPECT_NOT_NULL(client_hello); + + uint8_t version = 0; + EXPECT_SUCCESS(s2n_client_hello_get_legacy_protocol_version(client_hello, &version)); + EXPECT_EQUAL(version, S2N_TLS12); + }; + }; + + /* s2n_client_hello_get_legacy_record_version */ + { + /* Safety */ + { + uint8_t out = 0; + struct s2n_client_hello client_hello = { 0 }; + + EXPECT_FAILURE_WITH_ERRNO(s2n_client_hello_get_legacy_record_version(NULL, &out), S2N_ERR_NULL); + EXPECT_FAILURE_WITH_ERRNO(s2n_client_hello_get_legacy_record_version(&client_hello, NULL), S2N_ERR_NULL); + }; + + /* Retrieves record version */ + { + uint8_t out = 0; + struct s2n_client_hello client_hello = { 0 }; + client_hello.legacy_record_version = S2N_TLS12; + client_hello.record_version_recorded = 1; + EXPECT_SUCCESS(s2n_client_hello_get_legacy_record_version(&client_hello, &out)); + EXPECT_EQUAL(out, S2N_TLS12); + }; + }; + + /* s2n_client_hello_get_server_name() */ + { + /* Safety */ + { + struct s2n_client_hello ch = { 0 }; + uint16_t length = 0; + EXPECT_FAILURE_WITH_ERRNO(s2n_client_hello_get_server_name_length(NULL, &length), S2N_ERR_NULL); + EXPECT_FAILURE_WITH_ERRNO(s2n_client_hello_get_server_name_length(&ch, NULL), S2N_ERR_NULL); + + uint8_t buffer = 0; + uint16_t out_length = 0; + EXPECT_FAILURE_WITH_ERRNO(s2n_client_hello_get_server_name(NULL, &buffer, 0, &out_length), S2N_ERR_NULL); + EXPECT_FAILURE_WITH_ERRNO(s2n_client_hello_get_server_name(&ch, NULL, 0, &out_length), S2N_ERR_NULL); + EXPECT_FAILURE_WITH_ERRNO(s2n_client_hello_get_server_name(&ch, &buffer, 0, NULL), S2N_ERR_NULL); + }; + + /* Retrieves the first entry in the server_name extension */ + { + DEFER_CLEANUP(struct s2n_connection *client_conn = s2n_connection_new(S2N_CLIENT), + s2n_connection_ptr_free); + DEFER_CLEANUP(struct s2n_connection *server_conn = s2n_connection_new(S2N_SERVER), + s2n_connection_ptr_free); + EXPECT_NOT_NULL(server_conn); + EXPECT_NOT_NULL(client_conn); + + DEFER_CLEANUP(struct s2n_config *config = s2n_config_new(), + s2n_config_ptr_free); + EXPECT_NOT_NULL(config); + + EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(config, chain_and_key)); + EXPECT_SUCCESS(s2n_connection_set_config(client_conn, config)); + EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config)); + + const char *test_server_name = "test server name!"; + EXPECT_SUCCESS(s2n_set_server_name(client_conn, test_server_name)); + + EXPECT_SUCCESS(s2n_client_hello_send(client_conn)); + EXPECT_SUCCESS(s2n_stuffer_copy(&client_conn->handshake.io, &server_conn->handshake.io, + s2n_stuffer_data_available(&client_conn->handshake.io))); + EXPECT_SUCCESS(s2n_client_hello_recv(server_conn)); + + struct s2n_client_hello *client_hello = s2n_connection_get_client_hello(server_conn); + EXPECT_NOT_NULL(client_hello); + + uint16_t length = 0; + EXPECT_SUCCESS(s2n_client_hello_get_server_name_length(client_hello, &length)); + EXPECT_EQUAL(strlen(test_server_name), length); + uint8_t buffer[20] = { 0 }; + uint16_t out_length = 0; + EXPECT_SUCCESS(s2n_client_hello_get_server_name(client_hello, buffer, sizeof(buffer), &out_length)); + EXPECT_EQUAL(length, out_length); + + EXPECT_BYTEARRAY_EQUAL(buffer, test_server_name, out_length); + + /* Check error occurs if buffer is too small to hold server name */ + uint8_t small_buf[2] = { 0 }; + out_length = 0; + EXPECT_FAILURE_WITH_ERRNO(s2n_client_hello_get_server_name(client_hello, small_buf, sizeof(small_buf), &out_length), S2N_ERR_SAFETY); + }; + }; + EXPECT_SUCCESS(s2n_cert_chain_and_key_free(chain_and_key)); EXPECT_SUCCESS(s2n_cert_chain_and_key_free(ecdsa_chain_and_key)); END_TEST(); diff --git a/tests/unit/s2n_client_key_share_extension_pq_test.c b/tests/unit/s2n_client_key_share_extension_pq_test.c index bae35f96934..0308cde026a 100644 --- a/tests/unit/s2n_client_key_share_extension_pq_test.c +++ b/tests/unit/s2n_client_key_share_extension_pq_test.c @@ -59,14 +59,14 @@ int main() .signature_preferences = &s2n_signature_preferences_20200207, .ecc_preferences = &s2n_ecc_preferences_20200310, }; - uint32_t groups_available; + uint32_t groups_available = 0; /* Tests for s2n_client_key_share_extension.send */ { /* Test that s2n_client_key_share_extension.send sends only ECC key shares * when PQ is disabled, even if tls13_kem_groups is non-null. */ if (!s2n_pq_is_enabled()) { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); conn->security_policy_override = &security_policy_all; @@ -84,13 +84,13 @@ int main() EXPECT_SUCCESS(s2n_client_key_share_extension.send(conn, &key_share_extension)); /* Assert total key shares extension size is correct */ - uint16_t sent_key_shares_size; + uint16_t sent_key_shares_size = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint16(&key_share_extension, &sent_key_shares_size)); EXPECT_EQUAL(sent_key_shares_size, s2n_stuffer_data_available(&key_share_extension)); /* ECC key shares should have the format: IANA ID || size || share. Only one ECC key share * should be sent (as per default s2n behavior). */ - uint16_t iana_value, share_size; + uint16_t iana_value = 0, share_size = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint16(&key_share_extension, &iana_value)); EXPECT_EQUAL(iana_value, ecc_preferences->ecc_curves[0]->iana_id); EXPECT_SUCCESS(s2n_stuffer_read_uint16(&key_share_extension, &share_size)); @@ -134,7 +134,7 @@ int main() /* Test sending of default hybrid key share (non-HRR) */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); conn->security_policy_override = &test_security_policy; @@ -175,13 +175,13 @@ int main() /* Now, assert that the client sent the correct bytes over the wire for the key share extension */ /* Assert total key shares extension size is correct */ - uint16_t sent_key_shares_size; + uint16_t sent_key_shares_size = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint16(&key_share_extension, &sent_key_shares_size)); EXPECT_EQUAL(sent_key_shares_size, s2n_stuffer_data_available(&key_share_extension)); /* Assert that the hybrid key share is correct: * IANA ID || total hybrid share size || ECC share size || ECC share || PQ share size || PQ share */ - uint16_t sent_hybrid_iana_id; + uint16_t sent_hybrid_iana_id = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint16(&key_share_extension, &sent_hybrid_iana_id)); EXPECT_EQUAL(sent_hybrid_iana_id, kem_pref->tls13_kem_groups[0]->iana_id); @@ -215,7 +215,7 @@ int main() EXPECT_SUCCESS(s2n_stuffer_skip_read(&key_share_extension, test_kem_group->kem->public_key_length)); /* Assert that the ECC key share is correct: IANA ID || size || share */ - uint16_t ecc_iana_value, ecc_share_size; + uint16_t ecc_iana_value = 0, ecc_share_size = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint16(&key_share_extension, &ecc_iana_value)); EXPECT_EQUAL(ecc_iana_value, ecc_pref->ecc_curves[0]->iana_id); EXPECT_SUCCESS(s2n_stuffer_read_uint16(&key_share_extension, &ecc_share_size)); @@ -232,7 +232,7 @@ int main() /* Need at least two KEM's to test ClientHelloRetry fallback */ EXPECT_OK(s2n_kem_preferences_groups_available(security_policy_all.kem_preferences, &groups_available)); if (groups_available >= 2) { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); conn->security_policy_override = &test_security_policy; conn->actual_protocol_version = S2N_TLS13; @@ -283,17 +283,17 @@ int main() /* Assert that the client sent the correct bytes over the wire for the key share extension */ /* Assert total key shares extension size is correct */ - uint16_t sent_key_shares_size; + uint16_t sent_key_shares_size = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint16(&key_share_extension, &sent_key_shares_size)); EXPECT_EQUAL(sent_key_shares_size, s2n_stuffer_data_available(&key_share_extension)); /* Assert that the hybrid key share is correct: * IANA ID || total hybrid share size || ECC share size || ECC share || PQ share size || PQ share */ - uint16_t sent_hybrid_iana_id; + uint16_t sent_hybrid_iana_id = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint16(&key_share_extension, &sent_hybrid_iana_id)); EXPECT_EQUAL(sent_hybrid_iana_id, kem_pref->tls13_kem_groups[chosen_index]->iana_id); - uint16_t expected_hybrid_share_size; + uint16_t expected_hybrid_share_size = 0; if (len_prefixed) { expected_hybrid_share_size = S2N_SIZE_OF_KEY_SHARE_SIZE @@ -304,19 +304,19 @@ int main() expected_hybrid_share_size = negotiated_kem_group->curve->share_size + negotiated_kem_group->kem->public_key_length; } - uint16_t sent_hybrid_share_size; + uint16_t sent_hybrid_share_size = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint16(&key_share_extension, &sent_hybrid_share_size)); EXPECT_EQUAL(sent_hybrid_share_size, expected_hybrid_share_size); if (len_prefixed) { - uint16_t hybrid_ecc_share_size; + uint16_t hybrid_ecc_share_size = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint16(&key_share_extension, &hybrid_ecc_share_size)); EXPECT_EQUAL(hybrid_ecc_share_size, negotiated_kem_group->curve->share_size); } EXPECT_SUCCESS(s2n_stuffer_skip_read(&key_share_extension, negotiated_kem_group->curve->share_size)); if (len_prefixed) { - uint16_t hybrid_pq_share_size; + uint16_t hybrid_pq_share_size = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint16(&key_share_extension, &hybrid_pq_share_size)); EXPECT_EQUAL(hybrid_pq_share_size, negotiated_kem_group->kem->public_key_length); } @@ -604,8 +604,8 @@ int main() EXPECT_TRUE(groups_available >= 2); /* Select the two highest priority available KEM groups */ - const struct s2n_kem_group *kem_group0; - const struct s2n_kem_group *kem_group1; + const struct s2n_kem_group *kem_group0 = NULL; + const struct s2n_kem_group *kem_group1 = NULL; EXPECT_SUCCESS(s2n_get_two_highest_piority_kem_groups(kem_pref, &kem_group0, &kem_group1)); EXPECT_NOT_NULL(kem_group0); EXPECT_NOT_NULL(kem_group1); @@ -732,8 +732,8 @@ int main() EXPECT_TRUE(groups_available >= 2); /* Select the two highest priority available KEM groups */ - const struct s2n_kem_group *kem_group0; - const struct s2n_kem_group *kem_group1; + const struct s2n_kem_group *kem_group0 = NULL; + const struct s2n_kem_group *kem_group1 = NULL; EXPECT_SUCCESS(s2n_get_two_highest_piority_kem_groups(kem_pref, &kem_group0, &kem_group1)); EXPECT_NOT_NULL(kem_group0); EXPECT_NOT_NULL(kem_group1); @@ -792,8 +792,8 @@ int main() EXPECT_TRUE(groups_available >= 2); /* Select the two highest priority available KEM groups */ - const struct s2n_kem_group *kem_group0; - const struct s2n_kem_group *kem_group1; + const struct s2n_kem_group *kem_group0 = NULL; + const struct s2n_kem_group *kem_group1 = NULL; EXPECT_SUCCESS(s2n_get_two_highest_piority_kem_groups(kem_pref, &kem_group0, &kem_group1)); EXPECT_NOT_NULL(kem_group0); EXPECT_NOT_NULL(kem_group1); @@ -858,8 +858,8 @@ int main() EXPECT_TRUE(groups_available >= 2); /* Select the two highest priority available KEM groups */ - const struct s2n_kem_group *kem_group0; - const struct s2n_kem_group *kem_group1; + const struct s2n_kem_group *kem_group0 = NULL; + const struct s2n_kem_group *kem_group1 = NULL; EXPECT_SUCCESS(s2n_get_two_highest_piority_kem_groups(kem_pref, &kem_group0, &kem_group1)); EXPECT_NOT_NULL(kem_group0); EXPECT_NOT_NULL(kem_group1); diff --git a/tests/unit/s2n_client_key_share_extension_test.c b/tests/unit/s2n_client_key_share_extension_test.c index e92bea06382..f929d1629d3 100644 --- a/tests/unit/s2n_client_key_share_extension_test.c +++ b/tests/unit/s2n_client_key_share_extension_test.c @@ -70,7 +70,7 @@ int main(int argc, char **argv) /* Test that s2n_extensions_key_share_size produces the expected constant result */ { struct s2n_stuffer key_share_extension = { 0 }; - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); uint32_t key_share_size = 0; @@ -96,7 +96,7 @@ int main(int argc, char **argv) /* Test that s2n_client_key_share_extension.send initializes the client key share list */ { struct s2n_stuffer key_share_extension = { 0 }; - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_stuffer_growable_alloc(&key_share_extension, 0)); @@ -117,13 +117,13 @@ int main(int argc, char **argv) /* Test that s2n_client_key_share_extension.send writes a well-formed list of key shares */ { struct s2n_stuffer key_share_extension = { 0 }; - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_stuffer_growable_alloc(&key_share_extension, 0)); EXPECT_SUCCESS(s2n_client_key_share_extension.send(conn, &key_share_extension)); /* should have correct shares size */ - uint16_t key_shares_size; + uint16_t key_shares_size = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint16(&key_share_extension, &key_shares_size)); uint16_t actual_key_shares_size = s2n_stuffer_data_available(&key_share_extension); EXPECT_EQUAL(key_shares_size, actual_key_shares_size); @@ -134,7 +134,7 @@ int main(int argc, char **argv) EXPECT_NOT_NULL(ecc_preferences); /* should contain only the default supported curve */ - uint16_t iana_value, share_size; + uint16_t iana_value = 0, share_size = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint16(&key_share_extension, &iana_value)); EXPECT_EQUAL(iana_value, ecc_preferences->ecc_curves[0]->iana_id); EXPECT_SUCCESS(s2n_stuffer_read_uint16(&key_share_extension, &share_size)); @@ -150,8 +150,8 @@ int main(int argc, char **argv) * but not present in the ecc_preferences list selected */ if (s2n_is_evp_apis_supported()) { struct s2n_stuffer key_share_extension = { 0 }; - struct s2n_connection *conn; - struct s2n_config *config; + struct s2n_connection *conn = NULL; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); /* Explicitly set the ecc_preferences list to contain the curves p-256 and p-384 */ @@ -198,8 +198,8 @@ int main(int argc, char **argv) *# of the triggering HelloRetryRequest. **/ if (s2n_is_evp_apis_supported()) { - struct s2n_connection *conn; - struct s2n_config *config; + struct s2n_connection *conn = NULL; + struct s2n_config *config = NULL; struct s2n_stuffer key_share_extension = { 0 }; EXPECT_NOT_NULL(config = s2n_config_new()); @@ -230,7 +230,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_client_key_share_extension.send(conn, &key_share_extension)); - uint16_t key_shares_size; + uint16_t key_shares_size = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint16(&key_share_extension, &key_shares_size)); EXPECT_EQUAL(s2n_stuffer_data_available(&key_share_extension), key_shares_size); @@ -238,7 +238,7 @@ int main(int argc, char **argv) uint32_t bytes_processed = 0; EXPECT_EQUAL(key_shares_size, conn->kex_params.server_ecc_evp_params.negotiated_curve->share_size + S2N_SIZE_OF_NAMED_GROUP + S2N_SIZE_OF_KEY_SHARE_SIZE); - uint16_t iana_value, share_size; + uint16_t iana_value = 0, share_size = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint16(&key_share_extension, &iana_value)); EXPECT_SUCCESS(s2n_stuffer_read_uint16(&key_share_extension, &share_size)); bytes_processed += conn->kex_params.server_ecc_evp_params.negotiated_curve->share_size + S2N_SIZE_OF_NAMED_GROUP @@ -257,8 +257,8 @@ int main(int argc, char **argv) /* For HelloRetryRequests, test that s2n_client_key_share_extension.recv can read and parse * the result of s2n_client_key_share_extension.send */ { - struct s2n_connection *client_conn; - struct s2n_connection *server_conn; + struct s2n_connection *client_conn = NULL; + struct s2n_connection *server_conn = NULL; struct s2n_stuffer key_share_extension = { 0 }; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); @@ -309,7 +309,7 @@ int main(int argc, char **argv) /* For HelloRetryRequests, test that s2n_client_key_share_extension.send fails, * if the server negotiated_curve is not set and is NULL. */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; struct s2n_stuffer key_share_extension = { 0 }; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); @@ -378,7 +378,7 @@ int main(int argc, char **argv) /* Test that s2n_client_key_share_extension.recv is a no-op * if not using TLS1.3 */ { - struct s2n_connection *client_conn, *server_conn; + struct s2n_connection *client_conn = NULL, *server_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_OK(s2n_set_all_mutually_supported_groups(server_conn)); @@ -406,7 +406,7 @@ int main(int argc, char **argv) /* Test that s2n_client_key_share_extension.recv can read and parse * the result of s2n_client_key_share_extension.send */ { - struct s2n_connection *client_conn, *server_conn; + struct s2n_connection *client_conn = NULL, *server_conn = NULL; struct s2n_stuffer key_share_extension = { 0 }; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); @@ -689,7 +689,7 @@ int main(int argc, char **argv) /* Test that s2n_client_key_share_extension.recv errors on client shares size larger * than available data */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; struct s2n_stuffer key_share_extension = { 0 }; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); conn->actual_protocol_version = S2N_TLS13; @@ -711,7 +711,7 @@ int main(int argc, char **argv) /* Test that s2n_client_key_share_extension.recv errors on key share size longer than data */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; struct s2n_stuffer key_share_extension = { 0 }; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); conn->actual_protocol_version = S2N_TLS13; @@ -736,7 +736,7 @@ int main(int argc, char **argv) /* Test that s2n_client_key_share_extension.recv accepts a subset of supported curves */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; struct s2n_stuffer key_share_extension = { 0 }; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); conn->actual_protocol_version = S2N_TLS13; @@ -769,7 +769,7 @@ int main(int argc, char **argv) /* Test that s2n_client_key_share_extension.recv handles empty client share list */ { - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; struct s2n_stuffer key_share_extension = { 0 }; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_all_protocol_versions(server_conn, S2N_TLS13)); @@ -795,7 +795,7 @@ int main(int argc, char **argv) /* Test that s2n_client_key_share_extension.recv ignores unsupported curves */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; struct s2n_stuffer key_share_extension = { 0 }; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_all_protocol_versions(conn, S2N_TLS13)); @@ -834,7 +834,7 @@ int main(int argc, char **argv) /* Test that s2n_client_key_share_extension.recv ignores curves with incorrect key size */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; struct s2n_stuffer key_share_extension = { 0 }; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_all_protocol_versions(conn, S2N_TLS13)); @@ -867,7 +867,7 @@ int main(int argc, char **argv) /* Test that s2n_client_key_share_extension.recv uses first instance of duplicate curves */ { - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; struct s2n_stuffer key_share_extension = { 0 }; struct s2n_ecc_evp_params first_params, second_params; int supported_curve_index = 0; @@ -911,9 +911,9 @@ int main(int argc, char **argv) /* Test that s2n_client_key_share_extension.recv ignores ECDHE points that can't be parsed */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; struct s2n_stuffer key_share_extension = { 0 }; - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); /* Explicitly set the ecc_preferences list to only contain the curves p-256 and p-384 */ EXPECT_SUCCESS(s2n_config_set_cipher_preferences(config, "20140601")); @@ -956,7 +956,7 @@ int main(int argc, char **argv) /* Test that s2n_client_key_share_extension.recv ignores ECDHE points that can't be parsed, * and continues to parse valid key shares afterwards. */ { - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); /* Explicitly set the ecc_preferences list to only contain the curves p-256 and p-384 */ EXPECT_SUCCESS(s2n_config_set_cipher_preferences(config, "20140601")); @@ -1064,9 +1064,9 @@ int main(int argc, char **argv) */ { if (s2n_is_evp_apis_supported()) { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; struct s2n_stuffer key_share_extension = { 0 }; - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_all_protocol_versions(conn, S2N_TLS13)); diff --git a/tests/unit/s2n_client_max_frag_len_extension_test.c b/tests/unit/s2n_client_max_frag_len_extension_test.c index e282d633caf..6e1e0dc7f7d 100644 --- a/tests/unit/s2n_client_max_frag_len_extension_test.c +++ b/tests/unit/s2n_client_max_frag_len_extension_test.c @@ -24,10 +24,10 @@ int main(int argc, char **argv) /* Test should_send */ { - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); @@ -43,10 +43,10 @@ int main(int argc, char **argv) /* Test send */ { - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); @@ -57,7 +57,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_client_max_frag_len_extension.send(conn, &stuffer)); /* Should have correct fragment length */ - uint8_t actual_frag_len; + uint8_t actual_frag_len = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint8(&stuffer, &actual_frag_len)); EXPECT_EQUAL(actual_frag_len, S2N_TLS_MAX_FRAG_LEN_512); EXPECT_EQUAL(s2n_stuffer_data_available(&stuffer), 0); @@ -69,10 +69,10 @@ int main(int argc, char **argv) /* Test receive - accept_mfl not set */ { - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); @@ -102,11 +102,11 @@ int main(int argc, char **argv) *# handshake with an "illegal_parameter" alert. */ { - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_accept_max_fragment_length(config)); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); @@ -129,11 +129,11 @@ int main(int argc, char **argv) /* Test receive */ { - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_accept_max_fragment_length(config)); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); diff --git a/tests/unit/s2n_client_pq_kem_extension_test.c b/tests/unit/s2n_client_pq_kem_extension_test.c index c4ff26d92a2..cb11a2ac9cb 100644 --- a/tests/unit/s2n_client_pq_kem_extension_test.c +++ b/tests/unit/s2n_client_pq_kem_extension_test.c @@ -37,7 +37,7 @@ int main(int argc, char **argv) /* Test should_send */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); /* Default cipher preferences do not include PQ, so extension not sent */ @@ -56,7 +56,7 @@ int main(int argc, char **argv) /* Test send */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_cipher_preferences(conn, pq_security_policy_version)); @@ -66,13 +66,13 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_client_pq_kem_extension.send(conn, &stuffer)); /* Should write correct size */ - uint16_t size; + uint16_t size = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint16(&stuffer, &size)); EXPECT_EQUAL(size, s2n_stuffer_data_available(&stuffer)); EXPECT_EQUAL(size, kem_preferences->kem_count * sizeof(kem_extension_size)); /* Should write ids */ - uint16_t actual_id; + uint16_t actual_id = 0; for (size_t i = 0; i < kem_preferences->kem_count; i++) { POSIX_GUARD(s2n_stuffer_read_uint16(&stuffer, &actual_id)); EXPECT_EQUAL(actual_id, kem_preferences->kems[i]->kem_extension_id); @@ -84,7 +84,7 @@ int main(int argc, char **argv) /* Test receive - malformed length */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_cipher_preferences(conn, pq_security_policy_version)); @@ -104,7 +104,7 @@ int main(int argc, char **argv) /* Test receive */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_cipher_preferences(conn, pq_security_policy_version)); diff --git a/tests/unit/s2n_client_psk_extension_test.c b/tests/unit/s2n_client_psk_extension_test.c index 13c626a57b2..5f89b493b4a 100644 --- a/tests/unit/s2n_client_psk_extension_test.c +++ b/tests/unit/s2n_client_psk_extension_test.c @@ -151,7 +151,7 @@ int main(int argc, char **argv) /* Test: s2n_client_psk_is_missing */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); /* Okay if early data not requested */ @@ -176,7 +176,7 @@ int main(int argc, char **argv) { struct s2n_psk *psk = NULL; - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_FALSE(s2n_client_psk_extension.should_send(NULL)); @@ -289,7 +289,7 @@ int main(int argc, char **argv) struct s2n_stuffer out = { 0 }; EXPECT_SUCCESS(s2n_stuffer_growable_alloc(&out, 0)); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); struct s2n_psk *psk = NULL; @@ -311,7 +311,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_stuffer_read_uint16(&out, &identity_size)); EXPECT_EQUAL(identity_size, sizeof(test_identity)); - uint8_t *identity_data; + uint8_t *identity_data = NULL; EXPECT_NOT_NULL(identity_data = s2n_stuffer_raw_read(&out, identity_size)); EXPECT_BYTEARRAY_EQUAL(identity_data, test_identity, sizeof(test_identity)); @@ -333,7 +333,7 @@ int main(int argc, char **argv) struct s2n_stuffer out = { 0 }; EXPECT_SUCCESS(s2n_stuffer_growable_alloc(&out, 0)); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); struct s2n_psk_test_case test_cases[] = { @@ -367,7 +367,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_stuffer_read_uint16(&out, &identity_size)); EXPECT_EQUAL(identity_size, test_cases[i].identity_size); - uint8_t *identity_data; + uint8_t *identity_data = NULL; EXPECT_NOT_NULL(identity_data = s2n_stuffer_raw_read(&out, identity_size)); EXPECT_BYTEARRAY_EQUAL(identity_data, test_cases[i].identity, test_cases[i].identity_size); @@ -389,7 +389,7 @@ int main(int argc, char **argv) struct s2n_stuffer out = { 0 }; EXPECT_SUCCESS(s2n_stuffer_growable_alloc(&out, 0)); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); struct s2n_config *config = s2n_config_new(); @@ -445,7 +445,7 @@ int main(int argc, char **argv) }; struct s2n_psk_test_case test_cases[] = { matching_psk, non_matching_psk }; - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); conn->handshake.handshake_type = HELLO_RETRY_REQUEST; conn->secure->cipher_suite = &s2n_tls13_aes_256_gcm_sha384; @@ -557,7 +557,7 @@ int main(int argc, char **argv) { /* Safety checks */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_ERROR_WITH_ERRNO(s2n_select_external_psk(conn, NULL), S2N_ERR_NULL); @@ -643,7 +643,7 @@ int main(int argc, char **argv) }; for (size_t i = 0; i < s2n_array_len(test_cases); i++) { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); conn->psk_params.type = S2N_PSK_TYPE_EXTERNAL; @@ -848,7 +848,7 @@ int main(int argc, char **argv) { struct s2n_stuffer wire_identities_in = { 0 }; - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_ERROR_WITH_ERRNO(s2n_client_psk_recv_identity_list(conn, NULL), S2N_ERR_NULL); @@ -861,7 +861,7 @@ int main(int argc, char **argv) { struct s2n_stuffer empty_wire_identities_in = { 0 }; - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_OK(s2n_connection_set_psk_type(conn, S2N_PSK_TYPE_EXTERNAL)); @@ -873,7 +873,7 @@ int main(int argc, char **argv) /* Default selection logic: receive a list without a match */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_OK(s2n_connection_set_psk_type(conn, S2N_PSK_TYPE_EXTERNAL)); @@ -895,7 +895,7 @@ int main(int argc, char **argv) /* Default selection logic: receive a list with a match */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_OK(s2n_connection_set_psk_type(conn, S2N_PSK_TYPE_EXTERNAL)); @@ -922,7 +922,7 @@ int main(int argc, char **argv) EXPECT_NOT_NULL(config); EXPECT_SUCCESS(s2n_config_set_psk_selection_callback(config, s2n_test_error_select_psk_identity_callback, NULL)); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_OK(s2n_connection_set_psk_type(conn, S2N_PSK_TYPE_EXTERNAL)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); @@ -945,7 +945,7 @@ int main(int argc, char **argv) uint16_t expected_wire_choice = 0; EXPECT_SUCCESS(s2n_config_set_psk_selection_callback(config, s2n_test_select_psk_identity_callback, &expected_wire_choice)); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); EXPECT_OK(s2n_connection_set_psk_type(conn, S2N_PSK_TYPE_EXTERNAL)); @@ -976,7 +976,7 @@ int main(int argc, char **argv) uint16_t expected_wire_choice = 10; EXPECT_SUCCESS(s2n_config_set_psk_selection_callback(config, s2n_test_select_psk_identity_callback, &expected_wire_choice)); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_OK(s2n_connection_set_psk_type(conn, S2N_PSK_TYPE_EXTERNAL)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); @@ -1006,7 +1006,7 @@ int main(int argc, char **argv) uint16_t expected_wire_choice = 0; EXPECT_SUCCESS(s2n_config_set_psk_selection_callback(config, s2n_test_select_psk_identity_callback, &expected_wire_choice)); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_OK(s2n_connection_set_psk_type(conn, S2N_PSK_TYPE_EXTERNAL)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); @@ -1136,7 +1136,7 @@ int main(int argc, char **argv) struct s2n_blob valid_binder = { 0 }; EXPECT_SUCCESS(s2n_blob_init(&valid_binder, valid_binder_data, sizeof(valid_binder_data))); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); DEFER_CLEANUP(struct s2n_psk psk = { 0 }, s2n_psk_wipe); @@ -1227,8 +1227,8 @@ int main(int argc, char **argv) /* Test: s2n_client_psk_recv */ { const uint8_t client_hello_data[] = "ClientHello"; - s2n_extension_type_id key_share_id; - s2n_extension_type_id psk_ke_mode_id; + s2n_extension_type_id key_share_id = 0; + s2n_extension_type_id psk_ke_mode_id = 0; EXPECT_SUCCESS(s2n_extension_supported_iana_value_to_id(TLS_EXTENSION_PSK_KEY_EXCHANGE_MODES, &psk_ke_mode_id)); EXPECT_SUCCESS(s2n_extension_supported_iana_value_to_id(TLS_EXTENSION_KEY_SHARE, &key_share_id)); @@ -1239,7 +1239,7 @@ int main(int argc, char **argv) 0x00, 0x00, /* binder list size */ }; - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); conn->client_hello.extensions.count = 1; @@ -1279,7 +1279,7 @@ int main(int argc, char **argv) 0x00, 0x00, /* binder list size */ }; - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_OK(s2n_connection_set_psk_type(conn, S2N_PSK_TYPE_EXTERNAL)); conn->client_hello.extensions.count = 1; @@ -1321,7 +1321,7 @@ int main(int argc, char **argv) { const uint8_t extension_data[] = { 0 }; - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); conn->client_hello.extensions.count = 1; @@ -1343,7 +1343,7 @@ int main(int argc, char **argv) /* Receive a psk extension with an unknown psk key exchange mode */ { const uint8_t extension_data[] = { 0 }; - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); conn->client_hello.extensions.count = 1; @@ -1367,7 +1367,7 @@ int main(int argc, char **argv) * keyshare_extension */ { const uint8_t extension_data[] = { 0 }; - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); conn->client_hello.extensions.count = 1; @@ -1389,11 +1389,11 @@ int main(int argc, char **argv) /* The extension does not appear last in the extension list */ { - s2n_extension_type_id psk_ext_id; + s2n_extension_type_id psk_ext_id = 0; EXPECT_SUCCESS(s2n_extension_supported_iana_value_to_id(TLS_EXTENSION_PRE_SHARED_KEY, &psk_ext_id)); struct s2n_stuffer extension = { 0 }; - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); conn->client_hello.extensions.count = 2; @@ -1415,11 +1415,11 @@ int main(int argc, char **argv) 0x12, 0x34, 0x56, /* Message: random data */ }; - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); struct s2n_stuffer *client_out = &client_conn->handshake.io; - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_OK(s2n_connection_set_psk_type(server_conn, S2N_PSK_TYPE_EXTERNAL)); struct s2n_stuffer *server_in = &server_conn->handshake.io; @@ -1469,7 +1469,7 @@ int main(int argc, char **argv) /* Functional test */ if (s2n_is_tls13_fully_supported()) { /* Setup connections */ - struct s2n_connection *client_conn, *server_conn; + struct s2n_connection *client_conn = NULL, *server_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_OK(s2n_connection_set_psk_type(server_conn, S2N_PSK_TYPE_EXTERNAL)); diff --git a/tests/unit/s2n_client_record_version_test.c b/tests/unit/s2n_client_record_version_test.c index 7e626a1417b..795739dfe9e 100644 --- a/tests/unit/s2n_client_record_version_test.c +++ b/tests/unit/s2n_client_record_version_test.c @@ -32,8 +32,8 @@ int main(int argc, char **argv) { - char *cert_chain; - char *private_key; + char *cert_chain = NULL; + char *private_key = NULL; BEGIN_TEST(); EXPECT_SUCCESS(s2n_disable_tls13_in_test()); @@ -43,8 +43,8 @@ int main(int argc, char **argv) /* Server negotiates TLS1.2 */ { - struct s2n_connection *client_conn; - struct s2n_config *client_config; + struct s2n_connection *client_conn = NULL; + struct s2n_config *client_config = NULL; s2n_blocked_status client_blocked; uint8_t server_hello_message[] = { @@ -177,8 +177,8 @@ int main(int argc, char **argv) /* Server negotiates SSLv3 */ { - struct s2n_connection *client_conn; - struct s2n_config *client_config; + struct s2n_connection *client_conn = NULL; + struct s2n_config *client_config = NULL; s2n_blocked_status client_blocked; uint8_t server_hello_message[] = { diff --git a/tests/unit/s2n_client_renegotiation_info_extension_test.c b/tests/unit/s2n_client_renegotiation_info_extension_test.c index d2ac150a0e0..f5cf1ad91d4 100644 --- a/tests/unit/s2n_client_renegotiation_info_extension_test.c +++ b/tests/unit/s2n_client_renegotiation_info_extension_test.c @@ -38,7 +38,7 @@ int main(int argc, char **argv) /* Test receive - too much data */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); struct s2n_stuffer stuffer = { 0 }; @@ -63,7 +63,7 @@ int main(int argc, char **argv) *# and if it is not, MUST abort the handshake. */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); struct s2n_stuffer stuffer = { 0 }; @@ -81,7 +81,7 @@ int main(int argc, char **argv) /* Test receive */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); struct s2n_stuffer stuffer = { 0 }; diff --git a/tests/unit/s2n_client_sct_list_extension_test.c b/tests/unit/s2n_client_sct_list_extension_test.c index 26e0e0442c0..ae53b9a464b 100644 --- a/tests/unit/s2n_client_sct_list_extension_test.c +++ b/tests/unit/s2n_client_sct_list_extension_test.c @@ -23,10 +23,10 @@ int main(int argc, char **argv) /* Test should_send */ { - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); @@ -43,10 +43,10 @@ int main(int argc, char **argv) /* Test send */ { - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); @@ -63,10 +63,10 @@ int main(int argc, char **argv) /* Test receive */ { - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); diff --git a/tests/unit/s2n_client_secure_renegotiation_test.c b/tests/unit/s2n_client_secure_renegotiation_test.c index 1a5d348026c..22acb20cfdf 100644 --- a/tests/unit/s2n_client_secure_renegotiation_test.c +++ b/tests/unit/s2n_client_secure_renegotiation_test.c @@ -32,8 +32,8 @@ int main(int argc, char **argv) { - char *cert_chain; - char *private_key; + char *cert_chain = NULL; + char *private_key = NULL; BEGIN_TEST(); EXPECT_SUCCESS(s2n_disable_tls13_in_test()); @@ -43,8 +43,8 @@ int main(int argc, char **argv) /* Success: server sends an empty initial renegotiation_info */ { - struct s2n_connection *client_conn; - struct s2n_config *client_config; + struct s2n_connection *client_conn = NULL; + struct s2n_config *client_config = NULL; s2n_blocked_status client_blocked; uint8_t server_extensions[] = { @@ -136,8 +136,8 @@ int main(int argc, char **argv) /* Success: server doesn't send an renegotiation_info extension */ { - struct s2n_connection *client_conn; - struct s2n_config *client_config; + struct s2n_connection *client_conn = NULL; + struct s2n_config *client_config = NULL; s2n_blocked_status client_blocked; uint8_t server_hello_message[] = { @@ -214,8 +214,8 @@ int main(int argc, char **argv) /* Failure: server sends a non-empty initial renegotiation_info */ { - struct s2n_connection *client_conn; - struct s2n_config *client_config; + struct s2n_connection *client_conn = NULL; + struct s2n_config *client_config = NULL; s2n_blocked_status client_blocked; uint8_t server_extensions[] = { diff --git a/tests/unit/s2n_client_server_name_extension_test.c b/tests/unit/s2n_client_server_name_extension_test.c index 94413f22531..6e383ae380a 100644 --- a/tests/unit/s2n_client_server_name_extension_test.c +++ b/tests/unit/s2n_client_server_name_extension_test.c @@ -25,7 +25,7 @@ int main(int argc, char **argv) /* should_send */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); /* server_name not set -> don't send */ @@ -44,7 +44,7 @@ int main(int argc, char **argv) /* send */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_set_server_name(conn, test_server_name)); @@ -53,20 +53,20 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_client_server_name_extension.send(conn, &stuffer)); - uint16_t server_name_list_size; + uint16_t server_name_list_size = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint16(&stuffer, &server_name_list_size)); EXPECT_EQUAL(server_name_list_size, s2n_stuffer_data_available(&stuffer)); - uint8_t name_type; + uint8_t name_type = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint8(&stuffer, &name_type)); EXPECT_EQUAL(name_type, 0); - uint16_t server_name_size; + uint16_t server_name_size = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint16(&stuffer, &server_name_size)); EXPECT_EQUAL(server_name_size, s2n_stuffer_data_available(&stuffer)); EXPECT_EQUAL(server_name_size, strlen(test_server_name)); - char *server_name_data; + char *server_name_data = NULL; EXPECT_NOT_NULL(server_name_data = s2n_stuffer_raw_read(&stuffer, server_name_size)); EXPECT_BYTEARRAY_EQUAL(server_name_data, test_server_name, strlen(test_server_name)); @@ -78,10 +78,10 @@ int main(int argc, char **argv) /* recv - basic */ { - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); struct s2n_stuffer stuffer = { 0 }; @@ -103,10 +103,10 @@ int main(int argc, char **argv) /* recv - server name already set */ { - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_CLIENT)); struct s2n_stuffer stuffer = { 0 }; @@ -126,10 +126,10 @@ int main(int argc, char **argv) /* recv - extra data ignored */ { - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); struct s2n_stuffer stuffer = { 0 }; @@ -150,10 +150,10 @@ int main(int argc, char **argv) /* recv - malformed */ { - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); struct s2n_stuffer stuffer = { 0 }; diff --git a/tests/unit/s2n_client_session_ticket_extension_test.c b/tests/unit/s2n_client_session_ticket_extension_test.c index 4fbefc86300..d357ab44467 100644 --- a/tests/unit/s2n_client_session_ticket_extension_test.c +++ b/tests/unit/s2n_client_session_ticket_extension_test.c @@ -32,16 +32,16 @@ int main(int argc, char **argv) BEGIN_TEST(); EXPECT_SUCCESS(s2n_disable_tls13_in_test()); - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(client_conn, config)); /* should_send */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); @@ -81,7 +81,7 @@ int main(int argc, char **argv) /* recv - decrypt ticket */ { - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config)); @@ -103,7 +103,7 @@ int main(int argc, char **argv) /* recv - ignore extension if TLS1.3 */ { - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config)); @@ -128,7 +128,7 @@ int main(int argc, char **argv) /* recv - ignore extension if not correct size */ { - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config)); @@ -149,7 +149,7 @@ int main(int argc, char **argv) /* recv - ignore extension if tickets not allowed */ { - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config)); diff --git a/tests/unit/s2n_client_signature_algorithms_extension_test.c b/tests/unit/s2n_client_signature_algorithms_extension_test.c index 49f8b89e66f..14e8581c6d7 100644 --- a/tests/unit/s2n_client_signature_algorithms_extension_test.c +++ b/tests/unit/s2n_client_signature_algorithms_extension_test.c @@ -28,10 +28,10 @@ int main(int argc, char **argv) { BEGIN_TEST(); EXPECT_SUCCESS(s2n_disable_tls13_in_test()); - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); - struct s2n_cert_chain_and_key *chain_and_key; + struct s2n_cert_chain_and_key *chain_and_key = NULL; EXPECT_SUCCESS(s2n_test_cert_chain_and_key_new(&chain_and_key, S2N_DEFAULT_TEST_CERT_CHAIN, S2N_DEFAULT_TEST_PRIVATE_KEY)); EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(config, chain_and_key)); @@ -58,7 +58,7 @@ int main(int argc, char **argv) struct s2n_connection *server_conn = s2n_connection_new(S2N_SERVER); struct s2n_stuffer io = { 0 }; - s2n_stuffer_growable_alloc(&io, 0); + EXPECT_SUCCESS(s2n_stuffer_growable_alloc(&io, 0)); EXPECT_SUCCESS(s2n_client_signature_algorithms_extension.send(client_conn, &io)); EXPECT_SUCCESS(s2n_client_signature_algorithms_extension.recv(server_conn, &io)); @@ -77,7 +77,7 @@ int main(int argc, char **argv) .iana_list = { 0xFF01, 0xFFFF, TLS_SIGNATURE_SCHEME_RSA_PKCS1_SHA384 }, .len = 3, }; - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); POSIX_GUARD(s2n_connection_set_config(conn, config)); conn->actual_protocol_version = S2N_TLS12; diff --git a/tests/unit/s2n_client_supported_groups_extension_test.c b/tests/unit/s2n_client_supported_groups_extension_test.c index fd2a105ed62..1d8aa315856 100644 --- a/tests/unit/s2n_client_supported_groups_extension_test.c +++ b/tests/unit/s2n_client_supported_groups_extension_test.c @@ -32,7 +32,7 @@ int main() /* Test s2n_extension_should_send_if_ecc_enabled */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); /* ecc extensions are required for the default config */ @@ -46,7 +46,7 @@ int main() /* Test send (with default KEM prefs = kem_preferences_null) */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); struct s2n_stuffer stuffer = { 0 }; @@ -63,12 +63,12 @@ int main() EXPECT_SUCCESS(s2n_client_supported_groups_extension.send(conn, &stuffer)); - uint16_t length; + uint16_t length = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint16(&stuffer, &length)); EXPECT_EQUAL(length, s2n_stuffer_data_available(&stuffer)); EXPECT_EQUAL(length, ecc_pref->count * sizeof(uint16_t)); - uint16_t curve_id; + uint16_t curve_id = 0; for (size_t i = 0; i < ecc_pref->count; i++) { EXPECT_SUCCESS(s2n_stuffer_read_uint16(&stuffer, &curve_id)); EXPECT_EQUAL(curve_id, ecc_pref->ecc_curves[i]->iana_id); @@ -99,7 +99,7 @@ int main() /* Test send with TLS 1.3 KEM groups */ { EXPECT_SUCCESS(s2n_enable_tls13_in_test()); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); DEFER_CLEANUP(struct s2n_stuffer stuffer = { 0 }, s2n_stuffer_free); @@ -116,7 +116,7 @@ int main() EXPECT_SUCCESS(s2n_client_supported_groups_extension.send(conn, &stuffer)); - uint16_t length; + uint16_t length = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint16(&stuffer, &length)); uint16_t expected_length = ecc_pref->count * sizeof(uint16_t); uint32_t available_groups = 0; @@ -128,7 +128,7 @@ int main() EXPECT_EQUAL(length, expected_length); if (s2n_pq_is_enabled()) { - uint16_t kem_id; + uint16_t kem_id = 0; for (size_t i = 0; i < kem_pref->tls13_kem_group_count; i++) { if (!s2n_kem_group_is_available(kem_pref->tls13_kem_groups[i])) { continue; @@ -138,7 +138,7 @@ int main() } } - uint16_t curve_id; + uint16_t curve_id = 0; for (size_t i = 0; i < ecc_pref->count; i++) { EXPECT_SUCCESS(s2n_stuffer_read_uint16(&stuffer, &curve_id)); EXPECT_EQUAL(curve_id, ecc_pref->ecc_curves[i]->iana_id); @@ -149,7 +149,7 @@ int main() }; /* Test that send does not send KEM group IDs for versions != TLS 1.3 */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_EQUAL(s2n_connection_get_protocol_version(conn), S2N_TLS12); @@ -167,12 +167,12 @@ int main() EXPECT_SUCCESS(s2n_client_supported_groups_extension.send(conn, &stuffer)); - uint16_t length; + uint16_t length = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint16(&stuffer, &length)); EXPECT_EQUAL(length, s2n_stuffer_data_available(&stuffer)); EXPECT_EQUAL(length, ecc_pref->count * sizeof(uint16_t)); - uint16_t curve_id; + uint16_t curve_id = 0; for (size_t i = 0; i < ecc_pref->count; i++) { EXPECT_SUCCESS(s2n_stuffer_read_uint16(&stuffer, &curve_id)); EXPECT_EQUAL(curve_id, ecc_pref->ecc_curves[i]->iana_id); @@ -191,11 +191,11 @@ int main() for (size_t i = 0; i < s2n_array_len(test_policy_overrides); i++) { EXPECT_SUCCESS(s2n_enable_tls13_in_test()); - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); client_conn->security_policy_override = test_policy_overrides[i][0]; - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_CLIENT)); server_conn->security_policy_override = test_policy_overrides[i][1]; @@ -260,11 +260,11 @@ int main() for (size_t i = 0; i < NUM_MISMATCH_PQ_TEST_POLICY_OVERRIDES; i++) { EXPECT_SUCCESS(s2n_enable_tls13_in_test()); - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); client_conn->security_policy_override = test_policy_overrides[i][0]; - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_CLIENT)); server_conn->security_policy_override = test_policy_overrides[i][1]; @@ -299,7 +299,7 @@ int main() { EXPECT_SUCCESS(s2n_enable_tls13_in_test()); - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_CLIENT)); server_conn->security_policy_override = &test_pq_security_policy_kyber; @@ -332,7 +332,7 @@ int main() /* Test recv - server doesn't recognize PQ group IDs when TLS 1.3 is disabled */ { EXPECT_SUCCESS(s2n_disable_tls13_in_test()); - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); EXPECT_EQUAL(s2n_connection_get_protocol_version(client_conn), S2N_TLS12); client_conn->security_policy_override = &test_pq_security_policy_kyber; @@ -345,7 +345,7 @@ int main() EXPECT_SUCCESS(s2n_connection_get_kem_preferences(client_conn, &client_kem_pref)); EXPECT_NOT_NULL(client_kem_pref); - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_CLIENT)); server_conn->security_policy_override = &test_pq_security_policy_kyber; @@ -379,7 +379,7 @@ int main() { if (!s2n_pq_is_enabled()) { EXPECT_SUCCESS(s2n_enable_tls13_in_test()); - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); client_conn->security_policy_override = &test_pq_security_policy_kyber; @@ -391,7 +391,7 @@ int main() EXPECT_SUCCESS(s2n_connection_get_kem_preferences(client_conn, &client_kem_pref)); EXPECT_NOT_NULL(client_kem_pref); - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_CLIENT)); server_conn->security_policy_override = &test_pq_security_policy_kyber; @@ -426,7 +426,7 @@ int main() /* Test recv */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); struct s2n_stuffer stuffer = { 0 }; @@ -451,7 +451,7 @@ int main() /* Test recv - no common curve */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); struct s2n_stuffer stuffer = { 0 }; @@ -477,7 +477,7 @@ int main() /* Test recv - malformed extension */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); struct s2n_stuffer stuffer = { 0 }; @@ -508,7 +508,7 @@ int main() { .iana_id = 0xFF01, .libcrypto_nid = 0, .name = 0x0, .share_size = 0 }, }; int ec_curves_count = s2n_array_len(unsupported_curves); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); struct s2n_stuffer supported_groups_extension = { 0 }; diff --git a/tests/unit/s2n_client_supported_versions_extension_test.c b/tests/unit/s2n_client_supported_versions_extension_test.c index cd4d7b6a4b0..79fa0d0f9ee 100644 --- a/tests/unit/s2n_client_supported_versions_extension_test.c +++ b/tests/unit/s2n_client_supported_versions_extension_test.c @@ -49,7 +49,7 @@ int main(int argc, char **argv) uint8_t latest_version = S2N_TLS13; - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); const struct s2n_security_policy *security_policy_with_tls13_and_earlier = &security_policy_20190801; @@ -109,7 +109,7 @@ int main(int argc, char **argv) /* Client produces a version list that the server can parse */ { - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(client_conn, config)); @@ -118,7 +118,7 @@ int main(int argc, char **argv) uint16_t expected_length = size_result - S2N_EXTENSION_TYPE_FIELD_LENGTH - S2N_EXTENSION_LENGTH_FIELD_LENGTH; struct s2n_stuffer extension = { 0 }; - s2n_stuffer_alloc(&extension, expected_length); + EXPECT_SUCCESS(s2n_stuffer_alloc(&extension, expected_length)); EXPECT_SUCCESS(s2n_client_supported_versions_extension.send(client_conn, &extension)); @@ -126,7 +126,7 @@ int main(int argc, char **argv) EXPECT_EQUAL(expected_length, s2n_stuffer_data_available(&extension)); /* Check that the server can process the version list */ - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config)); @@ -143,7 +143,7 @@ int main(int argc, char **argv) /* Server selects highest supported version shared by client */ { - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config)); @@ -152,7 +152,7 @@ int main(int argc, char **argv) uint8_t supported_version_list_length = sizeof(supported_version_list); struct s2n_stuffer extension = { 0 }; - s2n_stuffer_alloc(&extension, supported_version_list_length * 2 + 1); + EXPECT_SUCCESS(s2n_stuffer_alloc(&extension, supported_version_list_length * 2 + 1)); EXPECT_SUCCESS(write_test_supported_versions_list(&extension, supported_version_list, supported_version_list_length)); @@ -169,7 +169,7 @@ int main(int argc, char **argv) /* Server does not process the extension if using TLS1.2. */ { EXPECT_SUCCESS(s2n_disable_tls13_in_test()); - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config)); @@ -178,7 +178,7 @@ int main(int argc, char **argv) uint8_t supported_version_list_length = sizeof(supported_version_list); struct s2n_stuffer extension = { 0 }; - s2n_stuffer_alloc(&extension, supported_version_list_length * 2 + 1); + EXPECT_SUCCESS(s2n_stuffer_alloc(&extension, supported_version_list_length * 2 + 1)); EXPECT_SUCCESS(write_test_supported_versions_list(&extension, supported_version_list, supported_version_list_length)); @@ -195,7 +195,7 @@ int main(int argc, char **argv) /* Server terminates connection if there are no supported version in the list */ { - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config)); @@ -203,7 +203,7 @@ int main(int argc, char **argv) uint8_t invalid_version_list_length = s2n_array_len(invalid_version_list); struct s2n_stuffer extension = { 0 }; - s2n_stuffer_alloc(&extension, invalid_version_list_length * S2N_TLS_PROTOCOL_VERSION_LEN + 1); + EXPECT_SUCCESS(s2n_stuffer_alloc(&extension, invalid_version_list_length * S2N_TLS_PROTOCOL_VERSION_LEN + 1)); POSIX_GUARD(s2n_stuffer_write_uint8(&extension, invalid_version_list_length * S2N_TLS_PROTOCOL_VERSION_LEN)); @@ -220,7 +220,7 @@ int main(int argc, char **argv) /* Check grease values for the supported versions */ { - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config)); @@ -228,7 +228,7 @@ int main(int argc, char **argv) uint8_t grease_version_list_length = s2n_array_len(grease_version_list); struct s2n_stuffer extension = { 0 }; - s2n_stuffer_alloc(&extension, grease_version_list_length * S2N_TLS_PROTOCOL_VERSION_LEN + 1); + EXPECT_SUCCESS(s2n_stuffer_alloc(&extension, grease_version_list_length * S2N_TLS_PROTOCOL_VERSION_LEN + 1)); POSIX_GUARD(s2n_stuffer_write_uint8(&extension, grease_version_list_length * S2N_TLS_PROTOCOL_VERSION_LEN)); @@ -247,7 +247,7 @@ int main(int argc, char **argv) /* Server selects highest supported protocol among list of invalid protocols (that purposefully test our conversion methods) */ { - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config)); @@ -255,7 +255,7 @@ int main(int argc, char **argv) uint8_t invalid_version_list_length = s2n_array_len(invalid_version_list); struct s2n_stuffer extension = { 0 }; - s2n_stuffer_alloc(&extension, invalid_version_list_length * S2N_TLS_PROTOCOL_VERSION_LEN + 1); + EXPECT_SUCCESS(s2n_stuffer_alloc(&extension, invalid_version_list_length * S2N_TLS_PROTOCOL_VERSION_LEN + 1)); POSIX_GUARD(s2n_stuffer_write_uint8(&extension, invalid_version_list_length * S2N_TLS_PROTOCOL_VERSION_LEN)); @@ -274,7 +274,7 @@ int main(int argc, char **argv) /* Server alerts if no shared supported version found */ { - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config)); @@ -282,7 +282,7 @@ int main(int argc, char **argv) uint8_t supported_version_list_length = sizeof(supported_version_list); struct s2n_stuffer extension = { 0 }; - s2n_stuffer_alloc(&extension, supported_version_list_length * 2 + 1); + EXPECT_SUCCESS(s2n_stuffer_alloc(&extension, supported_version_list_length * 2 + 1)); EXPECT_SUCCESS(write_test_supported_versions_list(&extension, supported_version_list, supported_version_list_length)); @@ -297,12 +297,12 @@ int main(int argc, char **argv) /* Server alerts if supported version list is empty */ { - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config)); struct s2n_stuffer extension = { 0 }; - s2n_stuffer_alloc(&extension, 1); + EXPECT_SUCCESS(s2n_stuffer_alloc(&extension, 1)); EXPECT_SUCCESS(s2n_stuffer_write_uint8(&extension, 0)); @@ -316,12 +316,12 @@ int main(int argc, char **argv) /* Server alerts if version list size exceeds the extension size */ { - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config)); struct s2n_stuffer extension = { 0 }; - s2n_stuffer_alloc(&extension, 1); + EXPECT_SUCCESS(s2n_stuffer_alloc(&extension, 1)); EXPECT_SUCCESS(s2n_stuffer_write_uint8(&extension, 13)); @@ -334,12 +334,12 @@ int main(int argc, char **argv) /* Server alerts if version list size is less than extension size */ { - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config)); struct s2n_stuffer extension = { 0 }; - s2n_stuffer_alloc(&extension, 5); + EXPECT_SUCCESS(s2n_stuffer_alloc(&extension, 5)); EXPECT_SUCCESS(s2n_stuffer_write_uint8(&extension, 2)); EXPECT_SUCCESS(s2n_stuffer_write_uint16(&extension, 0x0302)); @@ -354,12 +354,12 @@ int main(int argc, char **argv) /* Server alerts if version list size is odd */ { - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config)); struct s2n_stuffer extension = { 0 }; - s2n_stuffer_alloc(&extension, 4); + EXPECT_SUCCESS(s2n_stuffer_alloc(&extension, 4)); EXPECT_SUCCESS(s2n_stuffer_write_uint8(&extension, 3)); EXPECT_SUCCESS(s2n_stuffer_write_uint16(&extension, 0x0302)); @@ -376,13 +376,13 @@ int main(int argc, char **argv) * in the client hello, for backwards compatibility the version field * should be set to 1.2 even when a higher version is supported. */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_client_hello_send(conn)); struct s2n_stuffer client_hello = conn->handshake.io; uint8_t version[2]; - s2n_stuffer_read_bytes(&client_hello, version, 2); + EXPECT_SUCCESS(s2n_stuffer_read_bytes(&client_hello, version, 2)); EXPECT_EQUAL(version[0], 0x03); EXPECT_EQUAL(version[1], 0x03); @@ -443,6 +443,45 @@ int main(int argc, char **argv) EXPECT_EQUAL(server_conn->client_hello_version, S2N_TLS10); } + /* Ensure that TLS 1.3 is enforced in the supported versions extension for ClientHellos sent in + * response to a HelloRetryRequest + */ + for (uint8_t version = S2N_TLS10; version <= S2N_TLS13; version++) { + for (size_t is_hrr = 0; is_hrr <= 1; is_hrr++) { + DEFER_CLEANUP(struct s2n_connection *conn = s2n_connection_new(S2N_SERVER), s2n_connection_ptr_free); + EXPECT_SUCCESS(s2n_connection_set_cipher_preferences(conn, "test_all")); + if (is_hrr) { + EXPECT_OK(s2n_handshake_type_set_tls13_flag(conn, HELLO_RETRY_REQUEST)); + conn->handshake.message_number = 1; + } + + uint8_t supported_versions_list[] = { version }; + uint8_t supported_versions_list_len = sizeof(supported_versions_list); + + DEFER_CLEANUP(struct s2n_stuffer extension = { 0 }, s2n_stuffer_free); + EXPECT_SUCCESS(s2n_stuffer_growable_alloc(&extension, 0)); + EXPECT_SUCCESS(write_test_supported_versions_list(&extension, supported_versions_list, + supported_versions_list_len)); + + int ret = s2n_client_supported_versions_extension.recv(conn, &extension); + + if (is_hrr && version < S2N_TLS13) { + /* It should not be possible to negotiate a protocol version < TLS 1.3 after a + * HelloRetryRequest. + */ + EXPECT_FAILURE_WITH_ERRNO(ret, S2N_ERR_PROTOCOL_VERSION_UNSUPPORTED); + } else { + /* TLS 1.3 should be permitted after a HelloRetryRequest. Also, it should be + * possible to receive < TLS 1.3 in an initial ClientHello. + */ + EXPECT_SUCCESS(ret); + + EXPECT_EQUAL(conn->client_protocol_version, version); + EXPECT_EQUAL(conn->actual_protocol_version, version); + } + } + } + EXPECT_SUCCESS(s2n_config_free(config)); END_TEST(); diff --git a/tests/unit/s2n_config_test.c b/tests/unit/s2n_config_test.c index 423b0c94719..d4fe8d7d92d 100644 --- a/tests/unit/s2n_config_test.c +++ b/tests/unit/s2n_config_test.c @@ -29,9 +29,13 @@ #include "tls/s2n_security_policies.h" #include "tls/s2n_tls13.h" #include "unstable/npn.h" +#include "utils/s2n_map.h" #define S2N_TEST_MAX_SUPPORTED_GROUPS_COUNT 30 +/* forward declaration */ +int s2n_config_build_domain_name_to_cert_map(struct s2n_config *config, struct s2n_cert_chain_and_key *cert_key_pair); + static int s2n_test_select_psk_identity_callback(struct s2n_connection *conn, void *context, struct s2n_offered_psk_list *psk_identity_list) { @@ -65,7 +69,7 @@ int main(int argc, char **argv) const s2n_mode modes[] = { S2N_CLIENT, S2N_SERVER }; - const struct s2n_security_policy *default_security_policy, *tls13_security_policy, *fips_security_policy; + const struct s2n_security_policy *default_security_policy = NULL, *tls13_security_policy = NULL, *fips_security_policy = NULL; EXPECT_SUCCESS(s2n_find_security_policy_from_version("default_tls13", &tls13_security_policy)); EXPECT_SUCCESS(s2n_find_security_policy_from_version("default_fips", &fips_security_policy)); EXPECT_SUCCESS(s2n_find_security_policy_from_version("default", &default_security_policy)); @@ -77,7 +81,7 @@ int main(int argc, char **argv) /* Test: s2n_config_new and tls13_default_config match */ { - struct s2n_config *config, *default_config; + struct s2n_config *config = NULL, *default_config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); EXPECT_NOT_NULL(default_config = s2n_fetch_default_config()); @@ -102,8 +106,8 @@ int main(int argc, char **argv) { /* For TLS1.2 */ if (!s2n_is_in_fips_mode()) { - struct s2n_connection *conn; - const struct s2n_security_policy *security_policy; + struct s2n_connection *conn = NULL; + const struct s2n_security_policy *security_policy = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_EQUAL(conn->config, s2n_fetch_default_config()); @@ -117,8 +121,8 @@ int main(int argc, char **argv) /* For TLS1.3 */ { EXPECT_SUCCESS(s2n_enable_tls13_in_test()); - struct s2n_connection *conn; - const struct s2n_security_policy *security_policy; + struct s2n_connection *conn = NULL; + const struct s2n_security_policy *security_policy = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_EQUAL(conn->config, s2n_fetch_default_config()); @@ -132,8 +136,8 @@ int main(int argc, char **argv) /* For fips */ if (s2n_is_in_fips_mode()) { - struct s2n_connection *conn; - const struct s2n_security_policy *security_policy; + struct s2n_connection *conn = NULL; + const struct s2n_security_policy *security_policy = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_EQUAL(conn->config, s2n_fetch_default_config()); @@ -149,7 +153,7 @@ int main(int argc, char **argv) /* Test for s2n_config_new() and tls 1.3 behavior */ { if (!s2n_is_in_fips_mode()) { - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); EXPECT_EQUAL(config->security_policy, default_security_policy); EXPECT_EQUAL(config->security_policy->cipher_preferences, &cipher_preferences_20170210); @@ -201,7 +205,7 @@ int main(int argc, char **argv) struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); - struct s2n_config *config; + struct s2n_config *config = NULL; uint8_t num_tickets = 1; EXPECT_NOT_NULL(config = s2n_config_new()); @@ -259,6 +263,23 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_connection_free(conn)); EXPECT_SUCCESS(s2n_config_free(config)); }; + + /* Test that security policy validation is enforced on the config */ + { + DEFER_CLEANUP(struct s2n_config *config = s2n_config_new(), s2n_config_ptr_free); + EXPECT_NOT_NULL(config); + DEFER_CLEANUP(struct s2n_connection *conn = s2n_connection_new(S2N_SERVER), s2n_connection_ptr_free); + EXPECT_NOT_NULL(conn); + + DEFER_CLEANUP(struct s2n_cert_chain_and_key *invalid_cert = NULL, s2n_cert_chain_and_key_ptr_free); + EXPECT_SUCCESS(s2n_test_cert_permutation_load_server_chain(&invalid_cert, "rsae", "pss", "4096", "sha384")); + EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(config, invalid_cert)); + struct s2n_security_policy rfc9151_applied_locally = security_policy_rfc9151; + rfc9151_applied_locally.certificate_preferences_apply_locally = true; + config->security_policy = &rfc9151_applied_locally; + + EXPECT_FAILURE_WITH_ERRNO(s2n_connection_set_config(conn, config), S2N_ERR_SECURITY_POLICY_INCOMPATIBLE_CERT); + }; }; /* s2n_config_set_session_tickets_onoff */ @@ -1086,5 +1107,71 @@ int main(int argc, char **argv) } } + /* Test s2n_config_validate_loaded_certificates */ + { + DEFER_CLEANUP(struct s2n_cert_chain_and_key *invalid_cert = NULL, s2n_cert_chain_and_key_ptr_free); + DEFER_CLEANUP(struct s2n_cert_chain_and_key *valid_cert = NULL, s2n_cert_chain_and_key_ptr_free); + EXPECT_SUCCESS(s2n_test_cert_permutation_load_server_chain(&invalid_cert, "ec", "ecdsa", "p384", "sha256")); + EXPECT_SUCCESS(s2n_test_cert_permutation_load_server_chain(&valid_cert, "ec", "ecdsa", "p384", "sha384")); + + struct s2n_security_policy rfc9151_applied_locally = security_policy_rfc9151; + rfc9151_applied_locally.certificate_preferences_apply_locally = true; + + /* rfc9151 doesn't allow SHA256 signatures, but does allow SHA384 signatures, + * so ecdsa_p384_sha256 is invalid and ecdsa_p384_sha384 is valid */ + + /* valid certs are accepted */ + { + DEFER_CLEANUP(struct s2n_config *config = s2n_config_new(), s2n_config_ptr_free); + EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(config, valid_cert)); + EXPECT_OK(s2n_config_validate_loaded_certificates(config, &rfc9151_applied_locally)); + }; + + /* when cert preferences don't apply locally, invalid certs are accepted */ + { + struct s2n_security_policy non_local_rfc9151 = security_policy_rfc9151; + non_local_rfc9151.certificate_preferences_apply_locally = false; + + DEFER_CLEANUP(struct s2n_config *config = s2n_config_new(), s2n_config_ptr_free); + EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(config, invalid_cert)); + EXPECT_OK(s2n_config_validate_loaded_certificates(config, &non_local_rfc9151)); + }; + + /* Certs in an s2n_config are stored in default_certs_by_type, domain_name_to_cert_map, or + * both. We want to ensure that the s2n_config_validate_loaded_certificates method will + * validate certs in both locations. + */ + + /* certs in default_certs_by_type are validated */ + { + /* s2n_config_set_cert_chain_and_key_defaults populates default_certs_by_type + * but doesn't populate domain_name_to_cert_map + */ + DEFER_CLEANUP(struct s2n_config *config = s2n_config_new_minimal(), s2n_config_ptr_free); + EXPECT_SUCCESS(s2n_config_set_cert_chain_and_key_defaults(config, &invalid_cert, 1)); + + /* domain certs is empty */ + uint32_t domain_certs_count = 0; + EXPECT_OK(s2n_map_size(config->domain_name_to_cert_map, &domain_certs_count)); + EXPECT_EQUAL(domain_certs_count, 0); + + /* certs in default_certs_by_type are validated */ + EXPECT_ERROR_WITH_ERRNO(s2n_config_validate_loaded_certificates(config, &rfc9151_applied_locally), + S2N_ERR_SECURITY_POLICY_INCOMPATIBLE_CERT); + }; + + /* certs in the domain map are validated */ + { + DEFER_CLEANUP(struct s2n_config *config = s2n_config_new(), s2n_config_ptr_free); + EXPECT_SUCCESS(s2n_config_build_domain_name_to_cert_map(config, invalid_cert)); + + /* default_certs_by_type is empty. */ + EXPECT_EQUAL(s2n_config_get_num_default_certs(config), 0); + + /* certs in domain_map are validated */ + EXPECT_ERROR_WITH_ERRNO(s2n_config_validate_loaded_certificates(config, &rfc9151_applied_locally), + S2N_ERR_SECURITY_POLICY_INCOMPATIBLE_CERT); + }; + }; END_TEST(); } diff --git a/tests/unit/s2n_connection_context_test.c b/tests/unit/s2n_connection_context_test.c index 5bc04d4003c..0aeb734b7bf 100644 --- a/tests/unit/s2n_connection_context_test.c +++ b/tests/unit/s2n_connection_context_test.c @@ -20,8 +20,8 @@ int main(int argc, char **argv) { - struct s2n_connection *conn; - int ctx; + struct s2n_connection *conn = NULL; + int ctx = 0; struct s2n_connection *conn_null = NULL; diff --git a/tests/unit/s2n_connection_preferences_test.c b/tests/unit/s2n_connection_preferences_test.c index d56c15ddf05..1dc72bddbc9 100644 --- a/tests/unit/s2n_connection_preferences_test.c +++ b/tests/unit/s2n_connection_preferences_test.c @@ -28,7 +28,7 @@ int main(int argc, char **argv) BEGIN_TEST(); EXPECT_SUCCESS(s2n_disable_tls13_in_test()); - const struct s2n_security_policy *default_security_policy, *tls13_security_policy, *fips_security_policy; + const struct s2n_security_policy *default_security_policy = NULL, *tls13_security_policy = NULL, *fips_security_policy = NULL; EXPECT_SUCCESS(s2n_find_security_policy_from_version("default_tls13", &tls13_security_policy)); EXPECT_SUCCESS(s2n_find_security_policy_from_version("default_fips", &fips_security_policy)); EXPECT_SUCCESS(s2n_find_security_policy_from_version("default", &default_security_policy)); @@ -256,6 +256,10 @@ int main(int argc, char **argv) EXPECT_FAILURE_WITH_ERRNO(s2n_connection_get_ecc_preferences(conn, &ecc_preferences), S2N_ERR_INVALID_ECC_PREFERENCES); EXPECT_SUCCESS(s2n_connection_free(conn)); + + /* The static configs were mutated. Reset them to allow following unit tests to use them. */ + s2n_wipe_static_configs(); + EXPECT_SUCCESS(s2n_config_defaults_init()); }; /* s2n_connection_get_curve */ diff --git a/tests/unit/s2n_connection_size_test.c b/tests/unit/s2n_connection_size_test.c index 8364a67012f..9e53914b4cd 100644 --- a/tests/unit/s2n_connection_size_test.c +++ b/tests/unit/s2n_connection_size_test.c @@ -45,7 +45,7 @@ int main(int argc, char **argv) } /* Carefully consider any increases to this number. */ - const uint16_t max_connection_size = 4274; + const uint16_t max_connection_size = 4290; const uint16_t min_connection_size = max_connection_size * 0.9; size_t connection_size = sizeof(struct s2n_connection); diff --git a/tests/unit/s2n_connection_test.c b/tests/unit/s2n_connection_test.c index 61c03d7ac0c..cad18ab1b64 100644 --- a/tests/unit/s2n_connection_test.c +++ b/tests/unit/s2n_connection_test.c @@ -123,7 +123,7 @@ int main(int argc, char **argv) /* Return NULL by default / for new connection */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_NULL(s2n_get_server_name(conn)); @@ -133,7 +133,7 @@ int main(int argc, char **argv) /* Return server_name if set */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_set_server_name(conn, test_server_name)); @@ -146,7 +146,7 @@ int main(int argc, char **argv) /* Return server_name if server_name extension parsed, but not yet processed */ { - struct s2n_connection *client_conn, *server_conn; + struct s2n_connection *client_conn = NULL, *server_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); @@ -155,7 +155,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_set_server_name(client_conn, test_server_name)); EXPECT_SUCCESS(s2n_client_server_name_extension.send(client_conn, &stuffer)); - s2n_extension_type_id extension_id; + s2n_extension_type_id extension_id = 0; EXPECT_SUCCESS(s2n_extension_supported_iana_value_to_id(TLS_EXTENSION_SERVER_NAME, &extension_id)); server_conn->client_hello.extensions.parsed_extensions[extension_id].extension_type = TLS_EXTENSION_SERVER_NAME; server_conn->client_hello.extensions.parsed_extensions[extension_id].extension = stuffer.blob; @@ -173,15 +173,15 @@ int main(int argc, char **argv) { s2n_server_name_test_callback_flag = false; - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_set_client_hello_cb(config, s2n_server_name_test_callback, &test_server_name)); - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_set_server_name(client_conn, test_server_name)); - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config)); @@ -204,7 +204,7 @@ int main(int argc, char **argv) /* s2n_connection_get_protocol_version */ { - struct s2n_connection *client_conn, *server_conn; + struct s2n_connection *client_conn = NULL, *server_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_set_test_protocol_versions(client_conn)); EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); @@ -229,7 +229,7 @@ int main(int argc, char **argv) /* Test: get selected digest alg */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); s2n_tls_hash_algorithm output = { 0 }; @@ -278,7 +278,7 @@ int main(int argc, char **argv) /* Test: get selected signature alg */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); s2n_tls_signature_algorithm output = { 0 }; @@ -627,6 +627,29 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_config_free(config)); }; + /* Test s2n_connection_set_config */ + { + /* when the config is not compliant with the security policy override, then + * s2n_connection_set_config will fail + */ + { + struct s2n_security_policy rfc9151_applied_locally = security_policy_rfc9151; + rfc9151_applied_locally.certificate_preferences_apply_locally = true; + + DEFER_CLEANUP(struct s2n_config *config = s2n_config_new(), s2n_config_ptr_free); + EXPECT_NOT_NULL(config); + DEFER_CLEANUP(struct s2n_connection *conn = s2n_connection_new(S2N_SERVER), s2n_connection_ptr_free); + EXPECT_NOT_NULL(conn); + + DEFER_CLEANUP(struct s2n_cert_chain_and_key *invalid_cert = NULL, s2n_cert_chain_and_key_ptr_free); + EXPECT_SUCCESS(s2n_test_cert_permutation_load_server_chain(&invalid_cert, "rsae", "pss", "4096", "sha384")); + + EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(config, invalid_cert)); + conn->security_policy_override = &rfc9151_applied_locally; + EXPECT_FAILURE_WITH_ERRNO(s2n_connection_set_config(conn, config), S2N_ERR_SECURITY_POLICY_INCOMPATIBLE_CERT); + }; + }; + /* Test s2n_connection_get_wire_bytes_out */ { DEFER_CLEANUP(struct s2n_connection *conn = s2n_connection_new(S2N_CLIENT), @@ -906,6 +929,59 @@ int main(int argc, char **argv) EXPECT_EQUAL(recv_count, expected_recv_count); } + /* Test s2n_connection_get_client_auth_type */ + { + DEFER_CLEANUP(struct s2n_config *config = s2n_config_new(), s2n_config_ptr_free); + + DEFER_CLEANUP(struct s2n_connection *client = s2n_connection_new(S2N_CLIENT), + s2n_connection_ptr_free); + EXPECT_NOT_NULL(client); + EXPECT_SUCCESS(s2n_connection_set_config(client, config)); + + DEFER_CLEANUP(struct s2n_connection *server = s2n_connection_new(S2N_SERVER), + s2n_connection_ptr_free); + EXPECT_NOT_NULL(server); + EXPECT_SUCCESS(s2n_connection_set_config(server, config)); + + /* Test: use defaults if no overrides set */ + { + /* Ensure that defaults are still used if the override flags are not set, + * even if client_cert_auth_type is somehow set. + */ + server->client_cert_auth_type = S2N_CERT_AUTH_REQUIRED; + client->client_cert_auth_type = S2N_CERT_AUTH_REQUIRED; + + s2n_cert_auth_type auth_type = S2N_CERT_AUTH_REQUIRED; + EXPECT_SUCCESS(s2n_connection_get_client_auth_type(client, &auth_type)); + EXPECT_EQUAL(auth_type, S2N_CERT_AUTH_OPTIONAL); + EXPECT_SUCCESS(s2n_connection_get_client_auth_type(server, &auth_type)); + EXPECT_EQUAL(auth_type, S2N_CERT_AUTH_NONE); + }; + + /* Test: use config overrides if set */ + { + EXPECT_SUCCESS(s2n_config_set_client_auth_type(config, S2N_CERT_AUTH_REQUIRED)); + + s2n_cert_auth_type auth_type = S2N_CERT_AUTH_NONE; + EXPECT_SUCCESS(s2n_connection_get_client_auth_type(client, &auth_type)); + EXPECT_EQUAL(auth_type, S2N_CERT_AUTH_REQUIRED); + EXPECT_SUCCESS(s2n_connection_get_client_auth_type(server, &auth_type)); + EXPECT_EQUAL(auth_type, S2N_CERT_AUTH_REQUIRED); + }; + + /* Test: use connection overrides if set */ + { + EXPECT_SUCCESS(s2n_connection_set_client_auth_type(client, S2N_CERT_AUTH_NONE)); + EXPECT_SUCCESS(s2n_connection_set_client_auth_type(server, S2N_CERT_AUTH_OPTIONAL)); + + s2n_cert_auth_type auth_type = S2N_CERT_AUTH_REQUIRED; + EXPECT_SUCCESS(s2n_connection_get_client_auth_type(client, &auth_type)); + EXPECT_EQUAL(auth_type, S2N_CERT_AUTH_NONE); + EXPECT_SUCCESS(s2n_connection_get_client_auth_type(server, &auth_type)); + EXPECT_EQUAL(auth_type, S2N_CERT_AUTH_OPTIONAL); + }; + }; + EXPECT_SUCCESS(s2n_cert_chain_and_key_free(ecdsa_chain_and_key)); EXPECT_SUCCESS(s2n_cert_chain_and_key_free(rsa_chain_and_key)); END_TEST(); diff --git a/tests/unit/s2n_drain_alert_test.c b/tests/unit/s2n_drain_alert_test.c index 90356bf0842..6b5ddb8145a 100644 --- a/tests/unit/s2n_drain_alert_test.c +++ b/tests/unit/s2n_drain_alert_test.c @@ -89,12 +89,12 @@ int main(int argc, char **argv) INTERNAL_ERROR_ALERT_HEX, }; - struct s2n_connection *server_conn; - struct s2n_config *server_config; + struct s2n_connection *server_conn = NULL; + struct s2n_config *server_config = NULL; s2n_blocked_status server_blocked; char *cert_chain = malloc(S2N_MAX_TEST_PEM_SIZE); char *private_key = malloc(S2N_MAX_TEST_PEM_SIZE); - struct s2n_cert_chain_and_key *chain_and_key; + struct s2n_cert_chain_and_key *chain_and_key = NULL; struct s2n_test_io_pair io_pair; EXPECT_SUCCESS(s2n_io_pair_init_non_blocking(&io_pair)); diff --git a/tests/unit/s2n_drbg_test.c b/tests/unit/s2n_drbg_test.c index 91a8d8a9d99..a90715f933b 100644 --- a/tests/unit/s2n_drbg_test.c +++ b/tests/unit/s2n_drbg_test.c @@ -351,7 +351,7 @@ int main(int argc, char **argv) EXPECT_OK(s2n_drbg_instantiate(&aes128_drbg, &blob, S2N_AES_128_CTR_NO_DF_PR)); EXPECT_OK(s2n_drbg_instantiate(&aes256_pr_drbg, &blob, S2N_AES_256_CTR_NO_DF_PR)); - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); /* Use the AES128 DRBG for 32MB of data */ diff --git a/tests/unit/s2n_ecc_evp_test.c b/tests/unit/s2n_ecc_evp_test.c index a3074052439..44c0827d2dc 100644 --- a/tests/unit/s2n_ecc_evp_test.c +++ b/tests/unit/s2n_ecc_evp_test.c @@ -16,6 +16,8 @@ #include "crypto/s2n_ecc_evp.h" #include "api/s2n.h" +#include "crypto/s2n_fips.h" +#include "crypto/s2n_libcrypto.h" #include "s2n_test.h" #include "stuffer/s2n_stuffer.h" #include "testlib/s2n_testlib.h" @@ -27,10 +29,19 @@ extern const struct s2n_ecc_named_curve s2n_unsupported_curve; +DEFINE_POINTER_CLEANUP_FUNC(EC_KEY*, EC_KEY_free); +DEFINE_POINTER_CLEANUP_FUNC(EC_POINT*, EC_POINT_free); + int main(int argc, char** argv) { BEGIN_TEST(); EXPECT_SUCCESS(s2n_disable_tls13_in_test()); + + /* Test the EC_KEY_CHECK_FIPS feature probe. AWS-LC is a libcrypto known to support this feature. */ + if (s2n_libcrypto_is_awslc()) { + EXPECT_TRUE(s2n_ecc_evp_supports_fips_check()); + } + { /* Test generate ephemeral keys for all supported curves */ for (size_t i = 0; i < s2n_all_supported_curves_list_len; i++) { @@ -134,7 +145,7 @@ int main(int argc, char** argv) for (size_t i = 0; i < s2n_all_supported_curves_list_len; i++) { struct s2n_ecc_evp_params test_params = { 0 }; struct s2n_stuffer wire = { 0 }; - uint8_t legacy_form; + uint8_t legacy_form = 0; EXPECT_SUCCESS(s2n_stuffer_growable_alloc(&wire, 0)); @@ -405,5 +416,79 @@ int main(int argc, char** argv) EXPECT_SUCCESS(s2n_ecc_evp_params_free(&client_params)); } }; + + /** + *= https://tools.ietf.org/rfc/rfc8446#section-4.2.8.2 + *= type=test + *# For the curves secp256r1, secp384r1, and secp521r1, peers MUST + *# validate each other's public value Q by ensuring that the point is a + *# valid point on the elliptic curve. The appropriate validation + *# procedures are defined in Section 4.3.7 of [ECDSA] and alternatively + *# in Section 5.6.2.3 of [KEYAGREEMENT]. This process consists of three + *# steps: (1) verify that Q is not the point at infinity (O), (2) verify + *# that for Q = (x, y) both integers x and y are in the correct + *# interval, and (3) ensure that (x, y) is a correct solution to the + *# elliptic curve equation. For these curves, implementors do not need + *# to verify membership in the correct subgroup. + * + * s2n-tls performs this validation by invoking the libcrypto APIs: EC_KEY_check_key, and + * EC_KEY_check_fips. To ensure that these APIs are properly called, step (1) is invalidated. + */ + { + const struct s2n_ecc_named_curve* const nist_curves[] = { + &s2n_ecc_curve_secp256r1, + &s2n_ecc_curve_secp384r1, + &s2n_ecc_curve_secp521r1, + }; + + for (size_t i = 0; i < s2n_array_len(nist_curves); i++) { + const struct s2n_ecc_named_curve* curve = nist_curves[i]; + + DEFER_CLEANUP(struct s2n_ecc_evp_params server_params = { 0 }, s2n_ecc_evp_params_free); + DEFER_CLEANUP(struct s2n_ecc_evp_params client_params = { 0 }, s2n_ecc_evp_params_free); + DEFER_CLEANUP(struct s2n_blob shared_key = { 0 }, s2n_free); + + /* Create a server key. */ + server_params.negotiated_curve = curve; + EXPECT_SUCCESS(s2n_ecc_evp_generate_ephemeral_key(&server_params)); + EXPECT_NOT_NULL(server_params.evp_pkey); + + /* Create a client key. */ + client_params.negotiated_curve = curve; + EXPECT_SUCCESS(s2n_ecc_evp_generate_ephemeral_key(&client_params)); + EXPECT_NOT_NULL(client_params.evp_pkey); + + /* Retrieve the existing client public key. */ + DEFER_CLEANUP(EC_KEY* ec_key = EVP_PKEY_get1_EC_KEY(client_params.evp_pkey), + EC_KEY_free_pointer); + EXPECT_NOT_NULL(ec_key); + const EC_GROUP* group = EC_KEY_get0_group(ec_key); + EXPECT_NOT_NULL(group); + const EC_POINT* public_key = EC_KEY_get0_public_key(ec_key); + EXPECT_NOT_NULL(public_key); + + /* Invalidate the public key by setting the coordinate to infinity. */ + DEFER_CLEANUP(EC_POINT* invalid_public_key = EC_POINT_dup(public_key, group), + EC_POINT_free_pointer); + EXPECT_NOT_NULL(invalid_public_key); + EXPECT_EQUAL(EC_POINT_set_to_infinity(group, invalid_public_key), 1); + EXPECT_EQUAL(EC_KEY_set_public_key(ec_key, invalid_public_key), 1); + EXPECT_EQUAL(EVP_PKEY_set1_EC_KEY(client_params.evp_pkey, ec_key), 1); + + /* Compute the server's shared secret. */ + int ret = s2n_ecc_evp_compute_shared_secret_from_params(&server_params, + &client_params, &shared_key); + + /* If s2n-tls is in FIPS mode and the libcrypto supports the EC_KEY_check_fips API, + * ensure that this API is called by checking for the correct error. + */ + if (s2n_is_in_fips_mode() && s2n_ecc_evp_supports_fips_check()) { + EXPECT_FAILURE_WITH_ERRNO(ret, S2N_ERR_ECDHE_INVALID_PUBLIC_KEY_FIPS); + } else { + EXPECT_FAILURE_WITH_ERRNO(ret, S2N_ERR_ECDHE_INVALID_PUBLIC_KEY); + } + } + } + END_TEST(); } diff --git a/tests/unit/s2n_ecc_point_format_extension_test.c b/tests/unit/s2n_ecc_point_format_extension_test.c index bf543e97b2a..8d99cf6ee27 100644 --- a/tests/unit/s2n_ecc_point_format_extension_test.c +++ b/tests/unit/s2n_ecc_point_format_extension_test.c @@ -23,12 +23,12 @@ int main(int argc, char **argv) BEGIN_TEST(); EXPECT_SUCCESS(s2n_disable_tls13_in_test()); - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); /* Test server should_send */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); /* Do not send for null connection */ @@ -57,7 +57,7 @@ int main(int argc, char **argv) /* Test send */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); @@ -66,11 +66,11 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_client_ec_point_format_extension.send(conn, &stuffer)); - uint8_t length; + uint8_t length = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint8(&stuffer, &length)); EXPECT_EQUAL(length, s2n_stuffer_data_available(&stuffer)); - uint8_t point_format; + uint8_t point_format = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint8(&stuffer, &point_format)); EXPECT_EQUAL(point_format, TLS_EC_POINT_FORMAT_UNCOMPRESSED); @@ -82,7 +82,7 @@ int main(int argc, char **argv) /* Test recv */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); diff --git a/tests/unit/s2n_encrypted_extensions_test.c b/tests/unit/s2n_encrypted_extensions_test.c index 3b1c6259f51..6637beab10b 100644 --- a/tests/unit/s2n_encrypted_extensions_test.c +++ b/tests/unit/s2n_encrypted_extensions_test.c @@ -40,7 +40,7 @@ int main(int argc, char **argv) /* Should fail for pre-TLS1.3 */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_allow_all_response_extensions(conn)); @@ -57,7 +57,7 @@ int main(int argc, char **argv) /* Should send no extensions by default */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_allow_all_response_extensions(conn)); conn->actual_protocol_version = S2N_TLS13; @@ -66,7 +66,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_encrypted_extensions_send(conn)); - uint16_t extension_list_size; + uint16_t extension_list_size = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint16(stuffer, &extension_list_size)); EXPECT_EQUAL(extension_list_size, 0); EXPECT_EQUAL(s2n_stuffer_data_available(stuffer), 0); @@ -76,7 +76,7 @@ int main(int argc, char **argv) /* Should send a requested extension */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_allow_all_response_extensions(conn)); conn->actual_protocol_version = S2N_TLS13; @@ -86,12 +86,12 @@ int main(int argc, char **argv) conn->server_name_used = 1; EXPECT_SUCCESS(s2n_encrypted_extensions_send(conn)); - uint16_t extension_list_size; + uint16_t extension_list_size = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint16(stuffer, &extension_list_size)); EXPECT_NOT_EQUAL(extension_list_size, 0); EXPECT_EQUAL(s2n_stuffer_data_available(stuffer), extension_list_size); - uint16_t extension_type; + uint16_t extension_type = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint16(stuffer, &extension_type)); EXPECT_EQUAL(extension_type, s2n_server_server_name_extension.iana_value); @@ -106,7 +106,7 @@ int main(int argc, char **argv) /* Should fail for pre-TLS1.3 */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_allow_all_response_extensions(conn)); @@ -123,7 +123,7 @@ int main(int argc, char **argv) /* Should parse an empty list */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_allow_all_response_extensions(conn)); conn->actual_protocol_version = S2N_TLS13; @@ -149,7 +149,7 @@ int main(int argc, char **argv) /* Should parse a requested extension */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_allow_all_response_extensions(conn)); conn->actual_protocol_version = S2N_TLS13; @@ -174,11 +174,11 @@ int main(int argc, char **argv) if (s2n_is_tls13_fully_supported()) { s2n_blocked_status blocked = S2N_NOT_BLOCKED; - struct s2n_cert_chain_and_key *chain_and_key; + struct s2n_cert_chain_and_key *chain_and_key = NULL; EXPECT_SUCCESS(s2n_test_cert_chain_and_key_new(&chain_and_key, S2N_DEFAULT_ECDSA_TEST_CERT_CHAIN, S2N_DEFAULT_ECDSA_TEST_PRIVATE_KEY)); - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_set_cipher_preferences(config, "default_tls13")); EXPECT_SUCCESS(s2n_config_set_unsafe_for_testing(config)); diff --git a/tests/unit/s2n_examples_test.c b/tests/unit/s2n_examples_test.c index 8b835757a6b..9e06ee27ea7 100644 --- a/tests/unit/s2n_examples_test.c +++ b/tests/unit/s2n_examples_test.c @@ -213,24 +213,23 @@ static S2N_RESULT s2n_test_example_recv_echo(struct s2n_connection *conn, typedef S2N_RESULT (*s2n_test_scenario)(struct s2n_connection *conn, struct s2n_blob *input); static S2N_RESULT s2n_run_self_talk_test(s2n_test_scenario scenario_fn) { - DEFER_CLEANUP(struct s2n_cert_chain_and_key *chain_and_key = NULL, - s2n_cert_chain_and_key_ptr_free); + struct s2n_cert_chain_and_key *chain_and_key = NULL; RESULT_GUARD_POSIX(s2n_test_cert_chain_and_key_new(&chain_and_key, S2N_DEFAULT_TEST_CERT_CHAIN, S2N_DEFAULT_TEST_PRIVATE_KEY)); - DEFER_CLEANUP(struct s2n_config *config = s2n_config_new(), - s2n_config_ptr_free); + struct s2n_config *config = s2n_config_new(); + RESULT_ENSURE_REF(config); RESULT_GUARD_POSIX(s2n_config_set_unsafe_for_testing(config)); RESULT_GUARD_POSIX(s2n_config_set_cipher_preferences(config, "default_tls13")); RESULT_GUARD_POSIX(s2n_config_add_cert_chain_and_key_to_store(config, chain_and_key)); - DEFER_CLEANUP(struct s2n_test_io_pair io_pair = { 0 }, s2n_io_pair_close); - RESULT_GUARD_POSIX(s2n_io_pair_init_non_blocking(&io_pair)); - - DEFER_CLEANUP(struct s2n_blob input = { 0 }, s2n_free); + struct s2n_blob input = { 0 }; RESULT_GUARD_POSIX(s2n_alloc(&input, S2N_TEST_BYTES_TO_SEND)); RESULT_GUARD(s2n_get_public_random_data(&input)); + DEFER_CLEANUP(struct s2n_test_io_pair io_pair = { 0 }, s2n_io_pair_close); + RESULT_GUARD_POSIX(s2n_io_pair_init_non_blocking(&io_pair)); + pid_t client_pid = fork(); if (client_pid == 0) { /* Suppress stdout when running the examples. @@ -239,6 +238,7 @@ static S2N_RESULT s2n_run_self_talk_test(s2n_test_scenario scenario_fn) fclose(stdout); struct s2n_connection *client = s2n_connection_new(S2N_CLIENT); + EXPECT_NOT_NULL(client); EXPECT_SUCCESS(s2n_connection_set_config(client, config)); EXPECT_SUCCESS(s2n_io_pair_close_one_end(&io_pair, S2N_SERVER)); @@ -247,6 +247,9 @@ static S2N_RESULT s2n_run_self_talk_test(s2n_test_scenario scenario_fn) EXPECT_OK(scenario_fn(client, &input)); EXPECT_SUCCESS(s2n_connection_free(client)); + EXPECT_SUCCESS(s2n_cert_chain_and_key_free(chain_and_key)); + EXPECT_SUCCESS(s2n_config_free(config)); + EXPECT_SUCCESS(s2n_free(&input)); exit(EXIT_SUCCESS); } @@ -267,6 +270,9 @@ static S2N_RESULT s2n_run_self_talk_test(s2n_test_scenario scenario_fn) EXPECT_OK(scenario_fn(server, &input)); EXPECT_SUCCESS(s2n_connection_free(server)); + EXPECT_SUCCESS(s2n_cert_chain_and_key_free(chain_and_key)); + EXPECT_SUCCESS(s2n_config_free(config)); + EXPECT_SUCCESS(s2n_free(&input)); exit(EXIT_SUCCESS); } @@ -277,6 +283,10 @@ static S2N_RESULT s2n_run_self_talk_test(s2n_test_scenario scenario_fn) RESULT_ENSURE_EQ(waitpid(server_pid, &status, 0), server_pid); RESULT_ENSURE_EQ(status, EXIT_SUCCESS); + EXPECT_SUCCESS(s2n_cert_chain_and_key_free(chain_and_key)); + EXPECT_SUCCESS(s2n_config_free(config)); + EXPECT_SUCCESS(s2n_free(&input)); + return S2N_RESULT_OK; } @@ -285,8 +295,8 @@ static S2N_RESULT s2n_run_failure_tests() uint8_t buffer[100] = { 0 }; size_t buffer_size = sizeof(buffer); - DEFER_CLEANUP(struct s2n_connection *conn = s2n_connection_new(S2N_CLIENT), - s2n_connection_ptr_free); + struct s2n_connection *conn = s2n_connection_new(S2N_CLIENT); + EXPECT_NOT_NULL(conn); EXPECT_SUCCESS(s2n_connection_set_blinding(conn, S2N_SELF_SERVICE_BLINDING)); pid_t pid = fork(); @@ -303,6 +313,8 @@ static S2N_RESULT s2n_run_failure_tests() EXPECT_EQUAL(s2n_example_recv(conn, buffer, buffer_size), S2N_FAILURE); EXPECT_EQUAL(s2n_example_recv_echo(conn, buffer, buffer_size), S2N_FAILURE); + EXPECT_SUCCESS(s2n_connection_free(conn)); + exit(EXIT_SUCCESS); } @@ -310,6 +322,8 @@ static S2N_RESULT s2n_run_failure_tests() RESULT_ENSURE_EQ(waitpid(pid, &status, 0), pid); RESULT_ENSURE_EQ(status, EXIT_SUCCESS); + EXPECT_SUCCESS(s2n_connection_free(conn)); + return S2N_RESULT_OK; } diff --git a/tests/unit/s2n_extended_master_secret_test.c b/tests/unit/s2n_extended_master_secret_test.c index 4e84e369db2..c112114fa64 100644 --- a/tests/unit/s2n_extended_master_secret_test.c +++ b/tests/unit/s2n_extended_master_secret_test.c @@ -23,7 +23,7 @@ int main(int argc, char **argv) /* Test s2n_conn_set_handshake_type is processing EMS data correctly */ { - struct s2n_config *config; + struct s2n_config *config = NULL; uint64_t current_time = 0; EXPECT_NOT_NULL(config = s2n_config_new()); diff --git a/tests/unit/s2n_extension_list_parse_test.c b/tests/unit/s2n_extension_list_parse_test.c index 86acea3ed4a..10d365f78d0 100644 --- a/tests/unit/s2n_extension_list_parse_test.c +++ b/tests/unit/s2n_extension_list_parse_test.c @@ -75,7 +75,7 @@ int main() s2n_extension_type empty_test_extension = test_extension; empty_test_extension.send = s2n_extension_send_no_data; - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); /* Safety checks */ @@ -408,7 +408,7 @@ int main() uint16_t expected_order[] = { test_extension.iana_value, test_extension_2.iana_value, test_extension_3.iana_value }; for (size_t i = 0; i < s2n_array_len(expected_order); i++) { - s2n_extension_type_id id; + s2n_extension_type_id id = 0; EXPECT_SUCCESS(s2n_extension_supported_iana_value_to_id(expected_order[i], &id)); EXPECT_EQUAL(parsed_extension_list.parsed_extensions[id].wire_index, i); } diff --git a/tests/unit/s2n_extension_list_process_test.c b/tests/unit/s2n_extension_list_process_test.c index 13d55a0309f..4e7ba8f12ea 100644 --- a/tests/unit/s2n_extension_list_process_test.c +++ b/tests/unit/s2n_extension_list_process_test.c @@ -78,7 +78,7 @@ int main() .if_missing = s2n_extension_noop_if_missing, }; - s2n_extension_type_id test_extension_type_internal_id; + s2n_extension_type_id test_extension_type_internal_id = 0; EXPECT_SUCCESS(s2n_extension_supported_iana_value_to_id(test_extension_type.iana_value, &test_extension_type_internal_id)); @@ -101,7 +101,7 @@ int main() .extension = extension_blob, }; - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); SET_PARSED_EXTENSION(parsed_extension_list, test_parsed_extension); @@ -154,7 +154,7 @@ int main() .extension = empty_blob, }; - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); SET_PARSED_EXTENSION(parsed_extension_list, test_parsed_extension); @@ -176,7 +176,7 @@ int main() .extension = extension_blob, }; - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); parsed_extension_list.parsed_extensions[test_extension_type_internal_id] = test_parsed_extension; @@ -200,7 +200,7 @@ int main() s2n_extension_type test_required_extension_type = test_extension_type; test_required_extension_type.if_missing = s2n_extension_error_if_missing; - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); received_flag = false; @@ -220,7 +220,7 @@ int main() s2n_extension_type test_optional_extension_type = test_extension_type; test_optional_extension_type.if_missing = s2n_extension_noop_if_missing; - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); received_flag = false; @@ -244,7 +244,7 @@ int main() /* Set up parsed_extensions for simple real extensions */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_setup_test_parsed_extension(&s2n_server_server_name_extension, @@ -277,7 +277,7 @@ int main() { s2n_parsed_extensions_list parsed_extension_list = { 0 }; - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_allow_all_response_extensions(conn)); @@ -297,7 +297,7 @@ int main() { s2n_parsed_extensions_list parsed_extension_list = { 0 }; - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_allow_all_response_extensions(conn)); @@ -319,7 +319,7 @@ int main() { s2n_parsed_extensions_list parsed_extension_list = { 0 }; - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_allow_all_response_extensions(conn)); diff --git a/tests/unit/s2n_extension_list_send_test.c b/tests/unit/s2n_extension_list_send_test.c index 3302012f51a..f0e348a8e58 100644 --- a/tests/unit/s2n_extension_list_send_test.c +++ b/tests/unit/s2n_extension_list_send_test.c @@ -39,11 +39,11 @@ int main(int argc, char **argv) struct s2n_stuffer stuffer = { 0 }; EXPECT_SUCCESS(s2n_stuffer_growable_alloc(&stuffer, 0)); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_extension_list_send(S2N_EXTENSION_LIST_EMPTY, conn, &stuffer)); - uint16_t extension_list_size; + uint16_t extension_list_size = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint16(&stuffer, &extension_list_size)); EXPECT_EQUAL(extension_list_size, s2n_stuffer_data_available(&stuffer)); EXPECT_EQUAL(extension_list_size, 0); @@ -57,11 +57,11 @@ int main(int argc, char **argv) struct s2n_stuffer stuffer = { 0 }; EXPECT_SUCCESS(s2n_stuffer_growable_alloc(&stuffer, 0)); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_extension_list_send(S2N_EXTENSION_LIST_CLIENT_HELLO, conn, &stuffer)); - uint16_t extension_list_size; + uint16_t extension_list_size = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint16(&stuffer, &extension_list_size)); EXPECT_EQUAL(extension_list_size, s2n_stuffer_data_available(&stuffer)); EXPECT_NOT_EQUAL(extension_list_size, 0); @@ -75,14 +75,14 @@ int main(int argc, char **argv) struct s2n_stuffer stuffer = { 0 }; EXPECT_SUCCESS(s2n_stuffer_growable_alloc(&stuffer, 0)); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); /* S2N_EXTENSION_LIST_CERTIFICATE only sends responses, and we haven't received any requests. * Therefore, it should write an empty extensions list. */ EXPECT_SUCCESS(s2n_extension_list_send(S2N_EXTENSION_LIST_CERTIFICATE, conn, &stuffer)); - uint16_t extension_list_size; + uint16_t extension_list_size = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint16(&stuffer, &extension_list_size)); EXPECT_EQUAL(extension_list_size, s2n_stuffer_data_available(&stuffer)); EXPECT_EQUAL(extension_list_size, 0); @@ -96,18 +96,18 @@ int main(int argc, char **argv) struct s2n_stuffer stuffer = { 0 }; EXPECT_SUCCESS(s2n_stuffer_growable_alloc(&stuffer, 0)); - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_extension_list_send(S2N_EXTENSION_LIST_CLIENT_HELLO, client_conn, &stuffer)); /* Skip list size - already tested */ EXPECT_SUCCESS(s2n_stuffer_skip_read(&stuffer, sizeof(uint16_t))); - uint16_t first_extension_type; + uint16_t first_extension_type = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint16(&stuffer, &first_extension_type)); EXPECT_EQUAL(first_extension_type, TLS_EXTENSION_SUPPORTED_VERSIONS); - uint16_t first_extension_size; + uint16_t first_extension_size = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint16(&stuffer, &first_extension_size)); EXPECT_NOT_EQUAL(first_extension_size, 0); @@ -115,7 +115,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_stuffer_growable_alloc(&extensions_stuffer, 0)); EXPECT_SUCCESS(s2n_stuffer_copy(&stuffer, &extensions_stuffer, first_extension_size)); - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_extension_recv(&s2n_client_supported_versions_extension, server_conn, &extensions_stuffer)); diff --git a/tests/unit/s2n_extension_type_test.c b/tests/unit/s2n_extension_type_test.c index b23c68ddaa2..189dc20458b 100644 --- a/tests/unit/s2n_extension_type_test.c +++ b/tests/unit/s2n_extension_type_test.c @@ -241,7 +241,7 @@ int main() { struct s2n_connection conn = { 0 }; struct s2n_stuffer stuffer = { 0 }; - s2n_stuffer_alloc(&stuffer, S2N_TEST_DATA_LEN * 2); + EXPECT_SUCCESS(s2n_stuffer_alloc(&stuffer, S2N_TEST_DATA_LEN * 2)); s2n_extension_type request_extension_type = test_extension_type; request_extension_type.is_response = false; @@ -251,12 +251,12 @@ int main() EXPECT_TRUE(S2N_CBIT_TEST(conn.extension_requests_sent, test_extension_id)); /* writes iana_value */ - uint16_t iana_value; + uint16_t iana_value = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint16(&stuffer, &iana_value)); EXPECT_EQUAL(iana_value, request_extension_type.iana_value); /* writes length */ - uint16_t length; + uint16_t length = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint16(&stuffer, &length)); EXPECT_EQUAL(length, s2n_stuffer_data_available(&stuffer)); EXPECT_EQUAL(length, S2N_TEST_DATA_LEN); @@ -283,7 +283,7 @@ int main() { struct s2n_connection conn = { 0 }; struct s2n_stuffer stuffer = { 0 }; - s2n_stuffer_alloc(&stuffer, S2N_TEST_DATA_LEN * 2); + EXPECT_SUCCESS(s2n_stuffer_alloc(&stuffer, S2N_TEST_DATA_LEN * 2)); s2n_extension_type response_extension_type = test_extension_type; response_extension_type.is_response = true; @@ -301,12 +301,12 @@ int main() EXPECT_BITFIELD_CLEAR(conn.extension_requests_sent); /* writes iana_value */ - uint16_t iana_value; + uint16_t iana_value = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint16(&stuffer, &iana_value)); EXPECT_EQUAL(iana_value, response_extension_type.iana_value); /* writes length */ - uint16_t length; + uint16_t length = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint16(&stuffer, &length)); EXPECT_EQUAL(length, s2n_stuffer_data_available(&stuffer)); EXPECT_EQUAL(length, S2N_TEST_DATA_LEN); @@ -332,7 +332,7 @@ int main() { struct s2n_connection conn = { 0 }; struct s2n_stuffer stuffer = { 0 }; - s2n_stuffer_alloc(&stuffer, S2N_TEST_DATA_LEN); + EXPECT_SUCCESS(s2n_stuffer_alloc(&stuffer, S2N_TEST_DATA_LEN)); s2n_extension_type extension_type_with_failure = test_extension_type; extension_type_with_failure.send = s2n_extension_send_unimplemented; @@ -348,7 +348,7 @@ int main() { struct s2n_connection conn = { 0 }; struct s2n_stuffer stuffer = { 0 }; - s2n_stuffer_growable_alloc(&stuffer, 0); + EXPECT_SUCCESS(s2n_stuffer_growable_alloc(&stuffer, 0)); s2n_extension_type extension_type_with_too_much_data = test_extension_type; extension_type_with_too_much_data.send = test_send_too_much_data; diff --git a/tests/unit/s2n_fips_test.c b/tests/unit/s2n_fips_test.c new file mode 100644 index 00000000000..c4e5bdc134e --- /dev/null +++ b/tests/unit/s2n_fips_test.c @@ -0,0 +1,53 @@ +/* +* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"). +* You may not use this file except in compliance with the License. +* A copy of the License is located at +* +* http://aws.amazon.com/apache2.0 +* +* or in the "license" file accompanying this file. This file is distributed +* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +* express or implied. See the License for the specific language governing +* permissions and limitations under the License. +*/ + +#include "crypto/s2n_fips.h" + +#include "api/s2n.h" +#include "s2n_test.h" + +int main() +{ + BEGIN_TEST_NO_INIT(); + + /* s2n_get_fips_mode() fails before init */ + { + s2n_fips_mode fips_mode = S2N_FIPS_MODE_ENABLED; + EXPECT_FAILURE_WITH_ERRNO(s2n_get_fips_mode(&fips_mode), S2N_ERR_NOT_INITIALIZED); + EXPECT_EQUAL(fips_mode, S2N_FIPS_MODE_DISABLED); + } + + EXPECT_SUCCESS(s2n_init()); + + /* Test s2n_get_fips_mode() after init */ + { + /* Safety */ + EXPECT_FAILURE_WITH_ERRNO(s2n_get_fips_mode(NULL), S2N_ERR_NULL); + + /* FIPS mode matches s2n_is_in_fips_mode() */ + { + s2n_fips_mode fips_mode = S2N_FIPS_MODE_DISABLED; + EXPECT_SUCCESS(s2n_get_fips_mode(&fips_mode)); + + if (s2n_is_in_fips_mode()) { + EXPECT_EQUAL(fips_mode, S2N_FIPS_MODE_ENABLED); + } else { + EXPECT_EQUAL(fips_mode, S2N_FIPS_MODE_DISABLED); + } + } + } + + END_TEST(); +} diff --git a/tests/unit/s2n_fragmentation_coalescing_test.c b/tests/unit/s2n_fragmentation_coalescing_test.c index 0a0b6ff7bbc..923244a3816 100644 --- a/tests/unit/s2n_fragmentation_coalescing_test.c +++ b/tests/unit/s2n_fragmentation_coalescing_test.c @@ -391,12 +391,12 @@ void interleaved_fragmented_warning_alert(int write_fd) int main(int argc, char **argv) { - struct s2n_connection *conn; - struct s2n_config *config; + struct s2n_connection *conn = NULL; + struct s2n_config *config = NULL; s2n_blocked_status blocked; - int status; - pid_t pid; + int status = 0; + pid_t pid = 0; int p[2]; BEGIN_TEST(); diff --git a/tests/unit/s2n_handshake_errno_test.c b/tests/unit/s2n_handshake_errno_test.c index 22539f6ff7d..560bdd454d9 100644 --- a/tests/unit/s2n_handshake_errno_test.c +++ b/tests/unit/s2n_handshake_errno_test.c @@ -37,7 +37,7 @@ int fake_send(void *io_context, const uint8_t *buf, uint32_t len) int main(int argc, char **argv) { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; s2n_blocked_status blocked; BEGIN_TEST(); diff --git a/tests/unit/s2n_handshake_invariant_test.c b/tests/unit/s2n_handshake_invariant_test.c index a99837f6340..207dd0df911 100644 --- a/tests/unit/s2n_handshake_invariant_test.c +++ b/tests/unit/s2n_handshake_invariant_test.c @@ -68,7 +68,7 @@ int main(int argc, char **argv) BEGIN_TEST(); EXPECT_SUCCESS(s2n_disable_tls13_in_test()); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); /* Initialize *some* handshake type. Not terribly relevant for this test. */ diff --git a/tests/unit/s2n_handshake_io_test.c b/tests/unit/s2n_handshake_io_test.c index 4885abeae2a..2604a177af4 100644 --- a/tests/unit/s2n_handshake_io_test.c +++ b/tests/unit/s2n_handshake_io_test.c @@ -37,7 +37,7 @@ int main(int argc, char **argv) /* s2n_negotiate can't be called recursively */ { /* Setup connections */ - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_OK(s2n_connection_set_secrets(conn)); diff --git a/tests/unit/s2n_handshake_test.c b/tests/unit/s2n_handshake_test.c index c5e0ca314eb..72c8faea66a 100644 --- a/tests/unit/s2n_handshake_test.c +++ b/tests/unit/s2n_handshake_test.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include "api/s2n.h" @@ -242,9 +243,9 @@ int main(int argc, char **argv) for (test_type = TEST_TYPE_START; test_type < TEST_TYPE_END; test_type++) { /* Test: RSA cert */ { - struct s2n_config *server_config, *client_config; + struct s2n_config *server_config = NULL, *client_config = NULL; - struct s2n_cert_chain_and_key *chain_and_key; + struct s2n_cert_chain_and_key *chain_and_key = NULL; EXPECT_SUCCESS(s2n_test_cert_chain_and_key_new(&chain_and_key, S2N_DEFAULT_TEST_CERT_CHAIN, S2N_DEFAULT_TEST_PRIVATE_KEY)); @@ -277,9 +278,9 @@ int main(int argc, char **argv) if (!s2n_is_in_fips_mode()) { /* Enable TLS 1.3 for the client */ EXPECT_SUCCESS(s2n_enable_tls13_in_test()); - struct s2n_config *server_config, *client_config; + struct s2n_config *server_config = NULL, *client_config = NULL; - struct s2n_cert_chain_and_key *chain_and_key; + struct s2n_cert_chain_and_key *chain_and_key = NULL; EXPECT_SUCCESS(s2n_test_cert_chain_and_key_new(&chain_and_key, S2N_DEFAULT_TEST_CERT_CHAIN, S2N_DEFAULT_TEST_PRIVATE_KEY)); @@ -313,9 +314,9 @@ int main(int argc, char **argv) /* Test: ECDSA cert */ { - struct s2n_config *server_config, *client_config; + struct s2n_config *server_config = NULL, *client_config = NULL; - struct s2n_cert_chain_and_key *chain_and_key; + struct s2n_cert_chain_and_key *chain_and_key = NULL; EXPECT_SUCCESS(s2n_test_cert_chain_and_key_new(&chain_and_key, S2N_ECDSA_P384_PKCS1_CERT_CHAIN, S2N_ECDSA_P384_PKCS1_KEY)); @@ -357,9 +358,9 @@ int main(int argc, char **argv) .signature_schemes = rsa_pss_rsae_sig_schemes, }; - struct s2n_config *server_config, *client_config; + struct s2n_config *server_config = NULL, *client_config = NULL; - struct s2n_cert_chain_and_key *chain_and_key; + struct s2n_cert_chain_and_key *chain_and_key = NULL; EXPECT_SUCCESS(s2n_test_cert_chain_and_key_new(&chain_and_key, S2N_DEFAULT_TEST_CERT_CHAIN, S2N_DEFAULT_TEST_PRIVATE_KEY)); @@ -383,7 +384,6 @@ int main(int argc, char **argv) server_config->security_policy = &security_policy; EXPECT_NOT_NULL(client_config = s2n_config_new()); - client_config->client_cert_auth_type = S2N_CERT_AUTH_NONE; client_config->check_ocsp = 0; client_config->disable_x509_validation = 1; client_config->security_policy = &security_policy; @@ -402,9 +402,9 @@ int main(int argc, char **argv) if (s2n_is_rsa_pss_certs_supported()) { s2n_enable_tls13_in_test(); - struct s2n_config *server_config, *client_config; + struct s2n_config *server_config = NULL, *client_config = NULL; - struct s2n_cert_chain_and_key *chain_and_key; + struct s2n_cert_chain_and_key *chain_and_key = NULL; EXPECT_SUCCESS(s2n_test_cert_chain_and_key_new(&chain_and_key, S2N_RSA_PSS_2048_SHA256_LEAF_CERT, S2N_RSA_PSS_2048_SHA256_LEAF_KEY)); @@ -419,7 +419,6 @@ int main(int argc, char **argv) EXPECT_NOT_NULL(client_config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_set_cipher_preferences(client_config, "20200207")); - client_config->client_cert_auth_type = S2N_CERT_AUTH_NONE; client_config->check_ocsp = 0; client_config->disable_x509_validation = 1; @@ -434,6 +433,46 @@ int main(int argc, char **argv) } } + /* Ensure that a handshake can be performed after all file descriptors are closed */ + { + /* A fork is created to ensure that closing file descriptors (like stdout) won't impact + * other tests. + */ + pid_t pid = fork(); + if (pid == 0) { + long max_file_descriptors = sysconf(_SC_OPEN_MAX); + for (long fd = 0; fd < max_file_descriptors; fd++) { + EXPECT_TRUE(fd <= INT_MAX); + close((int) fd); + } + + /* use a nested scope to force the DEFER_CLEANUP statements to + * execute before the exit() call. + */ + { + DEFER_CLEANUP(struct s2n_cert_chain_and_key *chain_and_key = NULL, s2n_cert_chain_and_key_ptr_free); + EXPECT_SUCCESS(s2n_test_cert_chain_and_key_new(&chain_and_key, + S2N_DEFAULT_TEST_CERT_CHAIN, S2N_DEFAULT_TEST_PRIVATE_KEY)); + EXPECT_NOT_NULL(chain_and_key); + + 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_add_cert_chain_and_key_to_store(config, chain_and_key)); + EXPECT_SUCCESS(s2n_config_set_verification_ca_location(config, S2N_DEFAULT_TEST_CERT_CHAIN, NULL)); + EXPECT_SUCCESS(s2n_config_disable_x509_verification(config)); + + EXPECT_SUCCESS(test_cipher_preferences(config, config, chain_and_key, S2N_SIGNATURE_RSA)); + } + + exit(EXIT_SUCCESS); + } + + int status = 0; + EXPECT_EQUAL(waitpid(pid, &status, 0), pid); + EXPECT_EQUAL(status, EXIT_SUCCESS); + } + END_TEST(); return 0; } diff --git a/tests/unit/s2n_hash_test.c b/tests/unit/s2n_hash_test.c index 9c9d6aceb03..d9514e960b8 100644 --- a/tests/unit/s2n_hash_test.c +++ b/tests/unit/s2n_hash_test.c @@ -35,7 +35,7 @@ int main(int argc, char **argv) struct s2n_hash_state hash, copy; struct s2n_blob out = { 0 }; POSIX_GUARD(s2n_blob_init(&out, output_pad, sizeof(output_pad))); - uint64_t bytes_in_hash; + uint64_t bytes_in_hash = 0; BEGIN_TEST(); EXPECT_SUCCESS(s2n_disable_tls13_in_test()); @@ -57,7 +57,7 @@ int main(int argc, char **argv) if (s2n_hash_is_available(S2N_HASH_MD5)) { /* Try MD5 */ - uint8_t md5_digest_size; + uint8_t md5_digest_size = 0; POSIX_GUARD(s2n_hash_digest_size(S2N_HASH_MD5, &md5_digest_size)); EXPECT_EQUAL(md5_digest_size, 16); EXPECT_SUCCESS(s2n_hash_init(&hash, S2N_HASH_MD5)); @@ -89,7 +89,7 @@ int main(int argc, char **argv) } /* Try SHA1 */ - uint8_t sha1_digest_size; + uint8_t sha1_digest_size = 0; POSIX_GUARD(s2n_hash_digest_size(S2N_HASH_SHA1, &sha1_digest_size)); EXPECT_EQUAL(sha1_digest_size, 20); EXPECT_SUCCESS(s2n_hash_init(&hash, S2N_HASH_SHA1)); @@ -206,7 +206,7 @@ int main(int argc, char **argv) EXPECT_EQUAL(bytes_in_hash, 0); /* Try SHA224 and test s2n_hash_free */ - uint8_t sha224_digest_size; + uint8_t sha224_digest_size = 0; POSIX_GUARD(s2n_hash_digest_size(S2N_HASH_SHA224, &sha224_digest_size)); EXPECT_EQUAL(sha224_digest_size, 28); EXPECT_SUCCESS(s2n_hash_init(&hash, S2N_HASH_SHA224)); @@ -240,7 +240,7 @@ int main(int argc, char **argv) EXPECT_FALSE(s2n_hash_is_ready_for_input(&hash)); EXPECT_FAILURE(s2n_hash_get_currently_in_hash_total(&hash, &bytes_in_hash)); - uint8_t sha256_digest_size; + uint8_t sha256_digest_size = 0; POSIX_GUARD(s2n_hash_digest_size(S2N_HASH_SHA256, &sha256_digest_size)); EXPECT_EQUAL(sha256_digest_size, 32); EXPECT_SUCCESS(s2n_hash_init(&hash, S2N_HASH_SHA256)); @@ -271,7 +271,7 @@ int main(int argc, char **argv) EXPECT_EQUAL(bytes_in_hash, 0); /* Try SHA384 */ - uint8_t sha384_digest_size; + uint8_t sha384_digest_size = 0; POSIX_GUARD(s2n_hash_digest_size(S2N_HASH_SHA384, &sha384_digest_size)); EXPECT_EQUAL(sha384_digest_size, 48); EXPECT_SUCCESS(s2n_hash_init(&hash, S2N_HASH_SHA384)); @@ -302,7 +302,7 @@ int main(int argc, char **argv) EXPECT_EQUAL(bytes_in_hash, 0); /* Try SHA512 */ - uint8_t sha512_digest_size; + uint8_t sha512_digest_size = 0; POSIX_GUARD(s2n_hash_digest_size(S2N_HASH_SHA512, &sha512_digest_size)); EXPECT_EQUAL(sha512_digest_size, 64); EXPECT_SUCCESS(s2n_hash_init(&hash, S2N_HASH_SHA512)); diff --git a/tests/unit/s2n_hmac_test.c b/tests/unit/s2n_hmac_test.c index 123b2da7eb8..75a4955778f 100644 --- a/tests/unit/s2n_hmac_test.c +++ b/tests/unit/s2n_hmac_test.c @@ -49,7 +49,7 @@ int main(int argc, char **argv) if (s2n_hmac_is_available(S2N_HMAC_SSLv3_MD5)) { /* Try SSLv3 MD5 */ - uint8_t hmac_sslv3_md5_size; + uint8_t hmac_sslv3_md5_size = 0; POSIX_GUARD(s2n_hmac_digest_size(S2N_HMAC_SSLv3_MD5, &hmac_sslv3_md5_size)); EXPECT_EQUAL(hmac_sslv3_md5_size, 16); EXPECT_SUCCESS(s2n_hmac_init(&hmac, S2N_HMAC_SSLv3_MD5, sekrit, strlen((char *) sekrit))); @@ -82,7 +82,7 @@ int main(int argc, char **argv) if (s2n_hmac_is_available(S2N_HMAC_SSLv3_SHA1)) { /* Try SSLv3 SHA1 */ - uint8_t hmac_sslv3_sha1_size; + uint8_t hmac_sslv3_sha1_size = 0; POSIX_GUARD(s2n_hmac_digest_size(S2N_HMAC_SSLv3_SHA1, &hmac_sslv3_sha1_size)); EXPECT_EQUAL(hmac_sslv3_sha1_size, 20); EXPECT_SUCCESS(s2n_hmac_init(&hmac, S2N_HMAC_SSLv3_SHA1, sekrit, strlen((char *) sekrit))); @@ -115,7 +115,7 @@ int main(int argc, char **argv) if (s2n_hmac_is_available(S2N_HMAC_MD5)) { /* Try MD5 */ - uint8_t hmac_md5_size; + uint8_t hmac_md5_size = 0; POSIX_GUARD(s2n_hmac_digest_size(S2N_HMAC_MD5, &hmac_md5_size)); EXPECT_EQUAL(hmac_md5_size, 16); EXPECT_SUCCESS(s2n_hmac_init(&hmac, S2N_HMAC_MD5, sekrit, strlen((char *) sekrit))); @@ -134,7 +134,7 @@ int main(int argc, char **argv) } /* Try SHA1 */ - uint8_t hmac_sha1_size; + uint8_t hmac_sha1_size = 0; POSIX_GUARD(s2n_hmac_digest_size(S2N_HMAC_SHA1, &hmac_sha1_size)); EXPECT_EQUAL(hmac_sha1_size, 20); EXPECT_SUCCESS(s2n_hmac_init(&hmac, S2N_HMAC_SHA1, sekrit, strlen((char *) sekrit))); @@ -216,7 +216,7 @@ int main(int argc, char **argv) /* Try SHA224 */ EXPECT_SUCCESS(s2n_hmac_new(&hmac)); - uint8_t hmac_sha224_size; + uint8_t hmac_sha224_size = 0; POSIX_GUARD(s2n_hmac_digest_size(S2N_HMAC_SHA224, &hmac_sha224_size)); EXPECT_EQUAL(hmac_sha224_size, 28); EXPECT_SUCCESS(s2n_hmac_init(&hmac, S2N_HMAC_SHA224, sekrit, strlen((char *) sekrit))); @@ -235,7 +235,7 @@ int main(int argc, char **argv) /* Try SHA256 */ EXPECT_SUCCESS(s2n_hmac_new(&hmac)); - uint8_t hmac_sha256_size; + uint8_t hmac_sha256_size = 0; POSIX_GUARD(s2n_hmac_digest_size(S2N_HMAC_SHA256, &hmac_sha256_size)); EXPECT_EQUAL(hmac_sha256_size, 32); EXPECT_SUCCESS(s2n_hmac_init(&hmac, S2N_HMAC_SHA256, sekrit, strlen((char *) sekrit))); @@ -254,7 +254,7 @@ int main(int argc, char **argv) /* Try SHA384 */ EXPECT_SUCCESS(s2n_hmac_new(&hmac)); - uint8_t hmac_sha384_size; + uint8_t hmac_sha384_size = 0; POSIX_GUARD(s2n_hmac_digest_size(S2N_HMAC_SHA384, &hmac_sha384_size)); EXPECT_EQUAL(hmac_sha384_size, 48); EXPECT_SUCCESS(s2n_hmac_init(&hmac, S2N_HMAC_SHA384, sekrit, strlen((char *) sekrit))); @@ -273,7 +273,7 @@ int main(int argc, char **argv) /* Try SHA512 */ EXPECT_SUCCESS(s2n_hmac_new(&hmac)); - uint8_t hmac_sha512_size; + uint8_t hmac_sha512_size = 0; POSIX_GUARD(s2n_hmac_digest_size(S2N_HMAC_SHA512, &hmac_sha512_size)); EXPECT_EQUAL(hmac_sha512_size, 64); EXPECT_SUCCESS(s2n_hmac_init(&hmac, S2N_HMAC_SHA512, sekrit, strlen((char *) sekrit))); diff --git a/tests/unit/s2n_kem_test.c b/tests/unit/s2n_kem_test.c index c9423bc6606..d0b9d7db2ab 100644 --- a/tests/unit/s2n_kem_test.c +++ b/tests/unit/s2n_kem_test.c @@ -371,7 +371,7 @@ int main(int argc, char **argv) struct s2n_stuffer io_stuffer = { 0 }; EXPECT_SUCCESS(s2n_stuffer_init(&io_stuffer, &io_blob)); - s2n_alloc(&(kem_params.private_key), TEST_PRIVATE_KEY_LENGTH); + EXPECT_SUCCESS(s2n_alloc(&(kem_params.private_key), TEST_PRIVATE_KEY_LENGTH)); POSIX_CHECKED_MEMCPY(kem_params.private_key.data, TEST_PRIVATE_KEY, TEST_PRIVATE_KEY_LENGTH); /* {0, 5} = length of ciphertext to follow diff --git a/tests/unit/s2n_kex_with_kem_test.c b/tests/unit/s2n_kex_with_kem_test.c index 865c2495f73..e49d9480946 100644 --- a/tests/unit/s2n_kex_with_kem_test.c +++ b/tests/unit/s2n_kex_with_kem_test.c @@ -40,8 +40,8 @@ static struct s2n_cipher_suite kyber_test_suite = { static int do_kex_with_kem(struct s2n_cipher_suite *cipher_suite, const char *security_policy_version, const struct s2n_kem *negotiated_kem) { - struct s2n_connection *client_conn; - struct s2n_connection *server_conn; + struct s2n_connection *client_conn = NULL; + struct s2n_connection *server_conn = NULL; POSIX_GUARD_PTR(client_conn = s2n_connection_new(S2N_CLIENT)); POSIX_GUARD_PTR(server_conn = s2n_connection_new(S2N_SERVER)); @@ -116,7 +116,7 @@ static int do_kex_with_kem(struct s2n_cipher_suite *cipher_suite, const char *se static int assert_pq_disabled_checks(struct s2n_cipher_suite *cipher_suite, const char *security_policy_version, const struct s2n_kem *negotiated_kem) { - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; POSIX_GUARD_PTR(server_conn = s2n_connection_new(S2N_SERVER)); const struct s2n_security_policy *security_policy = NULL; POSIX_GUARD(s2n_find_security_policy_from_version(security_policy_version, &security_policy)); diff --git a/tests/unit/s2n_key_update_test.c b/tests/unit/s2n_key_update_test.c index 23955cdd2a8..4146ad29442 100644 --- a/tests/unit/s2n_key_update_test.c +++ b/tests/unit/s2n_key_update_test.c @@ -82,15 +82,15 @@ int main(int argc, char **argv) /* Move stuffer write cursor to correct position */ EXPECT_SUCCESS(s2n_stuffer_skip_write(&key_update_stuffer, S2N_KEY_UPDATE_MESSAGE_SIZE)); - uint8_t post_handshake_id; + uint8_t post_handshake_id = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint8(&key_update_stuffer, &post_handshake_id)); EXPECT_EQUAL(post_handshake_id, TLS_KEY_UPDATE); - uint32_t request_length; + uint32_t request_length = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint24(&key_update_stuffer, &request_length)); EXPECT_EQUAL(request_length, S2N_KEY_UPDATE_LENGTH); - uint8_t key_update_request; + uint8_t key_update_request = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint8(&key_update_stuffer, &key_update_request)); EXPECT_EQUAL(key_update_request, S2N_KEY_UPDATE_NOT_REQUESTED); }; @@ -111,11 +111,11 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_stuffer_alloc(&input, test_data_len)); EXPECT_SUCCESS(s2n_stuffer_skip_write(&input, test_data_len)); - struct s2n_config *quic_config; + struct s2n_config *quic_config = NULL; EXPECT_NOT_NULL(quic_config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_enable_quic(quic_config)); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_config(conn, quic_config)); @@ -136,7 +136,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_stuffer_alloc(&input, test_data_len)); EXPECT_SUCCESS(s2n_stuffer_skip_write(&input, test_data_len)); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); conn->actual_protocol_version = S2N_TLS12; @@ -193,7 +193,7 @@ int main(int argc, char **argv) DEFER_CLEANUP(struct s2n_stuffer input, s2n_stuffer_free); EXPECT_SUCCESS(s2n_stuffer_growable_alloc(&input, 0)); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); /* Write invalid value for key update request type */ EXPECT_SUCCESS(s2n_stuffer_write_uint8(&input, -1)); @@ -208,7 +208,7 @@ int main(int argc, char **argv) DEFER_CLEANUP(struct s2n_stuffer input, s2n_stuffer_free); EXPECT_SUCCESS(s2n_stuffer_growable_alloc(&input, 0)); - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); server_conn->actual_protocol_version = S2N_TLS13; server_conn->secure->cipher_suite = cipher_suite_with_limit; @@ -231,7 +231,7 @@ int main(int argc, char **argv) DEFER_CLEANUP(struct s2n_stuffer input, s2n_stuffer_free); EXPECT_SUCCESS(s2n_stuffer_growable_alloc(&input, 0)); - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); client_conn->actual_protocol_version = S2N_TLS13; client_conn->secure->cipher_suite = cipher_suite_with_limit; @@ -322,7 +322,7 @@ int main(int argc, char **argv) { /* Key update has been requested */ { - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); client_conn->actual_protocol_version = S2N_TLS13; client_conn->secure->cipher_suite = cipher_suite_with_limit; @@ -333,7 +333,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_stuffer_growable_alloc(&stuffer, 0)); EXPECT_SUCCESS(s2n_connection_set_io_stuffers(&stuffer, &stuffer, client_conn)); - s2n_atomic_flag_set(&client_conn->key_update_pending); + EXPECT_SUCCESS(s2n_connection_request_key_update(client_conn, S2N_KEY_UPDATE_NOT_REQUESTED)); s2n_blocked_status blocked = 0; EXPECT_SUCCESS(s2n_key_update_send(client_conn, &blocked)); @@ -349,7 +349,7 @@ int main(int argc, char **argv) /* Key update is triggered by encryption limits */ { - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); client_conn->actual_protocol_version = S2N_TLS13; client_conn->secure->cipher_suite = cipher_suite_with_limit; @@ -404,7 +404,7 @@ int main(int argc, char **argv) /* Key update is not triggered */ { - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); client_conn->actual_protocol_version = S2N_TLS13; client_conn->secure->cipher_suite = cipher_suite_with_limit; @@ -677,5 +677,27 @@ int main(int argc, char **argv) } } + /* s2n_connection_key_update_requested */ + { + /* null safety */ + { + EXPECT_FAILURE_WITH_ERRNO(s2n_connection_request_key_update(NULL, S2N_KEY_UPDATE_NOT_REQUESTED), S2N_ERR_NULL); + }; + + /* usage */ + { + DEFER_CLEANUP(struct s2n_connection *conn = s2n_connection_new(S2N_SERVER), s2n_connection_ptr_free); + EXPECT_FAILURE_WITH_ERRNO(s2n_connection_request_key_update(conn, S2N_KEY_UPDATE_REQUESTED), S2N_ERR_INVALID_ARGUMENT); + }; + + /* happy path */ + { + DEFER_CLEANUP(struct s2n_connection *conn = s2n_connection_new(S2N_SERVER), s2n_connection_ptr_free); + EXPECT_FALSE(s2n_atomic_flag_test(&conn->key_update_pending)); + EXPECT_SUCCESS(s2n_connection_request_key_update(conn, S2N_KEY_UPDATE_NOT_REQUESTED)); + EXPECT_TRUE(s2n_atomic_flag_test(&conn->key_update_pending)); + }; + }; + END_TEST(); } diff --git a/tests/unit/s2n_key_update_threads_test.c b/tests/unit/s2n_key_update_threads_test.c index 0a7ef4dd4c0..364e26edf67 100644 --- a/tests/unit/s2n_key_update_threads_test.c +++ b/tests/unit/s2n_key_update_threads_test.c @@ -35,7 +35,7 @@ _##name##_record_alg.encryption_limit = limit; \ name.record_alg = &_##name##_record_alg; -S2N_RESULT s2n_set_key_update_request_for_testing(keyupdate_request request); +S2N_RESULT s2n_set_key_update_request_for_testing(s2n_peer_key_update request); static void *s2n_send_random_data(void *arg) { @@ -176,13 +176,12 @@ static S2N_RESULT s2n_test_peer_requests(struct s2n_connection *conn) typedef S2N_RESULT (*s2n_test_scenario)(struct s2n_connection *conn); static S2N_RESULT s2n_run_self_talk_test(s2n_test_scenario scenario_fn) { - DEFER_CLEANUP(struct s2n_cert_chain_and_key *chain_and_key = NULL, - s2n_cert_chain_and_key_ptr_free); + struct s2n_cert_chain_and_key *chain_and_key = NULL; RESULT_GUARD_POSIX(s2n_test_cert_chain_and_key_new(&chain_and_key, S2N_DEFAULT_TEST_CERT_CHAIN, S2N_DEFAULT_TEST_PRIVATE_KEY)); - DEFER_CLEANUP(struct s2n_config *config = s2n_config_new(), - s2n_config_ptr_free); + struct s2n_config *config = s2n_config_new(); + RESULT_ENSURE_REF(config); RESULT_GUARD_POSIX(s2n_config_set_unsafe_for_testing(config)); RESULT_GUARD_POSIX(s2n_config_set_cipher_preferences(config, "default_tls13")); RESULT_GUARD_POSIX(s2n_config_add_cert_chain_and_key_to_store(config, chain_and_key)); @@ -207,6 +206,9 @@ static S2N_RESULT s2n_run_self_talk_test(s2n_test_scenario scenario_fn) EXPECT_OK(scenario_fn(client)); EXPECT_SUCCESS(s2n_connection_free(client)); + EXPECT_SUCCESS(s2n_cert_chain_and_key_free(chain_and_key)); + EXPECT_SUCCESS(s2n_config_free(config)); + exit(EXIT_SUCCESS); } @@ -227,6 +229,9 @@ static S2N_RESULT s2n_run_self_talk_test(s2n_test_scenario scenario_fn) EXPECT_OK(scenario_fn(server)); EXPECT_SUCCESS(s2n_connection_free(server)); + EXPECT_SUCCESS(s2n_cert_chain_and_key_free(chain_and_key)); + EXPECT_SUCCESS(s2n_config_free(config)); + exit(EXIT_SUCCESS); } @@ -236,6 +241,9 @@ static S2N_RESULT s2n_run_self_talk_test(s2n_test_scenario scenario_fn) RESULT_ENSURE_EQ(waitpid(server_pid, &status, 0), server_pid); RESULT_ENSURE_EQ(status, EXIT_SUCCESS); + EXPECT_SUCCESS(s2n_cert_chain_and_key_free(chain_and_key)); + EXPECT_SUCCESS(s2n_config_free(config)); + return S2N_RESULT_OK; } diff --git a/tests/unit/s2n_ktls_test.c b/tests/unit/s2n_ktls_test.c index 5309911fbcb..a57254c4432 100644 --- a/tests/unit/s2n_ktls_test.c +++ b/tests/unit/s2n_ktls_test.c @@ -184,7 +184,7 @@ int main(int argc, char **argv) EXPECT_EQUAL(crypto_info.value.size, sizeof(crypto_info.ciphers.aes_gcm_128)); EXPECT_EQUAL(crypto_info.value.data, (uint8_t *) &crypto_info.ciphers.aes_gcm_128); s2n_ktls_crypto_info_tls12_aes_gcm_128 *value = - (s2n_ktls_crypto_info_tls12_aes_gcm_128 *) crypto_info.value.data; + (s2n_ktls_crypto_info_tls12_aes_gcm_128 *) (void *) crypto_info.value.data; EXPECT_EQUAL(test_key.size, sizeof(value->key)); EXPECT_BYTEARRAY_EQUAL(test_key.data, value->key, sizeof(value->key)); @@ -216,7 +216,7 @@ int main(int argc, char **argv) EXPECT_EQUAL(crypto_info.value.size, sizeof(crypto_info.ciphers.aes_gcm_256)); EXPECT_EQUAL(crypto_info.value.data, (uint8_t *) &crypto_info.ciphers.aes_gcm_256); s2n_ktls_crypto_info_tls12_aes_gcm_256 *value = - (s2n_ktls_crypto_info_tls12_aes_gcm_256 *) crypto_info.value.data; + (s2n_ktls_crypto_info_tls12_aes_gcm_256 *) (void *) crypto_info.value.data; EXPECT_EQUAL(test_key.size, sizeof(value->key)); EXPECT_BYTEARRAY_EQUAL(test_key.data, value->key, sizeof(value->key)); @@ -370,14 +370,20 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_stuffer_write_uint8(&server_conn->out, write_byte)); EXPECT_FAILURE_WITH_ERRNO(s2n_connection_ktls_enable_send(server_conn), S2N_ERR_RECORD_STUFFER_NEEDS_DRAINING); /* drain conn->out buffer and assert success case */ - EXPECT_SUCCESS(s2n_stuffer_read_bytes(&server_conn->out, &read_byte, 1)); + EXPECT_SUCCESS(s2n_stuffer_read_uint8(&server_conn->out, &read_byte)); EXPECT_SUCCESS(s2n_connection_ktls_enable_send(server_conn)); - /* write to conn->in buffer and assert error */ + /* write to conn->header_in and assert error */ + EXPECT_SUCCESS(s2n_stuffer_write_uint8(&server_conn->header_in, write_byte)); + EXPECT_FAILURE_WITH_ERRNO(s2n_connection_ktls_enable_recv(server_conn), S2N_ERR_RECORD_STUFFER_NEEDS_DRAINING); + EXPECT_SUCCESS(s2n_stuffer_read_uint8(&server_conn->header_in, &read_byte)); + /* write to conn->in and assert error */ EXPECT_SUCCESS(s2n_stuffer_write_uint8(&server_conn->in, write_byte)); EXPECT_FAILURE_WITH_ERRNO(s2n_connection_ktls_enable_recv(server_conn), S2N_ERR_RECORD_STUFFER_NEEDS_DRAINING); - /* drain conn->in buffer and assert success case */ - EXPECT_SUCCESS(s2n_stuffer_read_bytes(&server_conn->in, &read_byte, 1)); + EXPECT_SUCCESS(s2n_stuffer_read_uint8(&server_conn->in, &read_byte)); + /* assert success with both IO buffers drained */ + EXPECT_EQUAL(s2n_stuffer_data_available(&server_conn->header_in), 0); + EXPECT_EQUAL(s2n_stuffer_data_available(&server_conn->in), 0); EXPECT_SUCCESS(s2n_connection_ktls_enable_recv(server_conn)); }; diff --git a/tests/unit/s2n_malformed_handshake_test.c b/tests/unit/s2n_malformed_handshake_test.c index 78f636aa80d..8b032f88cdf 100644 --- a/tests/unit/s2n_malformed_handshake_test.c +++ b/tests/unit/s2n_malformed_handshake_test.c @@ -228,8 +228,8 @@ void send_messages(int write_fd, uint8_t *server_hello, uint32_t server_hello_le int main(int argc, char **argv) { s2n_blocked_status blocked; - int status; - pid_t pid; + int status = 0; + pid_t pid = 0; int p[2]; BEGIN_TEST(); diff --git a/tests/unit/s2n_map_iterator_test.c b/tests/unit/s2n_map_iterator_test.c new file mode 100644 index 00000000000..dff3080d2d1 --- /dev/null +++ b/tests/unit/s2n_map_iterator_test.c @@ -0,0 +1,134 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +#include "api/s2n.h" +#include "s2n_test.h" +#include "utils/s2n_map.h" +#include "utils/s2n_map_internal.h" + +#define TEST_VALUE_COUNT 10 + +int main(int argc, char **argv) +{ + BEGIN_TEST(); + + /* s2n_map_iterator iteration test */ + { + struct s2n_map *map = s2n_map_new(); + EXPECT_NOT_NULL(map); + /* fail to initialize an iterator on a mutable map */ + { + struct s2n_map_iterator iter = { 0 }; + EXPECT_ERROR_WITH_ERRNO(s2n_map_iterator_init(&iter, map), S2N_ERR_MAP_MUTABLE); + }; + + EXPECT_OK(s2n_map_complete(map)); + + /* has next is false on an empty map, and next returns an error */ + { + struct s2n_map_iterator iter = { 0 }; + EXPECT_OK(s2n_map_iterator_init(&iter, map)); + + EXPECT_FALSE(s2n_map_iterator_has_next(&iter)); + + struct s2n_blob value = { 0 }; + EXPECT_ERROR_WITH_ERRNO(s2n_map_iterator_next(&iter, &value), S2N_ERR_ARRAY_INDEX_OOB); + }; + + EXPECT_OK(s2n_map_unlock(map)); + for (uint8_t i = 0; i < TEST_VALUE_COUNT; i++) { + struct s2n_blob key = { .size = 1, .data = &i }; + struct s2n_blob val = { .size = 1, .data = &i }; + EXPECT_OK(s2n_map_put(map, &key, &val)); + } + EXPECT_OK(s2n_map_complete(map)); + + /* iterator goes over all elements */ + { + bool seen[TEST_VALUE_COUNT] = { 0 }; + + struct s2n_map_iterator iter = { 0 }; + EXPECT_OK(s2n_map_iterator_init(&iter, map)); + + struct s2n_blob value = { 0 }; + for (size_t i = 0; i < TEST_VALUE_COUNT; i++) { + EXPECT_TRUE(s2n_map_iterator_has_next(&iter)); + + EXPECT_OK(s2n_map_iterator_next(&iter, &value)); + seen[*value.data] = true; + } + + /* all elements have been iterated over */ + EXPECT_FALSE(s2n_map_iterator_has_next(&iter)); + EXPECT_ERROR_WITH_ERRNO(s2n_map_iterator_next(&iter, &value), S2N_ERR_ARRAY_INDEX_OOB); + + /* all elements were seen */ + for (size_t i = 0; i < TEST_VALUE_COUNT; i++) { + EXPECT_TRUE(seen[i]); + } + }; + + /* next returns an error when the blob is null */ + { + struct s2n_map_iterator iter = { 0 }; + EXPECT_OK(s2n_map_iterator_init(&iter, map)); + + EXPECT_ERROR_WITH_ERRNO(s2n_map_iterator_next(&iter, NULL), S2N_ERR_NULL); + } + + EXPECT_OK(s2n_map_free(map)); + }; + + /* test first and last slots in table */ + { + /* 2 (first and last slot) * 2 (key and value) */ + struct s2n_blob blobs[2 * 2] = { 0 }; + for (uint8_t i = 0; i < (2 * 2); i++) { + EXPECT_SUCCESS(s2n_alloc(&blobs[i], 1)); + *blobs[i].data = i; + } + + struct s2n_map *test_map = s2n_map_new(); + EXPECT_NOT_NULL(test_map); + + /* set values in map to 0 and 1 */ + test_map->table[0].value = blobs[0]; + test_map->table[0].key = blobs[2]; + test_map->table[test_map->capacity - 1].value = blobs[1]; + test_map->table[test_map->capacity - 1].key = blobs[3]; + + test_map->size = 2; + EXPECT_OK(s2n_map_complete(test_map)); + + struct s2n_map_iterator iter = { 0 }; + EXPECT_OK(s2n_map_iterator_init(&iter, test_map)); + bool seen[2] = { 0 }; + + struct s2n_blob value = { 0 }; + for (size_t i = 0; i < 2; i++) { + EXPECT_TRUE(s2n_map_iterator_has_next(&iter)); + + EXPECT_OK(s2n_map_iterator_next(&iter, &value)); + seen[*value.data] = true; + } + + /* assert that 0 and 1 were both seen */ + EXPECT_TRUE(seen[0] && seen[1]); + + EXPECT_OK(s2n_map_free(test_map)); + }; + + END_TEST(); +} diff --git a/tests/unit/s2n_map_test.c b/tests/unit/s2n_map_test.c index 8f1d8bb8437..83f0cf21912 100644 --- a/tests/unit/s2n_map_test.c +++ b/tests/unit/s2n_map_test.c @@ -20,19 +20,24 @@ #include "api/s2n.h" #include "s2n_test.h" +#define TEST_VALUE_COUNT 8192 + int main(int argc, char **argv) { char keystr[sizeof("ffff")]; char valstr[sizeof("16384")]; - struct s2n_map *empty, *map; + uint32_t size = 0; + struct s2n_map *empty = NULL, *map = NULL; struct s2n_blob key = { 0 }; struct s2n_blob val = { 0 }; - bool key_found; + bool key_found = false; BEGIN_TEST(); EXPECT_SUCCESS(s2n_disable_tls13_in_test()); EXPECT_NOT_NULL(empty = s2n_map_new()); + EXPECT_OK(s2n_map_size(empty, &size)); + EXPECT_EQUAL(size, 0); /* Try a lookup on an empty map. Expect an error because the map is still mutable. */ EXPECT_SUCCESS(snprintf(keystr, sizeof(keystr), "%04x", 1234)); @@ -67,7 +72,7 @@ int main(int argc, char **argv) EXPECT_NOT_NULL(map = s2n_map_new_with_initial_capacity(1)); /* Insert 8k key value pairs of the form hex(i) -> dec(i) */ - for (int i = 0; i < 8192; i++) { + for (int i = 0; i < TEST_VALUE_COUNT; i++) { EXPECT_SUCCESS(snprintf(keystr, sizeof(keystr), "%04x", i)); EXPECT_SUCCESS(snprintf(valstr, sizeof(valstr), "%05d", i)); @@ -78,6 +83,8 @@ int main(int argc, char **argv) EXPECT_OK(s2n_map_add(map, &key, &val)); } + EXPECT_OK(s2n_map_size(map, &size)); + EXPECT_EQUAL(size, TEST_VALUE_COUNT); /* Try adding some duplicates */ for (int i = 0; i < 10; i++) { @@ -91,6 +98,8 @@ int main(int argc, char **argv) EXPECT_ERROR(s2n_map_add(map, &key, &val)); } + EXPECT_OK(s2n_map_size(map, &size)); + EXPECT_EQUAL(size, TEST_VALUE_COUNT); /* Try replacing some entries */ for (int i = 0; i < 10; i++) { @@ -113,8 +122,8 @@ int main(int argc, char **argv) EXPECT_OK(s2n_map_complete(map)); /* Make sure that add-after-complete fails */ - EXPECT_SUCCESS(snprintf(keystr, sizeof(keystr), "%04x", 8193)); - EXPECT_SUCCESS(snprintf(valstr, sizeof(valstr), "%05d", 8193)); + EXPECT_SUCCESS(snprintf(keystr, sizeof(keystr), "%04x", TEST_VALUE_COUNT + 1)); + EXPECT_SUCCESS(snprintf(valstr, sizeof(valstr), "%05d", TEST_VALUE_COUNT + 1)); key.data = (void *) keystr; key.size = strlen(keystr) + 1; @@ -124,7 +133,7 @@ int main(int argc, char **argv) EXPECT_ERROR(s2n_map_add(map, &key, &val)); /* Check for equivalence */ - for (int i = 0; i < 8192; i++) { + for (int i = 0; i < TEST_VALUE_COUNT; i++) { if (i >= 10) { EXPECT_SUCCESS(snprintf(keystr, sizeof(keystr), "%04x", i)); EXPECT_SUCCESS(snprintf(valstr, sizeof(valstr), "%05d", i)); @@ -144,7 +153,7 @@ int main(int argc, char **argv) } /* Check for a key that shouldn't be there */ - EXPECT_SUCCESS(snprintf(keystr, sizeof(keystr), "%04x", 8193)); + EXPECT_SUCCESS(snprintf(keystr, sizeof(keystr), "%04x", TEST_VALUE_COUNT + 1)); key.data = (void *) keystr; key.size = strlen(keystr) + 1; EXPECT_OK(s2n_map_lookup(map, &key, &val, &key_found)); @@ -153,8 +162,8 @@ int main(int argc, char **argv) /* Make the map mutable */ EXPECT_OK(s2n_map_unlock(map)); /* Make sure that add-after-unlock succeeds */ - EXPECT_SUCCESS(snprintf(keystr, sizeof(keystr), "%04x", 8193)); - EXPECT_SUCCESS(snprintf(valstr, sizeof(valstr), "%05d", 8193)); + EXPECT_SUCCESS(snprintf(keystr, sizeof(keystr), "%04x", TEST_VALUE_COUNT + 1)); + EXPECT_SUCCESS(snprintf(valstr, sizeof(valstr), "%05d", TEST_VALUE_COUNT + 1)); key.data = (void *) keystr; key.size = strlen(keystr) + 1; diff --git a/tests/unit/s2n_mem_allocator_test.c b/tests/unit/s2n_mem_allocator_test.c index 423fddcb2ca..9b13e7614c4 100644 --- a/tests/unit/s2n_mem_allocator_test.c +++ b/tests/unit/s2n_mem_allocator_test.c @@ -45,7 +45,7 @@ static int custom_mem_cleanup(void) static int custom_mem_malloc(void **ptr, uint32_t requested, uint32_t *allocated) { - int i; + int i = 0; for (i = 0; i < HISTOGRAM_SIZE; i++) { if (histogram_values[i] == 0) { histogram_values[i] = requested; @@ -78,8 +78,8 @@ static int custom_mem_free(void *ptr, uint32_t size) void mock_client(struct s2n_test_io_pair *io_pair) { char buffer[0xffff]; - struct s2n_connection *conn; - struct s2n_config *config; + struct s2n_connection *conn = NULL; + struct s2n_config *config = NULL; s2n_blocked_status blocked; /* Give the server a chance to listen */ @@ -101,7 +101,7 @@ void mock_client(struct s2n_test_io_pair *io_pair) uint16_t timeout = 1; s2n_connection_set_dynamic_record_threshold(conn, 0x7fff, timeout); - int i; + int i = 0; for (i = 1; i < 0xffff - 100; i += 100) { for (int j = 0; j < i; j++) { buffer[j] = 33; @@ -118,7 +118,7 @@ void mock_client(struct s2n_test_io_pair *io_pair) /* Simulate timeout second conneciton inactivity and tolerate 50 ms error */ struct timespec sleep_time = { .tv_sec = timeout, .tv_nsec = 50000000 }; - int r; + int r = 0; do { r = nanosleep(&sleep_time, &sleep_time); } while (r != 0); @@ -148,11 +148,10 @@ void mock_client(struct s2n_test_io_pair *io_pair) int main(int argc, char **argv) { s2n_blocked_status blocked; - int status; - pid_t pid; - char *cert_chain_pem; - char *private_key_pem; - char *dhparams_pem; + int status = 0; + char *cert_chain_pem = NULL; + char *private_key_pem = NULL; + char *dhparams_pem = NULL; /* We have to set the callback before BEGIN_TEST, because s2n_init() is called * there. @@ -175,7 +174,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_io_pair_init(&io_pair)); /* Create a child process */ - pid = fork(); + pid_t pid = fork(); if (pid == 0) { /* This is the client process, close the server end of the pipe */ EXPECT_SUCCESS(s2n_io_pair_close_one_end(&io_pair, S2N_SERVER)); diff --git a/tests/unit/s2n_mem_usage_test.c b/tests/unit/s2n_mem_usage_test.c index 765c7e634cd..062bf3de73c 100644 --- a/tests/unit/s2n_mem_usage_test.c +++ b/tests/unit/s2n_mem_usage_test.c @@ -76,8 +76,8 @@ ssize_t get_vm_data_size() { #ifdef __linux__ - long page_size; - ssize_t size, resident, share, text, lib, data, dt; + long page_size = 0; + ssize_t size = 0, resident = 0, share = 0, text = 0, lib = 0, data = 0, dt = 0; page_size = sysconf(_SC_PAGESIZE); if (page_size < 0) { @@ -149,8 +149,8 @@ int main(int argc, char **argv) { size_t connectionsToUse = MAX_CONNECTIONS; - char *cert_chain; - char *private_key; + char *cert_chain = NULL; + char *private_key = NULL; BEGIN_TEST(); EXPECT_SUCCESS(s2n_disable_tls13_in_test()); @@ -181,13 +181,13 @@ int main(int argc, char **argv) EXPECT_NOT_NULL(cert_chain = malloc(S2N_MAX_TEST_PEM_SIZE)); EXPECT_NOT_NULL(private_key = malloc(S2N_MAX_TEST_PEM_SIZE)); - struct s2n_config *client_config; + struct s2n_config *client_config = NULL; EXPECT_NOT_NULL(client_config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_set_check_stapled_ocsp_response(client_config, 0)); EXPECT_SUCCESS(s2n_config_disable_x509_verification(client_config)); - struct s2n_cert_chain_and_key *chain_and_key; - struct s2n_config *server_config; + struct s2n_cert_chain_and_key *chain_and_key = NULL; + struct s2n_config *server_config = NULL; EXPECT_NOT_NULL(server_config = s2n_config_new()); EXPECT_SUCCESS(s2n_read_test_pem(S2N_DEFAULT_TEST_CERT_CHAIN, cert_chain, S2N_MAX_TEST_PEM_SIZE)); EXPECT_SUCCESS(s2n_read_test_pem(S2N_DEFAULT_TEST_PRIVATE_KEY, private_key, S2N_MAX_TEST_PEM_SIZE)); @@ -200,13 +200,13 @@ int main(int argc, char **argv) /* Allocate all connections */ for (size_t i = 0; i < connectionsToUse; i++) { - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(client_conn, client_config)); EXPECT_SUCCESS(s2n_connection_set_blinding(client_conn, S2N_SELF_SERVICE_BLINDING)); clients[i] = client_conn; - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_config(server_conn, server_config)); EXPECT_SUCCESS(s2n_connection_set_blinding(server_conn, S2N_SELF_SERVICE_BLINDING)); diff --git a/tests/unit/s2n_mutual_auth_test.c b/tests/unit/s2n_mutual_auth_test.c index 46f6b487fc3..03b6881304d 100644 --- a/tests/unit/s2n_mutual_auth_test.c +++ b/tests/unit/s2n_mutual_auth_test.c @@ -39,13 +39,13 @@ static uint8_t verify_host_fn(const char *host_name, size_t host_name_len, void int main(int argc, char **argv) { - struct s2n_config *config; - const struct s2n_security_policy *default_security_policy; - const struct s2n_cipher_preferences *default_cipher_preferences; - char *cert_chain_pem; - char *private_key_pem; - char *dhparams_pem; - struct s2n_cert_chain_and_key *chain_and_key; + struct s2n_config *config = NULL; + const struct s2n_security_policy *default_security_policy = NULL; + const struct s2n_cipher_preferences *default_cipher_preferences = NULL; + char *cert_chain_pem = NULL; + char *private_key_pem = NULL; + char *dhparams_pem = NULL; + struct s2n_cert_chain_and_key *chain_and_key = NULL; BEGIN_TEST(); EXPECT_SUCCESS(s2n_disable_tls13_in_test()); @@ -84,8 +84,8 @@ int main(int argc, char **argv) verify_data.callback_invoked = 0; struct s2n_cipher_preferences server_cipher_preferences; struct s2n_security_policy server_security_policy; - struct s2n_connection *client_conn; - struct s2n_connection *server_conn; + struct s2n_connection *client_conn = NULL; + struct s2n_connection *server_conn = NULL; struct s2n_stuffer client_to_server = { 0 }; struct s2n_stuffer server_to_client = { 0 }; @@ -143,8 +143,8 @@ int main(int argc, char **argv) for (size_t cipher_idx = 0; cipher_idx < default_cipher_preferences->count; cipher_idx++) { struct s2n_cipher_preferences server_cipher_preferences; struct s2n_security_policy server_security_policy; - struct s2n_connection *client_conn; - struct s2n_connection *server_conn; + struct s2n_connection *client_conn = NULL; + struct s2n_connection *server_conn = NULL; struct s2n_stuffer client_to_server = { 0 }; struct s2n_stuffer server_to_client = { 0 }; @@ -197,8 +197,8 @@ int main(int argc, char **argv) for (size_t cipher_idx = 0; cipher_idx < default_cipher_preferences->count; cipher_idx++) { struct s2n_cipher_preferences server_cipher_preferences; struct s2n_security_policy server_security_policy; - struct s2n_connection *client_conn; - struct s2n_connection *server_conn; + struct s2n_connection *client_conn = NULL; + struct s2n_connection *server_conn = NULL; struct s2n_stuffer client_to_server = { 0 }; struct s2n_stuffer server_to_client = { 0 }; @@ -257,8 +257,8 @@ int main(int argc, char **argv) for (size_t cipher_idx = 0; cipher_idx < default_cipher_preferences->count; cipher_idx++) { struct s2n_cipher_preferences server_cipher_preferences; struct s2n_security_policy server_security_policy; - struct s2n_connection *client_conn; - struct s2n_connection *server_conn; + struct s2n_connection *client_conn = NULL; + struct s2n_connection *server_conn = NULL; struct s2n_stuffer client_to_server = { 0 }; struct s2n_stuffer server_to_client = { 0 }; diff --git a/tests/unit/s2n_openssl_x509_test.c b/tests/unit/s2n_openssl_x509_test.c index 4c6354a460a..85fa4500fd8 100644 --- a/tests/unit/s2n_openssl_x509_test.c +++ b/tests/unit/s2n_openssl_x509_test.c @@ -14,13 +14,28 @@ */ #include "crypto/s2n_openssl_x509.h" +#include +#include + +#include "crypto/s2n_rsa_pss.h" #include "s2n_test.h" #include "testlib/s2n_testlib.h" -S2N_RESULT s2n_x509_validator_read_asn1_cert(struct s2n_stuffer* cert_chain_in_stuffer, - struct s2n_blob* asn1_cert); +S2N_RESULT s2n_x509_validator_read_asn1_cert(struct s2n_stuffer *cert_chain_in_stuffer, + struct s2n_blob *asn1_cert); + +static S2N_RESULT s2n_test_assert_s2n_cert_info_equality(const struct s2n_cert_info *info_a, + const struct s2n_cert_info *info_b) +{ + RESULT_ENSURE_EQ(info_a->public_key_bits, info_b->public_key_bits); + RESULT_ENSURE_EQ(info_a->public_key_nid, info_b->public_key_nid); + RESULT_ENSURE_EQ(info_a->signature_nid, info_b->signature_nid); + RESULT_ENSURE_EQ(info_a->signature_digest_nid, info_b->signature_digest_nid); + RESULT_ENSURE_EQ(info_a->self_signed, info_b->self_signed); + return S2N_RESULT_OK; +} -int main(int argc, char** argv) +int main(int argc, char **argv) { BEGIN_TEST(); @@ -41,11 +56,11 @@ int main(int argc, char** argv) EXPECT_OK(s2n_x509_validator_read_asn1_cert(&cert_chain_stuffer, &cert_asn1_der)); { - DEFER_CLEANUP(X509* cert = NULL, X509_free_pointer); + DEFER_CLEANUP(X509 *cert = NULL, X509_free_pointer); EXPECT_OK(s2n_openssl_x509_parse(&cert_asn1_der, &cert)); } { - DEFER_CLEANUP(X509* cert = NULL, X509_free_pointer); + DEFER_CLEANUP(X509 *cert = NULL, X509_free_pointer); EXPECT_OK(s2n_openssl_x509_parse_without_length_validation(&cert_asn1_der, &cert)); } } @@ -67,14 +82,157 @@ int main(int argc, char** argv) EXPECT_OK(s2n_x509_validator_read_asn1_cert(&cert_chain_stuffer, &cert_asn1_der)); { - DEFER_CLEANUP(X509* cert = NULL, X509_free_pointer); + DEFER_CLEANUP(X509 *cert = NULL, X509_free_pointer); EXPECT_ERROR(s2n_openssl_x509_parse(&cert_asn1_der, &cert)); } { - DEFER_CLEANUP(X509* cert = NULL, X509_free_pointer); + DEFER_CLEANUP(X509 *cert = NULL, X509_free_pointer); EXPECT_OK(s2n_openssl_x509_parse_without_length_validation(&cert_asn1_der, &cert)); } } + /* s2n_openssl_x509_get_cert_info */ + struct { + const char *key_type; + const char *signature; + const char *key_size; + const char *digest; + int expected_signature_nid; + int expected_digest_nid; + int expected_public_key_nid; + int expected_public_key_bits; + } test_cases[] = { + { + .key_type = "ec", + .signature = "ecdsa", + .key_size = "p384", + .digest = "sha256", + .expected_signature_nid = NID_ecdsa_with_SHA256, + .expected_digest_nid = NID_sha256, + .expected_public_key_nid = NID_secp384r1, + .expected_public_key_bits = 384, + }, + { + .key_type = "ec", + .signature = "ecdsa", + .key_size = "p256", + .digest = "sha384", + .expected_signature_nid = NID_ecdsa_with_SHA384, + .expected_digest_nid = NID_sha384, + .expected_public_key_nid = NID_X9_62_prime256v1, + .expected_public_key_bits = 256, + }, + { + .key_type = "ec", + .signature = "ecdsa", + .key_size = "p521", + .digest = "sha512", + .expected_signature_nid = NID_ecdsa_with_SHA512, + .expected_digest_nid = NID_sha512, + .expected_public_key_nid = NID_secp521r1, + .expected_public_key_bits = 521, + }, + { + .key_type = "rsae", + .signature = "pkcs", + .key_size = "2048", + .digest = "sha1", + .expected_signature_nid = NID_sha1WithRSAEncryption, + .expected_digest_nid = NID_sha1, + .expected_public_key_nid = NID_rsaEncryption, + .expected_public_key_bits = 2048, + }, + { + .key_type = "rsae", + .signature = "pkcs", + .key_size = "2048", + .digest = "sha224", + .expected_signature_nid = NID_sha224WithRSAEncryption, + .expected_digest_nid = NID_sha224, + .expected_public_key_nid = NID_rsaEncryption, + .expected_public_key_bits = 2048, + }, + { + .key_type = "rsae", + .signature = "pkcs", + .key_size = "3072", + .digest = "sha384", + .expected_signature_nid = NID_sha384WithRSAEncryption, + .expected_digest_nid = NID_sha384, + .expected_public_key_nid = NID_rsaEncryption, + .expected_public_key_bits = 3072, + }, +#if RSA_PSS_CERTS_SUPPORTED + { + .key_type = "rsae", + .signature = "pss", + .key_size = "4096", + .digest = "sha384", + .expected_signature_nid = NID_rsassaPss, + .expected_digest_nid = NID_undef, + .expected_public_key_nid = NID_rsaEncryption, + .expected_public_key_bits = 4096, + }, + { + .key_type = "rsapss", + .signature = "pss", + .key_size = "2048", + .digest = "sha256", + .expected_signature_nid = NID_rsassaPss, + .expected_digest_nid = NID_undef, + .expected_public_key_nid = NID_rsassaPss, + .expected_public_key_bits = 2048, + }, +#endif + }; + + for (size_t i = 0; i < s2n_array_len(test_cases); i++) { + /* initialize variables and read in certificates */ + char pathbuffer[S2N_MAX_TEST_PEM_PATH_LENGTH] = { 0 }; + uint8_t cert_file[S2N_MAX_TEST_PEM_SIZE] = { 0 }; + EXPECT_OK(s2n_test_cert_permutation_get_server_chain_path(&pathbuffer[0], + test_cases[i].key_type, test_cases[i].signature, test_cases[i].key_size, + test_cases[i].digest)); + EXPECT_SUCCESS(s2n_read_test_pem(pathbuffer, (char *) cert_file, S2N_MAX_TEST_PEM_SIZE)); + + DEFER_CLEANUP(X509 *leaf = NULL, X509_free_pointer); + DEFER_CLEANUP(X509 *intermediate = NULL, X509_free_pointer); + DEFER_CLEANUP(X509 *root = NULL, X509_free_pointer); + + /* read in cert chain */ + size_t chain_len = strlen((const char *) cert_file); + BIO *cert_bio = NULL; + EXPECT_NOT_NULL(cert_bio = BIO_new(BIO_s_mem())); + EXPECT_TRUE(BIO_write(cert_bio, cert_file, chain_len) > 0); + EXPECT_NOT_NULL(leaf = PEM_read_bio_X509(cert_bio, NULL, NULL, NULL)); + EXPECT_NOT_NULL(intermediate = PEM_read_bio_X509(cert_bio, NULL, NULL, NULL)); + EXPECT_NOT_NULL(root = PEM_read_bio_X509(cert_bio, NULL, NULL, NULL)); + EXPECT_SUCCESS(BIO_free(cert_bio)); + + /* retrieve cert info from test case certificates */ + struct s2n_cert_info leaf_info = { 0 }; + struct s2n_cert_info intermediate_info = { 0 }; + struct s2n_cert_info root_info = { 0 }; + + EXPECT_OK(s2n_openssl_x509_get_cert_info(leaf, &leaf_info)); + EXPECT_OK(s2n_openssl_x509_get_cert_info(intermediate, &intermediate_info)); + EXPECT_OK(s2n_openssl_x509_get_cert_info(root, &root_info)); + + struct s2n_cert_info expected_info = { + .signature_nid = test_cases[i].expected_signature_nid, + .signature_digest_nid = test_cases[i].expected_digest_nid, + .public_key_nid = test_cases[i].expected_public_key_nid, + .public_key_bits = test_cases[i].expected_public_key_bits, + .self_signed = false, + }; + + /* assert that cert info matches expected values */ + EXPECT_OK(s2n_test_assert_s2n_cert_info_equality(&leaf_info, &expected_info)); + EXPECT_OK(s2n_test_assert_s2n_cert_info_equality(&intermediate_info, &expected_info)); + /* root should be self-signed, but otherwise equal */ + expected_info.self_signed = true; + EXPECT_OK(s2n_test_assert_s2n_cert_info_equality(&root_info, &expected_info)); + } + END_TEST(); } diff --git a/tests/unit/s2n_optional_client_auth_test.c b/tests/unit/s2n_optional_client_auth_test.c index 498b659efb1..9a0f664c8a3 100644 --- a/tests/unit/s2n_optional_client_auth_test.c +++ b/tests/unit/s2n_optional_client_auth_test.c @@ -25,14 +25,14 @@ int main(int argc, char **argv) { - struct s2n_config *client_config; - struct s2n_config *server_config; - const struct s2n_security_policy *default_security_policy; - const struct s2n_cipher_preferences *default_cipher_preferences; - char *cert_chain_pem; - char *private_key_pem; - char *dhparams_pem; - struct s2n_cert_chain_and_key *chain_and_key; + struct s2n_config *client_config = NULL; + struct s2n_config *server_config = NULL; + const struct s2n_security_policy *default_security_policy = NULL; + const struct s2n_cipher_preferences *default_cipher_preferences = NULL; + char *cert_chain_pem = NULL; + char *private_key_pem = NULL; + char *dhparams_pem = NULL; + struct s2n_cert_chain_and_key *chain_and_key = NULL; BEGIN_TEST(); EXPECT_SUCCESS(s2n_disable_tls13_in_test()); @@ -77,8 +77,8 @@ int main(int argc, char **argv) for (int cipher_idx = 0; cipher_idx < default_security_policy->cipher_preferences->count; cipher_idx++) { struct s2n_cipher_preferences server_cipher_preferences; struct s2n_security_policy security_policy; - struct s2n_connection *client_conn; - struct s2n_connection *server_conn; + struct s2n_connection *client_conn = NULL; + struct s2n_connection *server_conn = NULL; /* Craft a cipher preference with a cipher_idx cipher. */ EXPECT_MEMCPY_SUCCESS(&server_cipher_preferences, default_cipher_preferences, sizeof(server_cipher_preferences)); @@ -141,8 +141,8 @@ int main(int argc, char **argv) for (int cipher_idx = 0; cipher_idx < default_cipher_preferences->count; cipher_idx++) { struct s2n_cipher_preferences server_cipher_preferences; struct s2n_security_policy security_policy; - struct s2n_connection *client_conn; - struct s2n_connection *server_conn; + struct s2n_connection *client_conn = NULL; + struct s2n_connection *server_conn = NULL; /* Craft a cipher preference with a cipher_idx cipher. */ EXPECT_MEMCPY_SUCCESS(&server_cipher_preferences, default_cipher_preferences, sizeof(server_cipher_preferences)); @@ -204,8 +204,8 @@ int main(int argc, char **argv) for (int cipher_idx = 0; cipher_idx < default_cipher_preferences->count; cipher_idx++) { struct s2n_cipher_preferences server_cipher_preferences; struct s2n_security_policy security_policy; - struct s2n_connection *client_conn; - struct s2n_connection *server_conn; + struct s2n_connection *client_conn = NULL; + struct s2n_connection *server_conn = NULL; /* Craft a cipher preference with a cipher_idx cipher. */ EXPECT_MEMCPY_SUCCESS(&server_cipher_preferences, default_cipher_preferences, sizeof(server_cipher_preferences)); @@ -268,8 +268,8 @@ int main(int argc, char **argv) for (int cipher_idx = 0; cipher_idx < default_cipher_preferences->count; cipher_idx++) { struct s2n_cipher_preferences server_cipher_preferences; struct s2n_security_policy security_policy; - struct s2n_connection *client_conn; - struct s2n_connection *server_conn; + struct s2n_connection *client_conn = NULL; + struct s2n_connection *server_conn = NULL; /* Craft a cipher preference with a cipher_idx cipher. */ EXPECT_MEMCPY_SUCCESS(&server_cipher_preferences, default_cipher_preferences, sizeof(server_cipher_preferences)); @@ -337,8 +337,8 @@ int main(int argc, char **argv) for (int cipher_idx = 0; cipher_idx < default_cipher_preferences->count; cipher_idx++) { struct s2n_cipher_preferences server_cipher_preferences; struct s2n_security_policy security_policy; - struct s2n_connection *client_conn; - struct s2n_connection *server_conn; + struct s2n_connection *client_conn = NULL; + struct s2n_connection *server_conn = NULL; /* Craft a cipher preference with a cipher_idx cipher. */ EXPECT_MEMCPY_SUCCESS(&server_cipher_preferences, default_cipher_preferences, sizeof(server_cipher_preferences)); @@ -414,8 +414,8 @@ int main(int argc, char **argv) for (int cipher_idx = 0; cipher_idx < default_cipher_preferences->count; cipher_idx++) { struct s2n_cipher_preferences server_cipher_preferences; struct s2n_security_policy security_policy; - struct s2n_connection *client_conn; - struct s2n_connection *server_conn; + struct s2n_connection *client_conn = NULL; + struct s2n_connection *server_conn = NULL; /* Craft a cipher preference with a cipher_idx cipher. */ EXPECT_MEMCPY_SUCCESS(&server_cipher_preferences, default_cipher_preferences, sizeof(server_cipher_preferences)); diff --git a/tests/unit/s2n_pem_test.c b/tests/unit/s2n_pem_test.c index 7035a4445bb..0b734ab035b 100644 --- a/tests/unit/s2n_pem_test.c +++ b/tests/unit/s2n_pem_test.c @@ -61,10 +61,10 @@ static const char *invalid_pem_pairs[][2] = { int main(int argc, char **argv) { - struct s2n_config *config; - char *cert_chain_pem; - char *private_key_pem; - struct s2n_cert_chain_and_key *chain_and_key; + struct s2n_config *config = NULL; + char *cert_chain_pem = NULL; + char *private_key_pem = NULL; + struct s2n_cert_chain_and_key *chain_and_key = NULL; BEGIN_TEST(); EXPECT_SUCCESS(s2n_disable_tls13_in_test()); diff --git a/tests/unit/s2n_pkey_test.c b/tests/unit/s2n_pkey_test.c index 015c1a3ddc2..271cdc0e085 100644 --- a/tests/unit/s2n_pkey_test.c +++ b/tests/unit/s2n_pkey_test.c @@ -25,7 +25,7 @@ int main(int argc, char **argv) /* Test each combination of s2n_pkey_types to validate that only keys of * the same type can be compared */ { - struct s2n_cert_chain_and_key *chain_and_key; + struct s2n_cert_chain_and_key *chain_and_key = NULL; char rsa_cert_chain_pem[S2N_MAX_TEST_PEM_SIZE] = { 0 }; char rsa_pss_cert_chain_pem[S2N_MAX_TEST_PEM_SIZE] = { 0 }; char ecdsa_cert_chain_pem[S2N_MAX_TEST_PEM_SIZE] = { 0 }; @@ -94,7 +94,7 @@ int main(int argc, char **argv) /* Test the same as above but with non null terminated chain and key and * api that accepts length */ { - struct s2n_cert_chain_and_key *chain_and_key; + struct s2n_cert_chain_and_key *chain_and_key = NULL; uint8_t rsa_cert_chain_pem[S2N_MAX_TEST_PEM_SIZE] = { 0 }; uint8_t rsa_pss_cert_chain_pem[S2N_MAX_TEST_PEM_SIZE] = { 0 }; uint8_t ecdsa_cert_chain_pem[S2N_MAX_TEST_PEM_SIZE] = { 0 }; diff --git a/tests/unit/s2n_post_handshake_test.c b/tests/unit/s2n_post_handshake_test.c index b8098050c42..eb696c8d69d 100644 --- a/tests/unit/s2n_post_handshake_test.c +++ b/tests/unit/s2n_post_handshake_test.c @@ -41,7 +41,7 @@ int main(int argc, char **argv) { /* post_handshake_recv processes a key update requested message */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); conn->actual_protocol_version = S2N_TLS13; conn->secure->cipher_suite = &s2n_tls13_aes_256_gcm_sha384; @@ -60,7 +60,7 @@ int main(int argc, char **argv) /* post_handshake_recv rejects an unknown post handshake message */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); conn->actual_protocol_version = S2N_TLS13; conn->secure->cipher_suite = &s2n_tls13_aes_256_gcm_sha384; @@ -79,7 +79,7 @@ int main(int argc, char **argv) /* post_handshake_recv processes a malformed post handshake message */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); conn->actual_protocol_version = S2N_TLS13; conn->secure->cipher_suite = &s2n_tls13_aes_256_gcm_sha384; @@ -145,7 +145,7 @@ int main(int argc, char **argv) break; } - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); conn->actual_protocol_version = S2N_TLS13; @@ -162,7 +162,7 @@ int main(int argc, char **argv) break; } - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); conn->actual_protocol_version = S2N_TLS13; diff --git a/tests/unit/s2n_protocol_preferences_test.c b/tests/unit/s2n_protocol_preferences_test.c index 3edf757e302..b06345c69b2 100644 --- a/tests/unit/s2n_protocol_preferences_test.c +++ b/tests/unit/s2n_protocol_preferences_test.c @@ -36,7 +36,7 @@ int main(int argc, char **argv) /* Test config append */ { - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); EXPECT_EQUAL(config->application_protocols.size, 0); size_t prev_size = 0; @@ -65,7 +65,7 @@ int main(int argc, char **argv) /* Test connection append */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_EQUAL(conn->application_protocols_overridden.size, 0); size_t prev_size = 0; @@ -103,7 +103,7 @@ int main(int argc, char **argv) /* Test config set */ { - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); EXPECT_EQUAL(config->application_protocols.size, 0); @@ -133,7 +133,7 @@ int main(int argc, char **argv) /* Test connection set */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_EQUAL(conn->application_protocols_overridden.size, 0); diff --git a/tests/unit/s2n_psk_key_exchange_modes_extension_test.c b/tests/unit/s2n_psk_key_exchange_modes_extension_test.c index e3e25cff37b..0b421cc0f5c 100644 --- a/tests/unit/s2n_psk_key_exchange_modes_extension_test.c +++ b/tests/unit/s2n_psk_key_exchange_modes_extension_test.c @@ -26,7 +26,7 @@ int main(int argc, char **argv) struct s2n_stuffer out = { 0 }; EXPECT_SUCCESS(s2n_stuffer_growable_alloc(&out, 0)); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_psk_key_exchange_modes_extension.send(conn, &out)); @@ -50,7 +50,7 @@ int main(int argc, char **argv) struct s2n_stuffer out = { 0 }; EXPECT_SUCCESS(s2n_stuffer_growable_alloc(&out, 0)); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_EQUAL(conn->psk_params.psk_ke_mode, S2N_PSK_KE_UNKNOWN); @@ -71,7 +71,7 @@ int main(int argc, char **argv) struct s2n_stuffer out = { 0 }; EXPECT_SUCCESS(s2n_stuffer_growable_alloc(&out, 0)); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_EQUAL(conn->psk_params.psk_ke_mode, S2N_PSK_KE_UNKNOWN); @@ -93,7 +93,7 @@ int main(int argc, char **argv) struct s2n_stuffer out = { 0 }; EXPECT_SUCCESS(s2n_stuffer_growable_alloc(&out, 0)); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_EQUAL(conn->psk_params.psk_ke_mode, S2N_PSK_KE_UNKNOWN); @@ -115,7 +115,7 @@ int main(int argc, char **argv) struct s2n_stuffer out = { 0 }; EXPECT_SUCCESS(s2n_stuffer_growable_alloc(&out, 0)); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_EQUAL(conn->psk_params.psk_ke_mode, S2N_PSK_KE_UNKNOWN); @@ -268,8 +268,8 @@ int main(int argc, char **argv) struct s2n_stuffer out = { 0 }; EXPECT_SUCCESS(s2n_stuffer_growable_alloc(&out, 0)); - struct s2n_connection *server_conn; - struct s2n_connection *client_conn; + struct s2n_connection *server_conn = NULL; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); EXPECT_EQUAL(server_conn->psk_params.psk_ke_mode, S2N_PSK_KE_UNKNOWN); diff --git a/tests/unit/s2n_psk_test.c b/tests/unit/s2n_psk_test.c index e9718c94602..3dfea4caf0a 100644 --- a/tests/unit/s2n_psk_test.c +++ b/tests/unit/s2n_psk_test.c @@ -338,7 +338,7 @@ int main(int argc, char **argv) * There are no available test vectors for multiple PSKs, but we should at least * verify that we write something relatively sane for this use case. */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); struct s2n_stuffer out = { 0 }; @@ -385,7 +385,7 @@ int main(int argc, char **argv) *# ClientHello. */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); conn->handshake.handshake_type = HELLO_RETRY_REQUEST; conn->secure->cipher_suite = &s2n_tls13_aes_128_gcm_sha256; @@ -479,7 +479,7 @@ int main(int argc, char **argv) /* Test s2n_psk_calculate_binder_hash with known values */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); struct s2n_blob hash_value = { 0 }; @@ -509,7 +509,7 @@ int main(int argc, char **argv) /* Test s2n_psk_verify_binder with known values */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); DEFER_CLEANUP(struct s2n_psk test_psk, s2n_psk_wipe); @@ -528,7 +528,7 @@ int main(int argc, char **argv) /* Test s2n_psk_verify_binder with incorrect binder */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); DEFER_CLEANUP(struct s2n_psk test_psk, s2n_psk_wipe); @@ -549,7 +549,7 @@ int main(int argc, char **argv) /* Test s2n_psk_write_binder with known values */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); DEFER_CLEANUP(struct s2n_psk psk = { 0 }, s2n_psk_wipe); @@ -566,7 +566,7 @@ int main(int argc, char **argv) EXPECT_EQUAL(binder_size, s2n_stuffer_data_available(&out)); EXPECT_EQUAL(binder_size, finished_binder.size); - uint8_t *binder_data; + uint8_t *binder_data = NULL; EXPECT_NOT_NULL(binder_data = s2n_stuffer_raw_read(&out, binder_size)); EXPECT_BYTEARRAY_EQUAL(binder_data, finished_binder.data, binder_size); @@ -576,7 +576,7 @@ int main(int argc, char **argv) /* Test s2n_psk_write_binder_list with known values */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); struct s2n_psk *psk = NULL; @@ -599,7 +599,7 @@ int main(int argc, char **argv) EXPECT_EQUAL(binder_size, s2n_stuffer_data_available(&out)); EXPECT_EQUAL(binder_size, finished_binder.size); - uint8_t *binder_data; + uint8_t *binder_data = NULL; EXPECT_NOT_NULL(binder_data = s2n_stuffer_raw_read(&out, binder_size)); EXPECT_BYTEARRAY_EQUAL(binder_data, finished_binder.data, binder_size); @@ -611,7 +611,7 @@ int main(int argc, char **argv) { const uint8_t psk_count = 5; - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); for (uint8_t i = 0; i < psk_count; i++) { @@ -636,7 +636,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_stuffer_read_uint8(&out, &binder_size)); EXPECT_EQUAL(binder_size, finished_binder.size); - uint8_t *binder_data; + uint8_t *binder_data = NULL; EXPECT_NOT_NULL(binder_data = s2n_stuffer_raw_read(&out, binder_size)); EXPECT_BYTEARRAY_EQUAL(binder_data, finished_binder.data, binder_size); } @@ -649,7 +649,7 @@ int main(int argc, char **argv) /* Test s2n_psk_write_binder_list with multiple hash algs */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); for (s2n_hmac_algorithm hmac_alg = S2N_HMAC_SHA256; hmac_alg <= S2N_HMAC_SHA384; hmac_alg++) { @@ -678,7 +678,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_stuffer_read_uint8(&out, &binder_size)); EXPECT_EQUAL(binder_size, hash_size); - uint8_t *binder_data; + uint8_t *binder_data = NULL; EXPECT_NOT_NULL(binder_data = s2n_stuffer_raw_read(&out, binder_size)); /* We can only actually verify the result for SHA256; we don't have known * values for any other hash. */ @@ -695,7 +695,7 @@ int main(int argc, char **argv) /* Test s2n_finish_psk_extension with known values */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_stuffer_write(&conn->handshake.io, &client_hello_prefix)); @@ -732,7 +732,7 @@ int main(int argc, char **argv) /* Safety checks */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_FAILURE_WITH_ERRNO(s2n_connection_append_psk(NULL, input_psk), S2N_ERR_NULL); @@ -743,7 +743,7 @@ int main(int argc, char **argv) /* Append valid PSK to empty list */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_append_psk(conn, input_psk)); @@ -766,7 +766,7 @@ int main(int argc, char **argv) /* Original PSK can be safely freed after being added to a connection */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); struct s2n_psk *original_psk = s2n_external_psk_new(); @@ -794,7 +794,7 @@ int main(int argc, char **argv) /* Invalid PSK not added to connection */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); /* PSK is invalid because it has no identity */ @@ -814,7 +814,7 @@ int main(int argc, char **argv) /* Huge PSK not added to client connection */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); DEFER_CLEANUP(struct s2n_psk *invalid_psk = s2n_external_psk_new(), s2n_psk_free); @@ -844,7 +844,7 @@ int main(int argc, char **argv) /* Huge PSK added to server connection */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); DEFER_CLEANUP(struct s2n_psk *invalid_psk = s2n_external_psk_new(), s2n_psk_free); @@ -861,7 +861,7 @@ int main(int argc, char **argv) /* New PSK would make existing list too long for client */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); uint32_t offered_psks_size = 0; @@ -897,7 +897,7 @@ int main(int argc, char **argv) /* PSK matches existing external PSK */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_append_psk(conn, input_psk)); diff --git a/tests/unit/s2n_quic_support_io_test.c b/tests/unit/s2n_quic_support_io_test.c index f6aa0d0f970..5bb7b02d5f5 100644 --- a/tests/unit/s2n_quic_support_io_test.c +++ b/tests/unit/s2n_quic_support_io_test.c @@ -132,7 +132,7 @@ int main(int argc, char **argv) /* Writes handshake message */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); uint8_t message_data[] = "The client says hello"; @@ -160,7 +160,7 @@ int main(int argc, char **argv) /* Reads basic handshake message */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); struct s2n_stuffer stuffer = { 0 }; @@ -187,7 +187,7 @@ int main(int argc, char **argv) /* Blocks on insufficient data for handshake message header */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); struct s2n_stuffer stuffer = { 0 }; @@ -206,7 +206,7 @@ int main(int argc, char **argv) /* Blocks on insufficient data for handshake message data */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); struct s2n_stuffer stuffer = { 0 }; @@ -227,7 +227,7 @@ int main(int argc, char **argv) /* Fails for an impossibly large handshake message */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); struct s2n_stuffer stuffer = { 0 }; @@ -265,13 +265,13 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_stuffer_growable_alloc(&output_stuffer, 0)); /* Setup config */ - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_enable_quic(config)); /* Functional: successfully reads full handshake message */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_OK(s2n_setup_conn_for_server_hello(conn)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); @@ -287,7 +287,7 @@ int main(int argc, char **argv) /* Functional: successfully reads fragmented handshake message */ for (size_t i = 1; i < server_hello.size - 1; i++) { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_OK(s2n_setup_conn_for_server_hello(conn)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); @@ -312,7 +312,7 @@ int main(int argc, char **argv) /* Functional: successfully reads multiple handshake messages */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_OK(s2n_setup_conn_for_server_hello(conn)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); @@ -332,7 +332,7 @@ int main(int argc, char **argv) /* Function: fails to read record instead of handshake message */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_OK(s2n_setup_conn_for_server_hello(conn)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); @@ -352,7 +352,7 @@ int main(int argc, char **argv) /* Function: fails to read Change Cipher Spec record */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_OK(s2n_setup_conn_for_server_hello(conn)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); @@ -374,7 +374,7 @@ int main(int argc, char **argv) /* Functional: successfully writes full handshake message */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_OK(s2n_setup_conn_for_client_hello(conn)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); @@ -382,11 +382,11 @@ int main(int argc, char **argv) EXPECT_FAILURE_WITH_ERRNO(s2n_negotiate(conn, &blocked_status), S2N_ERR_IO_BLOCKED); client_hello_length = s2n_stuffer_data_available(&output_stuffer); - uint8_t actual_message_type; + uint8_t actual_message_type = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint8(&output_stuffer, &actual_message_type)); EXPECT_EQUAL(actual_message_type, TLS_CLIENT_HELLO); - uint32_t actual_message_size; + uint32_t actual_message_size = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint24(&output_stuffer, &actual_message_size)); EXPECT_EQUAL(actual_message_size, TEST_DATA_SIZE); @@ -401,7 +401,7 @@ int main(int argc, char **argv) /* Functional: successfully retries after blocked write */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_OK(s2n_setup_conn_for_client_hello(conn)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); diff --git a/tests/unit/s2n_quic_support_test.c b/tests/unit/s2n_quic_support_test.c index 976d929cd2b..a3f4a50cf9e 100644 --- a/tests/unit/s2n_quic_support_test.c +++ b/tests/unit/s2n_quic_support_test.c @@ -163,7 +163,7 @@ int main(int argc, char **argv) /* Set transport data */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); s2n_connection_set_quic_transport_parameters(conn, TEST_DATA, sizeof(TEST_DATA)); @@ -199,7 +199,7 @@ int main(int argc, char **argv) const uint8_t *data_buffer = TEST_DATA; uint16_t data_buffer_len = sizeof(TEST_DATA); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_get_quic_transport_parameters(conn, &data_buffer, &data_buffer_len)); @@ -214,7 +214,7 @@ int main(int argc, char **argv) const uint8_t *data_buffer = NULL; uint16_t data_buffer_len = 0; - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_alloc(&conn->peer_quic_transport_parameters, sizeof(TEST_DATA))); @@ -230,11 +230,11 @@ int main(int argc, char **argv) /* Test s2n_connection_set_secret_callback */ { - uint8_t test_context; + uint8_t test_context = 0; /* Safety checks */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_FAILURE_WITH_ERRNO(s2n_connection_set_secret_callback(NULL, s2n_test_noop_secret_handler, &test_context), S2N_ERR_NULL); @@ -248,7 +248,7 @@ int main(int argc, char **argv) /* Succeeds with NULL context */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_EQUAL(conn->secret_cb, NULL); EXPECT_EQUAL(conn->secret_cb_context, NULL); @@ -263,7 +263,7 @@ int main(int argc, char **argv) /* Succeeds with context */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_EQUAL(conn->secret_cb, NULL); EXPECT_EQUAL(conn->secret_cb_context, NULL); @@ -279,11 +279,11 @@ int main(int argc, char **argv) /* Test: no API that sends/receives application data is allowed when QUIC is enabled */ { - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_enable_quic(config)); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); diff --git a/tests/unit/s2n_quic_transport_params_extension_test.c b/tests/unit/s2n_quic_transport_params_extension_test.c index 60b4eb1d534..4d2a81cb8f0 100644 --- a/tests/unit/s2n_quic_transport_params_extension_test.c +++ b/tests/unit/s2n_quic_transport_params_extension_test.c @@ -32,10 +32,10 @@ int main(int argc, char **argv) /* Test should_send */ { - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); @@ -55,10 +55,10 @@ int main(int argc, char **argv) /* Test if_missing */ { - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); @@ -91,7 +91,7 @@ int main(int argc, char **argv) { struct s2n_stuffer out = { 0 }; - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_FAILURE_WITH_ERRNO(s2n_quic_transport_parameters_extension.send(NULL, &out), S2N_ERR_NULL); @@ -105,11 +105,11 @@ int main(int argc, char **argv) struct s2n_stuffer out = { 0 }; EXPECT_SUCCESS(s2n_stuffer_growable_alloc(&out, 0)); - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_enable_quic(config)); - struct s2n_connection *conn; + 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_quic_transport_parameters(conn, TEST_DATA, sizeof(TEST_DATA))); @@ -127,11 +127,11 @@ int main(int argc, char **argv) struct s2n_stuffer out = { 0 }; EXPECT_SUCCESS(s2n_stuffer_growable_alloc(&out, 0)); - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_enable_quic(config)); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); @@ -150,7 +150,7 @@ int main(int argc, char **argv) { struct s2n_stuffer extension = { 0 }; - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_FAILURE_WITH_ERRNO(s2n_quic_transport_parameters_extension.recv(NULL, &extension), S2N_ERR_NULL); @@ -163,11 +163,11 @@ int main(int argc, char **argv) /* Save transport parameters */ { - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_enable_quic(config)); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); @@ -185,11 +185,11 @@ int main(int argc, char **argv) /* Save empty transport parameters */ { - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_enable_quic(config)); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); @@ -207,15 +207,15 @@ int main(int argc, char **argv) struct s2n_stuffer out = { 0 }; EXPECT_SUCCESS(s2n_stuffer_growable_alloc(&out, 0)); - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_enable_quic(config)); - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config)); - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(client_conn, config)); EXPECT_SUCCESS(s2n_connection_set_quic_transport_parameters(client_conn, TEST_DATA, sizeof(TEST_DATA))); diff --git a/tests/unit/s2n_random_test.c b/tests/unit/s2n_random_test.c index 658de06a5cb..b2b5ecdbd63 100644 --- a/tests/unit/s2n_random_test.c +++ b/tests/unit/s2n_random_test.c @@ -48,6 +48,10 @@ #define NUMBER_OF_RANGE_FUNCTION_CALLS 200 #define MAX_REPEATED_OUTPUT 4 +S2N_RESULT s2n_rand_device_validate(struct s2n_rand_device *device); +S2N_RESULT s2n_rand_get_urandom_for_test(struct s2n_rand_device **device); +S2N_RESULT s2n_rand_set_urandom_for_test(); + struct random_test_case { const char *test_case_label; int (*test_case_cb)(struct random_test_case *test_case); @@ -374,7 +378,7 @@ static S2N_RESULT s2n_fork_test( S2N_RESULT (*s2n_get_random_data_cb)(struct s2n_blob *blob), S2N_RESULT (*s2n_get_random_data_cb_thread)(struct s2n_blob *blob)) { - pid_t proc_id; + pid_t proc_id = 0; int pipes[2]; /* A simple fork test. Generates random data in the parent and child, and @@ -460,7 +464,7 @@ static S2N_RESULT s2n_clone_tests( { #if defined(S2N_CLONE_SUPPORTED) - int proc_id; + int proc_id = 0; int pipes[2]; EXPECT_SUCCESS(pipe(pipes)); @@ -788,6 +792,87 @@ static int s2n_random_rand_bytes_after_cleanup_cb(struct random_test_case *test_ return S2N_SUCCESS; } +static int s2n_random_rand_bytes_before_init(struct random_test_case *test_case) +{ +#if S2N_LIBCRYPTO_SUPPORTS_CUSTOM_RAND + /* Calling RAND_bytes will set a global random method */ + unsigned char rndbytes[16] = { 0 }; + EXPECT_EQUAL(RAND_bytes(rndbytes, sizeof(rndbytes)), 1); + const RAND_METHOD *rand_method = RAND_get_rand_method(); + EXPECT_NOT_NULL(rand_method); + EXPECT_NOT_EQUAL(rand_method->bytes, s2n_openssl_compat_rand); + + EXPECT_SUCCESS(s2n_init()); + + /* The global random method is overridden after calling s2n_init() */ + const RAND_METHOD *custom_rand_method = RAND_get_rand_method(); + EXPECT_NOT_NULL(custom_rand_method); + EXPECT_EQUAL(custom_rand_method->bytes, s2n_openssl_compat_rand); + + /* RAND_bytes is still successful */ + EXPECT_EQUAL(RAND_bytes(rndbytes, sizeof(rndbytes)), 1); + +#endif + return S2N_SUCCESS; +} + +static int s2n_random_invalid_urandom_fd_cb(struct random_test_case *test_case) +{ + EXPECT_SUCCESS(s2n_disable_atexit()); + + struct s2n_rand_device *dev_urandom = NULL; + EXPECT_OK(s2n_rand_get_urandom_for_test(&dev_urandom)); + EXPECT_NOT_NULL(dev_urandom); + + for (size_t test = 0; test <= 1; test++) { + EXPECT_EQUAL(dev_urandom->fd, -1); + + /* Validation should fail before initialization. */ + EXPECT_ERROR(s2n_rand_device_validate(dev_urandom)); + + EXPECT_SUCCESS(s2n_init()); + + /* Validation should succeed after initialization. */ + EXPECT_OK(s2n_rand_device_validate(dev_urandom)); + + /* Override the mix callback with urandom, in case support for rdrand is detected and enabled. */ + EXPECT_OK(s2n_rand_set_urandom_for_test()); + + EXPECT_TRUE(dev_urandom->fd > STDERR_FILENO); + if (test == 0) { + /* Close the file descriptor. */ + EXPECT_EQUAL(close(dev_urandom->fd), 0); + } else { + /* Make the file descriptor invalid by pointing it to STDERR. */ + dev_urandom->fd = STDERR_FILENO; + } + + /* Validation should fail when the file descriptor is invalid. */ + EXPECT_ERROR(s2n_rand_device_validate(dev_urandom)); + + s2n_stack_blob(rand_data, 16, 16); + EXPECT_OK(s2n_get_public_random_data(&rand_data)); + + uint64_t public_bytes_used = 0; + EXPECT_OK(s2n_get_public_random_bytes_used(&public_bytes_used)); + + if (s2n_is_in_fips_mode()) { + /* The urandom implementation should not be in use when s2n-tls is in FIPS mode. */ + EXPECT_EQUAL(public_bytes_used, 0); + } else { + /* When the urandom implementation is used, the file descriptor is re-opened and + * validation should succeed. + */ + EXPECT_OK(s2n_rand_device_validate(dev_urandom)); + EXPECT_TRUE(public_bytes_used > 0); + } + + EXPECT_SUCCESS(s2n_cleanup()); + } + + return S2N_SUCCESS; +} + struct random_test_case random_test_cases[] = { { "Random API.", s2n_random_test_case_default_cb, CLONE_TEST_DETERMINE_AT_RUNTIME, EXIT_SUCCESS }, { "Random API without prediction resistance.", s2n_random_test_case_without_pr_cb, CLONE_TEST_DETERMINE_AT_RUNTIME, EXIT_SUCCESS }, @@ -800,6 +885,8 @@ struct random_test_case random_test_cases[] = { */ { "Test failure.", s2n_random_test_case_failure_cb, CLONE_TEST_DETERMINE_AT_RUNTIME, 1 }, { "Test libcrypto's RAND engine is reset correctly after manual s2n_cleanup()", s2n_random_rand_bytes_after_cleanup_cb, CLONE_TEST_DETERMINE_AT_RUNTIME, EXIT_SUCCESS }, + { "Test getting entropy with an invalid file descriptor", s2n_random_invalid_urandom_fd_cb, CLONE_TEST_DETERMINE_AT_RUNTIME, EXIT_SUCCESS }, + { "Test libcrypto's global RAND is unset after calling s2n_init()", s2n_random_rand_bytes_before_init, CLONE_TEST_DETERMINE_AT_RUNTIME, EXIT_SUCCESS }, }; int main(int argc, char **argv) diff --git a/tests/unit/s2n_rc4_test.c b/tests/unit/s2n_rc4_test.c index 31fab3d1c35..a1d42238ab9 100644 --- a/tests/unit/s2n_rc4_test.c +++ b/tests/unit/s2n_rc4_test.c @@ -43,7 +43,7 @@ int main(int argc, char **argv) EXPECT_FALSE(s2n_rc4.is_available()); } - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; uint8_t mac_key[] = "sample mac key"; uint8_t rc4_key[] = "123456789012345"; struct s2n_blob key_iv = { 0 }; @@ -80,7 +80,7 @@ int main(int argc, char **argv) for (size_t i = 0; i <= S2N_DEFAULT_FRAGMENT_LENGTH + 1; i++) { struct s2n_blob in = { 0 }; EXPECT_SUCCESS(s2n_blob_init(&in, random_data, i)); - int bytes_written; + int bytes_written = 0; EXPECT_SUCCESS(s2n_stuffer_wipe(&conn->out)); @@ -115,8 +115,8 @@ int main(int argc, char **argv) EXPECT_EQUAL(bytes_written + 20, s2n_stuffer_data_available(&conn->in)); /* Let's decrypt it */ - uint8_t content_type; - uint16_t fragment_length; + uint8_t content_type = 0; + uint16_t fragment_length = 0; EXPECT_SUCCESS(s2n_record_header_parse(conn, &content_type, &fragment_length)); EXPECT_SUCCESS(s2n_record_parse(conn)); EXPECT_EQUAL(content_type, TLS_APPLICATION_DATA); diff --git a/tests/unit/s2n_record_read_test.c b/tests/unit/s2n_record_read_test.c new file mode 100644 index 00000000000..067de45dc7e --- /dev/null +++ b/tests/unit/s2n_record_read_test.c @@ -0,0 +1,163 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +#include "s2n_test.h" +#include "testlib/s2n_testlib.h" +#include "tls/s2n_record.h" +#include "tls/s2n_tls.h" +#include "utils/s2n_safety.h" + +#define SSLV2_MIN_SIZE 3 + +int main(int argc, char *argv[]) +{ + BEGIN_TEST(); + + /* Test s2n_sslv2_record_header_parse */ + { + const struct { + uint8_t bytes[S2N_TLS_RECORD_HEADER_LENGTH]; + uint16_t length; + uint8_t type; + uint8_t version; + } test_cases[] = { + { + .bytes = { S2N_TLS_SSLV2_HEADER_FLAG, SSLV2_MIN_SIZE, TLS_CLIENT_HELLO, 0x03, 0x03 }, + .length = 0, + .type = TLS_CLIENT_HELLO, + .version = S2N_TLS12, + }, + { + .bytes = { S2N_TLS_SSLV2_HEADER_FLAG, SSLV2_MIN_SIZE + 1, TLS_CLIENT_HELLO, 0x03, 0x03 }, + .length = 1, + .type = TLS_CLIENT_HELLO, + .version = S2N_TLS12, + }, + { + .bytes = { S2N_TLS_SSLV2_HEADER_FLAG, 0xFF, TLS_CLIENT_HELLO, 0x03, 0x03 }, + .length = 0xFF - SSLV2_MIN_SIZE, + .type = TLS_CLIENT_HELLO, + .version = S2N_TLS12, + }, + { + .bytes = { S2N_TLS_SSLV2_HEADER_FLAG, 0x84, TLS_CLIENT_HELLO, 0x03, 0x03 }, + .length = 0x84 - SSLV2_MIN_SIZE, + .type = TLS_CLIENT_HELLO, + .version = S2N_TLS12, + }, + { + .bytes = { 0x84, 0x84, TLS_CLIENT_HELLO, 0x03, 0x03 }, + .length = 0x484 - SSLV2_MIN_SIZE, + .type = TLS_CLIENT_HELLO, + .version = S2N_TLS12, + }, + { + .bytes = { 0xFF, 0xFF, TLS_CLIENT_HELLO, 0x03, 0x03 }, + .length = 0x7FFF - SSLV2_MIN_SIZE, + .type = TLS_CLIENT_HELLO, + .version = S2N_TLS12, + }, + { + .bytes = { S2N_TLS_SSLV2_HEADER_FLAG, SSLV2_MIN_SIZE, 0, 0x03, 0x03 }, + .length = 0, + .type = 0, + .version = S2N_TLS12, + }, + { + .bytes = { S2N_TLS_SSLV2_HEADER_FLAG, SSLV2_MIN_SIZE, 77, 0x03, 0x03 }, + .length = 0, + .type = 77, + .version = S2N_TLS12, + }, + { + .bytes = { S2N_TLS_SSLV2_HEADER_FLAG, SSLV2_MIN_SIZE, TLS_SERVER_HELLO, 0x03, 0x03 }, + .length = 0, + .type = TLS_SERVER_HELLO, + .version = S2N_TLS12, + }, + { + .bytes = { S2N_TLS_SSLV2_HEADER_FLAG, SSLV2_MIN_SIZE, TLS_CLIENT_HELLO, 0x03, 0x04 }, + .length = 0, + .type = TLS_CLIENT_HELLO, + .version = S2N_TLS13, + }, + { + .bytes = { S2N_TLS_SSLV2_HEADER_FLAG, SSLV2_MIN_SIZE, TLS_CLIENT_HELLO, 0, 0 }, + .length = 0, + .type = TLS_CLIENT_HELLO, + .version = 0, + }, + }; + + /* Test: parse valid record headers */ + for (size_t i = 0; i < s2n_array_len(test_cases); i++) { + DEFER_CLEANUP(struct s2n_connection *conn = s2n_connection_new(S2N_SERVER), + s2n_connection_ptr_free); + EXPECT_NOT_NULL(conn); + + EXPECT_SUCCESS(s2n_stuffer_write_bytes(&conn->header_in, + test_cases[i].bytes, sizeof(test_cases[i].bytes))); + + uint8_t type = 0, version = 0; + uint16_t length = 0; + EXPECT_SUCCESS(s2n_sslv2_record_header_parse(conn, &type, &version, &length)); + EXPECT_EQUAL(test_cases[i].type, type); + EXPECT_EQUAL(test_cases[i].version, version); + EXPECT_EQUAL(test_cases[i].length, length); + + EXPECT_BYTEARRAY_EQUAL(conn->header_in_data, + test_cases[i].bytes, sizeof(test_cases[i].bytes)); + + EXPECT_EQUAL(s2n_stuffer_data_available(&conn->header_in), S2N_TLS_RECORD_HEADER_LENGTH); + } + + /* Test: parse header with bad length + * + * We already read 3 bytes by reading the header, so logically the message + * is at least 3 bytes long. + */ + { + DEFER_CLEANUP(struct s2n_connection *conn = s2n_connection_new(S2N_SERVER), + s2n_connection_ptr_free); + EXPECT_NOT_NULL(conn); + EXPECT_SUCCESS(s2n_stuffer_skip_write(&conn->header_in, S2N_TLS_RECORD_HEADER_LENGTH)); + conn->header_in_data[0] = S2N_TLS_SSLV2_HEADER_FLAG; + + uint8_t type = 0, version = 0; + uint16_t length = 0; + + conn->header_in_data[1] = SSLV2_MIN_SIZE - 1; + EXPECT_FAILURE_WITH_ERRNO( + s2n_sslv2_record_header_parse(conn, &type, &version, &length), + S2N_ERR_BAD_MESSAGE); + EXPECT_EQUAL(s2n_stuffer_data_available(&conn->header_in), 3); + EXPECT_SUCCESS(s2n_stuffer_reread(&conn->header_in)); + + conn->header_in_data[1] = SSLV2_MIN_SIZE; + EXPECT_SUCCESS(s2n_sslv2_record_header_parse(conn, &type, &version, &length)); + EXPECT_EQUAL(s2n_stuffer_data_available(&conn->header_in), S2N_TLS_RECORD_HEADER_LENGTH); + EXPECT_SUCCESS(s2n_stuffer_reread(&conn->header_in)); + + conn->header_in_data[1] = 0; + EXPECT_FAILURE_WITH_ERRNO( + s2n_sslv2_record_header_parse(conn, &type, &version, &length), + S2N_ERR_BAD_MESSAGE); + EXPECT_EQUAL(s2n_stuffer_data_available(&conn->header_in), 3); + EXPECT_SUCCESS(s2n_stuffer_reread(&conn->header_in)); + }; + }; + + END_TEST(); +} diff --git a/tests/unit/s2n_record_size_test.c b/tests/unit/s2n_record_size_test.c index 615a4d9dea3..cd144809cd7 100644 --- a/tests/unit/s2n_record_size_test.c +++ b/tests/unit/s2n_record_size_test.c @@ -122,12 +122,12 @@ int main(int argc, char **argv) /* Test s2n_record_max_write_payload_size() have proper checks in place */ { - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); /* we deal with the default null cipher suite for now, as it makes reasoning * about easier s2n_record_max_write_payload_size(), as it incur 0 overheads */ - uint16_t size; + uint16_t size = 0; server_conn->max_outgoing_fragment_length = ONE_BLOCK; EXPECT_OK(s2n_record_max_write_payload_size(server_conn, &size)); EXPECT_EQUAL(size, ONE_BLOCK); @@ -231,7 +231,7 @@ int main(int argc, char **argv) /* Test s2n_record_min_write_payload_size() */ { - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); uint16_t size = 0; @@ -397,7 +397,7 @@ int main(int argc, char **argv) /* Test large fragment/record sending for TLS 1.3 */ { - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); struct s2n_cipher_suite *cipher_suite = &s2n_tls13_aes_128_gcm_sha256; server_conn->actual_protocol_version = S2N_TLS13; @@ -428,7 +428,7 @@ int main(int argc, char **argv) small_io_vec.iov_base = small_blob.data; small_io_vec.iov_len = small_blob.size; - int bytes_taken; + int bytes_taken = 0; const uint16_t TLS13_RECORD_OVERHEAD = 22; EXPECT_SUCCESS(bytes_taken = s2n_record_writev(server_conn, TLS_APPLICATION_DATA, &small_io_vec, 1, 0, small_blob.size)); diff --git a/tests/unit/s2n_record_test.c b/tests/unit/s2n_record_test.c index bf7e9120fc6..5b94b45e45a 100644 --- a/tests/unit/s2n_record_test.c +++ b/tests/unit/s2n_record_test.c @@ -68,7 +68,7 @@ struct s2n_record_algorithm mock_null_sha1_record_alg = { int main(int argc, char **argv) { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; uint8_t mac_key[] = "sample mac key"; struct s2n_blob fixed_iv = { 0 }; EXPECT_SUCCESS(s2n_blob_init(&fixed_iv, mac_key, sizeof(mac_key))); @@ -97,7 +97,7 @@ int main(int argc, char **argv) for (size_t i = 0; i <= S2N_DEFAULT_FRAGMENT_LENGTH + 1; i++) { struct s2n_blob in = { 0 }; EXPECT_SUCCESS(s2n_blob_init(&in, random_data, i)); - int bytes_written; + int bytes_written = 0; EXPECT_SUCCESS(s2n_stuffer_wipe(&conn->out)); @@ -123,8 +123,8 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_stuffer_copy(&conn->out, &conn->header_in, 5)); EXPECT_SUCCESS(s2n_stuffer_copy(&conn->out, &conn->in, s2n_stuffer_data_available(&conn->out))); - uint8_t content_type; - uint16_t fragment_length; + uint8_t content_type = 0; + uint16_t fragment_length = 0; EXPECT_SUCCESS(s2n_record_header_parse(conn, &content_type, &fragment_length)); EXPECT_SUCCESS(s2n_record_parse(conn)); EXPECT_EQUAL(content_type, TLS_ALERT); @@ -141,7 +141,7 @@ int main(int argc, char **argv) for (size_t i = 0; i <= S2N_DEFAULT_FRAGMENT_LENGTH + 1; i++) { struct s2n_blob in = { 0 }; EXPECT_SUCCESS(s2n_blob_init(&in, random_data, i)); - int bytes_written; + int bytes_written = 0; EXPECT_SUCCESS(s2n_hmac_reset(&check_mac)); EXPECT_SUCCESS(s2n_hmac_update(&check_mac, conn->initial->server_sequence_number, 8)); @@ -184,8 +184,8 @@ int main(int argc, char **argv) uint8_t original_seq_num[8]; EXPECT_MEMCPY_SUCCESS(original_seq_num, conn->server->client_sequence_number, 8); - uint8_t content_type; - uint16_t fragment_length; + uint8_t content_type = 0; + uint16_t fragment_length = 0; EXPECT_SUCCESS(s2n_record_header_parse(conn, &content_type, &fragment_length)); EXPECT_SUCCESS(s2n_record_parse(conn)); EXPECT_EQUAL(content_type, TLS_ALERT); @@ -204,7 +204,7 @@ int main(int argc, char **argv) /* Deliberately corrupt a byte of the output and check that the record * won't parse */ - uint64_t byte_to_corrupt; + uint64_t byte_to_corrupt = 0; EXPECT_OK(s2n_public_random(fragment_length, &byte_to_corrupt)); EXPECT_SUCCESS(s2n_stuffer_wipe(&conn->header_in)); EXPECT_SUCCESS(s2n_stuffer_wipe(&conn->in)); @@ -225,7 +225,7 @@ int main(int argc, char **argv) for (size_t i = 0; i <= S2N_DEFAULT_FRAGMENT_LENGTH + 1; i++) { struct s2n_blob in = { 0 }; EXPECT_SUCCESS(s2n_blob_init(&in, random_data, i)); - int bytes_written; + int bytes_written = 0; EXPECT_SUCCESS(s2n_hmac_reset(&check_mac)); EXPECT_SUCCESS(s2n_hmac_update(&check_mac, conn->initial->client_sequence_number, 8)); @@ -278,8 +278,8 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_stuffer_copy(&conn->out, &conn->header_in, 5)); EXPECT_SUCCESS(s2n_stuffer_copy(&conn->out, &conn->in, s2n_stuffer_data_available(&conn->out))); - uint8_t content_type; - uint16_t fragment_length; + uint8_t content_type = 0; + uint16_t fragment_length = 0; EXPECT_SUCCESS(s2n_record_header_parse(conn, &content_type, &fragment_length)); EXPECT_SUCCESS(s2n_record_parse(conn)); EXPECT_EQUAL(content_type, TLS_APPLICATION_DATA); @@ -295,7 +295,7 @@ int main(int argc, char **argv) for (int i = 0; i <= S2N_DEFAULT_FRAGMENT_LENGTH + 1; i++) { struct s2n_blob in = { 0 }; EXPECT_SUCCESS(s2n_blob_init(&in, random_data, i)); - int bytes_written; + int bytes_written = 0; EXPECT_SUCCESS(s2n_hmac_reset(&check_mac)); EXPECT_SUCCESS(s2n_hmac_update(&check_mac, conn->initial->client_sequence_number, 8)); @@ -346,8 +346,8 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_stuffer_copy(&conn->out, &conn->header_in, 5)); EXPECT_SUCCESS(s2n_stuffer_copy(&conn->out, &conn->in, s2n_stuffer_data_available(&conn->out))); - uint8_t content_type; - uint16_t fragment_length; + uint8_t content_type = 0; + uint16_t fragment_length = 0; EXPECT_SUCCESS(s2n_record_header_parse(conn, &content_type, &fragment_length)); EXPECT_SUCCESS(s2n_record_parse(conn)); EXPECT_EQUAL(content_type, TLS_APPLICATION_DATA); @@ -386,8 +386,8 @@ int main(int argc, char **argv) /* Trigger condition to check for protocol version */ conn->actual_protocol_version_established = 1; - uint8_t content_type; - uint16_t fragment_length; + uint8_t content_type = 0; + uint16_t fragment_length = 0; EXPECT_SUCCESS(s2n_record_header_parse(conn, &content_type, &fragment_length)); /* If record version on wire is TLS 1.3, check s2n_record_header_parse fails */ @@ -411,23 +411,32 @@ int main(int argc, char **argv) EXPECT_FAILURE_WITH_ERRNO(s2n_record_parse(conn), S2N_ERR_DECRYPT); }; - /* Test s2n_sslv2_record_header_parse fails when fragment_length < 3 */ + /* Record version is recorded for the first message received (Client Hello) */ { - EXPECT_SUCCESS(s2n_stuffer_wipe(&conn->header_in)); - - uint8_t record_type = 0; - uint8_t protocol_version = 0; + DEFER_CLEANUP(struct s2n_connection *server_conn = s2n_connection_new(S2N_SERVER), + s2n_connection_ptr_free); + uint8_t content_type = 0; uint16_t fragment_length = 0; + uint8_t header[5] = { 0x16, /* Record type */ + 0x03, 0x01, /* Protocol version: TLS10 */ + 0x00, 0x00 }; /* Record size */ - /* First two bytes are the fragment length */ - uint8_t header_bytes[] = { 0x00, 0x00, 0x00, 0x00, 0x00 }; - EXPECT_SUCCESS(s2n_stuffer_write_bytes(&conn->header_in, header_bytes, sizeof(header_bytes))); + uint8_t altered_header[5] = { 0x16, /* Record type */ + 0x03, 0x03, /* Protocol version: TLS12 */ + 0x00, 0x00 }; /* Record size */ - EXPECT_FAILURE_WITH_ERRNO(s2n_sslv2_record_header_parse(conn, &record_type, &protocol_version, &fragment_length), S2N_ERR_SAFETY); + EXPECT_SUCCESS(s2n_stuffer_write_bytes(&server_conn->header_in, header, sizeof(header))); + EXPECT_SUCCESS(s2n_record_header_parse(server_conn, &content_type, &fragment_length)); + /* Record TLS version is retrieved as written in the header */ + EXPECT_EQUAL(server_conn->client_hello.legacy_record_version, S2N_TLS10); - /* Check the rest of the stuffer has not been read yet */ - EXPECT_EQUAL(s2n_stuffer_data_available(&conn->header_in), 3); - }; + EXPECT_SUCCESS(s2n_stuffer_wipe(&server_conn->header_in)); + + EXPECT_SUCCESS(s2n_stuffer_write_bytes(&server_conn->header_in, altered_header, sizeof(header))); + EXPECT_SUCCESS(s2n_record_header_parse(server_conn, &content_type, &fragment_length)); + /* Record TLS version is unchanged even though a different TLS version was in the record header */ + EXPECT_EQUAL(server_conn->client_hello.legacy_record_version, S2N_TLS10); + } EXPECT_SUCCESS(s2n_hmac_free(&check_mac)); diff --git a/tests/unit/s2n_recv_test.c b/tests/unit/s2n_recv_test.c index aa3fbe4c9b1..acb6e37ee12 100644 --- a/tests/unit/s2n_recv_test.c +++ b/tests/unit/s2n_recv_test.c @@ -195,7 +195,7 @@ int main(int argc, char **argv) /* s2n_recv cannot be called concurrently */ { /* Setup connection */ - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); /* Setup bad recv callback */ diff --git a/tests/unit/s2n_release_non_empty_buffers_test.c b/tests/unit/s2n_release_non_empty_buffers_test.c index c2a20dcc74f..7888583e925 100644 --- a/tests/unit/s2n_release_non_empty_buffers_test.c +++ b/tests/unit/s2n_release_non_empty_buffers_test.c @@ -33,8 +33,8 @@ static const uint8_t buf_to_send[1023] = { 27 }; int mock_client(struct s2n_test_io_pair *io_pair) { - struct s2n_connection *conn; - struct s2n_config *client_config; + struct s2n_connection *conn = NULL; + struct s2n_config *client_config = NULL; s2n_blocked_status blocked; int result = 0; @@ -70,10 +70,10 @@ int mock_client(struct s2n_test_io_pair *io_pair) int main(int argc, char **argv) { s2n_blocked_status blocked; - int status; - pid_t pid; - char *cert_chain_pem; - char *private_key_pem; + int status = 0; + pid_t pid = 0; + char *cert_chain_pem = NULL; + char *private_key_pem = NULL; uint8_t buf[sizeof(buf_to_send)]; uint32_t n = 0; ssize_t ret = 0; diff --git a/tests/unit/s2n_resume_test.c b/tests/unit/s2n_resume_test.c index eec6c211d75..5d70b026d2c 100644 --- a/tests/unit/s2n_resume_test.c +++ b/tests/unit/s2n_resume_test.c @@ -393,7 +393,7 @@ int main(int argc, char **argv) /* s2n_tls12_serialize_resumption_state */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); conn->actual_protocol_version = S2N_TLS12; @@ -448,7 +448,7 @@ int main(int argc, char **argv) { /* Safety checks */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); struct s2n_stuffer output = { 0 }; @@ -464,7 +464,7 @@ int main(int argc, char **argv) EXPECT_NOT_NULL(config); EXPECT_SUCCESS(s2n_config_set_wall_clock(config, mock_time, NULL)); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); conn->actual_protocol_version = S2N_TLS13; @@ -602,7 +602,7 @@ int main(int argc, char **argv) const uint8_t test_early_data_context[] = "context"; const uint8_t test_app_protocol[] = "protocol"; - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_server_early_data_context(conn, test_early_data_context, sizeof(test_early_data_context))); EXPECT_MEMCPY_SUCCESS(conn->application_protocol, test_app_protocol, sizeof(test_app_protocol)); @@ -770,7 +770,7 @@ int main(int argc, char **argv) /* Client processes TLS1.2 ticket with EMS data correctly */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); conn->actual_protocol_version = S2N_TLS12; /* Security policy must allow chosen cipher suite */ @@ -804,7 +804,7 @@ int main(int argc, char **argv) /* Server processes TLS1.2 ticket with EMS data correctly */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); conn->actual_protocol_version = S2N_TLS12; @@ -1290,9 +1290,9 @@ int main(int argc, char **argv) /* Check encrypted data can be decrypted correctly for TLS12 */ { - struct s2n_connection *conn; - struct s2n_config *config; - uint64_t current_time; + struct s2n_connection *conn = NULL; + struct s2n_config *config = NULL; + uint64_t current_time = 0; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_NOT_NULL(config = s2n_config_new()); @@ -1330,9 +1330,9 @@ int main(int argc, char **argv) /* Check session ticket can be decrypted with a small secret in TLS13 session resumption. */ { - struct s2n_connection *conn; - struct s2n_config *config; - uint64_t current_time; + struct s2n_connection *conn = NULL; + struct s2n_config *config = NULL; + uint64_t current_time = 0; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_NOT_NULL(config = s2n_config_new()); @@ -1372,9 +1372,9 @@ int main(int argc, char **argv) /* Check session ticket can be decrypted with the maximum size secret in TLS13 session resumption. */ { - struct s2n_connection *conn; - struct s2n_config *config; - uint64_t current_time; + struct s2n_connection *conn = NULL; + struct s2n_config *config = NULL; + uint64_t current_time = 0; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_NOT_NULL(config = s2n_config_new()); @@ -1458,8 +1458,8 @@ int main(int argc, char **argv) /* s2n_config_set_initial_ticket_count */ { - struct s2n_connection *conn; - struct s2n_config *config; + struct s2n_connection *conn = NULL; + struct s2n_config *config = NULL; uint8_t num_tickets = 1; EXPECT_NOT_NULL(config = s2n_config_new()); @@ -1484,7 +1484,7 @@ int main(int argc, char **argv) { /* New number of session tickets can be set */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; uint8_t original_num_tickets = 1; uint8_t new_num_tickets = 10; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); @@ -1499,7 +1499,7 @@ int main(int argc, char **argv) /* Overflow error is caught */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; uint8_t new_num_tickets = 1; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); conn->tickets_to_send = UINT16_MAX; diff --git a/tests/unit/s2n_rsa_pss_rsae_test.c b/tests/unit/s2n_rsa_pss_rsae_test.c index bfdafd3e536..f8ff3509757 100644 --- a/tests/unit/s2n_rsa_pss_rsae_test.c +++ b/tests/unit/s2n_rsa_pss_rsae_test.c @@ -161,7 +161,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_disable_tls13_in_test()); /* Load the RSA cert */ - struct s2n_cert_chain_and_key *rsa_cert_chain; + struct s2n_cert_chain_and_key *rsa_cert_chain = NULL; EXPECT_SUCCESS(s2n_test_cert_chain_and_key_new(&rsa_cert_chain, S2N_RSA_2048_PKCS1_CERT_CHAIN, S2N_RSA_2048_PKCS1_KEY)); @@ -198,7 +198,7 @@ int main(int argc, char **argv) #if RSA_PSS_CERTS_SUPPORTED - struct s2n_cert_chain_and_key *rsa_pss_cert_chain; + struct s2n_cert_chain_and_key *rsa_pss_cert_chain = NULL; EXPECT_SUCCESS(s2n_test_cert_chain_and_key_new(&rsa_pss_cert_chain, S2N_RSA_PSS_2048_SHA256_LEAF_CERT, S2N_RSA_PSS_2048_SHA256_LEAF_KEY)); diff --git a/tests/unit/s2n_rsa_pss_test.c b/tests/unit/s2n_rsa_pss_test.c index 2e0bf263c58..4f6b7be6bcb 100644 --- a/tests/unit/s2n_rsa_pss_test.c +++ b/tests/unit/s2n_rsa_pss_test.c @@ -27,9 +27,9 @@ int s2n_flip_random_bit(struct s2n_blob *blob) { /* Flip a random bit in the blob */ - uint64_t byte_flip_pos; + uint64_t byte_flip_pos = 0; POSIX_GUARD_RESULT(s2n_public_random(blob->size, &byte_flip_pos)); - uint64_t bit_flip_pos; + uint64_t bit_flip_pos = 0; POSIX_GUARD_RESULT(s2n_public_random(8, &bit_flip_pos)); uint8_t mask = 0x01 << (uint8_t) bit_flip_pos; @@ -57,10 +57,10 @@ int main(int argc, char **argv) * Pseudocode: assert(SUCCESS == verify(Key1_public, message, sign(Key1_private, message))) */ { - struct s2n_config *server_config; - char *cert_chain_pem; - char *private_key_pem; - struct s2n_cert_chain_and_key *chain_and_key; + struct s2n_config *server_config = NULL; + char *cert_chain_pem = NULL; + char *private_key_pem = NULL; + struct s2n_cert_chain_and_key *chain_and_key = NULL; struct s2n_pkey public_key = { 0 }; s2n_pkey_type pkey_type = S2N_PKEY_TYPE_UNKNOWN; @@ -98,10 +98,10 @@ int main(int argc, char **argv) * Pseudocode: assert(FAILURE == load_pem_pair(Key1_public, Key2_private)) */ { - struct s2n_config *server_config; - char *leaf_cert_chain_pem; - char *root_private_key_pem; - struct s2n_cert_chain_and_key *misconfigured_chain_and_key; + struct s2n_config *server_config = NULL; + char *leaf_cert_chain_pem = NULL; + char *root_private_key_pem = NULL; + struct s2n_cert_chain_and_key *misconfigured_chain_and_key = NULL; struct s2n_pkey public_key = { 0 }; EXPECT_NOT_NULL(leaf_cert_chain_pem = malloc(S2N_MAX_TEST_PEM_SIZE)); @@ -129,10 +129,10 @@ int main(int argc, char **argv) * Pseudocode: assert(FAILURE == verify(Key1_public, message, bitflip(sign(Key1_private, message))) */ { - struct s2n_config *server_config; - char *cert_chain_pem; - char *private_key_pem; - struct s2n_cert_chain_and_key *chain_and_key; + struct s2n_config *server_config = NULL; + char *cert_chain_pem = NULL; + char *private_key_pem = NULL; + struct s2n_cert_chain_and_key *chain_and_key = NULL; struct s2n_pkey public_key = { 0 }; s2n_pkey_type pkey_type = S2N_PKEY_TYPE_UNKNOWN; @@ -194,13 +194,13 @@ int main(int argc, char **argv) * Pseudocode: assert(FAILURE == verify(Key2_public, message, sign(Key1_private, message))) */ { - struct s2n_config *server_config; - char *root_cert_chain_pem; - char *root_private_key_pem; - char *leaf_cert_chain_pem; - char *leaf_private_key_pem; - struct s2n_cert_chain_and_key *root_chain_and_key; - struct s2n_cert_chain_and_key *leaf_chain_and_key; + struct s2n_config *server_config = NULL; + char *root_cert_chain_pem = NULL; + char *root_private_key_pem = NULL; + char *leaf_cert_chain_pem = NULL; + char *leaf_private_key_pem = NULL; + struct s2n_cert_chain_and_key *root_chain_and_key = NULL; + struct s2n_cert_chain_and_key *leaf_chain_and_key = NULL; struct s2n_pkey root_public_key = { 0 }; struct s2n_pkey leaf_public_key = { 0 }; s2n_pkey_type root_pkey_type = S2N_PKEY_TYPE_UNKNOWN; @@ -285,10 +285,10 @@ int main(int argc, char **argv) * Pseudocode: assert(FAILURE == verify(Key1_public, bitflip(message), sign(Key1_private, message))) */ { - struct s2n_config *server_config; - char *cert_chain_pem; - char *private_key_pem; - struct s2n_cert_chain_and_key *chain_and_key; + struct s2n_config *server_config = NULL; + char *cert_chain_pem = NULL; + char *private_key_pem = NULL; + struct s2n_cert_chain_and_key *chain_and_key = NULL; struct s2n_pkey public_key = { 0 }; s2n_pkey_type pkey_type = S2N_PKEY_TYPE_UNKNOWN; diff --git a/tests/unit/s2n_security_policy_cert_preferences_test.c b/tests/unit/s2n_security_policy_cert_preferences_test.c new file mode 100644 index 00000000000..28222d0c5c8 --- /dev/null +++ b/tests/unit/s2n_security_policy_cert_preferences_test.c @@ -0,0 +1,293 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +#include "s2n_test.h" +#include "testlib/s2n_testlib.h" +#include "tls/s2n_certificate_keys.h" +#include "tls/s2n_security_policies.h" +#include "tls/s2n_signature_scheme.h" + +#define CHAIN_LENGTH 3 + +static S2N_RESULT s2n_test_construct_cert_chain( + struct s2n_cert *certs, + size_t certs_length, + struct s2n_cert_chain *cert_chain, + struct s2n_cert_chain_and_key *chain, + const struct s2n_cert_info *valid_info) +{ + RESULT_ENSURE_REF(certs); + RESULT_ENSURE_REF(cert_chain); + RESULT_ENSURE_REF(chain); + RESULT_ENSURE_REF(valid_info); + + for (size_t i = 0; i < certs_length; i++) { + certs[i].info = *valid_info; + if (i != certs_length - 1) { + certs[i].next = &certs[i + 1]; + } + } + + /* root cert */ + certs[certs_length - 1].info.self_signed = true; + + cert_chain->head = &certs[0]; + chain->cert_chain = cert_chain; + + return S2N_RESULT_OK; +} + +int main(int argc, char **argv) +{ + BEGIN_TEST(); + + const int valid_sig_nid = NID_ecdsa_with_SHA256; + const int valid_hash_nid = NID_sha256; + const int valid_key_size = 384; + const int valid_key_nid = NID_secp384r1; + + const int invalid_sig_nid = NID_sha256WithRSAEncryption; + const int invalid_hash_nid = NID_sha1; + const int invalid_key_size = 256; + const int invalid_key_nid = NID_X9_62_prime256v1; + + const struct s2n_cert_info valid_info = { + .self_signed = false, + .signature_nid = valid_sig_nid, + .signature_digest_nid = valid_hash_nid, + .public_key_bits = valid_key_size, + .public_key_nid = valid_key_nid, + }; + + const struct s2n_signature_scheme *const test_sig_scheme_list[] = { + &s2n_ecdsa_sha256, + &s2n_rsa_pkcs1_sha1, + }; + + const struct s2n_certificate_key *const test_cert_key_list[] = { + &s2n_ec_p384, + &s2n_rsa_rsae_3072, + }; + + const struct s2n_signature_preferences test_certificate_signature_preferences = { + .count = s2n_array_len(test_sig_scheme_list), + .signature_schemes = test_sig_scheme_list, + }; + + const struct s2n_certificate_key_preferences test_cert_key_preferences = { + .count = s2n_array_len(test_cert_key_list), + .certificate_keys = test_cert_key_list, + }; + + const struct s2n_security_policy test_sp = { + .certificate_signature_preferences = &test_certificate_signature_preferences, + .certificate_key_preferences = &test_cert_key_preferences, + .certificate_preferences_apply_locally = true, + }; + + const struct s2n_signature_scheme *const pss_sig_scheme_list[] = { + &s2n_rsa_pss_pss_sha256, + &s2n_rsa_pss_pss_sha384, + &s2n_rsa_pss_pss_sha512, + &s2n_rsa_pss_rsae_sha256, + &s2n_rsa_pss_rsae_sha384, + &s2n_rsa_pss_rsae_sha512, + }; + + const struct s2n_signature_preferences pss_certificate_signature_preferences = { + .count = s2n_array_len(pss_sig_scheme_list), + .signature_schemes = pss_sig_scheme_list, + }; + + const struct s2n_security_policy test_pss_sp = { + .certificate_signature_preferences = &pss_certificate_signature_preferences, + }; + + /* s2n_security_policy_validate_cert_signature() */ + { + /* Certificate signature algorithm is in test certificate signature preferences list */ + { + struct s2n_cert_info info = { + .self_signed = false, + .signature_digest_nid = NID_sha256, + .signature_nid = NID_ecdsa_with_SHA256, + }; + + EXPECT_OK(s2n_security_policy_validate_cert_signature(&test_sp, &info, + S2N_ERR_SECURITY_POLICY_INCOMPATIBLE_CERT)); + }; + + /* Certificate signature algorithm is not in test certificate signature preferences list */ + { + struct s2n_cert_info info = { + .self_signed = false, + .signature_digest_nid = NID_undef, + .signature_nid = NID_rsassaPss, + }; + + EXPECT_ERROR_WITH_ERRNO(s2n_security_policy_validate_cert_signature(&test_sp, &info, + S2N_ERR_SECURITY_POLICY_INCOMPATIBLE_CERT), + S2N_ERR_SECURITY_POLICY_INCOMPATIBLE_CERT); + }; + + /* Certificates signed with an RSA PSS signature can be validated */ + { + struct s2n_cert_info info = { + .self_signed = false, + .signature_digest_nid = NID_undef, + .signature_nid = NID_rsassaPss, + }; + + EXPECT_OK(s2n_security_policy_validate_cert_signature(&test_pss_sp, &info, + S2N_ERR_SECURITY_POLICY_INCOMPATIBLE_CERT)); + }; + }; + + /* s2n_security_policy_validate_cert_key() */ + { + /* Certificate key is in test certificate key list */ + { + struct s2n_cert_info info = { + .public_key_nid = valid_key_nid, + .public_key_bits = valid_key_size, + }; + + EXPECT_OK(s2n_security_policy_validate_cert_key(&test_sp, &info, + S2N_ERR_SECURITY_POLICY_INCOMPATIBLE_CERT)); + }; + + /* Certificate key is not in test certificate key list */ + { + struct s2n_cert_info info = { + .public_key_nid = invalid_key_nid, + .signature_nid = invalid_key_size, + }; + + EXPECT_ERROR_WITH_ERRNO(s2n_security_policy_validate_cert_key(&test_sp, &info, + S2N_ERR_SECURITY_POLICY_INCOMPATIBLE_CERT), + S2N_ERR_SECURITY_POLICY_INCOMPATIBLE_CERT); + }; + }; + + /* s2n_security_policy_validate_certificate_chain() */ + { + /* a valid certificate chain passes validation */ + { + struct s2n_cert certs[CHAIN_LENGTH] = { 0 }; + struct s2n_cert_chain cert_chain = { 0 }; + struct s2n_cert_chain_and_key chain = { 0 }; + EXPECT_OK(s2n_test_construct_cert_chain(certs, CHAIN_LENGTH, &cert_chain, &chain, &valid_info)); + EXPECT_OK(s2n_security_policy_validate_certificate_chain(&test_sp, &chain)); + }; + + /* test that failures can be detected for any cert in the chain */ + for (size_t i = 0; i < CHAIN_LENGTH; i++) { + /* an invalid signature causes a failure */ + { + struct s2n_cert certs[CHAIN_LENGTH] = { 0 }; + struct s2n_cert_chain cert_chain = { 0 }; + struct s2n_cert_chain_and_key chain = { 0 }; + EXPECT_OK(s2n_test_construct_cert_chain(certs, CHAIN_LENGTH, &cert_chain, &chain, &valid_info)); + certs[i].info.signature_nid = invalid_sig_nid; + certs[i].info.signature_digest_nid = invalid_hash_nid; + EXPECT_ERROR_WITH_ERRNO(s2n_security_policy_validate_certificate_chain(&test_sp, &chain), + S2N_ERR_SECURITY_POLICY_INCOMPATIBLE_CERT); + }; + + /* an invalid key nid causes a failure */ + { + struct s2n_cert certs[CHAIN_LENGTH] = { 0 }; + struct s2n_cert_chain cert_chain = { 0 }; + struct s2n_cert_chain_and_key chain = { 0 }; + EXPECT_OK(s2n_test_construct_cert_chain(certs, CHAIN_LENGTH, &cert_chain, &chain, &valid_info)); + certs[i].info.public_key_nid = invalid_key_nid; + EXPECT_ERROR_WITH_ERRNO(s2n_security_policy_validate_certificate_chain(&test_sp, &chain), + S2N_ERR_SECURITY_POLICY_INCOMPATIBLE_CERT); + }; + + /* an invalid key size causes a failure */ + { + struct s2n_cert certs[CHAIN_LENGTH] = { 0 }; + struct s2n_cert_chain cert_chain = { 0 }; + struct s2n_cert_chain_and_key chain = { 0 }; + EXPECT_OK(s2n_test_construct_cert_chain(certs, CHAIN_LENGTH, &cert_chain, &chain, &valid_info)); + certs[i].info.public_key_bits = invalid_key_size; + EXPECT_ERROR_WITH_ERRNO(s2n_security_policy_validate_certificate_chain(&test_sp, &chain), + S2N_ERR_SECURITY_POLICY_INCOMPATIBLE_CERT); + }; + + /* when certificate_preferences_apply_locally is false then validation succeeds */ + { + struct s2n_cert certs[CHAIN_LENGTH] = { 0 }; + struct s2n_cert_chain cert_chain = { 0 }; + struct s2n_cert_chain_and_key chain = { 0 }; + EXPECT_OK(s2n_test_construct_cert_chain(certs, CHAIN_LENGTH, &cert_chain, &chain, &valid_info)); + + struct s2n_security_policy test_sp_no_local = test_sp; + test_sp_no_local.certificate_preferences_apply_locally = false; + + certs[i].info.signature_nid = invalid_sig_nid; + certs[i].info.public_key_nid = invalid_key_nid; + EXPECT_OK(s2n_security_policy_validate_certificate_chain(&test_sp_no_local, &chain)); + }; + } + }; + + /* s2n_connection_set_cipher_preferences */ + { + DEFER_CLEANUP(struct s2n_cert_chain_and_key *invalid_cert = NULL, s2n_cert_chain_and_key_ptr_free); + EXPECT_SUCCESS(s2n_test_cert_permutation_load_server_chain(&invalid_cert, "rsae", "pss", "4096", "sha384")); + + struct s2n_security_policy rfc9151_applied_locally = security_policy_rfc9151; + rfc9151_applied_locally.certificate_preferences_apply_locally = true; + + /* s2n_connection_set_cipher_preferences looks up the security policy from the security_policy_selection table + * but none of our current security policies apply certificate preferences locally. So instead we rewrite the + * rfc9151 policy from the table to apply cert preference locally. */ + struct s2n_security_policy_selection *rfc9151_selection = NULL; + const struct s2n_security_policy *original_rfc9151 = NULL; + for (int i = 0; security_policy_selection[i].version != NULL; i++) { + if (strcasecmp("rfc9151", security_policy_selection[i].version) == 0) { + rfc9151_selection = &security_policy_selection[i]; + break; + } + } + if (rfc9151_selection == NULL) { + FAIL_MSG("unable to find expected security policy"); + } + original_rfc9151 = rfc9151_selection->security_policy; + rfc9151_selection->security_policy = &rfc9151_applied_locally; + + /* when certificate preferences apply locally and the connection contains + * an invalid config then s2n_connection_set_cipher_preferences fails + */ + { + DEFER_CLEANUP(struct s2n_config *config = s2n_config_new(), s2n_config_ptr_free); + EXPECT_NOT_NULL(config); + DEFER_CLEANUP(struct s2n_connection *conn = s2n_connection_new(S2N_SERVER), s2n_connection_ptr_free); + EXPECT_NOT_NULL(conn); + EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(config, invalid_cert)); + EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); + EXPECT_FAILURE_WITH_ERRNO(s2n_connection_set_cipher_preferences(conn, "rfc9151"), + S2N_ERR_SECURITY_POLICY_INCOMPATIBLE_CERT); + } + + /* restore security_policy_selection */ + rfc9151_selection->security_policy = original_rfc9151; + }; + + END_TEST(); + return S2N_SUCCESS; +} diff --git a/tests/unit/s2n_self_talk_alerts_test.c b/tests/unit/s2n_self_talk_alerts_test.c index d047a08ac99..e3d6f9bb0a7 100644 --- a/tests/unit/s2n_self_talk_alerts_test.c +++ b/tests/unit/s2n_self_talk_alerts_test.c @@ -44,8 +44,8 @@ struct alert_ctx { int mock_client(struct s2n_test_io_pair *io_pair, s2n_alert_behavior alert_behavior, int expect_failure) { - struct s2n_connection *conn; - struct s2n_config *config; + struct s2n_connection *conn = NULL; + struct s2n_config *config = NULL; s2n_blocked_status blocked; int result = 0; int rc = 0; @@ -139,13 +139,13 @@ S2N_RESULT cleanup(char **cert_chain_pem, char **private_key_pem, int main(int argc, char **argv) { char buffer[0xffff]; - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; s2n_blocked_status blocked; - int status; - pid_t pid; - char *cert_chain_pem; - char *private_key_pem; - struct s2n_cert_chain_and_key *chain_and_key; + int status = 0; + pid_t pid = 0; + char *cert_chain_pem = NULL; + char *private_key_pem = NULL; + struct s2n_cert_chain_and_key *chain_and_key = NULL; BEGIN_TEST(); /* Ignore SIGPIPE */ diff --git a/tests/unit/s2n_self_talk_alpn_test.c b/tests/unit/s2n_self_talk_alpn_test.c index ba17025c1cb..efc4b6e80e5 100644 --- a/tests/unit/s2n_self_talk_alpn_test.c +++ b/tests/unit/s2n_self_talk_alpn_test.c @@ -13,11 +13,6 @@ * permissions and limitations under the License. */ -#include -#include -#include -#include - #include "api/s2n.h" #include "s2n_test.h" #include "testlib/s2n_testlib.h" @@ -25,401 +20,130 @@ #include "tls/s2n_handshake.h" #include "utils/s2n_safety.h" -int mock_nanoseconds_since_epoch(void *data, uint64_t *nanoseconds) -{ - static int called = 0; - - /* When first called return 0 seconds */ - *nanoseconds = 0; - - /* When next called return 31 seconds */ - if (called) { - *nanoseconds += (uint64_t) 31 * 1000000000; - } - - called = 1; - - return 0; -} - -int mock_client(int writefd, int readfd, const char **protocols, int count, const char *expected) -{ - char buffer[0xffff]; - struct s2n_connection *client_conn; - struct s2n_config *client_config; - s2n_blocked_status blocked; - int result = 0; - - /* Give the server a chance to listen */ - sleep(1); - - client_conn = s2n_connection_new(S2N_CLIENT); - client_config = s2n_config_new(); - s2n_config_set_protocol_preferences(client_config, protocols, count); - s2n_config_disable_x509_verification(client_config); - s2n_connection_set_config(client_conn, client_config); - - s2n_connection_set_read_fd(client_conn, readfd); - s2n_connection_set_write_fd(client_conn, writefd); - - result = s2n_negotiate(client_conn, &blocked); - if (result < 0) { - result = 1; - } - - const char *got = s2n_get_application_protocol(client_conn); - if ((got != NULL && expected == NULL) - || (got == NULL && expected != NULL) - || (got != NULL && expected != NULL && strcmp(expected, got) != 0)) { - result = 2; - } - - for (int i = 1; i < 0xffff; i += 100) { - for (int j = 0; j < i; j++) { - buffer[j] = 33; - } - - s2n_send(client_conn, buffer, i, &blocked); - } - - int shutdown_rc = -1; - if (!result) { - do { - shutdown_rc = s2n_shutdown(client_conn, &blocked); - } while (shutdown_rc != 0); - } - - s2n_connection_free(client_conn); - s2n_config_free(client_config); - - /* Give the server a chance to a void a sigpipe */ - sleep(1); - - s2n_cleanup(); - - exit(result); -} +#define TEST_DATA_SIZE 8 int main(int argc, char **argv) { - char buffer[0xffff]; - struct s2n_connection *conn; - struct s2n_config *config; - s2n_blocked_status blocked; - int status; - pid_t pid; - int server_to_client[2]; - int client_to_server[2]; - char *cert_chain_pem; - char *private_key_pem; - char *dhparams_pem; - struct s2n_cert_chain_and_key *chain_and_key; - const char *protocols[] = { "http/1.1", "spdy/3.1", "h2" }; - const int protocols_size = s2n_array_len(protocols); const char *mismatch_protocols[] = { "spdy/2" }; BEGIN_TEST(); - EXPECT_NOT_NULL(cert_chain_pem = malloc(S2N_MAX_TEST_PEM_SIZE)); - EXPECT_NOT_NULL(private_key_pem = malloc(S2N_MAX_TEST_PEM_SIZE)); - EXPECT_NOT_NULL(dhparams_pem = malloc(S2N_MAX_TEST_PEM_SIZE)); - EXPECT_NOT_NULL(config = s2n_config_new()); - - EXPECT_SUCCESS(s2n_read_test_pem(S2N_DEFAULT_TEST_CERT_CHAIN, cert_chain_pem, S2N_MAX_TEST_PEM_SIZE)); - EXPECT_SUCCESS(s2n_read_test_pem(S2N_DEFAULT_TEST_PRIVATE_KEY, private_key_pem, S2N_MAX_TEST_PEM_SIZE)); - EXPECT_SUCCESS(s2n_read_test_pem(S2N_DEFAULT_TEST_DHPARAMS, dhparams_pem, S2N_MAX_TEST_PEM_SIZE)); - EXPECT_NOT_NULL(chain_and_key = s2n_cert_chain_and_key_new()); - EXPECT_SUCCESS(s2n_cert_chain_and_key_load_pem(chain_and_key, cert_chain_pem, private_key_pem)); - - EXPECT_SUCCESS(s2n_config_set_protocol_preferences(config, protocols, protocols_size)); - EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(config, chain_and_key)); - EXPECT_SUCCESS(s2n_config_add_dhparams(config, dhparams_pem)); - EXPECT_SUCCESS(s2n_config_set_cipher_preferences(config, "default")); - - /** Test no client ALPN request */ - /* Create a pipe */ - EXPECT_SUCCESS(pipe(server_to_client)); - EXPECT_SUCCESS(pipe(client_to_server)); - - /* Create a child process */ - pid = fork(); - if (pid == 0) { - /* This is the child process, close the read end of the pipe */ - EXPECT_SUCCESS(close(client_to_server[0])); - EXPECT_SUCCESS(close(server_to_client[1])); - - /* Send the client hello with no ALPN extensions, and validate we didn't - * negotiate an application protocol */ - mock_client(client_to_server[1], server_to_client[0], NULL, 0, NULL); - } - - /* This is the parent */ - EXPECT_SUCCESS(close(client_to_server[1])); - EXPECT_SUCCESS(close(server_to_client[0])); - - EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); - - EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); - - /* Set up the connection to read from the fd */ - EXPECT_SUCCESS(s2n_connection_set_read_fd(conn, client_to_server[0])); - EXPECT_SUCCESS(s2n_connection_set_write_fd(conn, server_to_client[1])); - - /* Negotiate the handshake. */ - EXPECT_SUCCESS(s2n_negotiate(conn, &blocked)); - - EXPECT_EQUAL(s2n_connection_get_selected_cert(conn), chain_and_key); - - /* Expect NULL negotiated protocol */ - EXPECT_EQUAL(s2n_get_application_protocol(conn), NULL); - - for (int i = 1; i < 0xffff; i += 100) { - char *ptr = buffer; - int size = i; - - do { - int bytes_read = 0; - EXPECT_SUCCESS(bytes_read = s2n_recv(conn, ptr, size, &blocked)); - - size -= bytes_read; - ptr += bytes_read; - } while (size); - - for (int j = 0; j < i; j++) { - EXPECT_EQUAL(buffer[j], 33); - } - } - - EXPECT_SUCCESS(s2n_shutdown(conn, &blocked)); - EXPECT_SUCCESS(s2n_connection_free(conn)); - - /* Clean up */ - EXPECT_EQUAL(waitpid(-1, &status, 0), pid); - EXPECT_EQUAL(status, 0); - - /* Test a matching ALPN request */ - /* Create a pipe */ - EXPECT_SUCCESS(pipe(server_to_client)); - EXPECT_SUCCESS(pipe(client_to_server)); - - /* Create a child process */ - pid = fork(); - if (pid == 0) { - /* This is the child process, close the read end of the pipe */ - EXPECT_SUCCESS(close(client_to_server[0])); - EXPECT_SUCCESS(close(server_to_client[1])); - - /* Clients ALPN preferences match our preferences, so we pick the - * most preferred server one */ - mock_client(client_to_server[1], server_to_client[0], protocols, protocols_size, protocols[0]); - } - - /* This is the parent */ - EXPECT_SUCCESS(close(client_to_server[1])); - EXPECT_SUCCESS(close(server_to_client[0])); - - EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); - conn->server_protocol_version = S2N_TLS12; - conn->client_protocol_version = S2N_TLS12; - conn->actual_protocol_version = S2N_TLS12; - EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); - - /* Set up the connection to read from the fd */ - EXPECT_SUCCESS(s2n_connection_set_read_fd(conn, client_to_server[0])); - EXPECT_SUCCESS(s2n_connection_set_write_fd(conn, server_to_client[1])); - - /* Negotiate the handshake. */ - EXPECT_SUCCESS(s2n_negotiate(conn, &blocked)); - - /* Expect our most preferred negotiated protocol */ - EXPECT_STRING_EQUAL(s2n_get_application_protocol(conn), protocols[0]); - - for (int i = 1; i < 0xffff; i += 100) { - char *ptr = buffer; - int size = i; - - do { - int bytes_read = 0; - EXPECT_SUCCESS(bytes_read = s2n_recv(conn, ptr, size, &blocked)); - - size -= bytes_read; - ptr += bytes_read; - } while (size); - - for (int j = 0; j < i; j++) { - EXPECT_EQUAL(buffer[j], 33); - } - } - - EXPECT_SUCCESS(s2n_shutdown(conn, &blocked)); - EXPECT_SUCCESS(s2n_connection_free(conn)); - - /* Clean up */ - EXPECT_EQUAL(waitpid(-1, &status, 0), pid); - EXPECT_EQUAL(status, 0); - - /* Test a lower preferred matching ALPN request */ - /* Create a pipe */ - EXPECT_SUCCESS(pipe(server_to_client)); - EXPECT_SUCCESS(pipe(client_to_server)); - - /* Create a child process */ - pid = fork(); - if (pid == 0) { - /* This is the child process, close the read end of the pipe */ - EXPECT_SUCCESS(close(client_to_server[0])); - EXPECT_SUCCESS(close(server_to_client[1])); - - /* Client only advertises our second choice, so we should negotiate it */ - mock_client(client_to_server[1], server_to_client[0], &protocols[1], 1, protocols[1]); - } - - /* This is the parent */ - EXPECT_SUCCESS(close(client_to_server[1])); - EXPECT_SUCCESS(close(server_to_client[0])); - - EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); - conn->server_protocol_version = S2N_TLS12; - conn->client_protocol_version = S2N_TLS12; - conn->actual_protocol_version = S2N_TLS12; - EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); - - /* Set up the connection to read from the fd */ - EXPECT_SUCCESS(s2n_connection_set_read_fd(conn, client_to_server[0])); - EXPECT_SUCCESS(s2n_connection_set_write_fd(conn, server_to_client[1])); - - /* Negotiate the handshake. */ - - EXPECT_SUCCESS(s2n_negotiate(conn, &blocked)); - - for (int i = 1; i < 0xffff; i += 100) { - char *ptr = buffer; - int size = i; - - do { - int bytes_read = 0; - EXPECT_SUCCESS(bytes_read = s2n_recv(conn, ptr, size, &blocked)); - - size -= bytes_read; - ptr += bytes_read; - } while (size); - - for (int j = 0; j < i; j++) { - EXPECT_EQUAL(buffer[j], 33); + DEFER_CLEANUP(struct s2n_config *server_config = s2n_config_new(), s2n_config_ptr_free); + EXPECT_NOT_NULL(server_config); + EXPECT_SUCCESS(s2n_config_set_protocol_preferences(server_config, protocols, + s2n_array_len(protocols))); + EXPECT_SUCCESS(s2n_config_set_cipher_preferences(server_config, "default")); + + DEFER_CLEANUP(struct s2n_cert_chain_and_key *chain_and_key = NULL, + s2n_cert_chain_and_key_ptr_free); + EXPECT_SUCCESS(s2n_test_cert_chain_and_key_new(&chain_and_key, S2N_DEFAULT_TEST_CERT_CHAIN, + S2N_DEFAULT_TEST_PRIVATE_KEY)); + EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(server_config, chain_and_key)); + + struct { + int client_protocol_count; + const char *const *client_protocols; + const char *expected_protocol; + } test_cases[] = { + /* Test no client ALPN request */ + { + .client_protocol_count = 0, + .client_protocols = NULL, + .expected_protocol = NULL, + }, + /* Test a matching ALPN request */ + { + .client_protocol_count = s2n_array_len(protocols), + .client_protocols = protocols, + .expected_protocol = protocols[0], + }, + /* Test a lower preferred matching ALPN request */ + { + .client_protocol_count = 1, + .client_protocols = &protocols[1], + .expected_protocol = protocols[1], + }, + /* Test a non-matching ALPN request */ + { + .client_protocol_count = 1, + .client_protocols = mismatch_protocols, + .expected_protocol = NULL, + }, + }; + + for (size_t i = 0; i < s2n_array_len(test_cases); i++) { + DEFER_CLEANUP(struct s2n_config *client_config = s2n_config_new(), s2n_config_ptr_free); + EXPECT_NOT_NULL(client_config); + EXPECT_SUCCESS(s2n_config_set_protocol_preferences(client_config, + test_cases[i].client_protocols, test_cases[i].client_protocol_count)); + EXPECT_SUCCESS(s2n_config_disable_x509_verification(client_config)); + + DEFER_CLEANUP(struct s2n_connection *client = s2n_connection_new(S2N_CLIENT), + s2n_connection_ptr_free); + EXPECT_NOT_NULL(client); + EXPECT_SUCCESS(s2n_connection_set_config(client, client_config)); + + DEFER_CLEANUP(struct s2n_connection *server = s2n_connection_new(S2N_SERVER), + s2n_connection_ptr_free); + EXPECT_NOT_NULL(server); + EXPECT_SUCCESS(s2n_connection_set_config(server, server_config)); + + 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)); + EXPECT_OK(s2n_connections_set_io_stuffer_pair(client, server, &io_pair)); + + EXPECT_SUCCESS(s2n_negotiate_test_server_and_client(server, client)); + + if (test_cases[i].expected_protocol == NULL) { + EXPECT_NULL(s2n_get_application_protocol(server)); + } else { + EXPECT_STRING_EQUAL(s2n_get_application_protocol(server), + test_cases[i].expected_protocol); } - } - - /* Expect our least preferred negotiated protocol */ - EXPECT_STRING_EQUAL(s2n_get_application_protocol(conn), protocols[1]); - - EXPECT_SUCCESS(s2n_shutdown(conn, &blocked)); - EXPECT_SUCCESS(s2n_connection_free(conn)); - - /* Clean up */ - EXPECT_EQUAL(waitpid(-1, &status, 0), pid); - EXPECT_EQUAL(status, 0); - /* Test a non-matching ALPN request */ - /* Create a pipe */ - EXPECT_SUCCESS(pipe(server_to_client)); - EXPECT_SUCCESS(pipe(client_to_server)); - - /* Create a child process */ - pid = fork(); - if (pid == 0) { - /* This is the child process, close the read end of the pipe */ - EXPECT_SUCCESS(close(client_to_server[0])); - EXPECT_SUCCESS(close(server_to_client[1])); - - /* Client doesn't support any of our protocols, so we shouldn't complete - * the handshake */ - mock_client(client_to_server[1], server_to_client[0], mismatch_protocols, 1, NULL); + /* application data can be sent */ + s2n_blocked_status blocked = S2N_NOT_BLOCKED; + uint8_t data_send[TEST_DATA_SIZE] = { 3, 1, 4, 1, 5, 9, 2, 6 }; + uint8_t data_recv[TEST_DATA_SIZE] = { 0 }; + EXPECT_EQUAL(s2n_send(client, data_send, sizeof(data_send), &blocked), sizeof(data_send)); + EXPECT_EQUAL(s2n_recv(server, data_recv, sizeof(data_recv), &blocked), sizeof(data_recv)); + EXPECT_BYTEARRAY_EQUAL(data_send, data_recv, sizeof(data_send)); } - /* This is the parent */ - EXPECT_SUCCESS(close(client_to_server[1])); - EXPECT_SUCCESS(close(server_to_client[0])); - - EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); - conn->server_protocol_version = S2N_TLS12; - conn->client_protocol_version = S2N_TLS12; - conn->actual_protocol_version = S2N_TLS12; - EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); - - /* Set up the connection to read from the fd */ - EXPECT_SUCCESS(s2n_connection_set_read_fd(conn, client_to_server[0])); - EXPECT_SUCCESS(s2n_connection_set_write_fd(conn, server_to_client[1])); - - /* Negotiate the handshake. */ - EXPECT_SUCCESS(s2n_negotiate(conn, &blocked)); - - /* Expect NULL negotiated protocol */ - EXPECT_EQUAL(s2n_get_application_protocol(conn), NULL); - - /* Negotiation failed. Free the connection without shutdown */ - EXPECT_SUCCESS(s2n_connection_free(conn)); - - /* Close the pipes */ - EXPECT_SUCCESS(close(client_to_server[0])); - EXPECT_SUCCESS(close(server_to_client[1])); - - /* Clean up */ - EXPECT_EQUAL(waitpid(-1, &status, 0), pid); - EXPECT_NOT_EQUAL(status, 0); - /* Test a connection level application protocol */ - /* Create a pipe */ - EXPECT_SUCCESS(pipe(server_to_client)); - EXPECT_SUCCESS(pipe(client_to_server)); - - /* Create a child process */ - pid = fork(); - if (pid == 0) { - /* This is the child process, close the read end of the pipe */ - EXPECT_SUCCESS(close(client_to_server[0])); - EXPECT_SUCCESS(close(server_to_client[1])); - - /* Client config support all protocols, expect http 2 after negotiation */ - mock_client(client_to_server[1], server_to_client[0], protocols, protocols_size, protocols[2]); + { + DEFER_CLEANUP(struct s2n_config *client_config = s2n_config_new(), s2n_config_ptr_free); + EXPECT_NOT_NULL(client_config); + EXPECT_SUCCESS(s2n_config_set_protocol_preferences(client_config, protocols, + s2n_array_len(protocols))); + EXPECT_SUCCESS(s2n_config_disable_x509_verification(client_config)); + + DEFER_CLEANUP(struct s2n_connection *client = s2n_connection_new(S2N_CLIENT), + s2n_connection_ptr_free); + EXPECT_NOT_NULL(client); + EXPECT_SUCCESS(s2n_connection_set_config(client, client_config)); + + DEFER_CLEANUP(struct s2n_connection *server = s2n_connection_new(S2N_SERVER), + s2n_connection_ptr_free); + EXPECT_NOT_NULL(server); + EXPECT_SUCCESS(s2n_connection_set_config(server, server_config)); + + /* override the server (connection) preferences to only contain h2 */ + EXPECT_SUCCESS(s2n_connection_set_protocol_preferences(server, &protocols[2], 1)); + + 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)); + EXPECT_OK(s2n_connections_set_io_stuffer_pair(client, server, &io_pair)); + + EXPECT_SUCCESS(s2n_negotiate_test_server_and_client(server, client)); + + /* despite being least preferred for the server_config and client, the + * connection override correctly caused h2 to be negotiated + */ + EXPECT_STRING_EQUAL(s2n_get_application_protocol(server), protocols[2]); } - /* This is the parent */ - EXPECT_SUCCESS(close(client_to_server[1])); - EXPECT_SUCCESS(close(server_to_client[0])); - - EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); - conn->server_protocol_version = S2N_TLS12; - conn->client_protocol_version = S2N_TLS12; - conn->actual_protocol_version = S2N_TLS12; - EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); - - /* Set up the connection to read from the fd */ - EXPECT_SUCCESS(s2n_connection_set_read_fd(conn, client_to_server[0])); - EXPECT_SUCCESS(s2n_connection_set_write_fd(conn, server_to_client[1])); - - /* Override connection protocol to http 2 */ - EXPECT_SUCCESS(s2n_connection_set_protocol_preferences(conn, &protocols[2], 1)); - /* Negotiate the handshake. */ - EXPECT_SUCCESS(s2n_negotiate(conn, &blocked)); - - EXPECT_STRING_EQUAL(s2n_get_application_protocol(conn), protocols[2]); - /* Negotiation failed. Free the connection without shutdown */ - EXPECT_SUCCESS(s2n_connection_free(conn)); - - /* Close the pipes */ - EXPECT_SUCCESS(close(client_to_server[0])); - EXPECT_SUCCESS(close(server_to_client[1])); - - /* Clean up */ - EXPECT_EQUAL(waitpid(-1, &status, 0), pid); - EXPECT_NOT_EQUAL(status, 0); - - EXPECT_SUCCESS(s2n_config_free(config)); - EXPECT_SUCCESS(s2n_cert_chain_and_key_free(chain_and_key)); - free(cert_chain_pem); - free(private_key_pem); - free(dhparams_pem); END_TEST(); return 0; diff --git a/tests/unit/s2n_self_talk_broken_pipe_test.c b/tests/unit/s2n_self_talk_broken_pipe_test.c index 6469a431ca2..2303b9230da 100644 --- a/tests/unit/s2n_self_talk_broken_pipe_test.c +++ b/tests/unit/s2n_self_talk_broken_pipe_test.c @@ -32,8 +32,8 @@ static const char *private_key_paths[SUPPORTED_CERTIFICATE_FORMATS] = { S2N_RSA_ void mock_client(struct s2n_test_io_pair *io_pair) { - struct s2n_connection *conn; - struct s2n_config *config; + struct s2n_connection *conn = NULL; + struct s2n_config *config = NULL; s2n_blocked_status blocked; /* Give the server a chance to listen */ @@ -88,11 +88,10 @@ void mock_client(struct s2n_test_io_pair *io_pair) int main(int argc, char **argv) { - struct s2n_connection *conn; - struct s2n_config *config; + struct s2n_connection *conn = NULL; + struct s2n_config *config = NULL; s2n_blocked_status blocked; - int status; - pid_t pid; + int status = 0; char cert_chain_pem[S2N_MAX_TEST_PEM_SIZE]; char private_key_pem[S2N_MAX_TEST_PEM_SIZE]; char dhparams_pem[S2N_MAX_TEST_PEM_SIZE]; @@ -107,7 +106,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_io_pair_init(&io_pair)); /* Create a child process */ - pid = fork(); + pid_t pid = fork(); if (pid == 0) { /* This is the client process, close the server end of the pipe */ EXPECT_SUCCESS(s2n_io_pair_close_one_end(&io_pair, S2N_SERVER)); diff --git a/tests/unit/s2n_self_talk_client_hello_cb_test.c b/tests/unit/s2n_self_talk_client_hello_cb_test.c index d52ab587825..e63d1d80a59 100644 --- a/tests/unit/s2n_self_talk_client_hello_cb_test.c +++ b/tests/unit/s2n_self_talk_client_hello_cb_test.c @@ -41,8 +41,8 @@ struct client_hello_context { int mock_client(struct s2n_test_io_pair *io_pair, int expect_failure, int expect_server_name_used) { - struct s2n_connection *conn; - struct s2n_config *config; + struct s2n_connection *conn = NULL; + struct s2n_config *config = NULL; s2n_blocked_status blocked; int result = 0; int rc = 0; @@ -106,10 +106,10 @@ int mock_client(struct s2n_test_io_pair *io_pair, int expect_failure, int expect int client_hello_swap_config(struct s2n_connection *conn, void *ctx) { - struct client_hello_context *client_hello_ctx; + struct client_hello_context *client_hello_ctx = NULL; struct s2n_client_hello *client_hello = s2n_connection_get_client_hello(conn); const char *sent_server_name = "example.com"; - const char *received_server_name; + const char *received_server_name = NULL; if (ctx == NULL) { return -1; } @@ -168,7 +168,7 @@ int client_hello_swap_config(struct s2n_connection *conn, void *ctx) int client_hello_fail_handshake(struct s2n_connection *conn, void *ctx) { - struct client_hello_context *client_hello_ctx; + struct client_hello_context *client_hello_ctx = NULL; if (ctx == NULL) { return -1; @@ -281,7 +281,7 @@ static int test_case_clean(struct s2n_connection *conn, pid_t client_pid, struct client_hello_context *ch_ctx, struct s2n_cert_chain_and_key *chain_and_key) { s2n_blocked_status blocked; - int status; + int status = 0; EXPECT_SUCCESS(s2n_shutdown(conn, &blocked)); EXPECT_EQUAL(waitpid(-1, &status, 0), client_pid); @@ -301,11 +301,11 @@ int run_test_config_swap_ch_cb(s2n_client_hello_cb_mode cb_mode, struct client_hello_context *ch_ctx) { struct s2n_test_io_pair io_pair; - struct s2n_config *config; - struct s2n_connection *conn; - struct s2n_config *swap_config; - pid_t pid; - struct s2n_cert_chain_and_key *chain_and_key; + struct s2n_config *config = NULL; + struct s2n_connection *conn = NULL; + struct s2n_config *swap_config = NULL; + pid_t pid = 0; + struct s2n_cert_chain_and_key *chain_and_key = NULL; EXPECT_SUCCESS(start_client_conn(&io_pair, &pid, 0, 1)); @@ -359,10 +359,10 @@ int run_test_config_swap_ch_cb(s2n_client_hello_cb_mode cb_mode, int run_test_no_config_swap_ch_cb(s2n_client_hello_cb_mode cb_mode, struct client_hello_context *ch_ctx) { struct s2n_test_io_pair io_pair; - struct s2n_config *config; - struct s2n_connection *conn; - pid_t pid; - struct s2n_cert_chain_and_key *chain_and_key; + struct s2n_config *config = NULL; + struct s2n_connection *conn = NULL; + pid_t pid = 0; + struct s2n_cert_chain_and_key *chain_and_key = NULL; EXPECT_SUCCESS(start_client_conn(&io_pair, &pid, 0, 0)); @@ -396,11 +396,11 @@ int run_test_no_config_swap_ch_cb(s2n_client_hello_cb_mode cb_mode, struct clien int run_test_reject_handshake_ch_cb(s2n_client_hello_cb_mode cb_mode, struct client_hello_context *ch_ctx) { struct s2n_test_io_pair io_pair; - struct s2n_config *config; - struct s2n_connection *conn; - pid_t pid; + struct s2n_config *config = NULL; + struct s2n_connection *conn = NULL; + pid_t pid = 0; s2n_blocked_status blocked; - struct s2n_cert_chain_and_key *chain_and_key; + struct s2n_cert_chain_and_key *chain_and_key = NULL; EXPECT_SUCCESS(start_client_conn(&io_pair, &pid, 1, 0)); diff --git a/tests/unit/s2n_self_talk_custom_io_test.c b/tests/unit/s2n_self_talk_custom_io_test.c index d57894465e8..0ed66e0a20f 100644 --- a/tests/unit/s2n_self_talk_custom_io_test.c +++ b/tests/unit/s2n_self_talk_custom_io_test.c @@ -31,8 +31,8 @@ int mock_client(struct s2n_test_io_pair *io_pair) { - struct s2n_connection *conn; - struct s2n_config *client_config; + struct s2n_connection *conn = NULL; + struct s2n_config *client_config = NULL; s2n_blocked_status blocked; int result = 0; @@ -69,11 +69,11 @@ int main(int argc, char **argv) */ { s2n_blocked_status blocked; - int status; - pid_t pid; - char *cert_chain_pem; - char *private_key_pem; - char *dhparams_pem; + int status = 0; + pid_t pid = 0; + char *cert_chain_pem = NULL; + char *private_key_pem = NULL; + char *dhparams_pem = NULL; /* For convenience, this test will intentionally try to write to closed pipes during shutdown. Ignore the signal to * avoid exiting the process on SIGPIPE. @@ -131,7 +131,7 @@ int main(int argc, char **argv) /* Negotiate the handshake. */ do { - int ret; + int ret = 0; ret = s2n_negotiate(conn, &blocked); EXPECT_TRUE(ret == 0 || (blocked && (errno == EAGAIN || errno == EWOULDBLOCK))); @@ -146,7 +146,7 @@ int main(int argc, char **argv) /* Shutdown after negotiating */ uint8_t server_shutdown = 0; do { - int ret; + int ret = 0; ret = s2n_shutdown(conn, &blocked); EXPECT_TRUE(ret == 0 || (blocked && (errno == EAGAIN || errno == EWOULDBLOCK))); diff --git a/tests/unit/s2n_self_talk_io_mem_test.c b/tests/unit/s2n_self_talk_io_mem_test.c index a38c89e6955..2453150b03c 100644 --- a/tests/unit/s2n_self_talk_io_mem_test.c +++ b/tests/unit/s2n_self_talk_io_mem_test.c @@ -33,7 +33,7 @@ int main(int argc, char **argv) END_TEST(); } - struct s2n_cert_chain_and_key *chain_and_key; + struct s2n_cert_chain_and_key *chain_and_key = NULL; EXPECT_SUCCESS(s2n_test_cert_chain_and_key_new(&chain_and_key, S2N_DEFAULT_ECDSA_TEST_CERT_CHAIN, S2N_DEFAULT_ECDSA_TEST_PRIVATE_KEY)); diff --git a/tests/unit/s2n_self_talk_key_log_test.c b/tests/unit/s2n_self_talk_key_log_test.c index 319d7d6dcf7..9712b05a49e 100644 --- a/tests/unit/s2n_self_talk_key_log_test.c +++ b/tests/unit/s2n_self_talk_key_log_test.c @@ -67,15 +67,15 @@ int main(int argc, char **argv) /* TLS 1.2 */ { /* Setup connections */ - struct s2n_connection *client_conn, *server_conn; + struct s2n_connection *client_conn = NULL, *server_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); /* Setup config */ - struct s2n_cert_chain_and_key *chain_and_key; + struct s2n_cert_chain_and_key *chain_and_key = NULL; EXPECT_SUCCESS(s2n_test_cert_chain_and_key_new(&chain_and_key, S2N_DEFAULT_TEST_CERT_CHAIN, S2N_DEFAULT_TEST_PRIVATE_KEY)); - struct s2n_config *client_config; + struct s2n_config *client_config = NULL; EXPECT_NOT_NULL(client_config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_set_cipher_preferences(client_config, "default")); EXPECT_SUCCESS(s2n_config_set_unsafe_for_testing(client_config)); @@ -85,7 +85,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_config_set_key_log_cb(client_config, s2n_test_key_log_cb, &client_key_log)); EXPECT_SUCCESS(s2n_connection_set_config(client_conn, client_config)); - struct s2n_config *server_config; + struct s2n_config *server_config = NULL; EXPECT_NOT_NULL(server_config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_set_cipher_preferences(server_config, "default")); EXPECT_SUCCESS(s2n_config_set_unsafe_for_testing(server_config)); @@ -118,15 +118,15 @@ int main(int argc, char **argv) /* TLS 1.3 */ if (s2n_is_tls13_fully_supported()) { /* Setup connections */ - struct s2n_connection *client_conn, *server_conn; + struct s2n_connection *client_conn = NULL, *server_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); /* Setup config */ - struct s2n_cert_chain_and_key *chain_and_key; + struct s2n_cert_chain_and_key *chain_and_key = NULL; EXPECT_SUCCESS(s2n_test_cert_chain_and_key_new(&chain_and_key, S2N_DEFAULT_ECDSA_TEST_CERT_CHAIN, S2N_DEFAULT_ECDSA_TEST_PRIVATE_KEY)); - struct s2n_config *client_config; + struct s2n_config *client_config = NULL; EXPECT_NOT_NULL(client_config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_set_cipher_preferences(client_config, "default_tls13")); EXPECT_SUCCESS(s2n_config_set_unsafe_for_testing(client_config)); @@ -136,7 +136,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_config_set_key_log_cb(client_config, s2n_test_key_log_cb, &client_key_log)); EXPECT_SUCCESS(s2n_connection_set_config(client_conn, client_config)); - struct s2n_config *server_config; + struct s2n_config *server_config = NULL; EXPECT_NOT_NULL(server_config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_set_cipher_preferences(server_config, "default_tls13")); EXPECT_SUCCESS(s2n_config_set_unsafe_for_testing(server_config)); diff --git a/tests/unit/s2n_self_talk_min_protocol_version_test.c b/tests/unit/s2n_self_talk_min_protocol_version_test.c index eea38f7d872..4e0f2ecfa38 100644 --- a/tests/unit/s2n_self_talk_min_protocol_version_test.c +++ b/tests/unit/s2n_self_talk_min_protocol_version_test.c @@ -26,8 +26,8 @@ int mock_client(struct s2n_test_io_pair *io_pair, uint8_t version) { - struct s2n_connection *client_conn; - struct s2n_config *client_config; + struct s2n_connection *client_conn = NULL; + struct s2n_config *client_config = NULL; s2n_blocked_status blocked; int result = 0; @@ -63,8 +63,7 @@ int mock_client(struct s2n_test_io_pair *io_pair, uint8_t version) int main(int argc, char **argv) { s2n_blocked_status blocked; - int status; - pid_t pid; + int status = 0; char cert_chain_pem[S2N_MAX_TEST_PEM_SIZE]; char private_key_pem[S2N_MAX_TEST_PEM_SIZE]; @@ -82,7 +81,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_io_pair_init(&io_pair)); /* Create a child process */ - pid = fork(); + pid_t pid = fork(); if (pid == 0) { /* This is the client process, close the server end of the pipe */ EXPECT_SUCCESS(s2n_io_pair_close_one_end(&io_pair, S2N_SERVER)); diff --git a/tests/unit/s2n_self_talk_nonblocking_test.c b/tests/unit/s2n_self_talk_nonblocking_test.c index 0246eab38f9..ccc1ceee63e 100644 --- a/tests/unit/s2n_self_talk_nonblocking_test.c +++ b/tests/unit/s2n_self_talk_nonblocking_test.c @@ -35,8 +35,8 @@ int mock_client(struct s2n_test_io_pair *io_pair, uint8_t *expected_data, uint32 { uint8_t *buffer = malloc(size); uint8_t *ptr = buffer; - struct s2n_connection *client_conn; - struct s2n_config *client_config; + struct s2n_connection *client_conn = NULL; + struct s2n_config *client_config = NULL; s2n_blocked_status blocked; int result = 0; /* If something goes wrong, and the server never finishes sending, @@ -97,11 +97,11 @@ int mock_client(struct s2n_test_io_pair *io_pair, uint8_t *expected_data, uint32 int mock_client_iov(struct s2n_test_io_pair *io_pair, struct iovec *iov, uint32_t iov_size) { - struct s2n_connection *client_conn; - struct s2n_config *client_config; + struct s2n_connection *client_conn = NULL; + struct s2n_config *client_config = NULL; s2n_blocked_status blocked; int result = 0; - int total_size = 0, i; + int total_size = 0, i = 0; int should_block = 1; for (i = 0; i < iov_size; i++) { @@ -190,8 +190,8 @@ S2N_RESULT cleanup_io_data(struct iovec **iov, int iov_size, struct s2n_blob *bl int test_send(int use_tls13, int use_iov, int prefer_throughput) { s2n_blocked_status blocked; - int status; - pid_t pid; + int status = 0; + pid_t pid = 0; char cert_chain_pem[S2N_MAX_TEST_PEM_SIZE]; char private_key_pem[S2N_MAX_TEST_PEM_SIZE]; char dhparams_pem[S2N_MAX_TEST_PEM_SIZE]; @@ -221,7 +221,7 @@ int test_send(int use_tls13, int use_iov, int prefer_throughput) struct iovec *iov = NULL; if (!use_iov) { data_size = 10000000; - s2n_alloc(&blob, data_size); + EXPECT_SUCCESS(s2n_alloc(&blob, data_size)); EXPECT_OK(s2n_get_public_random_data(&blob)); } else { iov = malloc(sizeof(*iov) * iov_size); diff --git a/tests/unit/s2n_self_talk_quic_support_test.c b/tests/unit/s2n_self_talk_quic_support_test.c index 7099cadc7af..ef837544420 100644 --- a/tests/unit/s2n_self_talk_quic_support_test.c +++ b/tests/unit/s2n_self_talk_quic_support_test.c @@ -50,15 +50,15 @@ int main(int argc, char **argv) uint16_t transport_params_len = 0; /* Setup connections */ - struct s2n_connection *client_conn, *server_conn; + struct s2n_connection *client_conn = NULL, *server_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); /* Setup config */ - struct s2n_cert_chain_and_key *chain_and_key; + struct s2n_cert_chain_and_key *chain_and_key = NULL; EXPECT_SUCCESS(s2n_test_cert_chain_and_key_new(&chain_and_key, S2N_DEFAULT_ECDSA_TEST_CERT_CHAIN, S2N_DEFAULT_ECDSA_TEST_PRIVATE_KEY)); - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_set_cipher_preferences(config, "default_tls13")); EXPECT_SUCCESS(s2n_config_set_unsafe_for_testing(config)); diff --git a/tests/unit/s2n_self_talk_session_id_test.c b/tests/unit/s2n_self_talk_session_id_test.c index 4d5995a3e96..f4991cbb8dc 100644 --- a/tests/unit/s2n_self_talk_session_id_test.c +++ b/tests/unit/s2n_self_talk_session_id_test.c @@ -142,8 +142,8 @@ void mock_client(struct s2n_test_io_pair *io_pair) size_t serialized_session_state_length = 0; uint8_t serialized_session_state[256] = { 0 }; - struct s2n_connection *conn; - struct s2n_config *config; + struct s2n_connection *conn = NULL; + struct s2n_config *config = NULL; s2n_blocked_status blocked; int result = 0; @@ -288,18 +288,18 @@ void mock_client(struct s2n_test_io_pair *io_pair) int main(int argc, char **argv) { - struct s2n_connection *conn; - struct s2n_config *config; + struct s2n_connection *conn = NULL; + struct s2n_config *config = NULL; s2n_blocked_status blocked; - int status; - pid_t pid; - char *cert_chain_pem; - char *private_key_pem; - struct s2n_cert_chain_and_key *chain_and_key; + int status = 0; + pid_t pid = 0; + char *cert_chain_pem = NULL; + char *private_key_pem = NULL; + struct s2n_cert_chain_and_key *chain_and_key = NULL; char buffer[256]; - int bytes_read; + int bytes_read = 0; int shutdown_rc = -1; - uint64_t now; + uint64_t now = 0; uint8_t session_id_from_server[MAX_KEY_LEN]; uint8_t session_id_from_client[MAX_KEY_LEN]; diff --git a/tests/unit/s2n_self_talk_tls12_test.c b/tests/unit/s2n_self_talk_tls12_test.c index d737b07fd89..89c07c6b0b5 100644 --- a/tests/unit/s2n_self_talk_tls12_test.c +++ b/tests/unit/s2n_self_talk_tls12_test.c @@ -32,8 +32,8 @@ static const char *private_key_paths[SUPPORTED_CERTIFICATE_FORMATS] = { S2N_RSA_ void mock_client(struct s2n_test_io_pair *io_pair) { char buffer[0xffff]; - struct s2n_connection *conn; - struct s2n_config *config; + struct s2n_connection *conn = NULL; + struct s2n_config *config = NULL; s2n_blocked_status blocked; /* Give the server a chance to listen */ @@ -52,7 +52,7 @@ void mock_client(struct s2n_test_io_pair *io_pair) uint16_t timeout = 1; s2n_connection_set_dynamic_record_threshold(conn, 0x7fff, timeout); - int i; + int i = 0; for (i = 1; i < 0xffff - 100; i += 100) { for (int j = 0; j < i; j++) { buffer[j] = 33; @@ -69,7 +69,7 @@ void mock_client(struct s2n_test_io_pair *io_pair) /* Simulate timeout second conneciton inactivity and tolerate 50 ms error */ struct timespec sleep_time = { .tv_sec = timeout, .tv_nsec = 50000000 }; - int r; + int r = 0; do { r = nanosleep(&sleep_time, &sleep_time); } while (r != 0); @@ -98,14 +98,13 @@ void mock_client(struct s2n_test_io_pair *io_pair) int main(int argc, char **argv) { - struct s2n_connection *conn; - struct s2n_config *config; + struct s2n_connection *conn = NULL; + struct s2n_config *config = NULL; s2n_blocked_status blocked; - int status; - pid_t pid; - char *cert_chain_pem; - char *private_key_pem; - char *dhparams_pem; + int status = 0; + char *cert_chain_pem = NULL; + char *private_key_pem = NULL; + char *dhparams_pem = NULL; BEGIN_TEST(); EXPECT_SUCCESS(s2n_disable_tls13_in_test()); @@ -117,7 +116,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_io_pair_init(&io_pair)); /* Create a child process */ - pid = fork(); + pid_t pid = fork(); if (pid == 0) { /* This is the client process, close the server end of the pipe */ EXPECT_SUCCESS(s2n_io_pair_close_one_end(&io_pair, S2N_SERVER)); diff --git a/tests/unit/s2n_self_talk_tls13_test.c b/tests/unit/s2n_self_talk_tls13_test.c index 94e8e3b1b75..e4b725c032f 100644 --- a/tests/unit/s2n_self_talk_tls13_test.c +++ b/tests/unit/s2n_self_talk_tls13_test.c @@ -50,7 +50,7 @@ void mock_client(struct s2n_test_io_pair *io_pair) uint16_t timeout = 1; s2n_connection_set_dynamic_record_threshold(conn, 0x7fff, timeout); - int i; + int i = 0; for (i = 1; i < 0xffff - 100; i += 100) { for (int j = 0; j < i; j++) { buffer[j] = 33; @@ -67,7 +67,7 @@ void mock_client(struct s2n_test_io_pair *io_pair) /* Simulate timeout second conneciton inactivity and tolerate 50 ms error */ struct timespec sleep_time = { .tv_sec = timeout, .tv_nsec = 50000000 }; - int r; + int r = 0; do { r = nanosleep(&sleep_time, &sleep_time); } while (r != 0); @@ -99,8 +99,8 @@ int main(int argc, char **argv) struct s2n_connection *conn = NULL; struct s2n_config *config = NULL; s2n_blocked_status blocked; - int status; - pid_t pid; + int status = 0; + pid_t pid = 0; BEGIN_TEST(); @@ -123,7 +123,7 @@ int main(int argc, char **argv) EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); - struct s2n_cert_chain_and_key *chain_and_key; + struct s2n_cert_chain_and_key *chain_and_key = NULL; EXPECT_SUCCESS(s2n_test_cert_chain_and_key_new(&chain_and_key, S2N_DEFAULT_ECDSA_TEST_CERT_CHAIN, S2N_DEFAULT_ECDSA_TEST_PRIVATE_KEY)); diff --git a/tests/unit/s2n_send_key_update_test.c b/tests/unit/s2n_send_key_update_test.c index e17f20d38af..436356e52ca 100644 --- a/tests/unit/s2n_send_key_update_test.c +++ b/tests/unit/s2n_send_key_update_test.c @@ -78,8 +78,8 @@ int main(int argc, char **argv) /* s2n_send sends key update if necessary */ { - struct s2n_connection *server_conn; - struct s2n_connection *client_conn; + struct s2n_connection *server_conn = NULL; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); server_conn->actual_protocol_version = S2N_TLS13; @@ -127,21 +127,21 @@ int main(int argc, char **argv) { EXPECT_SUCCESS(s2n_disable_tls13_in_test()); - char *cert_chain; - char *private_key; + char *cert_chain = NULL; + char *private_key = NULL; EXPECT_NOT_NULL(cert_chain = malloc(S2N_MAX_TEST_PEM_SIZE)); EXPECT_NOT_NULL(private_key = malloc(S2N_MAX_TEST_PEM_SIZE)); EXPECT_SUCCESS(setenv("S2N_DONT_MLOCK", "1", 0)); struct s2n_test_io_pair io_pair; EXPECT_SUCCESS(s2n_io_pair_init_non_blocking(&io_pair)); - struct s2n_connection *client_conn; - struct s2n_connection *server_conn; - struct s2n_config *server_config; - struct s2n_cert_chain_and_key *chain_and_key; + struct s2n_connection *client_conn = NULL; + struct s2n_connection *server_conn = NULL; + struct s2n_config *server_config = NULL; + struct s2n_cert_chain_and_key *chain_and_key = NULL; s2n_blocked_status blocked = S2N_NOT_BLOCKED; - struct s2n_config *client_config; + struct s2n_config *client_config = NULL; EXPECT_NOT_NULL(client_config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_set_check_stapled_ocsp_response(client_config, 0)); EXPECT_SUCCESS(s2n_config_disable_x509_verification(client_config)); diff --git a/tests/unit/s2n_server_alpn_extension_test.c b/tests/unit/s2n_server_alpn_extension_test.c index 4d35eaabdb3..56dfe98f1b1 100644 --- a/tests/unit/s2n_server_alpn_extension_test.c +++ b/tests/unit/s2n_server_alpn_extension_test.c @@ -27,7 +27,7 @@ int main(int argc, char **argv) /* Test should_send */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); /* Should not send if protocol not set. Protocol not set by default. */ @@ -42,7 +42,7 @@ int main(int argc, char **argv) /* Test send */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_MEMCPY_SUCCESS(conn->application_protocol, test_protocol_name, test_protocol_name_size); @@ -52,18 +52,18 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_server_alpn_extension.send(conn, &stuffer)); /* Should have correct total size */ - uint16_t protocol_name_list_size; + uint16_t protocol_name_list_size = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint16(&stuffer, &protocol_name_list_size)); EXPECT_EQUAL(protocol_name_list_size, s2n_stuffer_data_available(&stuffer)); /* Should have correct protocol name size */ - uint8_t protocol_name_size; + uint8_t protocol_name_size = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint8(&stuffer, &protocol_name_size)); EXPECT_EQUAL(protocol_name_size, s2n_stuffer_data_available(&stuffer)); EXPECT_EQUAL(protocol_name_size, test_protocol_name_size); /* Should have correct protocol name */ - uint8_t *protocol_name; + uint8_t *protocol_name = NULL; EXPECT_NOT_NULL(protocol_name = s2n_stuffer_raw_read(&stuffer, protocol_name_size)); EXPECT_BYTEARRAY_EQUAL(protocol_name, test_protocol_name, test_protocol_name_size); @@ -73,13 +73,13 @@ int main(int argc, char **argv) /* Test recv */ { - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_MEMCPY_SUCCESS(server_conn->application_protocol, test_protocol_name, test_protocol_name_size); /* Should accept extension written by send */ { - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); struct s2n_stuffer stuffer = { 0 }; @@ -100,7 +100,7 @@ int main(int argc, char **argv) /* Should ignore extension if protocol name list size incorrect */ { - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); struct s2n_stuffer stuffer = { 0 }; diff --git a/tests/unit/s2n_server_cert_request_test.c b/tests/unit/s2n_server_cert_request_test.c index e376453e982..828eddfceb5 100644 --- a/tests/unit/s2n_server_cert_request_test.c +++ b/tests/unit/s2n_server_cert_request_test.c @@ -53,8 +53,8 @@ int main(int argc, char **argv) /* Test server cert request default behavior when s2n_config_enable_cert_req_dss_legacy_compat is not called * Certificate types enabled should be in s2n_cert_type_preference_list */ { - struct s2n_connection *server_conn; - struct s2n_config *server_config; + struct s2n_connection *server_conn = NULL; + struct s2n_config *server_config = NULL; EXPECT_NOT_NULL(server_config = s2n_config_new()); EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); @@ -62,9 +62,9 @@ int main(int argc, char **argv) s2n_cert_req_send(server_conn); struct s2n_stuffer *in = &server_conn->handshake.io; - uint8_t cert_types_len; + uint8_t cert_types_len = 0; - s2n_stuffer_read_uint8(in, &cert_types_len); + EXPECT_SUCCESS(s2n_stuffer_read_uint8(in, &cert_types_len)); uint8_t *their_cert_type_pref_list = s2n_stuffer_raw_read(in, cert_types_len); @@ -80,8 +80,8 @@ int main(int argc, char **argv) /* Test certificate types in server cert request when s2n_config_enable_cert_req_dss_legacy_compat is called * Certificate types enabled should be in s2n_cert_type_preference_list_legacy_dss */ { - struct s2n_connection *server_conn; - struct s2n_config *server_config; + struct s2n_connection *server_conn = NULL; + struct s2n_config *server_config = NULL; EXPECT_NOT_NULL(server_config = s2n_config_new()); EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); @@ -90,9 +90,9 @@ int main(int argc, char **argv) s2n_cert_req_send(server_conn); struct s2n_stuffer *in = &server_conn->handshake.io; - uint8_t cert_types_len; + uint8_t cert_types_len = 0; - s2n_stuffer_read_uint8(in, &cert_types_len); + EXPECT_SUCCESS(s2n_stuffer_read_uint8(in, &cert_types_len)); uint8_t *their_cert_type_pref_list = s2n_stuffer_raw_read(in, cert_types_len); diff --git a/tests/unit/s2n_server_extensions_test.c b/tests/unit/s2n_server_extensions_test.c index 91c101327b6..68911580cc0 100644 --- a/tests/unit/s2n_server_extensions_test.c +++ b/tests/unit/s2n_server_extensions_test.c @@ -62,19 +62,19 @@ int main(int argc, char **argv) BEGIN_TEST(); EXPECT_SUCCESS(s2n_disable_tls13_in_test()); - struct s2n_cert_chain_and_key *chain_and_key; + struct s2n_cert_chain_and_key *chain_and_key = NULL; EXPECT_SUCCESS(s2n_test_cert_chain_and_key_new(&chain_and_key, S2N_DEFAULT_TEST_CERT_CHAIN, S2N_DEFAULT_TEST_PRIVATE_KEY)); /* s2n_server_extensions_send */ { - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(config, chain_and_key)); /* Test Server Extensions Send - No extensions */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); struct s2n_stuffer *hello_stuffer = &conn->handshake.io; @@ -87,7 +87,7 @@ int main(int argc, char **argv) /* Test Server Extensions Send - Server Name */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); s2n_extension_type_id extension_id = 0; EXPECT_SUCCESS(s2n_extension_supported_iana_value_to_id(TLS_EXTENSION_SERVER_NAME, &extension_id)); @@ -121,7 +121,7 @@ int main(int argc, char **argv) /* Test Server Extensions Send - Application Protocol */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); s2n_extension_type_id extension_id = 0; EXPECT_SUCCESS(s2n_extension_supported_iana_value_to_id(TLS_EXTENSION_ALPN, &extension_id)); @@ -152,7 +152,7 @@ int main(int argc, char **argv) /* Test Server Extensions Send - Maximum Fragment Length (MFL) */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); s2n_extension_type_id extension_id = 0; EXPECT_SUCCESS(s2n_extension_supported_iana_value_to_id(TLS_EXTENSION_MAX_FRAG_LEN, &extension_id)); @@ -181,7 +181,7 @@ int main(int argc, char **argv) /* Test Server Extensions Send - Signed Certificate Timestamp extension */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); s2n_extension_type_id extension_id = 0; EXPECT_SUCCESS(s2n_extension_supported_iana_value_to_id(TLS_EXTENSION_SCT_LIST, &extension_id)); @@ -191,7 +191,7 @@ int main(int argc, char **argv) struct s2n_cert_chain_and_key fake_chain_and_key = { 0 }; static uint8_t sct_list[] = { 0xff, 0xff, 0xff }; - s2n_blob_init(&fake_chain_and_key.sct_list, sct_list, sizeof(sct_list)); + EXPECT_SUCCESS(s2n_blob_init(&fake_chain_and_key.sct_list, sct_list, sizeof(sct_list))); conn->ct_level_requested = S2N_CT_SUPPORT_REQUEST; conn->handshake_params.our_chain_and_key = &fake_chain_and_key; @@ -211,7 +211,7 @@ int main(int argc, char **argv) /* Test Server Extensions Send - OCSP Status Request */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); s2n_extension_type_id extension_id = 0; EXPECT_SUCCESS(s2n_extension_supported_iana_value_to_id(TLS_EXTENSION_STATUS_REQUEST, &extension_id)); @@ -221,7 +221,7 @@ int main(int argc, char **argv) struct s2n_cert_chain_and_key fake_chain_and_key = { 0 }; static uint8_t fake_ocsp[] = { 0xff, 0xff, 0xff }; - s2n_blob_init(&fake_chain_and_key.ocsp_status, fake_ocsp, sizeof(fake_ocsp)); + EXPECT_SUCCESS(s2n_blob_init(&fake_chain_and_key.ocsp_status, fake_ocsp, sizeof(fake_ocsp))); conn->status_type = S2N_STATUS_REQUEST_OCSP; conn->handshake_params.our_chain_and_key = &fake_chain_and_key; @@ -242,7 +242,7 @@ int main(int argc, char **argv) /* Test Server Extensions Send - Secure Negotiation */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); struct s2n_stuffer *hello_stuffer = &conn->handshake.io; @@ -259,7 +259,7 @@ int main(int argc, char **argv) /* Test Server Extensions Send - New Session Ticket */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); s2n_extension_type_id extension_id = 0; EXPECT_SUCCESS(s2n_extension_supported_iana_value_to_id(TLS_EXTENSION_SESSION_TICKET, &extension_id)); @@ -280,7 +280,7 @@ int main(int argc, char **argv) /* Test TLS13 Extensions */ { EXPECT_SUCCESS(s2n_enable_tls13_in_test()); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); @@ -322,7 +322,7 @@ int main(int argc, char **argv) /* Test Secure Negotiation server_hello extension not sent with TLS13 or higher */ { EXPECT_SUCCESS(s2n_enable_tls13_in_test()); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); @@ -365,7 +365,7 @@ int main(int argc, char **argv) /* Test New Session Ticket server_hello extension not sent with TLS13 or higher */ { EXPECT_SUCCESS(s2n_enable_tls13_in_test()); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); s2n_extension_type_id extension_id = 0; EXPECT_SUCCESS(s2n_extension_supported_iana_value_to_id(TLS_EXTENSION_SESSION_TICKET, &extension_id)); @@ -425,7 +425,7 @@ int main(int argc, char **argv) const uint8_t cipher_count_tls13 = sizeof(wire_ciphers_with_tls13) / S2N_TLS_CIPHER_SUITE_LEN; EXPECT_SUCCESS(s2n_enable_tls13_in_test()); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); @@ -516,7 +516,7 @@ int main(int argc, char **argv) /* Test ec_point_format extension */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); conn->secure->cipher_suite = &s2n_ecdhe_ecdsa_with_aes_128_cbc_sha; @@ -543,13 +543,13 @@ int main(int argc, char **argv) { EXPECT_SUCCESS(s2n_enable_tls13_in_test()); - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_allow_all_response_extensions(server_conn)); struct s2n_cert_chain_and_key fake_chain_and_key = { 0 }; static uint8_t fake_ocsp[] = { 0xff, 0xff, 0xff }; - s2n_blob_init(&fake_chain_and_key.ocsp_status, fake_ocsp, sizeof(fake_ocsp)); + EXPECT_SUCCESS(s2n_blob_init(&fake_chain_and_key.ocsp_status, fake_ocsp, sizeof(fake_ocsp))); /* For our test status_request extension */ server_conn->status_type = S2N_STATUS_REQUEST_OCSP; @@ -561,7 +561,7 @@ int main(int argc, char **argv) server_conn->actual_protocol_version = S2N_TLS12; server_conn->server_protocol_version = S2N_TLS12; - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_allow_all_response_extensions(client_conn)); @@ -590,7 +590,7 @@ int main(int argc, char **argv) server_conn->actual_protocol_version = S2N_TLS13; server_conn->server_protocol_version = S2N_TLS13; - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_allow_all_response_extensions(client_conn)); @@ -640,7 +640,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_stuffer_write_vector_size(&extension_list_size)); for (size_t is_hrr = 0; is_hrr < 2; is_hrr++) { - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_allow_all_response_extensions(client_conn)); client_conn->actual_protocol_version = S2N_TLS13; diff --git a/tests/unit/s2n_server_hello_retry_test.c b/tests/unit/s2n_server_hello_retry_test.c index ae44a31104c..db3c73160fb 100644 --- a/tests/unit/s2n_server_hello_retry_test.c +++ b/tests/unit/s2n_server_hello_retry_test.c @@ -78,7 +78,7 @@ static int client_hello_detect_duplicate_calls(struct s2n_connection *conn, void int s2n_client_hello_poll_cb(struct s2n_connection *conn, void *ctx) { - struct client_hello_context *client_hello_ctx; + struct client_hello_context *client_hello_ctx = NULL; if (ctx == NULL) { return -1; } @@ -157,8 +157,8 @@ int main(int argc, char **argv) /* Send Hello Retry Request messages */ { - struct s2n_config *server_config; - struct s2n_connection *server_conn; + struct s2n_config *server_config = NULL; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_config = s2n_config_new()); EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); @@ -203,8 +203,8 @@ int main(int argc, char **argv) /* Verify the requires_retry flag causes a retry to be sent */ { - struct s2n_config *conf; - struct s2n_connection *conn; + struct s2n_config *conf = NULL; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conf = s2n_config_new()); EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); @@ -228,8 +228,8 @@ int main(int argc, char **argv) /* Retry requests with incorrect random data are not accepted */ { - struct s2n_config *conf; - struct s2n_connection *conn; + struct s2n_config *conf = NULL; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conf = s2n_config_new()); EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); @@ -267,8 +267,8 @@ int main(int argc, char **argv) /* Verify the client key share extension properly handles HelloRetryRequests */ { - struct s2n_connection *server_conn; - struct s2n_connection *client_conn; + struct s2n_connection *server_conn = NULL; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); @@ -317,8 +317,8 @@ int main(int argc, char **argv) /* Verify that the hash transcript recreation function correctly takes the existing ClientHello1 * hash, and generates a synthetic message. */ { - struct s2n_config *conf; - struct s2n_connection *conn; + struct s2n_config *conf = NULL; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conf = s2n_config_new()); EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); @@ -385,13 +385,13 @@ int main(int argc, char **argv) /* Send and receive Hello Retry Request messages */ { - struct s2n_config *server_config; - struct s2n_config *client_config; + struct s2n_config *server_config = NULL; + struct s2n_config *client_config = NULL; - struct s2n_connection *server_conn; - struct s2n_connection *client_conn; + struct s2n_connection *server_conn = NULL; + struct s2n_connection *client_conn = NULL; - struct s2n_cert_chain_and_key *tls13_chain_and_key; + struct s2n_cert_chain_and_key *tls13_chain_and_key = NULL; EXPECT_NOT_NULL(server_config = s2n_config_new()); EXPECT_NOT_NULL(client_config = s2n_config_new()); @@ -459,13 +459,13 @@ int main(int argc, char **argv) /* Send and receive Hello Retry Request messages, test for non blocking client hello callback */ { - struct s2n_config *server_config; - struct s2n_config *client_config; + struct s2n_config *server_config = NULL; + struct s2n_config *client_config = NULL; - struct s2n_connection *server_conn; - struct s2n_connection *client_conn; + struct s2n_connection *server_conn = NULL; + struct s2n_connection *client_conn = NULL; - struct s2n_cert_chain_and_key *tls13_chain_and_key; + struct s2n_cert_chain_and_key *tls13_chain_and_key = NULL; EXPECT_NOT_NULL(server_config = s2n_config_new()); EXPECT_NOT_NULL(client_config = s2n_config_new()); @@ -527,7 +527,7 @@ int main(int argc, char **argv) /* Test s2n_set_hello_retry_required correctly sets the handshake type to HELLO_RETRY_REQUEST, * when conn->actual_protocol_version is set to TLS1.3 version */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_all_protocol_versions(conn, S2N_TLS13)); @@ -540,7 +540,7 @@ int main(int argc, char **argv) /* Test s2n_set_hello_retry_required raises a S2N_ERR_INVALID_HELLO_RETRY error * when conn->actual_protocol_version is less than TLS1.3 */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); conn->actual_protocol_version = S2N_TLS12; diff --git a/tests/unit/s2n_server_hello_test.c b/tests/unit/s2n_server_hello_test.c index c66c0fe0977..31bfd950d64 100644 --- a/tests/unit/s2n_server_hello_test.c +++ b/tests/unit/s2n_server_hello_test.c @@ -66,16 +66,16 @@ int main(int argc, char **argv) BEGIN_TEST(); EXPECT_SUCCESS(s2n_disable_tls13_in_test()); - struct s2n_cert_chain_and_key *chain_and_key; + struct s2n_cert_chain_and_key *chain_and_key = NULL; EXPECT_SUCCESS(s2n_test_cert_chain_and_key_new(&chain_and_key, S2N_DEFAULT_ECDSA_TEST_CERT_CHAIN, S2N_DEFAULT_ECDSA_TEST_PRIVATE_KEY)); /* Test basic Server Hello Send */ { - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); @@ -133,11 +133,11 @@ int main(int argc, char **argv) /* Test basic Server Hello Recv */ { - struct s2n_config *server_config; - struct s2n_config *client_config; + struct s2n_config *server_config = NULL; + struct s2n_config *client_config = NULL; - struct s2n_connection *server_conn; - struct s2n_connection *client_conn; + struct s2n_connection *server_conn = NULL; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(server_config = s2n_config_new()); EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); @@ -170,8 +170,8 @@ int main(int argc, char **argv) /* Test Server Hello Recv with invalid cipher */ { - struct s2n_connection *server_conn; - struct s2n_connection *client_conn; + struct s2n_connection *server_conn = NULL; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); @@ -196,8 +196,8 @@ int main(int argc, char **argv) /* Non-matching session IDs turn off EMS for the connection */ { - struct s2n_connection *server_conn; - struct s2n_connection *client_conn; + struct s2n_connection *server_conn = NULL; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); @@ -234,8 +234,8 @@ int main(int argc, char **argv) /* Test TLS 1.3 session id matching */ { EXPECT_SUCCESS(s2n_enable_tls13_in_test()); - struct s2n_config *client_config; - struct s2n_connection *client_conn; + struct s2n_config *client_config = NULL; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_config = s2n_config_new()); EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(client_conn, client_config)); @@ -297,10 +297,10 @@ int main(int argc, char **argv) /* Test TLS 1.3 => 1.1 protocol downgrade detection with a TLS1.3 client */ { EXPECT_SUCCESS(s2n_enable_tls13_in_test()); - struct s2n_config *client_config; - struct s2n_connection *client_conn; - struct s2n_config *server_config; - struct s2n_connection *server_conn; + struct s2n_config *client_config = NULL; + struct s2n_connection *client_conn = NULL; + struct s2n_config *server_config = NULL; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_config = s2n_config_new()); EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); @@ -341,10 +341,10 @@ int main(int argc, char **argv) /* Test TLS 1.3 => 1.2 protocol downgrade detection with a TLS1.3 client */ { EXPECT_SUCCESS(s2n_enable_tls13_in_test()); - struct s2n_config *client_config; - struct s2n_connection *client_conn; - struct s2n_config *server_config; - struct s2n_connection *server_conn; + struct s2n_config *client_config = NULL; + struct s2n_connection *client_conn = NULL; + struct s2n_config *server_config = NULL; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_config = s2n_config_new()); EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); @@ -384,10 +384,10 @@ int main(int argc, char **argv) /* Verify a TLS1.2 client can negotiate with a TLS1.3 server */ { - struct s2n_config *client_config; - struct s2n_connection *client_conn; - struct s2n_config *server_config; - struct s2n_connection *server_conn; + struct s2n_config *client_config = NULL; + struct s2n_connection *client_conn = NULL; + struct s2n_config *server_config = NULL; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_config = s2n_config_new()); EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); @@ -426,10 +426,10 @@ int main(int argc, char **argv) /* Verify a TLS1.3 client can negotiate with a TLS1.2 server */ { - struct s2n_config *client_config; - struct s2n_connection *client_conn; - struct s2n_config *server_config; - struct s2n_connection *server_conn; + struct s2n_config *client_config = NULL; + struct s2n_connection *client_conn = NULL; + struct s2n_config *server_config = NULL; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_config = s2n_config_new()); EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); @@ -468,10 +468,10 @@ int main(int argc, char **argv) /* Verify a TLS1.2 client can negotiate with a TLS1.3 server */ { - struct s2n_config *client_config; - struct s2n_connection *client_conn; - struct s2n_config *server_config; - struct s2n_connection *server_conn; + struct s2n_config *client_config = NULL; + struct s2n_connection *client_conn = NULL; + struct s2n_config *server_config = NULL; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_config = s2n_config_new()); EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); @@ -511,7 +511,7 @@ int main(int argc, char **argv) /* TLS13 hello retry message received results into S2N_ERR_UNIMPLEMENTED error*/ { - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); struct s2n_stuffer *io = &client_conn->handshake.io; client_conn->server_protocol_version = S2N_TLS13; diff --git a/tests/unit/s2n_server_key_share_extension_test.c b/tests/unit/s2n_server_key_share_extension_test.c index 44569f0f81e..15211898cba 100644 --- a/tests/unit/s2n_server_key_share_extension_test.c +++ b/tests/unit/s2n_server_key_share_extension_test.c @@ -81,7 +81,7 @@ int main(int argc, char **argv) /* Test s2n_extensions_server_key_share_send_size */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_EQUAL(0, s2n_extensions_server_key_share_send_size(conn)); @@ -200,8 +200,8 @@ int main(int argc, char **argv) int i = 0; do { - struct s2n_connection *server_send_conn; - struct s2n_connection *client_recv_conn; + struct s2n_connection *server_send_conn = NULL; + struct s2n_connection *client_recv_conn = NULL; EXPECT_NOT_NULL(server_send_conn = s2n_connection_new(S2N_SERVER)); EXPECT_NOT_NULL(client_recv_conn = s2n_connection_new(S2N_CLIENT)); @@ -248,7 +248,7 @@ int main(int argc, char **argv) for (int i = 0; i < 3; i++) { struct s2n_stuffer extension_stuffer = { 0 }; - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); @@ -276,7 +276,7 @@ int main(int argc, char **argv) * if tls1.3 not enabled */ { struct s2n_stuffer extension_stuffer = { 0 }; - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); @@ -312,7 +312,7 @@ int main(int argc, char **argv) /* Test error handling parsing broken/trancated p256 key share */ { struct s2n_stuffer extension_stuffer = { 0 }; - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); const char *p256 = "001700410474cfd75c0ab7b57247761a277e1c92b5810dacb251bb758f43e9d15aaf292c4a2be43e886425ba55653ebb7a4f32fe368bacce3df00c618645cf1eb6"; @@ -329,7 +329,7 @@ int main(int argc, char **argv) /* Test failure for receiving p256 key share for client configured p384 key share */ { struct s2n_stuffer extension_stuffer = { 0 }; - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); const struct s2n_ecc_preferences *ecc_pref = NULL; @@ -356,7 +356,7 @@ int main(int argc, char **argv) /* Test Shared Key Generation */ { - struct s2n_connection *client_conn, *server_conn; + struct s2n_connection *client_conn = NULL, *server_conn = NULL; struct s2n_stuffer key_share_extension = { 0 }; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); @@ -424,7 +424,7 @@ int main(int argc, char **argv) /* Test s2n_server_key_share_extension.send with supported curve not in s2n_ecc_preferences list selected */ if (s2n_is_evp_apis_supported()) { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_NOT_NULL(conn->config); @@ -441,7 +441,7 @@ int main(int argc, char **argv) /* Test s2n_server_key_share_extension.recv with supported curve not in s2n_ecc_preferences list selected */ if (s2n_is_evp_apis_supported()) { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); struct s2n_stuffer *extension_stuffer = &conn->handshake.io; @@ -464,8 +464,8 @@ int main(int argc, char **argv) /* For a HelloRetryRequest, we won't have a key share. We just have the server selected group/negotiated curve. * Test that s2n_server_key_share_extension.recv obtains the server negotiate curve successfully. */ { - struct s2n_connection *client_conn; - struct s2n_connection *server_conn; + struct s2n_connection *client_conn = NULL; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); @@ -682,7 +682,7 @@ int main(int argc, char **argv) if (!s2n_kem_group_is_available(kem_group)) { continue; } - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); client_conn->security_policy_override = &test_security_policy; diff --git a/tests/unit/s2n_server_max_frag_len_extension_test.c b/tests/unit/s2n_server_max_frag_len_extension_test.c index ccbe5e90b2a..4e351899d22 100644 --- a/tests/unit/s2n_server_max_frag_len_extension_test.c +++ b/tests/unit/s2n_server_max_frag_len_extension_test.c @@ -24,10 +24,10 @@ int main(int argc, char **argv) /* Test should_send */ { - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); @@ -44,11 +44,11 @@ int main(int argc, char **argv) /* Test send */ { - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_send_max_fragment_length(config, S2N_TLS_MAX_FRAG_LEN_512)); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); @@ -59,7 +59,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_server_max_fragment_length_extension.send(conn, &stuffer)); /* Should have correct fragment length */ - uint8_t actual_fragment_length; + uint8_t actual_fragment_length = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint8(&stuffer, &actual_fragment_length)); EXPECT_EQUAL(actual_fragment_length, S2N_TLS_MAX_FRAG_LEN_512); @@ -80,11 +80,11 @@ int main(int argc, char **argv) *# an "illegal_parameter" alert. */ { - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_send_max_fragment_length(config, S2N_TLS_MAX_FRAG_LEN_512)); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); @@ -104,11 +104,11 @@ int main(int argc, char **argv) /* Test receive */ { - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_send_max_fragment_length(config, S2N_TLS_MAX_FRAG_LEN_512)); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); @@ -133,11 +133,11 @@ int main(int argc, char **argv) /* Test receive - existing mfl value */ { - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_send_max_fragment_length(config, S2N_TLS_MAX_FRAG_LEN_1024)); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); diff --git a/tests/unit/s2n_server_new_session_ticket_test.c b/tests/unit/s2n_server_new_session_ticket_test.c index 5d282f76d55..b299964fefc 100644 --- a/tests/unit/s2n_server_new_session_ticket_test.c +++ b/tests/unit/s2n_server_new_session_ticket_test.c @@ -72,7 +72,7 @@ static int s2n_setup_test_ticket_key(struct s2n_config *config) "90b6c73bb50f9c3122ec844ad7c2b3e5"); /* Set up encryption key */ - uint64_t current_time; + uint64_t current_time = 0; uint8_t ticket_key_name[16] = "2016.07.26.15\0"; EXPECT_SUCCESS(s2n_config_set_session_tickets_onoff(config, 1)); EXPECT_SUCCESS(config->wall_clock(config->sys_clock_ctx, ¤t_time)); @@ -112,8 +112,8 @@ int main(int argc, char **argv) { /* Check session ticket message is correctly written. */ { - struct s2n_config *config; - struct s2n_connection *conn; + struct s2n_config *config = NULL; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_NOT_NULL(config = s2n_config_new()); @@ -184,8 +184,8 @@ int main(int argc, char **argv) /* tickets_sent overflow */ { - struct s2n_config *config; - struct s2n_connection *conn; + struct s2n_config *config = NULL; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_NOT_NULL(config = s2n_config_new()); @@ -214,8 +214,8 @@ int main(int argc, char **argv) *# for each ticket it sends. **/ { - struct s2n_config *config; - struct s2n_connection *conn; + struct s2n_config *config = NULL; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_NOT_NULL(config = s2n_config_new()); @@ -327,7 +327,7 @@ int main(int argc, char **argv) /* s2n_generate_ticket_lifetime */ { uint32_t min_lifetime = 0; - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); /* Test: encrypt + decrypt key has shortest lifetime */ @@ -829,7 +829,7 @@ int main(int argc, char **argv) { /* Mode is not server */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); conn->actual_protocol_version = S2N_TLS13; conn->tickets_to_send = 1; @@ -945,8 +945,8 @@ int main(int argc, char **argv) /* Sends one new session ticket */ { - struct s2n_config *config; - struct s2n_connection *conn; + struct s2n_config *config = NULL; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_NOT_NULL(config = s2n_config_new()); EXPECT_SUCCESS(s2n_setup_test_ticket_key(config)); @@ -1130,8 +1130,8 @@ int main(int argc, char **argv) /* Sends multiple new session tickets */ { - struct s2n_config *config; - struct s2n_connection *conn; + struct s2n_config *config = NULL; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_NOT_NULL(config = s2n_config_new()); @@ -1269,15 +1269,15 @@ int main(int argc, char **argv) /* Functional test: s2n_negotiate sends new session tickets after the handshake is complete */ if (s2n_is_tls13_fully_supported()) { /* Setup connections */ - struct s2n_connection *client_conn, *server_conn; + struct s2n_connection *client_conn = NULL, *server_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); /* Setup config */ - struct s2n_cert_chain_and_key *chain_and_key; + struct s2n_cert_chain_and_key *chain_and_key = NULL; EXPECT_SUCCESS(s2n_test_cert_chain_and_key_new(&chain_and_key, S2N_DEFAULT_ECDSA_TEST_CERT_CHAIN, S2N_DEFAULT_ECDSA_TEST_PRIVATE_KEY)); - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_set_cipher_preferences(config, "default_tls13")); EXPECT_SUCCESS(s2n_config_set_unsafe_for_testing(config)); diff --git a/tests/unit/s2n_server_psk_extension_test.c b/tests/unit/s2n_server_psk_extension_test.c index be655545631..cf01f82e43a 100644 --- a/tests/unit/s2n_server_psk_extension_test.c +++ b/tests/unit/s2n_server_psk_extension_test.c @@ -135,7 +135,7 @@ int main(int argc, char **argv) /* Test: s2n_server_psk_recv */ { - s2n_extension_type_id key_share_ext_id; + s2n_extension_type_id key_share_ext_id = 0; EXPECT_SUCCESS(s2n_extension_supported_iana_value_to_id(TLS_EXTENSION_KEY_SHARE, &key_share_ext_id)); /* Test s2n_server_psk_recv for invalid TLS versions <= TLS1.2 */ @@ -260,7 +260,7 @@ int main(int argc, char **argv) if (s2n_is_tls13_fully_supported()) { /* Setup connections */ EXPECT_SUCCESS(s2n_enable_tls13_in_test()); - struct s2n_connection *client_conn, *server_conn; + struct s2n_connection *client_conn = NULL, *server_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_cipher_preferences(client_conn, "default_tls13")); diff --git a/tests/unit/s2n_server_renegotiation_info_test.c b/tests/unit/s2n_server_renegotiation_info_test.c index ace9a73582e..9c9c6fdab7d 100644 --- a/tests/unit/s2n_server_renegotiation_info_test.c +++ b/tests/unit/s2n_server_renegotiation_info_test.c @@ -68,7 +68,7 @@ int main(int argc, char **argv) *# message. */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); /* TLS1.2 and secure renegotiation not enabled -> DON'T send */ @@ -104,7 +104,7 @@ int main(int argc, char **argv) *# that they have been upgraded. */ { - struct s2n_connection *server_conn, *client_conn; + struct s2n_connection *server_conn = NULL, *client_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); @@ -160,7 +160,7 @@ int main(int argc, char **argv) /* Test server_renegotiation_info recv during initial handshake - extension too long */ { - struct s2n_connection *server_conn, *client_conn; + struct s2n_connection *server_conn = NULL, *client_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); @@ -191,7 +191,7 @@ int main(int argc, char **argv) *# abort the handshake (by sending a fatal handshake_failure alert). */ { - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); struct s2n_stuffer extension = { 0 }; diff --git a/tests/unit/s2n_server_sct_list_extension_test.c b/tests/unit/s2n_server_sct_list_extension_test.c index 137710292d7..b44785b20a0 100644 --- a/tests/unit/s2n_server_sct_list_extension_test.c +++ b/tests/unit/s2n_server_sct_list_extension_test.c @@ -39,10 +39,10 @@ int main(int argc, char **argv) /* should_send */ { - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); @@ -79,7 +79,7 @@ int main(int argc, char **argv) /* Test send */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_test_enable_sending_extension(conn, chain_and_key)); @@ -97,7 +97,7 @@ int main(int argc, char **argv) /* Test recv */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_test_enable_sending_extension(conn, chain_and_key)); diff --git a/tests/unit/s2n_server_server_name_extension_test.c b/tests/unit/s2n_server_server_name_extension_test.c index e94e5e174cb..4bd6591b8da 100644 --- a/tests/unit/s2n_server_server_name_extension_test.c +++ b/tests/unit/s2n_server_server_name_extension_test.c @@ -28,7 +28,7 @@ int main(int argc, char **argv) /* should_send */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); /* By default, do not send */ @@ -65,7 +65,7 @@ int main(int argc, char **argv) /* recv */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); /* Recv reads nothing and always succeeds */ diff --git a/tests/unit/s2n_server_session_ticket_extension_test.c b/tests/unit/s2n_server_session_ticket_extension_test.c index fc1394feac9..625c0fc96a2 100644 --- a/tests/unit/s2n_server_session_ticket_extension_test.c +++ b/tests/unit/s2n_server_session_ticket_extension_test.c @@ -39,10 +39,10 @@ int main(int argc, char **argv) /* Test should_send */ { - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); @@ -79,7 +79,7 @@ int main(int argc, char **argv) /* Test server_session_ticket send and recv */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_server_session_ticket_extension.send(conn, NULL)); diff --git a/tests/unit/s2n_server_signature_algorithms_extension_test.c b/tests/unit/s2n_server_signature_algorithms_extension_test.c index 7ecfd7786ad..458e2664950 100644 --- a/tests/unit/s2n_server_signature_algorithms_extension_test.c +++ b/tests/unit/s2n_server_signature_algorithms_extension_test.c @@ -32,8 +32,8 @@ int main(int argc, char **argv) s2n_enable_tls13_in_test(); { - struct s2n_connection *client_conn; - struct s2n_connection *server_conn; + struct s2n_connection *client_conn = NULL; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); diff --git a/tests/unit/s2n_server_supported_versions_extension_test.c b/tests/unit/s2n_server_supported_versions_extension_test.c index 1e089b39619..7574dd8b452 100644 --- a/tests/unit/s2n_server_supported_versions_extension_test.c +++ b/tests/unit/s2n_server_supported_versions_extension_test.c @@ -41,19 +41,19 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_enable_tls13_in_test()); uint8_t latest_version = S2N_TLS13; - struct s2n_config *config; + struct s2n_config *config = NULL; EXPECT_NOT_NULL(config = s2n_config_new()); /* Server sends a supported_version the client can parse */ { - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_config(server_conn, config)); uint16_t expected_length = 6; struct s2n_stuffer extension = { 0 }; - s2n_stuffer_alloc(&extension, expected_length); + EXPECT_SUCCESS(s2n_stuffer_alloc(&extension, expected_length)); EXPECT_SUCCESS(s2n_server_supported_versions_extension.send(server_conn, &extension)); @@ -63,7 +63,7 @@ int main(int argc, char **argv) EXPECT_EQUAL(extension_length, s2n_stuffer_data_available(&extension)); /* Check that the client can process the version */ - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(client_conn, config)); @@ -80,7 +80,7 @@ int main(int argc, char **argv) /* Client alerts if supported_version less than min supported by client */ { - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(client_conn, config)); @@ -89,7 +89,7 @@ int main(int argc, char **argv) uint16_t supported_version_length = 6; struct s2n_stuffer extension = { 0 }; - s2n_stuffer_alloc(&extension, supported_version_length); + EXPECT_SUCCESS(s2n_stuffer_alloc(&extension, supported_version_length)); EXPECT_SUCCESS(write_test_supported_version(&extension, unsupported_version_unknown)); EXPECT_FAILURE_WITH_ERRNO(s2n_server_supported_versions_extension.recv(client_conn, &extension), S2N_ERR_BAD_MESSAGE); @@ -100,7 +100,7 @@ int main(int argc, char **argv) /* Client alerts if supported_version greater than max supported by client */ { - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(client_conn, config)); @@ -109,7 +109,7 @@ int main(int argc, char **argv) uint16_t supported_version_length = 6; struct s2n_stuffer extension = { 0 }; - s2n_stuffer_alloc(&extension, supported_version_length); + EXPECT_SUCCESS(s2n_stuffer_alloc(&extension, supported_version_length)); EXPECT_SUCCESS(write_test_supported_version(&extension, unsupported_version_gt_tls13)); EXPECT_FAILURE_WITH_ERRNO(s2n_server_supported_versions_extension.recv(client_conn, &extension), S2N_ERR_BAD_MESSAGE); @@ -120,12 +120,12 @@ int main(int argc, char **argv) /* Client alerts if supported_version is empty */ { - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(client_conn, config)); struct s2n_stuffer extension = { 0 }; - s2n_stuffer_alloc(&extension, 1); + EXPECT_SUCCESS(s2n_stuffer_alloc(&extension, 1)); EXPECT_SUCCESS(s2n_stuffer_write_uint8(&extension, 0)); EXPECT_FAILURE_WITH_ERRNO(s2n_server_supported_versions_extension.recv(client_conn, &extension), S2N_ERR_BAD_MESSAGE); @@ -136,12 +136,12 @@ int main(int argc, char **argv) /* Client alerts if supported_version is malformed */ { - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_config(client_conn, config)); struct s2n_stuffer extension = { 0 }; - s2n_stuffer_alloc(&extension, 1); + EXPECT_SUCCESS(s2n_stuffer_alloc(&extension, 1)); EXPECT_SUCCESS(s2n_stuffer_write_uint8(&extension, 13)); diff --git a/tests/unit/s2n_session_ticket_test.c b/tests/unit/s2n_session_ticket_test.c index 4dbd7669996..5c9fdb42fb2 100644 --- a/tests/unit/s2n_session_ticket_test.c +++ b/tests/unit/s2n_session_ticket_test.c @@ -85,15 +85,15 @@ struct small_name_ticket { int main(int argc, char **argv) { - char *cert_chain; - char *private_key; - struct s2n_cert_chain_and_key *chain_and_key; - struct s2n_connection *client_conn; - struct s2n_connection *server_conn; - struct s2n_config *client_config; - struct s2n_config *server_config; - uint64_t now; - struct s2n_ticket_key *ticket_key; + char *cert_chain = NULL; + char *private_key = NULL; + struct s2n_cert_chain_and_key *chain_and_key = NULL; + struct s2n_connection *client_conn = NULL; + struct s2n_connection *server_conn = NULL; + struct s2n_config *client_config = NULL; + struct s2n_config *server_config = NULL; + uint64_t now = 0; + struct s2n_ticket_key *ticket_key = NULL; uint32_t ticket_keys_len = 0; size_t serialized_session_state_length = 0; diff --git a/tests/unit/s2n_shutdown_test.c b/tests/unit/s2n_shutdown_test.c index e2054a6ef50..ee7042e23f2 100644 --- a/tests/unit/s2n_shutdown_test.c +++ b/tests/unit/s2n_shutdown_test.c @@ -45,6 +45,17 @@ int main(int argc, char **argv) const uint8_t alert_record_size = sizeof(alert_record_header) + S2N_ALERT_LENGTH; + DEFER_CLEANUP(struct s2n_cert_chain_and_key * chain_and_key, + s2n_cert_chain_and_key_ptr_free); + EXPECT_SUCCESS(s2n_test_cert_chain_and_key_new(&chain_and_key, + S2N_DEFAULT_ECDSA_TEST_CERT_CHAIN, S2N_DEFAULT_ECDSA_TEST_PRIVATE_KEY)); + + DEFER_CLEANUP(struct s2n_config *config = s2n_config_new(), + s2n_config_ptr_free); + EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(config, chain_and_key)); + EXPECT_SUCCESS(s2n_config_set_cipher_preferences(config, "default_tls13")); + EXPECT_SUCCESS(s2n_config_disable_x509_verification(config)); + /* Test: Do not send or await close_notify if reader alert already queued */ { DEFER_CLEANUP(struct s2n_connection *conn = s2n_connection_new(S2N_SERVER), @@ -356,7 +367,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_shutdown(conn, &blocked)); }; - /* Test: previous failed partial reads do not affect reading close_notify */ + /* Test: Do not await close_notify after reading malformed record */ { DEFER_CLEANUP(struct s2n_connection *conn = s2n_connection_new(S2N_SERVER), s2n_connection_ptr_free); @@ -395,20 +406,172 @@ int main(int argc, char **argv) EXPECT_FAILURE_WITH_ERRNO( s2n_recv(conn, recv_buffer, sizeof(recv_buffer), &blocked), S2N_ERR_BAD_MESSAGE); - EXPECT_TRUE(s2n_stuffer_space_remaining(&conn->header_in) < sizeof(header_bytes)); /* Clear the blinding delay so that we can call s2n_shutdown */ EXPECT_TRUE(conn->delay > 0); - conn->delay = 0; + conn->write_timer.time = 0; - /* Make the valid close_notify available */ - EXPECT_SUCCESS(s2n_stuffer_write_bytes(&input, alert_record_header, sizeof(alert_record_header))); - EXPECT_SUCCESS(s2n_stuffer_write_bytes(&input, close_notify_alert, sizeof(close_notify_alert))); + /* Successfully shutdown without waiting for more data. */ + EXPECT_SUCCESS(s2n_shutdown(conn, &blocked)); + EXPECT_FALSE(s2n_atomic_flag_test(&conn->close_notify_received)); + }; + + /* Test: s2n_shutdown successfully reads and skips a partial app data record */ + { + DEFER_CLEANUP(struct s2n_connection *client = s2n_connection_new(S2N_CLIENT), + s2n_connection_ptr_free); + EXPECT_NOT_NULL(client); + EXPECT_SUCCESS(s2n_connection_set_config(client, config)); + + DEFER_CLEANUP(struct s2n_connection *server = s2n_connection_new(S2N_SERVER), + s2n_connection_ptr_free); + EXPECT_NOT_NULL(server); + EXPECT_SUCCESS(s2n_connection_set_config(server, config)); + + 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)); + EXPECT_OK(s2n_connections_set_io_stuffer_pair(client, server, &io_pair)); + EXPECT_SUCCESS(s2n_negotiate_test_server_and_client(server, client)); + + s2n_blocked_status blocked = S2N_NOT_BLOCKED; + + /* Send some application data */ + uint8_t test_data[] = "hello world"; + EXPECT_EQUAL(s2n_send(client, test_data, sizeof(test_data), &blocked), sizeof(test_data)); + + /* Block reading application data */ + io_pair.server_in.write_cursor--; + EXPECT_FAILURE_WITH_ERRNO(s2n_recv(server, test_data, sizeof(test_data), &blocked), + S2N_ERR_IO_BLOCKED); + + /* Make the remainder of the application data + a close_notify available */ + io_pair.server_in.write_cursor++; + EXPECT_SUCCESS(s2n_shutdown_send(client, &blocked)); /* Successfully shutdown. - * The initial bad call to s2n_recv should not affect shutdown. + * The application data is skipped. */ - EXPECT_SUCCESS(s2n_shutdown(conn, &blocked)); + EXPECT_SUCCESS(s2n_shutdown(server, &blocked)); + EXPECT_TRUE(s2n_atomic_flag_test(&server->close_notify_received)); + }; + + /* Test: s2n_shutdown successfully reads a partial close_notify record */ + { + DEFER_CLEANUP(struct s2n_connection *client = s2n_connection_new(S2N_CLIENT), + s2n_connection_ptr_free); + EXPECT_NOT_NULL(client); + EXPECT_SUCCESS(s2n_connection_set_config(client, config)); + + DEFER_CLEANUP(struct s2n_connection *server = s2n_connection_new(S2N_SERVER), + s2n_connection_ptr_free); + EXPECT_NOT_NULL(server); + EXPECT_SUCCESS(s2n_connection_set_config(server, config)); + + 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)); + EXPECT_OK(s2n_connections_set_io_stuffer_pair(client, server, &io_pair)); + EXPECT_SUCCESS(s2n_negotiate_test_server_and_client(server, client)); + + s2n_blocked_status blocked = S2N_NOT_BLOCKED; + + /* Send the close_notify */ + EXPECT_SUCCESS(s2n_shutdown_send(client, &blocked)); + + /* Block reading the close_notify record */ + uint8_t read = 0; + io_pair.server_in.write_cursor--; + EXPECT_FAILURE_WITH_ERRNO(s2n_recv(server, &read, 1, &blocked), S2N_ERR_IO_BLOCKED); + EXPECT_FALSE(s2n_atomic_flag_test(&server->close_notify_received)); + + /* Receive the rest of the close_notify record and successful shutdown */ + io_pair.server_in.write_cursor++; + EXPECT_SUCCESS(s2n_shutdown(server, &blocked)); + EXPECT_TRUE(s2n_atomic_flag_test(&server->close_notify_received)); + }; + + /* Test: s2n_shutdown fails if a partial record is malformed */ + { + DEFER_CLEANUP(struct s2n_connection *client = s2n_connection_new(S2N_CLIENT), + s2n_connection_ptr_free); + EXPECT_NOT_NULL(client); + EXPECT_SUCCESS(s2n_connection_set_config(client, config)); + + DEFER_CLEANUP(struct s2n_connection *server = s2n_connection_new(S2N_SERVER), + s2n_connection_ptr_free); + EXPECT_NOT_NULL(server); + EXPECT_SUCCESS(s2n_connection_set_config(server, config)); + EXPECT_SUCCESS(s2n_connection_set_blinding(server, S2N_SELF_SERVICE_BLINDING)); + + 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)); + EXPECT_OK(s2n_connections_set_io_stuffer_pair(client, server, &io_pair)); + EXPECT_SUCCESS(s2n_negotiate_test_server_and_client(server, client)); + + s2n_blocked_status blocked = S2N_NOT_BLOCKED; + + /* Send some invalid application data */ + uint8_t test_data[] = "hello world"; + EXPECT_EQUAL(s2n_send(client, test_data, sizeof(test_data), &blocked), sizeof(test_data)); + const uint8_t overwrite_size = sizeof(test_data) / 2; + EXPECT_SUCCESS(s2n_stuffer_wipe_n(&io_pair.server_in, overwrite_size)); + EXPECT_SUCCESS(s2n_stuffer_skip_write(&io_pair.server_in, overwrite_size)); + + /* Block reading application data */ + io_pair.server_in.write_cursor--; + EXPECT_FAILURE_WITH_ERRNO(s2n_recv(server, test_data, sizeof(test_data), &blocked), + S2N_ERR_IO_BLOCKED); + + /* Make the remainder of the application data + a close_notify available */ + io_pair.server_in.write_cursor++; + EXPECT_SUCCESS(s2n_shutdown_send(client, &blocked)); + + /* Shutdown fails to decrypt bad application data record */ + EXPECT_FAILURE_WITH_ERRNO(s2n_shutdown(server, &blocked), S2N_ERR_DECRYPT); + EXPECT_FALSE(s2n_atomic_flag_test(&server->close_notify_received)); + }; + + /* Test: s2n_shutdown skips partially drained / consumed app data + * + * This is different from handling a partial record. The record is complete + * and decrypted, but the application has not consumed the plaintext data yet. + */ + { + DEFER_CLEANUP(struct s2n_connection *client = s2n_connection_new(S2N_CLIENT), + s2n_connection_ptr_free); + EXPECT_NOT_NULL(client); + EXPECT_SUCCESS(s2n_connection_set_config(client, config)); + + DEFER_CLEANUP(struct s2n_connection *server = s2n_connection_new(S2N_SERVER), + s2n_connection_ptr_free); + EXPECT_NOT_NULL(server); + EXPECT_SUCCESS(s2n_connection_set_config(server, config)); + + 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)); + EXPECT_OK(s2n_connections_set_io_stuffer_pair(client, server, &io_pair)); + EXPECT_SUCCESS(s2n_negotiate_test_server_and_client(server, client)); + + s2n_blocked_status blocked = S2N_NOT_BLOCKED; + + /* Send some application data */ + uint8_t test_data[] = "hello world"; + EXPECT_EQUAL(s2n_send(client, test_data, sizeof(test_data), &blocked), sizeof(test_data)); + + /* Only read some of the application data */ + EXPECT_EQUAL(s2n_recv(server, test_data, 1, &blocked), 1); + + /* Make a close_notify available */ + EXPECT_SUCCESS(s2n_shutdown_send(client, &blocked)); + + /* Successfully shutdown. + * The remaining application data is skipped. + */ + EXPECT_SUCCESS(s2n_shutdown(server, &blocked)); + EXPECT_TRUE(s2n_atomic_flag_test(&server->close_notify_received)); }; /* Test: s2n_shutdown with aggressive socket close */ diff --git a/tests/unit/s2n_signature_algorithms_test.c b/tests/unit/s2n_signature_algorithms_test.c index 6d4145e850b..63bea8097bf 100644 --- a/tests/unit/s2n_signature_algorithms_test.c +++ b/tests/unit/s2n_signature_algorithms_test.c @@ -239,7 +239,7 @@ int main(int argc, char **argv) /* Test: ECDSA */ { const struct s2n_signature_scheme *expected = &s2n_ecdsa_sha1; - conn->handshake_params.client_cert_pkey_type = S2N_AUTHENTICATION_ECDSA; + conn->handshake_params.client_cert_pkey_type = S2N_PKEY_TYPE_ECDSA; EXPECT_SUCCESS(s2n_connection_set_config(conn, client_ecdsa_config)); /* TLS1.1 selects the default */ @@ -256,7 +256,7 @@ int main(int argc, char **argv) /* Test: RSA */ { const struct s2n_signature_scheme *expected = &s2n_rsa_pkcs1_md5_sha1; - conn->handshake_params.client_cert_pkey_type = S2N_AUTHENTICATION_RSA; + conn->handshake_params.client_cert_pkey_type = S2N_PKEY_TYPE_RSA; EXPECT_SUCCESS(s2n_connection_set_config(conn, client_rsa_config)); /* TLS1.1 selects the default */ diff --git a/tests/unit/s2n_stuffer_hex_test.c b/tests/unit/s2n_stuffer_hex_test.c index 57758f36d70..d46c6f2645e 100644 --- a/tests/unit/s2n_stuffer_hex_test.c +++ b/tests/unit/s2n_stuffer_hex_test.c @@ -24,10 +24,10 @@ int main(int argc, char **argv) struct s2n_blob b = { 0 }; EXPECT_SUCCESS(s2n_blob_init(&b, pad, sizeof(pad))); struct s2n_stuffer stuffer = { 0 }; - uint8_t u8; - uint16_t u16; - uint32_t u32; - uint64_t u64; + uint8_t u8 = 0; + uint16_t u16 = 0; + uint32_t u32 = 0; + uint64_t u64 = 0; BEGIN_TEST(); EXPECT_SUCCESS(s2n_disable_tls13_in_test()); diff --git a/tests/unit/s2n_stuffer_network_order_test.c b/tests/unit/s2n_stuffer_network_order_test.c index fc696f08cbb..94d0c62d9d3 100644 --- a/tests/unit/s2n_stuffer_network_order_test.c +++ b/tests/unit/s2n_stuffer_network_order_test.c @@ -41,12 +41,12 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_stuffer_write_network_order(&stuffer, 0x00, 0)); EXPECT_EQUAL(s2n_stuffer_data_available(&stuffer), 0); - uint8_t byte_length; + uint8_t byte_length = 0; /* uint8_t */ { byte_length = sizeof(uint8_t); - uint8_t actual_value; + uint8_t actual_value = 0; for (int i = 0; i <= UINT8_MAX; i++) { EXPECT_SUCCESS(s2n_stuffer_write_network_order(&stuffer, i, byte_length)); @@ -58,7 +58,7 @@ int main(int argc, char **argv) /* uint16_t */ { byte_length = sizeof(uint16_t); - uint16_t actual_value; + uint16_t actual_value = 0; for (int i = 0; i < UINT16_MAX; i++) { EXPECT_SUCCESS(s2n_stuffer_write_network_order(&stuffer, i, byte_length)); @@ -70,7 +70,7 @@ int main(int argc, char **argv) /* uint24 */ { byte_length = 3; - uint32_t actual_value; + uint32_t actual_value = 0; uint32_t test_values[] = { 0x000001, 0x0000FF, 0xABCDEF, 0xFFFFFF }; for (size_t i = 0; i < s2n_array_len(test_values); i++) { @@ -90,7 +90,7 @@ int main(int argc, char **argv) /* uint32_t */ { byte_length = sizeof(uint32_t); - uint32_t actual_value; + uint32_t actual_value = 0; uint32_t test_values[] = { 0x00000001, 0x000000FF, 0xABCDEF12, UINT32_MAX }; for (size_t i = 0; i < s2n_array_len(test_values); i++) { @@ -112,7 +112,7 @@ int main(int argc, char **argv) /* s2n_stuffer_reserve_uint16 */ { - uint16_t actual_value; + uint16_t actual_value = 0; struct s2n_stuffer_reservation reservation = { 0 }; EXPECT_SUCCESS(s2n_stuffer_growable_alloc(&stuffer, 0)); @@ -159,7 +159,7 @@ int main(int argc, char **argv) /* s2n_stuffer_reserve_uint24 */ { - uint16_t actual_value; + uint16_t actual_value = 0; struct s2n_stuffer_reservation reservation = { 0 }; EXPECT_SUCCESS(s2n_stuffer_growable_alloc(&stuffer, 0)); @@ -206,7 +206,7 @@ int main(int argc, char **argv) /* s2n_stuffer_write_reservation */ { - uint16_t actual_value; + uint16_t actual_value = 0; struct s2n_stuffer_reservation reservation = { 0 }; struct s2n_stuffer_reservation other_reservation = { 0 }; EXPECT_SUCCESS(s2n_stuffer_growable_alloc(&stuffer, 0)); @@ -272,7 +272,7 @@ int main(int argc, char **argv) /* s2n_stuffer_write_vector_size */ { - uint16_t actual_value; + uint16_t actual_value = 0; struct s2n_stuffer_reservation reservation = { 0 }; EXPECT_SUCCESS(s2n_stuffer_growable_alloc(&stuffer, 0)); diff --git a/tests/unit/s2n_stuffer_test.c b/tests/unit/s2n_stuffer_test.c index 88e10acf54c..daeda686117 100644 --- a/tests/unit/s2n_stuffer_test.c +++ b/tests/unit/s2n_stuffer_test.c @@ -23,10 +23,10 @@ int main(int argc, char **argv) { uint8_t entropy[2048] = { 0 }; struct s2n_stuffer stuffer = { 0 }; - uint8_t u8; - uint16_t u16; - uint32_t u32; - uint64_t u64; + uint8_t u8 = 0; + uint16_t u16 = 0; + uint32_t u32 = 0; + uint64_t u64 = 0; BEGIN_TEST(); EXPECT_SUCCESS(s2n_disable_tls13_in_test()); @@ -240,5 +240,107 @@ int main(int argc, char **argv) } }; + /* Test s2n_stuffer_shift */ + { + /* Safety */ + EXPECT_FAILURE_WITH_ERRNO(s2n_stuffer_shift(NULL), S2N_ERR_NULL); + + const uint8_t test_data[] = "hello world"; + const uint32_t test_data_size = sizeof(test_data); + const uint32_t test_offset = 10; + + /* Uninitialized stuffer: no shift */ + { + struct s2n_stuffer test = { 0 }; + + EXPECT_SUCCESS(s2n_stuffer_shift(&test)); + EXPECT_EQUAL(test.read_cursor, 0); + EXPECT_EQUAL(test.write_cursor, 0); + EXPECT_EQUAL(s2n_stuffer_data_available(&test), 0); + } + + /* No data available: no shift */ + { + uint8_t data[100] = { 0 }; + struct s2n_stuffer test = { 0 }; + EXPECT_SUCCESS(s2n_blob_init(&test.blob, data, sizeof(data))); + + EXPECT_SUCCESS(s2n_stuffer_write_bytes(&test, test_data, sizeof(test_data))); + EXPECT_SUCCESS(s2n_stuffer_skip_read(&test, sizeof(test_data))); + EXPECT_EQUAL(s2n_stuffer_data_available(&test), 0); + + EXPECT_SUCCESS(s2n_stuffer_shift(&test)); + EXPECT_EQUAL(test.read_cursor, 0); + EXPECT_EQUAL(test.write_cursor, 0); + EXPECT_EQUAL(s2n_stuffer_data_available(&test), 0); + EXPECT_BYTEARRAY_EQUAL(data, test_data, sizeof(test_data)); + } + + /* Data not offset: no shift */ + { + uint8_t data[100] = { 0 }; + struct s2n_stuffer test = { 0 }; + EXPECT_SUCCESS(s2n_blob_init(&test.blob, data, sizeof(data))); + + EXPECT_SUCCESS(s2n_stuffer_write_bytes(&test, test_data, test_data_size)); + EXPECT_EQUAL(s2n_stuffer_data_available(&test), test_data_size); + + EXPECT_SUCCESS(s2n_stuffer_shift(&test)); + EXPECT_EQUAL(test.read_cursor, 0); + EXPECT_EQUAL(test.write_cursor, test_data_size); + EXPECT_EQUAL(s2n_stuffer_data_available(&test), test_data_size); + EXPECT_BYTEARRAY_EQUAL(data, test_data, test_data_size); + } + + /* Data at offset: shifted */ + { + uint8_t data[100] = { 0 }; + struct s2n_stuffer test = { 0 }; + EXPECT_SUCCESS(s2n_blob_init(&test.blob, data, sizeof(data))); + + EXPECT_SUCCESS(s2n_stuffer_skip_write(&test, test_offset)); + EXPECT_SUCCESS(s2n_stuffer_skip_read(&test, test_offset)); + EXPECT_EQUAL(s2n_stuffer_data_available(&test), 0); + EXPECT_SUCCESS(s2n_stuffer_write_bytes(&test, test_data, test_data_size)); + EXPECT_EQUAL(s2n_stuffer_data_available(&test), test_data_size); + + EXPECT_SUCCESS(s2n_stuffer_shift(&test)); + EXPECT_EQUAL(test.read_cursor, 0); + EXPECT_EQUAL(test.write_cursor, test_data_size); + EXPECT_EQUAL(s2n_stuffer_data_available(&test), test_data_size); + EXPECT_BYTEARRAY_EQUAL(data, test_data, test_data_size); + } + + /* Data overlaps: shifted */ + { + uint8_t data[100] = { 0 }; + struct s2n_stuffer test = { 0 }; + EXPECT_SUCCESS(s2n_blob_init(&test.blob, data, sizeof(data))); + + /* Allocate data large enough that it will overlap when shifted. + * Allocate the entire block to distinctive data, not just all one character. + */ + uint8_t overlap_test_data[sizeof(data) - 1] = { 0 }; + for (size_t i = 0; i < sizeof(overlap_test_data); i++) { + overlap_test_data[i] = i; + } + size_t overlap_test_data_size = sizeof(overlap_test_data); + EXPECT_TRUE(overlap_test_data_size > sizeof(data) / 2); + + EXPECT_SUCCESS(s2n_stuffer_skip_write(&test, 1)); + EXPECT_SUCCESS(s2n_stuffer_skip_read(&test, 1)); + EXPECT_SUCCESS(s2n_stuffer_write_bytes(&test, + overlap_test_data, overlap_test_data_size)); + EXPECT_EQUAL(s2n_stuffer_data_available(&test), overlap_test_data_size); + EXPECT_EQUAL(s2n_stuffer_space_remaining(&test), 0); + + EXPECT_SUCCESS(s2n_stuffer_shift(&test)); + EXPECT_EQUAL(test.read_cursor, 0); + EXPECT_EQUAL(test.write_cursor, overlap_test_data_size); + EXPECT_EQUAL(s2n_stuffer_data_available(&test), overlap_test_data_size); + EXPECT_BYTEARRAY_EQUAL(data, overlap_test_data, overlap_test_data_size); + } + } + END_TEST(); } diff --git a/tests/unit/s2n_stuffer_text_test.c b/tests/unit/s2n_stuffer_text_test.c index 04a0a1ad94d..43b4f59c437 100644 --- a/tests/unit/s2n_stuffer_text_test.c +++ b/tests/unit/s2n_stuffer_text_test.c @@ -22,7 +22,7 @@ int main(int argc, char **argv) { - char c; + char c = 0; uint32_t skipped = 0; struct s2n_stuffer stuffer, token; struct s2n_blob pad_blob, token_blob; diff --git a/tests/unit/s2n_testlib_test.c b/tests/unit/s2n_testlib_test.c index 649ee081242..7dbd2da11e4 100644 --- a/tests/unit/s2n_testlib_test.c +++ b/tests/unit/s2n_testlib_test.c @@ -29,7 +29,7 @@ int main(int argc, char **argv) * We should always report the actual error to allow better debugging of tests. */ { - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); /* Create nonblocking pipes */ diff --git a/tests/unit/s2n_timer_test.c b/tests/unit/s2n_timer_test.c index 66a174dac66..e6874233369 100644 --- a/tests/unit/s2n_timer_test.c +++ b/tests/unit/s2n_timer_test.c @@ -26,10 +26,10 @@ int mock_clock(void *in, uint64_t *out) int main(int argc, char **argv) { - struct s2n_config *config; + struct s2n_config *config = NULL; struct s2n_timer timer; - uint64_t nanoseconds; - uint64_t mock_time; + uint64_t nanoseconds = 0; + uint64_t mock_time = 0; BEGIN_TEST(); EXPECT_SUCCESS(s2n_disable_tls13_in_test()); diff --git a/tests/unit/s2n_tls12_handshake_test.c b/tests/unit/s2n_tls12_handshake_test.c index 2ba2984d58a..3d1d784de74 100644 --- a/tests/unit/s2n_tls12_handshake_test.c +++ b/tests/unit/s2n_tls12_handshake_test.c @@ -449,7 +449,7 @@ int main(int argc, char **argv) conn->handshake.handshake_type = NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH | NO_CLIENT_CERT | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS | WITH_SESSION_TICKET | WITH_NPN; EXPECT_STRING_EQUAL(all_flags_handshake_type_name, s2n_connection_get_handshake_type_name(conn)); - const char *handshake_type_name; + const char *handshake_type_name = NULL; for (int i = 0; i < valid_tls12_handshakes_size; i++) { conn->handshake.handshake_type = valid_tls12_handshakes[i]; @@ -492,12 +492,9 @@ int main(int argc, char **argv) /* Test: A WITH_NPN form of every valid, negotiated handshake exists */ { - uint32_t handshake_type_original, handshake_type_npn; - message_type_t *messages_original, *messages_npn; - for (size_t i = 0; i < valid_tls12_handshakes_size; i++) { - handshake_type_original = valid_tls12_handshakes[i]; - messages_original = handshakes[handshake_type_original]; + uint32_t handshake_type_original = valid_tls12_handshakes[i]; + message_type_t *messages_original = handshakes[handshake_type_original]; /* Ignore INITIAL and WITH_NPN handshakes */ if (!(handshake_type_original & NEGOTIATED) || (handshake_type_original & WITH_NPN)) { @@ -505,8 +502,8 @@ int main(int argc, char **argv) } /* Get the WITH_NPN form of the handshake */ - handshake_type_npn = handshake_type_original | WITH_NPN; - messages_npn = handshakes[handshake_type_npn]; + uint32_t handshake_type_npn = handshake_type_original | WITH_NPN; + message_type_t *messages_npn = handshakes[handshake_type_npn]; for (size_t j = 0, j_npn = 0; j < S2N_MAX_HANDSHAKE_LENGTH && j_npn < S2N_MAX_HANDSHAKE_LENGTH; j++, j_npn++) { /* The original handshake cannot contain the Next Protocol message */ diff --git a/tests/unit/s2n_tls13_cert_request_extensions_test.c b/tests/unit/s2n_tls13_cert_request_extensions_test.c index 755d3065891..f4bb6e31496 100644 --- a/tests/unit/s2n_tls13_cert_request_extensions_test.c +++ b/tests/unit/s2n_tls13_cert_request_extensions_test.c @@ -33,7 +33,7 @@ int main(int argc, char **argv) /* Test correct required extension (sig_alg) sent and received */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); conn->actual_protocol_version = S2N_TLS13; @@ -47,7 +47,7 @@ int main(int argc, char **argv) /* Test client fails to parse certificate request with no extensions */ { - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); client_conn->actual_protocol_version = S2N_TLS13; diff --git a/tests/unit/s2n_tls13_cert_request_test.c b/tests/unit/s2n_tls13_cert_request_test.c index 6d51b8df75c..aa8d1f8ccf7 100644 --- a/tests/unit/s2n_tls13_cert_request_test.c +++ b/tests/unit/s2n_tls13_cert_request_test.c @@ -32,15 +32,15 @@ int main(int argc, char **argv) /* Test the output of s2n_tls13_cert_req_send() */ { - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); server_conn->actual_protocol_version = S2N_TLS13; EXPECT_SUCCESS(s2n_tls13_cert_req_send(server_conn)); /* verify output */ - uint8_t request_context_length; - uint16_t extensions_length, extension_size, extension_type; + uint8_t request_context_length = 0; + uint16_t extensions_length = 0, extension_size = 0, extension_type = 0; EXPECT_TRUE(s2n_stuffer_data_available(&server_conn->handshake.io) > 7); EXPECT_SUCCESS(s2n_stuffer_read_uint8(&server_conn->handshake.io, &request_context_length)); EXPECT_SUCCESS(s2n_stuffer_read_uint16(&server_conn->handshake.io, &extensions_length)); @@ -56,8 +56,8 @@ int main(int argc, char **argv) /* Test client can receive and parse certificate request */ { - struct s2n_connection *server_conn; - struct s2n_connection *client_conn; + struct s2n_connection *server_conn = NULL; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); server_conn->actual_protocol_version = S2N_TLS13; @@ -77,7 +77,7 @@ int main(int argc, char **argv) /* Test request context length other than 0 fails */ { - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); client_conn->actual_protocol_version = S2N_TLS13; diff --git a/tests/unit/s2n_tls13_cert_verify_test.c b/tests/unit/s2n_tls13_cert_verify_test.c index 7155f4ca347..27b9cb9c4de 100644 --- a/tests/unit/s2n_tls13_cert_verify_test.c +++ b/tests/unit/s2n_tls13_cert_verify_test.c @@ -46,18 +46,28 @@ int run_tests(const struct s2n_tls13_cert_verify_test *test_case, s2n_mode verif const char *key_file = test_case->key_file; struct s2n_signature_scheme sig_scheme = *test_case->sig_scheme; - struct s2n_config *config = NULL; - EXPECT_NOT_NULL(config = s2n_config_new()); + 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, "20200207")); + DEFER_CLEANUP(struct s2n_cert_chain_and_key *cert_chain = s2n_cert_chain_and_key_new(), + s2n_cert_chain_and_key_ptr_free); + EXPECT_NOT_NULL(cert_chain); + + char cert_chain_pem[S2N_MAX_TEST_PEM_SIZE] = { 0 }; + char private_key_pem[S2N_MAX_TEST_PEM_SIZE] = { 0 }; + + EXPECT_SUCCESS(s2n_read_test_pem(cert_file, &cert_chain_pem[0], S2N_MAX_TEST_PEM_SIZE)); + EXPECT_SUCCESS(s2n_read_test_pem(key_file, &private_key_pem[0], S2N_MAX_TEST_PEM_SIZE)); + EXPECT_SUCCESS(s2n_cert_chain_and_key_load_pem(cert_chain, cert_chain_pem, private_key_pem)); + + EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(config, cert_chain)); + /* Successfully send and receive certificate verify */ { /* Derive private/public keys and set connection variables */ struct s2n_stuffer certificate_in = { 0 }, certificate_out = { 0 }; struct s2n_blob b = { 0 }; - struct s2n_cert_chain_and_key *cert_chain = NULL; - char *cert_chain_pem = NULL; - char *private_key_pem = NULL; s2n_pkey_type pkey_type = { 0 }; struct s2n_connection *verifying_conn = NULL, *sending_conn = NULL; @@ -67,14 +77,7 @@ int run_tests(const struct s2n_tls13_cert_verify_test *test_case, s2n_mode verif EXPECT_SUCCESS(s2n_stuffer_alloc(&certificate_in, S2N_MAX_TEST_PEM_SIZE)); EXPECT_SUCCESS(s2n_stuffer_alloc(&certificate_out, S2N_MAX_TEST_PEM_SIZE)); - EXPECT_NOT_NULL(cert_chain = s2n_cert_chain_and_key_new()); - EXPECT_NOT_NULL(cert_chain_pem = malloc(S2N_MAX_TEST_PEM_SIZE)); - EXPECT_NOT_NULL(private_key_pem = malloc(S2N_MAX_TEST_PEM_SIZE)); - EXPECT_SUCCESS(s2n_read_test_pem(cert_file, cert_chain_pem, S2N_MAX_TEST_PEM_SIZE)); - EXPECT_SUCCESS(s2n_read_test_pem(key_file, private_key_pem, S2N_MAX_TEST_PEM_SIZE)); - EXPECT_SUCCESS(s2n_cert_chain_and_key_load_pem(cert_chain, cert_chain_pem, private_key_pem)); - - EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(config, cert_chain)); + EXPECT_SUCCESS(s2n_connection_set_config(sending_conn, config)); sending_conn->handshake_params.our_chain_and_key = cert_chain; sending_conn->handshake_params.server_cert_sig_scheme = &sig_scheme; @@ -125,9 +128,6 @@ int run_tests(const struct s2n_tls13_cert_verify_test *test_case, s2n_mode verif EXPECT_FAILURE(s2n_tls13_cert_verify_recv(verifying_conn)); /* Clean up */ - free(cert_chain_pem); - free(private_key_pem); - EXPECT_SUCCESS(s2n_cert_chain_and_key_free(cert_chain)); EXPECT_SUCCESS(s2n_stuffer_free(&certificate_in)); EXPECT_SUCCESS(s2n_stuffer_free(&certificate_out)); EXPECT_SUCCESS(s2n_connection_free(sending_conn)); @@ -139,25 +139,15 @@ int run_tests(const struct s2n_tls13_cert_verify_test *test_case, s2n_mode verif /* Derive private/public keys and set connection variables */ struct s2n_stuffer certificate_in = { 0 }, certificate_out = { 0 }; struct s2n_blob b = { 0 }; - struct s2n_cert_chain_and_key *cert_chain = NULL; - char *cert_chain_pem = NULL; - char *private_key_pem = NULL; uint64_t bytes_in_hash = 0; s2n_pkey_type pkey_type = { 0 }; EXPECT_SUCCESS(s2n_stuffer_alloc(&certificate_in, S2N_MAX_TEST_PEM_SIZE)); EXPECT_SUCCESS(s2n_stuffer_alloc(&certificate_out, S2N_MAX_TEST_PEM_SIZE)); - EXPECT_NOT_NULL(cert_chain = s2n_cert_chain_and_key_new()); - EXPECT_NOT_NULL(cert_chain_pem = malloc(S2N_MAX_TEST_PEM_SIZE)); - EXPECT_NOT_NULL(private_key_pem = malloc(S2N_MAX_TEST_PEM_SIZE)); - EXPECT_SUCCESS(s2n_read_test_pem(cert_file, cert_chain_pem, S2N_MAX_TEST_PEM_SIZE)); - EXPECT_SUCCESS(s2n_read_test_pem(key_file, private_key_pem, S2N_MAX_TEST_PEM_SIZE)); - EXPECT_SUCCESS(s2n_cert_chain_and_key_load_pem(cert_chain, cert_chain_pem, private_key_pem)); struct s2n_connection *verifying_conn = NULL; EXPECT_NOT_NULL(verifying_conn = s2n_connection_new(verifier_mode)); verifying_conn->actual_protocol_version = S2N_TLS13; - EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(config, cert_chain)); EXPECT_SUCCESS(s2n_connection_set_config(verifying_conn, config)); verifying_conn->handshake_params.our_chain_and_key = cert_chain; verifying_conn->handshake_params.server_cert_sig_scheme = &sig_scheme; @@ -197,9 +187,6 @@ int run_tests(const struct s2n_tls13_cert_verify_test *test_case, s2n_mode verif EXPECT_SUCCESS(s2n_pkey_free(&verifying_conn->handshake_params.client_public_key)); /* Clean up */ - free(cert_chain_pem); - free(private_key_pem); - EXPECT_SUCCESS(s2n_cert_chain_and_key_free(cert_chain)); EXPECT_SUCCESS(s2n_stuffer_free(&certificate_in)); EXPECT_SUCCESS(s2n_stuffer_free(&certificate_out)); EXPECT_SUCCESS(s2n_connection_free(verifying_conn)); @@ -209,24 +196,14 @@ int run_tests(const struct s2n_tls13_cert_verify_test *test_case, s2n_mode verif { struct s2n_stuffer certificate_in = { 0 }, certificate_out = { 0 }; struct s2n_blob b = { 0 }; - struct s2n_cert_chain_and_key *cert_chain = NULL; - char *cert_chain_pem = NULL; - char *private_key_pem = NULL; s2n_pkey_type pkey_type = { 0 }; EXPECT_SUCCESS(s2n_stuffer_alloc(&certificate_in, S2N_MAX_TEST_PEM_SIZE)); EXPECT_SUCCESS(s2n_stuffer_alloc(&certificate_out, S2N_MAX_TEST_PEM_SIZE)); - EXPECT_NOT_NULL(cert_chain = s2n_cert_chain_and_key_new()); - EXPECT_NOT_NULL(cert_chain_pem = malloc(S2N_MAX_TEST_PEM_SIZE)); - EXPECT_NOT_NULL(private_key_pem = malloc(S2N_MAX_TEST_PEM_SIZE)); - EXPECT_SUCCESS(s2n_read_test_pem(cert_file, cert_chain_pem, S2N_MAX_TEST_PEM_SIZE)); - EXPECT_SUCCESS(s2n_read_test_pem(key_file, private_key_pem, S2N_MAX_TEST_PEM_SIZE)); - EXPECT_SUCCESS(s2n_cert_chain_and_key_load_pem(cert_chain, cert_chain_pem, private_key_pem)); struct s2n_connection *verifying_conn = NULL; EXPECT_NOT_NULL(verifying_conn = s2n_connection_new(verifier_mode)); verifying_conn->actual_protocol_version = S2N_TLS13; - EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(config, cert_chain)); EXPECT_SUCCESS(s2n_connection_set_config(verifying_conn, config)); verifying_conn->handshake_params.our_chain_and_key = cert_chain; verifying_conn->handshake_params.server_cert_sig_scheme = &sig_scheme; @@ -267,9 +244,6 @@ int run_tests(const struct s2n_tls13_cert_verify_test *test_case, s2n_mode verif EXPECT_SUCCESS(s2n_pkey_free(&verifying_conn->handshake_params.client_public_key)); } - free(cert_chain_pem); - free(private_key_pem); - EXPECT_SUCCESS(s2n_cert_chain_and_key_free(cert_chain)); EXPECT_SUCCESS(s2n_stuffer_free(&certificate_in)); EXPECT_SUCCESS(s2n_stuffer_free(&certificate_out)); EXPECT_SUCCESS(s2n_connection_free(verifying_conn)); @@ -280,23 +254,13 @@ int run_tests(const struct s2n_tls13_cert_verify_test *test_case, s2n_mode verif /* Derive private/public keys and set connection variables */ struct s2n_stuffer certificate_in = { 0 }, certificate_out = { 0 }; struct s2n_blob b = { 0 }; - struct s2n_cert_chain_and_key *cert_chain = NULL; - char *cert_chain_pem = NULL; - char *private_key_pem = NULL; s2n_pkey_type pkey_type = { 0 }; EXPECT_SUCCESS(s2n_stuffer_alloc(&certificate_in, S2N_MAX_TEST_PEM_SIZE)); EXPECT_SUCCESS(s2n_stuffer_alloc(&certificate_out, S2N_MAX_TEST_PEM_SIZE)); - EXPECT_NOT_NULL(cert_chain = s2n_cert_chain_and_key_new()); - EXPECT_NOT_NULL(cert_chain_pem = malloc(S2N_MAX_TEST_PEM_SIZE)); - EXPECT_NOT_NULL(private_key_pem = malloc(S2N_MAX_TEST_PEM_SIZE)); - EXPECT_SUCCESS(s2n_read_test_pem(cert_file, cert_chain_pem, S2N_MAX_TEST_PEM_SIZE)); - EXPECT_SUCCESS(s2n_read_test_pem(key_file, private_key_pem, S2N_MAX_TEST_PEM_SIZE)); - EXPECT_SUCCESS(s2n_cert_chain_and_key_load_pem(cert_chain, cert_chain_pem, private_key_pem)); struct s2n_connection *verifying_conn = NULL; EXPECT_NOT_NULL(verifying_conn = s2n_connection_new(verifier_mode)); - EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(config, cert_chain)); EXPECT_SUCCESS(s2n_connection_set_config(verifying_conn, config)); verifying_conn->handshake_params.our_chain_and_key = cert_chain; verifying_conn->handshake_params.server_cert_sig_scheme = &sig_scheme; @@ -358,16 +322,10 @@ int run_tests(const struct s2n_tls13_cert_verify_test *test_case, s2n_mode verif EXPECT_SUCCESS(s2n_pkey_free(&verifying_conn->handshake_params.client_public_key)); } - free(cert_chain_pem); - free(private_key_pem); - EXPECT_SUCCESS(s2n_cert_chain_and_key_free(cert_chain)); EXPECT_SUCCESS(s2n_stuffer_free(&certificate_in)); EXPECT_SUCCESS(s2n_stuffer_free(&certificate_out)); EXPECT_SUCCESS(s2n_connection_free(verifying_conn)); }; - - EXPECT_SUCCESS(s2n_config_free(config)); - return 0; } diff --git a/tests/unit/s2n_tls13_client_finished_test.c b/tests/unit/s2n_tls13_client_finished_test.c index dfdba69dde6..b51afb7cfd2 100644 --- a/tests/unit/s2n_tls13_client_finished_test.c +++ b/tests/unit/s2n_tls13_client_finished_test.c @@ -45,7 +45,7 @@ int main(int argc, char **argv) }; for (int i = 0; i < 3; i++) { - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); client_conn->actual_protocol_version = S2N_TLS13; @@ -56,7 +56,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_tls13_client_finished_send(client_conn)); EXPECT_EQUAL(s2n_stuffer_data_available(&client_conn->handshake.io), hash_size); - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_CLIENT)); server_conn->actual_protocol_version = S2N_TLS13; server_conn->secure->cipher_suite = &cipher_suites[i]; @@ -95,7 +95,7 @@ int main(int argc, char **argv) /* Test that they can only run in TLS 1.3 mode */ { - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); client_conn->secure->cipher_suite = &s2n_tls13_aes_256_gcm_sha384; @@ -106,7 +106,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_tls13_client_finished_send(client_conn)); EXPECT_EQUAL(s2n_stuffer_data_available(&client_conn->handshake.io), 48); - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_CLIENT)); server_conn->secure->cipher_suite = &s2n_tls13_aes_256_gcm_sha384; @@ -119,7 +119,7 @@ int main(int argc, char **argv) /* Test for failure cases if cipher suites are incompatible */ { - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); client_conn->actual_protocol_version = S2N_TLS13; @@ -128,7 +128,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_tls13_client_finished_send(client_conn)); EXPECT_EQUAL(s2n_stuffer_data_available(&client_conn->handshake.io), 32); - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_CLIENT)); server_conn->actual_protocol_version = S2N_TLS13; server_conn->secure->cipher_suite = &s2n_tls13_aes_256_gcm_sha384; @@ -143,7 +143,7 @@ int main(int argc, char **argv) /* Test for failure cases when finished secret key differs */ { - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); client_conn->actual_protocol_version = S2N_TLS13; @@ -152,7 +152,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_tls13_client_finished_send(client_conn)); EXPECT_EQUAL(s2n_stuffer_data_available(&client_conn->handshake.io), 48); - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_CLIENT)); server_conn->actual_protocol_version = S2N_TLS13; server_conn->secure->cipher_suite = &s2n_tls13_aes_256_gcm_sha384; diff --git a/tests/unit/s2n_tls13_compute_shared_secret_test.c b/tests/unit/s2n_tls13_compute_shared_secret_test.c index 69e4e97d13c..994ae9c2480 100644 --- a/tests/unit/s2n_tls13_compute_shared_secret_test.c +++ b/tests/unit/s2n_tls13_compute_shared_secret_test.c @@ -40,7 +40,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(config, cert_chain)); EXPECT_SUCCESS(s2n_config_set_cipher_preferences(config, "default_tls13")); - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; /* This test ensures that if the server did not send a keyshare extension in the server hello function, * a null pointer error is correctly thrown. diff --git a/tests/unit/s2n_tls13_handshake_state_machine_test.c b/tests/unit/s2n_tls13_handshake_state_machine_test.c index 963d195e11f..b9848188772 100644 --- a/tests/unit/s2n_tls13_handshake_state_machine_test.c +++ b/tests/unit/s2n_tls13_handshake_state_machine_test.c @@ -121,8 +121,8 @@ int main(int argc, char **argv) * message and client CCS messages. */ { - uint32_t original_handshake_type, early_data_handshake_type; - message_type_t *original_messages, *early_data_messages; + uint32_t original_handshake_type = 0, early_data_handshake_type = 0; + message_type_t *original_messages = NULL, *early_data_messages = NULL; for (size_t i = 0; i < valid_tls13_handshakes_size; i++) { original_handshake_type = valid_tls13_handshakes[i]; @@ -183,8 +183,8 @@ int main(int argc, char **argv) /* Test: A MIDDLEBOX_COMPAT form of every valid, negotiated handshake exists * and matches the non-MIDDLEBOX_COMPAT form EXCEPT for CCS messages */ { - uint32_t handshake_type_original, handshake_type_mc; - message_type_t *messages_original, *messages_mc; + uint32_t handshake_type_original = 0, handshake_type_mc = 0; + message_type_t *messages_original = NULL, *messages_mc = NULL; for (size_t i = 0; i < valid_tls13_handshakes_size; i++) { handshake_type_original = valid_tls13_handshakes[i]; @@ -218,8 +218,8 @@ int main(int argc, char **argv) /* Test: A non-FULL_HANDSHAKE form of every valid, negotiated handshake exists */ { - uint32_t handshake_type_original, handshake_type_fh; - message_type_t *messages_original, *messages_fh; + uint32_t handshake_type_original = 0, handshake_type_fh = 0; + message_type_t *messages_original = NULL, *messages_fh = NULL; for (size_t i = 0; i < valid_tls13_handshakes_size; i++) { handshake_type_original = valid_tls13_handshakes[i]; @@ -264,8 +264,8 @@ int main(int argc, char **argv) /* Test: A EARLY_CLIENT_CCS form of every middlebox compatible handshake exists. * Any handshake could start with early data, even if that early data is later rejected. */ { - uint32_t handshake_type_original, handshake_type_test; - message_type_t *messages_original, *messages_test; + uint32_t handshake_type_original = 0, handshake_type_test = 0; + message_type_t *messages_original = NULL, *messages_test = NULL; for (size_t i = 0; i < valid_tls13_handshakes_size; i++) { handshake_type_original = valid_tls13_handshakes[i]; @@ -655,10 +655,6 @@ int main(int argc, char **argv) *# the TLS 1.3 handshake look more like a TLS 1.2 handshake: */ { - bool change_cipher_spec_found; - uint32_t handshake_type; - message_type_t *messages; - /* *= https://tools.ietf.org/rfc/rfc8446#appendix-D.4 *= type=test @@ -668,9 +664,9 @@ int main(int argc, char **argv) *# its second ClientHello or before its encrypted handshake flight. **/ for (size_t i = 0; i < valid_tls13_handshakes_size; i++) { - change_cipher_spec_found = false; - handshake_type = valid_tls13_handshakes[i]; - messages = tls13_handshakes[handshake_type]; + bool change_cipher_spec_found = false; + uint32_t handshake_type = valid_tls13_handshakes[i]; + message_type_t *messages = tls13_handshakes[handshake_type]; /* Ignore INITIAL and non-MIDDLEBOX_COMPAT handshakes */ if (!(handshake_type & NEGOTIATED) @@ -705,8 +701,8 @@ int main(int argc, char **argv) *# first ClientHello. */ for (size_t i = 0; i < valid_tls13_handshakes_size; i++) { - handshake_type = valid_tls13_handshakes[i]; - messages = tls13_handshakes[handshake_type]; + uint32_t handshake_type = valid_tls13_handshakes[i]; + message_type_t *messages = tls13_handshakes[handshake_type]; /* Ignore handshakes where early data did not trigger the change in CCS behavior */ if (!(handshake_type & EARLY_CLIENT_CCS)) { @@ -728,9 +724,9 @@ int main(int argc, char **argv) *# ServerHello or a HelloRetryRequest. **/ for (size_t i = 0; i < valid_tls13_handshakes_size; i++) { - change_cipher_spec_found = false; - handshake_type = valid_tls13_handshakes[i]; - messages = tls13_handshakes[handshake_type]; + bool change_cipher_spec_found = false; + uint32_t handshake_type = valid_tls13_handshakes[i]; + message_type_t *messages = tls13_handshakes[handshake_type]; /* Ignore INITIAL and non-MIDDLEBOX_COMPAT handshakes */ if (!(handshake_type & NEGOTIATED) || !(handshake_type & MIDDLEBOX_COMPAT)) { @@ -766,7 +762,7 @@ int main(int argc, char **argv) conn->session_ticket_status = S2N_NEW_TICKET; /* Ensure CLIENT_AUTH is set */ - conn->config->client_cert_auth_type = S2N_CERT_AUTH_REQUIRED; + EXPECT_SUCCESS(s2n_connection_set_client_auth_type(conn, S2N_CERT_AUTH_REQUIRED)); /* Ensure TLS12_PERFECT_FORWARD_SECRECY is set by choosing a cipher suite with is_ephemeral=1 on the kex */ conn->secure->cipher_suite = &s2n_dhe_rsa_with_chacha20_poly1305_sha256; @@ -937,7 +933,7 @@ int main(int argc, char **argv) | MIDDLEBOX_COMPAT | WITH_EARLY_DATA | EARLY_CLIENT_CCS; EXPECT_STRING_EQUAL(all_flags_handshake_type_name, s2n_connection_get_handshake_type_name(conn)); - const char *handshake_type_name; + const char *handshake_type_name = NULL; for (int i = 0; i < valid_tls13_handshakes_size; i++) { conn->handshake.handshake_type = valid_tls13_handshakes[i]; diff --git a/tests/unit/s2n_tls13_handshake_test.c b/tests/unit/s2n_tls13_handshake_test.c index a5179800cdc..114d9828886 100644 --- a/tests/unit/s2n_tls13_handshake_test.c +++ b/tests/unit/s2n_tls13_handshake_test.c @@ -51,7 +51,7 @@ int main(int argc, char **argv) { /* PSKs are wiped when chosen PSK is NULL */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); const struct s2n_ecc_preferences *ecc_preferences = NULL; @@ -99,7 +99,7 @@ int main(int argc, char **argv) /* PSKs are wiped when chosen PSK is NOT NULL */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); const struct s2n_ecc_preferences *ecc_preferences = NULL; @@ -161,10 +161,10 @@ int main(int argc, char **argv) /* Test: Handshake self-talks using s2n_handshake_write_io and s2n_handshake_read_io */ { - struct s2n_connection *client_conn; - struct s2n_connection *server_conn; + struct s2n_connection *client_conn = NULL; + struct s2n_connection *server_conn = NULL; - struct s2n_config *server_config, *client_config; + struct s2n_config *server_config = NULL, *client_config = NULL; EXPECT_NOT_NULL(server_config = s2n_config_new()); EXPECT_NOT_NULL(client_config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_set_unsafe_for_testing(client_config)); @@ -180,7 +180,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_read_test_pem_and_len(S2N_ECDSA_P384_PKCS1_CERT_CHAIN, cert_chain, &cert_chain_len, S2N_MAX_TEST_PEM_SIZE)); EXPECT_SUCCESS(s2n_read_test_pem_and_len(S2N_ECDSA_P384_PKCS1_KEY, private_key, &private_key_len, S2N_MAX_TEST_PEM_SIZE)); - struct s2n_cert_chain_and_key *default_cert; + struct s2n_cert_chain_and_key *default_cert = NULL; EXPECT_NOT_NULL(default_cert = s2n_cert_chain_and_key_new()); EXPECT_SUCCESS(s2n_cert_chain_and_key_load_pem_bytes(default_cert, cert_chain, cert_chain_len, private_key, private_key_len)); EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(server_config, default_cert)); diff --git a/tests/unit/s2n_tls13_keys_test.c b/tests/unit/s2n_tls13_keys_test.c index d9b68228ebc..ba48ab87206 100644 --- a/tests/unit/s2n_tls13_keys_test.c +++ b/tests/unit/s2n_tls13_keys_test.c @@ -47,7 +47,7 @@ int main(int argc, char **argv) "ee85dd54781bd4d8a100589a9fe6ac9a3797b811e977f549cd" "531be2441d7c63e2b9729d145c11d84af35957727565a4"); - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); server_conn->actual_protocol_version = S2N_TLS13; server_conn->secure->cipher_suite = &s2n_tls13_aes_256_gcm_sha384; diff --git a/tests/unit/s2n_tls13_new_session_ticket_test.c b/tests/unit/s2n_tls13_new_session_ticket_test.c index a3a684712c8..627299e7214 100644 --- a/tests/unit/s2n_tls13_new_session_ticket_test.c +++ b/tests/unit/s2n_tls13_new_session_ticket_test.c @@ -90,7 +90,7 @@ int main(int argc, char **argv) struct s2n_config *client_config = s2n_config_new(); EXPECT_NOT_NULL(client_config); - struct s2n_cert_chain_and_key *chain_and_key; + struct s2n_cert_chain_and_key *chain_and_key = NULL; EXPECT_SUCCESS(s2n_test_cert_chain_and_key_new(&chain_and_key, S2N_DEFAULT_ECDSA_TEST_CERT_CHAIN, S2N_DEFAULT_ECDSA_TEST_PRIVATE_KEY)); EXPECT_SUCCESS(s2n_config_set_session_tickets_onoff(server_config, 1)); diff --git a/tests/unit/s2n_tls13_parse_record_type_test.c b/tests/unit/s2n_tls13_parse_record_type_test.c index 0372b229261..0b5393e9405 100644 --- a/tests/unit/s2n_tls13_parse_record_type_test.c +++ b/tests/unit/s2n_tls13_parse_record_type_test.c @@ -27,7 +27,7 @@ int main(int argc, char **argv) BEGIN_TEST(); EXPECT_SUCCESS(s2n_disable_tls13_in_test()); - uint8_t record_type; + uint8_t record_type = 0; /* In tls13 the true record type is inserted in the last byte of the encrypted payload. This * test creates a fake unencrypted payload and checks that the helper function diff --git a/tests/unit/s2n_tls13_prf_test.c b/tests/unit/s2n_tls13_prf_test.c index bbee3e26143..2231a642627 100644 --- a/tests/unit/s2n_tls13_prf_test.c +++ b/tests/unit/s2n_tls13_prf_test.c @@ -75,25 +75,25 @@ int main(int argc, char **argv) /* Parse the hex */ for (size_t i = 0; i < sizeof(client_handshake_message); i++) { - uint8_t c; + uint8_t c = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint8_hex(&client_handshake_message_in, &c)); client_handshake_message[i] = c; } for (size_t i = 0; i < sizeof(server_handshake_message); i++) { - uint8_t c; + uint8_t c = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint8_hex(&server_handshake_message_in, &c)); server_handshake_message[i] = c; } for (size_t i = 0; i < sizeof(expected_secret); i++) { - uint8_t c; + uint8_t c = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint8_hex(&expected_secret_in, &c)); expected_secret[i] = c; } for (size_t i = 0; i < sizeof(expected_expanded); i++) { - uint8_t c; + uint8_t c = 0; EXPECT_SUCCESS(s2n_stuffer_read_uint8_hex(&expected_expanded_in, &c)); expected_expanded[i] = c; } diff --git a/tests/unit/s2n_tls13_record_aead_test.c b/tests/unit/s2n_tls13_record_aead_test.c index dc4eb470fd4..572cff43bbf 100644 --- a/tests/unit/s2n_tls13_record_aead_test.c +++ b/tests/unit/s2n_tls13_record_aead_test.c @@ -127,7 +127,7 @@ int main(int argc, char **argv) /* Test s2n_tls13_aes_128_gcm_sha256 cipher suite with TLS 1.3 test vectors */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; struct s2n_session_key session_key = { 0 }; EXPECT_SUCCESS(s2n_session_key_alloc(&session_key)); @@ -211,7 +211,7 @@ int main(int argc, char **argv) /* Test s2n_tls13_aes_128_gcm_sha256 cipher suite ENCRYPTION with TLS 1.3 test vectors */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; struct s2n_cipher_suite *cipher_suite = &s2n_tls13_aes_128_gcm_sha256; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); conn->actual_protocol_version = S2N_TLS13; @@ -268,7 +268,7 @@ int main(int argc, char **argv) /* Test encrypt-decrypt roundtrip */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; struct s2n_cipher_suite *cipher_suite = &s2n_tls13_aes_128_gcm_sha256; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); conn->actual_protocol_version = S2N_TLS13; @@ -338,7 +338,7 @@ int main(int argc, char **argv) { s2n_mode modes[] = { S2N_SERVER, S2N_CLIENT }; for (size_t m = 0; m < s2n_array_len(modes); m++) { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; struct s2n_cipher_suite *cipher_suite = &s2n_tls13_aes_128_gcm_sha256; EXPECT_NOT_NULL(conn = s2n_connection_new(modes[m])); conn->actual_protocol_version = S2N_TLS13; diff --git a/tests/unit/s2n_tls13_secrets_test.c b/tests/unit/s2n_tls13_secrets_test.c index 32779e94cb4..427acb7a8f1 100644 --- a/tests/unit/s2n_tls13_secrets_test.c +++ b/tests/unit/s2n_tls13_secrets_test.c @@ -410,9 +410,7 @@ int main(int argc, char **argv) EXPECT_BYTEARRAY_EQUAL(conn->secrets.version.tls13.server_handshake_secret, empty_secret, sizeof(empty_secret)); - while (s2n_conn_get_current_message_type(conn) != SERVER_HELLO) { - conn->handshake.message_number++; - } + EXPECT_OK(s2n_connection_set_test_message_type(conn, SERVER_HELLO)); EXPECT_OK(s2n_tls13_secrets_update(conn)); EXPECT_BYTEARRAY_NOT_EQUAL(conn->secrets.version.tls13.client_handshake_secret, @@ -434,9 +432,7 @@ int main(int argc, char **argv) EXPECT_BYTEARRAY_EQUAL(conn->handshake.server_finished, empty_secret, sizeof(empty_secret)); - while (s2n_conn_get_current_message_type(conn) != SERVER_HELLO) { - conn->handshake.message_number++; - } + EXPECT_OK(s2n_connection_set_test_message_type(conn, SERVER_HELLO)); EXPECT_OK(s2n_tls13_secrets_update(conn)); uint8_t expected_len = 0; @@ -460,9 +456,7 @@ int main(int argc, char **argv) EXPECT_BYTEARRAY_EQUAL(conn->secrets.version.tls13.server_app_secret, empty_secret, sizeof(empty_secret)); - while (s2n_conn_get_current_message_type(conn) != SERVER_FINISHED) { - conn->handshake.message_number++; - } + EXPECT_OK(s2n_connection_set_test_message_type(conn, SERVER_FINISHED)); EXPECT_OK(s2n_tls13_secrets_update(conn)); EXPECT_BYTEARRAY_NOT_EQUAL(conn->secrets.version.tls13.client_app_secret, @@ -481,9 +475,7 @@ int main(int argc, char **argv) EXPECT_BYTEARRAY_EQUAL(conn->secrets.version.tls13.resumption_master_secret, empty_secret, sizeof(empty_secret)); - while (s2n_conn_get_current_message_type(conn) != CLIENT_FINISHED) { - conn->handshake.message_number++; - } + EXPECT_OK(s2n_connection_set_test_message_type(conn, CLIENT_FINISHED)); EXPECT_OK(s2n_tls13_secrets_update(conn)); EXPECT_BYTEARRAY_NOT_EQUAL(conn->secrets.version.tls13.resumption_master_secret, @@ -503,9 +495,7 @@ int main(int argc, char **argv) EXPECT_BYTEARRAY_EQUAL(conn->secrets.version.tls13.exporter_master_secret, empty_secret, sizeof(empty_secret)); - while (s2n_conn_get_current_message_type(conn) != SERVER_FINISHED) { - conn->handshake.message_number++; - } + EXPECT_OK(s2n_connection_set_test_message_type(conn, SERVER_FINISHED)); EXPECT_OK(s2n_tls13_secrets_update(conn)); EXPECT_BYTEARRAY_NOT_EQUAL(conn->secrets.version.tls13.exporter_master_secret, diff --git a/tests/unit/s2n_tls13_server_cert_test.c b/tests/unit/s2n_tls13_server_cert_test.c index 26c8c7cacbe..da9e6e6994d 100644 --- a/tests/unit/s2n_tls13_server_cert_test.c +++ b/tests/unit/s2n_tls13_server_cert_test.c @@ -92,7 +92,7 @@ int main(int argc, char **argv) /* Test s2n_server_cert_recv() parses tls13 certificate */ { S2N_BLOB_FROM_HEX(tls13_cert, tls13_cert_message_hex); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); conn->x509_validator.skip_cert_validation = 1; @@ -115,7 +115,7 @@ int main(int argc, char **argv) /* Test s2n_server_cert_send() verify server's certificate */ { - char *tls13_cert_chain_hex; + char *tls13_cert_chain_hex = NULL; /* creating a certificate chain by concatenating 1. chain header 2. certificate @@ -130,8 +130,8 @@ int main(int argc, char **argv) S2N_BLOB_FROM_HEX(tls13_cert_chain, tls13_cert_hex); - struct s2n_connection *conn; - uint8_t certificate_request_context_len; + struct s2n_connection *conn = NULL; + uint8_t certificate_request_context_len = 0; struct s2n_cert cert = { .raw = tls13_cert_chain, .next = NULL }; /* .chain_size is size of cert + 3 for the 3 bytes to express the length */ @@ -172,8 +172,8 @@ int main(int argc, char **argv) { EXPECT_SUCCESS(s2n_enable_tls13_in_test()); - struct s2n_connection *server_conn; - struct s2n_connection *client_conn; + struct s2n_connection *server_conn = NULL; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); server_conn->actual_protocol_version = S2N_TLS13; diff --git a/tests/unit/s2n_tls13_server_finished_test.c b/tests/unit/s2n_tls13_server_finished_test.c index 128290a422d..cc4bfcee9ec 100644 --- a/tests/unit/s2n_tls13_server_finished_test.c +++ b/tests/unit/s2n_tls13_server_finished_test.c @@ -45,7 +45,7 @@ int main(int argc, char **argv) }; for (int i = 0; i < 3; i++) { - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_CLIENT)); server_conn->actual_protocol_version = S2N_TLS13; @@ -56,7 +56,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_tls13_server_finished_send(server_conn)); EXPECT_EQUAL(s2n_stuffer_data_available(&server_conn->handshake.io), hash_size); - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); client_conn->actual_protocol_version = S2N_TLS13; client_conn->secure->cipher_suite = &cipher_suites[i]; @@ -95,7 +95,7 @@ int main(int argc, char **argv) /* Test that they can only run in TLS 1.3 mode */ { - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_CLIENT)); server_conn->secure->cipher_suite = &s2n_tls13_aes_256_gcm_sha384; @@ -106,7 +106,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_tls13_server_finished_send(server_conn)); EXPECT_EQUAL(s2n_stuffer_data_available(&server_conn->handshake.io), 48); - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); client_conn->secure->cipher_suite = &s2n_tls13_aes_256_gcm_sha384; @@ -119,7 +119,7 @@ int main(int argc, char **argv) /* Test for failure cases if cipher suites are incompatible */ { - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_CLIENT)); server_conn->actual_protocol_version = S2N_TLS13; @@ -128,7 +128,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_tls13_server_finished_send(server_conn)); EXPECT_EQUAL(s2n_stuffer_data_available(&server_conn->handshake.io), 32); - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); client_conn->actual_protocol_version = S2N_TLS13; client_conn->secure->cipher_suite = &s2n_tls13_aes_256_gcm_sha384; @@ -143,7 +143,7 @@ int main(int argc, char **argv) /* Test for failure cases when finished secret key differs */ { - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_CLIENT)); server_conn->actual_protocol_version = S2N_TLS13; @@ -152,7 +152,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_tls13_server_finished_send(server_conn)); EXPECT_EQUAL(s2n_stuffer_data_available(&server_conn->handshake.io), 48); - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); client_conn->actual_protocol_version = S2N_TLS13; client_conn->secure->cipher_suite = &s2n_tls13_aes_256_gcm_sha384; diff --git a/tests/unit/s2n_tls13_support_test.c b/tests/unit/s2n_tls13_support_test.c index 23c2959e261..867bb278c47 100644 --- a/tests/unit/s2n_tls13_support_test.c +++ b/tests/unit/s2n_tls13_support_test.c @@ -37,12 +37,12 @@ int main(int argc, char **argv) { /* Client does not support or configure TLS 1.3 */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_NOT_EQUAL(conn->client_protocol_version, S2N_TLS13); - const struct s2n_security_policy *security_policy; + const struct s2n_security_policy *security_policy = NULL; EXPECT_SUCCESS(s2n_connection_get_security_policy(conn, &security_policy)); EXPECT_FALSE(s2n_security_policy_supports_tls13(security_policy)); @@ -51,12 +51,12 @@ int main(int argc, char **argv) /* Server does not support or configure TLS 1.3 */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_NOT_EQUAL(conn->server_protocol_version, S2N_TLS13); - const struct s2n_security_policy *security_policy; + const struct s2n_security_policy *security_policy = NULL; EXPECT_SUCCESS(s2n_connection_get_security_policy(conn, &security_policy)); EXPECT_FALSE(s2n_security_policy_supports_tls13(security_policy)); @@ -75,12 +75,12 @@ int main(int argc, char **argv) { /* Client supports and configures TLS 1.3 */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); EXPECT_EQUAL(conn->client_protocol_version, S2N_TLS13); - const struct s2n_security_policy *security_policy; + const struct s2n_security_policy *security_policy = NULL; EXPECT_SUCCESS(s2n_connection_get_security_policy(conn, &security_policy)); EXPECT_TRUE(s2n_security_policy_supports_tls13(security_policy)); @@ -89,12 +89,12 @@ int main(int argc, char **argv) /* Server supports and configures TLS 1.3 */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_EQUAL(conn->server_protocol_version, S2N_TLS13); - const struct s2n_security_policy *security_policy; + const struct s2n_security_policy *security_policy = NULL; EXPECT_SUCCESS(s2n_connection_get_security_policy(conn, &security_policy)); EXPECT_TRUE(s2n_security_policy_supports_tls13(security_policy)); @@ -148,7 +148,7 @@ int main(int argc, char **argv) EXPECT_NOT_NULL(tls13_server_hello_extensions); EXPECT_TRUE(tls13_server_hello_extensions->count > 0); - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_allow_all_response_extensions(server_conn)); @@ -159,7 +159,7 @@ int main(int argc, char **argv) s2n_parsed_extensions_list parsed_extension_list = { 0 }; for (size_t i = 0; i < tls13_server_hello_extensions->count; i++) { const s2n_extension_type *tls13_extension_type = tls13_server_hello_extensions->extension_types[i]; - s2n_extension_type_id extension_id; + s2n_extension_type_id extension_id = 0; EXPECT_SUCCESS(s2n_extension_supported_iana_value_to_id(tls13_extension_type->iana_value, &extension_id)); s2n_parsed_extension *parsed_extension = &parsed_extension_list.parsed_extensions[extension_id]; diff --git a/tests/unit/s2n_tls13_zero_length_payload_test.c b/tests/unit/s2n_tls13_zero_length_payload_test.c index 4c3239a0cd6..337ebb211aa 100644 --- a/tests/unit/s2n_tls13_zero_length_payload_test.c +++ b/tests/unit/s2n_tls13_zero_length_payload_test.c @@ -51,12 +51,12 @@ int main(int argc, char **argv) *# TLSInnerPlaintext.content if the sender desires. **/ { - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); server_conn->actual_protocol_version = S2N_TLS13; EXPECT_OK(s2n_connection_set_secrets(server_conn)); - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); client_conn->actual_protocol_version = S2N_TLS13; EXPECT_OK(s2n_connection_set_secrets(client_conn)); @@ -81,8 +81,8 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_flush(server_conn, &blocked)); EXPECT_TRUE(s2n_stuffer_data_available(&server_to_client) > 0); - uint8_t record_type; - int isSSLv2; + uint8_t record_type = 0; + int isSSLv2 = 0; EXPECT_SUCCESS(s2n_read_full_record(server_conn, &record_type, &isSSLv2)); EXPECT_EQUAL(record_type, TLS_APPLICATION_DATA); @@ -103,11 +103,11 @@ int main(int argc, char **argv) *# implementation MUST terminate the connection with an "unexpected_message" alert. **/ { - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); server_conn->actual_protocol_version = S2N_TLS13; - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); client_conn->actual_protocol_version = S2N_TLS13; @@ -142,11 +142,11 @@ int main(int argc, char **argv) *# implementation MUST terminate the connection with an "unexpected_message" alert. **/ { - struct s2n_connection *server_conn; + struct s2n_connection *server_conn = NULL; EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); server_conn->actual_protocol_version = S2N_TLS13; - struct s2n_connection *client_conn; + struct s2n_connection *client_conn = NULL; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); client_conn->actual_protocol_version = S2N_TLS13; diff --git a/tests/unit/s2n_tls_hybrid_prf_test.c b/tests/unit/s2n_tls_hybrid_prf_test.c index 6c910904bd2..0e93b8a64fb 100644 --- a/tests/unit/s2n_tls_hybrid_prf_test.c +++ b/tests/unit/s2n_tls_hybrid_prf_test.c @@ -55,7 +55,7 @@ int main(int argc, char **argv) POSIX_ENSURE_GT(fscanf(kat_file, "%u", &count), 0); POSIX_ENSURE_EQ(count, i); - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); conn->actual_protocol_version = S2N_TLS12; /* Really only need for the hash function in the PRF */ @@ -70,7 +70,7 @@ int main(int argc, char **argv) POSIX_GUARD(FindMarker(kat_file, "premaster_kem_secret_length = ")); POSIX_ENSURE_GT(fscanf(kat_file, "%u", &premaster_kem_secret_length), 0); - uint8_t *premaster_kem_secret; + uint8_t *premaster_kem_secret = NULL; POSIX_ENSURE_REF(premaster_kem_secret = malloc(premaster_kem_secret_length)); POSIX_GUARD(ReadHex(kat_file, premaster_kem_secret, premaster_kem_secret_length, "premaster_kem_secret = ")); @@ -80,7 +80,7 @@ int main(int argc, char **argv) POSIX_GUARD(FindMarker(kat_file, "client_key_exchange_message_length = ")); POSIX_ENSURE_GT(fscanf(kat_file, "%u", &client_key_exchange_message_length), 0); - uint8_t *client_key_exchange_message; + uint8_t *client_key_exchange_message = NULL; POSIX_ENSURE_REF(client_key_exchange_message = malloc(client_key_exchange_message_length)); POSIX_GUARD(ReadHex(kat_file, client_key_exchange_message, client_key_exchange_message_length, "client_key_exchange_message = ")); @@ -95,9 +95,9 @@ int main(int argc, char **argv) DEFER_CLEANUP(struct s2n_blob combined_pms = { 0 }, s2n_free); EXPECT_SUCCESS(s2n_alloc(&combined_pms, classic_pms.size + kem_pms.size)); struct s2n_stuffer combined_stuffer = { 0 }; - s2n_stuffer_init(&combined_stuffer, &combined_pms); - s2n_stuffer_write(&combined_stuffer, &classic_pms); - s2n_stuffer_write(&combined_stuffer, &kem_pms); + EXPECT_SUCCESS(s2n_stuffer_init(&combined_stuffer, &combined_pms)); + EXPECT_SUCCESS(s2n_stuffer_write(&combined_stuffer, &classic_pms)); + EXPECT_SUCCESS(s2n_stuffer_write(&combined_stuffer, &kem_pms)); EXPECT_MEMCPY_SUCCESS(conn->handshake_params.client_random, client_random, CLIENT_RANDOM_LENGTH); EXPECT_MEMCPY_SUCCESS(conn->handshake_params.server_random, server_random, SERVER_RANDOM_LENGTH); diff --git a/tests/unit/s2n_x509_validator_certificate_signatures_test.c b/tests/unit/s2n_x509_validator_certificate_signatures_test.c index ffcb657171e..06bbf4f8093 100644 --- a/tests/unit/s2n_x509_validator_certificate_signatures_test.c +++ b/tests/unit/s2n_x509_validator_certificate_signatures_test.c @@ -30,6 +30,11 @@ #include "tls/s2n_x509_validator.h" #include "utils/s2n_safety.h" +/* forward declaration */ +S2N_RESULT s2n_x509_validator_check_cert_preferences(struct s2n_connection *conn, X509 *cert); + +DEFINE_POINTER_CLEANUP_FUNC(BIO *, BIO_free); + int main(int argc, char **argv) { BEGIN_TEST(); @@ -49,119 +54,16 @@ int main(int argc, char **argv) .signature_schemes = test_sig_scheme_list, }; - const struct s2n_signature_scheme *const pss_sig_scheme_list[] = { - &s2n_rsa_pss_pss_sha256, - &s2n_rsa_pss_pss_sha384, - &s2n_rsa_pss_pss_sha512, - &s2n_rsa_pss_rsae_sha256, - &s2n_rsa_pss_rsae_sha384, - &s2n_rsa_pss_rsae_sha512, - }; - - const struct s2n_signature_preferences pss_certificate_signature_preferences = { - .count = s2n_array_len(pss_sig_scheme_list), - .signature_schemes = pss_sig_scheme_list, + const struct s2n_security_policy test_sp = { + .minimum_protocol_version = S2N_TLS12, + .certificate_signature_preferences = &test_certificate_signature_preferences, }; - /* s2n_is_certificate_sig_scheme_supported() */ - { - struct s2n_connection *conn; - EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); - - /* Certificate signature algorithm is in test certificate signature preferences list */ - { - EXPECT_SUCCESS(s2n_read_test_pem(S2N_ECDSA_P256_PKCS1_CERT_CHAIN, (char *) cert_file, S2N_MAX_TEST_PEM_SIZE)); - certLen = strlen((const char *) cert_file); - - /* Read the test certificates into an Openssl X509 struct */ - EXPECT_NOT_NULL(certBio = BIO_new(BIO_s_mem())); - EXPECT_TRUE(BIO_write(certBio, cert_file, certLen) > 0); - EXPECT_NOT_NULL(cert = PEM_read_bio_X509(certBio, NULL, NULL, NULL)); - - EXPECT_OK(s2n_validate_sig_scheme_supported(conn, cert, &test_certificate_signature_preferences)); - - EXPECT_SUCCESS(BIO_free(certBio)); - X509_free(cert); - }; - - /* Certificate signature algorithm is not in test certificate signature preferences list */ - { - EXPECT_SUCCESS(s2n_read_test_pem(S2N_RSA_PSS_2048_SHA256_LEAF_CERT, (char *) cert_file, S2N_MAX_TEST_PEM_SIZE)); - certLen = strlen((const char *) cert_file); - - /* Read the test certificates into an Openssl X509 struct */ - EXPECT_NOT_NULL(certBio = BIO_new(BIO_s_mem())); - EXPECT_TRUE(BIO_write(certBio, cert_file, certLen) > 0); - EXPECT_NOT_NULL(cert = PEM_read_bio_X509(certBio, NULL, NULL, NULL)); - - EXPECT_ERROR_WITH_ERRNO(s2n_validate_sig_scheme_supported(conn, cert, &test_certificate_signature_preferences), S2N_ERR_CERT_UNTRUSTED); - - EXPECT_SUCCESS(BIO_free(certBio)); - X509_free(cert); - }; - - /* Certificate signature algorithm is in the test certificate signature preferences list but signature is SHA-1 - * and TLS 1.3 has been negotiated. - */ - { - conn->actual_protocol_version = S2N_TLS13; - EXPECT_SUCCESS(s2n_read_test_pem(S2N_RSA_2048_PKCS1_CERT_CHAIN, (char *) cert_file, S2N_MAX_TEST_PEM_SIZE)); - certLen = strlen((const char *) cert_file); - - /* Read the test certificates into an Openssl X509 struct */ - EXPECT_NOT_NULL(certBio = BIO_new(BIO_s_mem())); - EXPECT_TRUE(BIO_write(certBio, cert_file, certLen) > 0); - EXPECT_NOT_NULL(cert = PEM_read_bio_X509(certBio, NULL, NULL, NULL)); - - EXPECT_ERROR_WITH_ERRNO(s2n_validate_sig_scheme_supported(conn, cert, &test_certificate_signature_preferences), S2N_ERR_CERT_UNTRUSTED); - - EXPECT_SUCCESS(BIO_free(certBio)); - X509_free(cert); - }; - - /* Certificate signature algorithm is in the test certificate signature preferences list and signature is SHA-1 - * and TLS 1.2 has been negotiated. - */ - { - conn->actual_protocol_version = S2N_TLS12; - EXPECT_SUCCESS(s2n_read_test_pem(S2N_RSA_2048_PKCS1_CERT_CHAIN, (char *) cert_file, S2N_MAX_TEST_PEM_SIZE)); - certLen = strlen((const char *) cert_file); - - /* Read the test certificates into an Openssl X509 struct */ - EXPECT_NOT_NULL(certBio = BIO_new(BIO_s_mem())); - EXPECT_TRUE(BIO_write(certBio, cert_file, certLen) > 0); - EXPECT_NOT_NULL(cert = PEM_read_bio_X509(certBio, NULL, NULL, NULL)); - - EXPECT_OK(s2n_validate_sig_scheme_supported(conn, cert, &test_certificate_signature_preferences)); - - EXPECT_SUCCESS(BIO_free(certBio)); - X509_free(cert); - }; - - /* Certificates signed with an RSA PSS signature can be validated */ - { - EXPECT_SUCCESS(s2n_read_test_pem(S2N_RSA_PSS_2048_SHA256_LEAF_CERT, (char *) cert_file, S2N_MAX_TEST_PEM_SIZE)); - certLen = strlen((const char *) cert_file); - - /* Read the test certificates into an Openssl X509 struct */ - EXPECT_NOT_NULL(certBio = BIO_new(BIO_s_mem())); - EXPECT_TRUE(BIO_write(certBio, cert_file, certLen) > 0); - EXPECT_NOT_NULL(cert = PEM_read_bio_X509(certBio, NULL, NULL, NULL)); - - EXPECT_OK(s2n_validate_sig_scheme_supported(conn, cert, &pss_certificate_signature_preferences)); - - EXPECT_SUCCESS(BIO_free(certBio)); - X509_free(cert); - }; - - EXPECT_SUCCESS(s2n_connection_free(conn)); - } - - /* s2n_validate_certificate_signature */ + /* s2n_x509_validator_check_cert_preferences */ { /* Connection using a security policy with no certificate_signature_preferences allows SHA-1 signatures in certificates */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; struct s2n_config *config = s2n_config_new(); EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); @@ -177,7 +79,7 @@ int main(int argc, char **argv) EXPECT_TRUE(BIO_write(certBio, cert_file, certLen) > 0); EXPECT_NOT_NULL(cert = PEM_read_bio_X509(certBio, NULL, NULL, NULL)); - EXPECT_OK(s2n_validate_certificate_signature(conn, cert)); + EXPECT_OK(s2n_x509_validator_check_cert_preferences(conn, cert)); EXPECT_SUCCESS(s2n_config_free(config)); EXPECT_SUCCESS(s2n_connection_free(conn)); @@ -187,7 +89,7 @@ int main(int argc, char **argv) /* Connection using the default_tls13 security policy does not validate SHA-1 signatures in certificates */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; struct s2n_config *config = s2n_config_new(); EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); @@ -202,7 +104,8 @@ int main(int argc, char **argv) EXPECT_TRUE(BIO_write(certBio, cert_file, certLen) > 0); EXPECT_NOT_NULL(cert = PEM_read_bio_X509(certBio, NULL, NULL, NULL)); - EXPECT_ERROR_WITH_ERRNO(s2n_validate_certificate_signature(conn, cert), S2N_ERR_CERT_UNTRUSTED); + EXPECT_ERROR_WITH_ERRNO(s2n_x509_validator_check_cert_preferences(conn, cert), + S2N_ERR_CERT_UNTRUSTED); EXPECT_SUCCESS(s2n_config_free(config)); EXPECT_SUCCESS(s2n_connection_free(conn)); @@ -212,7 +115,7 @@ int main(int argc, char **argv) /* Connection using the default_tls13 security policy ignores a SHA-1 signature on a root certificate */ { - struct s2n_connection *conn; + struct s2n_connection *conn = NULL; struct s2n_config *config = s2n_config_new(); EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); @@ -227,13 +130,90 @@ int main(int argc, char **argv) EXPECT_TRUE(BIO_write(certBio, cert_file, certLen) > 0); EXPECT_NOT_NULL(cert = PEM_read_bio_X509(certBio, NULL, NULL, NULL)); - EXPECT_OK(s2n_validate_certificate_signature(conn, cert)); + EXPECT_OK(s2n_x509_validator_check_cert_preferences(conn, cert)); EXPECT_SUCCESS(s2n_config_free(config)); EXPECT_SUCCESS(s2n_connection_free(conn)); EXPECT_SUCCESS(BIO_free(certBio)); X509_free(cert); }; + + /* When the certificate signature algorithm is not in the preferences list, then an S2N_ERR_CERT_UNTRUSTED err + * is returned. + */ + { + DEFER_CLEANUP(struct s2n_config *config = s2n_config_new(), s2n_config_ptr_free); + EXPECT_NOT_NULL(config); + config->security_policy = &test_sp; + + DEFER_CLEANUP(struct s2n_connection *conn = s2n_connection_new(S2N_CLIENT), s2n_connection_ptr_free); + EXPECT_NOT_NULL(conn); + conn->actual_protocol_version = S2N_TLS12; + EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); + + DEFER_CLEANUP(struct s2n_cert_chain_and_key *ecdsa_p384_sha256 = NULL, + s2n_cert_chain_and_key_ptr_free); + EXPECT_SUCCESS(s2n_test_cert_permutation_load_server_chain(&ecdsa_p384_sha256, "ec", + "ecdsa", "p384", "sha384")); + DEFER_CLEANUP(X509 *test_cert = NULL, X509_free_pointer); + EXPECT_OK(s2n_openssl_x509_parse(&ecdsa_p384_sha256->cert_chain->head->raw, &test_cert)); + + EXPECT_ERROR_WITH_ERRNO(s2n_x509_validator_check_cert_preferences(conn, test_cert), S2N_ERR_CERT_UNTRUSTED); + }; + + /* Certificate signature algorithm is in the test certificate signature preferences list but signature is SHA-1 + * and TLS 1.3 has been negotiated. + */ + { + DEFER_CLEANUP(struct s2n_config *config = s2n_config_new(), s2n_config_ptr_free); + EXPECT_NOT_NULL(config); + config->security_policy = &test_sp; + + DEFER_CLEANUP(struct s2n_connection *conn = s2n_connection_new(S2N_CLIENT), s2n_connection_ptr_free); + EXPECT_NOT_NULL(conn); + conn->actual_protocol_version = S2N_TLS13; + EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); + + uint32_t cert_len = 0; + EXPECT_SUCCESS(s2n_read_test_pem_and_len(S2N_RSA_2048_PKCS1_CERT_CHAIN, cert_file, + &cert_len, S2N_MAX_TEST_PEM_SIZE)); + + /* Read the test certificates into an Openssl X509 struct */ + DEFER_CLEANUP(BIO *cert_bio = BIO_new(BIO_s_mem()), BIO_free_pointer); + EXPECT_NOT_NULL(cert_bio); + EXPECT_TRUE(BIO_write(cert_bio, cert_file, cert_len) > 0); + DEFER_CLEANUP(X509 *test_cert = PEM_read_bio_X509(cert_bio, NULL, NULL, NULL), X509_free_pointer); + EXPECT_NOT_NULL(test_cert); + + EXPECT_ERROR_WITH_ERRNO(s2n_x509_validator_check_cert_preferences(conn, test_cert), S2N_ERR_CERT_UNTRUSTED); + }; + + /* Certificate signature algorithm is in the test certificate signature preferences list and signature is SHA-1 + * and TLS 1.2 has been negotiated. + */ + { + DEFER_CLEANUP(struct s2n_config *config = s2n_config_new(), s2n_config_ptr_free); + EXPECT_NOT_NULL(config); + config->security_policy = &test_sp; + + DEFER_CLEANUP(struct s2n_connection *conn = s2n_connection_new(S2N_CLIENT), s2n_connection_ptr_free); + EXPECT_NOT_NULL(conn); + conn->actual_protocol_version = S2N_TLS12; + EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); + + uint32_t cert_len = 0; + EXPECT_SUCCESS(s2n_read_test_pem_and_len(S2N_RSA_2048_PKCS1_CERT_CHAIN, cert_file, + &cert_len, S2N_MAX_TEST_PEM_SIZE)); + + /* Read the test certificates into an Openssl X509 struct */ + DEFER_CLEANUP(BIO *cert_bio = BIO_new(BIO_s_mem()), BIO_free_pointer); + EXPECT_NOT_NULL(cert_bio); + EXPECT_TRUE(BIO_write(cert_bio, cert_file, cert_len) > 0); + DEFER_CLEANUP(X509 *test_cert = PEM_read_bio_X509(cert_bio, NULL, NULL, NULL), X509_free_pointer); + EXPECT_NOT_NULL(test_cert); + + EXPECT_OK(s2n_x509_validator_check_cert_preferences(conn, test_cert)); + }; }; END_TEST(); return S2N_SUCCESS; diff --git a/tests/unit/s2n_x509_validator_test.c b/tests/unit/s2n_x509_validator_test.c index 163fb5528a7..54f4ff08efe 100644 --- a/tests/unit/s2n_x509_validator_test.c +++ b/tests/unit/s2n_x509_validator_test.c @@ -13,10 +13,10 @@ * permissions and limitations under the License. */ +#include "crypto/s2n_openssl_x509.h" #include "s2n_test.h" #include "testlib/s2n_testlib.h" - -DEFINE_POINTER_CLEANUP_FUNC(X509 *, X509_free); +#include "tls/s2n_certificate_keys.h" static int mock_time(void *data, uint64_t *timestamp) { @@ -57,13 +57,13 @@ static int fetch_not_expired_ocsp_timestamp(void *data, uint64_t *timestamp) static int read_file(struct s2n_stuffer *file_output, const char *path, uint32_t max_len) { FILE *fd = fopen(path, "rb"); - s2n_stuffer_alloc(file_output, max_len); + POSIX_GUARD(s2n_stuffer_alloc(file_output, max_len)); if (fd) { char data[1024]; size_t r = 0; while ((r = fread(data, 1, sizeof(data), fd)) > 0) { - s2n_stuffer_write_bytes(file_output, (const uint8_t *) data, (const uint32_t) r); + POSIX_GUARD(s2n_stuffer_write_bytes(file_output, (const uint8_t *) data, (const uint32_t) r)); } fclose(fd); return s2n_stuffer_data_available(file_output) > 0; @@ -1965,8 +1965,8 @@ int main(int argc, char **argv) struct s2n_pkey public_key_out; EXPECT_SUCCESS(s2n_pkey_zero_init(&public_key_out)); s2n_pkey_type pkey_type = S2N_PKEY_TYPE_UNKNOWN; - EXPECT_ERROR_WITH_ERRNO(s2n_x509_validator_validate_cert_chain(&validator, connection, chain_data, chain_len, - &pkey_type, &public_key_out), + EXPECT_ERROR_WITH_ERRNO(s2n_x509_validator_validate_cert_chain(&validator, connection, + chain_data, chain_len, &pkey_type, &public_key_out), S2N_ERR_CERT_UNTRUSTED); s2n_connection_free(connection); @@ -2189,5 +2189,99 @@ int main(int argc, char **argv) } } + /* Test that CAs must comply with cert preferences */ + { + uint8_t invalid_root_pem[S2N_MAX_TEST_PEM_SIZE] = { 0 }; + uint32_t root_pem_len = 0; + EXPECT_SUCCESS(s2n_read_test_pem_and_len(S2N_MIXED_CHAIN_CA, &invalid_root_pem[0], &root_pem_len, + S2N_MAX_TEST_PEM_SIZE)); + + uint8_t chain_pem[S2N_MAX_TEST_PEM_SIZE] = { 0 }; + uint32_t chain_pem_len = 0; + EXPECT_SUCCESS(s2n_read_test_pem_and_len(S2N_MIXED_CHAIN_CERTS, &chain_pem[0], &chain_pem_len, + S2N_MAX_TEST_PEM_SIZE)); + + const struct s2n_certificate_key *const s2n_certificate_key_preferences_list_rfc9151[] = { + &s2n_ec_p384, + &s2n_rsa_rsae_3072, + &s2n_rsa_rsae_4096, + }; + + const struct s2n_certificate_key_preferences s2n_certificate_key_preferences_rfc9151 = { + .count = s2n_array_len(s2n_certificate_key_preferences_list_rfc9151), + .certificate_keys = s2n_certificate_key_preferences_list_rfc9151, + }; + + struct s2n_security_policy security_policy_not_local = security_policy_rfc9151; + security_policy_not_local.certificate_preferences_apply_locally = false; + security_policy_not_local.certificate_key_preferences = &s2n_certificate_key_preferences_rfc9151; + + /* when the peer sends the full chain with a non-compliant CA, verification fails when reading in the certs */ + { + DEFER_CLEANUP(struct s2n_config *config = s2n_config_new_minimal(), s2n_config_ptr_free); + EXPECT_SUCCESS(s2n_config_add_pem_to_trust_store(config, (char *) &invalid_root_pem[0])); + + DEFER_CLEANUP(struct s2n_x509_validator validator = { 0 }, s2n_x509_validator_wipe); + EXPECT_SUCCESS(s2n_x509_validator_init(&validator, &config->trust_store, 0)); + + DEFER_CLEANUP(struct s2n_connection *conn = s2n_connection_new(S2N_CLIENT), s2n_connection_ptr_free); + EXPECT_NOT_NULL(conn); + conn->security_policy_override = &security_policy_not_local; + EXPECT_SUCCESS(s2n_set_server_name(conn, "localhost")); + + DEFER_CLEANUP(struct s2n_stuffer cert_chain_stuffer = { 0 }, s2n_stuffer_free); + + EXPECT_OK(s2n_test_cert_chain_data_from_pem_data(conn, &chain_pem[0], chain_pem_len, &cert_chain_stuffer)); + uint32_t chain_len = s2n_stuffer_data_available(&cert_chain_stuffer); + uint8_t *chain_data = s2n_stuffer_raw_read(&cert_chain_stuffer, chain_len); + EXPECT_NOT_NULL(chain_data); + + DEFER_CLEANUP(struct s2n_pkey public_key_out = { 0 }, s2n_pkey_free); + EXPECT_SUCCESS(s2n_pkey_zero_init(&public_key_out)); + s2n_pkey_type pkey_type = S2N_PKEY_TYPE_UNKNOWN; + EXPECT_ERROR_WITH_ERRNO(s2n_x509_validator_validate_cert_chain(&validator, conn, chain_data, chain_len, + &pkey_type, &public_key_out), + S2N_ERR_CERT_UNTRUSTED); + /* Failed while processing/reading in the cert chain */ + EXPECT_TRUE(validator.state == INIT); + }; + + /* when the peer sends only compliant certs from a non-compliant CA, + * validation fails on the local trust store + */ + { + DEFER_CLEANUP(struct s2n_config *config = s2n_config_new_minimal(), s2n_config_ptr_free); + EXPECT_SUCCESS(s2n_config_add_pem_to_trust_store(config, (char *) &invalid_root_pem[0])); + + DEFER_CLEANUP(struct s2n_x509_validator validator = { 0 }, s2n_x509_validator_wipe); + EXPECT_SUCCESS(s2n_x509_validator_init(&validator, &config->trust_store, 0)); + + DEFER_CLEANUP(struct s2n_connection *conn = s2n_connection_new(S2N_CLIENT), s2n_connection_ptr_free); + EXPECT_NOT_NULL(conn); + conn->security_policy_override = &security_policy_not_local; + EXPECT_SUCCESS(s2n_set_server_name(conn, "localhost")); + + DEFER_CLEANUP(struct s2n_stuffer cert_chain_stuffer = { 0 }, s2n_stuffer_free); + + /* `chain_pem_len - root_pem_len`: only use the first two certs in the chain (leaf and intermediate) to + * ensure we are correctly failing on the local trust store and not the chain that the peer sent. + */ + EXPECT_OK(s2n_test_cert_chain_data_from_pem_data(conn, &chain_pem[0], chain_pem_len - root_pem_len, + &cert_chain_stuffer)); + uint32_t chain_len = s2n_stuffer_data_available(&cert_chain_stuffer); + uint8_t *chain_data = s2n_stuffer_raw_read(&cert_chain_stuffer, chain_len); + EXPECT_NOT_NULL(chain_data); + + DEFER_CLEANUP(struct s2n_pkey public_key_out = { 0 }, s2n_pkey_free); + EXPECT_SUCCESS(s2n_pkey_zero_init(&public_key_out)); + s2n_pkey_type pkey_type = S2N_PKEY_TYPE_UNKNOWN; + EXPECT_ERROR_WITH_ERRNO(s2n_x509_validator_validate_cert_chain(&validator, conn, chain_data, chain_len, + &pkey_type, &public_key_out), + S2N_ERR_SECURITY_POLICY_INCOMPATIBLE_CERT); + /* X509_verify_cert finished successfully */ + EXPECT_TRUE(validator.state == VALIDATED); + }; + }; + END_TEST(); } diff --git a/tests/unit/valgrind.suppressions b/tests/unit/valgrind.suppressions index 60d1bf66fa5..3662410a9bf 100644 --- a/tests/unit/valgrind.suppressions +++ b/tests/unit/valgrind.suppressions @@ -28,12 +28,3 @@ fun:s2n_test_case_madv_wipeonfork_cb fun:main } - -# TODO: fix the pedantic leak errors from s2n_self_talk_alpn_test -{ - ignore_s2n_self_talk_alpn_test - Memcheck:Leak - match-leak-kinds: reachable - ... - fun:main -} diff --git a/tls/extensions/s2n_cert_status.c b/tls/extensions/s2n_cert_status.c index 454795ce25f..557902854e1 100644 --- a/tls/extensions/s2n_cert_status.c +++ b/tls/extensions/s2n_cert_status.c @@ -77,7 +77,7 @@ int s2n_cert_status_recv(struct s2n_connection *conn, struct s2n_stuffer *in) *# (using the ASN.1 type OCSPResponse defined in [RFC2560]). Only one *# OCSP response may be sent. **/ - uint8_t type; + uint8_t type = 0; POSIX_GUARD(s2n_stuffer_read_uint8(in, &type)); if (type != S2N_STATUS_REQUEST_OCSP) { /* We only support OCSP */ @@ -92,7 +92,7 @@ int s2n_cert_status_recv(struct s2n_connection *conn, struct s2n_stuffer *in) conn->status_type = S2N_STATUS_REQUEST_OCSP; } - uint32_t status_size; + uint32_t status_size = 0; POSIX_GUARD(s2n_stuffer_read_uint24(in, &status_size)); POSIX_ENSURE_LTE(status_size, s2n_stuffer_data_available(in)); diff --git a/tls/extensions/s2n_client_alpn.c b/tls/extensions/s2n_client_alpn.c index bd8754a44e9..96f7dda8044 100644 --- a/tls/extensions/s2n_client_alpn.c +++ b/tls/extensions/s2n_client_alpn.c @@ -39,7 +39,7 @@ const s2n_extension_type s2n_client_alpn_extension = { bool s2n_client_alpn_should_send(struct s2n_connection *conn) { - struct s2n_blob *client_app_protocols; + struct s2n_blob *client_app_protocols = NULL; return s2n_connection_get_protocol_preferences(conn, &client_app_protocols) == S2N_SUCCESS && client_app_protocols->size != 0 && client_app_protocols->data != NULL; @@ -47,7 +47,7 @@ bool s2n_client_alpn_should_send(struct s2n_connection *conn) static int s2n_client_alpn_send(struct s2n_connection *conn, struct s2n_stuffer *out) { - struct s2n_blob *client_app_protocols; + struct s2n_blob *client_app_protocols = NULL; POSIX_GUARD(s2n_connection_get_protocol_preferences(conn, &client_app_protocols)); POSIX_ENSURE_REF(client_app_protocols); diff --git a/tls/extensions/s2n_client_cert_status_request.c b/tls/extensions/s2n_client_cert_status_request.c index 3872f277aab..bb151714549 100644 --- a/tls/extensions/s2n_client_cert_status_request.c +++ b/tls/extensions/s2n_client_cert_status_request.c @@ -67,7 +67,7 @@ static int s2n_client_cert_status_request_recv(struct s2n_connection *conn, stru return S2N_SUCCESS; } - uint8_t type; + uint8_t type = 0; POSIX_GUARD(s2n_stuffer_read_uint8(extension, &type)); if (type != (uint8_t) S2N_STATUS_REQUEST_OCSP) { /* We only support OCSP (type 1), ignore the extension */ diff --git a/tls/extensions/s2n_client_key_share.c b/tls/extensions/s2n_client_key_share.c index 1226ee15d4f..d7ce45eeea6 100644 --- a/tls/extensions/s2n_client_key_share.c +++ b/tls/extensions/s2n_client_key_share.c @@ -410,7 +410,7 @@ static int s2n_client_key_share_recv(struct s2n_connection *conn, struct s2n_stu POSIX_ENSURE_REF(conn); POSIX_ENSURE_REF(extension); - uint16_t key_shares_size; + uint16_t key_shares_size = 0; POSIX_GUARD(s2n_stuffer_read_uint16(extension, &key_shares_size)); POSIX_ENSURE(s2n_stuffer_data_available(extension) == key_shares_size, S2N_ERR_BAD_MESSAGE); diff --git a/tls/extensions/s2n_client_max_frag_len.c b/tls/extensions/s2n_client_max_frag_len.c index 8019d2d3ef9..5a47dbfb0ab 100644 --- a/tls/extensions/s2n_client_max_frag_len.c +++ b/tls/extensions/s2n_client_max_frag_len.c @@ -51,7 +51,7 @@ static int s2n_client_max_frag_len_recv(struct s2n_connection *conn, struct s2n_ return S2N_SUCCESS; } - uint8_t mfl_code; + uint8_t mfl_code = 0; POSIX_GUARD(s2n_stuffer_read_uint8(extension, &mfl_code)); /* diff --git a/tls/extensions/s2n_client_pq_kem.c b/tls/extensions/s2n_client_pq_kem.c index 83d3d9150a7..6bddbcf07a4 100644 --- a/tls/extensions/s2n_client_pq_kem.c +++ b/tls/extensions/s2n_client_pq_kem.c @@ -40,7 +40,7 @@ const s2n_extension_type s2n_client_pq_kem_extension = { static bool s2n_client_pq_kem_should_send(struct s2n_connection *conn) { - const struct s2n_security_policy *security_policy; + const struct s2n_security_policy *security_policy = NULL; return s2n_connection_get_security_policy(conn, &security_policy) == S2N_SUCCESS && s2n_pq_kem_is_extension_required(security_policy) && s2n_pq_is_enabled(); @@ -62,7 +62,7 @@ static int s2n_client_pq_kem_send(struct s2n_connection *conn, struct s2n_stuffe static int s2n_client_pq_kem_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) { - uint16_t size_of_all; + uint16_t size_of_all = 0; struct s2n_blob *proposed_kems = &conn->kex_params.client_pq_kem_extension; /* Ignore extension if PQ is disabled */ diff --git a/tls/extensions/s2n_client_psk.c b/tls/extensions/s2n_client_psk.c index 992e2ca4e99..98d4773126c 100644 --- a/tls/extensions/s2n_client_psk.c +++ b/tls/extensions/s2n_client_psk.c @@ -288,7 +288,7 @@ static S2N_RESULT s2n_client_psk_recv_binder_list(struct s2n_connection *conn, s uint8_t wire_binder_size = 0; RESULT_GUARD_POSIX(s2n_stuffer_read_uint8(wire_binders_in, &wire_binder_size)); - uint8_t *wire_binder_data; + uint8_t *wire_binder_data = NULL; RESULT_ENSURE_REF(wire_binder_data = s2n_stuffer_raw_read(wire_binders_in, wire_binder_size)); struct s2n_blob wire_binder = { 0 }; @@ -311,7 +311,7 @@ static S2N_RESULT s2n_client_psk_recv_identities(struct s2n_connection *conn, st uint16_t identity_list_size = 0; RESULT_GUARD_POSIX(s2n_stuffer_read_uint16(extension, &identity_list_size)); - uint8_t *identity_list_data; + uint8_t *identity_list_data = NULL; RESULT_ENSURE_REF(identity_list_data = s2n_stuffer_raw_read(extension, identity_list_size)); struct s2n_blob identity_list_blob = { 0 }; @@ -331,7 +331,7 @@ static S2N_RESULT s2n_client_psk_recv_binders(struct s2n_connection *conn, struc uint16_t binder_list_size = 0; RESULT_GUARD_POSIX(s2n_stuffer_read_uint16(extension, &binder_list_size)); - uint8_t *binder_list_data; + uint8_t *binder_list_data = NULL; RESULT_ENSURE_REF(binder_list_data = s2n_stuffer_raw_read(extension, binder_list_size)); struct s2n_blob binder_list_blob = { 0 }; @@ -364,7 +364,7 @@ int s2n_client_psk_recv(struct s2n_connection *conn, struct s2n_stuffer *extensi *# Servers MUST check that it is the last extension and otherwise fail *# the handshake with an "illegal_parameter" alert. */ - s2n_extension_type_id psk_ext_id; + s2n_extension_type_id psk_ext_id = 0; POSIX_GUARD(s2n_extension_supported_iana_value_to_id(TLS_EXTENSION_PRE_SHARED_KEY, &psk_ext_id)); POSIX_ENSURE_NE(conn->client_hello.extensions.count, 0); uint16_t last_wire_index = conn->client_hello.extensions.count - 1; @@ -379,12 +379,12 @@ int s2n_client_psk_recv(struct s2n_connection *conn, struct s2n_stuffer *extensi * We can safely do this check here because s2n_client_psk is * required to be the last extension sent in the list. */ - s2n_extension_type_id psk_ke_mode_ext_id; + s2n_extension_type_id psk_ke_mode_ext_id = 0; POSIX_GUARD(s2n_extension_supported_iana_value_to_id(TLS_EXTENSION_PSK_KEY_EXCHANGE_MODES, &psk_ke_mode_ext_id)); POSIX_ENSURE(S2N_CBIT_TEST(conn->extension_requests_received, psk_ke_mode_ext_id), S2N_ERR_MISSING_EXTENSION); if (conn->psk_params.psk_ke_mode == S2N_PSK_DHE_KE) { - s2n_extension_type_id key_share_ext_id; + s2n_extension_type_id key_share_ext_id = 0; POSIX_GUARD(s2n_extension_supported_iana_value_to_id(TLS_EXTENSION_KEY_SHARE, &key_share_ext_id)); /* A key_share extension must have been received in order to use a pre-shared key * in (EC)DHE key exchange mode. diff --git a/tls/extensions/s2n_client_server_name.c b/tls/extensions/s2n_client_server_name.c index f66c0e6512c..7ec68ada3d3 100644 --- a/tls/extensions/s2n_client_server_name.c +++ b/tls/extensions/s2n_client_server_name.c @@ -58,26 +58,28 @@ static int s2n_client_server_name_send(struct s2n_connection *conn, struct s2n_s return S2N_SUCCESS; } -/* Read the extension up to the first item in ServerNameList. Store the first entry's length in server_name_len. - * For now s2n ignores all subsequent items in ServerNameList. +/* Read the extension up to the first item in ServerNameList. Instantiates the server_name blob to + * point to the first entry. For now s2n ignores all subsequent items in ServerNameList. */ -static int s2n_client_server_name_check(struct s2n_connection *conn, struct s2n_stuffer *extension, uint16_t *server_name_len) +S2N_RESULT s2n_client_server_name_parse(struct s2n_stuffer *extension, struct s2n_blob *server_name) { - POSIX_ENSURE_REF(conn); + uint16_t list_size = 0; + RESULT_GUARD_POSIX(s2n_stuffer_read_uint16(extension, &list_size)); + RESULT_ENSURE_LTE(list_size, s2n_stuffer_data_available(extension)); - uint16_t size_of_all; - POSIX_GUARD(s2n_stuffer_read_uint16(extension, &size_of_all)); - POSIX_ENSURE_LTE(size_of_all, s2n_stuffer_data_available(extension)); + uint8_t server_name_type = 0; + RESULT_GUARD_POSIX(s2n_stuffer_read_uint8(extension, &server_name_type)); + RESULT_ENSURE_EQ(server_name_type, S2N_NAME_TYPE_HOST_NAME); - uint8_t server_name_type; - POSIX_GUARD(s2n_stuffer_read_uint8(extension, &server_name_type)); - POSIX_ENSURE_EQ(server_name_type, S2N_NAME_TYPE_HOST_NAME); + uint16_t length = 0; + RESULT_GUARD_POSIX(s2n_stuffer_read_uint16(extension, &length)); + RESULT_ENSURE_LTE(length, s2n_stuffer_data_available(extension)); - POSIX_GUARD(s2n_stuffer_read_uint16(extension, server_name_len)); - POSIX_ENSURE_LT(*server_name_len, sizeof(conn->server_name)); - POSIX_ENSURE_LTE(*server_name_len, s2n_stuffer_data_available(extension)); + uint8_t *data = s2n_stuffer_raw_read(extension, length); + RESULT_ENSURE_REF(data); + RESULT_GUARD_POSIX(s2n_blob_init(server_name, data, length)); - return S2N_SUCCESS; + return S2N_RESULT_OK; } static int s2n_client_server_name_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) @@ -89,15 +91,13 @@ static int s2n_client_server_name_recv(struct s2n_connection *conn, struct s2n_s return S2N_SUCCESS; } - /* Ignore if malformed. We just won't use the server name. */ - uint16_t server_name_len; - if (s2n_client_server_name_check(conn, extension, &server_name_len) != S2N_SUCCESS) { + /* Ignore if malformed or we don't have enough space to store it. We just won't use the server name. */ + struct s2n_blob server_name = { 0 }; + if (!s2n_result_is_ok(s2n_client_server_name_parse(extension, &server_name)) || server_name.size > S2N_MAX_SERVER_NAME) { return S2N_SUCCESS; } - uint8_t *server_name; - POSIX_ENSURE_REF(server_name = s2n_stuffer_raw_read(extension, server_name_len)); - POSIX_CHECKED_MEMCPY(conn->server_name, server_name, server_name_len); + POSIX_CHECKED_MEMCPY(conn->server_name, server_name.data, server_name.size); return S2N_SUCCESS; } diff --git a/tls/extensions/s2n_client_server_name.h b/tls/extensions/s2n_client_server_name.h index 8eb868cb6b0..06aeb14f755 100644 --- a/tls/extensions/s2n_client_server_name.h +++ b/tls/extensions/s2n_client_server_name.h @@ -20,3 +20,4 @@ #include "tls/s2n_connection.h" extern const s2n_extension_type s2n_client_server_name_extension; +S2N_RESULT s2n_client_server_name_parse(struct s2n_stuffer *extension, struct s2n_blob *server_name); diff --git a/tls/extensions/s2n_client_supported_groups.c b/tls/extensions/s2n_client_supported_groups.c index 60a2a90ce7e..cc30f0c9dff 100644 --- a/tls/extensions/s2n_client_supported_groups.c +++ b/tls/extensions/s2n_client_supported_groups.c @@ -40,7 +40,7 @@ const s2n_extension_type s2n_client_supported_groups_extension = { bool s2n_extension_should_send_if_ecc_enabled(struct s2n_connection *conn) { - const struct s2n_security_policy *security_policy; + const struct s2n_security_policy *security_policy = NULL; return s2n_connection_get_security_policy(conn, &security_policy) == S2N_SUCCESS && s2n_ecc_is_extension_required(security_policy); } diff --git a/tls/extensions/s2n_client_supported_versions.c b/tls/extensions/s2n_client_supported_versions.c index 5be11407b6d..d59adb1738e 100644 --- a/tls/extensions/s2n_client_supported_versions.c +++ b/tls/extensions/s2n_client_supported_versions.c @@ -81,7 +81,7 @@ int s2n_extensions_client_supported_versions_process(struct s2n_connection *conn uint8_t minimum_supported_version = s2n_unknown_protocol_version; POSIX_GUARD_RESULT(s2n_connection_get_minimum_supported_version(conn, &minimum_supported_version)); - uint8_t size_of_version_list; + uint8_t size_of_version_list = 0; POSIX_GUARD(s2n_stuffer_read_uint8(extension, &size_of_version_list)); S2N_ERROR_IF(size_of_version_list != s2n_stuffer_data_available(extension), S2N_ERR_BAD_MESSAGE); S2N_ERROR_IF(size_of_version_list % S2N_TLS_PROTOCOL_VERSION_LEN != 0, S2N_ERR_BAD_MESSAGE); @@ -156,6 +156,13 @@ static int s2n_client_supported_versions_recv(struct s2n_connection *conn, struc return S2N_SUCCESS; } + /* A TLS 1.3 state machine flag is used to determine if a HelloRetryRequest is negotiated. A + * protocol version of TLS 1.3 must be set in order to query the TLS 1.3 state machine, so + * it must be queried before the protocol version is potentially reset due to processing the + * extension. + */ + bool is_hrr_handshake = s2n_is_hello_retry_handshake(conn); + s2n_result result = s2n_client_supported_versions_recv_impl(conn, extension); if (s2n_result_is_error(result)) { conn->client_protocol_version = s2n_unknown_protocol_version; @@ -166,6 +173,14 @@ static int s2n_client_supported_versions_recv(struct s2n_connection *conn, struc } POSIX_GUARD_RESULT(result); + /* When the supported versions extension is received in a ClientHello sent in response to a + * HelloRetryRequest, ensure that TLS 1.3 is selected as the protocol version. + */ + if (is_hrr_handshake && conn->handshake.message_number > 0) { + POSIX_ENSURE(conn->client_protocol_version == S2N_TLS13, S2N_ERR_PROTOCOL_VERSION_UNSUPPORTED); + POSIX_ENSURE(conn->actual_protocol_version == S2N_TLS13, S2N_ERR_PROTOCOL_VERSION_UNSUPPORTED); + } + return S2N_SUCCESS; } diff --git a/tls/extensions/s2n_extension_list.c b/tls/extensions/s2n_extension_list.c index 71fd5213fdd..2a5fc8f98aa 100644 --- a/tls/extensions/s2n_extension_list.c +++ b/tls/extensions/s2n_extension_list.c @@ -25,7 +25,7 @@ int s2n_extension_list_send(s2n_extension_list_id list_type, struct s2n_connection *conn, struct s2n_stuffer *out) { - s2n_extension_type_list *extension_type_list; + s2n_extension_type_list *extension_type_list = NULL; POSIX_GUARD(s2n_extension_type_list_get(list_type, &extension_type_list)); struct s2n_stuffer_reservation total_extensions_size = { 0 }; @@ -80,7 +80,7 @@ int s2n_extension_process(const s2n_extension_type *extension_type, struct s2n_c POSIX_ENSURE_REF(parsed_extension_list); POSIX_ENSURE_REF(extension_type); - s2n_extension_type_id extension_id; + s2n_extension_type_id extension_id = 0; POSIX_GUARD(s2n_extension_supported_iana_value_to_id(extension_type->iana_value, &extension_id)); s2n_parsed_extension *parsed_extension = &parsed_extension_list->parsed_extensions[extension_id]; @@ -94,7 +94,7 @@ int s2n_extension_list_process(s2n_extension_list_id list_type, struct s2n_conne { POSIX_ENSURE_REF(parsed_extension_list); - s2n_extension_type_list *extension_type_list; + s2n_extension_type_list *extension_type_list = NULL; POSIX_GUARD(s2n_extension_type_list_get(list_type, &extension_type_list)); for (int i = 0; i < extension_type_list->count; i++) { @@ -123,18 +123,18 @@ static int s2n_extension_parse(struct s2n_stuffer *in, s2n_parsed_extension *par POSIX_ENSURE_REF(parsed_extensions); POSIX_ENSURE_REF(wire_index); - uint16_t extension_type; + uint16_t extension_type = 0; POSIX_ENSURE(s2n_stuffer_read_uint16(in, &extension_type) == S2N_SUCCESS, S2N_ERR_BAD_MESSAGE); - uint16_t extension_size; + uint16_t extension_size = 0; POSIX_ENSURE(s2n_stuffer_read_uint16(in, &extension_size) == S2N_SUCCESS, S2N_ERR_BAD_MESSAGE); uint8_t *extension_data = s2n_stuffer_raw_read(in, extension_size); POSIX_ENSURE(extension_data != NULL, S2N_ERR_BAD_MESSAGE); - s2n_extension_type_id extension_id; + s2n_extension_type_id extension_id = 0; if (s2n_extension_supported_iana_value_to_id(extension_type, &extension_id) != S2N_SUCCESS) { /* Ignore unknown extensions */ return S2N_SUCCESS; @@ -163,7 +163,7 @@ int s2n_extension_list_parse(struct s2n_stuffer *in, s2n_parsed_extensions_list POSIX_CHECKED_MEMSET((s2n_parsed_extension *) parsed_extension_list->parsed_extensions, 0, sizeof(parsed_extension_list->parsed_extensions)); - uint16_t total_extensions_size; + uint16_t total_extensions_size = 0; if (s2n_stuffer_read_uint16(in, &total_extensions_size) != S2N_SUCCESS) { total_extensions_size = 0; } diff --git a/tls/extensions/s2n_extension_type.c b/tls/extensions/s2n_extension_type.c index f0a4ffd9111..49f1bee2d95 100644 --- a/tls/extensions/s2n_extension_type.c +++ b/tls/extensions/s2n_extension_type.c @@ -86,7 +86,7 @@ int s2n_extension_send(const s2n_extension_type *extension_type, struct s2n_conn POSIX_ENSURE_REF(extension_type->send); POSIX_ENSURE_REF(conn); - s2n_extension_type_id extension_id; + s2n_extension_type_id extension_id = 0; POSIX_GUARD(s2n_extension_supported_iana_value_to_id(extension_type->iana_value, &extension_id)); /* Do not send response if request not received. */ @@ -131,7 +131,7 @@ int s2n_extension_recv(const s2n_extension_type *extension_type, struct s2n_conn POSIX_ENSURE_REF(extension_type->recv); POSIX_ENSURE_REF(conn); - s2n_extension_type_id extension_id; + s2n_extension_type_id extension_id = 0; POSIX_GUARD(s2n_extension_supported_iana_value_to_id(extension_type->iana_value, &extension_id)); /** @@ -180,7 +180,7 @@ int s2n_extension_is_missing(const s2n_extension_type *extension_type, struct s2 POSIX_ENSURE_REF(extension_type->if_missing); POSIX_ENSURE_REF(conn); - s2n_extension_type_id extension_id; + s2n_extension_type_id extension_id = 0; POSIX_GUARD(s2n_extension_supported_iana_value_to_id(extension_type->iana_value, &extension_id)); /* Do not consider an extension missing if we did not send a request */ diff --git a/tls/extensions/s2n_psk_key_exchange_modes.c b/tls/extensions/s2n_psk_key_exchange_modes.c index 41c9f7a5de3..e9a7bdb0463 100644 --- a/tls/extensions/s2n_psk_key_exchange_modes.c +++ b/tls/extensions/s2n_psk_key_exchange_modes.c @@ -70,7 +70,7 @@ static int s2n_psk_key_exchange_modes_recv(struct s2n_connection *conn, struct s { POSIX_ENSURE_REF(conn); - uint8_t psk_ke_mode_list_len; + uint8_t psk_ke_mode_list_len = 0; POSIX_GUARD(s2n_stuffer_read_uint8(extension, &psk_ke_mode_list_len)); if (psk_ke_mode_list_len > s2n_stuffer_data_available(extension)) { /* Malformed length, ignore the extension */ @@ -78,7 +78,7 @@ static int s2n_psk_key_exchange_modes_recv(struct s2n_connection *conn, struct s } for (size_t i = 0; i < psk_ke_mode_list_len; i++) { - uint8_t wire_psk_ke_mode; + uint8_t wire_psk_ke_mode = 0; POSIX_GUARD(s2n_stuffer_read_uint8(extension, &wire_psk_ke_mode)); /* s2n currently only supports pre-shared keys with (EC)DHE key establishment */ diff --git a/tls/extensions/s2n_server_alpn.c b/tls/extensions/s2n_server_alpn.c index dd556bd85ca..54f9e5e856e 100644 --- a/tls/extensions/s2n_server_alpn.c +++ b/tls/extensions/s2n_server_alpn.c @@ -57,14 +57,14 @@ static int s2n_alpn_recv(struct s2n_connection *conn, struct s2n_stuffer *extens { POSIX_ENSURE_REF(conn); - uint16_t size_of_all; + uint16_t size_of_all = 0; POSIX_GUARD(s2n_stuffer_read_uint16(extension, &size_of_all)); if (size_of_all > s2n_stuffer_data_available(extension) || size_of_all < 3) { /* ignore invalid extension size */ return S2N_SUCCESS; } - uint8_t protocol_len; + uint8_t protocol_len = 0; POSIX_GUARD(s2n_stuffer_read_uint8(extension, &protocol_len)); POSIX_ENSURE_LT(protocol_len, s2n_array_len(conn->application_protocol)); diff --git a/tls/extensions/s2n_server_key_share.c b/tls/extensions/s2n_server_key_share.c index 819b852116f..dad49ec14e1 100644 --- a/tls/extensions/s2n_server_key_share.c +++ b/tls/extensions/s2n_server_key_share.c @@ -135,7 +135,7 @@ static int s2n_server_key_share_send(struct s2n_connection *conn, struct s2n_stu /* Retry requests only require the selected named group, not an actual share. * https://tools.ietf.org/html/rfc8446#section-4.2.8 */ if (s2n_is_hello_retry_message(conn)) { - uint16_t named_group_id; + uint16_t named_group_id = 0; if (curve != NULL) { named_group_id = curve->iana_id; } else { @@ -291,7 +291,7 @@ static int s2n_server_key_share_recv_ecc(struct s2n_connection *conn, uint16_t n POSIX_ENSURE(client_ecc_evp_params->negotiated_curve == server_ecc_evp_params->negotiated_curve, S2N_ERR_BAD_KEY_SHARE); POSIX_ENSURE(client_ecc_evp_params->evp_pkey, S2N_ERR_BAD_KEY_SHARE); - uint16_t share_size; + uint16_t share_size = 0; S2N_ERROR_IF(s2n_stuffer_data_available(extension) < sizeof(share_size), S2N_ERR_BAD_KEY_SHARE); POSIX_GUARD(s2n_stuffer_read_uint16(extension, &share_size)); S2N_ERROR_IF(s2n_stuffer_data_available(extension) < share_size, S2N_ERR_BAD_KEY_SHARE); diff --git a/tls/extensions/s2n_server_max_fragment_length.c b/tls/extensions/s2n_server_max_fragment_length.c index 7ba3ddfdf9c..45158f5e4f4 100644 --- a/tls/extensions/s2n_server_max_fragment_length.c +++ b/tls/extensions/s2n_server_max_fragment_length.c @@ -54,7 +54,7 @@ static int s2n_max_fragment_length_recv(struct s2n_connection *conn, struct s2n_ POSIX_ENSURE_REF(conn); POSIX_ENSURE_REF(conn->config); - uint8_t mfl_code; + uint8_t mfl_code = 0; POSIX_GUARD(s2n_stuffer_read_uint8(extension, &mfl_code)); /* diff --git a/tls/s2n_alerts.c b/tls/s2n_alerts.c index ca0e2039664..88752b16d25 100644 --- a/tls/s2n_alerts.c +++ b/tls/s2n_alerts.c @@ -97,6 +97,8 @@ static S2N_RESULT s2n_translate_protocol_error_to_alert(int error_code, uint8_t S2N_NO_ALERT(S2N_ERR_ECDHE_GEN_KEY); S2N_NO_ALERT(S2N_ERR_ECDHE_SHARED_SECRET); S2N_NO_ALERT(S2N_ERR_ECDHE_UNSUPPORTED_CURVE); + S2N_NO_ALERT(S2N_ERR_ECDHE_INVALID_PUBLIC_KEY); + S2N_NO_ALERT(S2N_ERR_ECDHE_INVALID_PUBLIC_KEY_FIPS); S2N_NO_ALERT(S2N_ERR_ECDSA_UNSUPPORTED_CURVE); S2N_NO_ALERT(S2N_ERR_ECDHE_SERIALIZING); S2N_NO_ALERT(S2N_ERR_KEM_UNSUPPORTED_PARAMS); diff --git a/tls/s2n_auth_selection.c b/tls/s2n_auth_selection.c index 564b8488027..3d56a022104 100644 --- a/tls/s2n_auth_selection.c +++ b/tls/s2n_auth_selection.c @@ -123,7 +123,7 @@ static int s2n_certs_exist_for_sig_scheme(struct s2n_connection *conn, const str POSIX_ENSURE_REF(cert->cert_chain); POSIX_ENSURE_REF(cert->cert_chain->head); POSIX_ENSURE_EQ(cert->cert_chain->head->pkey_type, S2N_PKEY_TYPE_ECDSA); - POSIX_ENSURE_EQ(cert->cert_chain->head->ec_curve_nid, sig_scheme->signature_curve->libcrypto_nid); + POSIX_ENSURE_EQ(cert->cert_chain->head->info.public_key_nid, sig_scheme->signature_curve->libcrypto_nid); } return S2N_SUCCESS; diff --git a/tls/s2n_cbc.c b/tls/s2n_cbc.c index cc9d0546dcb..20367a10a0f 100644 --- a/tls/s2n_cbc.c +++ b/tls/s2n_cbc.c @@ -45,7 +45,7 @@ */ int s2n_verify_cbc(struct s2n_connection *conn, struct s2n_hmac_state *hmac, struct s2n_blob *decrypted) { - uint8_t mac_digest_size; + uint8_t mac_digest_size = 0; POSIX_GUARD(s2n_hmac_digest_size(hmac->alg, &mac_digest_size)); /* The record has to be at least big enough to contain the MAC, diff --git a/tls/s2n_certificate_keys.c b/tls/s2n_certificate_keys.c new file mode 100644 index 00000000000..276c47935ef --- /dev/null +++ b/tls/s2n_certificate_keys.c @@ -0,0 +1,73 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +#include "tls/s2n_certificate_keys.h" + +#include + +const struct s2n_certificate_key s2n_rsa_rsae_1024 = { + .public_key_libcrypto_nid = NID_rsaEncryption, + .bits = 1024, +}; + +const struct s2n_certificate_key s2n_rsa_rsae_2048 = { + .public_key_libcrypto_nid = NID_rsaEncryption, + .bits = 2048, +}; + +const struct s2n_certificate_key s2n_rsa_rsae_3072 = { + .public_key_libcrypto_nid = NID_rsaEncryption, + .bits = 3072, +}; + +const struct s2n_certificate_key s2n_rsa_rsae_4096 = { + .public_key_libcrypto_nid = NID_rsaEncryption, + .bits = 4096, +}; + +const struct s2n_certificate_key s2n_rsa_pss_1024 = { + .public_key_libcrypto_nid = NID_rsassaPss, + .bits = 1024, +}; + +const struct s2n_certificate_key s2n_rsa_pss_2048 = { + .public_key_libcrypto_nid = NID_rsassaPss, + .bits = 2048, +}; + +const struct s2n_certificate_key s2n_rsa_pss_3072 = { + .public_key_libcrypto_nid = NID_rsassaPss, + .bits = 3072, +}; + +const struct s2n_certificate_key s2n_rsa_pss_4096 = { + .public_key_libcrypto_nid = NID_rsassaPss, + .bits = 4096, +}; + +const struct s2n_certificate_key s2n_ec_p256 = { + .public_key_libcrypto_nid = NID_X9_62_prime256v1, + .bits = 256, +}; + +const struct s2n_certificate_key s2n_ec_p384 = { + .public_key_libcrypto_nid = NID_secp384r1, + .bits = 384, +}; + +const struct s2n_certificate_key s2n_ec_p521 = { + .public_key_libcrypto_nid = NID_secp521r1, + .bits = 521, +}; diff --git a/tls/s2n_certificate_keys.h b/tls/s2n_certificate_keys.h new file mode 100644 index 00000000000..bcae037374a --- /dev/null +++ b/tls/s2n_certificate_keys.h @@ -0,0 +1,44 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +#pragma once + +#include + +struct s2n_certificate_key { + uint16_t public_key_libcrypto_nid; + + /* modulus for RSA key, size for EC key */ + uint16_t bits; +}; + +struct s2n_certificate_key_preferences { + uint8_t count; + const struct s2n_certificate_key *const *certificate_keys; +}; + +extern const struct s2n_certificate_key s2n_rsa_rsae_1024; +extern const struct s2n_certificate_key s2n_rsa_rsae_2048; +extern const struct s2n_certificate_key s2n_rsa_rsae_3072; +extern const struct s2n_certificate_key s2n_rsa_rsae_4096; + +extern const struct s2n_certificate_key s2n_rsa_pss_1024; +extern const struct s2n_certificate_key s2n_rsa_pss_2048; +extern const struct s2n_certificate_key s2n_rsa_pss_3072; +extern const struct s2n_certificate_key s2n_rsa_pss_4096; + +extern const struct s2n_certificate_key s2n_ec_p256; +extern const struct s2n_certificate_key s2n_ec_p384; +extern const struct s2n_certificate_key s2n_ec_p521; diff --git a/tls/s2n_change_cipher_spec.c b/tls/s2n_change_cipher_spec.c index 14478e6d291..60cc45ad842 100644 --- a/tls/s2n_change_cipher_spec.c +++ b/tls/s2n_change_cipher_spec.c @@ -27,7 +27,7 @@ int s2n_basic_ccs_recv(struct s2n_connection *conn) { - uint8_t type; + uint8_t type = 0; POSIX_GUARD(s2n_stuffer_read_uint8(&conn->handshake.io, &type)); S2N_ERROR_IF(type != CHANGE_CIPHER_SPEC_TYPE, S2N_ERR_BAD_MESSAGE); diff --git a/tls/s2n_cipher_suites.c b/tls/s2n_cipher_suites.c index 81e08a8126b..02110a767e0 100644 --- a/tls/s2n_cipher_suites.c +++ b/tls/s2n_cipher_suites.c @@ -1089,7 +1089,7 @@ int s2n_set_cipher_as_client(struct s2n_connection *conn, uint8_t wire[S2N_TLS_C POSIX_ENSURE_REF(conn->secure); POSIX_ENSURE_REF(conn->secure->cipher_suite); - const struct s2n_security_policy *security_policy; + const struct s2n_security_policy *security_policy = NULL; POSIX_GUARD(s2n_connection_get_security_policy(conn, &security_policy)); POSIX_ENSURE_REF(security_policy); @@ -1232,7 +1232,7 @@ static int s2n_set_cipher_as_server(struct s2n_connection *conn, uint8_t *wire, conn->secure_renegotiation = 1; } - const struct s2n_security_policy *security_policy; + const struct s2n_security_policy *security_policy = NULL; POSIX_GUARD(s2n_connection_get_security_policy(conn, &security_policy)); const struct s2n_cipher_preferences *cipher_preferences = security_policy->cipher_preferences; diff --git a/tls/s2n_client_cert.c b/tls/s2n_client_cert.c index d2183277dfd..8d4af88645c 100644 --- a/tls/s2n_client_cert.c +++ b/tls/s2n_client_cert.c @@ -102,7 +102,7 @@ static S2N_RESULT s2n_client_cert_chain_store(struct s2n_connection *conn, int s2n_client_cert_recv(struct s2n_connection *conn) { if (conn->actual_protocol_version == S2N_TLS13) { - uint8_t certificate_request_context_len; + uint8_t certificate_request_context_len = 0; POSIX_GUARD(s2n_stuffer_read_uint8(&conn->handshake.io, &certificate_request_context_len)); S2N_ERROR_IF(certificate_request_context_len != 0, S2N_ERR_BAD_MESSAGE); } diff --git a/tls/s2n_client_cert_verify.c b/tls/s2n_client_cert_verify.c index c037bcea27a..1bdc2064c3a 100644 --- a/tls/s2n_client_cert_verify.c +++ b/tls/s2n_client_cert_verify.c @@ -37,7 +37,7 @@ int s2n_client_cert_verify_recv(struct s2n_connection *conn) const struct s2n_signature_scheme *chosen_sig_scheme = conn->handshake_params.client_cert_sig_scheme; POSIX_ENSURE_REF(chosen_sig_scheme); - uint16_t signature_size; + uint16_t signature_size = 0; struct s2n_blob signature = { 0 }; POSIX_GUARD(s2n_stuffer_read_uint16(in, &signature_size)); signature.size = signature_size; diff --git a/tls/s2n_client_finished.c b/tls/s2n_client_finished.c index b805a186a6f..eea8eaf0a5c 100644 --- a/tls/s2n_client_finished.c +++ b/tls/s2n_client_finished.c @@ -57,7 +57,7 @@ int s2n_tls13_client_finished_recv(struct s2n_connection *conn) /* read finished mac from handshake */ struct s2n_blob wire_finished_mac = { 0 }; - s2n_blob_init(&wire_finished_mac, s2n_stuffer_raw_read(&conn->handshake.io, length), length); + POSIX_GUARD(s2n_blob_init(&wire_finished_mac, s2n_stuffer_raw_read(&conn->handshake.io, length), length)); /* get tls13 keys */ s2n_tls13_connection_keys(keys, conn); diff --git a/tls/s2n_client_hello.c b/tls/s2n_client_hello.c index bba2f13b128..17bf3e6a82b 100644 --- a/tls/s2n_client_hello.c +++ b/tls/s2n_client_hello.c @@ -26,6 +26,7 @@ #include "crypto/s2n_rsa_signing.h" #include "error/s2n_errno.h" #include "stuffer/s2n_stuffer.h" +#include "tls/extensions/s2n_client_server_name.h" #include "tls/extensions/s2n_client_supported_groups.h" #include "tls/extensions/s2n_extension_list.h" #include "tls/extensions/s2n_server_key_share.h" @@ -231,39 +232,40 @@ static S2N_RESULT s2n_client_hello_verify_for_retry(struct s2n_connection *conn, *# ClientHello without modification, except as follows: * * All of the exceptions that follow are extensions. - * Ignoring the extensions, the client hellos should match /exactly/. */ - ssize_t old_msg_len = old_ch->raw_message.size; - /* Also consider the 2-byte size of the extension list */ - ssize_t old_extensions_len = old_ch->extensions.raw.size + sizeof(uint16_t); - RESULT_ENSURE_GT(old_msg_len, old_extensions_len); - size_t verify_len = old_msg_len - old_extensions_len; - RESULT_ENSURE_LTE(verify_len, new_ch->raw_message.size); - RESULT_ENSURE(s2n_constant_time_equals( - old_ch->raw_message.data, - new_ch->raw_message.data, - verify_len), + RESULT_ENSURE(old_ch->legacy_version == new_ch->legacy_version, S2N_ERR_BAD_MESSAGE); + RESULT_ENSURE(old_ch->compression_methods.size == new_ch->compression_methods.size, S2N_ERR_BAD_MESSAGE); + RESULT_ENSURE(s2n_constant_time_equals(old_ch->compression_methods.data, new_ch->compression_methods.data, + new_ch->compression_methods.size), S2N_ERR_BAD_MESSAGE); - /* In the past, the s2n-tls client updated the client hello in ways not - * allowed by RFC8446: https://github.com/aws/s2n-tls/pull/3311 - * Although the issue was addressed, its existence means that old versions - * of the s2n-tls client will fail this validation. - * - * So to avoid breaking old s2n-tls clients, we do not enforce this validation - * outside of tests. We continue to enforce it during tests to avoid regressions. + /* Some clients are not compliant with TLS 1.3 RFC, and send mismatching values in their second + * ClientHello. For increased compatibility, these checks are skipped outside of tests. The + * checks are still included in tests to ensure the s2n-tls client remains compliant. */ if (s2n_in_test()) { - /* - * We need to verify the client random separately - * because we erase it from the client hello during parsing. - * Compare the old value to the current value. + /* In the past, the s2n-tls client updated the client random in the second ClientHello + * which is not allowed by RFC8446: https://github.com/aws/s2n-tls/pull/3311. Although the + * issue was addressed, its existence means that old versions of the s2n-tls client will + * fail this validation. */ RESULT_ENSURE(s2n_constant_time_equals( previous_client_random, conn->handshake_params.client_random, S2N_TLS_RANDOM_DATA_LEN), S2N_ERR_BAD_MESSAGE); + + /* Some clients have been found to send a mismatching legacy session ID. */ + RESULT_ENSURE(old_ch->session_id.size == new_ch->session_id.size, S2N_ERR_BAD_MESSAGE); + RESULT_ENSURE(s2n_constant_time_equals(old_ch->session_id.data, new_ch->session_id.data, + new_ch->session_id.size), + S2N_ERR_BAD_MESSAGE); + + /* Some clients have been found to send a mismatching cipher suite list. */ + RESULT_ENSURE(old_ch->cipher_suites.size == new_ch->cipher_suites.size, S2N_ERR_BAD_MESSAGE); + RESULT_ENSURE(s2n_constant_time_equals(old_ch->cipher_suites.data, new_ch->cipher_suites.data, + new_ch->cipher_suites.size), + S2N_ERR_BAD_MESSAGE); } /* @@ -324,6 +326,17 @@ static S2N_RESULT s2n_client_hello_verify_for_retry(struct s2n_connection *conn, case TLS_EXTENSION_PRE_SHARED_KEY: /* Handled when parsing the psk extension */ break; + + /* Some clients have been found to send mismatching supported versions in their second + * ClientHello. The extension isn't compared byte-for-byte for increased compatibility + * with these clients. + */ + case TLS_EXTENSION_SUPPORTED_VERSIONS: + /* Additional HRR validation for the supported versions extension is performed when + * parsing the extension. + */ + break; + /* * No more exceptions. * All other extensions must match. @@ -373,6 +386,12 @@ S2N_RESULT s2n_client_hello_parse_raw(struct s2n_client_hello *client_hello, /* legacy_version */ RESULT_GUARD_POSIX(s2n_stuffer_read_bytes(in, client_protocol_version, S2N_TLS_PROTOCOL_VERSION_LEN)); + /* Encode the version as a 1 byte representation of the two protocol version bytes, with the + * major version in the tens place and the minor version in the ones place. For example, the + * TLS 1.2 protocol version is 0x0303, which is encoded as S2N_TLS12 (33). + */ + client_hello->legacy_version = (client_protocol_version[0] * 10) + client_protocol_version[1]; + /* random */ RESULT_GUARD_POSIX(s2n_stuffer_erase_and_read_bytes(in, client_random, S2N_TLS_RANDOM_DATA_LEN)); @@ -393,10 +412,12 @@ S2N_RESULT s2n_client_hello_parse_raw(struct s2n_client_hello *client_hello, RESULT_ENSURE(cipher_suites != NULL, S2N_ERR_BAD_MESSAGE); RESULT_GUARD_POSIX(s2n_blob_init(&client_hello->cipher_suites, cipher_suites, cipher_suites_length)); - /* legacy_compression_methods (ignored) */ - uint8_t num_compression_methods = 0; - RESULT_GUARD_POSIX(s2n_stuffer_read_uint8(in, &num_compression_methods)); - RESULT_GUARD_POSIX(s2n_stuffer_skip_read(in, num_compression_methods)); + /* legacy_compression_methods */ + uint8_t compression_methods_len = 0; + RESULT_GUARD_POSIX(s2n_stuffer_read_uint8(in, &compression_methods_len)); + uint8_t *compression_methods = s2n_stuffer_raw_read(in, compression_methods_len); + RESULT_ENSURE(compression_methods != NULL, S2N_ERR_BAD_MESSAGE); + RESULT_GUARD_POSIX(s2n_blob_init(&client_hello->compression_methods, compression_methods, compression_methods_len)); /* extensions */ RESULT_GUARD_POSIX(s2n_extension_list_parse(in, &client_hello->extensions)); @@ -536,7 +557,7 @@ int s2n_process_client_hello(struct s2n_connection *conn) * Negotiate protocol version, cipher suite, ALPN, select a cert, etc. */ struct s2n_client_hello *client_hello = &conn->client_hello; - const struct s2n_security_policy *security_policy; + const struct s2n_security_policy *security_policy = NULL; POSIX_GUARD(s2n_connection_get_security_policy(conn, &security_policy)); if (!s2n_connection_supports_tls13(conn) || !s2n_security_policy_supports_tls13(security_policy)) { @@ -680,7 +701,7 @@ int s2n_client_hello_send(struct s2n_connection *conn) { POSIX_ENSURE_REF(conn); - const struct s2n_security_policy *security_policy; + const struct s2n_security_policy *security_policy = NULL; POSIX_GUARD(s2n_connection_get_security_policy(conn, &security_policy)); const struct s2n_cipher_preferences *cipher_preferences = security_policy->cipher_preferences; @@ -800,7 +821,7 @@ int s2n_sslv2_client_hello_recv(struct s2n_connection *conn) POSIX_GUARD(s2n_stuffer_skip_write(&in_stuffer, client_hello->raw_message.size)); struct s2n_stuffer *in = &in_stuffer; - const struct s2n_security_policy *security_policy; + const struct s2n_security_policy *security_policy = NULL; POSIX_GUARD(s2n_connection_get_security_policy(conn, &security_policy)); if (conn->client_protocol_version < security_policy->minimum_protocol_version) { @@ -810,15 +831,15 @@ int s2n_sslv2_client_hello_recv(struct s2n_connection *conn) conn->actual_protocol_version = MIN(conn->client_protocol_version, conn->server_protocol_version); /* We start 5 bytes into the record */ - uint16_t cipher_suites_length; + uint16_t cipher_suites_length = 0; POSIX_GUARD(s2n_stuffer_read_uint16(in, &cipher_suites_length)); POSIX_ENSURE(cipher_suites_length > 0, S2N_ERR_BAD_MESSAGE); POSIX_ENSURE(cipher_suites_length % S2N_SSLv2_CIPHER_SUITE_LEN == 0, S2N_ERR_BAD_MESSAGE); - uint16_t session_id_length; + uint16_t session_id_length = 0; POSIX_GUARD(s2n_stuffer_read_uint16(in, &session_id_length)); - uint16_t challenge_length; + uint16_t challenge_length = 0; POSIX_GUARD(s2n_stuffer_read_uint16(in, &challenge_length)); S2N_ERROR_IF(challenge_length > S2N_TLS_RANDOM_DATA_LEN, S2N_ERR_BAD_MESSAGE); @@ -858,7 +879,7 @@ int s2n_client_hello_get_parsed_extension(s2n_tls_extension_type extension_type, POSIX_ENSURE_REF(parsed_extension_list); POSIX_ENSURE_REF(parsed_extension); - s2n_extension_type_id extension_type_id; + s2n_extension_type_id extension_type_id = 0; POSIX_GUARD(s2n_extension_supported_iana_value_to_id(extension_type, &extension_type_id)); s2n_parsed_extension *found_parsed_extension = &parsed_extension_list->parsed_extensions[extension_type_id]; @@ -917,7 +938,44 @@ int s2n_client_hello_get_session_id(struct s2n_client_hello *ch, uint8_t *out, u return S2N_SUCCESS; } -static S2N_RESULT s2n_client_hello_get_raw_extension(uint16_t extension_iana, +int s2n_client_hello_get_compression_methods_length(struct s2n_client_hello *ch, uint32_t *out_length) +{ + POSIX_ENSURE_REF(ch); + POSIX_ENSURE_REF(out_length); + *out_length = ch->compression_methods.size; + return S2N_SUCCESS; +} + +int s2n_client_hello_get_compression_methods(struct s2n_client_hello *ch, uint8_t *list, uint32_t list_length, uint32_t *out_length) +{ + POSIX_ENSURE_REF(ch); + POSIX_ENSURE_REF(list); + POSIX_ENSURE_REF(out_length); + + POSIX_ENSURE(list_length >= ch->compression_methods.size, S2N_ERR_INSUFFICIENT_MEM_SIZE); + POSIX_CHECKED_MEMCPY(list, ch->compression_methods.data, ch->compression_methods.size); + *out_length = ch->compression_methods.size; + return S2N_SUCCESS; +} + +int s2n_client_hello_get_legacy_protocol_version(struct s2n_client_hello *ch, uint8_t *out) +{ + POSIX_ENSURE_REF(ch); + POSIX_ENSURE_REF(out); + *out = ch->legacy_version; + return S2N_SUCCESS; +} + +int s2n_client_hello_get_legacy_record_version(struct s2n_client_hello *ch, uint8_t *out) +{ + POSIX_ENSURE_REF(ch); + POSIX_ENSURE_REF(out); + POSIX_ENSURE(ch->record_version_recorded, S2N_ERR_INVALID_ARGUMENT); + *out = ch->legacy_record_version; + return S2N_SUCCESS; +} + +S2N_RESULT s2n_client_hello_get_raw_extension(uint16_t extension_iana, struct s2n_blob *raw_extensions, struct s2n_blob *extension) { RESULT_ENSURE_REF(raw_extensions); @@ -1001,3 +1059,47 @@ int s2n_client_hello_get_supported_groups(struct s2n_client_hello *ch, uint16_t return S2N_SUCCESS; } + +int s2n_client_hello_get_server_name_length(struct s2n_client_hello *ch, uint16_t *length) +{ + POSIX_ENSURE_REF(ch); + POSIX_ENSURE_REF(length); + *length = 0; + + s2n_parsed_extension *server_name_extension = NULL; + POSIX_GUARD(s2n_client_hello_get_parsed_extension(S2N_EXTENSION_SERVER_NAME, &ch->extensions, &server_name_extension)); + POSIX_ENSURE_REF(server_name_extension); + + struct s2n_stuffer extension_stuffer = { 0 }; + POSIX_GUARD(s2n_stuffer_init_written(&extension_stuffer, &server_name_extension->extension)); + + struct s2n_blob blob = { 0 }; + POSIX_GUARD_RESULT(s2n_client_server_name_parse(&extension_stuffer, &blob)); + *length = blob.size; + + return S2N_SUCCESS; +} + +int s2n_client_hello_get_server_name(struct s2n_client_hello *ch, uint8_t *server_name, uint16_t length, uint16_t *out_length) +{ + POSIX_ENSURE_REF(out_length); + POSIX_ENSURE_REF(ch); + POSIX_ENSURE_REF(server_name); + *out_length = 0; + + s2n_parsed_extension *server_name_extension = NULL; + POSIX_GUARD(s2n_client_hello_get_parsed_extension(S2N_EXTENSION_SERVER_NAME, &ch->extensions, &server_name_extension)); + POSIX_ENSURE_REF(server_name_extension); + + struct s2n_stuffer extension_stuffer = { 0 }; + POSIX_GUARD(s2n_stuffer_init_written(&extension_stuffer, &server_name_extension->extension)); + + struct s2n_blob blob = { 0 }; + POSIX_GUARD_RESULT(s2n_client_server_name_parse(&extension_stuffer, &blob)); + POSIX_ENSURE_LTE(blob.size, length); + POSIX_CHECKED_MEMCPY(server_name, blob.data, blob.size); + + *out_length = blob.size; + + return S2N_SUCCESS; +} diff --git a/tls/s2n_client_hello.h b/tls/s2n_client_hello.h index bed6a568497..8d6d32eb317 100644 --- a/tls/s2n_client_hello.h +++ b/tls/s2n_client_hello.h @@ -31,6 +31,13 @@ struct s2n_client_hello { s2n_parsed_extensions_list extensions; struct s2n_blob cipher_suites; struct s2n_blob session_id; + struct s2n_blob compression_methods; + /* The protocol version as written in the client hello */ + uint8_t legacy_version; + /* The protocol written on the record header containing the client hello */ + uint8_t legacy_record_version; + /* Tracks if we have recorded the version in the first record */ + unsigned int record_version_recorded : 1; unsigned int callback_invoked : 1; unsigned int callback_async_blocked : 1; diff --git a/tls/s2n_client_key_exchange.c b/tls/s2n_client_key_exchange.c index fdb08fb88b8..29114df7035 100644 --- a/tls/s2n_client_key_exchange.c +++ b/tls/s2n_client_key_exchange.c @@ -111,7 +111,7 @@ int s2n_rsa_client_key_recv(struct s2n_connection *conn, struct s2n_blob *shared struct s2n_stuffer *in = &conn->handshake.io; uint8_t client_hello_protocol_version[S2N_TLS_PROTOCOL_VERSION_LEN]; - uint16_t length; + uint16_t length = 0; if (conn->actual_protocol_version == S2N_SSLv3) { length = s2n_stuffer_data_available(in); diff --git a/tls/s2n_config.c b/tls/s2n_config.c index 45bb6790995..aea8689a217 100644 --- a/tls/s2n_config.c +++ b/tls/s2n_config.c @@ -96,10 +96,6 @@ static int s2n_config_init(struct s2n_config *config) config->encrypt_decrypt_key_lifetime_in_nanos = S2N_TICKET_ENCRYPT_DECRYPT_KEY_LIFETIME_IN_NANOS; config->decrypt_key_lifetime_in_nanos = S2N_TICKET_DECRYPT_KEY_LIFETIME_IN_NANOS; config->async_pkey_validation_mode = S2N_ASYNC_PKEY_VALIDATION_FAST; - - /* By default, only the client will authenticate the Server's Certificate. The Server does not request or - * authenticate any client certificates. */ - config->client_cert_auth_type = S2N_CERT_AUTH_NONE; config->check_ocsp = 1; config->client_hello_cb_mode = S2N_CLIENT_HELLO_CB_BLOCKING; @@ -130,6 +126,8 @@ static int s2n_config_cleanup(struct s2n_config *config) POSIX_GUARD(s2n_free(&config->application_protocols)); POSIX_GUARD_RESULT(s2n_map_free(config->domain_name_to_cert_map)); + POSIX_CHECKED_MEMSET(config, 0, sizeof(struct s2n_config)); + return 0; } @@ -182,7 +180,7 @@ static int s2n_config_update_domain_name_to_cert_map(struct s2n_config *config, return 0; } -static int s2n_config_build_domain_name_to_cert_map(struct s2n_config *config, struct s2n_cert_chain_and_key *cert_key_pair) +int s2n_config_build_domain_name_to_cert_map(struct s2n_config *config, struct s2n_cert_chain_and_key *cert_key_pair) { uint32_t cn_len = 0; POSIX_GUARD_RESULT(s2n_array_num_elements(cert_key_pair->cn_names, &cn_len)); @@ -220,7 +218,6 @@ struct s2n_config *s2n_fetch_default_config(void) int s2n_config_set_unsafe_for_testing(struct s2n_config *config) { POSIX_ENSURE(s2n_in_test(), S2N_ERR_NOT_IN_TEST); - config->client_cert_auth_type = S2N_CERT_AUTH_NONE; config->check_ocsp = 0; config->disable_x509_validation = 1; @@ -241,14 +238,19 @@ int s2n_config_defaults_init(void) POSIX_GUARD(s2n_config_load_system_certs(&s2n_default_config)); } - /* Set up TLS 1.3 defaults */ + /* TLS 1.3 default config is only used in tests so avoid initialization costs in applications */ POSIX_GUARD(s2n_config_init(&s2n_default_tls13_config)); POSIX_GUARD(s2n_config_setup_tls13(&s2n_default_tls13_config)); - POSIX_GUARD(s2n_config_load_system_certs(&s2n_default_tls13_config)); return S2N_SUCCESS; } +S2N_RESULT s2n_config_testing_defaults_init_tls13_certs(void) +{ + RESULT_GUARD_POSIX(s2n_config_load_system_certs(&s2n_default_tls13_config)); + return S2N_RESULT_OK; +} + void s2n_wipe_static_configs(void) { s2n_config_cleanup(&s2n_default_fips_config); @@ -281,7 +283,7 @@ int s2n_config_load_system_certs(struct s2n_config *config) struct s2n_config *s2n_config_new_minimal(void) { struct s2n_blob allocator = { 0 }; - struct s2n_config *new_config; + struct s2n_config *new_config = NULL; PTR_GUARD_POSIX(s2n_alloc(&allocator, sizeof(struct s2n_config))); PTR_GUARD_POSIX(s2n_blob_zero(&allocator)); @@ -408,6 +410,7 @@ int s2n_config_get_client_auth_type(struct s2n_config *config, s2n_cert_auth_typ int s2n_config_set_client_auth_type(struct s2n_config *config, s2n_cert_auth_type client_auth_type) { POSIX_ENSURE_REF(config); + config->client_cert_auth_type_overridden = 1; config->client_cert_auth_type = client_auth_type; return 0; } @@ -557,6 +560,41 @@ static int s2n_config_add_cert_chain_and_key_impl(struct s2n_config *config, str return S2N_SUCCESS; } +S2N_RESULT s2n_config_validate_loaded_certificates(const struct s2n_config *config, + const struct s2n_security_policy *security_policy) +{ + RESULT_ENSURE_REF(config); + RESULT_ENSURE_REF(security_policy); + + /* validate the default certs */ + for (int i = 0; i < S2N_CERT_TYPE_COUNT; i++) { + struct s2n_cert_chain_and_key *cert = config->default_certs_by_type.certs[i]; + if (cert == NULL) { + continue; + } + RESULT_GUARD(s2n_security_policy_validate_certificate_chain(security_policy, cert)); + } + + /* validate the certs in the domain map */ + struct s2n_map_iterator iter = { 0 }; + RESULT_GUARD(s2n_map_iterator_init(&iter, config->domain_name_to_cert_map)); + + while (s2n_map_iterator_has_next(&iter)) { + struct s2n_blob value = { 0 }; + RESULT_GUARD(s2n_map_iterator_next(&iter, &value)); + + struct certs_by_type *domain_certs = (void *) value.data; + for (int i = 0; i < S2N_CERT_TYPE_COUNT; i++) { + struct s2n_cert_chain_and_key *cert = domain_certs->certs[i]; + if (cert == NULL) { + continue; + } + RESULT_GUARD(s2n_security_policy_validate_certificate_chain(security_policy, cert)); + } + } + return S2N_RESULT_OK; +} + /* Deprecated. Superseded by s2n_config_add_cert_chain_and_key_to_store */ int s2n_config_add_cert_chain_and_key(struct s2n_config *config, const char *cert_chain_pem, const char *private_key_pem) { @@ -986,7 +1024,7 @@ struct s2n_cert_chain_and_key *s2n_config_get_single_default_cert(struct s2n_con return cert; } -int s2n_config_get_num_default_certs(struct s2n_config *config) +int s2n_config_get_num_default_certs(const struct s2n_config *config) { POSIX_ENSURE_REF(config); int num_certs = 0; diff --git a/tls/s2n_config.h b/tls/s2n_config.h index 22aea637449..10da5ce8f1a 100644 --- a/tls/s2n_config.h +++ b/tls/s2n_config.h @@ -144,6 +144,16 @@ struct s2n_config { s2n_ct_support_level ct_type; + /* Track whether the application has overriden the default client auth type. + * Clients and servers have different default client auth behavior, and this + * config could apply to either. + * This should be a bitflag, but that change is blocked on the SAW proofs. + */ + uint8_t client_cert_auth_type_overridden; + + /* Whether or not the client should authenticate itself to the server. + * Only used if client_cert_auth_type_overridden is true. + */ s2n_cert_auth_type client_cert_auth_type; s2n_alert_behavior alert_behavior; @@ -203,6 +213,7 @@ struct s2n_config { S2N_CLEANUP_RESULT s2n_config_ptr_free(struct s2n_config **config); int s2n_config_defaults_init(void); +S2N_RESULT s2n_config_testing_defaults_init_tls13_certs(void); struct s2n_config *s2n_fetch_default_config(void); int s2n_config_set_unsafe_for_testing(struct s2n_config *config); @@ -211,5 +222,10 @@ int s2n_config_free_session_ticket_keys(struct s2n_config *config); void s2n_wipe_static_configs(void); struct s2n_cert_chain_and_key *s2n_config_get_single_default_cert(struct s2n_config *config); -int s2n_config_get_num_default_certs(struct s2n_config *config); +int s2n_config_get_num_default_certs(const struct s2n_config *config); S2N_RESULT s2n_config_wall_clock(struct s2n_config *config, uint64_t *output); + +/* Validate that the certificates in `config` respect the certificate preferences + * in `security_policy` */ +S2N_RESULT s2n_config_validate_loaded_certificates(const struct s2n_config *config, + const struct s2n_security_policy *security_policy); diff --git a/tls/s2n_connection.c b/tls/s2n_connection.c index cabc2ea9f15..1a555bdc054 100644 --- a/tls/s2n_connection.c +++ b/tls/s2n_connection.c @@ -59,6 +59,9 @@ #define S2N_SET_KEY_SHARE_LIST_EMPTY(keyshares) (keyshares |= 1) #define S2N_SET_KEY_SHARE_REQUEST(keyshares, i) (keyshares |= (1 << (i + 1))) +static S2N_RESULT s2n_connection_and_config_get_client_auth_type(const struct s2n_connection *conn, + const struct s2n_config *config, s2n_cert_auth_type *client_cert_auth_type); + /* Allocates and initializes memory for a new connection. * * Since customers can reuse a connection, ensure that values on the connection are @@ -283,6 +286,12 @@ int s2n_connection_set_config(struct s2n_connection *conn, struct s2n_config *co return 0; } + const struct s2n_security_policy *security_policy = conn->security_policy_override; + if (!security_policy) { + security_policy = config->security_policy; + } + POSIX_GUARD_RESULT(s2n_config_validate_loaded_certificates(config, security_policy)); + /* We only support one client certificate */ if (s2n_config_get_num_default_certs(config) > 1 && conn->mode == S2N_CLIENT) { POSIX_BAIL(S2N_ERR_TOO_MANY_CERTIFICATES); @@ -290,11 +299,8 @@ int s2n_connection_set_config(struct s2n_connection *conn, struct s2n_config *co s2n_x509_validator_wipe(&conn->x509_validator); - s2n_cert_auth_type auth_type = config->client_cert_auth_type; - - if (conn->client_cert_auth_type_overridden) { - auth_type = conn->client_cert_auth_type; - } + s2n_cert_auth_type auth_type = S2N_CERT_AUTH_NONE; + POSIX_GUARD_RESULT(s2n_connection_and_config_get_client_auth_type(conn, config, &auth_type)); int8_t dont_need_x509_validation = (conn->mode == S2N_SERVER) && (auth_type == S2N_CERT_AUTH_NONE); @@ -742,19 +748,37 @@ int s2n_connection_get_protocol_preferences(struct s2n_connection *conn, struct return 0; } -int s2n_connection_get_client_auth_type(struct s2n_connection *conn, s2n_cert_auth_type *client_cert_auth_type) +static S2N_RESULT s2n_connection_and_config_get_client_auth_type(const struct s2n_connection *conn, + const struct s2n_config *config, s2n_cert_auth_type *client_cert_auth_type) { - POSIX_ENSURE_REF(conn); - POSIX_ENSURE_REF(client_cert_auth_type); + RESULT_ENSURE_REF(conn); + RESULT_ENSURE_REF(config); + RESULT_ENSURE_REF(client_cert_auth_type); if (conn->client_cert_auth_type_overridden) { *client_cert_auth_type = conn->client_cert_auth_type; + } else if (config->client_cert_auth_type_overridden) { + *client_cert_auth_type = config->client_cert_auth_type; + } else if (conn->mode == S2N_CLIENT) { + /* Clients should default to "Optional" so that they handle any + * CertificateRequests sent by the server. + */ + *client_cert_auth_type = S2N_CERT_AUTH_OPTIONAL; } else { - POSIX_ENSURE_REF(conn->config); - *client_cert_auth_type = conn->config->client_cert_auth_type; + /* Servers should default to "None" so that they send no CertificateRequests. */ + *client_cert_auth_type = S2N_CERT_AUTH_NONE; } - return 0; + return S2N_RESULT_OK; +} + +int s2n_connection_get_client_auth_type(struct s2n_connection *conn, + s2n_cert_auth_type *client_cert_auth_type) +{ + POSIX_ENSURE_REF(conn); + POSIX_GUARD_RESULT(s2n_connection_and_config_get_client_auth_type( + conn, conn->config, client_cert_auth_type)); + return S2N_SUCCESS; } int s2n_connection_set_client_auth_type(struct s2n_connection *conn, s2n_cert_auth_type client_cert_auth_type) @@ -767,7 +791,7 @@ int s2n_connection_set_client_auth_type(struct s2n_connection *conn, s2n_cert_au int s2n_connection_set_read_fd(struct s2n_connection *conn, int rfd) { struct s2n_blob ctx_mem = { 0 }; - struct s2n_socket_read_io_context *peer_socket_ctx; + struct s2n_socket_read_io_context *peer_socket_ctx = NULL; POSIX_ENSURE_REF(conn); POSIX_GUARD(s2n_alloc(&ctx_mem, sizeof(struct s2n_socket_read_io_context))); @@ -802,7 +826,7 @@ int s2n_connection_get_read_fd(struct s2n_connection *conn, int *readfd) int s2n_connection_set_write_fd(struct s2n_connection *conn, int wfd) { struct s2n_blob ctx_mem = { 0 }; - struct s2n_socket_write_io_context *peer_socket_ctx; + struct s2n_socket_write_io_context *peer_socket_ctx = NULL; POSIX_ENSURE_REF(conn); POSIX_GUARD(s2n_alloc(&ctx_mem, sizeof(struct s2n_socket_write_io_context))); @@ -819,7 +843,7 @@ int s2n_connection_set_write_fd(struct s2n_connection *conn, int wfd) */ POSIX_GUARD(s2n_socket_write_snapshot(conn)); - uint8_t ipv6; + uint8_t ipv6 = 0; if (0 == s2n_socket_is_ipv6(wfd, &ipv6)) { conn->ipv6 = (ipv6 ? 1 : 0); } diff --git a/tls/s2n_connection.h b/tls/s2n_connection.h index 1f8c735f127..44f3e892345 100644 --- a/tls/s2n_connection.h +++ b/tls/s2n_connection.h @@ -224,15 +224,15 @@ struct s2n_connection { /* The PRF needs some storage elements to work with */ struct s2n_prf_working_space *prf_space; - /* Whether to use client_cert_auth_type stored in s2n_config or in this s2n_connection. - * - * By default the s2n_connection will defer to s2n_config->client_cert_auth_type on whether or not to use Client Auth. - * But users can override Client Auth at the connection level using s2n_connection_set_client_auth_type() without mutating - * s2n_config since s2n_config can be shared between multiple s2n_connections. */ + /* Indicates whether the application has overridden the client auth behavior + * inherited from the config. + * This should be a bitflag, but that change is blocked on the SAW proofs. + */ uint8_t client_cert_auth_type_overridden; - /* Whether or not the s2n_connection should require the Client to authenticate itself to the server. Only used if - * client_cert_auth_type_overridden is non-zero. */ + /* Whether or not the client should authenticate itself to the server. + * Only used if client_cert_auth_type_overridden is true. + */ s2n_cert_auth_type client_cert_auth_type; /* Our workhorse stuffers, used for buffering the plaintext diff --git a/tls/s2n_handshake.h b/tls/s2n_handshake.h index 6ff1664cf48..864ba9d7d54 100644 --- a/tls/s2n_handshake.h +++ b/tls/s2n_handshake.h @@ -47,6 +47,9 @@ #define TLS_NPN 67 #define TLS_MESSAGE_HASH 254 +/* Maximum number of messages in a handshake */ +#define S2N_MAX_HANDSHAKE_LENGTH 32 + /* This is the list of message types that we support */ typedef enum { CLIENT_HELLO = 0, diff --git a/tls/s2n_handshake_io.c b/tls/s2n_handshake_io.c index 52eb65e95aa..2b16ac5c3f0 100644 --- a/tls/s2n_handshake_io.c +++ b/tls/s2n_handshake_io.c @@ -133,9 +133,6 @@ static const char *message_names[] = { MESSAGE_NAME_ENTRY(CLIENT_NPN), }; -/* Maximum number of messages in a handshake */ -#define S2N_MAX_HANDSHAKE_LENGTH 32 - /* We support different ordering of TLS Handshake messages, depending on what is being negotiated. There's also a dummy "INITIAL" handshake * that everything starts out as until we know better. */ @@ -1336,13 +1333,10 @@ static int s2n_handshake_handle_sslv2(struct s2n_connection *conn) POSIX_GUARD(s2n_stuffer_wipe(&conn->handshake.io)); /* We're done with the record, wipe it */ - POSIX_GUARD(s2n_stuffer_wipe(&conn->header_in)); - POSIX_GUARD(s2n_stuffer_wipe(&conn->in)); + POSIX_GUARD_RESULT(s2n_record_wipe(conn)); WITH_ERROR_BLINDING(conn, POSIX_GUARD(r)); - conn->in_status = ENCRYPTED; - /* Advance the state machine */ POSIX_GUARD(s2n_advance_message(conn)); @@ -1360,15 +1354,6 @@ static int s2n_try_delete_session_cache(struct s2n_connection *conn) return S2N_SUCCESS; } -static S2N_RESULT s2n_wipe_record(struct s2n_connection *conn) -{ - RESULT_ENSURE_REF(conn); - RESULT_GUARD_POSIX(s2n_stuffer_wipe(&conn->header_in)); - RESULT_GUARD_POSIX(s2n_stuffer_wipe(&conn->in)); - conn->in_status = ENCRYPTED; - return S2N_RESULT_OK; -} - static S2N_RESULT s2n_finish_read(struct s2n_connection *conn) { RESULT_ENSURE_REF(conn); @@ -1409,8 +1394,8 @@ static S2N_RESULT s2n_handshake_app_data_recv(struct s2n_connection *conn) */ static int s2n_handshake_read_io(struct s2n_connection *conn) { - uint8_t record_type; - uint8_t message_type; + uint8_t record_type = 0; + uint8_t message_type = 0; int isSSLv2 = 0; /* Fill conn->in stuffer necessary for the handshake. @@ -1439,7 +1424,7 @@ static int s2n_handshake_read_io(struct s2n_connection *conn) if ((r < S2N_SUCCESS) && (s2n_errno == S2N_ERR_EARLY_DATA_TRIAL_DECRYPT)) { POSIX_GUARD(s2n_stuffer_reread(&conn->in)); POSIX_GUARD_RESULT(s2n_early_data_record_bytes(conn, s2n_stuffer_data_available(&conn->in))); - POSIX_GUARD_RESULT(s2n_wipe_record(conn)); + POSIX_GUARD_RESULT(s2n_record_wipe(conn)); return S2N_SUCCESS; } POSIX_GUARD(r); @@ -1473,7 +1458,7 @@ static int s2n_handshake_read_io(struct s2n_connection *conn) POSIX_GUARD(s2n_stuffer_wipe(&conn->handshake.io)); /* We're done with the record, wipe it */ - POSIX_GUARD_RESULT(s2n_wipe_record(conn)); + POSIX_GUARD_RESULT(s2n_record_wipe(conn)); /* Advance the state machine if this was an expected message */ if (EXPECTED_RECORD_TYPE(conn) == TLS_CHANGE_CIPHER_SPEC && !CONNECTION_IS_WRITER(conn)) { @@ -1489,7 +1474,7 @@ static int s2n_handshake_read_io(struct s2n_connection *conn) /* Ignore record types that we don't support */ /* We're done with the record, wipe it */ - POSIX_GUARD_RESULT(s2n_wipe_record(conn)); + POSIX_GUARD_RESULT(s2n_record_wipe(conn)); return S2N_SUCCESS; } @@ -1499,7 +1484,7 @@ static int s2n_handshake_read_io(struct s2n_connection *conn) while (s2n_stuffer_data_available(&conn->in)) { /* We're done with negotiating but we have trailing data in this record. Bail on the handshake. */ S2N_ERROR_IF(EXPECTED_RECORD_TYPE(conn) == TLS_APPLICATION_DATA, S2N_ERR_BAD_MESSAGE); - int r; + int r = 0; POSIX_GUARD((r = s2n_read_full_handshake_message(conn, &message_type))); /* Do we need more data? This happens for message fragmentation */ @@ -1507,7 +1492,7 @@ static int s2n_handshake_read_io(struct s2n_connection *conn) /* Break out of this inner loop, but since we're not changing the state, the * outer loop in s2n_handshake_io() will read another record. */ - POSIX_GUARD_RESULT(s2n_wipe_record(conn)); + POSIX_GUARD_RESULT(s2n_record_wipe(conn)); return S2N_SUCCESS; } @@ -1556,7 +1541,7 @@ static int s2n_handshake_read_io(struct s2n_connection *conn) } /* We're done with the record, wipe it */ - POSIX_GUARD_RESULT(s2n_wipe_record(conn)); + POSIX_GUARD_RESULT(s2n_record_wipe(conn)); return S2N_SUCCESS; } @@ -1579,9 +1564,7 @@ static int s2n_handle_retry_state(struct s2n_connection *conn) if (!CONNECTION_IS_WRITER(conn)) { /* We're done parsing the record, reset everything */ - POSIX_GUARD(s2n_stuffer_wipe(&conn->header_in)); - POSIX_GUARD(s2n_stuffer_wipe(&conn->in)); - conn->in_status = ENCRYPTED; + POSIX_GUARD_RESULT(s2n_record_wipe(conn)); } if (CONNECTION_IS_WRITER(conn)) { diff --git a/tls/s2n_kem.c b/tls/s2n_kem.c index 59d26d48b06..175e2e62599 100644 --- a/tls/s2n_kem.c +++ b/tls/s2n_kem.c @@ -242,7 +242,7 @@ int s2n_choose_kem_with_peer_pref_list(const uint8_t iana_value[S2N_TLS_CIPHER_S } for (uint8_t j = 0; j < num_client_candidate_kems; j++) { - kem_extension_size candidate_client_kem_id; + kem_extension_size candidate_client_kem_id = 0; POSIX_GUARD(s2n_stuffer_read_uint16(&client_kem_ids_stuffer, &candidate_client_kem_id)); if (candidate_server_kem->kem_extension_id == candidate_client_kem_id) { diff --git a/tls/s2n_key_update.c b/tls/s2n_key_update.c index d10d7c5b244..be6d8eb49f2 100644 --- a/tls/s2n_key_update.c +++ b/tls/s2n_key_update.c @@ -24,12 +24,12 @@ #include "utils/s2n_atomic.h" #include "utils/s2n_safety.h" -static keyupdate_request key_update_request_val = S2N_KEY_UPDATE_NOT_REQUESTED; +static s2n_peer_key_update key_update_request_val = S2N_KEY_UPDATE_NOT_REQUESTED; int s2n_key_update_write(struct s2n_blob *out); int s2n_check_record_limit(struct s2n_connection *conn, struct s2n_blob *sequence_number); -S2N_RESULT s2n_set_key_update_request_for_testing(keyupdate_request request) +S2N_RESULT s2n_set_key_update_request_for_testing(s2n_peer_key_update request) { RESULT_ENSURE(s2n_in_unit_test(), S2N_ERR_NOT_IN_UNIT_TEST); key_update_request_val = request; @@ -43,7 +43,7 @@ int s2n_key_update_recv(struct s2n_connection *conn, struct s2n_stuffer *request POSIX_ENSURE(!s2n_connection_is_quic_enabled(conn), S2N_ERR_BAD_MESSAGE); POSIX_ENSURE(!conn->ktls_recv_enabled, S2N_ERR_KTLS_KEYUPDATE); - uint8_t key_update_request; + uint8_t key_update_request = 0; POSIX_GUARD(s2n_stuffer_read_uint8(request, &key_update_request)); if (key_update_request == S2N_KEY_UPDATE_REQUESTED) { POSIX_ENSURE(!conn->ktls_send_enabled, S2N_ERR_KTLS_KEYUPDATE); @@ -146,3 +146,12 @@ int s2n_check_record_limit(struct s2n_connection *conn, struct s2n_blob *sequenc return S2N_SUCCESS; } + +int s2n_connection_request_key_update(struct s2n_connection *conn, s2n_peer_key_update peer_request) +{ + POSIX_ENSURE_REF(conn); + /* s2n-tls does not currently support requesting key updates from peers */ + POSIX_ENSURE(peer_request == S2N_KEY_UPDATE_NOT_REQUESTED, S2N_ERR_INVALID_ARGUMENT); + s2n_atomic_flag_set(&conn->key_update_pending); + return S2N_SUCCESS; +} diff --git a/tls/s2n_key_update.h b/tls/s2n_key_update.h index 2b787f08487..79a103d8261 100644 --- a/tls/s2n_key_update.h +++ b/tls/s2n_key_update.h @@ -25,10 +25,5 @@ typedef enum { RECEIVING } keyupdate_status; -typedef enum { - S2N_KEY_UPDATE_NOT_REQUESTED = 0, - S2N_KEY_UPDATE_REQUESTED -} keyupdate_request; - int s2n_key_update_recv(struct s2n_connection *conn, struct s2n_stuffer *request); int s2n_key_update_send(struct s2n_connection *conn, s2n_blocked_status *blocked); diff --git a/tls/s2n_ktls.c b/tls/s2n_ktls.c index ed3e2024d26..15caac00337 100644 --- a/tls/s2n_ktls.c +++ b/tls/s2n_ktls.c @@ -102,7 +102,8 @@ static S2N_RESULT s2n_ktls_validate(struct s2n_connection *conn, s2n_ktls_mode k break; case S2N_KTLS_MODE_RECV: RESULT_ENSURE(conn->managed_recv_io, S2N_ERR_KTLS_MANAGED_IO); - /* The input stuffer should be empty before enabling kTLS. */ + /* The input stuffers should be empty before enabling kTLS. */ + RESULT_ENSURE(s2n_stuffer_data_available(&conn->header_in) == 0, S2N_ERR_RECORD_STUFFER_NEEDS_DRAINING); RESULT_ENSURE(s2n_stuffer_data_available(&conn->in) == 0, S2N_ERR_RECORD_STUFFER_NEEDS_DRAINING); break; default: diff --git a/tls/s2n_prf.c b/tls/s2n_prf.c index 3e912453c50..c467d3b616b 100644 --- a/tls/s2n_prf.c +++ b/tls/s2n_prf.c @@ -412,7 +412,7 @@ const struct s2n_p_hash_hmac *s2n_get_hmac_implementation() static int s2n_p_hash(struct s2n_prf_working_space *ws, s2n_hmac_algorithm alg, struct s2n_blob *secret, struct s2n_blob *label, struct s2n_blob *seed_a, struct s2n_blob *seed_b, struct s2n_blob *seed_c, struct s2n_blob *out) { - uint8_t digest_size; + uint8_t digest_size = 0; POSIX_GUARD(s2n_hmac_digest_size(alg, &digest_size)); const struct s2n_p_hash_hmac *hmac = s2n_get_hmac_implementation(); diff --git a/tls/s2n_protocol_preferences.c b/tls/s2n_protocol_preferences.c index 83fbbbd5f91..6320550c01a 100644 --- a/tls/s2n_protocol_preferences.c +++ b/tls/s2n_protocol_preferences.c @@ -129,11 +129,7 @@ S2N_RESULT s2n_protocol_preferences_set(struct s2n_blob *application_protocols, /* update the connection/config application_protocols with the newly allocated blob */ *application_protocols = new_protocols; - /* zero out new_protocols so the DEFER_CLEANUP from above doesn't free - * the blob that we created and assigned to application_protocols - */ - /* cppcheck-suppress unreadVariable */ - new_protocols = (struct s2n_blob){ 0 }; + ZERO_TO_DISABLE_DEFER_CLEANUP(new_protocols); return S2N_RESULT_OK; } diff --git a/tls/s2n_quic_support.c b/tls/s2n_quic_support.c index 210c9f72a6c..ba146eacbc9 100644 --- a/tls/s2n_quic_support.c +++ b/tls/s2n_quic_support.c @@ -136,7 +136,7 @@ S2N_RESULT s2n_quic_read_handshake_message(struct s2n_connection *conn, uint8_t RESULT_GUARD(s2n_read_in_bytes(conn, &conn->handshake.io, TLS_HANDSHAKE_HEADER_LENGTH)); - uint32_t message_len; + uint32_t message_len = 0; RESULT_GUARD(s2n_handshake_parse_header(&conn->handshake.io, message_type, &message_len)); RESULT_GUARD_POSIX(s2n_stuffer_reread(&conn->handshake.io)); diff --git a/tls/s2n_record.h b/tls/s2n_record.h index 70da62f3d0d..36d34d59eaa 100644 --- a/tls/s2n_record.h +++ b/tls/s2n_record.h @@ -22,6 +22,9 @@ #define S2N_TLS_CONTENT_TYPE_LENGTH 1 +#define S2N_TLS_SSLV2_HEADER_FLAG (0x80) +#define S2N_TLS_SSLV2_HEADER_FLAG_UINT16 (S2N_TLS_SSLV2_HEADER_FLAG << 8) + /* All versions of TLS define the record header the same: * ContentType + ProtocolVersion + length */ @@ -78,3 +81,4 @@ int s2n_sslv2_record_header_parse(struct s2n_connection *conn, uint8_t *record_t int s2n_verify_cbc(struct s2n_connection *conn, struct s2n_hmac_state *hmac, struct s2n_blob *decrypted); S2N_RESULT s2n_aead_aad_init(const struct s2n_connection *conn, uint8_t *sequence_number, uint8_t content_type, uint16_t record_length, struct s2n_blob *ad); S2N_RESULT s2n_tls13_aead_aad_init(uint16_t record_length, uint8_t tag_length, struct s2n_blob *ad); +S2N_RESULT s2n_record_wipe(struct s2n_connection *conn); diff --git a/tls/s2n_record_read.c b/tls/s2n_record_read.c index 484570e103d..5281e1734f3 100644 --- a/tls/s2n_record_read.c +++ b/tls/s2n_record_read.c @@ -34,36 +34,51 @@ int s2n_sslv2_record_header_parse( uint8_t *client_protocol_version, uint16_t *fragment_length) { - struct s2n_stuffer *in = &conn->header_in; + struct s2n_stuffer *header_in = &conn->header_in; - S2N_ERROR_IF(s2n_stuffer_data_available(in) < S2N_TLS_RECORD_HEADER_LENGTH, S2N_ERR_BAD_MESSAGE); + POSIX_ENSURE(s2n_stuffer_data_available(header_in) >= S2N_TLS_RECORD_HEADER_LENGTH, + S2N_ERR_BAD_MESSAGE); - POSIX_GUARD(s2n_stuffer_read_uint16(in, fragment_length)); + POSIX_GUARD(s2n_stuffer_read_uint16(header_in, fragment_length)); - /* The SSLv2 header is only a 2 byte record length (technically 3 bytes if - * padding is included, but s2n-tls assumes no padding). - * See https://www.ietf.org/archive/id/draft-hickman-netscape-ssl-00.txt. + /* The first bit of the SSLv2 message would usually indicate whether the + * length is 2 bytes long or 3 bytes long. + * See https://www.ietf.org/archive/id/draft-hickman-netscape-ssl-00.txt + * + * However, s2n-tls only supports SSLv2 for ClientHellos as defined in the + * TLS1.2 RFC. In that case, the first bit must always be set to distinguish + * SSLv2 from non-SSLv2 headers. The length is always 2 bytes. + * See https://datatracker.ietf.org/doc/html/rfc5246#appendix-E.2 * - * So by reading 5 bytes for a standard header we have also read the first - * 3 bytes of the record payload. s2n-tls only supports SSLv2 ClientHellos, - * so we assume that those 3 bytes are the first two fields of the - * SSLv2 ClientHello. + * Since the first bit is not actually used to indicate length, we need to + * remove it from the length. + * + *= https://tools.ietf.org/rfc/rfc5246#appendix-E.2 + *# msg_length + *# The highest bit MUST be 1; the remaining bits contain the length + *# of the following data in bytes. */ - - /* Because we already read 3 bytes of the record payload while trying to - * read a standard header, we need to adjust the length so that we only - * try to read the remainder of the record payload. + POSIX_ENSURE(*fragment_length & S2N_TLS_SSLV2_HEADER_FLAG_UINT16, S2N_ERR_BAD_MESSAGE); + *fragment_length ^= S2N_TLS_SSLV2_HEADER_FLAG_UINT16; + + /* We read 5 bytes into header_in because we expected a standard, non-SSLv2 record header + * instead of an SSLv2 message. We have therefore already read 3 bytes of the payload. + * We need to adjust "fragment_length" to account for the bytes we have already + * read so that we will only attempt to read the remainder of the payload on + * our next call to conn->recv. */ - POSIX_ENSURE_GTE(*fragment_length, 3); - *fragment_length -= 3; + POSIX_ENSURE(*fragment_length >= s2n_stuffer_data_available(header_in), S2N_ERR_BAD_MESSAGE); + *fragment_length -= s2n_stuffer_data_available(header_in); - /* - * The first field of an SSLv2 ClientHello is the msg_type. + /* By reading 5 bytes for a standard header we have also read the first + * 3 bytes of the SSLv2 ClientHello message. + * So we now need to parse those three bytes. * + * The first field of an SSLv2 ClientHello is the msg_type. * This is always '1', matching the ClientHello msg_type used by later * handshake messages. */ - POSIX_GUARD(s2n_stuffer_read_uint8(in, record_type)); + POSIX_GUARD(s2n_stuffer_read_uint8(header_in, record_type)); /* * The second field of an SSLv2 ClientHello is the version. @@ -73,10 +88,10 @@ int s2n_sslv2_record_header_parse( * See s2n_sslv2_client_hello_recv. */ uint8_t protocol_version[S2N_TLS_PROTOCOL_VERSION_LEN] = { 0 }; - POSIX_GUARD(s2n_stuffer_read_bytes(in, protocol_version, S2N_TLS_PROTOCOL_VERSION_LEN)); - + POSIX_GUARD(s2n_stuffer_read_bytes(header_in, protocol_version, S2N_TLS_PROTOCOL_VERSION_LEN)); *client_protocol_version = (protocol_version[0] * 10) + protocol_version[1]; + POSIX_GUARD(s2n_stuffer_reread(header_in)); return 0; } @@ -95,6 +110,12 @@ int s2n_record_header_parse( POSIX_GUARD(s2n_stuffer_read_bytes(in, protocol_version, S2N_TLS_PROTOCOL_VERSION_LEN)); const uint8_t version = (protocol_version[0] * 10) + protocol_version[1]; + /* We record the protocol version in the first record seen by the server for fingerprinting usecases */ + if (!conn->client_hello.record_version_recorded) { + conn->client_hello.legacy_record_version = version; + conn->client_hello.record_version_recorded = 1; + } + /* https://tools.ietf.org/html/rfc5246#appendix-E.1 states that servers must accept any value {03,XX} as the record * layer version number for the first TLS record. There is some ambiguity here because the client does not know * what version to use in the record header prior to receiving the ServerHello. Some client implementations may use @@ -144,8 +165,8 @@ static bool s2n_is_tls13_plaintext_content(struct s2n_connection *conn, uint8_t int s2n_record_parse(struct s2n_connection *conn) { - uint8_t content_type; - uint16_t encrypted_length; + uint8_t content_type = 0; + uint16_t encrypted_length = 0; POSIX_GUARD(s2n_record_header_parse(conn, &content_type, &encrypted_length)); struct s2n_crypto_parameters *current_client_crypto = conn->client; @@ -246,3 +267,12 @@ int s2n_tls13_parse_record_type(struct s2n_stuffer *stuffer, uint8_t *record_typ return 0; } + +S2N_RESULT s2n_record_wipe(struct s2n_connection *conn) +{ + RESULT_ENSURE_REF(conn); + RESULT_GUARD_POSIX(s2n_stuffer_wipe(&conn->header_in)); + RESULT_GUARD_POSIX(s2n_stuffer_wipe(&conn->in)); + conn->in_status = ENCRYPTED; + return S2N_RESULT_OK; +} diff --git a/tls/s2n_record_read_cbc.c b/tls/s2n_record_read_cbc.c index 77dd499a57e..08fd52e3277 100644 --- a/tls/s2n_record_read_cbc.c +++ b/tls/s2n_record_read_cbc.c @@ -56,7 +56,7 @@ int s2n_record_parse_cbc( POSIX_ENSURE_REF(en.data); uint16_t payload_length = encrypted_length; - uint8_t mac_digest_size; + uint8_t mac_digest_size = 0; POSIX_GUARD(s2n_hmac_digest_size(mac->alg, &mac_digest_size)); POSIX_ENSURE_GTE(payload_length, mac_digest_size); diff --git a/tls/s2n_record_read_composite.c b/tls/s2n_record_read_composite.c index ef4ef5ba648..679053af146 100644 --- a/tls/s2n_record_read_composite.c +++ b/tls/s2n_record_read_composite.c @@ -47,7 +47,7 @@ int s2n_record_parse_composite( POSIX_ENSURE_REF(en.data); uint16_t payload_length = encrypted_length; - uint8_t mac_digest_size; + uint8_t mac_digest_size = 0; POSIX_GUARD(s2n_hmac_digest_size(mac->alg, &mac_digest_size)); POSIX_ENSURE_GTE(payload_length, mac_digest_size); diff --git a/tls/s2n_record_read_stream.c b/tls/s2n_record_read_stream.c index bef04a830bf..f40621b2fe1 100644 --- a/tls/s2n_record_read_stream.c +++ b/tls/s2n_record_read_stream.c @@ -43,7 +43,7 @@ int s2n_record_parse_stream( POSIX_ENSURE_REF(en.data); uint16_t payload_length = encrypted_length; - uint8_t mac_digest_size; + uint8_t mac_digest_size = 0; POSIX_GUARD(s2n_hmac_digest_size(mac->alg, &mac_digest_size)); POSIX_ENSURE_GTE(payload_length, mac_digest_size); diff --git a/tls/s2n_record_write.c b/tls/s2n_record_write.c index dd115a3ca2b..f0455c8842d 100644 --- a/tls/s2n_record_write.c +++ b/tls/s2n_record_write.c @@ -43,7 +43,7 @@ static S2N_RESULT s2n_tls_record_overhead(struct s2n_connection *conn, uint16_t active = conn->client; } - uint8_t extra; + uint8_t extra = 0; RESULT_GUARD_POSIX(s2n_hmac_digest_size(active->cipher_suite->record_alg->hmac_alg, &extra)); if (active->cipher_suite->record_alg->cipher->type == S2N_CBC) { @@ -294,7 +294,7 @@ int s2n_record_writev(struct s2n_connection *conn, uint8_t content_type, const s POSIX_ENSURE(s2n_stuffer_data_available(&conn->out) == 0, S2N_ERR_RECORD_STUFFER_NEEDS_DRAINING); } - uint8_t mac_digest_size; + uint8_t mac_digest_size = 0; POSIX_GUARD(s2n_hmac_digest_size(mac->alg, &mac_digest_size)); /* Before we do anything, we need to figure out what the length of the @@ -379,7 +379,7 @@ int s2n_record_writev(struct s2n_connection *conn, uint8_t content_type, const s } /* Outputs number of extra bytes required for MAC and padding */ - int pad_and_mac_len; + int pad_and_mac_len = 0; POSIX_GUARD(cipher_suite->record_alg->cipher->io.comp.initial_hmac(session_key, sequence_number, content_type, conn->actual_protocol_version, payload_and_eiv_len, &pad_and_mac_len)); extra += pad_and_mac_len; @@ -401,7 +401,7 @@ int s2n_record_writev(struct s2n_connection *conn, uint8_t content_type, const s /* If we're AEAD, write the sequence number as an IV, and generate the AAD */ if (cipher_suite->record_alg->cipher->type == S2N_AEAD) { struct s2n_stuffer iv_stuffer = { 0 }; - s2n_blob_init(&iv, aad_iv, sizeof(aad_iv)); + POSIX_GUARD(s2n_blob_init(&iv, aad_iv, sizeof(aad_iv))); POSIX_GUARD(s2n_stuffer_init(&iv_stuffer, &iv)); if (cipher_suite->record_alg->flags & S2N_TLS12_AES_GCM_AEAD_NONCE) { @@ -429,7 +429,7 @@ int s2n_record_writev(struct s2n_connection *conn, uint8_t content_type, const s POSIX_GUARD_RESULT(s2n_aead_aad_init(conn, sequence_number, content_type, data_bytes_to_take, &aad)); } } else if (cipher_suite->record_alg->cipher->type == S2N_CBC || cipher_suite->record_alg->cipher->type == S2N_COMPOSITE) { - s2n_blob_init(&iv, implicit_iv, block_size); + POSIX_GUARD(s2n_blob_init(&iv, implicit_iv, block_size)); /* For TLS1.1/1.2; write the IV with random data */ if (conn->actual_protocol_version > S2N_TLS10) { diff --git a/tls/s2n_recv.c b/tls/s2n_recv.c index 691c2e2daa6..323c4b5edef 100644 --- a/tls/s2n_recv.c +++ b/tls/s2n_recv.c @@ -70,15 +70,14 @@ int s2n_read_full_record(struct s2n_connection *conn, uint8_t *record_type, int POSIX_GUARD(s2n_stuffer_resize_if_empty(&conn->in, S2N_LARGE_FRAGMENT_LENGTH)); /* Read the record until we at least have a header */ + POSIX_GUARD(s2n_stuffer_reread(&conn->header_in)); POSIX_GUARD_RESULT(s2n_read_in_bytes(conn, &conn->header_in, S2N_TLS_RECORD_HEADER_LENGTH)); - uint16_t fragment_length; + uint16_t fragment_length = 0; /* If the first bit is set then this is an SSLv2 record */ - if (conn->header_in.blob.data[0] & 0x80) { - conn->header_in.blob.data[0] &= 0x7f; + if (conn->header_in.blob.data[0] & S2N_TLS_SSLV2_HEADER_FLAG) { *isSSLv2 = 1; - WITH_ERROR_BLINDING(conn, POSIX_GUARD(s2n_sslv2_record_header_parse(conn, record_type, &conn->client_protocol_version, &fragment_length))); } else { WITH_ERROR_BLINDING(conn, POSIX_GUARD(s2n_record_header_parse(conn, record_type, &fragment_length))); @@ -151,7 +150,7 @@ ssize_t s2n_recv_impl(struct s2n_connection *conn, void *buf, ssize_t size_signe while (size && s2n_connection_check_io_status(conn, S2N_IO_READABLE)) { int isSSLv2 = 0; - uint8_t record_type; + uint8_t record_type = 0; int r = s2n_read_full_record(conn, &record_type, &isSSLv2); if (r < 0) { /* Don't propagate the error if we already read some bytes. */ @@ -203,9 +202,7 @@ ssize_t s2n_recv_impl(struct s2n_connection *conn, void *buf, ssize_t size_signe break; } } - POSIX_GUARD(s2n_stuffer_wipe(&conn->header_in)); - POSIX_GUARD(s2n_stuffer_wipe(&conn->in)); - conn->in_status = ENCRYPTED; + POSIX_GUARD_RESULT(s2n_record_wipe(conn)); continue; } @@ -219,9 +216,7 @@ ssize_t s2n_recv_impl(struct s2n_connection *conn, void *buf, ssize_t size_signe /* Are we ready for more encrypted data? */ if (s2n_stuffer_data_available(&conn->in) == 0) { - POSIX_GUARD(s2n_stuffer_wipe(&conn->header_in)); - POSIX_GUARD(s2n_stuffer_wipe(&conn->in)); - conn->in_status = ENCRYPTED; + POSIX_GUARD_RESULT(s2n_record_wipe(conn)); } /* If we've read some data, return it in legacy mode */ diff --git a/tls/s2n_resume.c b/tls/s2n_resume.c index d5f10b7ad07..f2a7a5de359 100644 --- a/tls/s2n_resume.c +++ b/tls/s2n_resume.c @@ -66,7 +66,7 @@ static int s2n_tls12_serialize_resumption_state(struct s2n_connection *conn, str POSIX_ENSURE_REF(conn); POSIX_ENSURE_REF(conn->secure); - uint64_t now; + uint64_t now = 0; S2N_ERROR_IF(s2n_stuffer_space_remaining(to) < S2N_TLS12_STATE_SIZE_IN_BYTES, S2N_ERR_STUFFER_IS_FULL); @@ -167,10 +167,10 @@ static int s2n_tls12_deserialize_resumption_state(struct s2n_connection *conn, s POSIX_GUARD(s2n_stuffer_read_bytes(from, cipher_suite, S2N_TLS_CIPHER_SUITE_LEN)); S2N_ERROR_IF(memcmp(conn->secure->cipher_suite->iana_value, cipher_suite, S2N_TLS_CIPHER_SUITE_LEN), S2N_ERR_INVALID_SERIALIZED_SESSION_STATE); - uint64_t now; + uint64_t now = 0; POSIX_GUARD_RESULT(s2n_config_wall_clock(conn->config, &now)); - uint64_t then; + uint64_t then = 0; POSIX_GUARD(s2n_stuffer_read_uint64(from, &then)); S2N_ERROR_IF(then > now, S2N_ERR_INVALID_SERIALIZED_SESSION_STATE); S2N_ERROR_IF(now - then > conn->config->session_state_lifetime_in_nanos, S2N_ERR_INVALID_SERIALIZED_SESSION_STATE); @@ -389,7 +389,7 @@ S2N_RESULT s2n_deserialize_resumption_state(struct s2n_connection *conn, static int s2n_client_deserialize_with_session_id(struct s2n_connection *conn, struct s2n_stuffer *from) { - uint8_t session_id_len; + uint8_t session_id_len = 0; POSIX_GUARD(s2n_stuffer_read_uint8(from, &session_id_len)); if (session_id_len == 0 || session_id_len > S2N_TLS_SESSION_ID_MAX_LEN @@ -425,7 +425,7 @@ static int s2n_client_deserialize_with_session_ticket(struct s2n_connection *con static int s2n_client_deserialize_resumption_state(struct s2n_connection *conn, struct s2n_stuffer *from) { - uint8_t format; + uint8_t format = 0; POSIX_GUARD(s2n_stuffer_read_uint8(from, &format)); switch (format) { @@ -612,7 +612,7 @@ int s2n_connection_is_ocsp_stapled(struct s2n_connection *conn) int s2n_config_is_encrypt_decrypt_key_available(struct s2n_config *config) { - uint64_t now; + uint64_t now = 0; struct s2n_ticket_key *ticket_key = NULL; POSIX_GUARD_RESULT(s2n_config_wall_clock(config, &now)); POSIX_ENSURE_REF(config->ticket_keys); @@ -696,7 +696,7 @@ struct s2n_ticket_key *s2n_get_ticket_encrypt_decrypt_key(struct s2n_config *con uint8_t encrypt_decrypt_keys_index[S2N_MAX_TICKET_KEYS] = { 0 }; struct s2n_ticket_key *ticket_key = NULL; - uint64_t now; + uint64_t now = 0; PTR_GUARD_RESULT(s2n_config_wall_clock(config, &now)); PTR_ENSURE_REF(config->ticket_keys); @@ -724,7 +724,7 @@ struct s2n_ticket_key *s2n_get_ticket_encrypt_decrypt_key(struct s2n_config *con return ticket_key; } - int8_t idx; + int8_t idx = 0; PTR_GUARD_POSIX(idx = s2n_compute_weight_of_encrypt_decrypt_keys(config, encrypt_decrypt_keys_index, num_encrypt_decrypt_keys, now)); PTR_GUARD_RESULT(s2n_set_get(config->ticket_keys, idx, (void **) &ticket_key)); @@ -736,7 +736,7 @@ struct s2n_ticket_key *s2n_get_ticket_encrypt_decrypt_key(struct s2n_config *con */ struct s2n_ticket_key *s2n_find_ticket_key(struct s2n_config *config, const uint8_t name[S2N_TICKET_KEY_NAME_LEN]) { - uint64_t now; + uint64_t now = 0; struct s2n_ticket_key *ticket_key = NULL; PTR_GUARD_RESULT(s2n_config_wall_clock(config, &now)); PTR_ENSURE_REF(config->ticket_keys); @@ -766,7 +766,7 @@ struct s2n_ticket_key *s2n_find_ticket_key(struct s2n_config *config, const uint int s2n_encrypt_session_ticket(struct s2n_connection *conn, struct s2n_stuffer *to) { - struct s2n_ticket_key *key; + struct s2n_ticket_key *key = NULL; struct s2n_session_key aes_ticket_key = { 0 }; struct s2n_blob aes_key_blob = { 0 }; @@ -820,7 +820,7 @@ int s2n_encrypt_session_ticket(struct s2n_connection *conn, struct s2n_stuffer * int s2n_decrypt_session_ticket(struct s2n_connection *conn, struct s2n_stuffer *from) { - struct s2n_ticket_key *key; + struct s2n_ticket_key *key = NULL; DEFER_CLEANUP(struct s2n_session_key aes_ticket_key = { 0 }, s2n_session_key_free); struct s2n_blob aes_key_blob = { 0 }; @@ -844,7 +844,7 @@ int s2n_decrypt_session_ticket(struct s2n_connection *conn, struct s2n_stuffer * POSIX_GUARD(s2n_stuffer_read(from, &iv)); - s2n_blob_init(&aes_key_blob, key->aes_key, S2N_AES256_KEY_LEN); + POSIX_GUARD(s2n_blob_init(&aes_key_blob, key->aes_key, S2N_AES256_KEY_LEN)); POSIX_GUARD(s2n_session_key_alloc(&aes_ticket_key)); POSIX_GUARD(s2n_aes256_gcm.init(&aes_ticket_key)); POSIX_GUARD(s2n_aes256_gcm.set_decryption_key(&aes_ticket_key, &aes_key_blob)); @@ -868,7 +868,7 @@ int s2n_decrypt_session_ticket(struct s2n_connection *conn, struct s2n_stuffer * POSIX_GUARD(s2n_stuffer_skip_write(&state_stuffer, state_blob_size)); POSIX_GUARD_RESULT(s2n_deserialize_resumption_state(conn, &from->blob, &state_stuffer)); - uint64_t now; + uint64_t now = 0; POSIX_GUARD_RESULT(s2n_config_wall_clock(conn->config, &now)); /* If the key is in decrypt-only state, then a new key is assigned @@ -892,7 +892,7 @@ int s2n_encrypt_session_cache(struct s2n_connection *conn, struct s2n_stuffer *t int s2n_decrypt_session_cache(struct s2n_connection *conn, struct s2n_stuffer *from) { - struct s2n_ticket_key *key; + struct s2n_ticket_key *key = NULL; struct s2n_session_key aes_ticket_key = { 0 }; struct s2n_blob aes_key_blob = { 0 }; @@ -925,7 +925,7 @@ int s2n_decrypt_session_cache(struct s2n_connection *conn, struct s2n_stuffer *f POSIX_GUARD(s2n_stuffer_read(from, &iv)); - s2n_blob_init(&aes_key_blob, key->aes_key, S2N_AES256_KEY_LEN); + POSIX_GUARD(s2n_blob_init(&aes_key_blob, key->aes_key, S2N_AES256_KEY_LEN)); POSIX_GUARD(s2n_session_key_alloc(&aes_ticket_key)); POSIX_GUARD(s2n_aes256_gcm.init(&aes_ticket_key)); POSIX_GUARD(s2n_aes256_gcm.set_decryption_key(&aes_ticket_key, &aes_key_blob)); @@ -962,7 +962,7 @@ int s2n_config_wipe_expired_ticket_crypto_keys(struct s2n_config *config, int8_t goto end; } - uint64_t now; + uint64_t now = 0; POSIX_GUARD_RESULT(s2n_config_wall_clock(config, &now)); POSIX_ENSURE_REF(config->ticket_keys); diff --git a/tls/s2n_security_policies.c b/tls/s2n_security_policies.c index 0ac9e960da9..4bdec0f1414 100644 --- a/tls/s2n_security_policies.c +++ b/tls/s2n_security_policies.c @@ -16,6 +16,7 @@ #include "tls/s2n_security_policies.h" #include "api/s2n.h" +#include "tls/s2n_certificate_keys.h" #include "tls/s2n_connection.h" #include "utils/s2n_safety.h" @@ -1213,6 +1214,7 @@ int s2n_config_set_cipher_preferences(struct s2n_config *config, const char *ver int s2n_connection_set_cipher_preferences(struct s2n_connection *conn, const char *version) { + POSIX_ENSURE_REF(conn); const struct s2n_security_policy *security_policy = NULL; POSIX_GUARD(s2n_find_security_policy_from_version(version, &security_policy)); POSIX_ENSURE_REF(security_policy); @@ -1224,6 +1226,10 @@ int s2n_connection_set_cipher_preferences(struct s2n_connection *conn, const cha /* If the security policy's minimum version is higher than what libcrypto supports, return an error. */ POSIX_ENSURE((security_policy->minimum_protocol_version <= s2n_get_highest_fully_supported_tls_version()), S2N_ERR_PROTOCOL_VERSION_UNSUPPORTED); + /* If the certificates loaded in the config are incompatible with the security + * policy's certificate preferences, return an error. */ + POSIX_GUARD_RESULT(s2n_config_validate_loaded_certificates(conn->config, security_policy)); + conn->security_policy_override = security_policy; return 0; } @@ -1459,3 +1465,64 @@ S2N_RESULT s2n_security_policy_get_version(const struct s2n_security_policy *sec } RESULT_BAIL(S2N_ERR_INVALID_SECURITY_POLICY); } + +S2N_RESULT s2n_security_policy_validate_cert_signature(const struct s2n_security_policy *security_policy, + const struct s2n_cert_info *info, s2n_error error) +{ + RESULT_ENSURE_REF(info); + RESULT_ENSURE_REF(security_policy); + const struct s2n_signature_preferences *sig_preferences = security_policy->certificate_signature_preferences; + + if (sig_preferences != NULL) { + for (size_t i = 0; i < sig_preferences->count; i++) { + if (sig_preferences->signature_schemes[i]->libcrypto_nid == info->signature_nid) { + return S2N_RESULT_OK; + } + } + + RESULT_BAIL(error); + } + return S2N_RESULT_OK; +} + +S2N_RESULT s2n_security_policy_validate_cert_key(const struct s2n_security_policy *security_policy, + const struct s2n_cert_info *info, s2n_error error) +{ + RESULT_ENSURE_REF(info); + RESULT_ENSURE_REF(security_policy); + const struct s2n_certificate_key_preferences *key_preferences = security_policy->certificate_key_preferences; + + if (key_preferences != NULL) { + for (size_t i = 0; i < key_preferences->count; i++) { + if (key_preferences->certificate_keys[i]->public_key_libcrypto_nid == info->public_key_nid + && key_preferences->certificate_keys[i]->bits == info->public_key_bits) { + return S2N_RESULT_OK; + } + } + RESULT_BAIL(error); + } + return S2N_RESULT_OK; +} + +S2N_RESULT s2n_security_policy_validate_certificate_chain( + const struct s2n_security_policy *security_policy, + const struct s2n_cert_chain_and_key *cert_key_pair) +{ + RESULT_ENSURE_REF(security_policy); + RESULT_ENSURE_REF(cert_key_pair); + RESULT_ENSURE_REF(cert_key_pair->cert_chain); + + if (!security_policy->certificate_preferences_apply_locally) { + return S2N_RESULT_OK; + } + + struct s2n_cert *current = cert_key_pair->cert_chain->head; + while (current != NULL) { + RESULT_GUARD(s2n_security_policy_validate_cert_key(security_policy, ¤t->info, + S2N_ERR_SECURITY_POLICY_INCOMPATIBLE_CERT)); + RESULT_GUARD(s2n_security_policy_validate_cert_signature(security_policy, ¤t->info, + S2N_ERR_SECURITY_POLICY_INCOMPATIBLE_CERT)); + current = current->next; + } + return S2N_RESULT_OK; +} diff --git a/tls/s2n_security_policies.h b/tls/s2n_security_policies.h index af9211e009a..90bfda1296b 100644 --- a/tls/s2n_security_policies.h +++ b/tls/s2n_security_policies.h @@ -70,6 +70,16 @@ struct s2n_security_policy { * https://www.rfc-editor.org/rfc/rfc8446#section-4.2.7 */ const struct s2n_ecc_preferences *ecc_preferences; + /* This field determines what public keys are allowed for use. It restricts + * both the type of the key (Elliptic Curve, RSA w/ Encryption, RSA PSS) and + * the size of the key. Note that this field structure is likely to change + * until https://github.com/aws/s2n-tls/issues/4435 is closed. + */ + const struct s2n_certificate_key_preferences *certificate_key_preferences; + /* This field controls whether the certificate_signature_preferences apply + * to local certs loaded on configs. + */ + bool certificate_preferences_apply_locally; bool rules[S2N_SECURITY_RULES_COUNT]; }; @@ -105,6 +115,7 @@ extern const struct s2n_security_policy security_policy_20190802; extern const struct s2n_security_policy security_policy_20230317; extern const struct s2n_security_policy security_policy_default_tls13; extern const struct s2n_security_policy security_policy_default_fips; +extern const struct s2n_security_policy security_policy_rfc9151; extern const struct s2n_security_policy security_policy_test_all; extern const struct s2n_security_policy security_policy_test_all_tls12; @@ -190,4 +201,14 @@ bool s2n_security_policy_supports_tls13(const struct s2n_security_policy *securi int s2n_find_security_policy_from_version(const char *version, const struct s2n_security_policy **security_policy); int s2n_validate_kem_preferences(const struct s2n_kem_preferences *kem_preferences, bool pq_kem_extension_required); S2N_RESULT s2n_validate_certificate_signature_preferences(const struct s2n_signature_preferences *s2n_certificate_signature_preferences); -S2N_RESULT s2n_security_policy_get_version(const struct s2n_security_policy *security_policy, const char **version); +S2N_RESULT s2n_security_policy_get_version(const struct s2n_security_policy *security_policy, + const char **version); +/* Checks to see if a certificate has a signature algorithm that's in our + * certificate_signature_preferences list + */ +S2N_RESULT s2n_security_policy_validate_certificate_chain(const struct s2n_security_policy *security_policy, + const struct s2n_cert_chain_and_key *cert_key_pair); +S2N_RESULT s2n_security_policy_validate_cert_signature( + const struct s2n_security_policy *security_policy, const struct s2n_cert_info *info, s2n_error error); +S2N_RESULT s2n_security_policy_validate_cert_key( + const struct s2n_security_policy *security_policy, const struct s2n_cert_info *info, s2n_error error); diff --git a/tls/s2n_security_rules.c b/tls/s2n_security_rules.c index ebeefe99430..2d1513d3909 100644 --- a/tls/s2n_security_rules.c +++ b/tls/s2n_security_rules.c @@ -219,7 +219,7 @@ S2N_CLEANUP_RESULT s2n_security_rule_result_free(struct s2n_security_rule_result { if (result) { RESULT_GUARD_POSIX(s2n_stuffer_free(&result->output)); + *result = (struct s2n_security_rule_result){ 0 }; } - *result = (struct s2n_security_rule_result){ 0 }; return S2N_RESULT_OK; } diff --git a/tls/s2n_send.c b/tls/s2n_send.c index 7b8e4209660..98ce35b96d8 100644 --- a/tls/s2n_send.c +++ b/tls/s2n_send.c @@ -138,7 +138,7 @@ S2N_RESULT s2n_sendv_with_offset_total_size(const struct iovec *bufs, ssize_t co ssize_t s2n_sendv_with_offset_impl(struct s2n_connection *conn, const struct iovec *bufs, ssize_t count, ssize_t offs, s2n_blocked_status *blocked) { - ssize_t user_data_sent, total_size = 0; + ssize_t user_data_sent = 0, total_size = 0; POSIX_ENSURE(s2n_connection_check_io_status(conn, S2N_IO_WRITABLE), S2N_ERR_CLOSED); POSIX_ENSURE(!s2n_connection_is_quic_enabled(conn), S2N_ERR_UNSUPPORTED_WITH_QUIC); @@ -175,7 +175,7 @@ ssize_t s2n_sendv_with_offset_impl(struct s2n_connection *conn, const struct iov POSIX_GUARD_RESULT(s2n_early_data_validate_send(conn, total_size)); if (conn->dynamic_record_timeout_threshold > 0) { - uint64_t elapsed; + uint64_t elapsed = 0; POSIX_GUARD_RESULT(s2n_timer_elapsed(conn->config, &conn->write_timer, &elapsed)); /* Reset record size back to a single segment after threshold seconds of inactivity */ if (elapsed - conn->last_write_elapsed > (uint64_t) conn->dynamic_record_timeout_threshold * 1000000000) { diff --git a/tls/s2n_server_cert.c b/tls/s2n_server_cert.c index ac3415a2c2c..5c1882ceb29 100644 --- a/tls/s2n_server_cert.c +++ b/tls/s2n_server_cert.c @@ -23,12 +23,12 @@ int s2n_server_cert_recv(struct s2n_connection *conn) { if (conn->actual_protocol_version == S2N_TLS13) { - uint8_t certificate_request_context_len; + uint8_t certificate_request_context_len = 0; POSIX_GUARD(s2n_stuffer_read_uint8(&conn->handshake.io, &certificate_request_context_len)); S2N_ERROR_IF(certificate_request_context_len != 0, S2N_ERR_BAD_MESSAGE); } - uint32_t size_of_all_certificates; + uint32_t size_of_all_certificates = 0; POSIX_GUARD(s2n_stuffer_read_uint24(&conn->handshake.io, &size_of_all_certificates)); S2N_ERROR_IF(size_of_all_certificates > s2n_stuffer_data_available(&conn->handshake.io) || size_of_all_certificates < 3, diff --git a/tls/s2n_server_cert_request.c b/tls/s2n_server_cert_request.c index 6635306fd74..79929a32cda 100644 --- a/tls/s2n_server_cert_request.c +++ b/tls/s2n_server_cert_request.c @@ -62,7 +62,7 @@ static uint8_t s2n_cert_type_preference_list_legacy_dss[] = { static int s2n_recv_client_cert_preferences(struct s2n_stuffer *in, s2n_cert_type *chosen_cert_type_out) { - uint8_t cert_types_len; + uint8_t cert_types_len = 0; POSIX_GUARD(s2n_stuffer_read_uint8(in, &cert_types_len)); uint8_t *their_cert_type_pref_list = s2n_stuffer_raw_read(in, cert_types_len); @@ -100,7 +100,7 @@ int s2n_tls13_cert_req_recv(struct s2n_connection *conn) struct s2n_stuffer *in = &conn->handshake.io; /* read request context length */ - uint8_t request_context_length; + uint8_t request_context_length = 0; POSIX_GUARD(s2n_stuffer_read_uint8(in, &request_context_length)); /* RFC 8446: This field SHALL be zero length unless used for the post-handshake authentication */ S2N_ERROR_IF(request_context_length != 0, S2N_ERR_BAD_MESSAGE); diff --git a/tls/s2n_server_finished.c b/tls/s2n_server_finished.c index 671abab9380..ee7e7524512 100644 --- a/tls/s2n_server_finished.c +++ b/tls/s2n_server_finished.c @@ -86,7 +86,7 @@ int s2n_tls13_server_finished_recv(struct s2n_connection *conn) /* read finished mac from handshake */ struct s2n_blob wire_finished_mac = { 0 }; - s2n_blob_init(&wire_finished_mac, s2n_stuffer_raw_read(&conn->handshake.io, length), length); + POSIX_GUARD(s2n_blob_init(&wire_finished_mac, s2n_stuffer_raw_read(&conn->handshake.io, length), length)); /* get tls13 keys */ s2n_tls13_connection_keys(keys, conn); diff --git a/tls/s2n_server_hello.c b/tls/s2n_server_hello.c index edee59eac15..7c889bba63d 100644 --- a/tls/s2n_server_hello.c +++ b/tls/s2n_server_hello.c @@ -99,8 +99,8 @@ static int s2n_server_hello_parse(struct s2n_connection *conn) POSIX_ENSURE_REF(conn->secure); struct s2n_stuffer *in = &conn->handshake.io; - uint8_t compression_method; - uint8_t session_id_len; + uint8_t compression_method = 0; + uint8_t session_id_len = 0; uint8_t protocol_version[S2N_TLS_PROTOCOL_VERSION_LEN]; uint8_t session_id[S2N_TLS_SESSION_ID_MAX_LEN]; @@ -212,7 +212,7 @@ static int s2n_server_hello_parse(struct s2n_connection *conn) */ POSIX_ENSURE(conn->early_data_state != S2N_EARLY_DATA_REQUESTED, S2N_ERR_PROTOCOL_VERSION_UNSUPPORTED); - const struct s2n_security_policy *security_policy; + const struct s2n_security_policy *security_policy = NULL; POSIX_GUARD(s2n_connection_get_security_policy(conn, &security_policy)); if (conn->server_protocol_version < security_policy->minimum_protocol_version diff --git a/tls/s2n_server_key_exchange.c b/tls/s2n_server_key_exchange.c index 0251920431d..0e710950270 100644 --- a/tls/s2n_server_key_exchange.c +++ b/tls/s2n_server_key_exchange.c @@ -65,7 +65,7 @@ int s2n_server_key_recv(struct s2n_connection *conn) POSIX_GUARD(s2n_hash_update(signature_hash, data_to_verify.data, data_to_verify.size)); /* Verify the signature */ - uint16_t signature_length; + uint16_t signature_length = 0; POSIX_GUARD(s2n_stuffer_read_uint16(in, &signature_length)); struct s2n_blob signature = { 0 }; @@ -107,9 +107,9 @@ int s2n_dhe_server_key_recv_read_data(struct s2n_connection *conn, struct s2n_bl struct s2n_stuffer *in = &conn->handshake.io; struct s2n_dhe_raw_server_points *dhe_data = &raw_server_data->dhe_data; - uint16_t p_length; - uint16_t g_length; - uint16_t Ys_length; + uint16_t p_length = 0; + uint16_t g_length = 0; + uint16_t Ys_length = 0; /* Keep a copy to the start of the whole structure for the signature check */ data_to_verify->data = s2n_stuffer_raw_read(in, 0); @@ -162,7 +162,7 @@ int s2n_kem_server_key_recv_read_data(struct s2n_connection *conn, struct s2n_bl struct s2n_stuffer kem_id_stuffer = { 0 }; uint8_t kem_id_arr[2]; - kem_extension_size kem_id; + kem_extension_size kem_id = 0; struct s2n_blob kem_id_blob = { 0 }; POSIX_GUARD(s2n_blob_init(&kem_id_blob, kem_id_arr, s2n_array_len(kem_id_arr))); POSIX_GUARD(s2n_stuffer_init(&kem_id_stuffer, &kem_id_blob)); diff --git a/tls/s2n_server_new_session_ticket.c b/tls/s2n_server_new_session_ticket.c index 043ba425b53..db40ea5a8b4 100644 --- a/tls/s2n_server_new_session_ticket.c +++ b/tls/s2n_server_new_session_ticket.c @@ -43,7 +43,7 @@ int s2n_server_nst_recv(struct s2n_connection *conn) { POSIX_GUARD(s2n_stuffer_read_uint32(&conn->handshake.io, &conn->ticket_lifetime_hint)); - uint16_t session_ticket_len; + uint16_t session_ticket_len = 0; POSIX_GUARD(s2n_stuffer_read_uint16(&conn->handshake.io, &session_ticket_len)); if (session_ticket_len > 0) { diff --git a/tls/s2n_shutdown.c b/tls/s2n_shutdown.c index 3ad818d6c00..f390b98290f 100644 --- a/tls/s2n_shutdown.c +++ b/tls/s2n_shutdown.c @@ -49,6 +49,13 @@ static bool s2n_shutdown_expect_close_notify(struct s2n_connection *conn) return false; } + /* Blinded errors indicate a fatal error handling inputs. + * We should not attempt to handle further inputs. + */ + if (conn->delay) { + return false; + } + return true; } @@ -121,18 +128,12 @@ int s2n_shutdown(struct s2n_connection *conn, s2n_blocked_status *blocked) int isSSLv2 = false; *blocked = S2N_BLOCKED_ON_READ; while (!s2n_atomic_flag_test(&conn->close_notify_received)) { - /* Reset IO. Make sure we do this before attempting to read a record in - * case a previous failed read left IO in a bad state. - */ - POSIX_GUARD(s2n_stuffer_wipe(&conn->header_in)); - POSIX_GUARD(s2n_stuffer_wipe(&conn->in)); - conn->in_status = ENCRYPTED; - POSIX_GUARD(s2n_read_full_record(conn, &record_type, &isSSLv2)); POSIX_ENSURE(!isSSLv2, S2N_ERR_BAD_MESSAGE); if (record_type == TLS_ALERT) { POSIX_GUARD(s2n_process_alert_fragment(conn)); } + POSIX_GUARD_RESULT(s2n_record_wipe(conn)); } *blocked = S2N_NOT_BLOCKED; diff --git a/tls/s2n_signature_algorithms.c b/tls/s2n_signature_algorithms.c index 9be581fbb35..f805512a510 100644 --- a/tls/s2n_signature_algorithms.c +++ b/tls/s2n_signature_algorithms.c @@ -348,7 +348,7 @@ S2N_RESULT s2n_signature_algorithms_supported_list_send(struct s2n_connection *c int s2n_recv_supported_sig_scheme_list(struct s2n_stuffer *in, struct s2n_sig_scheme_list *sig_hash_algs) { - uint16_t length_of_all_pairs; + uint16_t length_of_all_pairs = 0; POSIX_GUARD(s2n_stuffer_read_uint16(in, &length_of_all_pairs)); if (length_of_all_pairs > s2n_stuffer_data_available(in)) { /* Malformed length, ignore the extension */ diff --git a/tls/s2n_tls13_certificate_verify.c b/tls/s2n_tls13_certificate_verify.c index 8e1689d7318..427a14307f2 100644 --- a/tls/s2n_tls13_certificate_verify.c +++ b/tls/s2n_tls13_certificate_verify.c @@ -168,7 +168,7 @@ int s2n_tls13_cert_read_and_verify_signature(struct s2n_connection *conn, POSIX_GUARD(s2n_hash_new(&message_hash)); /* Get signature size */ - uint16_t signature_size; + uint16_t signature_size = 0; POSIX_GUARD(s2n_stuffer_read_uint16(in, &signature_size)); S2N_ERROR_IF(signature_size > s2n_stuffer_data_available(in), S2N_ERR_BAD_MESSAGE); diff --git a/tls/s2n_tls13_handshake.c b/tls/s2n_tls13_handshake.c index a4fb5d49c99..e22c4902426 100644 --- a/tls/s2n_tls13_handshake.c +++ b/tls/s2n_tls13_handshake.c @@ -159,7 +159,7 @@ int s2n_update_application_traffic_keys(struct s2n_connection *conn, s2n_mode mo /* get tls13 key context */ s2n_tls13_connection_keys(keys, conn); - struct s2n_session_key *old_key; + struct s2n_session_key *old_key = NULL; struct s2n_blob old_app_secret = { 0 }; struct s2n_blob app_iv = { 0 }; diff --git a/tls/s2n_x509_validator.c b/tls/s2n_x509_validator.c index 907cc445993..f7af91640dc 100644 --- a/tls/s2n_x509_validator.c +++ b/tls/s2n_x509_validator.c @@ -27,6 +27,7 @@ #include "tls/s2n_config.h" #include "tls/s2n_connection.h" #include "tls/s2n_crl.h" +#include "tls/s2n_security_policies.h" #include "utils/s2n_result.h" #include "utils/s2n_rfc5952.h" #include "utils/s2n_safety.h" @@ -399,6 +400,94 @@ S2N_RESULT s2n_x509_validator_read_asn1_cert(struct s2n_stuffer *cert_chain_in_s return S2N_RESULT_OK; } +/** +* Validates that each certificate in a peer's cert chain contains only signature algorithms in a security policy's +* certificate_signatures_preference list. +*/ +S2N_RESULT s2n_x509_validator_check_cert_preferences(struct s2n_connection *conn, X509 *cert) +{ + RESULT_ENSURE_REF(conn); + RESULT_ENSURE_REF(cert); + + const struct s2n_security_policy *security_policy = NULL; + RESULT_GUARD_POSIX(s2n_connection_get_security_policy(conn, &security_policy)); + + /** + * We only restrict the signature algorithm on the certificates in the + * peer's certificate chain if the certificate_signature_preferences field + * is set in the security policy. This is contrary to the RFC, which + * specifies that the signatures in the "signature_algorithms" extension + * apply to signatures in the certificate chain in certain scenarios, so RFC + * compliance would imply validating that the certificate chain signature + * algorithm matches one of the algorithms specified in the + * "signature_algorithms" extension. + * + *= https://www.rfc-editor.org/rfc/rfc5246#section-7.4.2 + *= type=exception + *= reason=not implemented due to lack of utility + *# If the client provided a "signature_algorithms" extension, then all + *# certificates provided by the server MUST be signed by a + *# hash/signature algorithm pair that appears in that extension. + * + *= https://www.rfc-editor.org/rfc/rfc8446#section-4.2.3 + *= type=exception + *= reason=not implemented due to lack of utility + *# If no "signature_algorithms_cert" extension is present, then the + *# "signature_algorithms" extension also applies to signatures appearing in + *# certificates. + */ + struct s2n_cert_info info = { 0 }; + RESULT_GUARD(s2n_openssl_x509_get_cert_info(cert, &info)); + + bool certificate_preferences_defined = security_policy->certificate_signature_preferences != NULL + || security_policy->certificate_key_preferences != NULL; + if (certificate_preferences_defined && !info.self_signed && conn->actual_protocol_version == S2N_TLS13) { + /* Ensure that the certificate signature does not use SHA-1. While this check + * would ideally apply to all connections, we only enforce it when certificate + * preferences exist to stay backwards compatible. + */ + RESULT_ENSURE(info.signature_digest_nid != NID_sha1, S2N_ERR_CERT_UNTRUSTED); + } + + if (!info.self_signed) { + RESULT_GUARD(s2n_security_policy_validate_cert_signature(security_policy, &info, S2N_ERR_CERT_UNTRUSTED)); + } + RESULT_GUARD(s2n_security_policy_validate_cert_key(security_policy, &info, S2N_ERR_CERT_UNTRUSTED)); + + return S2N_RESULT_OK; +} + +/* Validates that the root certificate uses a key allowed by the security policy + * certificate preferences. + */ +static S2N_RESULT s2n_x509_validator_check_root_cert(struct s2n_x509_validator *validator, struct s2n_connection *conn) +{ + RESULT_ENSURE_REF(validator); + RESULT_ENSURE_REF(conn); + + const struct s2n_security_policy *security_policy = NULL; + RESULT_GUARD_POSIX(s2n_connection_get_security_policy(conn, &security_policy)); + RESULT_ENSURE_REF(security_policy); + + RESULT_ENSURE_REF(validator->store_ctx); + DEFER_CLEANUP(STACK_OF(X509) *cert_chain = X509_STORE_CTX_get1_chain(validator->store_ctx), + s2n_openssl_x509_stack_pop_free); + RESULT_ENSURE_REF(cert_chain); + + const int certs_in_chain = sk_X509_num(cert_chain); + RESULT_ENSURE(certs_in_chain > 0, S2N_ERR_CERT_UNTRUSTED); + X509 *root = sk_X509_value(cert_chain, certs_in_chain - 1); + RESULT_ENSURE_REF(root); + + struct s2n_cert_info info = { 0 }; + RESULT_GUARD(s2n_openssl_x509_get_cert_info(root, &info)); + + RESULT_GUARD(s2n_security_policy_validate_cert_key(security_policy, &info, + S2N_ERR_SECURITY_POLICY_INCOMPATIBLE_CERT)); + + return S2N_RESULT_OK; +} + static S2N_RESULT s2n_x509_validator_read_cert_chain(struct s2n_x509_validator *validator, struct s2n_connection *conn, uint8_t *cert_chain_in, uint32_t cert_chain_len) { @@ -428,8 +517,7 @@ static S2N_RESULT s2n_x509_validator_read_cert_chain(struct s2n_x509_validator * } if (!validator->skip_cert_validation) { - RESULT_ENSURE_OK(s2n_validate_certificate_signature(conn, cert), - S2N_ERR_CERT_UNTRUSTED); + RESULT_GUARD(s2n_x509_validator_check_cert_preferences(conn, cert)); } /* add the cert to the chain */ @@ -685,6 +773,7 @@ S2N_RESULT s2n_x509_validator_validate_cert_chain(struct s2n_x509_validator *val if (validator->state == READY_TO_VERIFY) { RESULT_GUARD(s2n_x509_validator_verify_cert_chain(validator, conn)); + RESULT_GUARD(s2n_x509_validator_check_root_cert(validator, conn)); } if (conn->actual_protocol_version >= S2N_TLS13) { @@ -799,7 +888,7 @@ S2N_RESULT s2n_x509_validator_validate_cert_stapled_ocsp_response(struct s2n_x50 *# nextUpdate The time at or before which newer information will be *# available about the status of the certificate. **/ - ASN1_GENERALIZEDTIME *revtime, *thisupd, *nextupd; + ASN1_GENERALIZEDTIME *revtime = NULL, *thisupd = NULL, *nextupd = NULL; /* Actual verification of the response */ const int ocsp_resp_find_status_res = OCSP_resp_find_status(basic_response, cert_id, &status, &reason, &revtime, &thisupd, &nextupd); OCSP_CERTID_free(cert_id); @@ -864,88 +953,6 @@ S2N_RESULT s2n_x509_validator_validate_cert_stapled_ocsp_response(struct s2n_x50 #endif /* S2N_OCSP_STAPLING_SUPPORTED */ } -S2N_RESULT s2n_validate_certificate_signature(struct s2n_connection *conn, X509 *x509_cert) -{ - RESULT_ENSURE_REF(conn); - RESULT_ENSURE_REF(x509_cert); - - const struct s2n_security_policy *security_policy; - RESULT_GUARD_POSIX(s2n_connection_get_security_policy(conn, &security_policy)); - - /** - * We only restrict the signature algorithm on the certificates in the - * peer's certificate chain if the certificate_signature_preferences field - * is set in the security policy. This is contrary to the RFC, which - * specifies that the signatures in the "signature_algorithms" extension - * apply to signatures in the certificate chain in certain scenarios, so RFC - * compliance would imply validating that the certificate chain signature - * algorithm matches one of the algorithms specified in the - * "signature_algorithms" extension. - * - *= https://www.rfc-editor.org/rfc/rfc5246#section-7.4.2 - *= type=exception - *= reason=not implemented due to lack of utility - *# If the client provided a "signature_algorithms" extension, then all - *# certificates provided by the server MUST be signed by a - *# hash/signature algorithm pair that appears in that extension. - * - *= https://www.rfc-editor.org/rfc/rfc8446#section-4.2.3 - *= type=exception - *= reason=not implemented due to lack of utility - *# If no "signature_algorithms_cert" extension is present, then the - *# "signature_algorithms" extension also applies to signatures appearing in - *# certificates. - */ - if (security_policy->certificate_signature_preferences == NULL) { - return S2N_RESULT_OK; - } - - X509_NAME *issuer_name = X509_get_issuer_name(x509_cert); - RESULT_ENSURE_REF(issuer_name); - - X509_NAME *subject_name = X509_get_subject_name(x509_cert); - RESULT_ENSURE_REF(subject_name); - - /* Do not validate any self-signed certificates */ - if (X509_NAME_cmp(issuer_name, subject_name) == 0) { - return S2N_RESULT_OK; - } - - RESULT_GUARD(s2n_validate_sig_scheme_supported(conn, x509_cert, security_policy->certificate_signature_preferences)); - - return S2N_RESULT_OK; -} - -S2N_RESULT s2n_validate_sig_scheme_supported(struct s2n_connection *conn, X509 *x509_cert, - const struct s2n_signature_preferences *cert_sig_preferences) -{ - RESULT_ENSURE_REF(conn); - RESULT_ENSURE_REF(x509_cert); - RESULT_ENSURE_REF(cert_sig_preferences); - - int nid = 0; - -#if defined(LIBRESSL_VERSION_NUMBER) && (LIBRESSL_VERSION_NUMBER < 0x02070000f) - RESULT_ENSURE_REF(x509_cert->sig_alg); - nid = OBJ_obj2nid(x509_cert->sig_alg->algorithm); -#else - nid = X509_get_signature_nid(x509_cert); -#endif - - for (size_t i = 0; i < cert_sig_preferences->count; i++) { - if (cert_sig_preferences->signature_schemes[i]->libcrypto_nid == nid) { - /* SHA-1 algorithms are not supported in certificate signatures in TLS1.3 */ - RESULT_ENSURE(!(conn->actual_protocol_version >= S2N_TLS13 - && cert_sig_preferences->signature_schemes[i]->hash_alg == S2N_HASH_SHA1), - S2N_ERR_CERT_UNTRUSTED); - - return S2N_RESULT_OK; - } - } - - RESULT_BAIL(S2N_ERR_CERT_UNTRUSTED); -} - bool s2n_x509_validator_is_cert_chain_validated(const struct s2n_x509_validator *validator) { return validator && (validator->state == VALIDATED || validator->state == OCSP_VALIDATED); diff --git a/tls/s2n_x509_validator.h b/tls/s2n_x509_validator.h index 8ca2d624d4d..7706fc0a031 100644 --- a/tls/s2n_x509_validator.h +++ b/tls/s2n_x509_validator.h @@ -133,13 +133,3 @@ S2N_RESULT s2n_x509_validator_validate_cert_stapled_ocsp_response(struct s2n_x50 * Should be verified before any use of the peer's certificate data. */ bool s2n_x509_validator_is_cert_chain_validated(const struct s2n_x509_validator *validator); - -/** - * Validates that each certificate in a peer's cert chain contains only signature algorithms in a security policy's - * certificate_signatures_preference list. - */ -S2N_RESULT s2n_validate_certificate_signature(struct s2n_connection *conn, X509 *x509_cert); - -/* Checks to see if a certificate has a signature algorithm that's in our certificate_signature_preferences list */ -S2N_RESULT s2n_validate_sig_scheme_supported(struct s2n_connection *conn, X509 *x509_cert, - const struct s2n_signature_preferences *cert_sig_preferences); diff --git a/utils/s2n_array.c b/utils/s2n_array.c index 0ac68131b8d..b9f5d88431e 100644 --- a/utils/s2n_array.c +++ b/utils/s2n_array.c @@ -38,12 +38,12 @@ static S2N_RESULT s2n_array_enlarge(struct s2n_array *array, uint32_t capacity) RESULT_ENSURE_REF(array); /* Acquire the memory */ - uint32_t mem_needed; + uint32_t mem_needed = 0; RESULT_GUARD_POSIX(s2n_mul_overflow(array->element_size, capacity, &mem_needed)); RESULT_GUARD_POSIX(s2n_realloc(&array->mem, mem_needed)); /* Zero the extened part */ - uint32_t array_elements_size; + uint32_t array_elements_size = 0; RESULT_GUARD_POSIX(s2n_mul_overflow(array->element_size, array->len, &array_elements_size)); RESULT_CHECKED_MEMSET(array->mem.data + array_elements_size, 0, array->mem.size - array_elements_size); RESULT_POSTCONDITION(s2n_array_validate(array)); diff --git a/utils/s2n_blob.h b/utils/s2n_blob.h index fd1c84f1240..deba566466d 100644 --- a/utils/s2n_blob.h +++ b/utils/s2n_blob.h @@ -40,11 +40,11 @@ struct s2n_blob { bool s2n_blob_is_growable(const struct s2n_blob *b); S2N_RESULT s2n_blob_validate(const struct s2n_blob *b); -int s2n_blob_init(struct s2n_blob *b, uint8_t *data, uint32_t size); +int S2N_RESULT_MUST_USE s2n_blob_init(struct s2n_blob *b, uint8_t *data, uint32_t size); int s2n_blob_zero(struct s2n_blob *b); -int s2n_blob_char_to_lower(struct s2n_blob *b); -int s2n_hex_string_to_bytes(const uint8_t *str, struct s2n_blob *blob); -int s2n_blob_slice(const struct s2n_blob *b, struct s2n_blob *slice, uint32_t offset, uint32_t size); +int S2N_RESULT_MUST_USE s2n_blob_char_to_lower(struct s2n_blob *b); +int S2N_RESULT_MUST_USE s2n_hex_string_to_bytes(const uint8_t *str, struct s2n_blob *blob); +int S2N_RESULT_MUST_USE s2n_blob_slice(const struct s2n_blob *b, struct s2n_blob *slice, uint32_t offset, uint32_t size); #define s2n_stack_blob(name, requested_size, maximum) \ size_t name##_requested_size = (requested_size); \ diff --git a/utils/s2n_ensure.c b/utils/s2n_ensure.c index 5824f9b6186..c2350740462 100644 --- a/utils/s2n_ensure.c +++ b/utils/s2n_ensure.c @@ -15,7 +15,7 @@ #include "utils/s2n_safety.h" -void *s2n_ensure_memcpy_trace(void *restrict to, const void *restrict from, size_t size) +void *s2n_ensure_memmove_trace(void *to, const void *from, size_t size) { PTR_ENSURE_REF(to); PTR_ENSURE_REF(from); diff --git a/utils/s2n_ensure.h b/utils/s2n_ensure.h index c072d93e952..890cca162b5 100644 --- a/utils/s2n_ensure.h +++ b/utils/s2n_ensure.h @@ -60,13 +60,13 @@ #define __S2N_ENSURE_POSTCONDITION(result) (s2n_likely(s2n_result_is_ok(result)) ? S2N_RESULT_OK : S2N_RESULT_ERROR) #endif -#define __S2N_ENSURE_SAFE_MEMCPY(d, s, n, guard) \ - do { \ - __typeof(n) __tmp_n = (n); \ - if (s2n_likely(__tmp_n)) { \ - void *r = s2n_ensure_memcpy_trace((d), (s), (__tmp_n)); \ - guard(r); \ - } \ +#define __S2N_ENSURE_SAFE_MEMMOVE(d, s, n, guard) \ + do { \ + __typeof(n) __tmp_n = (n); \ + if (s2n_likely(__tmp_n)) { \ + void *r = s2n_ensure_memmove_trace((d), (s), (__tmp_n)); \ + guard(r); \ + } \ } while (0) #define __S2N_ENSURE_SAFE_MEMSET(d, c, n, guard) \ @@ -90,23 +90,7 @@ #define __S2N_ENSURE_CHECKED_RETURN(v) return v #endif -/** - * `restrict` is a part of the c99 standard and will work with any C compiler. If you're trying to - * compile with a C++ compiler `restrict` is invalid. However some C++ compilers support the behavior - * of `restrict` using the `__restrict__` keyword. Therefore if the compiler supports `__restrict__` - * use it. - * - * This is helpful for the benchmarks in tests/benchmark which use Google's Benchmark library and - * are all written in C++. - * - * https://gcc.gnu.org/onlinedocs/gcc/Restricted-Pointers.html - * - */ -#if defined(S2N___RESTRICT__SUPPORTED) -void *s2n_ensure_memcpy_trace(void *__restrict__ to, const void *__restrict__ from, size_t size); -#else -void *s2n_ensure_memcpy_trace(void *restrict to, const void *restrict from, size_t size); -#endif +void *s2n_ensure_memmove_trace(void *to, const void *from, size_t size); /** * These macros should not be used in validate functions. diff --git a/utils/s2n_map.c b/utils/s2n_map.c index e95679553e0..93574609fac 100644 --- a/utils/s2n_map.c +++ b/utils/s2n_map.c @@ -32,6 +32,7 @@ static S2N_RESULT s2n_map_slot(const struct s2n_map *map, struct s2n_blob *key, uint32_t *slot) { RESULT_ENSURE_REF(map); + RESULT_ENSURE(map->capacity != 0, S2N_ERR_SAFETY); union { uint8_t u8[32]; uint32_t u32[8]; @@ -90,7 +91,7 @@ struct s2n_map *s2n_map_new_with_initial_capacity(uint32_t capacity) { PTR_ENSURE(capacity != 0, S2N_ERR_MAP_INVALID_MAP_SIZE); struct s2n_blob mem = { 0 }; - struct s2n_map *map; + struct s2n_map *map = NULL; PTR_GUARD_POSIX(s2n_alloc(&mem, sizeof(struct s2n_map))); @@ -209,8 +210,8 @@ S2N_RESULT s2n_map_lookup(const struct s2n_map *map, struct s2n_blob *key, struc } /* We found a match */ - value->data = map->table[slot].value.data; - value->size = map->table[slot].value.size; + struct s2n_blob entry_value = map->table[slot].value; + RESULT_GUARD_POSIX(s2n_blob_init(value, entry_value.data, entry_value.size)); *key_found = true; @@ -246,3 +247,73 @@ S2N_RESULT s2n_map_free(struct s2n_map *map) return S2N_RESULT_OK; } + +S2N_RESULT s2n_map_size(struct s2n_map *map, uint32_t *size) +{ + RESULT_ENSURE_REF(map); + *size = map->size; + return S2N_RESULT_OK; +} + +/* Update the internal state so that `current_index` will point to the next value + * in the table or set iter->consumed equal to true if there are no more elements + * in the map. + */ +S2N_RESULT s2n_map_iterator_advance(struct s2n_map_iterator *iter) +{ + RESULT_ENSURE_REF(iter); + RESULT_ENSURE_REF(iter->map); + RESULT_ENSURE(s2n_map_iterator_has_next(iter), S2N_ERR_ARRAY_INDEX_OOB); + + iter->current_index++; + while (iter->current_index < iter->map->capacity) { + /* a value was found in the map */ + if (iter->map->table[iter->current_index].key.size) { + return S2N_RESULT_OK; + } + iter->current_index++; + } + /* no more values were found in the map */ + iter->consumed = true; + return S2N_RESULT_OK; +} + +S2N_RESULT s2n_map_iterator_init(struct s2n_map_iterator *iter, const struct s2n_map *map) +{ + RESULT_ENSURE_REF(iter); + RESULT_ENSURE_REF(map); + RESULT_ENSURE(map->immutable, S2N_ERR_MAP_MUTABLE); + + iter->map = map; + iter->current_index = 0; + + /* Advance the index to point to the first value in the map. This isn't + * necessary if the slot at index 0 already contains a value. + */ + if (iter->map->table[0].key.size == 0) { + RESULT_GUARD(s2n_map_iterator_advance(iter)); + } + + return S2N_RESULT_OK; +} + +S2N_RESULT s2n_map_iterator_next(struct s2n_map_iterator *iter, struct s2n_blob *value) +{ + RESULT_ENSURE_REF(iter); + RESULT_ENSURE_REF(iter->map); + RESULT_ENSURE(iter->map->immutable, S2N_ERR_MAP_MUTABLE); + RESULT_ENSURE(s2n_map_iterator_has_next(iter), S2N_ERR_ARRAY_INDEX_OOB); + + RESULT_ENSURE(iter->current_index < iter->map->capacity, S2N_ERR_ARRAY_INDEX_OOB); + struct s2n_blob entry_value = iter->map->table[iter->current_index].value; + RESULT_GUARD_POSIX(s2n_blob_init(value, entry_value.data, entry_value.size)); + + RESULT_GUARD(s2n_map_iterator_advance(iter)); + + return S2N_RESULT_OK; +} + +bool s2n_map_iterator_has_next(const struct s2n_map_iterator *iter) +{ + return iter && !iter->consumed; +} diff --git a/utils/s2n_map.h b/utils/s2n_map.h index 259082936cf..eaabe4d5825 100644 --- a/utils/s2n_map.h +++ b/utils/s2n_map.h @@ -21,6 +21,12 @@ #include "utils/s2n_result.h" struct s2n_map; +struct s2n_map_iterator { + const struct s2n_map *map; + /* Index of the entry to be returned on the next `s2n_map_iterator_next()` call. */ + uint32_t current_index; + bool consumed; +}; struct s2n_map *s2n_map_new(); struct s2n_map *s2n_map_new_with_initial_capacity(uint32_t capacity); @@ -30,3 +36,8 @@ S2N_RESULT s2n_map_complete(struct s2n_map *map); S2N_RESULT s2n_map_unlock(struct s2n_map *map); S2N_RESULT s2n_map_lookup(const struct s2n_map *map, struct s2n_blob *key, struct s2n_blob *value, bool *key_found); S2N_RESULT s2n_map_free(struct s2n_map *map); +S2N_RESULT s2n_map_size(struct s2n_map *map, uint32_t *size); + +S2N_RESULT s2n_map_iterator_init(struct s2n_map_iterator *iter, const struct s2n_map *map); +S2N_RESULT s2n_map_iterator_next(struct s2n_map_iterator *iter, struct s2n_blob *value); +bool s2n_map_iterator_has_next(const struct s2n_map_iterator *iter); diff --git a/utils/s2n_mem.c b/utils/s2n_mem.c index d8c79ddee77..7f8b2afa03e 100644 --- a/utils/s2n_mem.c +++ b/utils/s2n_mem.c @@ -92,7 +92,7 @@ static int s2n_mem_malloc_mlock_impl(void **ptr, uint32_t requested, uint32_t *a POSIX_ENSURE_REF(ptr); /* Page aligned allocation required for mlock */ - uint32_t allocate; + uint32_t allocate = 0; POSIX_GUARD(s2n_align_to(requested, page_size, &allocate)); diff --git a/utils/s2n_mem.h b/utils/s2n_mem.h index 4b87ab39059..3f04d6d6cf8 100644 --- a/utils/s2n_mem.h +++ b/utils/s2n_mem.h @@ -28,12 +28,12 @@ int s2n_mem_cleanup(void); * Generally, s2n_realloc is preferred over s2n_alloc. This is because calling * s2n_alloc on a blob that already has memory allocated will leak memory. */ -int s2n_alloc(struct s2n_blob *b, uint32_t size); -int s2n_realloc(struct s2n_blob *b, uint32_t size); +int S2N_RESULT_MUST_USE s2n_alloc(struct s2n_blob *b, uint32_t size); +int S2N_RESULT_MUST_USE s2n_realloc(struct s2n_blob *b, uint32_t size); int s2n_free(struct s2n_blob *b); int s2n_free_without_wipe(struct s2n_blob *b); int s2n_free_object(uint8_t **p_data, uint32_t size); -int s2n_dup(struct s2n_blob *from, struct s2n_blob *to); +int S2N_RESULT_MUST_USE s2n_dup(struct s2n_blob *from, struct s2n_blob *to); /* Unlike free, s2n_free_or_wipe accepts static blobs. * It frees allocated blobs and wipes static blobs. diff --git a/utils/s2n_random.c b/utils/s2n_random.c index 78154d85a7e..ac8f9817b1f 100644 --- a/utils/s2n_random.c +++ b/utils/s2n_random.c @@ -67,6 +67,7 @@ #include "crypto/s2n_drbg.h" #include "crypto/s2n_fips.h" #include "error/s2n_errno.h" +#include "s2n_io.h" #include "stuffer/s2n_stuffer.h" #include "utils/s2n_fork_detection.h" #include "utils/s2n_init.h" @@ -75,8 +76,6 @@ #include "utils/s2n_result.h" #include "utils/s2n_safety.h" -#define ENTROPY_SOURCE "/dev/urandom" - #if defined(O_CLOEXEC) #define ENTROPY_FLAGS O_RDONLY | O_CLOEXEC #else @@ -92,7 +91,10 @@ /* Placeholder value for an uninitialized entropy file descriptor */ #define UNINITIALIZED_ENTROPY_FD -1 -static int entropy_fd = UNINITIALIZED_ENTROPY_FD; +static struct s2n_rand_device s2n_dev_urandom = { + .source = "/dev/urandom", + .fd = UNINITIALIZED_ENTROPY_FD, +}; struct s2n_rand_state { uint64_t cached_fork_generation_number; @@ -115,15 +117,23 @@ static __thread struct s2n_rand_state s2n_per_thread_rand_state = { .drbgs_initialized = false }; -static int s2n_rand_init_impl(void); -static int s2n_rand_cleanup_impl(void); -static int s2n_rand_urandom_impl(void *ptr, uint32_t size); -static int s2n_rand_rdrand_impl(void *ptr, uint32_t size); +static int s2n_rand_init_cb_impl(void); +static int s2n_rand_cleanup_cb_impl(void); +static int s2n_rand_get_entropy_from_urandom(void *ptr, uint32_t size); +static int s2n_rand_get_entropy_from_rdrand(void *ptr, uint32_t size); -static s2n_rand_init_callback s2n_rand_init_cb = s2n_rand_init_impl; -static s2n_rand_cleanup_callback s2n_rand_cleanup_cb = s2n_rand_cleanup_impl; -static s2n_rand_seed_callback s2n_rand_seed_cb = s2n_rand_urandom_impl; -static s2n_rand_mix_callback s2n_rand_mix_cb = s2n_rand_urandom_impl; +static s2n_rand_init_callback s2n_rand_init_cb = s2n_rand_init_cb_impl; +static s2n_rand_cleanup_callback s2n_rand_cleanup_cb = s2n_rand_cleanup_cb_impl; +static s2n_rand_seed_callback s2n_rand_seed_cb = s2n_rand_get_entropy_from_urandom; +static s2n_rand_mix_callback s2n_rand_mix_cb = s2n_rand_get_entropy_from_urandom; + +static int s2n_rand_entropy_fd_close_ptr(int *fd) +{ + if (fd && *fd != UNINITIALIZED_ENTROPY_FD) { + close(*fd); + } + return S2N_SUCCESS; +} /* non-static for SAW proof */ bool s2n_cpu_supports_rdrand() @@ -332,9 +342,76 @@ S2N_RESULT s2n_get_private_random_bytes_used(uint64_t *bytes_used) return S2N_RESULT_OK; } -static int s2n_rand_urandom_impl(void *ptr, uint32_t size) +S2N_RESULT s2n_rand_get_urandom_for_test(struct s2n_rand_device **device) +{ + RESULT_ENSURE_REF(device); + RESULT_ENSURE(s2n_in_unit_test(), S2N_ERR_NOT_IN_UNIT_TEST); + *device = &s2n_dev_urandom; + return S2N_RESULT_OK; +} + +static S2N_RESULT s2n_rand_device_open(struct s2n_rand_device *device) +{ + RESULT_ENSURE_REF(device); + RESULT_ENSURE_REF(device->source); + + DEFER_CLEANUP(int fd = -1, s2n_rand_entropy_fd_close_ptr); + S2N_IO_RETRY_EINTR(fd, open(device->source, ENTROPY_FLAGS)); + RESULT_ENSURE(fd >= 0, S2N_ERR_OPEN_RANDOM); + + struct stat st = { 0 }; + RESULT_ENSURE(fstat(fd, &st) == 0, S2N_ERR_OPEN_RANDOM); + device->dev = st.st_dev; + device->ino = st.st_ino; + device->mode = st.st_mode; + device->rdev = st.st_rdev; + + device->fd = fd; + + /* Disable closing the file descriptor with defer cleanup */ + fd = UNINITIALIZED_ENTROPY_FD; + + return S2N_RESULT_OK; +} + +S2N_RESULT s2n_rand_device_validate(struct s2n_rand_device *device) { - POSIX_ENSURE(entropy_fd != UNINITIALIZED_ENTROPY_FD, S2N_ERR_NOT_INITIALIZED); + RESULT_ENSURE_REF(device); + RESULT_ENSURE_NE(device->fd, UNINITIALIZED_ENTROPY_FD); + + /* Ensure that the random device is still valid by comparing it to the current file descriptor + * status. From: + * https://github.com/openssl/openssl/blob/260d97229c467d17934ca3e2e0455b1b5c0994a6/providers/implementations/rands/seeding/rand_unix.c#L513 + */ + struct stat st = { 0 }; + RESULT_ENSURE(fstat(device->fd, &st) == 0, S2N_ERR_OPEN_RANDOM); + RESULT_ENSURE_EQ(device->dev, st.st_dev); + RESULT_ENSURE_EQ(device->ino, st.st_ino); + RESULT_ENSURE_EQ(device->rdev, st.st_rdev); + + /* Ensure that the mode is the same (equal to 0 when xor'd), but don't check the permission bits. */ + mode_t permission_mask = ~(S_IRWXU | S_IRWXG | S_IRWXO); + RESULT_ENSURE_EQ((device->mode ^ st.st_mode) & permission_mask, 0); + + return S2N_RESULT_OK; +} + +static int s2n_rand_get_entropy_from_urandom(void *ptr, uint32_t size) +{ + POSIX_ENSURE_REF(ptr); + POSIX_ENSURE(s2n_dev_urandom.fd != UNINITIALIZED_ENTROPY_FD, S2N_ERR_NOT_INITIALIZED); + + /* It's possible that the file descriptor pointing to /dev/urandom was closed or changed from + * when it was last opened. Ensure that the file descriptor is still valid, and if it isn't, + * re-open it before getting entropy. + * + * If the file descriptor is invalid and the process doesn't have access to /dev/urandom (as is + * the case within a chroot tree), an error is raised here before attempting to indefinitely + * read. + */ + if (s2n_result_is_error(s2n_rand_device_validate(&s2n_dev_urandom))) { + POSIX_GUARD_RESULT(s2n_rand_device_open(&s2n_dev_urandom)); + } uint8_t *data = ptr; uint32_t n = size; @@ -343,7 +420,7 @@ static int s2n_rand_urandom_impl(void *ptr, uint32_t size) while (n) { errno = 0; - int r = read(entropy_fd, data, n); + int r = read(s2n_dev_urandom.fd, data, n); if (r <= 0) { /* * A non-blocking read() on /dev/urandom should "never" fail, @@ -386,7 +463,7 @@ static int s2n_rand_urandom_impl(void *ptr, uint32_t size) */ S2N_RESULT s2n_public_random(int64_t bound, uint64_t *output) { - uint64_t r; + uint64_t r = 0; RESULT_ENSURE_GT(bound, 0); @@ -450,19 +527,16 @@ RAND_METHOD s2n_openssl_rand_method = { }; #endif -static int s2n_rand_init_impl(void) +static int s2n_rand_init_cb_impl(void) { -OPEN: - entropy_fd = open(ENTROPY_SOURCE, ENTROPY_FLAGS); - if (entropy_fd == -1) { - if (errno == EINTR) { - goto OPEN; - } - POSIX_BAIL(S2N_ERR_OPEN_RANDOM); - } + /* Currently, s2n-tls may mix in entropy from urandom into every generation of random data. The + * file descriptor is opened on initialization for better performance reading from urandom, and + * to ensure that urandom is accessible from within a chroot tree. + */ + POSIX_GUARD_RESULT(s2n_rand_device_open(&s2n_dev_urandom)); if (s2n_cpu_supports_rdrand()) { - s2n_rand_mix_cb = s2n_rand_rdrand_impl; + s2n_rand_mix_cb = s2n_rand_get_entropy_from_rdrand; } return S2N_SUCCESS; @@ -479,6 +553,9 @@ S2N_RESULT s2n_rand_init(void) return S2N_RESULT_OK; } + /* Unset any existing random engine */ + RESULT_GUARD_OSSL(RAND_set_rand_engine(NULL), S2N_ERR_OPEN_RANDOM); + /* Create an engine */ ENGINE *e = ENGINE_new(); @@ -502,12 +579,14 @@ S2N_RESULT s2n_rand_init(void) return S2N_RESULT_OK; } -static int s2n_rand_cleanup_impl(void) +static int s2n_rand_cleanup_cb_impl(void) { - POSIX_ENSURE(entropy_fd != UNINITIALIZED_ENTROPY_FD, S2N_ERR_NOT_INITIALIZED); + POSIX_ENSURE(s2n_dev_urandom.fd != UNINITIALIZED_ENTROPY_FD, S2N_ERR_NOT_INITIALIZED); - POSIX_GUARD(close(entropy_fd)); - entropy_fd = UNINITIALIZED_ENTROPY_FD; + if (s2n_result_is_ok(s2n_rand_device_validate(&s2n_dev_urandom))) { + POSIX_GUARD(close(s2n_dev_urandom.fd)); + } + s2n_dev_urandom.fd = UNINITIALIZED_ENTROPY_FD; return S2N_SUCCESS; } @@ -530,10 +609,10 @@ S2N_RESULT s2n_rand_cleanup(void) } #endif - s2n_rand_init_cb = s2n_rand_init_impl; - s2n_rand_cleanup_cb = s2n_rand_cleanup_impl; - s2n_rand_seed_cb = s2n_rand_urandom_impl; - s2n_rand_mix_cb = s2n_rand_urandom_impl; + s2n_rand_init_cb = s2n_rand_init_cb_impl; + s2n_rand_cleanup_cb = s2n_rand_cleanup_cb_impl; + s2n_rand_seed_cb = s2n_rand_get_entropy_from_urandom; + s2n_rand_mix_cb = s2n_rand_get_entropy_from_urandom; return S2N_RESULT_OK; } @@ -571,11 +650,18 @@ S2N_RESULT s2n_set_private_drbg_for_test(struct s2n_drbg drbg) return S2N_RESULT_OK; } +S2N_RESULT s2n_rand_set_urandom_for_test() +{ + RESULT_ENSURE(s2n_in_unit_test(), S2N_ERR_NOT_IN_UNIT_TEST); + s2n_rand_mix_cb = s2n_rand_get_entropy_from_urandom; + return S2N_RESULT_OK; +} + /* * volatile is important to prevent the compiler from * re-ordering or optimizing the use of RDRAND. */ -static int s2n_rand_rdrand_impl(void *data, uint32_t size) +static int s2n_rand_get_entropy_from_rdrand(void *data, uint32_t size) { #if defined(__x86_64__) || defined(__i386__) struct s2n_blob out = { 0 }; diff --git a/utils/s2n_random.h b/utils/s2n_random.h index c0ad048bf27..5284e6271a8 100644 --- a/utils/s2n_random.h +++ b/utils/s2n_random.h @@ -19,6 +19,15 @@ #include "utils/s2n_blob.h" #include "utils/s2n_result.h" +struct s2n_rand_device { + const char *source; + int fd; + dev_t dev; + ino_t ino; + mode_t mode; + dev_t rdev; +}; + S2N_RESULT s2n_rand_init(void); S2N_RESULT s2n_rand_cleanup(void); S2N_RESULT s2n_get_seed_entropy(struct s2n_blob *blob); @@ -31,3 +40,4 @@ S2N_RESULT s2n_get_public_random_bytes_used(uint64_t *bytes_used); S2N_RESULT s2n_get_private_random_data(struct s2n_blob *blob); S2N_RESULT s2n_get_private_random_bytes_used(uint64_t *bytes_used); S2N_RESULT s2n_public_random(int64_t max, uint64_t *output); +int s2n_openssl_compat_rand(unsigned char *buf, int num); diff --git a/utils/s2n_rfc5952.c b/utils/s2n_rfc5952.c index cf6cf9f1d3f..5ed078a51dc 100644 --- a/utils/s2n_rfc5952.c +++ b/utils/s2n_rfc5952.c @@ -106,7 +106,7 @@ S2N_RESULT s2n_inet_ntop(int af, const void *addr, struct s2n_blob *dst) (octets[i] & 0x000F) }; /* Skip up to three leading zeroes */ - int j; + int j = 0; for (j = 0; j < 3; j++) { if (nibbles[j]) { break; diff --git a/utils/s2n_safety_macros.h b/utils/s2n_safety_macros.h index 33e5133dca4..e3896e8c360 100644 --- a/utils/s2n_safety_macros.h +++ b/utils/s2n_safety_macros.h @@ -161,7 +161,7 @@ * * The size of the data pointed to by both the `destination` and `source` parameters, * shall be at least `len` bytes. */ -#define RESULT_CHECKED_MEMCPY(destination, source, len) __S2N_ENSURE_SAFE_MEMCPY((destination), (source), (len), RESULT_ENSURE_REF) +#define RESULT_CHECKED_MEMCPY(destination, source, len) __S2N_ENSURE_SAFE_MEMMOVE((destination), (source), (len), RESULT_ENSURE_REF) /** * Performs a safer memset @@ -357,7 +357,7 @@ * * The size of the data pointed to by both the `destination` and `source` parameters, * shall be at least `len` bytes. */ -#define POSIX_CHECKED_MEMCPY(destination, source, len) __S2N_ENSURE_SAFE_MEMCPY((destination), (source), (len), POSIX_ENSURE_REF) +#define POSIX_CHECKED_MEMCPY(destination, source, len) __S2N_ENSURE_SAFE_MEMMOVE((destination), (source), (len), POSIX_ENSURE_REF) /** * DEPRECATED: all methods (except those in s2n.h) should return s2n_result. @@ -563,7 +563,7 @@ * * The size of the data pointed to by both the `destination` and `source` parameters, * shall be at least `len` bytes. */ -#define PTR_CHECKED_MEMCPY(destination, source, len) __S2N_ENSURE_SAFE_MEMCPY((destination), (source), (len), PTR_ENSURE_REF) +#define PTR_CHECKED_MEMCPY(destination, source, len) __S2N_ENSURE_SAFE_MEMMOVE((destination), (source), (len), PTR_ENSURE_REF) /** * DEPRECATED: all methods (except those in s2n.h) should return s2n_result. diff --git a/utils/s2n_socket.c b/utils/s2n_socket.c index 6928f1e0156..0aa16432569 100644 --- a/utils/s2n_socket.c +++ b/utils/s2n_socket.c @@ -227,7 +227,7 @@ int s2n_socket_is_ipv6(int fd, uint8_t *ipv6) { POSIX_ENSURE_REF(ipv6); - socklen_t len; + socklen_t len = 0; struct sockaddr_storage addr; len = sizeof(addr); POSIX_GUARD(getpeername(fd, (struct sockaddr *) &addr, &len)); diff --git a/utils/s2n_timer.c b/utils/s2n_timer.c index 3017d4af9cf..7c4eeee0793 100644 --- a/utils/s2n_timer.c +++ b/utils/s2n_timer.c @@ -29,7 +29,7 @@ S2N_RESULT s2n_timer_start(struct s2n_config *config, struct s2n_timer *timer) S2N_RESULT s2n_timer_elapsed(struct s2n_config *config, struct s2n_timer *timer, uint64_t *nanoseconds) { - uint64_t current_time; + uint64_t current_time = 0; RESULT_ENSURE(config->monotonic_clock(config->monotonic_clock_ctx, ¤t_time) >= S2N_SUCCESS, S2N_ERR_CANCELLED);