summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIngela Anderton Andin <ingela@erlang.org>2020-03-05 11:21:21 +0100
committerIngela Anderton Andin <ingela@erlang.org>2020-03-05 11:21:21 +0100
commit115357fb3958132f759bc12aee9c84fd3a6d5248 (patch)
treeafd8064cd480faec547bfdb9c462e3ff89e08c1c
parentafbd3cfe96930eba2dbde9632683a558fa6deb67 (diff)
parentfa7c7409f42aa8577e56a81efb68044d8a13f873 (diff)
downloaderlang-115357fb3958132f759bc12aee9c84fd3a6d5248.tar.gz
Merge branch 'ingela/ssl/public_key/edwardcurves-TLS-1.2/OTP-16528' into maint
* ingela/ssl/public_key/edwardcurves-TLS-1.2/OTP-16528: ssl: Add TLS-1.3 group to ssl_cipher_suite_SUITE ssl: Add support for key exchange with Edwards curves and RSASSA-PSS in TLS-1.2 public_key: Add support for key exchange with Edward curves
-rw-r--r--lib/public_key/asn1/PKIX1Algorithms88.asn18
-rw-r--r--lib/public_key/src/pubkey_cert_records.erl8
-rw-r--r--lib/public_key/src/public_key.erl4
-rw-r--r--lib/ssl/src/ssl.app.src2
-rw-r--r--lib/ssl/src/ssl_handshake.erl20
-rw-r--r--lib/ssl/src/tls_sender.erl4
-rw-r--r--lib/ssl/src/tls_v1.erl6
-rw-r--r--lib/ssl/test/ssl_cipher_suite_SUITE.erl95
8 files changed, 140 insertions, 7 deletions
diff --git a/lib/public_key/asn1/PKIX1Algorithms88.asn1 b/lib/public_key/asn1/PKIX1Algorithms88.asn1
index 6cc6745af6..207ab005a9 100644
--- a/lib/public_key/asn1/PKIX1Algorithms88.asn1
+++ b/lib/public_key/asn1/PKIX1Algorithms88.asn1
@@ -283,4 +283,12 @@
sect571k1 OBJECT IDENTIFIER ::= { ellipticCurve 38 }
sect571r1 OBJECT IDENTIFIER ::= { ellipticCurve 39 }
+
+ id-edwards-curve-algs OBJECT IDENTIFIER ::= { 1 3 101 }
+
+ id-X25519 OBJECT IDENTIFIER ::= { id-edwards-curve-algs 110 }
+ id-X448 OBJECT IDENTIFIER ::= { id-edwards-curve-algs 111 }
+ id-Ed25519 OBJECT IDENTIFIER ::= { id-edwards-curve-algs 112 }
+ id-Ed448 OBJECT IDENTIFIER ::= { id-edwards-curve-algs 113 }
+
END
diff --git a/lib/public_key/src/pubkey_cert_records.erl b/lib/public_key/src/pubkey_cert_records.erl
index 6a80874df8..1c79f904f3 100644
--- a/lib/public_key/src/pubkey_cert_records.erl
+++ b/lib/public_key/src/pubkey_cert_records.erl
@@ -113,7 +113,8 @@ supportedPublicKeyAlgorithms(?'id-keyExchangeAlgorithm') -> 'KEA-PublicKey';
supportedPublicKeyAlgorithms(?'id-ecPublicKey') -> 'ECPoint'.
supportedCurvesTypes(?'characteristic-two-field') -> characteristic_two_field;
-supportedCurvesTypes(?'prime-field') -> prime_field.
+supportedCurvesTypes(?'prime-field') -> prime_field;
+supportedCurvesTypes(?'id-edwards-curve-algs') -> edwards_curve.
namedCurves(?'sect571r1') -> sect571r1;
namedCurves(?'sect571k1') -> sect571k1;
@@ -148,6 +149,8 @@ namedCurves(?'sect163r1') -> sect163r1;
namedCurves(?'sect163k1') -> sect163k1;
namedCurves(?'secp256r1') -> secp256r1;
namedCurves(?'secp192r1') -> secp192r1;
+namedCurves(?'id-X25519') -> x25519;
+namedCurves(?'id-X448') -> x448;
namedCurves(?'brainpoolP160r1') -> brainpoolP160r1;
namedCurves(?'brainpoolP160t1') -> brainpoolP160t1;
namedCurves(?'brainpoolP192r1') -> brainpoolP192r1;
@@ -162,7 +165,6 @@ namedCurves(?'brainpoolP384r1') -> brainpoolP384r1;
namedCurves(?'brainpoolP384t1') -> brainpoolP384t1;
namedCurves(?'brainpoolP512r1') -> brainpoolP512r1;
namedCurves(?'brainpoolP512t1') -> brainpoolP512t1;
-
namedCurves(sect571r1) -> ?'sect571r1';
namedCurves(sect571k1) -> ?'sect571k1';
namedCurves(sect409r1) -> ?'sect409r1';
@@ -196,6 +198,8 @@ namedCurves(sect163r1) -> ?'sect163r1';
namedCurves(sect163k1) -> ?'sect163k1';
namedCurves(secp256r1) -> ?'secp256r1';
namedCurves(secp192r1) -> ?'secp192r1';
+namedCurves(x25519) -> ?'id-X25519';
+namedCurves(x448) -> ?'id-X448';
namedCurves(brainpoolP160r1) -> ?'brainpoolP160r1';
namedCurves(brainpoolP160t1) -> ?'brainpoolP160t1';
namedCurves(brainpoolP192r1) -> ?'brainpoolP192r1';
diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl
index 47266c514c..ce5151750d 100644
--- a/lib/public_key/src/public_key.erl
+++ b/lib/public_key/src/public_key.erl
@@ -1536,6 +1536,10 @@ ec_curve_spec({ecParameters, ECParams}) ->
ec_curve_spec(ECParams);
ec_curve_spec({namedCurve, OID}) when is_tuple(OID), is_integer(element(1,OID)) ->
ec_curve_spec({namedCurve, pubkey_cert_records:namedCurves(OID)});
+ec_curve_spec({namedCurve, x25519 = Name}) ->
+ Name;
+ec_curve_spec({namedCurve, x448 = Name}) ->
+ Name;
ec_curve_spec({namedCurve, Name}) when is_atom(Name) ->
crypto:ec_curve(Name).
diff --git a/lib/ssl/src/ssl.app.src b/lib/ssl/src/ssl.app.src
index c45e6bcf9a..63ccaabd74 100644
--- a/lib/ssl/src/ssl.app.src
+++ b/lib/ssl/src/ssl.app.src
@@ -74,5 +74,5 @@
{applications, [crypto, public_key, kernel, stdlib]},
{env, []},
{mod, {ssl_app, []}},
- {runtime_dependencies, ["stdlib-3.5","public_key-1.5","kernel-6.0",
+ {runtime_dependencies, ["stdlib-3.5","public_key-@OTP-16528@","kernel-6.0",
"erts-10.0","crypto-4.2", "inets-5.10.7"]}]}.
diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl
index 8e53be72ed..3b33af95d0 100644
--- a/lib/ssl/src/ssl_handshake.erl
+++ b/lib/ssl/src/ssl_handshake.erl
@@ -402,6 +402,12 @@ certificate_verify(Signature, PublicKeyInfo, Version,
%%--------------------------------------------------------------------
verify_signature(_Version, _Hash, {_HashAlgo, anon}, _Signature, _) ->
true;
+verify_signature({3, Minor}, Hash, {HashAlgo, rsa_pss_rsae}, Signature, {?rsaEncryption, PubKey, _PubKeyParams})
+ when Minor >= 3 ->
+ public_key:verify({digest, Hash}, HashAlgo, Signature, PubKey,
+ [{rsa_padding, rsa_pkcs1_pss_padding},
+ {rsa_pss_saltlen, -1},
+ {rsa_mgf1_md, HashAlgo}]);
verify_signature({3, Minor}, Hash, {HashAlgo, rsa}, Signature, {?rsaEncryption, PubKey, _PubKeyParams})
when Minor >= 3 ->
public_key:verify({digest, Hash}, HashAlgo, Signature, PubKey);
@@ -2356,6 +2362,20 @@ dec_server_key_params(Len, Keys, Version) ->
<<Params:Len/bytes, Signature/binary>> = Keys,
dec_server_key_signature(Params, Signature, Version).
+dec_server_key_signature(Params, <<?BYTE(8), ?BYTE(SignAlgo),
+ ?UINT16(0)>>, {Major, Minor})
+ when Major == 3, Minor >= 3 ->
+ <<?UINT16(Scheme0)>> = <<?BYTE(8), ?BYTE(SignAlgo)>>,
+ Scheme = ssl_cipher:signature_scheme(Scheme0),
+ {Hash, Sign, _} = ssl_cipher:scheme_to_components(Scheme),
+ {Params, {Hash, Sign}, <<>>};
+dec_server_key_signature(Params, <<?BYTE(8), ?BYTE(SignAlgo),
+ ?UINT16(Len), Signature:Len/binary>>, {Major, Minor})
+ when Major == 3, Minor >= 3 ->
+ <<?UINT16(Scheme0)>> = <<?BYTE(8), ?BYTE(SignAlgo)>>,
+ Scheme = ssl_cipher:signature_scheme(Scheme0),
+ {Hash, Sign, _} = ssl_cipher:scheme_to_components(Scheme),
+ {Params, {Hash, Sign}, Signature};
dec_server_key_signature(Params, <<?BYTE(HashAlgo), ?BYTE(SignAlgo),
?UINT16(0)>>, {Major, Minor})
when Major == 3, Minor >= 3 ->
diff --git a/lib/ssl/src/tls_sender.erl b/lib/ssl/src/tls_sender.erl
index 951d4302e9..790746658e 100644
--- a/lib/ssl/src/tls_sender.erl
+++ b/lib/ssl/src/tls_sender.erl
@@ -540,7 +540,9 @@ key_update_at(Version, #{security_parameters :=
?AES_GCM ->
KeyUpdateAt;
?CHACHA20_POLY1305 ->
- seq_num_wrap
+ seq_num_wrap;
+ ?AES_CCM ->
+ KeyUpdateAt
end;
key_update_at(_, _, KeyUpdateAt) ->
KeyUpdateAt.
diff --git a/lib/ssl/src/tls_v1.erl b/lib/ssl/src/tls_v1.erl
index 381793c65d..38594151d9 100644
--- a/lib/ssl/src/tls_v1.erl
+++ b/lib/ssl/src/tls_v1.erl
@@ -884,7 +884,9 @@ oid_to_enum(?secp384r1) -> 24;
oid_to_enum(?secp521r1) -> 25;
oid_to_enum(?brainpoolP256r1) -> 26;
oid_to_enum(?brainpoolP384r1) -> 27;
-oid_to_enum(?brainpoolP512r1) -> 28.
+oid_to_enum(?brainpoolP512r1) -> 28;
+oid_to_enum(?'id-X25519') -> 29;
+oid_to_enum(?'id-X448') -> 30.
enum_to_oid(1) -> ?sect163k1;
enum_to_oid(2) -> ?sect163r1;
@@ -914,5 +916,7 @@ enum_to_oid(25) -> ?secp521r1;
enum_to_oid(26) -> ?brainpoolP256r1;
enum_to_oid(27) -> ?brainpoolP384r1;
enum_to_oid(28) -> ?brainpoolP512r1;
+enum_to_oid(29) -> ?'id-X25519';
+enum_to_oid(30) -> ?'id-X448';
enum_to_oid(_) ->
undefined.
diff --git a/lib/ssl/test/ssl_cipher_suite_SUITE.erl b/lib/ssl/test/ssl_cipher_suite_SUITE.erl
index e598d662e9..855533cc3d 100644
--- a/lib/ssl/test/ssl_cipher_suite_SUITE.erl
+++ b/lib/ssl/test/ssl_cipher_suite_SUITE.erl
@@ -32,6 +32,7 @@
%%--------------------------------------------------------------------
all() ->
[
+ {group, 'tlsv1.3'},
{group, 'tlsv1.2'},
{group, 'tlsv1.1'},
{group, 'tlsv1'},
@@ -42,6 +43,7 @@ all() ->
groups() ->
[
+ {'tlsv1.3', [], tls_1_3_kex()},
{'tlsv1.2', [], kex()},
{'tlsv1.1', [], kex()},
{'tlsv1', [], kex()},
@@ -60,6 +62,7 @@ groups() ->
ecdhe_rsa_aes_256_gcm,
ecdhe_rsa_chacha20_poly1305
]},
+ {ecdhe_1_3_rsa_cert, [], tls_1_3_cipher_suites()},
{ecdhe_ecdsa, [],[ecdhe_ecdsa_rc4_128,
ecdhe_ecdsa_3des_ede_cbc,
ecdhe_ecdsa_aes_128_cbc,
@@ -127,6 +130,17 @@ groups() ->
]}
].
+
+tls_1_3_kex() ->
+ [{group, ecdhe_1_3_rsa_cert}].
+
+tls_1_3_cipher_suites() ->
+ [aes_256_gcm_sha384,
+ aes_128_gcm_sha256,
+ chacha20_poly1305_sha256,
+ aes_128_ccm_sha256
+ ].
+
kex() ->
rsa() ++ ecdsa() ++ dss() ++ anonymous().
@@ -186,7 +200,13 @@ end_per_suite(_Config) ->
ssl:stop(),
application:stop(crypto).
-
+init_per_group(GroupName, Config) when GroupName == ecdhe_1_3_rsa_cert ->
+ case proplists:get_bool(ecdh, proplists:get_value(public_keys, crypto:supports())) of
+ true ->
+ init_certs(GroupName, Config);
+ false ->
+ {skip, "Missing EC crypto support"}
+ end;
init_per_group(GroupName, Config) when GroupName == ecdh_anon;
GroupName == ecdhe_rsa;
GroupName == ecdhe_psk ->
@@ -318,6 +338,53 @@ init_per_testcase(TestCase, Config) when TestCase == psk_aes_256_ccm_8;
_ ->
{skip, "Missing AES_256_CCM crypto support"}
end;
+init_per_testcase(aes_256_gcm_sha384, Config) ->
+ SupCiphers = proplists:get_value(ciphers, crypto:supports()),
+ SupHashs = proplists:get_value(hashs, crypto:supports()),
+ case (lists:member(aes_256_gcm, SupCiphers)) andalso
+ (lists:member(sha384, SupHashs))
+ of
+ true ->
+ ct:timetrap({seconds, 5}),
+ Config;
+ _ ->
+ {skip, "Missing AES_256_GCM_SHA384 crypto support"}
+ end;
+init_per_testcase(aes_128_gcm_sha256, Config) ->
+ SupCiphers = proplists:get_value(ciphers, crypto:supports()),
+ SupHashs = proplists:get_value(hashs, crypto:supports()),
+ case (lists:member(aes_256_gcm, SupCiphers)) andalso
+ (lists:member(sha256, SupHashs))
+ of
+ true ->
+ ct:timetrap({seconds, 5}),
+ Config;
+ _ ->
+ {skip, "Missing AES_128_GCM_SHA256 crypto support"}
+ end;
+init_per_testcase(chacha20_poly1305_sha256, Config) ->
+ SupCiphers = proplists:get_value(ciphers, crypto:supports()),
+ SupHashs = proplists:get_value(hashs, crypto:supports()),
+ case (lists:member(chacha20_poly1305, SupCiphers)) andalso
+ (lists:member(sha256, SupHashs))
+ of
+ true ->
+ ct:timetrap({seconds, 5}),
+ Config;
+ _ ->
+ {skip, "Missing chacha20_poly1305_sha256 crypto support"}
+ end;
+init_per_testcase(aes_128_ccm_sha256, Config) ->
+ SupCiphers = proplists:get_value(ciphers, crypto:supports()),
+ SupHashs = proplists:get_value(hashs, crypto:supports()),
+ case (lists:member(aes_128_ccm, SupCiphers)) andalso
+ (lists:member(sha256, SupHashs)) of
+ true ->
+ ct:timetrap({seconds, 5}),
+ Config;
+ _ ->
+ {skip, "Missing AES_128_CCM_SHA256 crypto support"}
+ end;
init_per_testcase(TestCase, Config) ->
Cipher = ssl_test_lib:test_cipher(TestCase, Config),
SupCiphers = proplists:get_value(ciphers, crypto:supports()),
@@ -335,7 +402,6 @@ end_per_testcase(_TestCase, Config) ->
%%--------------------------------------------------------------------
%% Initializtion ------------------------------------------
%%--------------------------------------------------------------------
-
init_certs(srp_rsa, Config) ->
DefConf = ssl_test_lib:default_cert_chain_conf(),
CertChainConf = ssl_test_lib:gen_conf(rsa, rsa, DefConf, DefConf),
@@ -367,6 +433,14 @@ init_certs(rsa, Config) ->
[{tls_config, #{server_config => ServerOpts,
client_config => ClientOpts}} |
proplists:delete(tls_config, Config)];
+init_certs(ecdhe_1_3_rsa_cert, Config) ->
+ ClientExt = x509_test:extensions([{key_usage, [digitalSignature]}]),
+ {ClientOpts, ServerOpts} = ssl_test_lib:make_rsa_cert_chains([{server_chain,
+ [[],[],[{extensions, ClientExt}]]}],
+ Config, "_peer_rsa_digitalsign"),
+ [{tls_config, #{server_config => ServerOpts,
+ client_config => ClientOpts}} |
+ proplists:delete(tls_config, Config)];
init_certs(dhe_dss, Config) ->
DefConf = ssl_test_lib:default_cert_chain_conf(),
CertChainConf = ssl_test_lib:gen_conf(dsa, dsa, DefConf, DefConf),
@@ -427,6 +501,22 @@ init_certs(_GroupName, Config) ->
%% Test Cases --------------------------------------------------------
%%--------------------------------------------------------------------
+aes_256_gcm_sha384(Config) when is_list(Config)->
+ Version = ssl_test_lib:protocol_version(Config),
+ cipher_suite_test(ssl:str_to_suite("TLS_AES_256_GCM_SHA384"), Version, Config).
+
+aes_128_gcm_sha256(Config) when is_list(Config) ->
+ Version = ssl_test_lib:protocol_version(Config),
+ cipher_suite_test(ssl:str_to_suite("TLS_AES_128_GCM_SHA256"), Version, Config).
+
+chacha20_poly1305_sha256(Config) when is_list(Config) ->
+ Version = ssl_test_lib:protocol_version(Config),
+ cipher_suite_test(ssl:str_to_suite("TLS_CHACHA20_POLY1305_SHA256"), Version, Config).
+
+aes_128_ccm_sha256(Config) when is_list(Config) ->
+ Version = ssl_test_lib:protocol_version(Config),
+ cipher_suite_test(ssl:str_to_suite("TLS_AES_128_CCM_SHA256"), Version, Config).
+
%%--------------------------------------------------------------------
%% SRP --------------------------------------------------------
%%--------------------------------------------------------------------
@@ -775,3 +865,4 @@ test_ciphers(Kex, Cipher, Version) ->
(_) -> false
end}]).
+