File 2911-ssl-Remove-SSL-3.0-support.patch of Package erlang

From ef628499fce1a1c942e546505bb383bc5b9c436c Mon Sep 17 00:00:00 2001
From: Ingela Anderton Andin <ingela@erlang.org>
Date: Fri, 13 Dec 2019 11:05:19 +0100
Subject: [PATCH] ssl: Remove SSL-3.0 support

---
 lib/ssl/doc/src/ssl.xml                            |  15 +-
 lib/ssl/doc/src/standards_compliance.xml           |   1 +
 lib/ssl/src/Makefile                               |   1 -
 lib/ssl/src/ssl.app.src                            |   1 -
 lib/ssl/src/ssl.erl                                |  47 +----
 lib/ssl/src/ssl_cipher.erl                         |   8 -
 lib/ssl/src/ssl_handshake.erl                      |  22 ---
 lib/ssl/src/ssl_internal.hrl                       |   4 +-
 lib/ssl/src/ssl_v3.erl                             | 200 ---------------------
 lib/ssl/src/tls_record.erl                         |   6 +-
 lib/ssl/test/openssl_alpn_SUITE.erl                |   1 -
 lib/ssl/test/openssl_cipher_suite_SUITE.erl        |   2 -
 lib/ssl/test/openssl_client_cert_SUITE.erl         |   2 -
 lib/ssl/test/openssl_reject_SUITE.erl              |  49 ++++-
 lib/ssl/test/openssl_renegotiate_SUITE.erl         |   9 +-
 lib/ssl/test/openssl_server_cert_SUITE.erl         |   2 -
 lib/ssl/test/openssl_session_SUITE.erl             |   9 +-
 .../test/property_test/ssl_eqc_cipher_format.erl   |   7 +-
 lib/ssl/test/property_test/ssl_eqc_handshake.erl   |  21 +--
 lib/ssl/test/ssl_alpn_SUITE.erl                    |  30 ----
 lib/ssl/test/ssl_api_SUITE.erl                     |   2 -
 lib/ssl/test/ssl_app_env_SUITE.erl                 |   2 -
 lib/ssl/test/ssl_basic_SUITE.erl                   |   3 +-
 lib/ssl/test/ssl_cert_SUITE.erl                    |   2 -
 lib/ssl/test/ssl_cipher_suite_SUITE.erl            |  20 ---
 lib/ssl/test/ssl_npn_SUITE.erl                     |  35 +---
 lib/ssl/test/ssl_packet_SUITE.erl                  |   2 -
 lib/ssl/test/ssl_payload_SUITE.erl                 |   6 +-
 lib/ssl/test/ssl_renegotiate_SUITE.erl             |   4 +-
 lib/ssl/test/ssl_session_SUITE.erl                 |   4 +-
 lib/ssl/test/ssl_test_lib.erl                      |  20 +--
 lib/ssl/test/tls_api_SUITE.erl                     |  39 +---
 system/doc/general_info/deprecations.xml           |  10 ++
 system/doc/general_info/scheduled_for_removal.xml  |   6 +
 34 files changed, 103 insertions(+), 489 deletions(-)
 delete mode 100644 lib/ssl/src/ssl_v3.erl

diff --git a/lib/ssl/doc/src/ssl.xml b/lib/ssl/doc/src/ssl.xml
index 0ad2d8da0b..11ea4669de 100644
--- a/lib/ssl/doc/src/ssl.xml
+++ b/lib/ssl/doc/src/ssl.xml
@@ -612,7 +612,7 @@ fun(Chain::[public_key:der_encoded()]) ->
       <desc><p>TLS protocol versions supported by started clients and servers.
       This option overrides the application environment option
       <c>protocol_version</c> and  <c>dtls_protocol_version</c>. If the environment option is not set, it defaults
-      to all versions, except SSL-3.0, supported by the SSL application.
+      to all versions, supported by the SSL application.
       See also <seealso marker="ssl:ssl_app">ssl(6).</seealso></p>
       </desc>
     </datatype>
@@ -701,7 +701,7 @@ fun(srp, Username :: string(), UserState :: term()) ->
 
     <datatype>
       <name name="beast_mitigation"/>
-      <desc><p>Affects SSL-3.0 and TLS-1.0 connections only. Used to change the BEAST
+      <desc><p>Affects TLS-1.0 connections only. Used to change the BEAST
        mitigation strategy to interoperate with legacy software.
        Defaults to <c>one_n_minus_one</c>.</p>
 
@@ -711,7 +711,7 @@ fun(srp, Username :: string(), UserState :: term()) ->
 
       <p><c>disabled</c> - Disable BEAST mitigation.</p>
 
-      <warning><p>Using <c>{beast_mitigation, disabled}</c> makes SSL-3.0 or TLS-1.0
+      <warning><p>Using <c>{beast_mitigation, disabled}</c> makes TLS-1.0
         vulnerable to the BEAST attack.</p></warning>
       </desc>
     </datatype>
@@ -860,10 +860,9 @@ fun(srp, Username :: string(), UserState :: term()) ->
 	  <warning><p>Note this option is not needed in normal TLS usage and should not be used
 	  to implement new clients. But legacy clients that retries connections in the following manner</p>
 	  
-	  <p><c> ssl:connect(Host, Port, [...{versions, ['tlsv2', 'tlsv1.1', 'tlsv1', 'sslv3']}])</c></p>
-	  <p><c>  ssl:connect(Host, Port, [...{versions, [tlsv1.1', 'tlsv1', 'sslv3']}, {fallback, true}])</c></p>
-	  <p><c>  ssl:connect(Host, Port, [...{versions, ['tlsv1', 'sslv3']}, {fallback, true}]) </c></p>
-	  <p><c>  ssl:connect(Host, Port, [...{versions, ['sslv3']}, {fallback, true}]) </c></p>
+	  <p><c> ssl:connect(Host, Port, [...{versions, ['tlsv2', 'tlsv1.1', 'tlsv1']}])</c></p>
+	  <p><c>  ssl:connect(Host, Port, [...{versions, [tlsv1.1', 'tlsv1']}, {fallback, true}])</c></p>
+	  <p><c>  ssl:connect(Host, Port, [...{versions, ['tlsv1']}, {fallback, true}]) </c></p>
 	  
 	  <p>may use it to avoid undesired TLS version downgrade. Note that TLS_FALLBACK_SCSV must also
 	  be supported by the server for the prevention to work.
@@ -1478,8 +1477,6 @@ fun(srp, Username :: string(), UserState :: term()) ->
 	  extra key material. It either takes user-generated values for
 	  <c>Secret</c> and <c>Seed</c> or atoms directing it to use a specific
 	  value from the session security parameters.</p>
-        <p>Can only be used with TLS/DTLS connections; <c>{error, undefined}</c>
-	  is returned for SSLv3 connections.</p>
       </desc>
     </func>
     
diff --git a/lib/ssl/doc/src/standards_compliance.xml b/lib/ssl/doc/src/standards_compliance.xml
index 9df48b99d3..22c83a1ff8 100644
--- a/lib/ssl/doc/src/standards_compliance.xml
+++ b/lib/ssl/doc/src/standards_compliance.xml
@@ -91,6 +91,7 @@
 
   <section>
     <title>SSL 3.0</title>
+    <p>For security reasons SSL-3.0 is no longer supported at all. (OTP 23) </p>
     <p>For security reasons SSL-3.0 is no longer supported by default, but can be configured. (OTP 19)</p>
   </section>
 
diff --git a/lib/ssl/src/Makefile b/lib/ssl/src/Makefile
index e961f05b37..c3fa65f262 100644
--- a/lib/ssl/src/Makefile
+++ b/lib/ssl/src/Makefile
@@ -83,7 +83,6 @@ MODULES= \
 	ssl_session_cache \
 	ssl_srp_primes \
 	ssl_sup \
-	ssl_v3 \
 	tls_bloom_filter \
 	tls_connection \
 	tls_connection_sup \
diff --git a/lib/ssl/src/ssl.app.src b/lib/ssl/src/ssl.app.src
index c45e6bcf9a..e35da9206e 100644
--- a/lib/ssl/src/ssl.app.src
+++ b/lib/ssl/src/ssl.app.src
@@ -11,7 +11,6 @@
 	       tls_record_1_3,
 	       tls_socket,
 	       tls_v1,
-	       ssl_v3,
 	       tls_connection_sup,
 	       tls_sender,
                tls_server_sup,
diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl
index 1a0c52ea40..8274832f1b 100644
--- a/lib/ssl/src/ssl.erl
+++ b/lib/ssl/src/ssl.erl
@@ -152,7 +152,7 @@
 -type protocol_version()         :: tls_version() | dtls_version(). % exported
 -type tls_version()              :: 'tlsv1.2' | 'tlsv1.3' | tls_legacy_version().
 -type dtls_version()             :: 'dtlsv1.2' | dtls_legacy_version().
--type tls_legacy_version()       ::  tlsv1 | 'tlsv1.1' | sslv3.
+-type tls_legacy_version()       ::  tlsv1 | 'tlsv1.1' .
 -type dtls_legacy_version()      :: 'dtlsv1'.
 -type verify_type()              :: verify_none | verify_peer.
 -type cipher()                   :: aes_128_cbc |
@@ -996,8 +996,7 @@ cipher_suites(all) ->
 cipher_suites(Base, Version) when Version == 'tlsv1.3';
                                   Version == 'tlsv1.2';
                                   Version == 'tlsv1.1';
-                                  Version == tlsv1;
-                                  Version == sslv3 ->
+                                  Version == tlsv1 ->
     cipher_suites(Base, tls_record:protocol_version(Version));
 cipher_suites(Base, Version)  when Version == 'dtlsv1.2';
                                    Version == 'dtlsv1'->
@@ -1015,8 +1014,7 @@ cipher_suites(Base, Version) ->
 %%--------------------------------------------------------------------
 cipher_suites(Base, Version, StringType) when Version == 'tlsv1.2';
                                               Version == 'tlsv1.1';
-                                                  Version == tlsv1;
-                                              Version == sslv3 ->
+                                              Version == tlsv1 ->
     cipher_suites(Base, tls_record:protocol_version(Version), StringType);
 cipher_suites(Base, Version, StringType)  when Version == 'dtlsv1.2';
                                                Version == 'dtlsv1'->
@@ -1102,8 +1100,6 @@ eccs() ->
 %% Description: returns the curves supported for a given version of
 %% ssl/tls.
 %%--------------------------------------------------------------------
-eccs(sslv3) ->
-    [];
 eccs('dtlsv1') ->
     eccs('tlsv1.1');
 eccs('dtlsv1.2') ->
@@ -1491,21 +1487,13 @@ handle_options(Opts0, Role, Host) ->
 
     %% Ensure all options are evaluated at startup
     SslOpts1 = add_missing_options(SslOpts0, ?RULES),
-    SslOpts = #{protocol := Protocol,
-                versions := Versions}
+    SslOpts = #{protocol := Protocol}
         = process_options(SslOpts1,
                           #{},
                           #{role => Role,
                             host => Host,
                             rules => ?RULES}),
-
-    case Versions of
-        [{3, 0}] ->
-            reject_alpn_next_prot_options(SslOpts0);
-        _ ->
-            ok
-    end,
-
+    
     %% Handle special options
     {Sock, Emulated} = emulated_options(Protocol, SockOpts),
     ConnetionCb = connection_cb(Protocol),
@@ -2192,8 +2180,7 @@ validate_versions([], Versions) ->
 validate_versions([Version | Rest], Versions) when Version == 'tlsv1.3';
                                                    Version == 'tlsv1.2';
                                                    Version == 'tlsv1.1';
-                                                   Version == tlsv1;
-                                                   Version == sslv3 ->
+                                                   Version == tlsv1 ->
     tls_validate_versions(Rest, Versions);                                      
 validate_versions([Version | Rest], Versions) when Version == 'dtlsv1';
                                                    Version == 'dtlsv1.2'->
@@ -2206,8 +2193,7 @@ tls_validate_versions([], Versions) ->
 tls_validate_versions([Version | Rest], Versions) when Version == 'tlsv1.3';
                                                        Version == 'tlsv1.2';
                                                        Version == 'tlsv1.1';
-                                                       Version == tlsv1;
-                                                       Version == sslv3 ->
+                                                       Version == tlsv1 ->
     tls_validate_versions(Rest, Versions);                  
 tls_validate_versions([Ver| _], Versions) ->
     throw({error, {options, {Ver, {versions, Versions}}}}).
@@ -2465,25 +2451,6 @@ server_name_indication_default(Host) when is_list(Host) ->
 server_name_indication_default(_) ->
     undefined.
 
-
-reject_alpn_next_prot_options({Opts,_,_}) ->
-    AlpnNextOpts = [alpn_advertised_protocols,
-                    alpn_preferred_protocols,
-                    next_protocols_advertised,
-                    next_protocol_selector,
-                    client_preferred_next_protocols],
-    reject_alpn_next_prot_options(AlpnNextOpts, Opts).
-
-reject_alpn_next_prot_options([], _) ->
-    ok;
-reject_alpn_next_prot_options([Opt| AlpnNextOpts], Opts) ->
-    case lists:keyfind(Opt, 1, Opts) of
-        {Opt, Value} ->
-            throw({error, {options, {not_supported_in_sslv3, {Opt, Value}}}});
-        false ->
-            reject_alpn_next_prot_options(AlpnNextOpts, Opts)
-    end.
-
 add_filter(undefined, Filters) ->
     Filters;
 add_filter(Filter, Filters) ->
diff --git a/lib/ssl/src/ssl_cipher.erl b/lib/ssl/src/ssl_cipher.erl
index ac3eb1f5a6..35a3f9027f 100644
--- a/lib/ssl/src/ssl_cipher.erl
+++ b/lib/ssl/src/ssl_cipher.erl
@@ -296,8 +296,6 @@ block_decipher(Fun, #cipher_state{key=Key, iv=IV} = CipherState0,
 %%
 %% Description: Returns a list of supported cipher suites.
 %%--------------------------------------------------------------------
-suites({3, 0}) ->
-    ssl_v3:suites();
 suites({3, Minor}) ->
     tls_v1:suites(Minor);
 suites({_, Minor}) ->
@@ -445,8 +443,6 @@ psk_suites_anon(0) ->
 %% Description: Returns a list of the SRP cipher suites, only supported
 %% if explicitly set by user.
 %%--------------------------------------------------------------------
-srp_suites({3,0}) ->
-    [];
 srp_suites(_) ->
     [?TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA,
      ?TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA,
@@ -461,8 +457,6 @@ srp_suites(_) ->
 %% Description: Returns a list of the SRP anonymous cipher suites, only supported
 %% if explicitly set by user.
 %%--------------------------------------------------------------------
-srp_suites_anon({3,0}) ->
-    [];
 srp_suites_anon(_) ->
     [?TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA,
      ?TLS_SRP_SHA_WITH_AES_128_CBC_SHA,
@@ -741,8 +735,6 @@ hash_size(sha512) ->
 mac_hash({_,_}, ?NULL, _MacSecret, _SeqNo, _Type,
 	 _Length, _Fragment) ->
     <<>>;
-mac_hash({3, 0}, MacAlg, MacSecret, SeqNo, Type, Length, Fragment) ->
-    ssl_v3:mac_hash(MacAlg, MacSecret, SeqNo, Type, Length, Fragment);
 mac_hash({3, N} = Version, MacAlg, MacSecret, SeqNo, Type, Length, Fragment)  
   when N =:= 1; N =:= 2; N =:= 3; N =:= 4 ->
     tls_v1:mac_hash(MacAlg, MacSecret, SeqNo, Type, Version,
diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl
index 5bbb8c506f..26d7e62d68 100644
--- a/lib/ssl/src/ssl_handshake.erl
+++ b/lib/ssl/src/ssl_handshake.erl
@@ -948,8 +948,6 @@ cipher_suites(Suites, true) ->
 %%
 %% Description: use the TLS PRF to generate key material
 %%--------------------------------------------------------------------
-prf({3,0}, _, _, _, _, _) ->
-    {error, undefined};
 prf({3,_N}, PRFAlgo, Secret, Label, Seed, WantedLength) ->
     {ok, tls_v1:prf(PRFAlgo, Secret, Label, Seed, WantedLength)}.
 
@@ -1910,13 +1908,8 @@ encrypted_premaster_secret(Secret, RSAPublicKey) ->
             throw(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE, premaster_encryption_failed))
     end.
 
-calc_certificate_verify({3, 0}, HashAlgo, MasterSecret, Handshake) ->
-    ssl_v3:certificate_verify(HashAlgo, MasterSecret, lists:reverse(Handshake));
 calc_certificate_verify({3, N}, HashAlgo, _MasterSecret, Handshake) ->
     tls_v1:certificate_verify(HashAlgo, N, lists:reverse(Handshake)).
-
-calc_finished({3, 0}, Role, _PrfAlgo, MasterSecret, Handshake) ->
-    ssl_v3:finished(Role, MasterSecret, lists:reverse(Handshake));
 calc_finished({3, N}, Role, PrfAlgo, MasterSecret, Handshake) ->
     tls_v1:finished(Role, N, PrfAlgo, MasterSecret, lists:reverse(Handshake)).
 
@@ -1946,20 +1939,10 @@ master_secret(Version, MasterSecret,
     {MasterSecret,
      ssl_record:set_pending_cipher_state(ConnStates2, ClientCipherState,
 					 ServerCipherState, Role)}.
-
-setup_keys({3,0}, _PrfAlgo, MasterSecret,
-	   ServerRandom, ClientRandom, HashSize, KML, EKML, IVS) ->
-    ssl_v3:setup_keys(MasterSecret, ServerRandom,
-			ClientRandom, HashSize, KML, EKML, IVS);
-
 setup_keys({3,N}, PrfAlgo, MasterSecret,
 	   ServerRandom, ClientRandom, HashSize, KML, _EKML, IVS) ->
     tls_v1:setup_keys(N, PrfAlgo, MasterSecret, ServerRandom, ClientRandom, HashSize,
 			KML, IVS).
-
-calc_master_secret({3,0}, _PrfAlgo, PremasterSecret, ClientRandom, ServerRandom) ->
-    ssl_v3:master_secret(PremasterSecret, ClientRandom, ServerRandom);
-
 calc_master_secret({3,_}, PrfAlgo, PremasterSecret, ClientRandom, ServerRandom) ->
     tls_v1:master_secret(PrfAlgo, PremasterSecret, ClientRandom, ServerRandom).
 	
@@ -3182,9 +3165,6 @@ handle_renegotiation_info(_, _RecordCB, server, #renegotiation_info{renegotiated
                       throw(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE, server_renegotiation))
 	      end
       end;
-handle_renegotiation_info({3,0}, _RecordCB, client, undefined, ConnectionStates, true, _SecureRenegotation, _) ->
-    {ok, ssl_record:set_renegotiation_flag(true, ConnectionStates)};
-
 handle_renegotiation_info(_, RecordCB, client, undefined, ConnectionStates, true, SecureRenegotation, _) ->
     handle_renegotiation_info(RecordCB, ConnectionStates, SecureRenegotation);
 
@@ -3271,8 +3251,6 @@ empty_extensions({3,4}, hello_retry_request) ->
       key_share => undefined,
       pre_shared_key => undefined
      };
-empty_extensions({3,0}, _) ->
-    empty_extensions();
 empty_extensions(_, server_hello) ->
     #{renegotiation_info => undefined,
       alpn => undefined,
diff --git a/lib/ssl/src/ssl_internal.hrl b/lib/ssl/src/ssl_internal.hrl
index ceca206605..7ad7378382 100644
--- a/lib/ssl/src/ssl_internal.hrl
+++ b/lib/ssl/src/ssl_internal.hrl
@@ -75,7 +75,7 @@
 %% Keep as interop with legacy software but do not support as default
 %% tlsv1.0 and tlsv1.1 is now also considered legacy
 %% tlsv1.3 is under development (experimental).
--define(ALL_AVAILABLE_VERSIONS, ['tlsv1.3', 'tlsv1.2', 'tlsv1.1', tlsv1, sslv3]).
+-define(ALL_AVAILABLE_VERSIONS, ['tlsv1.3', 'tlsv1.2', 'tlsv1.1', tlsv1]).
 -define(ALL_AVAILABLE_DATAGRAM_VERSIONS, ['dtlsv1.2', dtlsv1]).
 %% Defines the default versions when not specified by an ssl option.
 -define(ALL_SUPPORTED_VERSIONS, ['tlsv1.2']).
@@ -86,7 +86,7 @@
 %% TLS 1.3 sets TLSCiphertext.legacy_record_version to 0x0303 for all records
 %% generated other than an than an initial ClientHello, where it MAY also be 0x0301.
 %% Thus, the allowed range is limited to 0x0300 - 0x0303.
--define(ALL_TLS_RECORD_VERSIONS, ['tlsv1.2', 'tlsv1.1', tlsv1, sslv3]).
+-define(ALL_TLS_RECORD_VERSIONS, ['tlsv1.2', 'tlsv1.1', tlsv1]).
 
 -define(ALL_DATAGRAM_SUPPORTED_VERSIONS, ['dtlsv1.2']).
 -define(MIN_DATAGRAM_SUPPORTED_VERSIONS, [dtlsv1]).
diff --git a/lib/ssl/src/ssl_v3.erl b/lib/ssl/src/ssl_v3.erl
deleted file mode 100644
index 4eab60b440..0000000000
--- a/lib/ssl/src/ssl_v3.erl
+++ /dev/null
@@ -1,200 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2018. 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.
-%% You may obtain a copy of the License at
-%%
-%%     http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License 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.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%%----------------------------------------------------------------------
-%% Purpose: Handles sslv3 encryption.
-%%----------------------------------------------------------------------
-
--module(ssl_v3).
-
--include("ssl_cipher.hrl").
--include("ssl_internal.hrl").
--include("ssl_record.hrl"). 			% MD5 and SHA
-
--export([master_secret/3, finished/3, certificate_verify/3,
-	 mac_hash/6, setup_keys/7,
-	 suites/0]).
--compile(inline).
-
-%%====================================================================
-%% Internal application API
-%%====================================================================
-
--spec master_secret(binary(), binary(), binary()) -> binary().
-
-master_secret(PremasterSecret, ClientRandom, ServerRandom) ->
-    %%  draft-ietf-tls-ssl-version3-00 - 6.2.2
-    %% key_block =
-    %%   MD5(master_secret + SHA(`A' + master_secret +
-    %%                           ServerHello.random +
-    %%                           ClientHello.random)) +
-    %%   MD5(master_secret + SHA(`BB' + master_secret +
-    %%                           ServerHello.random +
-    %%                           ClientHello.random)) +
-    %%   MD5(master_secret + SHA(`CCC' + master_secret +
-    %%                           ServerHello.random +
-    %%                           ClientHello.random)) + [...];
-    Block = generate_keyblock(PremasterSecret, ClientRandom, ServerRandom, 48),
-    Block.
-
--spec finished(client | server, binary(), [binary()]) -> binary().
-
-finished(Role, MasterSecret, Handshake) ->
-   %%  draft-ietf-tls-ssl-version3-00 - 5.6.9 Finished
-   %%     struct {
-   %%      opaque md5_hash[16];
-   %%      opaque sha_hash[20];
-   %%  } Finished;
-   %%
-   %%   md5_hash       MD5(master_secret + pad2 +
-   %%                     MD5(handshake_messages + Sender +
-   %%                         master_secret + pad1));
-   %%  sha_hash        SHA(master_secret + pad2 +
-   %%                      SHA(handshake_messages + Sender +
-   %%                          master_secret + pad1));
-    Sender = get_sender(Role),
-    MD5 = handshake_hash(?MD5, MasterSecret, Sender, Handshake),
-    SHA = handshake_hash(?SHA, MasterSecret, Sender, Handshake),
-    <<MD5/binary, SHA/binary>>.
-
--spec certificate_verify(md5sha | sha, binary(), [binary()]) -> binary().
-
-certificate_verify(md5sha, MasterSecret, Handshake) ->
-     %% md5_hash
-     %%           MD5(master_secret + pad_2 +
-     %%               MD5(handshake_messages + master_secret + pad_1));
-     %% sha_hash
-     %%           SHA(master_secret + pad_2 +
-     %%               SHA(handshake_messages + master_secret + pad_1));
-
-    MD5 = handshake_hash(?MD5, MasterSecret, undefined, Handshake),
-    SHA = handshake_hash(?SHA, MasterSecret, undefined, Handshake),
-    <<MD5/binary, SHA/binary>>;
-
-certificate_verify(sha, MasterSecret, Handshake) ->
-     %% sha_hash
-     %%           SHA(master_secret + pad_2 +
-     %%               SHA(handshake_messages + master_secret + pad_1));
-
-    handshake_hash(?SHA, MasterSecret, undefined, Handshake).
-
--spec mac_hash(integer(), binary(), integer(), integer(), integer(), binary()) -> binary().
-
-mac_hash(Method, Mac_write_secret, Seq_num, Type, Length, Fragment) ->
-    %% draft-ietf-tls-ssl-version3-00 - 5.2.3.1
-    %% hash(MAC_write_secret + pad_2 +
-    %%      hash(MAC_write_secret + pad_1 + seq_num +
-    %%           SSLCompressed.type + SSLCompressed.length +
-    %%           SSLCompressed.fragment));
-    Mac = mac_hash(Method, Mac_write_secret,
-		   [<<?UINT64(Seq_num), ?BYTE(Type),
-		     ?UINT16(Length)>>, Fragment]),
-    Mac.
-
--spec setup_keys(binary(), binary(), binary(),
-		 integer(), integer(), term(), integer()) ->
-			{binary(), binary(), binary(),
-			 binary(), binary(), binary()}.
-
-setup_keys(MasterSecret, ServerRandom, ClientRandom, HS, KML, _EKML, IVS) ->
-    KeyBlock = generate_keyblock(MasterSecret, ServerRandom, ClientRandom,
-				 2*(HS+KML+IVS)),
-    %%  draft-ietf-tls-ssl-version3-00 - 6.2.2
-    %% The key_block is partitioned as follows.
-    %% client_write_MAC_secret[CipherSpec.hash_size]
-    %% server_write_MAC_secret[CipherSpec.hash_size]
-    %% client_write_key[CipherSpec.key_material]
-    %% server_write_key[CipherSpec.key_material]
-    %% client_write_IV[CipherSpec.IV_size] /* non-export ciphers */
-    %% server_write_IV[CipherSpec.IV_size] /* non-export ciphers */
-    <<ClientWriteMacSecret:HS/binary, ServerWriteMacSecret:HS/binary,
-     ClientWriteKey:KML/binary, ServerWriteKey:KML/binary,
-     ClientIV:IVS/binary, ServerIV:IVS/binary>> = KeyBlock,
-    {ClientWriteMacSecret, ServerWriteMacSecret, ClientWriteKey,
-     ServerWriteKey, ClientIV, ServerIV}.
-
--spec suites() -> [ssl_cipher_format:cipher_suite()].
-
-suites() ->
-    [
-      ?TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
-      ?TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
-      ?TLS_RSA_WITH_AES_256_CBC_SHA,
-      ?TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
-      ?TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
-      ?TLS_RSA_WITH_3DES_EDE_CBC_SHA,
-      ?TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
-      ?TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
-      ?TLS_RSA_WITH_AES_128_CBC_SHA
-     ].
-
-%%--------------------------------------------------------------------
-%%% Internal functions
-%%--------------------------------------------------------------------
-
-hash(?MD5, Data) ->
-    crypto:hash(md5, Data);
-hash(?SHA, Data) ->
-    crypto:hash(sha, Data).
-
-%%pad_1(?NULL) ->
-%%    "";
-pad_1(?MD5) ->
-    <<"666666666666666666666666666666666666666666666666">>;
-pad_1(?SHA) ->
-    <<"6666666666666666666666666666666666666666">>.
-%%pad_2(?NULL) ->
-%%    "";
-pad_2(?MD5) ->
-    <<"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
-     "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\">>;
-pad_2(?SHA) ->
-    <<"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
-     "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\">>.
-
-mac_hash(?NULL, _Secret, _Data) ->
-    <<>>;
-mac_hash(Method, Secret, Data) ->
-    InnerHash = hash(Method, [Secret, pad_1(Method), Data]),
-    hash(Method, [Secret, pad_2(Method), InnerHash]).
-
-handshake_hash(Method, MasterSecret, undefined, Handshake) ->
-    InnerHash = hash(Method, [Handshake, MasterSecret, pad_1(Method)]),
-    hash(Method, [MasterSecret, pad_2(Method), InnerHash]);
-handshake_hash(Method, MasterSecret, Sender, Handshake) ->
-    InnerHash = hash(Method, [Handshake, Sender, MasterSecret, pad_1(Method)]),
-    hash(Method, [MasterSecret, pad_2(Method), InnerHash]).
-
-get_sender(client) -> "CLNT";
-get_sender(server) -> "SRVR".
-
-generate_keyblock(MasterSecret, ServerRandom, ClientRandom, WantedLength) ->
-    gen(MasterSecret, [MasterSecret, ServerRandom, ClientRandom],
-	WantedLength, 0, $A, 1, []).
-
-gen(_Secret, _All, Wanted, Len, _C, _N, Acc) when Wanted =< Len ->
-    <<Block:Wanted/binary, _/binary>> = list_to_binary(lists:reverse(Acc)),
-    Block;
-gen(Secret, All, Wanted, Len, C, N, Acc) ->
-    Prefix = lists:duplicate(N, C),
-    SHA = crypto:hash(sha, [Prefix, All]),
-    MD5 = crypto:hash(md5, [Secret, SHA]),
-    gen(Secret, All, Wanted, Len + 16, C+1, N+1, [MD5 | Acc]).
diff --git a/lib/ssl/src/tls_record.erl b/lib/ssl/src/tls_record.erl
index e8040b461d..e980762fb8 100644
--- a/lib/ssl/src/tls_record.erl
+++ b/lib/ssl/src/tls_record.erl
@@ -468,7 +468,7 @@ validate_tls_records_type(Versions, Q, SslOpts, Acc, Type, Version, Length) ->
             validate_tls_record_version(Versions, Q, SslOpts, Acc, Type, Version, Length);
         true ->
             %% Not ?KNOWN_RECORD_TYPE(Type)
-            ?ALERT_REC(?FATAL, ?UNEXPECTED_MESSAGE)
+            ?ALERT_REC(?FATAL, ?UNEXPECTED_MESSAGE, {unsupported_record_type, Type})
     end.
 
 validate_tls_record_version(_Versions, Q, _SslOpts, Acc, Type, undefined, _Length) ->
@@ -481,7 +481,7 @@ validate_tls_record_version(Versions, Q, SslOpts, Acc, Type, Version, Length) ->
                 true ->
                     validate_tls_record_length(Versions, Q, SslOpts, Acc, Type, Version, Length);
                 false ->
-                    ?ALERT_REC(?FATAL, ?BAD_RECORD_MAC)
+                    ?ALERT_REC(?FATAL, ?BAD_RECORD_MAC, {unsupported_version, Version})
             end;
         {3, 4} when Version =:= {3, 3} ->
             validate_tls_record_length(Versions, Q, SslOpts, Acc, Type, Version, Length);
@@ -489,7 +489,7 @@ validate_tls_record_version(Versions, Q, SslOpts, Acc, Type, Version, Length) ->
             %% Exact version match
             validate_tls_record_length(Versions, Q, SslOpts, Acc, Type, Version, Length);
         _ ->
-            ?ALERT_REC(?FATAL, ?BAD_RECORD_MAC)
+            ?ALERT_REC(?FATAL, ?BAD_RECORD_MAC, {unsupported_version, Version})
     end.
 
 validate_tls_record_length(_Versions, Q, _SslOpts, Acc, Type, Version, undefined) ->
diff --git a/lib/ssl/test/openssl_alpn_SUITE.erl b/lib/ssl/test/openssl_alpn_SUITE.erl
index 3813562cda..475ed06df4 100644
--- a/lib/ssl/test/openssl_alpn_SUITE.erl
+++ b/lib/ssl/test/openssl_alpn_SUITE.erl
@@ -35,7 +35,6 @@
 %%--------------------------------------------------------------------
 
 all() ->
-    %% Note: ALPN not supported in sslv3
     case ssl_test_lib:openssl_sane_dtls_alpn() of 
         true ->
             [
diff --git a/lib/ssl/test/openssl_cipher_suite_SUITE.erl b/lib/ssl/test/openssl_cipher_suite_SUITE.erl
index 5c10defd2f..6daf1a56b4 100644
--- a/lib/ssl/test/openssl_cipher_suite_SUITE.erl
+++ b/lib/ssl/test/openssl_cipher_suite_SUITE.erl
@@ -42,7 +42,6 @@ all_protocol_groups() ->
     [{group, 'tlsv1.2'},
      {group, 'tlsv1.1'},
      {group, 'tlsv1'},
-     {group, 'sslv3'},
      {group, 'dtlsv1.2'},
      {group, 'dtlsv1'}
      ].
@@ -56,7 +55,6 @@ groups() ->
      {'tlsv1.2', [], kex()},
      {'tlsv1.1', [], kex()},
      {'tlsv1', [], kex()},
-     {'sslv3', [], kex()},
      {'dtlsv1.2', [], dtls_kex()},
      {'dtlsv1', [], dtls_kex()},
      {dhe_rsa, [],[dhe_rsa_3des_ede_cbc, 
diff --git a/lib/ssl/test/openssl_client_cert_SUITE.erl b/lib/ssl/test/openssl_client_cert_SUITE.erl
index dce40b5638..a094b8ab39 100644
--- a/lib/ssl/test/openssl_client_cert_SUITE.erl
+++ b/lib/ssl/test/openssl_client_cert_SUITE.erl
@@ -41,7 +41,6 @@ groups() ->
      {'tlsv1.2', [], pre_tls_1_3_protocol_groups()},
      {'tlsv1.1', [], pre_tls_1_3_protocol_groups()},
      {'tlsv1', [], pre_tls_1_3_protocol_groups()},
-     {'sslv3', [], ssl_protocol_groups()},
      {'dtlsv1.2', [], pre_tls_1_3_protocol_groups()},
      {'dtlsv1', [], pre_tls_1_3_protocol_groups()},
      {rsa, [], all_version_tests()},
@@ -57,7 +56,6 @@ protocol_groups() ->
      {group, 'tlsv1.2'},
      {group, 'tlsv1.1'},
      {group, 'tlsv1'},
-     {group, 'sslv3'},
      {group, 'dtlsv1.2'},
      {group, 'dtlsv1'}
      ].
diff --git a/lib/ssl/test/openssl_reject_SUITE.erl b/lib/ssl/test/openssl_reject_SUITE.erl
index deefd11823..a637035f3c 100644
--- a/lib/ssl/test/openssl_reject_SUITE.erl
+++ b/lib/ssl/test/openssl_reject_SUITE.erl
@@ -36,20 +36,20 @@
 all() -> 
     [{group, 'tlsv1.2'},
      {group, 'tlsv1.1'},
-     {group, 'tlsv1'},
-     {group, 'sslv3'}].
+     {group, 'tlsv1'}
+     ].
 
 groups() ->
     [{'tlsv1.2', [], all_versions_tests()},
      {'tlsv1.1', [], all_versions_tests()},
-     {'tlsv1', [], all_versions_tests()},
-     {'sslv3', [], all_versions_tests()}
+     {'tlsv1', [], all_versions_tests()}
     ].
- 
+
 all_versions_tests() ->
-    [    
+    [
      erlang_client_bad_openssl_server,
-     ssl2_erlang_server_openssl_client
+     ssl2_erlang_server_openssl_client,
+     ssl3_erlang_server_openssl_client
     ].
 
 init_per_suite(Config0) ->
@@ -110,6 +110,14 @@ special_init(ssl2_erlang_server_openssl_client, Config) ->
         false ->
             {skip, "sslv2 not supported by openssl"}
      end;
+special_init(ssl3_erlang_server_openssl_client, Config) ->
+    case ssl_test_lib:supports_ssl_tls_version(sslv3) of
+        true ->
+            Config;
+        false ->
+            {skip, "sslv3 not supported by openssl"}
+     end;
+
 special_init(_, Config) ->
      Config.
 
@@ -193,9 +201,34 @@ ssl2_erlang_server_openssl_client(Config) when is_list(Config) ->
 
     ct:log("Ports ~p~n", [[erlang:port_info(P) || P <- erlang:ports()]]), 
     ssl_test_lib:consume_port_exit(OpenSslPort),
-    ssl_test_lib:check_server_alert(Server, unexpected_message),
+    ssl_test_lib:check_server_alert(Server, bad_record_mac),
     process_flag(trap_exit, false).
 
+%%--------------------------------------------------------------------
+ssl3_erlang_server_openssl_client() ->
+    [{doc,"Test that ssl v3 clients are rejected"}].
+
+ssl3_erlang_server_openssl_client(Config) when is_list(Config) ->
+    process_flag(trap_exit, true),
+    ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+
+    {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+    Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0}, 
+                                              {from, self()},
+                                              {options, ServerOpts}]),
+    Port = ssl_test_lib:inet_port(Server),
+
+    Exe = "openssl",
+    Args = ["s_client", "-connect", ssl_test_lib:hostname_format(Hostname) ++ ":" ++ integer_to_list(Port), 
+            "-ssl3", "-msg"],
+
+    OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),  
+
+    ct:log("Ports ~p~n", [[erlang:port_info(P) || P <- erlang:ports()]]), 
+    ssl_test_lib:consume_port_exit(OpenSslPort),
+    ssl_test_lib:check_server_alert(Server, bad_record_mac),
+    process_flag(trap_exit, false).
 
 %%--------------------------------------------------------------------
 %% Internal functions ------------------------------------------------
diff --git a/lib/ssl/test/openssl_renegotiate_SUITE.erl b/lib/ssl/test/openssl_renegotiate_SUITE.erl
index f40d0b1575..f548b75abe 100644
--- a/lib/ssl/test/openssl_renegotiate_SUITE.erl
+++ b/lib/ssl/test/openssl_renegotiate_SUITE.erl
@@ -40,14 +40,13 @@ all() ->
             [{group, 'tlsv1.2'},
              {group, 'tlsv1.1'},
              {group, 'tlsv1'},
-             {group, 'sslv3'},
              {group, 'dtlsv1.2'},
              {group, 'dtlsv1'}];
         false ->
             [{group, 'tlsv1.2'},
              {group, 'tlsv1.1'},
-             {group, 'tlsv1'},
-             {group, 'sslv3'}]
+             {group, 'tlsv1'}
+             ]
     end.
 
 groups() ->
@@ -56,15 +55,13 @@ groups() ->
              [{'tlsv1.2', [], all_versions_tests()},
               {'tlsv1.1', [], all_versions_tests()},
               {'tlsv1', [], all_versions_tests()},
-              {'sslv3', [], all_versions_tests()},
               {'dtlsv1.2', [], all_versions_tests()},
               {'dtlsv1', [], all_versions_tests()}
              ];
         false ->
              [{'tlsv1.2', [], all_versions_tests()},
               {'tlsv1.1', [], all_versions_tests()},
-              {'tlsv1', [], all_versions_tests()},
-              {'sslv3', [], all_versions_tests()}
+              {'tlsv1', [], all_versions_tests()}
            ]
      end.
  
diff --git a/lib/ssl/test/openssl_server_cert_SUITE.erl b/lib/ssl/test/openssl_server_cert_SUITE.erl
index 8e97f70064..b0713ab37d 100644
--- a/lib/ssl/test/openssl_server_cert_SUITE.erl
+++ b/lib/ssl/test/openssl_server_cert_SUITE.erl
@@ -40,7 +40,6 @@ groups() ->
      {'tlsv1.2', [], pre_tls_1_3_protocol_groups()},
      {'tlsv1.1', [], pre_tls_1_3_protocol_groups()},
      {'tlsv1', [], pre_tls_1_3_protocol_groups()},
-     {'sslv3', [], ssl_protocol_groups()},
      {'dtlsv1.2', [], pre_tls_1_3_protocol_groups()},
      {'dtlsv1', [], pre_tls_1_3_protocol_groups()},
      {rsa, [], all_version_tests()},
@@ -58,7 +57,6 @@ protocol_groups() ->
      {group, 'tlsv1.2'},
      {group, 'tlsv1.1'},
      {group, 'tlsv1'},
-     {group, 'sslv3'},
      {group, 'dtlsv1.2'},
      {group, 'dtlsv1'}
      ].
diff --git a/lib/ssl/test/openssl_session_SUITE.erl b/lib/ssl/test/openssl_session_SUITE.erl
index 6f74408cb4..d524e6c039 100644
--- a/lib/ssl/test/openssl_session_SUITE.erl
+++ b/lib/ssl/test/openssl_session_SUITE.erl
@@ -39,14 +39,13 @@ all() ->
             [{group, 'tlsv1.2'},
              {group, 'tlsv1.1'},
              {group, 'tlsv1'},
-             {group, 'sslv3'},
              {group, 'dtlsv1.2'},
              {group, 'dtlsv1'}];
         false ->
             [{group, 'tlsv1.2'},
              {group, 'tlsv1.1'},
-             {group, 'tlsv1'},
-             {group, 'sslv3'}]
+             {group, 'tlsv1'}
+             ]
     end.
 
 groups() ->
@@ -55,15 +54,13 @@ groups() ->
              [{'tlsv1.2', [], tests()},
               {'tlsv1.1', [], tests()},
               {'tlsv1', [], tests()},
-              {'sslv3', [], tests()},
               {'dtlsv1.2', [], tests()},
               {'dtlsv1', [], tests()}
              ];
         false ->
              [{'tlsv1.2', [], tests()},
               {'tlsv1.1', [], tests()},
-              {'tlsv1', [], tests()},
-              {'sslv3', [], tests()}
+              {'tlsv1', [], tests()}
            ]
      end.
  
diff --git a/lib/ssl/test/property_test/ssl_eqc_cipher_format.erl b/lib/ssl/test/property_test/ssl_eqc_cipher_format.erl
index f225065ba6..b661ec8806 100644
--- a/lib/ssl/test/property_test/ssl_eqc_cipher_format.erl
+++ b/lib/ssl/test/property_test/ssl_eqc_cipher_format.erl
@@ -55,14 +55,13 @@
 -define('TLS_v1.2', 'tlsv1.2').
 -define('TLS_v1.1', 'tlsv1.1').
 -define('TLS_v1',   'tlsv1').
--define('SSL_v3',   'sslv3').
 
 %%--------------------------------------------------------------------
 %% Properties --------------------------------------------------------
 %%--------------------------------------------------------------------
 
 prop_tls_cipher_suite_rfc_name() ->
-    ?FORALL({CipherSuite, TLSVersion}, ?LET(Version, tls_version(), {cipher_suite(Version), Version}),
+    ?FORALL({CipherSuite, _TLSVersion}, ?LET(Version, tls_version(), {cipher_suite(Version), Version}),
             case ssl:str_to_suite(ssl:suite_to_str(CipherSuite)) of
 		CipherSuite ->
 		    true;
@@ -72,7 +71,7 @@ prop_tls_cipher_suite_rfc_name() ->
 	   ).
 
 prop_tls_cipher_suite_openssl_name() ->
-    ?FORALL({CipherSuite, TLSVersion}, ?LET(Version, tls_version(), {cipher_suite(Version), Version}),
+    ?FORALL({CipherSuite, _TLSVersion}, ?LET(Version, tls_version(), {cipher_suite(Version), Version}),
             case ssl:str_to_suite(ssl:suite_to_openssl_str(CipherSuite)) of
 		CipherSuite ->
 		    true;
@@ -86,7 +85,7 @@ prop_tls_cipher_suite_openssl_name() ->
 %% Generators  -----------------------------------------------
 %%--------------------------------------------------------------------
 tls_version() ->
-    oneof([?'TLS_v1.2', ?'TLS_v1.1', ?'TLS_v1', ?'SSL_v3']).
+    oneof([?'TLS_v1.3', ?'TLS_v1.2', ?'TLS_v1.1', ?'TLS_v1']).
 
 cipher_suite(Version) ->
     oneof(cipher_suites(Version)).
diff --git a/lib/ssl/test/property_test/ssl_eqc_handshake.erl b/lib/ssl/test/property_test/ssl_eqc_handshake.erl
index 9ae267a2d3..f78956e83a 100644
--- a/lib/ssl/test/property_test/ssl_eqc_handshake.erl
+++ b/lib/ssl/test/property_test/ssl_eqc_handshake.erl
@@ -62,7 +62,6 @@
 -define('TLS_v1.2', {3,3}).
 -define('TLS_v1.1', {3,2}).
 -define('TLS_v1',   {3,1}).
--define('SSL_v3',   {3,0}).
 
 %%--------------------------------------------------------------------
 %% Properties --------------------------------------------------------
@@ -132,14 +131,6 @@ client_hello(Version) ->
 		  compression_methods = compressions(Version),
 		  random = client_random(Version),
 		  extensions = client_hello_extensions(Version)    
-                 };
-client_hello(?'SSL_v3' = Version) ->
-    #client_hello{session_id = session_id(),
-		  client_version = Version,
-                  cipher_suites = cipher_suites(Version),
-		  compression_methods = compressions(Version),
-		  random = client_random(Version),
-		  extensions = ssl_handshake:empty_extensions(Version, client_hello)
                  }.
 
 server_hello(?'TLS_v1.3' = Version) ->
@@ -150,14 +141,6 @@ server_hello(?'TLS_v1.3' = Version) ->
 		  compression_method = compression(Version),
 		  extensions = server_hello_extensions(Version)    
                  };
-server_hello(?'SSL_v3' = Version) ->
-    #server_hello{server_version = Version,
-		  session_id = session_id(),
-                  random = server_random(Version),
-                  cipher_suite = cipher_suite(Version),
-		  compression_method = compression(Version),
-		  extensions = ssl_handshake:empty_extensions(Version, server_hello)
-                 };
 server_hello(Version) ->
     #server_hello{server_version = Version,
 		  session_id = session_id(),
@@ -214,7 +197,7 @@ key_update() ->
 %%--------------------------------------------------------------------
 
 tls_version() ->
-    oneof([?'TLS_v1.3', ?'TLS_v1.2', ?'TLS_v1.1', ?'TLS_v1', ?'SSL_v3']).
+    oneof([?'TLS_v1.3', ?'TLS_v1.2', ?'TLS_v1.1', ?'TLS_v1']).
 
 cipher_suite(Version) ->
     oneof(cipher_suites(Version)).
@@ -382,8 +365,6 @@ extensions(?'TLS_v1.3' = Version, MsgType = client_hello) ->
                         %% post_handshake_auth => PostHandshakeAuth,
                         signature_algs_cert => SignatureAlgorithmsCert
                        }));
-extensions(?'SSL_v3', client_hello) ->
-    #{};
 extensions(Version, client_hello) ->
     ?LET({
           SNI,
diff --git a/lib/ssl/test/ssl_alpn_SUITE.erl b/lib/ssl/test/ssl_alpn_SUITE.erl
index 82a49e1469..f81a853bd1 100644
--- a/lib/ssl/test/ssl_alpn_SUITE.erl
+++ b/lib/ssl/test/ssl_alpn_SUITE.erl
@@ -37,7 +37,6 @@ all() ->
      {group, 'tlsv1.2'},
      {group, 'tlsv1.1'},
      {group, 'tlsv1'},
-     {group, 'sslv3'},
      {group, 'dtlsv1.2'},
      {group, 'dtlsv1'}
     ].
@@ -48,7 +47,6 @@ groups() ->
      {'tlsv1.2', [], alpn_tests() ++ alpn_npn_coexist()},
      {'tlsv1.1', [], alpn_tests() ++ alpn_npn_coexist()},
      {'tlsv1', [], alpn_tests() ++ alpn_npn_coexist()},
-     {'sslv3', [], alpn_not_supported()},
      {'dtlsv1.2', [], alpn_tests() ++ alpn_npn_coexist()},
      {'dtlsv1', [], alpn_tests() ++ alpn_npn_coexist()}
     ].
@@ -74,10 +72,6 @@ alpn_npn_coexist() ->
      client_alpn_and_server_alpn_npn
     ].
 
-alpn_not_supported() ->
-    [alpn_not_supported_client,
-     alpn_not_supported_server
-    ].
 
 init_per_suite(Config0) ->
     catch crypto:stop(),
@@ -274,30 +268,6 @@ session_reused(Config) when  is_list(Config)->
     ServerOpts = [{alpn_preferred_protocols, [<<"spdy/2">>, <<"http/1.1">>, <<"http/1.0">>]}] ++  ServerOpts0,
 
     ssl_test_lib:reuse_session(ClientOpts, ServerOpts, Config).
-%--------------------------------------------------------------------------------
-
-alpn_not_supported_client(Config) when is_list(Config) ->
-    ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_opts, Config),
-    PrefProtocols = {client_preferred_next_protocols,
-		     {client, [<<"http/1.0">>], <<"http/1.1">>}},
-    ClientOpts = [PrefProtocols] ++ ClientOpts0,
-    {ClientNode, _ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-    Client = ssl_test_lib:start_client_error([{node, ClientNode}, 
-			    {port, 8888}, {host, Hostname},
-			    {from, self()},  {options, ClientOpts}]),
-    
-    ssl_test_lib:check_result(Client, {error, 
-				       {options, 
-					{not_supported_in_sslv3, PrefProtocols}}}).
-
-%--------------------------------------------------------------------------------
-
-alpn_not_supported_server(Config) when is_list(Config)->
-    ServerOpts0 =  ssl_test_lib:ssl_options(server_rsa_opts, Config),
-    AdvProtocols = {next_protocols_advertised, [<<"spdy/2">>, <<"http/1.1">>, <<"http/1.0">>]},
-    ServerOpts = [AdvProtocols] ++  ServerOpts0,
-  
-    {error, {options, {not_supported_in_sslv3, AdvProtocols}}} = ssl:listen(0, ServerOpts).
 
 %%--------------------------------------------------------------------
 %% Internal functions ------------------------------------------------
diff --git a/lib/ssl/test/ssl_api_SUITE.erl b/lib/ssl/test/ssl_api_SUITE.erl
index 03ec202b8c..63cc2fd329 100644
--- a/lib/ssl/test/ssl_api_SUITE.erl
+++ b/lib/ssl/test/ssl_api_SUITE.erl
@@ -37,7 +37,6 @@ all() ->
      {group, 'tlsv1.2'},
      {group, 'tlsv1.1'},
      {group, 'tlsv1'},
-     {group, 'sslv3'},
      {group, 'dtlsv1.2'},
      {group, 'dtlsv1'}
     ].
@@ -51,7 +50,6 @@ groups() ->
      {'tlsv1.2', [],  gen_api_tests() ++ since_1_2() ++ handshake_paus_tests() ++ pre_1_3()},
      {'tlsv1.1', [],  gen_api_tests() ++ handshake_paus_tests() ++ pre_1_3()},
      {'tlsv1', [],  gen_api_tests() ++ handshake_paus_tests() ++ pre_1_3() ++ beast_mitigation_test()},
-     {'sslv3', [],  (gen_api_tests() -- [new_options_in_handshake]) ++ beast_mitigation_test() ++ pre_1_3()},
      {'dtlsv1.2', [], (gen_api_tests() --
                            [invalid_keyfile, invalid_certfile, invalid_cacertfile,
                             invalid_options, new_options_in_handshake])  ++
diff --git a/lib/ssl/test/ssl_app_env_SUITE.erl b/lib/ssl/test/ssl_app_env_SUITE.erl
index 27fbcb8e47..233985c729 100644
--- a/lib/ssl/test/ssl_app_env_SUITE.erl
+++ b/lib/ssl/test/ssl_app_env_SUITE.erl
@@ -37,7 +37,6 @@ all() ->
      {group, 'tlsv1.2'},
      {group, 'tlsv1.1'},
      {group, 'tlsv1'},
-     {group, 'sslv3'},
      {group, 'dtlsv1.2'},
      {group, 'dtlsv1'}
     ].
@@ -48,7 +47,6 @@ groups() ->
      {'tlsv1.2', [],  tests()},
      {'tlsv1.1', [],  tests()},
      {'tlsv1', [],  tests()},
-     {'sslv3', [],  tests()},
      {'dtlsv1.2', [], tests()},
      {'dtlsv1', [],  tests()}
     ].
diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl
index 355cd31070..432801f61b 100644
--- a/lib/ssl/test/ssl_basic_SUITE.erl
+++ b/lib/ssl/test/ssl_basic_SUITE.erl
@@ -173,7 +173,7 @@ connect_twice(Config) when is_list(Config) ->
     ssl_test_lib:close(Client1).
 defaults(Config) when is_list(Config)->
     Versions = ssl:versions(),
-    true = lists:member(sslv3, proplists:get_value(available, Versions)),
+    false = lists:member(sslv3, proplists:get_value(available, Versions)),
     false = lists:member(sslv3,  proplists:get_value(supported, Versions)),
     true = lists:member('tlsv1', proplists:get_value(available, Versions)),
     false = lists:member('tlsv1',  proplists:get_value(supported, Versions)),
@@ -406,7 +406,6 @@ eccs() ->
 
 eccs(Config) when is_list(Config) ->
     [_|_] = All = ssl:eccs(),
-    [] = ssl:eccs(sslv3),
     [_|_] = Tls = ssl:eccs(tlsv1),
     [_|_] = Tls1 = ssl:eccs('tlsv1.1'),
     [_|_] = Tls2 = ssl:eccs('tlsv1.2'),
diff --git a/lib/ssl/test/ssl_cert_SUITE.erl b/lib/ssl/test/ssl_cert_SUITE.erl
index d5ca9bcf02..bcf2086cca 100644
--- a/lib/ssl/test/ssl_cert_SUITE.erl
+++ b/lib/ssl/test/ssl_cert_SUITE.erl
@@ -36,7 +36,6 @@ all() ->
      {group, 'tlsv1.2'},
      {group, 'tlsv1.1'},
      {group, 'tlsv1'},
-     {group, 'sslv3'},
      {group, 'dtlsv1.2'},
      {group, 'dtlsv1'}
     ].
@@ -47,7 +46,6 @@ groups() ->
      {'tlsv1.2', [], tls_1_2_protocol_groups()},
      {'tlsv1.1', [], ssl_protocol_groups()},
      {'tlsv1', [], ssl_protocol_groups()},
-     {'sslv3', [], ssl_protocol_groups()},
      {'dtlsv1.2', [], tls_1_2_protocol_groups()},
      {'dtlsv1', [], ssl_protocol_groups()},
      {rsa, [], all_version_tests() ++ rsa_tests() ++ pre_tls_1_3_rsa_tests()},
diff --git a/lib/ssl/test/ssl_cipher_suite_SUITE.erl b/lib/ssl/test/ssl_cipher_suite_SUITE.erl
index e598d662e9..afb11660e7 100644
--- a/lib/ssl/test/ssl_cipher_suite_SUITE.erl
+++ b/lib/ssl/test/ssl_cipher_suite_SUITE.erl
@@ -35,7 +35,6 @@ all() ->
      {group, 'tlsv1.2'},
      {group, 'tlsv1.1'},
      {group, 'tlsv1'},
-     {group, 'sslv3'},
      {group, 'dtlsv1.2'},
      {group, 'dtlsv1'}
     ].
@@ -45,7 +44,6 @@ groups() ->
      {'tlsv1.2', [], kex()},
      {'tlsv1.1', [], kex()},
      {'tlsv1', [], kex()},
-     {'sslv3', [], ssl3_kex()},
      {'dtlsv1.2', [], kex()},
      {'dtlsv1', [], kex()},
      {dhe_rsa, [],[dhe_rsa_3des_ede_cbc, 
@@ -130,11 +128,6 @@ groups() ->
 kex() ->
      rsa() ++ ecdsa() ++ dss() ++ anonymous().
 
-
-ssl3_kex() ->
-    ssl3_rsa() ++ ssl3_dss() ++ ssl3_anonymous().
-
-
 rsa() ->
     [{group, dhe_rsa},
      {group, ecdhe_rsa},
@@ -143,11 +136,6 @@ rsa() ->
      {group, rsa_psk}
     ].
 
-ssl3_rsa() ->
-    [{group, dhe_rsa},
-     {group, rsa}
-    ].
-
 ecdsa() ->
     [{group, ecdhe_ecdsa}].
     
@@ -155,10 +143,6 @@ dss() ->
     [{group, dhe_dss},
      {group, srp_dss}].
 
-ssl3_dss() ->
-    [{group, dhe_dss}
-    ].
-
 anonymous() ->
     [{group, dh_anon},
      {group, ecdh_anon},
@@ -168,10 +152,6 @@ anonymous() ->
      {group, srp_anon}
     ].
 
-ssl3_anonymous() ->
-    [{group, dh_anon}].
-
-
 init_per_suite(Config) ->
     catch crypto:stop(),
     try crypto:start() of
diff --git a/lib/ssl/test/ssl_npn_SUITE.erl b/lib/ssl/test/ssl_npn_SUITE.erl
index 1f794075c1..94448b5721 100644
--- a/lib/ssl/test/ssl_npn_SUITE.erl
+++ b/lib/ssl/test/ssl_npn_SUITE.erl
@@ -33,15 +33,14 @@
 all() ->
     [{group, 'tlsv1.2'},
      {group, 'tlsv1.1'},
-     {group, 'tlsv1'},
-     {group, 'sslv3'}].
+     {group, 'tlsv1'}
+    ].
 
 groups() ->
     [
      {'tlsv1.2', [], next_protocol_tests()},
      {'tlsv1.1', [], next_protocol_tests()},
-     {'tlsv1', [], next_protocol_tests()},
-     {'sslv3', [], next_protocol_not_supported()}
+     {'tlsv1', [], next_protocol_tests()}
     ].
 
 next_protocol_tests() ->
@@ -59,11 +58,6 @@ next_protocol_tests() ->
      npn_handshake_session_reused
     ].
 
-next_protocol_not_supported() ->
-    [npn_not_supported_client,
-     npn_not_supported_server
-    ].
-
 init_per_suite(Config0) ->
     catch crypto:stop(),
     try crypto:start() of
@@ -219,29 +213,6 @@ renegotiate_from_client_after_npn_handshake(Config) when is_list(Config) ->
 
     ssl_test_lib:check_result(Server, ok, Client, ok).
 
-%--------------------------------------------------------------------------------
-npn_not_supported_client(Config) when is_list(Config) ->
-    ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
-    PrefProtocols = {client_preferred_next_protocols,
-		     {client, [<<"http/1.0">>], <<"http/1.1">>}},
-    ClientOpts = [PrefProtocols] ++ ClientOpts0,
-    {ClientNode, _ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-    Client = ssl_test_lib:start_client_error([{node, ClientNode}, 
-			    {port, 8888}, {host, Hostname},
-			    {from, self()},  {options, ClientOpts}]),
-    
-    ssl_test_lib:check_result(Client, {error, 
-				       {options, 
-					{not_supported_in_sslv3, PrefProtocols}}}).
-
-%--------------------------------------------------------------------------------
-npn_not_supported_server(Config) when is_list(Config)->
-    ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_opts, Config),
-    AdvProtocols = {next_protocols_advertised, [<<"spdy/2">>, <<"http/1.1">>, <<"http/1.0">>]},
-    ServerOpts = [AdvProtocols] ++  ServerOpts0,
-  
-    {error, {options, {not_supported_in_sslv3, AdvProtocols}}} = ssl:listen(0, ServerOpts).
-
 %--------------------------------------------------------------------------------
 npn_handshake_session_reused(Config) when  is_list(Config)->
     ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
diff --git a/lib/ssl/test/ssl_packet_SUITE.erl b/lib/ssl/test/ssl_packet_SUITE.erl
index b83256e6e2..11d3fbc1c3 100644
--- a/lib/ssl/test/ssl_packet_SUITE.erl
+++ b/lib/ssl/test/ssl_packet_SUITE.erl
@@ -54,7 +54,6 @@ all() ->
      {group, 'tlsv1.2'},
      {group, 'tlsv1.1'},
      {group, 'tlsv1'},
-     {group, 'sslv3'},
      {group, 'dtlsv1.2'},
      {group, 'dtlsv1'}
     ].
@@ -64,7 +63,6 @@ groups() ->
      {'tlsv1.2', [], socket_packet_tests() ++ protocol_packet_tests()},
      {'tlsv1.1', [], socket_packet_tests() ++ protocol_packet_tests()},
      {'tlsv1', [], socket_packet_tests() ++ protocol_packet_tests()},
-     {'sslv3', [], socket_packet_tests() ++ protocol_packet_tests()},
      %% We will not support any packet types if the transport is
      %% not reliable. We might support it for DTLS over SCTP in the future 
      {'dtlsv1.2', [], [reject_packet_opt]},
diff --git a/lib/ssl/test/ssl_payload_SUITE.erl b/lib/ssl/test/ssl_payload_SUITE.erl
index 91043408b7..bf9303c9ec 100644
--- a/lib/ssl/test/ssl_payload_SUITE.erl
+++ b/lib/ssl/test/ssl_payload_SUITE.erl
@@ -36,8 +36,7 @@ all() ->
      {group, 'tlsv1.3'},
      {group, 'tlsv1.2'},
      {group, 'tlsv1.1'},
-     {group, 'tlsv1'},
-     {group, 'sslv3'}
+     {group, 'tlsv1'}    
     ].
 
 groups() ->
@@ -45,8 +44,7 @@ groups() ->
      {'tlsv1.3', [], payload_tests()},
      {'tlsv1.2', [], payload_tests()},
      {'tlsv1.1', [], payload_tests()},
-     {'tlsv1', [], payload_tests()},
-     {'sslv3', [], payload_tests()}
+     {'tlsv1', [], payload_tests()}
     ].
 
 payload_tests() ->
diff --git a/lib/ssl/test/ssl_renegotiate_SUITE.erl b/lib/ssl/test/ssl_renegotiate_SUITE.erl
index ef3f9ebb52..340b391cc2 100644
--- a/lib/ssl/test/ssl_renegotiate_SUITE.erl
+++ b/lib/ssl/test/ssl_renegotiate_SUITE.erl
@@ -39,7 +39,6 @@ all() ->
      {group, 'tlsv1.2'},
      {group, 'tlsv1.1'},
      {group, 'tlsv1'},
-     {group, 'sslv3'},
      {group, 'dtlsv1.2'},
      {group, 'dtlsv1'}
     ].
@@ -50,8 +49,7 @@ groups() ->
      {'tlsv1.3', [], renegotiate_tests()},
      {'tlsv1.2', [], renegotiate_tests()},
      {'tlsv1.1', [], renegotiate_tests()},
-     {'tlsv1', [], renegotiate_tests()},
-     {'sslv3', [], ssl3_renegotiate_tests()}
+     {'tlsv1', [], renegotiate_tests()}
     ].
 
 renegotiate_tests() ->
diff --git a/lib/ssl/test/ssl_session_SUITE.erl b/lib/ssl/test/ssl_session_SUITE.erl
index aa79698a72..632ce6b46b 100644
--- a/lib/ssl/test/ssl_session_SUITE.erl
+++ b/lib/ssl/test/ssl_session_SUITE.erl
@@ -40,7 +40,6 @@ all() ->
      {group, 'tlsv1.2'},
      {group, 'tlsv1.1'},
      {group, 'tlsv1'},
-     {group, 'sslv3'},
      {group, 'dtlsv1.2'},
      {group, 'dtlsv1'}
     ].
@@ -51,8 +50,7 @@ groups() ->
      {'tlsv1.3', [], session_tests() ++ tls_session_tests()},
      {'tlsv1.2', [], session_tests() ++ tls_session_tests()},
      {'tlsv1.1', [], session_tests() ++ tls_session_tests()},
-     {'tlsv1', [], session_tests() ++ tls_session_tests()},
-     {'sslv3', [], session_tests() ++ tls_session_tests()}
+     {'tlsv1', [], session_tests() ++ tls_session_tests()}
     ].
 
 session_tests() ->
diff --git a/lib/ssl/test/ssl_test_lib.erl b/lib/ssl/test/ssl_test_lib.erl
index 6218857e05..78725c8de5 100644
--- a/lib/ssl/test/ssl_test_lib.erl
+++ b/lib/ssl/test/ssl_test_lib.erl
@@ -1858,8 +1858,6 @@ is_tls_version('tlsv1.1') ->
     true;
 is_tls_version('tlsv1') ->
     true;
-is_tls_version('sslv3') ->
-    true;
 is_tls_version(_) ->
     false.
 
@@ -2278,13 +2276,6 @@ check_sane_openssl_renegotaite(Config, Version) when Version == 'tlsv1.1';
         _ ->
 	    check_sane_openssl_renegotaite(Config)
     end;
-check_sane_openssl_renegotaite(Config, 'sslv3') ->
-    case os:cmd("openssl version") of     
-	"OpenSSL 1" ++ _ ->
-	    {skip, "Known renegotiation bug with sslv3 in OpenSSL"};
-	_ ->
-	    check_sane_openssl_renegotaite(Config)
-    end;
 check_sane_openssl_renegotaite(Config, _) ->
     check_sane_openssl_renegotaite(Config).
 	
@@ -2437,16 +2437,12 @@ portable_cmd(Exe, Args) ->
             Data
     end.
 
-supports_ssl_tls_version(Version) when Version == sslv2;
-                                       Version == sslv3 ->
-
+supports_ssl_tls_version(sslv2) ->
     case ubuntu_legacy_support() of
         true ->   
             case portable_cmd("openssl", ["version"]) of
-                "OpenSSL 1.1" ++ _ ->
-                    false;
                 "OpenSSL 1" ++ _ ->
-                    Version =/= sslv2;
+                    false;
                 %% Appears to be broken
                 "OpenSSL 0.9.8.o" ++ _ -> 
                     false;
@@ -2481,8 +2468,13 @@ do_supports_ssl_tls_version(Port, Acc) ->
                 "s_client: Unknown option: " ++ _->
                     false;
                 Info when length(Info) >= 24 ->
-                    ct:pal("~p", [Info]),
-                    true;
+                    case lists:member("error", string:tokens(Info, ":")) of
+                        true ->
+                            false;
+                        false ->
+                            ct:pal("~p", [Info]),
+                            true
+                    end;
                 _ ->
                     do_supports_ssl_tls_version(Port, Acc ++ Data)
             end
diff --git a/lib/ssl/test/tls_api_SUITE.erl b/lib/ssl/test/tls_api_SUITE.erl
index fc0e9cf3fc..01de312a81 100644
--- a/lib/ssl/test/tls_api_SUITE.erl
+++ b/lib/ssl/test/tls_api_SUITE.erl
@@ -40,8 +40,7 @@ all() ->
      {group, 'tlsv1.3'},
      {group, 'tlsv1.2'},
      {group, 'tlsv1.1'},
-     {group, 'tlsv1'},
-     {group, 'sslv3'}
+     {group, 'tlsv1'}
     ].
 
 groups() ->
@@ -49,8 +48,7 @@ groups() ->
      {'tlsv1.3', [], api_tests() -- [sockname]},
      {'tlsv1.2', [],  api_tests()},
      {'tlsv1.1', [],  api_tests()},
-     {'tlsv1', [],  api_tests()},
-     {'sslv3', [],  api_tests() ++ [ssl3_cipher_suite_limitation]}
+     {'tlsv1', [],  api_tests()}
     ].
 
 api_tests() ->
@@ -605,39 +603,6 @@ transport_close(Config) when is_list(Config) ->
     {error, _} = ssl:send(SslS, "Hello world").
 
 %%--------------------------------------------------------------------
-ssl3_cipher_suite_limitation()  ->
-    [{doc,"Test a SSLv3 client cannot negotiate a TLSv* cipher suite."}].
-ssl3_cipher_suite_limitation(Config) when is_list(Config) ->
-    
-    {_ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-    ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
-    
-    Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
-					      {from, self()},
-					      {options, ServerOpts}]),
-    Port = ssl_test_lib:inet_port(Server),
-    
-    {ok, Socket} = gen_tcp:connect(Hostname, Port, [binary, {active, false}]),
-    ok = gen_tcp:send(Socket, 
-		      <<22, 3,0, 49:16, % handshake, SSL 3.0, length
-			1, 45:24, % client_hello, length
-			3,0, % SSL 3.0
-			16#deadbeef:256, % 32 'random' bytes = 256 bits
-			0, % no session ID
-			%% three cipher suites -- null, one with sha256 hash and one with sha hash
-			6:16, 0,255, 0,61, 0,57, 
-			1, 0 % no compression
-		      >>),
-    {ok, <<22, RecMajor:8, RecMinor:8, _RecLen:16, 2, HelloLen:24>>} = gen_tcp:recv(Socket, 9, 10000),
-    {ok, <<HelloBin:HelloLen/binary>>} = gen_tcp:recv(Socket, HelloLen, 5000),
-    ServerHello = tls_handshake:decode_handshake({RecMajor, RecMinor}, 2, HelloBin),
-    case ServerHello of
-	#server_hello{server_version = {3,0}, cipher_suite = <<0,57>>} -> 
-	    ok;
-	_ ->
-	    ct:fail({unexpected_server_hello, ServerHello})
-    end.
-%%--------------------------------------------------------------------
 emulated_options() ->
     [{doc,"Test API function getopts/2 and setopts/2"}].
 
diff --git a/system/doc/general_info/deprecations.xml b/system/doc/general_info/deprecations.xml
index 69d063faf4..cbdb56c3be 100644
--- a/system/doc/general_info/deprecations.xml
+++ b/system/doc/general_info/deprecations.xml
@@ -106,6 +106,16 @@
       </p>
     </section>
   </section>
+
+ <section>
+    <marker id="OTP-19"/>
+    <title>OTP 19</title>
+    <section>
+      <title>SSL/TLS</title>
+      <p>For security reasons SSL-3.0 is no longer supported by default, but can be configured.</p>
+    </section>
+  </section>
+
   <section>
     <marker id="OTP-18"/>
     <title>OTP 18</title>
diff --git a/system/doc/general_info/scheduled_for_removal.xml b/system/doc/general_info/scheduled_for_removal.xml
index 6f3d408f82..3a20100620 100644
--- a/system/doc/general_info/scheduled_for_removal.xml
+++ b/system/doc/general_info/scheduled_for_removal.xml
@@ -57,5 +57,11 @@
       of the <c>ei</c> library which also is part of the <c>erl_interface</c>
       application.</p>
     </section>
+
+     <section>
+       <title>SSL/TLS</title>
+       <p>For security reasons SSL-3.0 is no longer supported at all.</p>
+     </section>
+
   </section>
 </chapter>
-- 
2.16.4

openSUSE Build Service is sponsored by