aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/restricted/aws/s2n
diff options
context:
space:
mode:
authorrobot-contrib <robot-contrib@yandex-team.com>2022-11-07 16:54:51 +0300
committerrobot-contrib <robot-contrib@yandex-team.com>2022-11-07 16:54:51 +0300
commit9ca5282bca79550f17a48f7aef639f0e6d477b2c (patch)
tree6b03d26c014c76bea0c1743e7f03dd066023b72e /contrib/restricted/aws/s2n
parent964584075fe8d2284078222e1e7e2e424c8bd9a1 (diff)
downloadydb-9ca5282bca79550f17a48f7aef639f0e6d477b2c.tar.gz
Update contrib/restricted/aws/s2n to 1.3.25
Diffstat (limited to 'contrib/restricted/aws/s2n')
-rw-r--r--contrib/restricted/aws/s2n/CMakeLists.darwin.txt2
-rw-r--r--contrib/restricted/aws/s2n/CMakeLists.linux-aarch64.txt2
-rw-r--r--contrib/restricted/aws/s2n/CMakeLists.linux.txt2
-rw-r--r--contrib/restricted/aws/s2n/api/s2n.h2
-rw-r--r--contrib/restricted/aws/s2n/api/unstable/renegotiate.h145
-rw-r--r--contrib/restricted/aws/s2n/error/s2n_errno.c1
-rw-r--r--contrib/restricted/aws/s2n/error/s2n_errno.h1
-rw-r--r--contrib/restricted/aws/s2n/pq-crypto/kyber_r3/kyber512r3_cbd.c4
-rw-r--r--contrib/restricted/aws/s2n/pq-crypto/kyber_r3/kyber512r3_fips202.c4
-rw-r--r--contrib/restricted/aws/s2n/pq-crypto/kyber_r3/kyber512r3_indcpa.c4
-rw-r--r--contrib/restricted/aws/s2n/pq-crypto/kyber_r3/kyber512r3_kem.c4
-rw-r--r--contrib/restricted/aws/s2n/pq-crypto/kyber_r3/kyber512r3_ntt.c4
-rw-r--r--contrib/restricted/aws/s2n/pq-crypto/kyber_r3/kyber512r3_poly.c4
-rw-r--r--contrib/restricted/aws/s2n/pq-crypto/kyber_r3/kyber512r3_polyvec.c4
-rw-r--r--contrib/restricted/aws/s2n/pq-crypto/kyber_r3/kyber512r3_reduce.c4
-rw-r--r--contrib/restricted/aws/s2n/pq-crypto/s2n_pq_asm.h11
-rw-r--r--contrib/restricted/aws/s2n/stuffer/s2n_stuffer.h3
-rw-r--r--contrib/restricted/aws/s2n/stuffer/s2n_stuffer_pem.c5
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_client_renegotiation_info.c114
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_extension_list.h1
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type.h1
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type_lists.c8
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_npn.c98
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_npn.h1
-rw-r--r--contrib/restricted/aws/s2n/tls/extensions/s2n_server_renegotiation_info.c83
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_alerts.c12
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_cipher_suites.c20
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_client_hello_request.c15
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_config.c5
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_crl.c88
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_crl.h31
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_handshake.c3
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_handshake_io.c23
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_renegotiate.c73
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_renegotiate.h10
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_tls.h2
-rw-r--r--contrib/restricted/aws/s2n/tls/s2n_tls12_encrypted_extensions.c41
37 files changed, 764 insertions, 71 deletions
diff --git a/contrib/restricted/aws/s2n/CMakeLists.darwin.txt b/contrib/restricted/aws/s2n/CMakeLists.darwin.txt
index dd09fdecd4..b3c337c78b 100644
--- a/contrib/restricted/aws/s2n/CMakeLists.darwin.txt
+++ b/contrib/restricted/aws/s2n/CMakeLists.darwin.txt
@@ -139,6 +139,7 @@ target_sources(restricted-aws-s2n PRIVATE
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_client_key_exchange.c
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_config.c
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_connection.c
+ ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_crl.c
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_crypto.c
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_early_data.c
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_early_data_io.c
@@ -185,6 +186,7 @@ target_sources(restricted-aws-s2n PRIVATE
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_signature_algorithms.c
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_signature_scheme.c
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_tls.c
+ ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_tls12_encrypted_extensions.c
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_tls13.c
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_tls13_certificate_verify.c
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_tls13_handshake.c
diff --git a/contrib/restricted/aws/s2n/CMakeLists.linux-aarch64.txt b/contrib/restricted/aws/s2n/CMakeLists.linux-aarch64.txt
index 9e3cb12f6f..c10014f87f 100644
--- a/contrib/restricted/aws/s2n/CMakeLists.linux-aarch64.txt
+++ b/contrib/restricted/aws/s2n/CMakeLists.linux-aarch64.txt
@@ -133,6 +133,7 @@ target_sources(restricted-aws-s2n PRIVATE
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_client_key_exchange.c
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_config.c
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_connection.c
+ ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_crl.c
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_crypto.c
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_early_data.c
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_early_data_io.c
@@ -179,6 +180,7 @@ target_sources(restricted-aws-s2n PRIVATE
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_signature_algorithms.c
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_signature_scheme.c
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_tls.c
+ ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_tls12_encrypted_extensions.c
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_tls13.c
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_tls13_certificate_verify.c
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_tls13_handshake.c
diff --git a/contrib/restricted/aws/s2n/CMakeLists.linux.txt b/contrib/restricted/aws/s2n/CMakeLists.linux.txt
index f22ac9bb39..504c30980d 100644
--- a/contrib/restricted/aws/s2n/CMakeLists.linux.txt
+++ b/contrib/restricted/aws/s2n/CMakeLists.linux.txt
@@ -140,6 +140,7 @@ target_sources(restricted-aws-s2n PRIVATE
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_client_key_exchange.c
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_config.c
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_connection.c
+ ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_crl.c
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_crypto.c
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_early_data.c
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_early_data_io.c
@@ -186,6 +187,7 @@ target_sources(restricted-aws-s2n PRIVATE
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_signature_algorithms.c
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_signature_scheme.c
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_tls.c
+ ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_tls12_encrypted_extensions.c
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_tls13.c
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_tls13_certificate_verify.c
${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_tls13_handshake.c
diff --git a/contrib/restricted/aws/s2n/api/s2n.h b/contrib/restricted/aws/s2n/api/s2n.h
index c555b1bc2f..7e2e6581c8 100644
--- a/contrib/restricted/aws/s2n/api/s2n.h
+++ b/contrib/restricted/aws/s2n/api/s2n.h
@@ -1854,7 +1854,7 @@ typedef enum {
*
* @param conn A pointer to the s2n_connection object
* @param blocked A pointer which will be set to the blocked status.
- * @returns The number of bytes written, and may indicate a partial write
+ * @returns S2N_SUCCESS if the handshake completed. S2N_FAILURE if the handshake encountered an error or is blocked.
*/
S2N_API
extern int s2n_negotiate(struct s2n_connection *conn, s2n_blocked_status *blocked);
diff --git a/contrib/restricted/aws/s2n/api/unstable/renegotiate.h b/contrib/restricted/aws/s2n/api/unstable/renegotiate.h
new file mode 100644
index 0000000000..c605988cb8
--- /dev/null
+++ b/contrib/restricted/aws/s2n/api/unstable/renegotiate.h
@@ -0,0 +1,145 @@
+/*
+ * 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 <s2n.h>
+
+/**
+ * @file renegotiate.h
+ *
+ * "Renegotiation" is a TLS feature offered in TLS1.2 and earlier.
+ * During renegotiation, a new handshake is performed on an already established
+ * connection. The new handshake is encrypted using the keys from the original handshake.
+ * The new handshake may not match the first handshake; for example, the server may choose
+ * a different cipher suite or require client authentication for the new handshake.
+ *
+ * s2n-tls clients support secure (compliant with RFC5746) renegotiation for compatibility reasons,
+ * but s2n-tls does NOT recommend its use. While s2n-tls addresses all currently known security concerns,
+ * renegotiation has appeared in many CVEs and was completely removed from TLS1.3.
+ */
+
+/**
+ * Used to indicate that an attempt to renegotiate encountered
+ * application data which the application should process before
+ * continuing the handshake.
+ */
+extern const s2n_blocked_status S2N_BLOCKED_ON_APPLICATION_DATA;
+
+/**
+ * Indicates how a renegotiation request should be handled.
+ */
+typedef enum {
+ /* The client will take no action */
+ S2N_RENEGOTIATE_IGNORE = 0,
+ /* The client will send a warning alert to the server */
+ S2N_RENEGOTIATE_REJECT,
+ /* The client will begin renegotiation in the future */
+ S2N_RENEGOTIATE_ACCEPT,
+} s2n_renegotiate_response;
+
+/**
+ * Callback function to handle requests for renegotiation.
+ *
+ * s2n-tls calls this method when a client receives a request from the server
+ * to renegotiate the connection. If the server makes multiple requests,
+ * s2n-tls will call this method multiple times.
+ *
+ * Applications should use the `response` value to indicate how the request
+ * should be handled. If `response` is set to `S2N_RENEGOTIATE_IGNORE`
+ * or `S2N_RENEGOTIATE_REJECT`, no further application involvement is required.
+ *
+ * If `response` is set to `S2N_RENEGOTIATE_ACCEPT`, then the application should
+ * handle renegotiation. The application should stop calling s2n_send and s2n_recv,
+ * wipe the connection with s2n_renegotiate_wipe, and then call s2n_renegotiate
+ * until the handshake is complete.
+ *
+ * @param conn A pointer to the connection object.
+ * @param context Context for the callback function.
+ * @param response How the request should be handled.
+ * @returns S2N_SUCCESS on success, S2N_FAILURE on error.
+ */
+typedef int (*s2n_renegotiate_request_cb)(struct s2n_connection *conn, void *context, s2n_renegotiate_response *response);
+
+/**
+ * Sets a method to be called when the client receives a request to renegotiate.
+ *
+ * @param config A pointer to the config object.
+ * @param callback The function to be called when a renegotiation request is received.
+ * @param context Context to be passed to the callback function.
+ * @returns S2N_SUCCESS on success, S2N_FAILURE on error.
+ */
+S2N_API
+int s2n_config_set_renegotiate_request_cb(struct s2n_config *config, s2n_renegotiate_request_cb callback, void *context);
+
+/**
+ * Reset the connection so that it can be renegotiated.
+ *
+ * Similar to `s2n_connection_wipe`, this method resets a connection so that it can be used again.
+ * However, unlike `s2n_connection_wipe`, it retains enough state from the previous connection
+ * that the connection can continue to send and receive data encrypted with the old keys.
+ *
+ * The application MUST handle any incomplete IO before calling this method. The last call to `s2n_send` must
+ * have succeeded, and `s2n_peek` must return zero. If there is any data in the send or receive buffers,
+ * this method will fail.
+ *
+ * The application MUST repeat any connection-specific setup after calling this method. This method
+ * cannot distinguish between internal connection state and configuration state set by the application,
+ * so it wipes all state not directly related to handling encrypted records. For example,
+ * if the application originally called `s2n_connection_set_blinding` on the connection,
+ * then the application will need to call `s2n_connection_set_blinding` again after `s2n_renegotiate_wipe`.
+ *
+ * The connection-specific setup methods the application does not need to call again are:
+ * - Methods to set the file descriptors
+ * (`s2n_connection_set_fd`, `s2n_connection_set_read_fd`, `s2n_connection_set_write_fd`)
+ * - Methods to set the send callback
+ * (`s2n_connection_set_send_cb`, `s2n_connection_set_send_ctx`)
+ * - Methods to set the recv callback
+ * (`s2n_connection_set_recv_cb`, `s2n_connection_set_recv_ctx`)
+ *
+ * @note This method MUST be called before s2n_renegotiate.
+ * @note Calling this method on a server connection will fail. s2n-tls servers do not support renegotiation.
+ *
+ * @param conn A pointer to the connection object.
+ * @returns S2N_SUCCESS on success, S2N_FAILURE on error.
+ */
+S2N_API
+int s2n_renegotiate_wipe(struct s2n_connection *conn);
+
+/**
+ * Perform a new handshake on an already established connection.
+ *
+ * This method should be called like `s2n_negotiate`, with the same handling of return values,
+ * error types, and blocked statuses.
+ *
+ * However, unlike the initial handshake performed by `s2n_negotiate`, the renegotiation
+ * handshake can encounter valid application data. In that case, this method will fail
+ * with an error of type S2N_ERR_T_BLOCKED, set the `blocked` field to `S2N_BLOCKED_ON_APPLICATION_DATA`,
+ * copy the data to `app_data_buf`, and set `app_data_size` to the size of the data.
+ * The application should handle the data in `app_data_buf` before calling s2n_renegotiate again.
+ *
+ * @note s2n_renegotiate_wipe MUST be called before this method.
+ * @note Calling this method on a server connection will fail. s2n-tls servers do not support renegotiation.
+ *
+ * @param conn A pointer to the connection object.
+ * @param app_data_buf A pointer to a buffer that s2n will copy application data read into.
+ * @param app_data_buf_size The size of `app_data_buf`.
+ * @param app_data_size The number of application data bytes read.
+ * @param blocked A pointer which will be set to the blocked status.
+ * @returns S2N_SUCCESS if the handshake completed. S2N_FAILURE if the handshake encountered an error or is blocked.
+ */
+S2N_API
+int s2n_renegotiate(struct s2n_connection *conn, uint8_t *app_data_buf, ssize_t app_data_buf_size,
+ ssize_t *app_data_size, s2n_blocked_status *blocked);
diff --git a/contrib/restricted/aws/s2n/error/s2n_errno.c b/contrib/restricted/aws/s2n/error/s2n_errno.c
index 816b76780e..ce77f9f315 100644
--- a/contrib/restricted/aws/s2n/error/s2n_errno.c
+++ b/contrib/restricted/aws/s2n/error/s2n_errno.c
@@ -278,6 +278,7 @@ static const char *no_such_error = "Internal s2n error";
ERR_ENTRY(S2N_ERR_CERT_OWNERSHIP, "The ownership of the certificate chain is incompatible with the operation") \
ERR_ENTRY(S2N_ERR_INTERNAL_LIBCRYPTO_ERROR, "An internal error has occurred in the libcrypto API") \
ERR_ENTRY(S2N_ERR_NO_RENEGOTIATION, "Only secure, server-initiated renegotiation is supported") \
+ ERR_ENTRY(S2N_ERR_APP_DATA_BLOCKED, "Blocked on application data during handshake") \
/* clang-format on */
#define ERR_STR_CASE(ERR, str) case ERR: return str;
diff --git a/contrib/restricted/aws/s2n/error/s2n_errno.h b/contrib/restricted/aws/s2n/error/s2n_errno.h
index 17482e6033..40eebfa157 100644
--- a/contrib/restricted/aws/s2n/error/s2n_errno.h
+++ b/contrib/restricted/aws/s2n/error/s2n_errno.h
@@ -59,6 +59,7 @@ typedef enum {
S2N_ERR_IO_BLOCKED = S2N_ERR_T_BLOCKED_START,
S2N_ERR_ASYNC_BLOCKED,
S2N_ERR_EARLY_DATA_BLOCKED,
+ S2N_ERR_APP_DATA_BLOCKED,
S2N_ERR_T_BLOCKED_END,
/* S2N_ERR_T_ALERT */
diff --git a/contrib/restricted/aws/s2n/pq-crypto/kyber_r3/kyber512r3_cbd.c b/contrib/restricted/aws/s2n/pq-crypto/kyber_r3/kyber512r3_cbd.c
index 72f2941683..82acdb30f8 100644
--- a/contrib/restricted/aws/s2n/pq-crypto/kyber_r3/kyber512r3_cbd.c
+++ b/contrib/restricted/aws/s2n/pq-crypto/kyber_r3/kyber512r3_cbd.c
@@ -2,9 +2,7 @@
#include "kyber512r3_params.h"
#include "kyber512r3_cbd.h"
-#if S2N_ANY_NONPORTABLE_OPTIMIZATIONS_ENABLED
-#error "Compiling portable code with non-portable assembly optimizations is not allowed"
-#endif
+S2N_ENSURE_PORTABLE_OPTIMIZATIONS
/*************************************************
* Name: load32_littleendian
diff --git a/contrib/restricted/aws/s2n/pq-crypto/kyber_r3/kyber512r3_fips202.c b/contrib/restricted/aws/s2n/pq-crypto/kyber_r3/kyber512r3_fips202.c
index b9f7fbaea8..3632963ed8 100644
--- a/contrib/restricted/aws/s2n/pq-crypto/kyber_r3/kyber512r3_fips202.c
+++ b/contrib/restricted/aws/s2n/pq-crypto/kyber_r3/kyber512r3_fips202.c
@@ -14,9 +14,7 @@
#define NROUNDS 24
#define ROL(a, offset) (((a) << (offset)) ^ ((a) >> (64 - (offset))))
-#if S2N_ANY_NONPORTABLE_OPTIMIZATIONS_ENABLED
-#error "Compiling portable code with non-portable assembly optimizations is not allowed"
-#endif
+S2N_ENSURE_PORTABLE_OPTIMIZATIONS
/*************************************************
* Name: load64
diff --git a/contrib/restricted/aws/s2n/pq-crypto/kyber_r3/kyber512r3_indcpa.c b/contrib/restricted/aws/s2n/pq-crypto/kyber_r3/kyber512r3_indcpa.c
index 5b03bc7cff..bbb77259df 100644
--- a/contrib/restricted/aws/s2n/pq-crypto/kyber_r3/kyber512r3_indcpa.c
+++ b/contrib/restricted/aws/s2n/pq-crypto/kyber_r3/kyber512r3_indcpa.c
@@ -9,9 +9,7 @@
#include "pq-crypto/s2n_pq_random.h"
#include "utils/s2n_safety.h"
-#if S2N_ANY_NONPORTABLE_OPTIMIZATIONS_ENABLED
-#error "Compiling portable code with non-portable assembly optimizations is not allowed"
-#endif
+S2N_ENSURE_PORTABLE_OPTIMIZATIONS
/*************************************************
* Name: pack_pk
diff --git a/contrib/restricted/aws/s2n/pq-crypto/kyber_r3/kyber512r3_kem.c b/contrib/restricted/aws/s2n/pq-crypto/kyber_r3/kyber512r3_kem.c
index d5d1dd22be..e35b3df805 100644
--- a/contrib/restricted/aws/s2n/pq-crypto/kyber_r3/kyber512r3_kem.c
+++ b/contrib/restricted/aws/s2n/pq-crypto/kyber_r3/kyber512r3_kem.c
@@ -9,9 +9,7 @@
#include "pq-crypto/s2n_pq_random.h"
#include "pq-crypto/s2n_pq.h"
-#if S2N_ANY_NONPORTABLE_OPTIMIZATIONS_ENABLED
-#error "Compiling portable code with non-portable assembly optimizations is not allowed"
-#endif
+S2N_ENSURE_PORTABLE_OPTIMIZATIONS
/*************************************************
* Name: crypto_kem_keypair
diff --git a/contrib/restricted/aws/s2n/pq-crypto/kyber_r3/kyber512r3_ntt.c b/contrib/restricted/aws/s2n/pq-crypto/kyber_r3/kyber512r3_ntt.c
index 921f6ffc2c..c38147bafe 100644
--- a/contrib/restricted/aws/s2n/pq-crypto/kyber_r3/kyber512r3_ntt.c
+++ b/contrib/restricted/aws/s2n/pq-crypto/kyber_r3/kyber512r3_ntt.c
@@ -3,9 +3,7 @@
#include "kyber512r3_ntt.h"
#include "kyber512r3_reduce.h"
-#if S2N_ANY_NONPORTABLE_OPTIMIZATIONS_ENABLED
-#error "Compiling portable code with non-portable assembly optimizations is not allowed"
-#endif
+S2N_ENSURE_PORTABLE_OPTIMIZATIONS
const int16_t zetas[128] = {
2285, 2571, 2970, 1812, 1493, 1422, 287, 202, 3158, 622, 1577, 182, 962,
diff --git a/contrib/restricted/aws/s2n/pq-crypto/kyber_r3/kyber512r3_poly.c b/contrib/restricted/aws/s2n/pq-crypto/kyber_r3/kyber512r3_poly.c
index 3cc392b0d4..61a725ec44 100644
--- a/contrib/restricted/aws/s2n/pq-crypto/kyber_r3/kyber512r3_poly.c
+++ b/contrib/restricted/aws/s2n/pq-crypto/kyber_r3/kyber512r3_poly.c
@@ -6,9 +6,7 @@
#include "kyber512r3_cbd.h"
#include "kyber512r3_symmetric.h"
-#if S2N_ANY_NONPORTABLE_OPTIMIZATIONS_ENABLED
-#error "Compiling portable code with non-portable assembly optimizations is not allowed"
-#endif
+S2N_ENSURE_PORTABLE_OPTIMIZATIONS
/*************************************************
* Name: poly_compress
diff --git a/contrib/restricted/aws/s2n/pq-crypto/kyber_r3/kyber512r3_polyvec.c b/contrib/restricted/aws/s2n/pq-crypto/kyber_r3/kyber512r3_polyvec.c
index 9800da93e7..fb3b54f8cc 100644
--- a/contrib/restricted/aws/s2n/pq-crypto/kyber_r3/kyber512r3_polyvec.c
+++ b/contrib/restricted/aws/s2n/pq-crypto/kyber_r3/kyber512r3_polyvec.c
@@ -3,9 +3,7 @@
#include "kyber512r3_poly.h"
#include "kyber512r3_polyvec.h"
-#if S2N_ANY_NONPORTABLE_OPTIMIZATIONS_ENABLED
-#error "Compiling portable code with non-portable assembly optimizations is not allowed"
-#endif
+S2N_ENSURE_PORTABLE_OPTIMIZATIONS
/*************************************************
* Name: polyvec_compress
diff --git a/contrib/restricted/aws/s2n/pq-crypto/kyber_r3/kyber512r3_reduce.c b/contrib/restricted/aws/s2n/pq-crypto/kyber_r3/kyber512r3_reduce.c
index e764568826..ed7099f7ae 100644
--- a/contrib/restricted/aws/s2n/pq-crypto/kyber_r3/kyber512r3_reduce.c
+++ b/contrib/restricted/aws/s2n/pq-crypto/kyber_r3/kyber512r3_reduce.c
@@ -2,9 +2,7 @@
#include "kyber512r3_params.h"
#include "kyber512r3_reduce.h"
-#if S2N_ANY_NONPORTABLE_OPTIMIZATIONS_ENABLED
-#error "Compiling portable code with non-portable assembly optimizations is not allowed"
-#endif
+S2N_ENSURE_PORTABLE_OPTIMIZATIONS
/*************************************************
* Name: montgomery_reduce
diff --git a/contrib/restricted/aws/s2n/pq-crypto/s2n_pq_asm.h b/contrib/restricted/aws/s2n/pq-crypto/s2n_pq_asm.h
index 1a39464d48..0701e6b270 100644
--- a/contrib/restricted/aws/s2n/pq-crypto/s2n_pq_asm.h
+++ b/contrib/restricted/aws/s2n/pq-crypto/s2n_pq_asm.h
@@ -15,4 +15,15 @@
#pragma once
+#ifndef S2N_BLOCK_NONPORTABLE_OPTIMIZATIONS
+#define S2N_BLOCK_NONPORTABLE_OPTIMIZATIONS 0
+#endif
+
#define S2N_ANY_NONPORTABLE_OPTIMIZATIONS_ENABLED __AVX__ || __AVX2__ || __BMI2__
+
+#if S2N_BLOCK_NONPORTABLE_OPTIMIZATIONS && S2N_ANY_NONPORTABLE_OPTIMIZATIONS_ENABLED
+#define S2N_ENSURE_PORTABLE_OPTIMIZATIONS \
+ #error "Compiling portable code with non-portable assembly optimizations. This can result in runtime crashes if artifacts are deployed to older CPU's without these CPU instructions"
+#else
+#define S2N_ENSURE_PORTABLE_OPTIMIZATIONS
+#endif
diff --git a/contrib/restricted/aws/s2n/stuffer/s2n_stuffer.h b/contrib/restricted/aws/s2n/stuffer/s2n_stuffer.h
index 91de251eaf..52b6761e54 100644
--- a/contrib/restricted/aws/s2n/stuffer/s2n_stuffer.h
+++ b/contrib/restricted/aws/s2n/stuffer/s2n_stuffer.h
@@ -167,6 +167,9 @@ extern int s2n_stuffer_private_key_from_pem(struct s2n_stuffer *pem, struct s2n_
/* Read a certificate from a PEM encoded stuffer to an ASN1/DER encoded one */
extern int 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 */
+extern int 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 */
extern int s2n_stuffer_dhparams_from_pem(struct s2n_stuffer *pem, struct s2n_stuffer *pkcs3);
diff --git a/contrib/restricted/aws/s2n/stuffer/s2n_stuffer_pem.c b/contrib/restricted/aws/s2n/stuffer/s2n_stuffer_pem.c
index 6c18694179..bd2f591fc6 100644
--- a/contrib/restricted/aws/s2n/stuffer/s2n_stuffer_pem.c
+++ b/contrib/restricted/aws/s2n/stuffer/s2n_stuffer_pem.c
@@ -31,6 +31,7 @@
#define S2N_PEM_DH_PARAMETERS "DH PARAMETERS"
#define S2N_PEM_EC_PARAMETERS "EC PARAMETERS"
#define S2N_PEM_CERTIFICATE "CERTIFICATE"
+#define S2N_PEM_CRL "X509 CRL"
static int s2n_stuffer_pem_read_encapsulation_line(struct s2n_stuffer *pem, const char* encap_marker, const char *keyword) {
@@ -165,6 +166,10 @@ int s2n_stuffer_certificate_from_pem(struct s2n_stuffer *pem, struct s2n_stuffer
return s2n_stuffer_data_from_pem(pem, asn1, S2N_PEM_CERTIFICATE);
}
+int s2n_stuffer_crl_from_pem(struct s2n_stuffer *pem, struct s2n_stuffer *asn1) {
+ return s2n_stuffer_data_from_pem(pem, asn1, S2N_PEM_CRL);
+}
+
int s2n_stuffer_dhparams_from_pem(struct s2n_stuffer *pem, struct s2n_stuffer *pkcs3)
{
return s2n_stuffer_data_from_pem(pem, pkcs3, S2N_PEM_DH_PARAMETERS);
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_renegotiation_info.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_renegotiation_info.c
index ac11ad22e2..187d5603dc 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_renegotiation_info.c
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_renegotiation_info.c
@@ -24,6 +24,7 @@
static int s2n_client_renegotiation_send(struct s2n_connection *conn, struct s2n_stuffer *out);
static int s2n_client_renegotiation_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
static bool s2n_client_renegotiation_should_send(struct s2n_connection *conn);
+static int s2n_client_renegotiation_if_missing(struct s2n_connection *conn);
const s2n_extension_type s2n_client_renegotiation_info_extension = {
.iana_value = TLS_EXTENSION_RENEGOTIATION_INFO,
@@ -31,21 +32,7 @@ const s2n_extension_type s2n_client_renegotiation_info_extension = {
.send = s2n_client_renegotiation_send,
.recv = s2n_client_renegotiation_recv,
.should_send = s2n_client_renegotiation_should_send,
-
- /**
- *= https://tools.ietf.org/rfc/rfc5746#3.6
- *# o If neither the TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV nor the
- *# "renegotiation_info" extension was included, set the
- *# secure_renegotiation flag to FALSE. In this case, some servers
- *# may want to terminate the handshake instead of continuing
- *
- * The conn->secure_renegotiation flag defaults to false, so this is a no-op.
- * We do not terminate the handshake, although missing messaging for secure
- * renegotiation degrades client security.
- *
- * We could introduce an option to fail in this case in the future.
- */
- .if_missing = s2n_extension_noop_if_missing,
+ .if_missing = s2n_client_renegotiation_if_missing,
};
/**
@@ -75,6 +62,7 @@ static int s2n_client_renegotiation_send(struct s2n_connection *conn, struct s2n
POSIX_ENSURE(conn->secure_renegotiation, S2N_ERR_NO_RENEGOTIATION);
uint8_t renegotiated_connection_len = conn->handshake.finished_len;
+ POSIX_ENSURE_GT(renegotiated_connection_len, 0);
POSIX_GUARD(s2n_stuffer_write_uint8(out, renegotiated_connection_len));
POSIX_GUARD(s2n_stuffer_write_bytes(out, conn->handshake.client_finished, renegotiated_connection_len));
@@ -85,8 +73,14 @@ static int s2n_client_renegotiation_send(struct s2n_connection *conn, struct s2n
*= https://tools.ietf.org/rfc/rfc5746#3.6
*# o The server MUST check if the "renegotiation_info" extension is
*# included in the ClientHello.
+ *
+ * Note that this extension must also work for SSLv3:
+ *= https://tools.ietf.org/rfc/rfc5746#4.5
+ *# TLS servers that support secure renegotiation and support SSLv3 MUST accept SCSV or the
+ *# "renegotiation_info" extension and respond as described in this
+ *# specification even if the offered client version is {0x03, 0x00}.
*/
-static int s2n_client_renegotiation_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
+static int s2n_client_renegotiation_recv_initial(struct s2n_connection *conn, struct s2n_stuffer *extension)
{
/**
*= https://tools.ietf.org/rfc/rfc5746#3.6
@@ -108,6 +102,94 @@ static int s2n_client_renegotiation_recv(struct s2n_connection *conn, struct s2n
return S2N_SUCCESS;
}
+static int s2n_client_renegotiation_recv_renegotiation(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+ POSIX_ENSURE_REF(conn);
+
+ /* s2n-tls servers do not support renegotiation.
+ * We add the renegotiation version of this logic only for testing.
+ */
+ POSIX_ENSURE(s2n_in_unit_test(), S2N_ERR_NOT_IN_UNIT_TEST);
+
+ /**
+ *= https://tools.ietf.org/rfc/rfc5746#3.7
+ *# This text applies if the connection's "secure_renegotiation" flag is
+ *# set to TRUE (if it is set to FALSE, see Section 4.4).
+ */
+ POSIX_ENSURE(conn->secure_renegotiation, S2N_ERR_NO_RENEGOTIATION);
+
+ /**
+ *= https://tools.ietf.org/rfc/rfc5746#3.7
+ *# o The server MUST verify that the value of the
+ *# "renegotiated_connection" field is equal to the saved
+ *# client_verify_data value; if it is not, the server MUST abort the
+ *# handshake.
+ */
+
+ uint8_t verify_data_len = conn->handshake.finished_len;
+ POSIX_ENSURE_GT(verify_data_len, 0);
+
+ uint8_t renegotiated_connection_len = 0;
+ POSIX_GUARD(s2n_stuffer_read_uint8(extension, &renegotiated_connection_len));
+ POSIX_ENSURE(verify_data_len == renegotiated_connection_len, S2N_ERR_BAD_MESSAGE);
+
+ uint8_t *renegotiated_connection = s2n_stuffer_raw_read(extension, verify_data_len);
+ POSIX_ENSURE_REF(renegotiated_connection);
+ POSIX_ENSURE(s2n_constant_time_equals(renegotiated_connection, conn->handshake.client_finished, verify_data_len),
+ S2N_ERR_BAD_MESSAGE);
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_client_renegotiation_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+ if (s2n_handshake_is_renegotiation(conn)) {
+ POSIX_GUARD(s2n_client_renegotiation_recv_renegotiation(conn, extension));
+ } else {
+ POSIX_GUARD(s2n_client_renegotiation_recv_initial(conn, extension));
+ }
+ POSIX_ENSURE(s2n_stuffer_data_available(extension) == 0, S2N_ERR_BAD_MESSAGE);
+ return S2N_SUCCESS;
+}
+
+static int s2n_client_renegotiation_if_missing(struct s2n_connection *conn)
+{
+ POSIX_ENSURE_REF(conn);
+ if (s2n_handshake_is_renegotiation(conn)) {
+ /* s2n-tls servers do not support renegotiation.
+ * We add the renegotiation version of this logic only for testing.
+ */
+ POSIX_ENSURE(s2n_in_unit_test(), S2N_ERR_NOT_IN_UNIT_TEST);
+
+ /**
+ *= https://tools.ietf.org/rfc/rfc5746#3.7
+ *# This text applies if the connection's "secure_renegotiation" flag is
+ *# set to TRUE (if it is set to FALSE, see Section 4.4).
+ */
+ POSIX_ENSURE(conn->secure_renegotiation, S2N_ERR_NO_RENEGOTIATION);
+
+ /**
+ *= https://tools.ietf.org/rfc/rfc5746#3.7
+ *# o The server MUST verify that the "renegotiation_info" extension is
+ *# present; if it is not, the server MUST abort the handshake.
+ */
+ POSIX_BAIL(S2N_ERR_MISSING_EXTENSION);
+ } else {
+ /**
+ *= https://tools.ietf.org/rfc/rfc5746#3.6
+ *# o If neither the TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV nor the
+ *# "renegotiation_info" extension was included, set the
+ *# secure_renegotiation flag to FALSE. In this case, some servers
+ *# may want to terminate the handshake instead of continuing
+ *
+ * We do not terminate the handshake for compatibility reasons.
+ * See https://github.com/aws/s2n-tls/issues/3528
+ */
+ conn->secure_renegotiation = false;
+ return S2N_SUCCESS;
+ }
+}
+
/* Old-style extension functions -- remove after extensions refactor is complete */
int s2n_recv_client_renegotiation_info(struct s2n_connection *conn, struct s2n_stuffer *extension)
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_list.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_list.h
index 00245dacec..cddddf4135 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_list.h
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_list.h
@@ -42,6 +42,7 @@ typedef enum {
S2N_EXTENSION_LIST_CERT_REQ,
S2N_EXTENSION_LIST_CERTIFICATE,
S2N_EXTENSION_LIST_NST,
+ S2N_EXTENSION_LIST_ENCRYPTED_EXTENSIONS_TLS12,
S2N_EXTENSION_LIST_EMPTY,
S2N_EXTENSION_LIST_IDS_COUNT,
} s2n_extension_list_id;
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type.h
index f3ccf58730..a5ecb36ce4 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type.h
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type.h
@@ -67,6 +67,7 @@ static const uint16_t s2n_supported_extensions[] = {
TLS_EXTENSION_PRE_SHARED_KEY,
TLS_EXTENSION_EARLY_DATA,
TLS_EXTENSION_EMS,
+ TLS_EXTENSION_NPN,
};
typedef char s2n_extension_bitfield[S2N_SUPPORTED_EXTENSIONS_BITFIELD_LEN];
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type_lists.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type_lists.c
index e28e774acc..d8505894cd 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type_lists.c
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type_lists.c
@@ -49,6 +49,7 @@
#include "tls/extensions/s2n_server_supported_versions.h"
#include "tls/extensions/s2n_server_key_share.h"
#include "tls/extensions/s2n_server_psk.h"
+#include "tls/extensions/s2n_npn.h"
static const s2n_extension_type *const client_hello_extensions[] = {
&s2n_client_supported_versions_extension,
@@ -74,6 +75,7 @@ static const s2n_extension_type *const client_hello_extensions[] = {
&s2n_psk_key_exchange_modes_extension,
&s2n_client_early_data_indication_extension,
&s2n_client_ems_extension,
+ &s2n_client_npn_extension,
&s2n_client_psk_extension /* MUST be last */
};
@@ -88,6 +90,7 @@ static const s2n_extension_type *const tls12_server_hello_extensions[] = {
&s2n_server_max_fragment_length_extension,
&s2n_server_session_ticket_extension,
&s2n_server_ems_extension,
+ &s2n_server_npn_extension,
};
/**
@@ -121,6 +124,10 @@ static const s2n_extension_type *const encrypted_extensions[] = {
&s2n_server_early_data_indication_extension,
};
+static const s2n_extension_type *const tls12_encrypted_extensions[] = {
+ &s2n_npn_encrypted_extension,
+};
+
static const s2n_extension_type *const cert_req_extensions[] = {
&s2n_server_signature_algorithms_extension,
};
@@ -145,6 +152,7 @@ static s2n_extension_type_list extension_lists[] = {
[S2N_EXTENSION_LIST_CERT_REQ] = S2N_EXTENSION_LIST(cert_req_extensions),
[S2N_EXTENSION_LIST_CERTIFICATE] = S2N_EXTENSION_LIST(certificate_extensions),
[S2N_EXTENSION_LIST_NST] = S2N_EXTENSION_LIST(nst_extensions),
+ [S2N_EXTENSION_LIST_ENCRYPTED_EXTENSIONS_TLS12] = S2N_EXTENSION_LIST(tls12_encrypted_extensions),
[S2N_EXTENSION_LIST_EMPTY] = { .extension_types = NULL, .count = 0 },
};
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_npn.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_npn.c
index 61c5b3a6d1..4731f97ffb 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_npn.c
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_npn.c
@@ -66,7 +66,33 @@ int s2n_server_npn_recv(struct s2n_connection *conn, struct s2n_stuffer *extensi
return S2N_SUCCESS;
}
- POSIX_GUARD_RESULT(s2n_select_server_preference_protocol(conn, extension, supported_protocols));
+ /*
+ *= https://datatracker.ietf.org/doc/id/draft-agl-tls-nextprotoneg-04#section-3
+ *# The "extension_data" field of a "next_protocol_negotiation" extension
+ *# in a "ServerHello" contains an optional list of protocols advertised
+ *# by the server.
+ */
+ if (s2n_stuffer_data_available(extension)) {
+ POSIX_GUARD_RESULT(s2n_select_server_preference_protocol(conn, extension, supported_protocols));
+ }
+
+ /*
+ *= https://datatracker.ietf.org/doc/id/draft-agl-tls-nextprotoneg-04#section-4
+ *# In the event that the client doesn't support any of server's protocols, or
+ *# the server doesn't advertise any, it SHOULD select the first protocol
+ *# that it supports.
+ */
+ if (s2n_get_application_protocol(conn) == NULL) {
+ struct s2n_stuffer stuffer = { 0 };
+ POSIX_GUARD(s2n_stuffer_init(&stuffer, supported_protocols));
+ POSIX_GUARD(s2n_stuffer_skip_write(&stuffer, supported_protocols->size));
+ struct s2n_blob protocol = { 0 };
+ POSIX_GUARD_RESULT(s2n_protocol_preferences_read(&stuffer, &protocol));
+
+ POSIX_ENSURE_LT(protocol.size, sizeof(conn->application_protocol));
+ POSIX_CHECKED_MEMCPY(conn->application_protocol, protocol.data, protocol.size);
+ conn->application_protocol[protocol.size] = '\0';
+ }
return S2N_SUCCESS;
}
@@ -79,3 +105,73 @@ const s2n_extension_type s2n_server_npn_extension = {
.should_send = s2n_server_npn_should_send,
.if_missing = s2n_extension_noop_if_missing,
};
+
+bool s2n_npn_encrypted_should_send(struct s2n_connection *conn)
+{
+ return s2n_server_alpn_should_send(conn);
+}
+
+S2N_RESULT s2n_calculate_padding(uint8_t protocol_len, uint8_t *padding_len)
+{
+ RESULT_ENSURE_REF(padding_len);
+
+ /*
+ *= https://datatracker.ietf.org/doc/id/draft-agl-tls-nextprotoneg-04#section-3
+ *# The length of "padding" SHOULD be 32 - ((len(selected_protocol) + 2) % 32).
+ */
+ *padding_len = 32 - ((protocol_len + 2) % 32);
+ return S2N_RESULT_OK;
+}
+
+int s2n_npn_encrypted_extension_send(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ uint8_t protocol_len = strlen(conn->application_protocol);
+ POSIX_GUARD(s2n_stuffer_write_uint8(out, protocol_len));
+ POSIX_GUARD(s2n_stuffer_write_bytes(out, (uint8_t*) conn->application_protocol, protocol_len));
+
+ uint8_t padding_len = 0;
+ POSIX_GUARD_RESULT(s2n_calculate_padding(protocol_len, &padding_len));
+ POSIX_GUARD(s2n_stuffer_write_uint8(out, padding_len));
+ for (size_t i = 0; i < padding_len; i++) {
+ POSIX_GUARD(s2n_stuffer_write_uint8(out, 0));
+ }
+
+ return S2N_SUCCESS;
+}
+
+int s2n_npn_encrypted_extension_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+ uint8_t protocol_len = 0;
+ POSIX_GUARD(s2n_stuffer_read_uint8(extension, &protocol_len));
+
+ uint8_t *protocol = s2n_stuffer_raw_read(extension, protocol_len);
+ POSIX_ENSURE_REF(protocol);
+ POSIX_CHECKED_MEMCPY(conn->application_protocol, protocol, protocol_len);
+ conn->application_protocol[protocol_len] = '\0';
+
+ uint8_t expected_padding_len = 0;
+ POSIX_GUARD_RESULT(s2n_calculate_padding(protocol_len, &expected_padding_len));
+ uint8_t padding_len = 0;
+ POSIX_GUARD(s2n_stuffer_read_uint8(extension, &padding_len));
+ POSIX_ENSURE_EQ(padding_len, expected_padding_len);
+
+ for (size_t i = 0; i < padding_len; i++) {
+ uint8_t byte = 0;
+ POSIX_GUARD(s2n_stuffer_read_uint8(extension, &byte));
+ POSIX_ENSURE_EQ(byte, 0);
+ }
+ POSIX_ENSURE_EQ(s2n_stuffer_data_available(extension), 0);
+
+ return S2N_SUCCESS;
+}
+
+const s2n_extension_type s2n_npn_encrypted_extension = {
+ .iana_value = TLS_EXTENSION_NPN,
+ .is_response = true,
+ .send = s2n_npn_encrypted_extension_send,
+ .recv = s2n_npn_encrypted_extension_recv,
+ .should_send = s2n_npn_encrypted_should_send,
+ /* The NPN extension is the only one defined for TLS1.2 Encrypted Extensions.
+ * If it's missing, something has gone wrong. */
+ .if_missing = s2n_extension_error_if_missing,
+};
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_npn.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_npn.h
index 0b03e5c1b4..81f0f60220 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_npn.h
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_npn.h
@@ -19,3 +19,4 @@
extern const s2n_extension_type s2n_client_npn_extension;
extern const s2n_extension_type s2n_server_npn_extension;
+extern const s2n_extension_type s2n_npn_encrypted_extension;
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_renegotiation_info.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_renegotiation_info.c
index 1052a41ab1..5834412e10 100644
--- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_renegotiation_info.c
+++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_renegotiation_info.c
@@ -24,6 +24,17 @@
#include "tls/s2n_tls.h"
#include "tls/extensions/s2n_server_renegotiation_info.h"
+/**
+ * s2n-tls servers do NOT support renegotiation.
+ *
+ * We implement this extension to handle clients that require secure renegotiation support:
+ *= https://tools.ietf.org/rfc/rfc5746#4.3
+ *# In order to enable clients to probe, even servers that do not support
+ *# renegotiation MUST implement the minimal version of the extension
+ *# described in this document for initial handshakes, thus signaling
+ *# that they have been upgraded.
+ */
+
static bool s2n_renegotiation_info_should_send(struct s2n_connection *conn);
static int s2n_renegotiation_info_send(struct s2n_connection *conn, struct s2n_stuffer *out);
static int s2n_renegotiation_info_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
@@ -69,12 +80,53 @@ static bool s2n_renegotiation_info_should_send(struct s2n_connection *conn)
*# include an empty "renegotiation_info" extension in the ServerHello
*# message.
*/
-static int s2n_renegotiation_info_send(struct s2n_connection *conn, struct s2n_stuffer *out)
+static int s2n_renegotiation_info_send_initial(struct s2n_connection *conn, struct s2n_stuffer *out)
{
POSIX_GUARD(s2n_stuffer_write_uint8(out, 0));
return S2N_SUCCESS;
}
+static int s2n_renegotiation_info_send_renegotiation(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ POSIX_ENSURE_REF(conn);
+
+ /* s2n-tls servers do not support renegotiation.
+ * We add the renegotiation version of this logic only for testing.
+ */
+ POSIX_ENSURE(s2n_in_unit_test(), S2N_ERR_NOT_IN_UNIT_TEST);
+
+ /**
+ *= https://tools.ietf.org/rfc/rfc5746#3.7
+ *# This text applies if the connection's "secure_renegotiation" flag is
+ *# set to TRUE (if it is set to FALSE, see Section 4.4).
+ */
+ POSIX_ENSURE(conn->secure_renegotiation, S2N_ERR_NO_RENEGOTIATION);
+
+ /**
+ *= https://tools.ietf.org/rfc/rfc5746#3.7
+ *# o The server MUST include a "renegotiation_info" extension
+ *# containing the saved client_verify_data and server_verify_data in
+ *# the ServerHello.
+ */
+ const uint8_t verify_data_len = conn->handshake.finished_len;
+ POSIX_ENSURE_GT(verify_data_len, 0);
+ POSIX_GUARD(s2n_stuffer_write_uint8(out, verify_data_len * 2));
+ POSIX_GUARD(s2n_stuffer_write_bytes(out, conn->handshake.client_finished, verify_data_len));
+ POSIX_GUARD(s2n_stuffer_write_bytes(out, conn->handshake.server_finished, verify_data_len));
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_renegotiation_info_send(struct s2n_connection *conn, struct s2n_stuffer *out)
+{
+ if (s2n_handshake_is_renegotiation(conn)) {
+ POSIX_GUARD(s2n_renegotiation_info_send_renegotiation(conn, out));
+ } else {
+ POSIX_GUARD(s2n_renegotiation_info_send_initial(conn, out));
+ }
+ return S2N_SUCCESS;
+}
+
/**
*= https://tools.ietf.org/rfc/rfc5746#3.4
*# o When a ServerHello is received, the client MUST check if it
@@ -142,6 +194,14 @@ static int s2n_renegotiation_info_recv_renegotiation(struct s2n_connection *conn
return S2N_SUCCESS;
}
+/**
+ * Note that this extension must also work for SSLv3:
+ *= https://tools.ietf.org/rfc/rfc5746#4.5
+ *# Clients that support SSLv3 and offer secure renegotiation (either via SCSV or
+ *# "renegotiation_info") MUST accept the "renegotiation_info" extension
+ *# from the server, even if the server version is {0x03, 0x00}, and
+ *# behave as described in this specification.
+ */
static int s2n_renegotiation_info_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
{
if (s2n_handshake_is_renegotiation(conn)) {
@@ -170,13 +230,24 @@ static int s2n_renegotiation_info_if_missing(struct s2n_connection *conn)
*# secure renegotiation; set secure_renegotiation flag to FALSE.
*# In this case, some clients may want to terminate the handshake
*# instead of continuing; see Section 4.1 for discussion.
- *
- * We do not terminate the handshake, although missing messaging for secure
- * renegotiation degrades server security.
- *
- * We could introduce an option to fail in this case in the future.
*/
conn->secure_renegotiation = false;
+
+ /**
+ *= https://tools.ietf.org/rfc/rfc5746#4.1
+ *= type=exception
+ *= reason=Avoid interoperability problems
+ *# If clients wish to ensure that such attacks are impossible, they need
+ *# to terminate the connection immediately upon failure to receive the
+ *# extension without completing the handshake. Such clients MUST
+ *# generate a fatal "handshake_failure" alert prior to terminating the
+ *# connection. However, it is expected that many TLS servers that do
+ *# not support renegotiation (and thus are not vulnerable) will not
+ *# support this extension either, so in general, clients that implement
+ *# this behavior will encounter interoperability problems.
+ *
+ * TODO: https://github.com/aws/s2n-tls/issues/3528
+ */
return S2N_SUCCESS;
}
}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_alerts.c b/contrib/restricted/aws/s2n/tls/s2n_alerts.c
index 5ecf10b47d..8ed8a3adc1 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_alerts.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_alerts.c
@@ -300,6 +300,18 @@ int s2n_queue_reader_handshake_failure_alert(struct s2n_connection *conn)
S2N_RESULT s2n_queue_reader_no_renegotiation_alert(struct s2n_connection *conn)
{
+ /**
+ *= https://tools.ietf.org/rfc/rfc5746#4.5
+ *# SSLv3 does not define the "no_renegotiation" alert (and does
+ *# not offer a way to indicate a refusal to renegotiate at a "warning"
+ *# level). SSLv3 clients that refuse renegotiation SHOULD use a fatal
+ *# handshake_failure alert.
+ **/
+ if (s2n_connection_get_protocol_version(conn) == S2N_SSLv3) {
+ RESULT_GUARD_POSIX(s2n_queue_reader_alert(conn, S2N_TLS_ALERT_LEVEL_FATAL, S2N_TLS_ALERT_HANDSHAKE_FAILURE));
+ return S2N_RESULT_OK;
+ }
+
RESULT_GUARD_POSIX(s2n_queue_reader_alert(conn, S2N_TLS_ALERT_LEVEL_WARNING, S2N_TLS_ALERT_NO_RENEGOTIATION));
return S2N_RESULT_OK;
}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_cipher_suites.c b/contrib/restricted/aws/s2n/tls/s2n_cipher_suites.c
index 75cf0f6ba4..df7aa796c6 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_cipher_suites.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_cipher_suites.c
@@ -1188,13 +1188,21 @@ static int s2n_set_cipher_as_server(struct s2n_connection *conn, uint8_t *wire,
}
}
- /**
- *= https://tools.ietf.org/rfc/rfc5746#3.6
- *# o When a ClientHello is received, the server MUST check if it
- *# includes the TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. If it does,
- *# set the secure_renegotiation flag to TRUE.
- */
if (s2n_wire_ciphers_contain(renegotiation_info_scsv, wire, count, cipher_suite_len)) {
+ /** For renegotiation handshakes:
+ *= https://tools.ietf.org/rfc/rfc5746#3.7
+ *# o When a ClientHello is received, the server MUST verify that it
+ *# does not contain the TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. If
+ *# the SCSV is present, the server MUST abort the handshake.
+ */
+ POSIX_ENSURE(!s2n_handshake_is_renegotiation(conn), S2N_ERR_BAD_MESSAGE);
+
+ /** For initial handshakes:
+ *= https://tools.ietf.org/rfc/rfc5746#3.6
+ *# o When a ClientHello is received, the server MUST check if it
+ *# includes the TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. If it does,
+ *# set the secure_renegotiation flag to TRUE.
+ */
conn->secure_renegotiation = 1;
}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_client_hello_request.c b/contrib/restricted/aws/s2n/tls/s2n_client_hello_request.c
index 824c1eb2dc..188f9440cc 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_client_hello_request.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_client_hello_request.c
@@ -41,6 +41,13 @@ S2N_RESULT s2n_client_hello_request_recv(struct s2n_connection *conn)
RESULT_ENSURE_REF(conn->config);
RESULT_GUARD(s2n_client_hello_request_validate(conn));
+ /* Maintain the old s2n-tls behavior by default.
+ * Traditionally, s2n-tls has just ignored all hello requests.
+ */
+ if (!conn->config->renegotiate_request_cb) {
+ return S2N_RESULT_OK;
+ }
+
/*
*= https://tools.ietf.org/rfc/rfc5746#section-4.2
*# This text applies if the connection's "secure_renegotiation" flag is
@@ -61,10 +68,8 @@ S2N_RESULT s2n_client_hello_request_recv(struct s2n_connection *conn)
}
s2n_renegotiate_response response = S2N_RENEGOTIATE_REJECT;
- if (conn->config->renegotiate_request_cb) {
- RESULT_GUARD_POSIX((conn->config->renegotiate_request_cb)(
- conn, conn->config->renegotiate_request_ctx, &response));
- }
+ int result = conn->config->renegotiate_request_cb(conn, conn->config->renegotiate_request_ctx, &response);
+ RESULT_ENSURE(result == S2N_SUCCESS, S2N_ERR_CANCELLED);
/*
*= https://tools.ietf.org/rfc/rfc5246#section-7.4.1.1
@@ -72,7 +77,7 @@ S2N_RESULT s2n_client_hello_request_recv(struct s2n_connection *conn)
*# the client if it does not wish to renegotiate a session, or the
*# client may, if it wishes, respond with a no_renegotiation alert.
*/
- if (response != S2N_RENEGOTIATE_ACCEPT) {
+ if (response == S2N_RENEGOTIATE_REJECT) {
RESULT_GUARD(s2n_queue_reader_no_renegotiation_alert(conn));
return S2N_RESULT_OK;
}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_config.c b/contrib/restricted/aws/s2n/tls/s2n_config.c
index dba71e2bf3..adaa533287 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_config.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_config.c
@@ -1019,6 +1019,11 @@ int s2n_config_set_verify_after_sign(struct s2n_config *config, s2n_verify_after
return S2N_SUCCESS;
}
+/*
+ *= https://tools.ietf.org/rfc/rfc5746#5
+ *# TLS implementations SHOULD provide a mechanism to disable and enable
+ *# renegotiation.
+ */
int s2n_config_set_renegotiate_request_cb(struct s2n_config *config, s2n_renegotiate_request_cb cb, void *ctx)
{
POSIX_ENSURE_REF(config);
diff --git a/contrib/restricted/aws/s2n/tls/s2n_crl.c b/contrib/restricted/aws/s2n/tls/s2n_crl.c
new file mode 100644
index 0000000000..a3c404c353
--- /dev/null
+++ b/contrib/restricted/aws/s2n/tls/s2n_crl.c
@@ -0,0 +1,88 @@
+/*
+* 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_crl.h"
+#include "tls/s2n_connection.h"
+
+struct s2n_crl *s2n_crl_new(void) {
+ DEFER_CLEANUP(struct s2n_blob mem = { 0 }, s2n_free);
+ PTR_GUARD_POSIX(s2n_alloc(&mem, sizeof(struct s2n_crl)));
+ PTR_GUARD_POSIX(s2n_blob_zero(&mem));
+
+ struct s2n_crl *crl = (struct s2n_crl *)(void*) mem.data;
+
+ ZERO_TO_DISABLE_DEFER_CLEANUP(mem);
+ return crl;
+}
+
+int s2n_crl_load_pem(struct s2n_crl *crl, uint8_t *pem, size_t len) {
+ POSIX_ENSURE_REF(crl);
+ POSIX_ENSURE(crl->crl == NULL, S2N_ERR_INVALID_ARGUMENT);
+
+ struct s2n_blob pem_blob = { 0 };
+ POSIX_GUARD(s2n_blob_init(&pem_blob, pem, len));
+
+ struct s2n_stuffer pem_stuffer = { 0 };
+ POSIX_GUARD(s2n_stuffer_init(&pem_stuffer, &pem_blob));
+ POSIX_GUARD(s2n_stuffer_skip_write(&pem_stuffer, pem_blob.size));
+
+ DEFER_CLEANUP(struct s2n_stuffer der_out_stuffer = {0}, s2n_stuffer_free);
+ POSIX_GUARD(s2n_stuffer_growable_alloc(&der_out_stuffer, len));
+ POSIX_GUARD(s2n_stuffer_crl_from_pem(&pem_stuffer, &der_out_stuffer));
+
+ uint32_t data_size = s2n_stuffer_data_available(&der_out_stuffer);
+ const uint8_t *data = s2n_stuffer_raw_read(&der_out_stuffer, data_size);
+ POSIX_ENSURE_REF(data);
+ crl->crl = d2i_X509_CRL(NULL, &data, data_size);
+ POSIX_ENSURE(crl->crl != NULL, S2N_ERR_INVALID_PEM);
+
+ return S2N_SUCCESS;
+}
+
+int s2n_crl_free(struct s2n_crl **crl) {
+ if (crl == NULL) {
+ return S2N_SUCCESS;
+ }
+ if (*crl == NULL) {
+ return S2N_SUCCESS;
+ }
+
+ if ((*crl)->crl != NULL) {
+ X509_CRL_free((*crl)->crl);
+ (*crl)->crl = NULL;
+ }
+
+ POSIX_GUARD(s2n_free_object((uint8_t **) crl, sizeof(struct s2n_crl)));
+
+ *crl = NULL;
+
+ return S2N_SUCCESS;
+}
+
+int s2n_crl_get_issuer_hash(struct s2n_crl *crl, uint64_t *hash) {
+ POSIX_ENSURE_REF(crl);
+ POSIX_ENSURE_REF(crl->crl);
+ POSIX_ENSURE_REF(hash);
+
+ X509_NAME *crl_name = X509_CRL_get_issuer(crl->crl);
+ POSIX_ENSURE_REF(crl_name);
+
+ unsigned long temp_hash = X509_NAME_hash(crl_name);
+ POSIX_ENSURE(temp_hash != 0, S2N_ERR_INTERNAL_LIBCRYPTO_ERROR);
+
+ *hash = temp_hash;
+
+ return S2N_SUCCESS;
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_crl.h b/contrib/restricted/aws/s2n/tls/s2n_crl.h
new file mode 100644
index 0000000000..db8c967d32
--- /dev/null
+++ b/contrib/restricted/aws/s2n/tls/s2n_crl.h
@@ -0,0 +1,31 @@
+/*
+* 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 "api/s2n.h"
+
+#include <openssl/x509v3.h>
+
+struct s2n_crl {
+ X509_CRL *crl;
+};
+
+/* TODO: APIs are part of an unfinished CRL validation feature and are temporarily hidden
+ * https://github.com/aws/s2n-tls/issues/3499 */
+struct s2n_crl *s2n_crl_new(void);
+int s2n_crl_load_pem(struct s2n_crl *crl, uint8_t *pem, size_t len);
+int s2n_crl_free(struct s2n_crl **crl);
+int s2n_crl_get_issuer_hash(struct s2n_crl *crl, uint64_t *hash);
diff --git a/contrib/restricted/aws/s2n/tls/s2n_handshake.c b/contrib/restricted/aws/s2n/tls/s2n_handshake.c
index e8a8b12c58..cc343d622d 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_handshake.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_handshake.c
@@ -373,6 +373,5 @@ S2N_RESULT s2n_handshake_set_finished_len(struct s2n_connection *conn, uint8_t l
bool s2n_handshake_is_renegotiation(struct s2n_connection *conn)
{
- return s2n_in_unit_test() && conn &&
- (conn->mode == S2N_CLIENT) && conn->handshake.renegotiation;
+ return conn && conn->handshake.renegotiation;
}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_handshake_io.c b/contrib/restricted/aws/s2n/tls/s2n_handshake_io.c
index 4e1737e2dc..7a28eb34b8 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_handshake_io.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_handshake_io.c
@@ -1149,6 +1149,25 @@ static S2N_RESULT s2n_finish_read(struct s2n_connection *conn)
return S2N_RESULT_OK;
}
+static S2N_RESULT s2n_handshake_app_data_recv(struct s2n_connection *conn)
+{
+ if (conn->early_data_expected) {
+ RESULT_GUARD(s2n_early_data_validate_recv(conn));
+ RESULT_BAIL(S2N_ERR_EARLY_DATA_BLOCKED);
+ }
+
+ if (conn->handshake.renegotiation) {
+ RESULT_GUARD(s2n_renegotiate_validate(conn));
+ /* During renegotiation, Application Data may only be received until
+ * the server acknowledges the new handshake with a ServerHello.
+ */
+ RESULT_ENSURE(ACTIVE_MESSAGE(conn) == SERVER_HELLO, S2N_ERR_BAD_MESSAGE);
+ RESULT_BAIL(S2N_ERR_APP_DATA_BLOCKED);
+ }
+
+ RESULT_BAIL(S2N_ERR_BAD_MESSAGE);
+}
+
/* Reading is a little more complicated than writing as the TLS RFCs allow content
* types to be interleaved at the record layer. We may get an alert message
* during the handshake phase, or messages of types that we don't support (e.g.
@@ -1204,9 +1223,7 @@ static int s2n_handshake_read_io(struct s2n_connection *conn)
*/
if (record_type == TLS_APPLICATION_DATA) {
- POSIX_ENSURE(conn->early_data_expected, S2N_ERR_BAD_MESSAGE);
- POSIX_GUARD_RESULT(s2n_early_data_validate_recv(conn));
- POSIX_BAIL(S2N_ERR_EARLY_DATA_BLOCKED);
+ POSIX_GUARD_RESULT(s2n_handshake_app_data_recv(conn));
} else if (record_type == TLS_CHANGE_CIPHER_SPEC) {
/* TLS1.3 can receive unexpected CCS messages at any point in the handshake
* due to a peer operating in middlebox compatibility mode.
diff --git a/contrib/restricted/aws/s2n/tls/s2n_renegotiate.c b/contrib/restricted/aws/s2n/tls/s2n_renegotiate.c
index f8bf49ddf8..f930390d79 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_renegotiate.c
+++ b/contrib/restricted/aws/s2n/tls/s2n_renegotiate.c
@@ -20,6 +20,25 @@
#include "tls/s2n_connection.h"
#include "utils/s2n_safety.h"
+/* We don't want to introduce a new blocked status for renegotiation
+ * because that would potentially require applications to update their
+ * blocked status handling logic for no reason.
+ *
+ * It is impossible to use both early data and renegotiation for the same handshake,
+ * and both are just application data received during the handshake.
+ * Therefore, we will alias S2N_BLOCKED_ON_EARLY_DATA for reuse with renegotiation.
+ */
+const s2n_blocked_status S2N_BLOCKED_ON_APPLICATION_DATA = S2N_BLOCKED_ON_EARLY_DATA;
+
+S2N_RESULT s2n_renegotiate_validate(struct s2n_connection *conn)
+{
+ RESULT_ENSURE_REF(conn);
+ RESULT_ENSURE(conn->mode == S2N_CLIENT, S2N_ERR_NO_RENEGOTIATION);
+ RESULT_ENSURE(conn->secure_renegotiation, S2N_ERR_NO_RENEGOTIATION);
+ RESULT_ENSURE(conn->handshake.renegotiation, S2N_ERR_INVALID_STATE);
+ return S2N_RESULT_OK;
+}
+
/*
* Prepare a connection to be reused for a second handshake.
*
@@ -93,6 +112,15 @@ int s2n_renegotiate_wipe(struct s2n_connection *conn)
bool secure_renegotiation = conn->secure_renegotiation;
POSIX_ENSURE(secure_renegotiation, S2N_ERR_NO_RENEGOTIATION);
+ /* Save the finished data.
+ * This is required for the renegotiate_info extension on the new handshake.
+ */
+ uint8_t finished_len = conn->handshake.finished_len;
+ uint8_t client_finished[sizeof(conn->handshake.client_finished)] = { 0 };
+ POSIX_CHECKED_MEMCPY(client_finished, conn->handshake.client_finished, finished_len);
+ uint8_t server_finished[sizeof(conn->handshake.server_finished)] = { 0 };
+ POSIX_CHECKED_MEMCPY(server_finished, conn->handshake.server_finished, finished_len);
+
POSIX_GUARD(s2n_connection_wipe(conn));
/* Setup the new crypto parameters.
@@ -107,6 +135,9 @@ int s2n_renegotiate_wipe(struct s2n_connection *conn)
/* Restore saved values */
POSIX_GUARD_RESULT(s2n_connection_set_max_fragment_length(conn, max_frag_len));
+ POSIX_CHECKED_MEMCPY(conn->handshake.client_finished, client_finished, finished_len);
+ POSIX_CHECKED_MEMCPY(conn->handshake.server_finished, server_finished, finished_len);
+ conn->handshake.finished_len = finished_len;
conn->actual_protocol_version = actual_protocol_version;
conn->server_protocol_version = server_protocol_version;
conn->client_protocol_version = client_protocol_version;
@@ -123,3 +154,45 @@ int s2n_renegotiate_wipe(struct s2n_connection *conn)
conn->handshake.renegotiation = true;
return S2N_SUCCESS;
}
+
+static S2N_RESULT s2n_renegotiate_read_app_data(struct s2n_connection *conn, uint8_t *app_data_buf, ssize_t app_data_buf_size,
+ ssize_t *app_data_size, s2n_blocked_status *blocked)
+{
+ RESULT_ENSURE_REF(blocked);
+
+ ssize_t r = s2n_recv(conn, app_data_buf, app_data_buf_size, blocked);
+ RESULT_GUARD_POSIX(r);
+ *app_data_size = r;
+
+ *blocked = S2N_BLOCKED_ON_APPLICATION_DATA;
+ RESULT_BAIL(S2N_ERR_APP_DATA_BLOCKED);
+}
+
+int s2n_renegotiate(struct s2n_connection *conn, uint8_t *app_data_buf, ssize_t app_data_buf_size,
+ ssize_t *app_data_size, s2n_blocked_status *blocked)
+{
+ POSIX_GUARD_RESULT(s2n_renegotiate_validate(conn));
+
+ POSIX_ENSURE_REF(app_data_size);
+ *app_data_size = 0;
+
+ /* If there is outstanding application data, pass it back to the application.
+ * We can't read the next handshake record until we drain the buffer.
+ */
+ if (s2n_peek(conn) > 0) {
+ POSIX_GUARD_RESULT(s2n_renegotiate_read_app_data(conn,
+ app_data_buf, app_data_buf_size, app_data_size, blocked));
+ }
+
+ int result = s2n_negotiate(conn, blocked);
+
+ /* If we encounter application data while reading handshake records,
+ * pass it back to the application.
+ */
+ if (result != S2N_SUCCESS && s2n_errno == S2N_ERR_APP_DATA_BLOCKED) {
+ POSIX_GUARD_RESULT(s2n_renegotiate_read_app_data(conn,
+ app_data_buf, app_data_buf_size, app_data_size, blocked));
+ }
+
+ return result;
+}
diff --git a/contrib/restricted/aws/s2n/tls/s2n_renegotiate.h b/contrib/restricted/aws/s2n/tls/s2n_renegotiate.h
index 9e11e6e892..83333aa49b 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_renegotiate.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_renegotiate.h
@@ -15,11 +15,7 @@
#pragma once
-struct s2n_connection;
-struct s2n_config;
+#include "api/unstable/renegotiate.h"
+#include "utils/s2n_result.h"
-typedef enum { S2N_RENEGOTIATE_REJECT, S2N_RENEGOTIATE_ACCEPT} s2n_renegotiate_response;
-typedef int (*s2n_renegotiate_request_cb)(struct s2n_connection *conn, void *context, s2n_renegotiate_response *response);
-int s2n_config_set_renegotiate_request_cb(struct s2n_config *config, s2n_renegotiate_request_cb cb, void *ctx);
-
-int s2n_renegotiate_wipe(struct s2n_connection *conn);
+S2N_RESULT s2n_renegotiate_validate(struct s2n_connection *conn);
diff --git a/contrib/restricted/aws/s2n/tls/s2n_tls.h b/contrib/restricted/aws/s2n/tls/s2n_tls.h
index ca398b92b2..a4bffb18bf 100644
--- a/contrib/restricted/aws/s2n/tls/s2n_tls.h
+++ b/contrib/restricted/aws/s2n/tls/s2n_tls.h
@@ -37,6 +37,8 @@ extern int s2n_server_hello_send(struct s2n_connection *conn);
extern int s2n_server_hello_recv(struct s2n_connection *conn);
extern int s2n_encrypted_extensions_send(struct s2n_connection *conn);
extern int s2n_encrypted_extensions_recv(struct s2n_connection *conn);
+extern int s2n_tls12_encrypted_extensions_send(struct s2n_connection *conn);
+extern int s2n_tls12_encrypted_extensions_recv(struct s2n_connection *conn);
extern int s2n_server_cert_send(struct s2n_connection *conn);
extern int s2n_server_cert_recv(struct s2n_connection *conn);
extern int s2n_server_status_send(struct s2n_connection *conn);
diff --git a/contrib/restricted/aws/s2n/tls/s2n_tls12_encrypted_extensions.c b/contrib/restricted/aws/s2n/tls/s2n_tls12_encrypted_extensions.c
new file mode 100644
index 0000000000..b248ac5d3b
--- /dev/null
+++ b/contrib/restricted/aws/s2n/tls/s2n_tls12_encrypted_extensions.c
@@ -0,0 +1,41 @@
+/*
+ * 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 "error/s2n_errno.h"
+#include "utils/s2n_safety.h"
+#include "stuffer/s2n_stuffer.h"
+
+#include "tls/s2n_tls.h"
+#include "tls/extensions/s2n_extension_list.h"
+
+int s2n_tls12_encrypted_extensions_send(struct s2n_connection *conn)
+{
+ POSIX_ENSURE_REF(conn);
+ POSIX_ENSURE(conn->actual_protocol_version < S2N_TLS13, S2N_ERR_BAD_MESSAGE);
+
+ struct s2n_stuffer *out = &conn->handshake.io;
+ POSIX_GUARD(s2n_extension_list_send(S2N_EXTENSION_LIST_ENCRYPTED_EXTENSIONS_TLS12, conn, out));
+ return S2N_SUCCESS;
+}
+
+int s2n_tls12_encrypted_extensions_recv(struct s2n_connection *conn)
+{
+ POSIX_ENSURE_REF(conn);
+ POSIX_ENSURE(conn->actual_protocol_version < S2N_TLS13, S2N_ERR_BAD_MESSAGE);
+
+ struct s2n_stuffer *in = &conn->handshake.io;
+ POSIX_GUARD(s2n_extension_list_recv(S2N_EXTENSION_LIST_ENCRYPTED_EXTENSIONS_TLS12, conn, in));
+ return S2N_SUCCESS;
+}