Browse Source

Update contrib/restricted/aws/s2n to 1.3.56

robot-contrib 1 year ago
parent
commit
f3235e82c4

+ 9 - 5
contrib/restricted/aws/s2n/api/s2n.h

@@ -2127,14 +2127,18 @@ S2N_API extern int s2n_connection_get_client_auth_type(struct s2n_connection *co
 S2N_API extern int s2n_connection_set_client_auth_type(struct s2n_connection *conn, s2n_cert_auth_type client_auth_type);
 
 /**
- * Gets the client certificate chain and places it in the `der_cert_chain_out` buffer. `cert_chain_len` is updated
- * to match the size the chain buffer.
+ * Gets the raw certificate chain received from the client.
  *
- * @warning The buffers share a lifetime with the s2n_connection object.
+ * The retrieved certificate chain has the format described by the TLS 1.2 RFC:
+ * https://datatracker.ietf.org/doc/html/rfc5246#section-7.4.2. Each certificate is a DER-encoded ASN.1 X.509,
+ * prepended by a 3 byte network-endian length value. Note that this format is used regardless of the connection's
+ * protocol version.
+ *
+ * @warning The buffer pointed to by `cert_chain_out` shares its lifetime with the s2n_connection object.
  *
  * @param conn A pointer to the s2n_connection object
- * @param der_cert_chain_out A uint8_t pointer. This will be updated to point to the client certificate chain.
- * @param cert_chain_len A pointer to a uint32_t. This will be updated to match the size of the buffer `der_cert_chain_out` points to.
+ * @param cert_chain_out A pointer that's set to the client certificate chain.
+ * @param cert_chain_len A pointer that's set to the size of the `cert_chain_out` buffer.
  * @returns S2N_SUCCESS on success. S2N_FAILURE on failure
  */
 S2N_API extern int s2n_connection_get_client_cert_chain(struct s2n_connection *conn, uint8_t **der_cert_chain_out, uint32_t *cert_chain_len);

+ 8 - 1
contrib/restricted/aws/s2n/tls/extensions/s2n_client_signature_algorithms.c

@@ -24,12 +24,13 @@
 #include "utils/s2n_safety.h"
 
 static bool s2n_client_signature_algorithms_should_send(struct s2n_connection *conn);
+static int s2n_client_signature_algorithms_send(struct s2n_connection *conn, struct s2n_stuffer *extension);
 static int s2n_client_signature_algorithms_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
 
 const s2n_extension_type s2n_client_signature_algorithms_extension = {
     .iana_value = TLS_EXTENSION_SIGNATURE_ALGORITHMS,
     .is_response = false,
-    .send = s2n_send_supported_sig_scheme_list,
+    .send = s2n_client_signature_algorithms_send,
     .recv = s2n_client_signature_algorithms_recv,
     .should_send = s2n_client_signature_algorithms_should_send,
     .if_missing = s2n_extension_noop_if_missing,
@@ -40,6 +41,12 @@ static bool s2n_client_signature_algorithms_should_send(struct s2n_connection *c
     return s2n_connection_get_protocol_version(conn) >= S2N_TLS12;
 }
 
+static int s2n_client_signature_algorithms_send(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+    POSIX_GUARD_RESULT(s2n_signature_algorithms_supported_list_send(conn, extension));
+    return S2N_SUCCESS;
+}
+
 static int s2n_client_signature_algorithms_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
 {
     return s2n_recv_supported_sig_scheme_list(extension, &conn->handshake_params.client_sig_hash_algs);

+ 43 - 11
contrib/restricted/aws/s2n/tls/extensions/s2n_client_supported_versions.c

@@ -74,7 +74,8 @@ static int s2n_client_supported_versions_send(struct s2n_connection *conn, struc
     return S2N_SUCCESS;
 }
 
-static int s2n_extensions_client_supported_versions_process(struct s2n_connection *conn, struct s2n_stuffer *extension)
+int s2n_extensions_client_supported_versions_process(struct s2n_connection *conn, struct s2n_stuffer *extension,
+        uint8_t *client_protocol_version_out, uint8_t *actual_protocol_version_out)
 {
     uint8_t highest_supported_version = conn->server_protocol_version;
     uint8_t minimum_supported_version = s2n_unknown_protocol_version;
@@ -85,8 +86,8 @@ static int s2n_extensions_client_supported_versions_process(struct s2n_connectio
     S2N_ERROR_IF(size_of_version_list != s2n_stuffer_data_available(extension), S2N_ERR_BAD_MESSAGE);
     S2N_ERROR_IF(size_of_version_list % S2N_TLS_PROTOCOL_VERSION_LEN != 0, S2N_ERR_BAD_MESSAGE);
 
-    conn->client_protocol_version = s2n_unknown_protocol_version;
-    conn->actual_protocol_version = s2n_unknown_protocol_version;
+    uint8_t client_protocol_version = s2n_unknown_protocol_version;
+    uint8_t actual_protocol_version = s2n_unknown_protocol_version;
 
     for (int i = 0; i < size_of_version_list; i += S2N_TLS_PROTOCOL_VERSION_LEN) {
         uint8_t client_version_parts[S2N_TLS_PROTOCOL_VERSION_LEN];
@@ -101,7 +102,7 @@ static int s2n_extensions_client_supported_versions_process(struct s2n_connectio
 
         uint16_t client_version = (client_version_parts[0] * 10) + client_version_parts[1];
 
-        conn->client_protocol_version = MAX(client_version, conn->client_protocol_version);
+        client_protocol_version = MAX(client_version, client_protocol_version);
 
         if (client_version > highest_supported_version) {
             continue;
@@ -113,27 +114,58 @@ static int s2n_extensions_client_supported_versions_process(struct s2n_connectio
 
         /* We ignore the client's preferred order and instead choose
          * the highest version that both client and server support. */
-        conn->actual_protocol_version = MAX(client_version, conn->actual_protocol_version);
+        actual_protocol_version = MAX(client_version, actual_protocol_version);
     }
 
-    POSIX_ENSURE(conn->client_protocol_version != s2n_unknown_protocol_version, S2N_ERR_UNKNOWN_PROTOCOL_VERSION);
-    POSIX_ENSURE(conn->actual_protocol_version != s2n_unknown_protocol_version, S2N_ERR_PROTOCOL_VERSION_UNSUPPORTED);
+    *client_protocol_version_out = client_protocol_version;
+    *actual_protocol_version_out = actual_protocol_version;
 
     return S2N_SUCCESS;
 }
 
-static int s2n_client_supported_versions_recv(struct s2n_connection *conn, struct s2n_stuffer *in)
+static S2N_RESULT s2n_client_supported_versions_recv_impl(struct s2n_connection *conn, struct s2n_stuffer *extension)
 {
+    RESULT_ENSURE_REF(conn);
+    RESULT_ENSURE_REF(extension);
+
+    RESULT_GUARD_POSIX(s2n_extensions_client_supported_versions_process(conn, extension, &conn->client_protocol_version,
+            &conn->actual_protocol_version));
+
+    RESULT_ENSURE(conn->client_protocol_version != s2n_unknown_protocol_version, S2N_ERR_UNKNOWN_PROTOCOL_VERSION);
+    RESULT_ENSURE(conn->actual_protocol_version != s2n_unknown_protocol_version, S2N_ERR_PROTOCOL_VERSION_UNSUPPORTED);
+
+    return S2N_RESULT_OK;
+}
+
+static int s2n_client_supported_versions_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+    /* For backwards compatibility, the supported versions extension isn't used for protocol
+     * version selection if the server doesn't support TLS 1.3. This ensures that TLS 1.2 servers
+     * experience no behavior change due to processing the TLS 1.3 extension. See
+     * https://github.com/aws/s2n-tls/issues/4240.
+     *
+     *= https://www.rfc-editor.org/rfc/rfc8446#section-4.2.1
+     *= type=exception
+     *= reason=The client hello legacy version is used for version selection on TLS 1.2 servers for backwards compatibility
+     *# If this extension is present in the ClientHello, servers MUST NOT use
+     *# the ClientHello.legacy_version value for version negotiation and MUST
+     *# use only the "supported_versions" extension to determine client
+     *# preferences.
+     */
     if (s2n_connection_get_protocol_version(conn) < S2N_TLS13) {
         return S2N_SUCCESS;
     }
 
-    int result = s2n_extensions_client_supported_versions_process(conn, in);
-    if (result != S2N_SUCCESS) {
+    s2n_result result = s2n_client_supported_versions_recv_impl(conn, extension);
+    if (s2n_result_is_error(result)) {
+        conn->client_protocol_version = s2n_unknown_protocol_version;
+        conn->actual_protocol_version = s2n_unknown_protocol_version;
+
         s2n_queue_reader_unsupported_protocol_version_alert(conn);
         POSIX_ENSURE(s2n_errno != S2N_ERR_SAFETY, S2N_ERR_BAD_MESSAGE);
     }
-    POSIX_GUARD(result);
+    POSIX_GUARD_RESULT(result);
+
     return S2N_SUCCESS;
 }
 

+ 3 - 0
contrib/restricted/aws/s2n/tls/extensions/s2n_client_supported_versions.h

@@ -20,6 +20,9 @@
 
 extern const s2n_extension_type s2n_client_supported_versions_extension;
 
+int s2n_extensions_client_supported_versions_process(struct s2n_connection *conn, struct s2n_stuffer *extension,
+        uint8_t *client_protocol_version_out, uint8_t *actual_protocol_version_out);
+
 /* Old-style extension functions -- remove after extensions refactor is complete */
 int s2n_extensions_client_supported_versions_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
 int s2n_extensions_client_supported_versions_size(struct s2n_connection *conn);

+ 8 - 1
contrib/restricted/aws/s2n/tls/extensions/s2n_server_signature_algorithms.c

@@ -24,17 +24,24 @@
 #include "tls/s2n_tls_parameters.h"
 #include "utils/s2n_safety.h"
 
+static int s2n_signature_algorithms_send(struct s2n_connection *conn, struct s2n_stuffer *extension);
 static int s2n_signature_algorithms_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
 
 const s2n_extension_type s2n_server_signature_algorithms_extension = {
     .iana_value = TLS_EXTENSION_SIGNATURE_ALGORITHMS,
     .is_response = false,
-    .send = s2n_send_supported_sig_scheme_list,
+    .send = s2n_signature_algorithms_send,
     .recv = s2n_signature_algorithms_recv,
     .should_send = s2n_extension_always_send,
     .if_missing = s2n_extension_error_if_missing,
 };
 
+static int s2n_signature_algorithms_send(struct s2n_connection *conn, struct s2n_stuffer *extension)
+{
+    POSIX_GUARD_RESULT(s2n_signature_algorithms_supported_list_send(conn, extension));
+    return S2N_SUCCESS;
+}
+
 static int s2n_signature_algorithms_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
 {
     return s2n_recv_supported_sig_scheme_list(extension, &conn->handshake_params.server_sig_hash_algs);

+ 1 - 8
contrib/restricted/aws/s2n/tls/s2n_client_cert_verify.c

@@ -33,14 +33,7 @@ int s2n_client_cert_verify_recv(struct s2n_connection *conn)
 
     struct s2n_stuffer *in = &conn->handshake.io;
 
-    if (conn->actual_protocol_version < S2N_TLS12) {
-        POSIX_GUARD(s2n_choose_default_sig_scheme(conn,
-                &conn->handshake_params.client_cert_sig_scheme, S2N_CLIENT));
-    } else {
-        /* Verify the SigScheme picked by the Client was in the preference list we sent (or is the default SigScheme) */
-        POSIX_GUARD(s2n_get_and_validate_negotiated_signature_scheme(conn, in,
-                &conn->handshake_params.client_cert_sig_scheme));
-    }
+    POSIX_GUARD_RESULT(s2n_signature_algorithm_recv(conn, in));
     const struct s2n_signature_scheme *chosen_sig_scheme = conn->handshake_params.client_cert_sig_scheme;
     POSIX_ENSURE_REF(chosen_sig_scheme);
 

+ 53 - 4
contrib/restricted/aws/s2n/tls/s2n_connection.c

@@ -32,6 +32,7 @@
 #include "crypto/s2n_openssl_x509.h"
 #include "error/s2n_errno.h"
 #include "tls/extensions/s2n_client_server_name.h"
+#include "tls/extensions/s2n_client_supported_versions.h"
 #include "tls/s2n_alerts.h"
 #include "tls/s2n_cipher_suites.h"
 #include "tls/s2n_handshake.h"
@@ -619,17 +620,17 @@ int s2n_connection_set_send_cb(struct s2n_connection *conn, s2n_send_fn send)
     return S2N_SUCCESS;
 }
 
-int s2n_connection_get_client_cert_chain(struct s2n_connection *conn, uint8_t **der_cert_chain_out, uint32_t *cert_chain_len)
+int s2n_connection_get_client_cert_chain(struct s2n_connection *conn, uint8_t **cert_chain_out, uint32_t *cert_chain_len)
 {
     POSIX_ENSURE_REF(conn);
-    POSIX_ENSURE_REF(der_cert_chain_out);
+    POSIX_ENSURE_REF(cert_chain_out);
     POSIX_ENSURE_REF(cert_chain_len);
     POSIX_ENSURE_REF(conn->handshake_params.client_cert_chain.data);
 
-    *der_cert_chain_out = conn->handshake_params.client_cert_chain.data;
+    *cert_chain_out = conn->handshake_params.client_cert_chain.data;
     *cert_chain_len = conn->handshake_params.client_cert_chain.size;
 
-    return 0;
+    return S2N_SUCCESS;
 }
 
 int s2n_connection_get_cipher_preferences(struct s2n_connection *conn, const struct s2n_cipher_preferences **cipher_preferences)
@@ -938,10 +939,58 @@ const char *s2n_connection_get_kem_group_name(struct s2n_connection *conn)
     return conn->kex_params.client_kem_group_params.kem_group->name;
 }
 
+static S2N_RESULT s2n_connection_get_client_supported_version(struct s2n_connection *conn,
+        uint8_t *client_supported_version)
+{
+    RESULT_ENSURE_REF(conn);
+    RESULT_ENSURE_EQ(conn->mode, S2N_SERVER);
+
+    struct s2n_client_hello *client_hello = s2n_connection_get_client_hello(conn);
+    RESULT_ENSURE_REF(client_hello);
+
+    s2n_parsed_extension *supported_versions_extension = NULL;
+    RESULT_GUARD_POSIX(s2n_client_hello_get_parsed_extension(S2N_EXTENSION_SUPPORTED_VERSIONS, &client_hello->extensions,
+            &supported_versions_extension));
+    RESULT_ENSURE_REF(supported_versions_extension);
+
+    struct s2n_stuffer supported_versions_stuffer = { 0 };
+    RESULT_GUARD_POSIX(s2n_stuffer_init_written(&supported_versions_stuffer, &supported_versions_extension->extension));
+
+    uint8_t client_protocol_version = s2n_unknown_protocol_version;
+    uint8_t actual_protocol_version = s2n_unknown_protocol_version;
+    RESULT_GUARD_POSIX(s2n_extensions_client_supported_versions_process(conn, &supported_versions_stuffer,
+            &client_protocol_version, &actual_protocol_version));
+
+    RESULT_ENSURE_NE(client_protocol_version, s2n_unknown_protocol_version);
+
+    *client_supported_version = client_protocol_version;
+
+    return S2N_RESULT_OK;
+}
+
 int s2n_connection_get_client_protocol_version(struct s2n_connection *conn)
 {
     POSIX_ENSURE_REF(conn);
 
+    /* For backwards compatibility, the client_protocol_version field isn't updated via the
+     * supported versions extension on TLS 1.2 servers. See
+     * https://github.com/aws/s2n-tls/issues/4240.
+     *
+     * The extension is processed here to ensure that TLS 1.2 servers report the same client
+     * protocol version to applications as TLS 1.3 servers.
+     */
+    if (conn->mode == S2N_SERVER && conn->server_protocol_version <= S2N_TLS12) {
+        uint8_t client_supported_version = s2n_unknown_protocol_version;
+        s2n_result result = s2n_connection_get_client_supported_version(conn, &client_supported_version);
+
+        /* If the extension wasn't received, or if a client protocol version couldn't be determined
+         * after processing the extension, the extension is ignored.
+         */
+        if (s2n_result_is_ok(result)) {
+            return client_supported_version;
+        }
+    }
+
     return conn->client_protocol_version;
 }
 

+ 1 - 1
contrib/restricted/aws/s2n/tls/s2n_server_cert_request.c

@@ -172,7 +172,7 @@ int s2n_cert_req_send(struct s2n_connection *conn)
     }
 
     if (conn->actual_protocol_version == S2N_TLS12) {
-        POSIX_GUARD(s2n_send_supported_sig_scheme_list(conn, out));
+        POSIX_GUARD_RESULT(s2n_signature_algorithms_supported_list_send(conn, out));
     }
 
     /* RFC 5246 7.4.4 - If the certificate_authorities list is empty, then the

+ 0 - 3
contrib/restricted/aws/s2n/tls/s2n_server_hello.c

@@ -286,9 +286,6 @@ int s2n_server_hello_recv(struct s2n_connection *conn)
         POSIX_GUARD(s2n_prf_key_expansion(conn));
     }
 
-    /* Choose a default signature scheme */
-    POSIX_GUARD(s2n_choose_default_sig_scheme(conn, &conn->handshake_params.server_cert_sig_scheme, S2N_SERVER));
-
     /* Update the required hashes for this connection */
     POSIX_GUARD(s2n_conn_update_required_handshake_hashes(conn));
 

+ 1 - 5
contrib/restricted/aws/s2n/tls/s2n_server_key_exchange.c

@@ -48,11 +48,7 @@ int s2n_server_key_recv(struct s2n_connection *conn)
     struct s2n_kex_raw_server_data kex_data = { 0 };
     POSIX_GUARD_RESULT(s2n_kex_server_key_recv_read_data(key_exchange, conn, &data_to_verify, &kex_data));
 
-    /* Add common signature data */
-    if (conn->actual_protocol_version == S2N_TLS12) {
-        /* Verify the SigScheme picked by the Server was in the preference list we sent (or is the default SigScheme) */
-        POSIX_GUARD(s2n_get_and_validate_negotiated_signature_scheme(conn, in, &conn->handshake_params.server_cert_sig_scheme));
-    }
+    POSIX_GUARD_RESULT(s2n_signature_algorithm_recv(conn, in));
     const struct s2n_signature_scheme *active_sig_scheme = conn->handshake_params.server_cert_sig_scheme;
     POSIX_ENSURE_REF(active_sig_scheme);
 

Some files were not shown because too many files changed in this diff