aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/restricted/aws/s2n
diff options
context:
space:
mode:
authorrobot-contrib <robot-contrib@yandex-team.com>2023-05-12 10:28:42 +0300
committerrobot-contrib <robot-contrib@yandex-team.com>2023-05-12 10:28:42 +0300
commitbb9187654c4ea19cbbac471a7d9ba158fa0ebe99 (patch)
tree20e41b05f4a95138a08c6e2225030958624ba263 /contrib/restricted/aws/s2n
parentaa95211fddb9867731b60e56b78ac75f05f42243 (diff)
downloadydb-bb9187654c4ea19cbbac471a7d9ba158fa0ebe99.tar.gz
Update contrib/restricted/aws/s2n to 1.3.43
Diffstat (limited to 'contrib/restricted/aws/s2n')
-rw-r--r--contrib/restricted/aws/s2n/README.md4
-rw-r--r--contrib/restricted/aws/s2n/api/s2n.h23
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_libcrypto.c12
-rw-r--r--contrib/restricted/aws/s2n/pq-crypto/README.md6
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_alerts.c11
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_cipher_suites.c1
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_config.c2
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_config.h2
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_connection.c109
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_connection.h29
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_handshake_io.c5
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_recv.c7
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_security_policies.c40
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_security_policies.h41
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_send.c6
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_shutdown.c34
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_x509_validator.c41
17 files changed, 286 insertions, 87 deletions
diff --git a/contrib/restricted/aws/s2n/README.md b/contrib/restricted/aws/s2n/README.md
index e3e9b08057..64baa0db5c 100644
--- a/contrib/restricted/aws/s2n/README.md
+++ b/contrib/restricted/aws/s2n/README.md
@@ -2,6 +2,10 @@
s2n-tls is a C99 implementation of the TLS/SSL protocols that is designed to be simple, small, fast, and with security as a priority. It is released and licensed under the Apache License 2.0.
+> s2n-tls is short for "signal to noise" and is a nod to the almost magical act of encryption — disguising meaningful signals, like your critical data, as seemingly random noise.
+>
+> -- [s2n-tls announcement](https://aws.amazon.com/blogs/security/introducing-s2n-a-new-open-source-tls-implementation/)
+
[![Build Status](https://codebuild.us-west-2.amazonaws.com/badges?uuid=eyJlbmNyeXB0ZWREYXRhIjoiMndlTzJNbHVxWEo3Nm82alp4eGdGNm4rTWdxZDVYU2VTbitIR0ZLbHVtcFFGOW5majk5QnhqaUp3ZEkydG1ueWg0NGlhRE43a1ZnUzZaQTVnSm91TzFFPSIsIml2UGFyYW1ldGVyU3BlYyI6IlJLbW42NENlYXhJNy80QnYiLCJtYXRlcmlhbFNldFNlcmlhbCI6MX0%3D&branch=main)](https://github.com/aws/s2n-tls/)
[![Apache 2 License](https://img.shields.io/github/license/aws/s2n-tls.svg)](http://aws.amazon.com/apache-2-0/)
[![C99](https://img.shields.io/badge/language-C99-blue.svg)](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf)
diff --git a/contrib/restricted/aws/s2n/api/s2n.h b/contrib/restricted/aws/s2n/api/s2n.h
index ca8d4d4923..665370da4b 100644
--- a/contrib/restricted/aws/s2n/api/s2n.h
+++ b/contrib/restricted/aws/s2n/api/s2n.h
@@ -869,13 +869,20 @@ S2N_API extern int s2n_config_set_verify_after_sign(struct s2n_config *config, s
S2N_API extern int s2n_config_set_send_buffer_size(struct s2n_config *config, uint32_t size);
/**
- * Enable or disable recieving of multiple TLS records in a single s2n_recv call
+ * Enable or disable receiving of multiple TLS records in a single s2n_recv call
*
- * Legacy behavior is to return after reading a single TLS record which may not be the most
- * efficient way to invoke this function, especially if larger receive buffers are used.
+ * By default, s2n-tls returns from s2n_recv() after reading a single TLS record.
+ * Enabling receiving of multiple records will instead cause s2n_recv() to attempt
+ * to read until the application-provided output buffer is full. This may be more
+ * efficient, especially if larger receive buffers are used.
+ *
+ * @note If this option is enabled with blocking IO, the call to s2n_recv() will
+ * not return until either the application-provided output buffer is full or the
+ * peer closes the connection. This may lead to unintentionally long waits if the
+ * peer does not send enough data.
*
* @param config The configuration object being updated
- * @param enabled Set to `true` if multiple record recieve is to be enabled; `false` to disable.
+ * @param enabled Set to `true` if multiple record receive is to be enabled; `false` to disable.
* @returns S2N_SUCCESS on success. S2N_FAILURE on failure
*/
S2N_API extern int s2n_config_set_recv_multi_record(struct s2n_config *config, bool enabled);
@@ -1711,11 +1718,17 @@ S2N_API extern int s2n_connection_set_protocol_preferences(struct s2n_connection
/**
* Sets the server name for the connection.
*
- * It may be desirable for clients
+ * The provided server name will be sent by the client to the server in the
+ * server_name ClientHello extension. It may be desirable for clients
* to provide this information to facilitate secure connections to
* servers that host multiple 'virtual' servers at a single underlying
* network address.
*
+ * s2n-tls does not place any restrictions on the provided server name. However,
+ * other TLS implementations might. Specifically, the TLS specification for the
+ * server_name extension requires that it be an ASCII-encoded DNS name without a
+ * trailing dot, and explicitly forbids literal IPv4 or IPv6 addresses.
+ *
* @param conn The connection object being queried
* @param server_name A pointer to a string containing the desired server name
* @warning `server_name` must be a NULL terminated string.
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_libcrypto.c b/contrib/restricted/aws/s2n/crypto/s2n_libcrypto.c
index 92ed4bf15d..1b73ff782d 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_libcrypto.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_libcrypto.c
@@ -43,9 +43,9 @@
* distinguish AWS-LC fips and non-fips at pre-processing time since AWS-LC
* doesn't distribute fips-specific header files.
*/
-#define EXPECTED_AWSLC_VERSION_PREFIX_FIPS_OR_OLD "BoringSSL"
-#define EXPECTED_AWSLC_VERSION_PREFIX_NON_FIPS "AWS-LC"
-#define EXPECTED_BORINGSSL_VERSION_PREFIX "BoringSSL"
+#define EXPECTED_AWSLC_VERSION_PREFIX_OLD "BoringSSL"
+#define EXPECTED_AWSLC_VERSION_PREFIX_NEW "AWS-LC"
+#define EXPECTED_BORINGSSL_VERSION_PREFIX "BoringSSL"
/* https://www.openssl.org/docs/man{1.0.2, 1.1.1, 3.0}/man3/OPENSSL_VERSION_NUMBER.html
* OPENSSL_VERSION_NUMBER in hex is: MNNFFPPS major minor fix patch status.
@@ -192,10 +192,10 @@ S2N_RESULT s2n_libcrypto_validate_runtime(void)
* don't meet anymore "old" AWS-LC libcrypto's, this API version check
* can be removed.
*/
- if (s2n_libcrypto_is_fips() || s2n_libcrypto_awslc_api_version() < 17) {
- expected_awslc_name_prefix = EXPECTED_AWSLC_VERSION_PREFIX_FIPS_OR_OLD;
+ if (s2n_libcrypto_awslc_api_version() < 17) {
+ expected_awslc_name_prefix = EXPECTED_AWSLC_VERSION_PREFIX_OLD;
} else {
- expected_awslc_name_prefix = EXPECTED_AWSLC_VERSION_PREFIX_NON_FIPS;
+ expected_awslc_name_prefix = EXPECTED_AWSLC_VERSION_PREFIX_NEW;
}
RESULT_GUARD(s2n_libcrypto_validate_expected_version_prefix(expected_awslc_name_prefix));
} else if (s2n_libcrypto_is_boringssl()) {
diff --git a/contrib/restricted/aws/s2n/pq-crypto/README.md b/contrib/restricted/aws/s2n/pq-crypto/README.md
index f798ccc2c1..3e1c0d0543 100644
--- a/contrib/restricted/aws/s2n/pq-crypto/README.md
+++ b/contrib/restricted/aws/s2n/pq-crypto/README.md
@@ -49,9 +49,9 @@ variable before compiling.
1. Add fuzz testing in `tests/fuzz/s2n_KEM_NAME_fuzz_test.c`
1. Add formal verification in `tests/saw/KEM_NAME/verify.saw`
1. Create a new `s2n_cipher_suite` in `tls/s2n_cipher_suites.c`
-1. Create a new `s2n_cipher_preferences` in `tls/s2n_cipher_prefrences.c` that uses the new cipher suite
+1. Create a new `s2n_cipher_preferences` in `tls/s2n_cipher_preferences.c` that uses the new cipher suite
1. Once this change is made, the KEM will be available for use in TLS handshakes; ensure that all testing/verification has been completed
-
+
## How to add a new variant to an existing PQ KEM family for use in hybrid TLS 1.2
1. Add the code to `pq-crypto/KEM_NAME/`
1. Update `pq-crypto/Makefile` to build that directory
@@ -64,7 +64,7 @@ variable before compiling.
1. Add fuzz testing in `tests/fuzz/s2n_KEM_NAME_fuzz_test.c`
1. Add formal verification in `tests/saw/KEM_NAME/verify.saw`
1. Update the appropriate `supported_KEM_NAME_params` array in `tls/s2n_kem.c`
- 1. Once this change is made, the KEM extension will be available for use in TLS handshakes; ensure that all testing/verification has been completed
+ 1. Once this change is made, the KEM extension will be available for use in TLS handshakes; ensure that all testing/verification has been completed
## How to use PQ cipher suites for hybrid TLS 1.2
1. Checkout s2n `git clone https://github.com/awslabs/s2n.git`
diff --git a/contrib/restricted/aws/s2n/tls/s2n_alerts.c b/contrib/restricted/aws/s2n/tls/s2n_alerts.c
index 4e1ea5f31a..1ca06577d5 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_alerts.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_alerts.c
@@ -168,7 +168,7 @@ S2N_RESULT s2n_alerts_close_if_fatal(struct s2n_connection *conn, struct s2n_blo
RESULT_ENSURE_EQ(alert->data[0], S2N_TLS_ALERT_LEVEL_WARNING);
return S2N_RESULT_OK;
}
- conn->closing = true;
+ conn->write_closing = 1;
return S2N_RESULT_OK;
}
@@ -220,7 +220,7 @@ int s2n_process_alert_fragment(struct s2n_connection *conn)
if (s2n_stuffer_data_available(&conn->alert_in) == 2) {
/* Close notifications are handled as shutdowns */
if (conn->alert_in_data[1] == S2N_TLS_ALERT_CLOSE_NOTIFY) {
- conn->closed = 1;
+ conn->read_closed = 1;
conn->close_notify_received = true;
return 0;
}
@@ -237,7 +237,7 @@ int s2n_process_alert_fragment(struct s2n_connection *conn)
}
/* All other alerts are treated as fatal errors */
- conn->closed = 1;
+ POSIX_GUARD_RESULT(s2n_connection_set_closed(conn));
POSIX_BAIL(S2N_ERR_ALERT);
}
}
@@ -256,8 +256,8 @@ int s2n_queue_writer_close_alert_warning(struct s2n_connection *conn)
struct s2n_blob out = { 0 };
POSIX_GUARD(s2n_blob_init(&out, alert, sizeof(alert)));
- /* If there is an alert pending or we've already sent a close_notify, do nothing */
- if (s2n_stuffer_data_available(&conn->writer_alert_out) || conn->close_notify_queued) {
+ /* If there is an alert pending, do nothing */
+ if (s2n_stuffer_data_available(&conn->writer_alert_out)) {
return S2N_SUCCESS;
}
@@ -266,7 +266,6 @@ int s2n_queue_writer_close_alert_warning(struct s2n_connection *conn)
}
POSIX_GUARD(s2n_stuffer_write(&conn->writer_alert_out, &out));
- conn->close_notify_queued = 1;
return S2N_SUCCESS;
}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_cipher_suites.c b/contrib/restricted/aws/s2n/tls/s2n_cipher_suites.c
index 84e0c94d02..e9c38dc0a6 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_cipher_suites.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_cipher_suites.c
@@ -1210,7 +1210,6 @@ static int s2n_set_cipher_as_server(struct s2n_connection *conn, uint8_t *wire,
if (conn->client_protocol_version < conn->server_protocol_version) {
uint8_t fallback_scsv[S2N_TLS_CIPHER_SUITE_LEN] = { TLS_FALLBACK_SCSV };
if (s2n_wire_ciphers_contain(fallback_scsv, wire, count, cipher_suite_len)) {
- conn->closed = 1;
POSIX_BAIL(S2N_ERR_FALLBACK_DETECTED);
}
}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_config.c b/contrib/restricted/aws/s2n/tls/s2n_config.c
index 9545defa4c..6420766352 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_config.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_config.c
@@ -402,7 +402,7 @@ int s2n_config_set_alert_behavior(struct s2n_config *config, s2n_alert_behavior
int s2n_config_set_verify_host_callback(struct s2n_config *config, s2n_verify_host_fn verify_host_fn, void *data)
{
POSIX_ENSURE_REF(config);
- config->verify_host = verify_host_fn;
+ config->verify_host_fn = verify_host_fn;
config->data_for_verify_host = data;
return 0;
}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_config.h b/contrib/restricted/aws/s2n/tls/s2n_config.h
index 16eaba6183..82588b780d 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_config.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_config.h
@@ -146,7 +146,7 @@ struct s2n_config {
/* Return TRUE if the host should be trusted, If FALSE this will likely be called again for every host/alternative name
* in the certificate. If any respond TRUE. If none return TRUE, the cert will be considered untrusted. */
- uint8_t (*verify_host)(const char *host_name, size_t host_name_len, void *data);
+ s2n_verify_host_fn verify_host_fn;
void *data_for_verify_host;
s2n_crl_lookup_callback crl_lookup_cb;
diff --git a/contrib/restricted/aws/s2n/tls/s2n_connection.c b/contrib/restricted/aws/s2n/tls/s2n_connection.c
index 16d1c19850..07768e2075 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_connection.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_connection.c
@@ -306,8 +306,8 @@ int s2n_connection_set_config(struct s2n_connection *conn, struct s2n_config *co
} else {
POSIX_GUARD(s2n_x509_validator_init(&conn->x509_validator, &config->trust_store, config->check_ocsp));
if (!conn->verify_host_fn_overridden) {
- if (config->verify_host != NULL) {
- conn->verify_host_fn = config->verify_host;
+ if (config->verify_host_fn != NULL) {
+ conn->verify_host_fn = config->verify_host_fn;
conn->data_for_verify_host = config->data_for_verify_host;
} else {
conn->verify_host_fn = s2n_default_verify_host;
@@ -1093,6 +1093,35 @@ uint64_t s2n_connection_get_delay(struct s2n_connection *conn)
return conn->delay - elapsed;
}
+static S2N_RESULT s2n_connection_kill(struct s2n_connection *conn)
+{
+ RESULT_ENSURE_REF(conn);
+ RESULT_GUARD(s2n_connection_set_closed(conn));
+
+ /* Delay between 10 and 30 seconds in nanoseconds */
+ int64_t min = TEN_S, max = 3 * TEN_S;
+
+ /* Keep track of the delay so that it can be enforced */
+ uint64_t rand_delay = 0;
+ RESULT_GUARD(s2n_public_random(max - min, &rand_delay));
+
+ conn->delay = min + rand_delay;
+
+ /* Restart the write timer */
+ RESULT_GUARD(s2n_timer_start(conn->config, &conn->write_timer));
+
+ if (conn->blinding == S2N_BUILT_IN_BLINDING) {
+ struct timespec sleep_time = { .tv_sec = conn->delay / ONE_S, .tv_nsec = conn->delay % ONE_S };
+
+ int r = 0;
+ do {
+ r = nanosleep(&sleep_time, &sleep_time);
+ } while (r != 0);
+ }
+
+ return S2N_RESULT_OK;
+}
+
S2N_CLEANUP_RESULT s2n_connection_apply_error_blinding(struct s2n_connection **conn)
{
RESULT_ENSURE_REF(conn);
@@ -1126,45 +1155,23 @@ S2N_CLEANUP_RESULT s2n_connection_apply_error_blinding(struct s2n_connection **c
case S2N_ERR_CANCELLED:
case S2N_ERR_CIPHER_NOT_SUPPORTED:
case S2N_ERR_PROTOCOL_VERSION_UNSUPPORTED:
- (*conn)->closed = 1;
+ RESULT_GUARD(s2n_connection_set_closed(*conn));
break;
default:
/* Apply blinding to all other errors */
- RESULT_GUARD_POSIX(s2n_connection_kill(*conn));
+ RESULT_GUARD(s2n_connection_kill(*conn));
break;
}
return S2N_RESULT_OK;
}
-int s2n_connection_kill(struct s2n_connection *conn)
+S2N_RESULT s2n_connection_set_closed(struct s2n_connection *conn)
{
- POSIX_ENSURE_REF(conn);
-
- conn->closed = 1;
-
- /* Delay between 10 and 30 seconds in nanoseconds */
- int64_t min = TEN_S, max = 3 * TEN_S;
-
- /* Keep track of the delay so that it can be enforced */
- uint64_t rand_delay = 0;
- POSIX_GUARD_RESULT(s2n_public_random(max - min, &rand_delay));
-
- conn->delay = min + rand_delay;
-
- /* Restart the write timer */
- POSIX_GUARD_RESULT(s2n_timer_start(conn->config, &conn->write_timer));
-
- if (conn->blinding == S2N_BUILT_IN_BLINDING) {
- struct timespec sleep_time = { .tv_sec = conn->delay / ONE_S, .tv_nsec = conn->delay % ONE_S };
- int r;
-
- do {
- r = nanosleep(&sleep_time, &sleep_time);
- } while (r != 0);
- }
-
- return 0;
+ RESULT_ENSURE_REF(conn);
+ conn->read_closed = 1;
+ conn->write_closed = 1;
+ return S2N_RESULT_OK;
}
const uint8_t *s2n_connection_get_ocsp_response(struct s2n_connection *conn, uint32_t *length)
@@ -1534,3 +1541,43 @@ S2N_RESULT s2n_connection_dynamic_free_in_buffer(struct s2n_connection *conn)
return S2N_RESULT_OK;
}
+
+bool s2n_connection_check_io_status(struct s2n_connection *conn, s2n_io_status status)
+{
+ if (!conn) {
+ return false;
+ }
+
+ const bool is_full_duplex = !conn->read_closed && !conn->write_closed;
+
+ /*
+ *= https://tools.ietf.org/rfc/rfc8446#section-6.1
+ *# Note that this is a change from versions of TLS prior to TLS 1.3 in
+ *# which implementations were required to react to a "close_notify" by
+ *# discarding pending writes and sending an immediate "close_notify"
+ *# alert of their own.
+ */
+ if (s2n_connection_get_protocol_version(conn) < S2N_TLS13) {
+ switch (status) {
+ case S2N_IO_WRITABLE:
+ case S2N_IO_READABLE:
+ case S2N_IO_FULL_DUPLEX:
+ return is_full_duplex;
+ case S2N_IO_CLOSED:
+ return !is_full_duplex;
+ }
+ }
+
+ switch (status) {
+ case S2N_IO_WRITABLE:
+ return !conn->write_closed;
+ case S2N_IO_READABLE:
+ return !conn->read_closed;
+ case S2N_IO_FULL_DUPLEX:
+ return is_full_duplex;
+ case S2N_IO_CLOSED:
+ return conn->read_closed && conn->write_closed;
+ }
+
+ return false;
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_connection.h b/contrib/restricted/aws/s2n/tls/s2n_connection.h
index 60d29b6cad..e177889b63 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_connection.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_connection.h
@@ -316,21 +316,14 @@ struct s2n_connection {
uint64_t wire_bytes_out;
uint64_t early_data_bytes;
- /* Is the connection open or closed ? We use C's only
- * atomic type as both the reader and the writer threads
- * may declare a connection closed.
+ /* Is the connection open or closed?
*
- * A connection can be gracefully closed or hard-closed.
- * When gracefully closed the reader or the writer mark
- * the connection as closing, and then the writer will
- * send an alert message before closing the connection
- * and marking it as closed.
- *
- * A hard-close goes straight to closed with no alert
- * message being sent.
+ * We use C's only atomic type as an error requires shutting down both read
+ * and write, so both the reader and writer threads may access both fields.
*/
- sig_atomic_t closing;
- sig_atomic_t closed;
+ sig_atomic_t read_closed;
+ sig_atomic_t write_closing;
+ sig_atomic_t write_closed;
/* TLS extension data */
char server_name[S2N_MAX_SERVER_NAME + 1];
@@ -405,8 +398,14 @@ S2N_CLEANUP_RESULT s2n_connection_ptr_free(struct s2n_connection **s2n_connectio
int s2n_connection_is_managed_corked(const struct s2n_connection *s2n_connection);
int s2n_connection_is_client_auth_enabled(struct s2n_connection *s2n_connection);
-/* Kill a bad connection */
-int s2n_connection_kill(struct s2n_connection *conn);
+typedef enum {
+ S2N_IO_WRITABLE,
+ S2N_IO_READABLE,
+ S2N_IO_FULL_DUPLEX,
+ S2N_IO_CLOSED,
+} s2n_io_status;
+bool s2n_connection_check_io_status(struct s2n_connection *conn, s2n_io_status status);
+S2N_RESULT s2n_connection_set_closed(struct s2n_connection *conn);
/* Send/recv a stuffer to/from a connection */
int s2n_connection_send_stuffer(struct s2n_stuffer *stuffer, struct s2n_connection *conn, uint32_t len);
diff --git a/contrib/restricted/aws/s2n/tls/s2n_handshake_io.c b/contrib/restricted/aws/s2n/tls/s2n_handshake_io.c
index efc92eb625..6bc5d16d12 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_handshake_io.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_handshake_io.c
@@ -1622,10 +1622,7 @@ int s2n_negotiate_impl(struct s2n_connection *conn, s2n_blocked_status *blocked)
/* Flush any pending I/O or alert messages */
POSIX_GUARD(s2n_flush(conn, blocked));
- /* If the connection is closed, the handshake will never complete. */
- if (conn->closed) {
- POSIX_BAIL(S2N_ERR_CLOSED);
- }
+ POSIX_ENSURE(s2n_connection_check_io_status(conn, S2N_IO_FULL_DUPLEX), S2N_ERR_CLOSED);
/* If the handshake was paused, retry the current message */
if (conn->handshake.paused) {
diff --git a/contrib/restricted/aws/s2n/tls/s2n_recv.c b/contrib/restricted/aws/s2n/tls/s2n_recv.c
index cf267f1926..d1f04814dc 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_recv.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_recv.c
@@ -42,7 +42,7 @@ S2N_RESULT s2n_read_in_bytes(struct s2n_connection *conn, struct s2n_stuffer *ou
errno = 0;
int r = s2n_connection_recv_stuffer(output, conn, remaining);
if (r == 0) {
- conn->closed = 1;
+ conn->read_closed = 1;
RESULT_BAIL(S2N_ERR_CLOSED);
} else if (r < 0) {
if (errno == EWOULDBLOCK || errno == EAGAIN) {
@@ -114,7 +114,7 @@ ssize_t s2n_recv_impl(struct s2n_connection *conn, void *buf, ssize_t size, s2n_
struct s2n_blob out = { 0 };
POSIX_GUARD(s2n_blob_init(&out, (uint8_t *) buf, 0));
- if (conn->closed) {
+ if (!s2n_connection_check_io_status(conn, S2N_IO_READABLE)) {
return 0;
}
*blocked = S2N_BLOCKED_ON_READ;
@@ -122,7 +122,7 @@ ssize_t s2n_recv_impl(struct s2n_connection *conn, void *buf, ssize_t size, s2n_
POSIX_ENSURE(!s2n_connection_is_quic_enabled(conn), S2N_ERR_UNSUPPORTED_WITH_QUIC);
POSIX_GUARD_RESULT(s2n_early_data_validate_recv(conn));
- while (size && !conn->closed) {
+ while (size && s2n_connection_check_io_status(conn, S2N_IO_READABLE)) {
int isSSLv2 = 0;
uint8_t record_type;
int r = s2n_read_full_record(conn, &record_type, &isSSLv2);
@@ -174,7 +174,6 @@ ssize_t s2n_recv_impl(struct s2n_connection *conn, void *buf, ssize_t size, s2n_
switch (record_type) {
case TLS_ALERT:
POSIX_GUARD(s2n_process_alert_fragment(conn));
- POSIX_GUARD(s2n_flush(conn, blocked));
break;
case TLS_HANDSHAKE: {
s2n_result result = s2n_post_handshake_recv(conn);
diff --git a/contrib/restricted/aws/s2n/tls/s2n_security_policies.c b/contrib/restricted/aws/s2n/tls/s2n_security_policies.c
index 1f51175d7c..40c410b92b 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_security_policies.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_security_policies.c
@@ -523,6 +523,42 @@ const struct s2n_security_policy security_policy_pq_tls_1_0_2023_01_24 = {
.ecc_preferences = &s2n_ecc_preferences_20200310,
};
+/* Same as security_policy_pq_tls_1_1_2021_05_21, but with TLS 1.2 as minimum */
+const struct s2n_security_policy security_policy_pq_tls_1_2_2023_04_07 = {
+ .minimum_protocol_version = S2N_TLS12,
+ .cipher_preferences = &cipher_preferences_pq_tls_1_1_2021_05_21,
+ .kem_preferences = &kem_preferences_pq_tls_1_0_2021_05,
+ .signature_preferences = &s2n_signature_preferences_20200207,
+ .ecc_preferences = &s2n_ecc_preferences_20200310,
+};
+
+/* Same as security_policy_pq_tls_1_0_2021_05_22, but with TLS 1.2 as minimum */
+const struct s2n_security_policy security_policy_pq_tls_1_2_2023_04_08 = {
+ .minimum_protocol_version = S2N_TLS12,
+ .cipher_preferences = &cipher_preferences_pq_tls_1_0_2021_05_22,
+ .kem_preferences = &kem_preferences_pq_tls_1_0_2021_05,
+ .signature_preferences = &s2n_signature_preferences_20200207,
+ .ecc_preferences = &s2n_ecc_preferences_20200310,
+};
+
+/* Same as security_policy_pq_tls_1_0_2021_05_24, but with TLS 1.2 as minimum */
+const struct s2n_security_policy security_policy_pq_tls_1_2_2023_04_09 = {
+ .minimum_protocol_version = S2N_TLS12,
+ .cipher_preferences = &cipher_preferences_pq_tls_1_0_2021_05_24,
+ .kem_preferences = &kem_preferences_pq_tls_1_0_2021_05,
+ .signature_preferences = &s2n_signature_preferences_20200207,
+ .ecc_preferences = &s2n_ecc_preferences_20200310,
+};
+
+/* Same as security_policy_pq_tls_1_0_2021_05_26, but with TLS 1.2 as minimum */
+const struct s2n_security_policy security_policy_pq_tls_1_2_2023_04_10 = {
+ .minimum_protocol_version = S2N_TLS12,
+ .cipher_preferences = &cipher_preferences_pq_tls_1_0_2021_05_26,
+ .kem_preferences = &kem_preferences_pq_tls_1_0_2021_05,
+ .signature_preferences = &s2n_signature_preferences_20200207,
+ .ecc_preferences = &s2n_ecc_preferences_20200310,
+};
+
const struct s2n_security_policy security_policy_kms_fips_tls_1_2_2018_10 = {
.minimum_protocol_version = S2N_TLS12,
.cipher_preferences = &cipher_preferences_kms_fips_tls_1_2_2018_10,
@@ -856,6 +892,10 @@ struct s2n_security_policy_selection security_policy_selection[] = {
{ .version = "PQ-TLS-1-0-2021-05-25", .security_policy = &security_policy_pq_tls_1_0_2021_05_25, .ecc_extension_required = 0, .pq_kem_extension_required = 0 },
{ .version = "PQ-TLS-1-0-2021-05-26", .security_policy = &security_policy_pq_tls_1_0_2021_05_26, .ecc_extension_required = 0, .pq_kem_extension_required = 0 },
{ .version = "PQ-TLS-1-0-2023-01-24", .security_policy = &security_policy_pq_tls_1_0_2023_01_24, .ecc_extension_required = 0, .pq_kem_extension_required = 0 },
+ { .version = "PQ-TLS-1-2-2023-04-07", .security_policy = &security_policy_pq_tls_1_2_2023_04_07, .ecc_extension_required = 0, .pq_kem_extension_required = 0 },
+ { .version = "PQ-TLS-1-2-2023-04-08", .security_policy = &security_policy_pq_tls_1_2_2023_04_08, .ecc_extension_required = 0, .pq_kem_extension_required = 0 },
+ { .version = "PQ-TLS-1-2-2023-04-09", .security_policy = &security_policy_pq_tls_1_2_2023_04_09, .ecc_extension_required = 0, .pq_kem_extension_required = 0 },
+ { .version = "PQ-TLS-1-2-2023-04-10", .security_policy = &security_policy_pq_tls_1_2_2023_04_10, .ecc_extension_required = 0, .pq_kem_extension_required = 0 },
{ .version = "20140601", .security_policy = &security_policy_20140601, .ecc_extension_required = 0, .pq_kem_extension_required = 0 },
{ .version = "20141001", .security_policy = &security_policy_20141001, .ecc_extension_required = 0, .pq_kem_extension_required = 0 },
{ .version = "20150202", .security_policy = &security_policy_20150202, .ecc_extension_required = 0, .pq_kem_extension_required = 0 },
diff --git a/contrib/restricted/aws/s2n/tls/s2n_security_policies.h b/contrib/restricted/aws/s2n/tls/s2n_security_policies.h
index ad98ab6923..367aeeb8c1 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_security_policies.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_security_policies.h
@@ -25,12 +25,49 @@
/* Kept up-to-date by s2n_security_policies_test */
#define NUM_RSA_PSS_SCHEMES 6
+/* The s2n_security_policy struct is used to define acceptable and available
+ * algorithms for use in the TLS protocol. Note that the behavior of each field
+ * likely differs between different TLS versions, as the mechanics of cipher
+ * negotiation often have significant differences between TLS versions.
+ *
+ * In s2n-tls, the signature_algorithms extension only applies to signatures in
+ * CertificateVerify messages. To specify acceptable signature algorithms for
+ * certificates the certificate_signature_preferences field should be set in the
+ * security policy.
+ */
struct s2n_security_policy {
uint8_t minimum_protocol_version;
+ /* TLS 1.0 - 1.2 - cipher preference includes multiple elements such
+ * as signature algorithms, record algorithms, and key exchange algorithms
+ * TLS 1.3 - cipher preference only determines record encryption
+ */
const struct s2n_cipher_preferences *cipher_preferences;
+ /* kem_preferences is only used for Post-Quantum cryptography */
const struct s2n_kem_preferences *kem_preferences;
+ /* This field roughly corresponds to the "signature_algorithms" extension.
+ * The client serializes this field of the security_policy to populate the
+ * extension, and it is also used by the server to choose an appropriate
+ * entry from the options supplied by the client.
+ * TLS 1.2 - optional extension to specify signature algorithms other than
+ * default: https://www.rfc-editor.org/rfc/rfc5246#section-7.4.1.4.1
+ * TLS 1.3 - required extension specifying signature algorithms
+ */
const struct s2n_signature_preferences *signature_preferences;
+ /* When this field is set, the endpoint will ensure that the signatures on
+ * the certificates in the peer's certificate chain are in the specified
+ * list. Note that s2n-tls does not support the signature_algorithms_cert
+ * extension. Unlike the signature_preferences field, this information is
+ * never transmitted to a peer.
+ */
const struct s2n_signature_preferences *certificate_signature_preferences;
+ /* This field roughly corresponds to the information in the
+ * "supported_groups" extension.
+ * TLS 1.0 - 1.2 - "elliptic_curves" extension indicates supported groups
+ * for both key exchange and signature algorithms.
+ * TLS 1.3 - the "supported_groups" extension indicates the named groups
+ * which the client supports for key exchange
+ * https://www.rfc-editor.org/rfc/rfc8446#section-4.2.7
+ */
const struct s2n_ecc_preferences *ecc_preferences;
};
@@ -109,6 +146,10 @@ extern const struct s2n_security_policy security_policy_pq_tls_1_0_2021_05_24;
extern const struct s2n_security_policy security_policy_pq_tls_1_0_2021_05_25;
extern const struct s2n_security_policy security_policy_pq_tls_1_0_2021_05_26;
extern const struct s2n_security_policy security_policy_pq_tls_1_0_2023_01_24;
+extern const struct s2n_security_policy security_policy_pq_tls_1_2_2023_04_07;
+extern const struct s2n_security_policy security_policy_pq_tls_1_2_2023_04_08;
+extern const struct s2n_security_policy security_policy_pq_tls_1_2_2023_04_09;
+extern const struct s2n_security_policy security_policy_pq_tls_1_2_2023_04_10;
extern const struct s2n_security_policy security_policy_cloudfront_upstream;
extern const struct s2n_security_policy security_policy_cloudfront_upstream_tls10;
diff --git a/contrib/restricted/aws/s2n/tls/s2n_send.c b/contrib/restricted/aws/s2n/tls/s2n_send.c
index 34d7a8f613..4fea390c88 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_send.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_send.c
@@ -98,8 +98,8 @@ WRITE:
conn->wire_bytes_out += w;
}
- if (conn->closing) {
- conn->closed = 1;
+ if (conn->write_closing) {
+ conn->write_closed = 1;
}
POSIX_GUARD(s2n_stuffer_rewrite(&conn->out));
@@ -139,7 +139,7 @@ ssize_t s2n_sendv_with_offset_impl(struct s2n_connection *conn, const struct iov
{
ssize_t user_data_sent, total_size = 0;
- POSIX_ENSURE(!conn->closed, S2N_ERR_CLOSED);
+ 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);
/* Flush any pending I/O */
diff --git a/contrib/restricted/aws/s2n/tls/s2n_shutdown.c b/contrib/restricted/aws/s2n/tls/s2n_shutdown.c
index 3a89221375..4afe783d61 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_shutdown.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_shutdown.c
@@ -19,6 +19,21 @@
#include "tls/s2n_tls.h"
#include "utils/s2n_safety.h"
+static bool s2n_is_close_notify_required(struct s2n_connection *conn)
+{
+ /* We only send one close_notify */
+ if (conn->close_notify_queued) {
+ return false;
+ }
+ /* We don't send a close_notify if an error alert was already sent.
+ * Sending an error alert always sets conn->closing: see s2n_flush.
+ */
+ if (conn->write_closing) {
+ return false;
+ }
+ return true;
+}
+
int s2n_shutdown(struct s2n_connection *conn, s2n_blocked_status *blocked)
{
POSIX_ENSURE_REF(conn);
@@ -33,14 +48,20 @@ int s2n_shutdown(struct s2n_connection *conn, s2n_blocked_status *blocked)
POSIX_GUARD_RESULT(s2n_timer_elapsed(conn->config, &conn->write_timer, &elapsed));
S2N_ERROR_IF(elapsed < conn->delay, S2N_ERR_SHUTDOWN_PAUSED);
- /* Queue our close_notify alert.
- * If we have already sent a close_notify, then this operation is a no-op.
- */
- POSIX_GUARD(s2n_queue_writer_close_alert_warning(conn));
-
- /* Flush any pending records, then send the queued close_notify. */
+ /* Flush any outstanding data or alerts */
POSIX_GUARD(s2n_flush(conn, blocked));
+ /**
+ *= https://tools.ietf.org/rfc/rfc8446#section-6.1
+ *# Each party MUST send a "close_notify" alert before closing its write
+ *# side of the connection, unless it has already sent some error alert.
+ */
+ if (s2n_is_close_notify_required(conn)) {
+ POSIX_GUARD(s2n_queue_writer_close_alert_warning(conn));
+ conn->close_notify_queued = 1;
+ POSIX_GUARD(s2n_flush(conn, blocked));
+ }
+
/*
* The purpose of the peer responding to our close_notify
* with its own close_notify is to prevent application data truncation.
@@ -51,6 +72,7 @@ int s2n_shutdown(struct s2n_connection *conn, s2n_blocked_status *blocked)
* and unnecessary blinding.
*/
if (!s2n_handshake_is_complete(conn)) {
+ POSIX_GUARD_RESULT(s2n_connection_set_closed(conn));
return S2N_SUCCESS;
}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_x509_validator.c b/contrib/restricted/aws/s2n/tls/s2n_x509_validator.c
index 3f63c81fa0..78fdb3fbb2 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_x509_validator.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_x509_validator.c
@@ -354,11 +354,26 @@ static S2N_RESULT s2n_verify_host_information(struct s2n_connection *conn, X509
/* Check SubjectAltNames before CommonName as per RFC 6125 6.4.4 */
s2n_result result = s2n_verify_host_information_san(conn, public_cert, &entry_found);
+
+ /*
+ *= https://www.rfc-editor.org/rfc/rfc6125#section-6.4.4
+ *# As noted, a client MUST NOT seek a match for a reference identifier
+ *# of CN-ID if the presented identifiers include a DNS-ID, SRV-ID,
+ *# URI-ID, or any application-specific identifier types supported by the
+ *# client.
+ */
if (entry_found) {
return result;
}
- /* if no SubjectAltNames of type DNS found, go to the common name. */
+ /*
+ *= https://www.rfc-editor.org/rfc/rfc6125#section-6.4.4
+ *# Therefore, if and only if the presented identifiers do not include a
+ *# DNS-ID, SRV-ID, URI-ID, or any application-specific identifier types
+ *# supported by the client, then the client MAY as a last resort check
+ *# for a string whose form matches that of a fully qualified DNS domain
+ *# name in a Common Name field of the subject field (i.e., a CN-ID).
+ */
result = s2n_verify_host_information_common_name(conn, public_cert, &entry_found);
if (entry_found) {
return result;
@@ -717,6 +732,30 @@ S2N_RESULT s2n_validate_certificate_signature(struct s2n_connection *conn, X509
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;
}