aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/ssl/doc/src/ssl.xml37
-rw-r--r--lib/ssl/src/ssl.erl125
-rw-r--r--lib/ssl/src/ssl_cipher_format.erl109
-rw-r--r--lib/ssl/test/property_test/ssl_eqc_cipher_format.erl96
-rw-r--r--lib/ssl/test/ssl_eqc_SUITE.erl14
5 files changed, 328 insertions, 53 deletions
diff --git a/lib/ssl/doc/src/ssl.xml b/lib/ssl/doc/src/ssl.xml
index d626748af6..3aa6e09c2c 100644
--- a/lib/ssl/doc/src/ssl.xml
+++ b/lib/ssl/doc/src/ssl.xml
@@ -1132,6 +1132,15 @@ fun(srp, Username :: string(), UserState :: term()) ->
</func>
<func>
+ <name name="cipher_suites" arity="3" since="OTP 22.0"/>
+ <fsummary>Returns a list of RFC or OpenSSL names</fsummary>
+ <desc><p>Same as <seealso marker="#cipher_suites-2">cipher_suites/2</seealso>
+ but lists RFC or OpenSSL string names instead of <seealso marker="#type-erl_cipher_suite">erl_cipher_suite()</seealso>
+ </p>
+ </desc>
+ </func>
+
+ <func>
<name name="eccs" arity="0" since="OTP 19.2"/>
<name name="eccs" arity="1" since="OTP 19.2"/>
<fsummary>Returns a list of supported ECCs.</fsummary>
@@ -1563,12 +1572,36 @@ fun(srp, Username :: string(), UserState :: term()) ->
<p>Stops the SSL application.</p>
</desc>
</func>
+
+ <func>
+ <name since="OTP 22.0" name="str_to_suite" arity="1" />
+ <fsummary>Converts an RFC or OpenSSL name string to an erlang cipher suite format</fsummary>
+ <desc>
+ <p>Converts an RFC or OpenSSL name string to an
+ <seealso marker="#type-erl_cipher_suite">erl_cipher_suite()</seealso>
+ Returns an error if the cipher suite is not supported or the name is not a valid cipher suite name.</p>
+ </desc>
+ </func>
<func>
+ <name since="OTP 22.0" name="suite_to_openssl_str" arity="1" />
+ <fsummary>Converts erlang cipher suite format to an OpenSSL name string.
+ </fsummary>
+ <desc>
+ <p>Converts <seealso marker="#type-erl_cipher_suite">erl_cipher_suite()</seealso>
+ to OpenSSL name string. </p>
+
+ <p>PRE TLS-1.3 these names differ for RFC names</p>
+
+ </desc>
+ </func>
+
+ <func>
<name since="OTP 21.0" name="suite_to_str" arity="1" clause_i="1" />
- <fsummary>Returns the string representation of a cipher suite.</fsummary>
+ <fsummary>Converts an erlang cipher suite to an RFC name string.</fsummary>
<desc>
- <p>Returns the string representation of a cipher suite.</p>
+ <p>Converts <seealso marker="#type-erl_cipher_suite">erl_cipher_suite()</seealso>
+ to RFC name string.</p>
</desc>
</func>
diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl
index e3bb4df1ac..fa9da25f0c 100644
--- a/lib/ssl/src/ssl.erl
+++ b/lib/ssl/src/ssl.erl
@@ -35,27 +35,69 @@
-include("ssl_srp.hrl").
%% Application handling
--export([start/0, start/1, stop/0, clear_pem_cache/0]).
+-export([start/0,
+ start/1,
+ stop/0,
+ clear_pem_cache/0]).
%% Socket handling
--export([connect/3, connect/2, connect/4,
- listen/2, transport_accept/1, transport_accept/2,
- handshake/1, handshake/2, handshake/3, handshake_continue/2,
- handshake_continue/3, handshake_cancel/1,
- ssl_accept/1, ssl_accept/2, ssl_accept/3,
- controlling_process/2, peername/1, peercert/1, sockname/1,
- close/1, close/2, shutdown/2, recv/2, recv/3, send/2,
- getopts/2, setopts/2, getstat/1, getstat/2
+-export([connect/3,
+ connect/2,
+ connect/4,
+ listen/2,
+ transport_accept/1,
+ transport_accept/2,
+ handshake/1,
+ handshake/2,
+ handshake/3,
+ handshake_continue/2,
+ handshake_continue/3,
+ handshake_cancel/1,
+ ssl_accept/1,
+ ssl_accept/2,
+ ssl_accept/3,
+ controlling_process/2,
+ peername/1,
+ peercert/1,
+ sockname/1,
+ close/1,
+ close/2,
+ shutdown/2,
+ recv/2,
+ recv/3,
+ send/2,
+ getopts/2,
+ setopts/2,
+ getstat/1,
+ getstat/2
]).
%% SSL/TLS protocol handling
--export([cipher_suites/0, cipher_suites/1, cipher_suites/2, filter_cipher_suites/2,
- prepend_cipher_suites/2, append_cipher_suites/2,
- eccs/0, eccs/1, versions/0, groups/0, groups/1,
- format_error/1, renegotiate/1, prf/5, negotiated_protocol/1,
- connection_information/1, connection_information/2]).
+-export([cipher_suites/0,
+ cipher_suites/1,
+ cipher_suites/2,
+ cipher_suites/3,
+ filter_cipher_suites/2,
+ prepend_cipher_suites/2,
+ append_cipher_suites/2,
+ eccs/0,
+ eccs/1,
+ versions/0,
+ groups/0,
+ groups/1,
+ format_error/1,
+ renegotiate/1,
+ prf/5,
+ negotiated_protocol/1,
+ connection_information/1,
+ connection_information/2]).
%% Misc
--export([handle_options/2, tls_version/1, new_ssl_options/3, suite_to_str/1]).
+-export([handle_options/2,
+ tls_version/1,
+ new_ssl_options/3,
+ suite_to_str/1,
+ suite_to_openssl_str/1,
+ str_to_suite/1]).
-deprecated({ssl_accept, 1, eventually}).
-deprecated({ssl_accept, 2, eventually}).
@@ -945,6 +987,29 @@ cipher_suites(Base, Version) ->
[ssl_cipher_format:suite_bin_to_map(Suite) || Suite <- supported_suites(Base, Version)].
%%--------------------------------------------------------------------
+-spec cipher_suites(Supported, Version, rfc | openssl) -> string() when
+ Supported :: default | all | anonymous,
+ Version :: protocol_version().
+
+%% Description: Returns all default and all supported cipher suites for a
+%% TLS/DTLS version
+%%--------------------------------------------------------------------
+cipher_suites(Base, Version, StringType) when Version == 'tlsv1.2';
+ Version == 'tlsv1.1';
+ Version == tlsv1;
+ Version == sslv3 ->
+ cipher_suites(Base, tls_record:protocol_version(Version), StringType);
+cipher_suites(Base, Version, StringType) when Version == 'dtlsv1.2';
+ Version == 'dtlsv1'->
+ cipher_suites(Base, dtls_record:protocol_version(Version), StringType);
+cipher_suites(Base, Version, rfc) ->
+ [ssl_cipher_format:suite_map_to_str(ssl_cipher_format:suite_bin_to_map(Suite))
+ || Suite <- supported_suites(Base, Version)];
+cipher_suites(Base, Version, openssl) ->
+ [ssl_cipher_format:suite_map_to_openssl_str(ssl_cipher_format:suite_bin_to_map(Suite))
+ || Suite <- supported_suites(Base, Version)].
+
+%%--------------------------------------------------------------------
-spec filter_cipher_suites(Suites, Filters) -> Ciphers when
Suites :: ciphers(),
Filters :: cipher_filters(),
@@ -1325,9 +1390,39 @@ tls_version({254, _} = Version) ->
suite_to_str(Cipher) ->
ssl_cipher_format:suite_map_to_str(Cipher).
+%%--------------------------------------------------------------------
+-spec suite_to_openssl_str(CipherSuite) -> string() when
+ CipherSuite :: erl_cipher_suite().
+%%
+%% Description: Return the string representation of a cipher suite.
+%%--------------------------------------------------------------------
+suite_to_openssl_str(Cipher) ->
+ ssl_cipher_format:suite_map_to_openssl_str(Cipher).
+
+%%
+%%--------------------------------------------------------------------
+-spec str_to_suite(CipherSuiteName) -> erl_cipher_suite() when
+ CipherSuiteName :: string() | {error, {not_recognized, CipherSuiteName :: string()}}.
+%%
+%% Description: Return the map representation of a cipher suite.
+%%--------------------------------------------------------------------
+str_to_suite(CipherSuiteName) ->
+ try
+ %% Note in TLS-1.3 OpenSSL conforms to RFC names
+ %% so if CipherSuiteName starts with TLS this
+ %% function will call ssl_cipher_format:suite_str_to_map
+ %% so both RFC names and legacy OpenSSL names of supported
+ %% cipher suites will be handled
+ ssl_cipher_format:suite_openssl_str_to_map(CipherSuiteName)
+ catch
+ _:_ ->
+ {error, {not_recognized, CipherSuiteName}}
+ end.
+
%%%--------------------------------------------------------------
%%% Internal functions
%%%--------------------------------------------------------------------
+
%% Possible filters out suites not supported by crypto
available_suites(default) ->
Version = tls_record:highest_protocol_version([]),
diff --git a/lib/ssl/src/ssl_cipher_format.erl b/lib/ssl/src/ssl_cipher_format.erl
index 577156a4b5..bca1022b5f 100644
--- a/lib/ssl/src/ssl_cipher_format.erl
+++ b/lib/ssl/src/ssl_cipher_format.erl
@@ -93,10 +93,16 @@ suite_str_to_map("TLS_EMPTY_RENEGOTIATION_INFO_SCSV") ->
mac => null,
prf => null};
suite_str_to_map(SuiteStr)->
- Str0 = string:trim(SuiteStr, leading, "TLS_"),
+ Str0 = string:prefix(SuiteStr, "TLS_"),
case string:split(Str0, "_WITH_") of
[Rest] ->
tls_1_3_suite_str_to_map(Rest);
+ [Prefix, Kex | Rest] when Prefix == "SPR";
+ Prefix == "PSK";
+ Prefix == "DHE";
+ Prefix == "ECDHE"
+ ->
+ pre_tls_1_3_suite_str_to_map(Prefix ++ "_" ++ Kex, Rest);
[Kex| Rest] ->
pre_tls_1_3_suite_str_to_map(Kex, Rest)
end.
@@ -108,9 +114,15 @@ suite_map_to_openssl_str(#{key_exchange := any,
suite_map_to_openssl_str(#{key_exchange := null} = Suite) ->
%% TLS_EMPTY_RENEGOTIATION_INFO_SCSV
suite_map_to_str(Suite);
+suite_map_to_openssl_str(#{key_exchange := rsa = Kex,
+ cipher := Cipher,
+ mac := Mac}) when Cipher == "des_cbc";
+ Cipher == "3des_ede_cbc" ->
+ openssl_cipher_name(Kex, string:to_upper(atom_to_list(Cipher))) ++
+ "-" ++ string:to_upper(atom_to_list(Mac));
suite_map_to_openssl_str(#{key_exchange := Kex,
- cipher := chacha20_poly1305 = Cipher,
- mac := aead}) ->
+ cipher := chacha20_poly1305 = Cipher,
+ mac := aead}) ->
openssl_suite_start(string:to_upper(atom_to_list(Kex)))
++ openssl_cipher_name(Kex, string:to_upper(atom_to_list(Cipher)));
suite_map_to_openssl_str(#{key_exchange := Kex,
@@ -130,6 +142,12 @@ suite_map_to_openssl_str(#{key_exchange := Kex,
suite_openssl_str_to_map("TLS_" ++ _ = SuiteStr) ->
suite_str_to_map(SuiteStr);
+suite_openssl_str_to_map("DES-CBC-SHA") ->
+ suite_str_to_map("TLS_RSA_WITH_DES_CBC_SHA");
+suite_openssl_str_to_map("DES-CBC3-SHA") ->
+ suite_str_to_map("TLS_RSA_WITH_3DES_EDE_CBC_SHA");
+suite_openssl_str_to_map("SRP-DSS-DES-CBC3-SHA") ->
+ suite_str_to_map("TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA");
suite_openssl_str_to_map("DHE-RSA-" ++ Rest) ->
suite_openssl_str_to_map("DHE-RSA", Rest);
suite_openssl_str_to_map("DHE-DSS-" ++ Rest) ->
@@ -164,6 +182,8 @@ suite_openssl_str_to_map("PSK-" ++ Rest) ->
suite_openssl_str_to_map("PSK", Rest);
suite_openssl_str_to_map("SRP-RSA-" ++ Rest) ->
suite_openssl_str_to_map("SRP-RSA", Rest);
+suite_openssl_str_to_map("SRP-DSS-" ++ Rest) ->
+ suite_openssl_str_to_map("SRP-DSS", Rest);
suite_openssl_str_to_map("SRP-" ++ Rest) ->
suite_openssl_str_to_map("SRP", Rest).
@@ -451,7 +471,7 @@ suite_bin_to_map(?TLS_PSK_WITH_AES_256_CBC_SHA384) ->
#{key_exchange => psk,
cipher => aes_256_cbc,
mac => sha384,
- prf => default_prf};
+ prf => sha384};
suite_bin_to_map(?TLS_DHE_PSK_WITH_AES_128_CBC_SHA256) ->
#{key_exchange => dhe_psk,
cipher => aes_128_cbc,
@@ -461,7 +481,7 @@ suite_bin_to_map(?TLS_DHE_PSK_WITH_AES_256_CBC_SHA384) ->
#{key_exchange => dhe_psk,
cipher => aes_256_cbc,
mac => sha384,
- prf => default_prf};
+ prf => sha384};
suite_bin_to_map(?TLS_RSA_PSK_WITH_AES_128_CBC_SHA256) ->
#{key_exchange => rsa_psk,
cipher => aes_128_cbc,
@@ -471,7 +491,7 @@ suite_bin_to_map(?TLS_RSA_PSK_WITH_AES_256_CBC_SHA384) ->
#{key_exchange => rsa_psk,
cipher => aes_256_cbc,
mac => sha384,
- prf => default_prf};
+ prf => sha384};
suite_bin_to_map(?TLS_PSK_WITH_NULL_SHA256) ->
#{key_exchange => psk,
cipher => null,
@@ -481,7 +501,7 @@ suite_bin_to_map(?TLS_PSK_WITH_NULL_SHA384) ->
#{key_exchange => psk,
cipher => null,
mac => sha384,
- prf => default_prf};
+ prf => sha384};
suite_bin_to_map(?TLS_DHE_PSK_WITH_NULL_SHA256) ->
#{key_exchange => dhe_psk,
cipher => null,
@@ -491,7 +511,7 @@ suite_bin_to_map(?TLS_DHE_PSK_WITH_NULL_SHA384) ->
#{key_exchange => dhe_psk,
cipher => null,
mac => sha384,
- prf => default_prf};
+ prf => sha384};
suite_bin_to_map(?TLS_RSA_PSK_WITH_NULL_SHA256) ->
#{key_exchange => rsa_psk,
cipher => null,
@@ -501,7 +521,7 @@ suite_bin_to_map(?TLS_RSA_PSK_WITH_NULL_SHA384) ->
#{key_exchange => rsa_psk,
cipher => null,
mac => sha384,
- prf => default_prf};
+ prf => sha384};
%%% ECDHE PSK Cipher Suites RFC 5489
suite_bin_to_map(?TLS_ECDHE_PSK_WITH_RC4_128_SHA) ->
#{key_exchange => ecdhe_psk,
@@ -532,7 +552,7 @@ suite_bin_to_map(?TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384) ->
#{key_exchange => ecdhe_psk,
cipher => aes_256_cbc,
mac => sha384,
- prf => default_prf};
+ prf => sha384};
suite_bin_to_map(?TLS_ECDHE_PSK_WITH_NULL_SHA256) ->
#{key_exchange => ecdhe_psk,
cipher => null,
@@ -541,7 +561,7 @@ suite_bin_to_map(?TLS_ECDHE_PSK_WITH_NULL_SHA256) ->
suite_bin_to_map(?TLS_ECDHE_PSK_WITH_NULL_SHA384) ->
#{key_exchange => ecdhe_psk,
cipher => null, mac => sha384,
- prf => default_prf};
+ prf => sha384};
%%% ECDHE_PSK with AES-GCM and AES-CCM Cipher Suites, draft-ietf-tls-ecdhe-psk-aead-05
suite_bin_to_map(?TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256) ->
#{key_exchange => ecdhe_psk,
@@ -557,12 +577,12 @@ suite_bin_to_map(?TLS_ECDHE_PSK_WITH_AES_128_CCM_SHA256) ->
#{key_exchange => ecdhe_psk,
cipher => aes_128_ccm,
mac => null,
- prf =>sha256};
+ prf => sha256};
suite_bin_to_map(?TLS_ECDHE_PSK_WITH_AES_128_CCM_8_SHA256) ->
#{key_exchange => ecdhe_psk,
cipher => aes_128_ccm_8,
mac => null,
- prf =>sha256};
+ prf => sha256};
%%% SRP Cipher Suites RFC 5054
suite_bin_to_map(?TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA) ->
#{key_exchange => srp_anon,
@@ -1704,7 +1724,7 @@ suite_map_to_bin(#{key_exchange := any,
tls_1_3_suite_str_to_map(CipherStr) ->
- {Cipher, Mac, Prf} = cipher_str_to_algs(CipherStr, ""),
+ {Cipher, Mac, Prf} = cipher_str_to_algs(any, CipherStr, ""),
#{key_exchange => any,
mac => Mac,
cipher => Cipher,
@@ -1714,37 +1734,56 @@ tls_1_3_suite_str_to_map(CipherStr) ->
pre_tls_1_3_suite_str_to_map(KexStr, Rest) ->
Kex = algo_str_to_atom(KexStr),
[CipherStr, AlgStr] = string:split(Rest, "_", trailing),
- {Cipher, Mac, Prf} = cipher_str_to_algs(CipherStr, AlgStr),
+ {Cipher, Mac, Prf} = cipher_str_to_algs(Kex, CipherStr, AlgStr),
#{key_exchange => Kex,
mac => Mac,
cipher => Cipher,
prf => Prf
}.
-cipher_str_to_algs(CipherStr, "CCM"= End) -> %% PRE TLS 1.3
+cipher_str_to_algs(_, CipherStr, "CCM"= End) -> %% PRE TLS 1.3
Cipher = algo_str_to_atom(CipherStr ++ "_" ++ End),
{Cipher, aead, sha256};
-cipher_str_to_algs(CipherStr, "8" = End) -> %% PRE TLS 1.3
+cipher_str_to_algs(_, CipherStr, "8" = End) -> %% PRE TLS 1.3
Cipher = algo_str_to_atom(CipherStr ++ "_" ++ End),
{Cipher, aead, sha256};
-cipher_str_to_algs(CipherStr, "CHACHA20_POLY1305" = End) -> %% PRE TLS 1.3
+cipher_str_to_algs(_, CipherStr, "CHACHA20_POLY1305" = End) -> %% PRE TLS 1.3
Cipher = algo_str_to_atom(CipherStr ++ "_" ++ End),
{Cipher, aead, sha256};
-cipher_str_to_algs(CipherStr0, "") -> %% TLS 1.3
+cipher_str_to_algs(_, CipherStr0, "") -> %% TLS 1.3
[CipherStr, AlgStr] = string:split(CipherStr0, "_", trailing),
Hash = algo_str_to_atom(AlgStr),
Cipher = algo_str_to_atom(CipherStr),
{Cipher, aead, Hash};
-cipher_str_to_algs(CipherStr, HashStr) -> %% PRE TLS 1.3
+cipher_str_to_algs(Kex, CipherStr, HashStr) -> %% PRE TLS 1.3
Hash = algo_str_to_atom(HashStr),
Cipher = algo_str_to_atom(CipherStr),
case is_aead_cipher(CipherStr) of
true ->
{Cipher, aead, Hash};
false ->
- {Cipher, Hash, default_prf}
+ {Cipher, Hash, default_prf(Kex, Hash)}
end.
+default_prf(_, md5) ->
+ default_prf;
+default_prf(_, sha) ->
+ default_prf;
+default_prf(ecdhe_ecdsa, sha256) ->
+ sha256;
+default_prf(ecdhe_rsa, sha256) ->
+ sha256;
+default_prf(dhe_rsa, sha256) ->
+ default_prf;
+default_prf(dhe_dss, sha256) ->
+ default_prf;
+default_prf(rsa, sha256) ->
+ default_prf;
+default_prf(rsa_psk, sha256) ->
+ default_prf;
+default_prf(_, Hash) ->
+ Hash.
+
%% PRE TLS 1.3
is_aead_cipher("CHACHA20_POLY1305") ->
true;
@@ -1762,10 +1801,13 @@ openssl_is_aead_cipher(CipherStr) ->
false
end.
+algo_str_to_atom("SRP_SHA_DSS") ->
+ srp_dss;
algo_str_to_atom(AlgoStr) ->
erlang:list_to_existing_atom(string:to_lower(AlgoStr)).
-
+openssl_cipher_name(_, "3DES_EDE_CBC" ++ _) ->
+ "DES-CBC3";
openssl_cipher_name(Kex, "AES_128_CBC" ++ _ = CipherStr) when Kex == rsa;
Kex == dhe_rsa;
Kex == ecdhe_rsa;
@@ -1828,6 +1870,10 @@ cipher_name_from_openssl("AES128-GCM") ->
"AES_128_GCM";
cipher_name_from_openssl("AES256-GCM") ->
"AES_256_GCM";
+cipher_name_from_openssl("DES-CBC") ->
+ "DES_CBC";
+cipher_name_from_openssl("DES-CBC3") ->
+ "3DES_EDE_CBC";
cipher_name_from_openssl("RC4") ->
"RC4_128";
cipher_name_from_openssl(Str) ->
@@ -1842,7 +1888,7 @@ openssl_name_concat(Str0) ->
suite_openssl_str_to_map(Kex0, Rest) ->
Kex = algo_str_to_atom(kex_name_from_openssl(Kex0)),
[CipherStr, AlgStr] = string:split(Rest, "-", trailing),
- {Cipher, Mac, Prf} = openssl_cipher_str_to_algs(CipherStr, AlgStr),
+ {Cipher, Mac, Prf} = openssl_cipher_str_to_algs(Kex, CipherStr, AlgStr),
#{key_exchange => Kex,
mac => Mac,
cipher => Cipher,
@@ -1850,31 +1896,24 @@ suite_openssl_str_to_map(Kex0, Rest) ->
}.
%% Does only need own implementation PRE TLS 1.3
-openssl_cipher_str_to_algs(CipherStr, "CCM"= End) ->
+openssl_cipher_str_to_algs(_, CipherStr, "CCM"= End) ->
Cipher = algo_str_to_atom(CipherStr ++ "_" ++ End),
{Cipher, aead, sha256};
-openssl_cipher_str_to_algs(CipherStr, "8" = End) ->
+openssl_cipher_str_to_algs(_, CipherStr, "8" = End) ->
Cipher = algo_str_to_atom(CipherStr ++ "_" ++ End),
{Cipher, aead, sha256};
-openssl_cipher_str_to_algs(CipherStr, "POLY1305" = End) ->
+openssl_cipher_str_to_algs(_, CipherStr, "POLY1305" = End) ->
Cipher = algo_str_to_atom(CipherStr ++ "_" ++ End),
{Cipher, aead, sha256};
-openssl_cipher_str_to_algs(CipherStr, HashStr) ->
+openssl_cipher_str_to_algs(Kex, CipherStr, HashStr) ->
Hash = algo_str_to_atom(HashStr),
Cipher = algo_str_to_atom(cipher_name_from_openssl(CipherStr)),
case openssl_is_aead_cipher(CipherStr) of
true ->
{Cipher, aead, Hash};
false ->
- {Cipher, Hash, openssl_prf(Hash)}
+ {Cipher, Hash, default_prf(Kex, Hash)}
end.
-openssl_prf(sha256)->
- sha256;
-openssl_prf(sha384) ->
- sha384;
-openssl_prf(_) ->
- default_prf.
-
diff --git a/lib/ssl/test/property_test/ssl_eqc_cipher_format.erl b/lib/ssl/test/property_test/ssl_eqc_cipher_format.erl
new file mode 100644
index 0000000000..f225065ba6
--- /dev/null
+++ b/lib/ssl/test/property_test/ssl_eqc_cipher_format.erl
@@ -0,0 +1,96 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2019-2019. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(ssl_eqc_cipher_format).
+
+-compile(export_all).
+
+-proptest(eqc).
+-proptest([triq,proper]).
+
+-ifndef(EQC).
+-ifndef(PROPER).
+-ifndef(TRIQ).
+-define(EQC,true).
+-endif.
+-endif.
+-endif.
+
+-ifdef(EQC).
+-include_lib("eqc/include/eqc.hrl").
+-define(MOD_eqc,eqc).
+
+-else.
+-ifdef(PROPER).
+-include_lib("proper/include/proper.hrl").
+-define(MOD_eqc,proper).
+
+-else.
+-ifdef(TRIQ).
+-define(MOD_eqc,triq).
+-include_lib("triq/include/triq.hrl").
+
+-endif.
+-endif.
+-endif.
+
+-define('TLS_v1.3', 'tlsv1.3').
+-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}),
+ case ssl:str_to_suite(ssl:suite_to_str(CipherSuite)) of
+ CipherSuite ->
+ true;
+ _ ->
+ false
+ end
+ ).
+
+prop_tls_cipher_suite_openssl_name() ->
+ ?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;
+ _ ->
+ false
+ end
+ ).
+
+
+%%--------------------------------------------------------------------
+%% Generators -----------------------------------------------
+%%--------------------------------------------------------------------
+tls_version() ->
+ oneof([?'TLS_v1.2', ?'TLS_v1.1', ?'TLS_v1', ?'SSL_v3']).
+
+cipher_suite(Version) ->
+ oneof(cipher_suites(Version)).
+
+cipher_suites(Version) ->
+ ssl:cipher_suites(all, Version).
+
diff --git a/lib/ssl/test/ssl_eqc_SUITE.erl b/lib/ssl/test/ssl_eqc_SUITE.erl
index bd36d35c02..bfdb1a3d54 100644
--- a/lib/ssl/test/ssl_eqc_SUITE.erl
+++ b/lib/ssl/test/ssl_eqc_SUITE.erl
@@ -27,7 +27,9 @@
all() ->
[
- tls_handshake_encoding
+ tls_handshake_encoding,
+ tls_cipher_suite_names,
+ tls_cipher_openssl_suite_names
].
%%--------------------------------------------------------------------
@@ -56,3 +58,13 @@ tls_handshake_encoding(Config) when is_list(Config) ->
%% manual test: proper:quickcheck(ssl_eqc_handshake:prop_tls_hs_encode_decode()).
true = ct_property_test:quickcheck(ssl_eqc_handshake:prop_tls_hs_encode_decode(),
Config).
+
+tls_cipher_suite_names(Config) when is_list(Config) ->
+ %% manual test: proper:quickcheck(ssl_eqc_cipher_format:prop_tls_cipher_suite_rfc_name()).
+ true = ct_property_test:quickcheck(ssl_eqc_cipher_format:prop_tls_cipher_suite_rfc_name(),
+ Config).
+
+tls_cipher_openssl_suite_names(Config) when is_list(Config) ->
+ %% manual test: proper:quickcheck(ssl_eqc_handshake:prop_tls_cipher_suite_openssl_name()).
+ true = ct_property_test:quickcheck(ssl_eqc_cipher_format:prop_tls_cipher_suite_openssl_name(),
+ Config).