File 2952-ssl-Implement-option-middlebox_comp_mode.patch of Package erlang
From dd83fea8259ebc8cc12fc6b0445c7d576a8a636a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C3=A9ter=20Dimitrov?= <peterdmv@erlang.org>
Date: Thu, 19 Mar 2020 12:37:25 +0100
Subject: [PATCH 2/3] ssl: Implement option 'middlebox_comp_mode'
---
 lib/ssl/doc/src/ssl.xml           | 11 +++++++++++
 lib/ssl/src/ssl.erl               |  6 +++++-
 lib/ssl/src/ssl_internal.hrl      |  3 ++-
 lib/ssl/src/tls_handshake_1_3.erl |  2 ++
 4 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/lib/ssl/doc/src/ssl.xml b/lib/ssl/doc/src/ssl.xml
index 6a8201e9d5..f0ebf5fc00 100644
--- a/lib/ssl/doc/src/ssl.xml
+++ b/lib/ssl/doc/src/ssl.xml
@@ -777,6 +777,17 @@ fun(srp, Username :: string(), UserState :: term()) ->
       </desc>
     </datatype>
 
+    <datatype>
+      <name name="middlebox_comp_mode"/>
+      <desc><p>Configures the middlebox compatibility mode on a TLS 1.3 connection.</p>
+      <p>A significant number of middleboxes misbehave when a TLS 1.3 connection is
+      negotiated. Implementations can increase the chance of making connections
+      through those middleboxes by making the TLS 1.3 handshake more like a
+      TLS 1.2 handshake.</p>
+      <p>The middlebox compatibility mode is enabled (<c>true</c>) by default.</p>
+      </desc>
+    </datatype>
+
     <datatype_title>TLS/DTLS OPTION DESCRIPTIONS - CLIENT</datatype_title>
     
     <datatype>
diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl
index ec95f841f7..d331d09e6b 100644
--- a/lib/ssl/src/ssl.erl
+++ b/lib/ssl/src/ssl.erl
@@ -318,7 +318,8 @@
                                 {beast_mitigation, beast_mitigation()} |
                                 {ssl_imp, ssl_imp()} |
                                 {session_tickets, session_tickets()} |
-                                {key_update_at, key_update_at()}.
+                                {key_update_at, key_update_at()} |
+                                {middlebox_comp_mode, middlebox_comp_mode()}.
 
 -type protocol()                  :: tls | dtls.
 -type handshake_completion()      :: hello | full.
@@ -370,6 +371,7 @@
                                      bloom_filter_hash_functions(), %% k - number of hash functions
                                      bloom_filter_bits()}.          %% m - number of bits in bit vector
 -type use_ticket()               :: [binary()].
+-type middlebox_comp_mode()      :: boolean().
 
 %% -------------------------------------------------------------------------------------------------------
 
@@ -2100,6 +2102,8 @@ validate_option(log_level, Value) when
        Value =:= info orelse
        Value =:= debug) ->
     Value;
+validate_option(middlebox_comp_mode, Value) when is_boolean(Value) ->
+    Value;
 validate_option(next_protocols_advertised, Value) when is_list(Value) ->
     validate_binary_list(next_protocols_advertised, Value),
     Value;
diff --git a/lib/ssl/src/ssl_internal.hrl b/lib/ssl/src/ssl_internal.hrl
index 9d04fe1122..cb41742404 100644
--- a/lib/ssl/src/ssl_internal.hrl
+++ b/lib/ssl/src/ssl_internal.hrl
@@ -124,6 +124,7 @@
         #{
           alpn_advertised_protocols  => {undefined, [versions]},
           alpn_preferred_protocols   => {undefined, [versions]},
+          anti_replay                => {undefined, [versions, session_tickets]},
           beast_mitigation           => {one_n_minus_one, [versions]},
           cacertfile                 => {undefined, [versions,
                                                      verify_fun,
@@ -153,6 +154,7 @@
           key_update_at              => {?KEY_USAGE_LIMIT_AES_GCM, [versions]},
           log_level                  => {notice,    [versions]},
           max_handshake_size         => {?DEFAULT_MAX_HANDSHAKE_SIZE, [versions]},
+          middlebox_comp_mode        => {true, [versions]},
           next_protocol_selector     => {undefined, [versions]},
           next_protocols_advertised  => {undefined, [versions]},
           padding_check              => {true,      [versions]},
@@ -163,7 +165,6 @@
           renegotiate_at             => {?DEFAULT_RENEGOTIATE_AT, [versions]},
           reuse_session              => {undefined, [versions]},
           reuse_sessions             => {true,      [versions]},
-          anti_replay                => {undefined, [versions, session_tickets]},
           secure_renegotiate         => {true,      [versions]},
           server_name_indication     => {undefined, [versions]},
           session_tickets            => {disabled,     [versions]},
diff --git a/lib/ssl/src/tls_handshake_1_3.erl b/lib/ssl/src/tls_handshake_1_3.erl
index 0fa01fe568..9a87d98dbe 100644
--- a/lib/ssl/src/tls_handshake_1_3.erl
+++ b/lib/ssl/src/tls_handshake_1_3.erl
@@ -1016,6 +1016,8 @@ maybe_queue_change_cipher_spec(#state{flight_buffer = FlightBuffer0} = State0) -
 %%      first ClientHello.
 %% @end
 maybe_prepend_change_cipher_spec(#state{
+                                    ssl_options =
+                                        #{middlebox_comp_mode := true},
                                     handshake_env =
                                         #handshake_env{
                                            change_cipher_spec_sent = false} = HSEnv} = State, Bin) ->
-- 
2.16.4