Skip to content

Commit 7397ffc

Browse files
committed
ssl: Adjust max_handshake_size for SLH_DSA
Correct doc and fix whitespace errors and long lines
1 parent 9174fc6 commit 7397ffc

File tree

2 files changed

+65
-40
lines changed

2 files changed

+65
-40
lines changed

lib/ssl/src/ssl.erl

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -660,13 +660,13 @@ Options common to both client and server side.
660660

661661
The `keep_secrets` functionality is disabled (`false`) by default.
662662
If set to legacy value `true` keylog information can be retrieved from the connection
663-
using connection_information/2.
663+
using connection_information/2.
664664

665665
Added in OTP 23.2.
666666

667667
> #### Note {: .info }
668668
> Note that having to ask the connection has some drawbacks
669-
> as for instance you can not get keylog information for
669+
> as for instance you can not get keylog information for
670670
> failed connections, and other keylog items have
671671
> to be retrieved in a polling manner and are not correctly
672672
> formatted for key_updates.
@@ -692,7 +692,8 @@ Options common to both client and server side.
692692
Used to limit the size of valid TLS handshake packets to avoid DoS
693693
attacks.
694694

695-
Integer (24 bits, unsigned). Defaults to `256*1024`.
695+
Integer (24 bits, unsigned). Defaults to `256*1024` before OTP-26 or if SLH-DSA algorithms
696+
are configured, otherwise the default is `256*1024`/2.
696697

697698
- **`{hibernate_after, HibernateTimeout}`** - Hibernate inactive connection processes.
698699

@@ -723,9 +724,10 @@ Options common to both client and server side.
723724
{ciphers, cipher_suites()} |
724725
{signature_algs, signature_algs()} |
725726
{signature_algs_cert, [sign_scheme()]} |
726-
{keep_secrets, KeepSecrets:: boolean() |
727-
{keylog_hs, fun((Info::keylog_info()) -> any())} |
728-
{keylog, fun((Info::keylog_info()) -> any())}} |
727+
{keep_secrets,
728+
KeepSecrets:: boolean() |
729+
{keylog_hs, fun((Info::keylog_info()) -> any())} |
730+
{keylog, fun((Info::keylog_info()) -> any())}} |
729731
{max_handshake_size, HandshakeSize::pos_integer()} |
730732
{versions, [protocol_version()]} |
731733
{log_level, Level::logger:level() | none | all} |
@@ -734,7 +736,7 @@ Options common to both client and server side.
734736
{sender_spawn_opts, SpawnOpts::[erlang:spawn_opt_option()]}.
735737

736738

737-
-doc(#{group =>
739+
-doc(#{group =>
738740
<<"Client and Server Options">>}).
739741
-doc """
740742
Common certificate related options to both client and server.

lib/ssl/src/ssl_config.erl

Lines changed: 56 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@
2727

2828
-include("ssl_internal.hrl").
2929
-include("ssl_connection.hrl").
30-
-include_lib("public_key/include/public_key.hrl").
30+
-include_lib("public_key/include/public_key.hrl").
3131

3232
-define(DEFAULT_MAX_SESSION_CACHE, 1000).
3333
-define(TWO_HOURS, 7200).
34-
-define(SEVEN_DAYS, 604800).
34+
-define(SEVEN_DAYS, 604800).
3535

3636
%% Connection parameter configuration
3737
-export([init/2,
@@ -175,22 +175,25 @@ group_pairs(Pairs) ->
175175
dsa => []
176176
}).
177177

178-
group_pairs([#{private_key := #'ECPrivateKey'{parameters = {namedCurve, ?'id-Ed25519'}}} = Pair | Rest],
178+
group_pairs([#{private_key :=
179+
#'ECPrivateKey'{parameters = {namedCurve, ?'id-Ed25519'}}} = Pair | Rest],
179180
#{eddsa := EDDSA} = Group) ->
180181
group_pairs(Rest, Group#{eddsa => [Pair | EDDSA]});
181-
group_pairs([#{private_key := #'ECPrivateKey'{parameters = {namedCurve, ?'id-Ed448'}}} = Pair | Rest],
182+
group_pairs([#{private_key :=
183+
#'ECPrivateKey'{parameters = {namedCurve, ?'id-Ed448'}}} = Pair | Rest],
182184
#{eddsa := EDDSA} = Group) ->
183185
group_pairs(Rest, Group#{eddsa => [Pair | EDDSA]});
184186
group_pairs([#{private_key := #'ECPrivateKey'{}} = Pair | Rest], #{ecdsa := ECDSA} = Group) ->
185187
group_pairs(Rest, Group#{ecdsa => [Pair | ECDSA]});
186-
group_pairs([#{private_key := {#'RSAPrivateKey'{}, #'RSASSA-PSS-params'{}}} = Pair | Rest],
188+
group_pairs([#{private_key := {#'RSAPrivateKey'{}, #'RSASSA-PSS-params'{}}} = Pair | Rest],
187189
#{rsa_pss_pss := RSAPSS} = Group) ->
188190
group_pairs(Rest, Group#{rsa_pss_pss => [Pair | RSAPSS]});
189191
group_pairs([#{private_key := #'RSAPrivateKey'{}} = Pair | Rest], #{rsa := RSA} = Group) ->
190192
group_pairs(Rest, Group#{rsa => [Pair | RSA]});
191193
group_pairs([#{private_key := #'ML-DSAPrivateKey'{}} = Pair | Rest], #{mldsa := MLDSA} = Group) ->
192194
group_pairs(Rest, Group#{mldsa => [Pair | MLDSA]});
193-
group_pairs([#{private_key := #'SLH-DSAPrivateKey'{}} = Pair | Rest], #{slhdsa := SLHDSA} = Group) ->
195+
group_pairs([#{private_key :=
196+
#'SLH-DSAPrivateKey'{}} = Pair | Rest], #{slhdsa := SLHDSA} = Group) ->
194197
group_pairs(Rest, Group#{slhdsa => [Pair | SLHDSA]});
195198
group_pairs([#{private_key := #'DSAPrivateKey'{}} = Pair | Rest], #{dsa := DSA} = Group) ->
196199
group_pairs(Rest, Group#{dsa => [Pair | DSA]});
@@ -337,10 +340,11 @@ private_key(#'PrivateKeyInfo'{privateKeyAlgorithm =
337340
Algorithm == ?'id-slh-dsa-shake-256f';
338341
Algorithm == ?'id-slh-dsa-shake-256s' ->
339342
public_key:der_decode('SLH-DSA-PrivateKey', DerKey);
340-
private_key(#'PrivateKeyInfo'{privateKeyAlgorithm =
341-
#'PrivateKeyInfo_privateKeyAlgorithm'{algorithm = ?'id-ecPublicKey',
342-
parameters = {asn1_OPENTYPE, Parameters}},
343-
privateKey = Key}) ->
343+
private_key(#'PrivateKeyInfo'{
344+
privateKeyAlgorithm =
345+
#'PrivateKeyInfo_privateKeyAlgorithm'{algorithm = ?'id-ecPublicKey',
346+
parameters = {asn1_OPENTYPE, Parameters}},
347+
privateKey = Key}) ->
344348
ECKey = public_key:der_decode('ECPrivateKey', iolist_to_binary(Key)),
345349
ECParameters = public_key:der_decode('EcpkParameters', Parameters),
346350
ECKey#'ECPrivateKey'{parameters = ECParameters};
@@ -476,7 +480,7 @@ dh_file(DbHandle, DHParamFile) ->
476480
end
477481
catch
478482
_:Reason ->
479-
file_error(DHParamFile, {dhfile, Reason})
483+
file_error(DHParamFile, {dhfile, Reason})
480484
end.
481485

482486
%%====================================================================
@@ -815,7 +819,8 @@ opt_certs(UserOpts, #{log_level := LogLevel, versions := Versions} = Opts0, Env)
815819
{old, [CertKey]} ->
816820
opt_old_certs(UserOpts, CertKey, Opts0, Env);
817821
{Where, CKs0} when is_list(CKs0) ->
818-
warn_override(Where, UserOpts, certs_keys, [cert,certfile,key,keyfile,password], LogLevel),
822+
warn_override(Where, UserOpts, certs_keys,
823+
[cert,certfile,key,keyfile,password], LogLevel),
819824
CKs = lists:foldl(fun(CK0, Acc) ->
820825
CK = check_legacy_cert_key(Versions, CK0, #{}, LogLevel),
821826
case maps:size(CK) =:= 0 of
@@ -839,7 +844,7 @@ opt_old_certs(UserOpts, CertKeys, #{log_level := LogLevel, versions := Versions}
839844

840845
check_legacy_cert_key(Versions, UserOpts, CertKeys0, LogLevel) ->
841846
CertKeys1 = handle_legacy_cert_opt(UserOpts, CertKeys0, LogLevel),
842-
CertKeys = handle_legacy_key_opt(Versions, UserOpts, CertKeys1),
847+
CertKeys = handle_legacy_key_opt(Versions, UserOpts, CertKeys1),
843848
handle_possible_legacy_key_password(UserOpts, CertKeys).
844849

845850
handle_legacy_cert_opt(UserOpts, CertKeys, LogLevel) ->
@@ -1136,7 +1141,7 @@ valid_signature_algs(AlgCertSchemes0, #{versions := Versions} = Opts, UserOpts,
11361141
{old, Algs} ->
11371142
{Algs, AlgCertSchemes0}
11381143
end.
1139-
1144+
11401145
opt_signature_algs_not_valid(UserOpts, #{versions := Versions} = Opts0) ->
11411146
Opts =
11421147
case get_opt_list(signature_algs, undefined, UserOpts, Opts0) of
@@ -1167,7 +1172,8 @@ opt_alpn(UserOpts, #{versions := Versions} = Opts, #{role := server}) ->
11671172

11681173
{Where, NPA} = get_opt_list(next_protocols_advertised, undefined, UserOpts, Opts),
11691174
validate_protocols(is_list(NPA), next_protocols_advertised, NPA),
1170-
assert_version_dep(is_list(NPA), next_protocols_advertised, Versions, ['tlsv1','tlsv1.1','tlsv1.2']),
1175+
assert_version_dep(is_list(NPA), next_protocols_advertised, Versions,
1176+
['tlsv1','tlsv1.1','tlsv1.2']),
11711177

11721178
assert_client_only(alpn_advertised_protocols, UserOpts),
11731179
assert_client_only(client_preferred_next_protocols, UserOpts),
@@ -1203,10 +1209,11 @@ make_next_protocol_selector({Precedence, PrefProtcol} = V) ->
12031209
make_next_protocol_selector({Precedence, PrefProtcol, ?NO_PROTOCOL});
12041210
make_next_protocol_selector({Precedence, AllProtocols, DefP} = V) ->
12051211
option_error(not is_list(AllProtocols), client_preferred_next_protocols, V),
1206-
option_error(not (is_binary(DefP) andalso byte_size(DefP) < 256), client_preferred_next_protocols, V),
1212+
option_error(not (is_binary(DefP) andalso byte_size(DefP) < 256),
1213+
client_preferred_next_protocols, V),
12071214
validate_protocols(true, client_preferred_next_protocols, AllProtocols),
12081215
case Precedence of
1209-
client ->
1216+
client ->
12101217
fun(Advertised) ->
12111218
Search = fun(P) -> lists:member(P, Advertised) end,
12121219
case lists:search(Search, AllProtocols) of
@@ -1398,7 +1405,7 @@ handle_user_lookup(UserOpts, #{versions := Versions} = Opts) ->
13981405
{_, Lookup} ->
13991406
Lookup
14001407
end.
1401-
1408+
14021409

14031410
opt_supported_groups(UserOpts, #{versions := TlsVsns} = Opts, Env) ->
14041411
SG = case get_opt_list(supported_groups, undefined, UserOpts, Opts) of
@@ -1421,7 +1428,7 @@ opt_supported_groups(UserOpts, #{versions := TlsVsns} = Opts, Env) ->
14211428
{old, CPS0} -> CPS0;
14221429
{_, CPS0} -> handle_cipher_option(CPS0, TlsVsns)
14231430
end,
1424-
1431+
14251432
ECCS = try assert_version_dep(eccs, TlsVsns, ['tlsv1.2', 'tlsv1.1', 'tlsv1']) of
14261433
_ ->
14271434
case get_opt_list(eccs, undefined, UserOpts, Opts) of
@@ -1468,11 +1475,26 @@ opt_crl(UserOpts, Opts, _Env) ->
14681475
opt_handshake(UserOpts, Opts, _Env) ->
14691476
{_, HS} = get_opt_of(handshake, [hello, full], full, UserOpts, Opts),
14701477

1471-
{_, MHSS} = get_opt_int(max_handshake_size, 1, ?MAX_UNIT24, ?DEFAULT_MAX_HANDSHAKE_SIZE,
1478+
DefaultMaxHS = default_max_hs(Opts),
1479+
1480+
{_, MHSS} = get_opt_int(max_handshake_size, 1, ?MAX_UNIT24 , DefaultMaxHS,
14721481
UserOpts, Opts),
14731482

14741483
Opts#{handshake => HS, max_handshake_size => MHSS}.
14751484

1485+
default_max_hs(#{signature_algs:= Algs}) ->
1486+
%%% In OTP-26 max handshake_size was lowered by half for most
1487+
%%% handshakes would fit that size and OpenSSL had a lower default
1488+
case sets:intersection(sets:from_list(Algs),
1489+
sets:form_list(tls_v1:slh_dsa_schemes())) of
1490+
[] ->
1491+
?DEFAULT_MAX_HANDSHAKE_SIZE;
1492+
[_|_] ->
1493+
%% SLH_DSA creates fairly big handshake sizes so raise limit back
1494+
%% if these algrorith$ms are supported,
1495+
?DEFAULT_MAX_HANDSHAKE_SIZE * 2
1496+
end.
1497+
14761498
opt_use_srtp(UserOpts, #{protocol := Protocol} = Opts, _Env) ->
14771499
UseSRTP = case get_opt_map(use_srtp, undefined, UserOpts, Opts) of
14781500
{old, UseSRTP0} ->
@@ -1788,7 +1810,8 @@ validate_server_cert_opts(#{handshake := hello}, _) ->
17881810
%% This verification should be done only when handshake := full, as options
17891811
%% to fulfill the requirement can be supplied at that time.
17901812
ok;
1791-
validate_server_cert_opts(#{certs_keys := [_|_]=CertsKeys, ciphers := CPHS, versions := Versions}, _) ->
1813+
validate_server_cert_opts(#{certs_keys := [_|_]=CertsKeys,
1814+
ciphers := CPHS, versions := Versions}, _) ->
17921815
validate_certs_or_anon_ciphers(CertsKeys, CPHS, Versions);
17931816
validate_server_cert_opts(#{ciphers := CPHS, versions := Versions}, _) ->
17941817
validate_anon_ciphers(CPHS, Versions).
@@ -1872,7 +1895,7 @@ binary_cipher_suites([?TLS_1_3], []) ->
18721895
%% not require explicit configuration TLS-1.3
18731896
%% only mode.
18741897
default_binary_suites(exclusive, ?TLS_1_3);
1875-
binary_cipher_suites([Version| _], []) ->
1898+
binary_cipher_suites([Version| _], []) ->
18761899
%% Defaults to all supported suites that does
18771900
%% not require explicit configuration
18781901
default_binary_suites(default, Version);
@@ -1928,9 +1951,9 @@ tuple_to_map({Kex, Cipher, Mac, Prf}) ->
19281951
prf => Prf}.
19291952

19301953
%% Backwards compatible
1931-
tuple_to_map_mac(aes_128_gcm, _) ->
1954+
tuple_to_map_mac(aes_128_gcm, _) ->
19321955
aead;
1933-
tuple_to_map_mac(aes_256_gcm, _) ->
1956+
tuple_to_map_mac(aes_256_gcm, _) ->
19341957
aead;
19351958
tuple_to_map_mac(chacha20_poly1305, _) ->
19361959
aead;
@@ -1974,20 +1997,20 @@ unambiguous_path(Value) ->
19741997
validate_filename(UP, cacertfile).
19751998

19761999
%% Assert that basic options are on the format {Key, Value}
1977-
%% with a few exceptions and phase out log_alert
2000+
%% with a few exceptions and phase out log_alert
19782001
handle_option_format([], Acc) ->
19792002
lists:reverse(Acc);
19802003
handle_option_format([{log_alert, Bool} | Rest], Acc) when is_boolean(Bool) ->
19812004
case proplists:get_value(log_level, Acc ++ Rest, undefined) of
19822005
undefined ->
1983-
handle_option_format(Rest, [{log_level,
2006+
handle_option_format(Rest, [{log_level,
19842007
map_log_level(Bool)} | Acc]);
19852008
_ ->
19862009
handle_option_format(Rest, Acc)
19872010
end;
19882011
handle_option_format([{Key,_} = Opt | Rest], Acc) when is_atom(Key) ->
19892012
handle_option_format(Rest, [Opt | Acc]);
1990-
%% Handle exceptions
2013+
%% Handle exceptions
19912014
handle_option_format([{raw,_,_,_} = Opt | Rest], Acc) ->
19922015
handle_option_format(Rest, [Opt | Acc]);
19932016
handle_option_format([inet = Opt | Rest], Acc) ->
@@ -2074,11 +2097,11 @@ connection_cb(tls) ->
20742097
connection_cb(dtls) ->
20752098
dtls_gen_connection.
20762099

2077-
handle_possible_version_change([Version|_], [Version|_] = VersionOpt, OrigSSLOpts, _) ->
2100+
handle_possible_version_change([Version|_], [Version|_] = VersionOpt, OrigSSLOpts, _) ->
20782101
filter_for_versions(VersionOpt, OrigSSLOpts);
20792102
handle_possible_version_change(_, [], OrigSSLOpts, _) ->
20802103
OrigSSLOpts;
2081-
handle_possible_version_change(_, VersionsOpt, #{ciphers := Suites} = OrigSSLOpts, Record) ->
2104+
handle_possible_version_change(_, VersionsOpt, #{ciphers := Suites} = OrigSSLOpts, Record) ->
20822105
FallbackSuites = ciphers_for_version(VersionsOpt, Suites, Record),
20832106
filter_for_versions(VersionsOpt, OrigSSLOpts#{ciphers => FallbackSuites}).
20842107

@@ -2167,7 +2190,7 @@ validate_cert_keys_pems(#{certs_keys := CertKeys}, PemCacheName) ->
21672190
case handle_key_file(CertKey, PemCacheName) of
21682191
ok ->
21692192
true;
2170-
{error, Reason} ->
2193+
{error, Reason} ->
21712194
#{keyfile := KeyFile} = CertKey,
21722195
option_error(keyfile, {binary_to_list(KeyFile), Reason})
21732196
end
@@ -2177,7 +2200,7 @@ validate_cert_keys_pems(#{certs_keys := CertKeys}, PemCacheName) ->
21772200
validate_cert_keys_pems(_, _) ->
21782201
%% Needs validation when called from listen, to
21792202
%% provide early failure.
2180-
true.
2203+
true.
21812204

21822205
validate_cacerts_pem(#{cacertfile := Cacertfile}, PemCacheName) ->
21832206
case do_handle_cert_file(Cacertfile, PemCacheName) of
@@ -2195,7 +2218,7 @@ validate_dh_pem(#{dhfile := DHFile}, PemCacheName) ->
21952218
true;
21962219
{error, Reason} ->
21972220
option_error(dhfile, Reason)
2198-
end;
2221+
end;
21992222
validate_dh_pem(_, _) ->
22002223
true.
22012224

@@ -2207,7 +2230,7 @@ handle_cert_file(_,_) ->
22072230

22082231
do_handle_cert_file(File, PemCacheName) ->
22092232
case file:read_file(File) of
2210-
{ok, Pem} ->
2233+
{ok, Pem} ->
22112234
Entries = public_key:pem_decode(Pem),
22122235
case lists:keyfind('Certificate', 1, Entries) of
22132236
false ->

0 commit comments

Comments
 (0)