Skip to content

Commit 3a93b8c

Browse files
committed
ssl: Adjust max_handshake_size for SLH_DSA
Correct doc and fix whitespace errors and long lines
1 parent 2c26091 commit 3a93b8c

File tree

2 files changed

+69
-40
lines changed

2 files changed

+69
-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: 60 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,30 @@ 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:= undefined}) ->
1486+
?DEFAULT_MAX_EARLY_DATA_SIZE;
1487+
default_max_hs(#{signature_algs:= Algs}) ->
1488+
%%% In OTP-26 max handshake_size was lowered by half for most
1489+
%%% handshakes would fit that size and OpenSSL had a lower default
1490+
Set = sets:intersection(sets:from_list(Algs, [{version, 2}]),
1491+
sets:from_list(tls_v1:slh_dsa_schemes(),
1492+
[{version, 2}])),
1493+
case sets:is_empty(Set) of
1494+
true ->
1495+
?DEFAULT_MAX_HANDSHAKE_SIZE;
1496+
false ->
1497+
%% SLH_DSA creates fairly big handshake sizes so raise limit back
1498+
%% if these algorithms are supported,
1499+
?DEFAULT_MAX_HANDSHAKE_SIZE * 2
1500+
end.
1501+
14761502
opt_use_srtp(UserOpts, #{protocol := Protocol} = Opts, _Env) ->
14771503
UseSRTP = case get_opt_map(use_srtp, undefined, UserOpts, Opts) of
14781504
{old, UseSRTP0} ->
@@ -1788,7 +1814,8 @@ validate_server_cert_opts(#{handshake := hello}, _) ->
17881814
%% This verification should be done only when handshake := full, as options
17891815
%% to fulfill the requirement can be supplied at that time.
17901816
ok;
1791-
validate_server_cert_opts(#{certs_keys := [_|_]=CertsKeys, ciphers := CPHS, versions := Versions}, _) ->
1817+
validate_server_cert_opts(#{certs_keys := [_|_]=CertsKeys,
1818+
ciphers := CPHS, versions := Versions}, _) ->
17921819
validate_certs_or_anon_ciphers(CertsKeys, CPHS, Versions);
17931820
validate_server_cert_opts(#{ciphers := CPHS, versions := Versions}, _) ->
17941821
validate_anon_ciphers(CPHS, Versions).
@@ -1872,7 +1899,7 @@ binary_cipher_suites([?TLS_1_3], []) ->
18721899
%% not require explicit configuration TLS-1.3
18731900
%% only mode.
18741901
default_binary_suites(exclusive, ?TLS_1_3);
1875-
binary_cipher_suites([Version| _], []) ->
1902+
binary_cipher_suites([Version| _], []) ->
18761903
%% Defaults to all supported suites that does
18771904
%% not require explicit configuration
18781905
default_binary_suites(default, Version);
@@ -1928,9 +1955,9 @@ tuple_to_map({Kex, Cipher, Mac, Prf}) ->
19281955
prf => Prf}.
19291956

19301957
%% Backwards compatible
1931-
tuple_to_map_mac(aes_128_gcm, _) ->
1958+
tuple_to_map_mac(aes_128_gcm, _) ->
19321959
aead;
1933-
tuple_to_map_mac(aes_256_gcm, _) ->
1960+
tuple_to_map_mac(aes_256_gcm, _) ->
19341961
aead;
19351962
tuple_to_map_mac(chacha20_poly1305, _) ->
19361963
aead;
@@ -1974,20 +2001,20 @@ unambiguous_path(Value) ->
19742001
validate_filename(UP, cacertfile).
19752002

19762003
%% Assert that basic options are on the format {Key, Value}
1977-
%% with a few exceptions and phase out log_alert
2004+
%% with a few exceptions and phase out log_alert
19782005
handle_option_format([], Acc) ->
19792006
lists:reverse(Acc);
19802007
handle_option_format([{log_alert, Bool} | Rest], Acc) when is_boolean(Bool) ->
19812008
case proplists:get_value(log_level, Acc ++ Rest, undefined) of
19822009
undefined ->
1983-
handle_option_format(Rest, [{log_level,
2010+
handle_option_format(Rest, [{log_level,
19842011
map_log_level(Bool)} | Acc]);
19852012
_ ->
19862013
handle_option_format(Rest, Acc)
19872014
end;
19882015
handle_option_format([{Key,_} = Opt | Rest], Acc) when is_atom(Key) ->
19892016
handle_option_format(Rest, [Opt | Acc]);
1990-
%% Handle exceptions
2017+
%% Handle exceptions
19912018
handle_option_format([{raw,_,_,_} = Opt | Rest], Acc) ->
19922019
handle_option_format(Rest, [Opt | Acc]);
19932020
handle_option_format([inet = Opt | Rest], Acc) ->
@@ -2074,11 +2101,11 @@ connection_cb(tls) ->
20742101
connection_cb(dtls) ->
20752102
dtls_gen_connection.
20762103

2077-
handle_possible_version_change([Version|_], [Version|_] = VersionOpt, OrigSSLOpts, _) ->
2104+
handle_possible_version_change([Version|_], [Version|_] = VersionOpt, OrigSSLOpts, _) ->
20782105
filter_for_versions(VersionOpt, OrigSSLOpts);
20792106
handle_possible_version_change(_, [], OrigSSLOpts, _) ->
20802107
OrigSSLOpts;
2081-
handle_possible_version_change(_, VersionsOpt, #{ciphers := Suites} = OrigSSLOpts, Record) ->
2108+
handle_possible_version_change(_, VersionsOpt, #{ciphers := Suites} = OrigSSLOpts, Record) ->
20822109
FallbackSuites = ciphers_for_version(VersionsOpt, Suites, Record),
20832110
filter_for_versions(VersionsOpt, OrigSSLOpts#{ciphers => FallbackSuites}).
20842111

@@ -2167,7 +2194,7 @@ validate_cert_keys_pems(#{certs_keys := CertKeys}, PemCacheName) ->
21672194
case handle_key_file(CertKey, PemCacheName) of
21682195
ok ->
21692196
true;
2170-
{error, Reason} ->
2197+
{error, Reason} ->
21712198
#{keyfile := KeyFile} = CertKey,
21722199
option_error(keyfile, {binary_to_list(KeyFile), Reason})
21732200
end
@@ -2177,7 +2204,7 @@ validate_cert_keys_pems(#{certs_keys := CertKeys}, PemCacheName) ->
21772204
validate_cert_keys_pems(_, _) ->
21782205
%% Needs validation when called from listen, to
21792206
%% provide early failure.
2180-
true.
2207+
true.
21812208

21822209
validate_cacerts_pem(#{cacertfile := Cacertfile}, PemCacheName) ->
21832210
case do_handle_cert_file(Cacertfile, PemCacheName) of
@@ -2195,7 +2222,7 @@ validate_dh_pem(#{dhfile := DHFile}, PemCacheName) ->
21952222
true;
21962223
{error, Reason} ->
21972224
option_error(dhfile, Reason)
2198-
end;
2225+
end;
21992226
validate_dh_pem(_, _) ->
22002227
true.
22012228

@@ -2207,7 +2234,7 @@ handle_cert_file(_,_) ->
22072234

22082235
do_handle_cert_file(File, PemCacheName) ->
22092236
case file:read_file(File) of
2210-
{ok, Pem} ->
2237+
{ok, Pem} ->
22112238
Entries = public_key:pem_decode(Pem),
22122239
case lists:keyfind('Certificate', 1, Entries) of
22132240
false ->

0 commit comments

Comments
 (0)