Skip to content

Commit 7057c0f

Browse files
author
Erlang/OTP
committed
Merge branch 'ingela/maint/ssl/unique-extensions/OTP-19791' into maint-27
* ingela/maint/ssl/unique-extensions/OTP-19791: ssl: Assert that hello extensions are unique
2 parents 858f78a + cdb26ed commit 7057c0f

File tree

1 file changed

+36
-1
lines changed

1 file changed

+36
-1
lines changed

lib/ssl/src/ssl_handshake.erl

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2884,10 +2884,12 @@ decode_extensions(<<?UINT16(?ALPN_EXT), ?UINT16(ExtLen), ?UINT16(Len),
28842884
ExtensionData:Len/binary, Rest/binary>>, Version, MessageType, Acc)
28852885
when Len + 2 =:= ExtLen ->
28862886
ALPN = #alpn{extension_data = ExtensionData},
2887+
assert_unique_extension(alpn, Acc),
28872888
decode_extensions(Rest, Version, MessageType, Acc#{alpn => ALPN});
28882889
decode_extensions(<<?UINT16(?NEXTPROTONEG_EXT), ?UINT16(Len),
28892890
ExtensionData:Len/binary, Rest/binary>>, Version, MessageType, Acc) ->
28902891
NextP = #next_protocol_negotiation{extension_data = ExtensionData},
2892+
assert_unique_extension(next_protocol_negotiation, Acc),
28912893
decode_extensions(Rest, Version, MessageType, Acc#{next_protocol_negotiation => NextP});
28922894
decode_extensions(<<?UINT16(?RENEGOTIATION_EXT), ?UINT16(Len),
28932895
Info:Len/binary, Rest/binary>>, Version, MessageType, Acc) ->
@@ -2899,6 +2901,7 @@ decode_extensions(<<?UINT16(?RENEGOTIATION_EXT), ?UINT16(Len),
28992901
<<?BYTE(VerifyLen), VerifyInfo/binary>> = Info,
29002902
VerifyInfo
29012903
end,
2904+
assert_unique_extension(renegotiation_info, Acc),
29022905
decode_extensions(Rest, Version, MessageType,
29032906
Acc#{renegotiation_info =>
29042907
#renegotiation_info{renegotiated_connection =
@@ -2907,6 +2910,7 @@ decode_extensions(<<?UINT16(?RENEGOTIATION_EXT), ?UINT16(Len),
29072910
decode_extensions(<<?UINT16(?SRP_EXT), ?UINT16(Len), ?BYTE(SRPLen),
29082911
SRP:SRPLen/binary, Rest/binary>>, Version, MessageType, Acc)
29092912
when Len == SRPLen + 1 ->
2913+
assert_unique_extension(srp, Acc),
29102914
decode_extensions(Rest, Version, MessageType, Acc#{srp => #srp{username = SRP}});
29112915

29122916
decode_extensions(<<?UINT16(?SIGNATURE_ALGORITHMS_EXT), ?UINT16(Len),
@@ -2916,6 +2920,7 @@ decode_extensions(<<?UINT16(?SIGNATURE_ALGORITHMS_EXT), ?UINT16(Len),
29162920
<<?UINT16(SignAlgoListLen), SignAlgoList/binary>> = ExtData,
29172921
HashSignAlgos = [{ssl_cipher:hash_algorithm(Hash), ssl_cipher:sign_algorithm(Sign)} ||
29182922
<<?BYTE(Hash), ?BYTE(Sign)>> <= SignAlgoList],
2923+
assert_unique_extension(signature_algs, Acc),
29192924
decode_extensions(Rest, Version, MessageType,
29202925
Acc#{signature_algs =>
29212926
#hash_sign_algos{hash_sign_algos =
@@ -2925,6 +2930,7 @@ decode_extensions(<<?UINT16(?SIGNATURE_ALGORITHMS_EXT), ?UINT16(Len),
29252930
SignSchemeListLen = Len - 2,
29262931
<<?UINT16(SignSchemeListLen), SignSchemeList/binary>> = ExtData,
29272932
HashSigns = decode_sign_alg(Version, SignSchemeList),
2933+
assert_unique_extension(signature_algs, Acc),
29282934
decode_extensions(Rest, Version, MessageType,
29292935
Acc#{signature_algs =>
29302936
#hash_sign_algos{
@@ -2934,6 +2940,7 @@ decode_extensions(<<?UINT16(?SIGNATURE_ALGORITHMS_EXT), ?UINT16(Len),
29342940
SignSchemeListLen = Len - 2,
29352941
<<?UINT16(SignSchemeListLen), SignSchemeList/binary>> = ExtData,
29362942
SignSchemes = decode_sign_alg(Version, SignSchemeList),
2943+
assert_unique_extension(signature_algs, Acc),
29372944
decode_extensions(Rest, Version, MessageType,
29382945
Acc#{signature_algs =>
29392946
#signature_algorithms{
@@ -2974,6 +2981,7 @@ decode_extensions(<<?UINT16(?SIGNATURE_ALGORITHMS_CERT_EXT), ?UINT16(Len),
29742981
end,
29752982
SignSchemes= lists:filtermap(Fun, [SignScheme ||
29762983
<<?UINT16(SignScheme)>> <= SignSchemeList]),
2984+
assert_unique_extension(signature_algs_cert, Acc),
29772985
decode_extensions(Rest, Version, MessageType,
29782986
Acc#{signature_algs_cert =>
29792987
#signature_algorithms_cert{
@@ -2983,6 +2991,7 @@ decode_extensions(<<?UINT16(?USE_SRTP_EXT), ?UINT16(Len),
29832991
ExtData:Len/binary, Rest/binary>>, Version, MessageType, Acc) ->
29842992
<<?UINT16(ProfilesLen), ProfilesBin:ProfilesLen/binary, ?BYTE(MKILen), MKI:MKILen/binary>> = ExtData,
29852993
Profiles = [P || <<P:2/binary>> <= ProfilesBin],
2994+
assert_unique_extension(use_srtp, Acc),
29862995
decode_extensions(Rest, Version, MessageType,
29872996
Acc#{use_srtp =>
29882997
#use_srtp{
@@ -3003,6 +3012,7 @@ decode_extensions(<<?UINT16(?ELLIPTIC_CURVES_EXT), ?UINT16(Len),
30033012
end
30043013
end,
30053014
EllipticCurves = lists:filtermap(Pick, [ECC || <<ECC:16>> <= EllipticCurveList]),
3015+
assert_unique_extension(elliptic_curves, Acc),
30063016
decode_extensions(Rest, Version, MessageType,
30073017
Acc#{elliptic_curves =>
30083018
#elliptic_curves{elliptic_curve_list =
@@ -3021,6 +3031,7 @@ decode_extensions(<<?UINT16(?ELLIPTIC_CURVES_EXT), ?UINT16(Len),
30213031
end
30223032
end,
30233033
SupportedGroups = lists:filtermap(Pick, [Group || <<Group:16>> <= GroupList]),
3034+
assert_unique_extension(elliptic_curves, Acc),
30243035
decode_extensions(Rest, Version, MessageType,
30253036
Acc#{elliptic_curves =>
30263037
#supported_groups{supported_groups =
@@ -3030,29 +3041,34 @@ decode_extensions(<<?UINT16(?EC_POINT_FORMATS_EXT), ?UINT16(Len),
30303041
ExtData:Len/binary, Rest/binary>>, Version, MessageType, Acc) ->
30313042
<<?BYTE(_), ECPointFormatList/binary>> = ExtData,
30323043
ECPointFormats = binary_to_list(ECPointFormatList),
3044+
assert_unique_extension(ec_point_formats, Acc),
30333045
decode_extensions(Rest, Version, MessageType,
30343046
Acc#{ec_point_formats =>
30353047
#ec_point_formats{ec_point_format_list =
30363048
ECPointFormats}});
30373049

30383050
decode_extensions(<<?UINT16(?SNI_EXT), ?UINT16(Len),
30393051
Rest/binary>>, Version, MessageType, Acc) when Len == 0 ->
3052+
assert_unique_extension(sni, Acc),
30403053
decode_extensions(Rest, Version, MessageType,
30413054
Acc#{sni => #sni{hostname = ""}}); %% Server may send an empty SNI
30423055

30433056
decode_extensions(<<?UINT16(?SNI_EXT), ?UINT16(Len),
30443057
ExtData:Len/binary, Rest/binary>>, Version, MessageType, Acc) ->
30453058
<<?UINT16(_), NameList/binary>> = ExtData,
3059+
assert_unique_extension(sni, Acc),
30463060
decode_extensions(Rest, Version, MessageType,
30473061
Acc#{sni => dec_sni(NameList)});
30483062

30493063
decode_extensions(<<?UINT16(?MAX_FRAGMENT_LENGTH_EXT), ?UINT16(1), ?BYTE(MaxFragEnum), Rest/binary>>,
30503064
Version, MessageType, Acc) ->
30513065
%% RFC 6066 Section 4
3066+
assert_unique_extension(max_frag_enum, Acc),
30523067
decode_extensions(Rest, Version, MessageType, Acc#{max_frag_enum => #max_frag_enum{enum = MaxFragEnum}});
30533068
decode_extensions(<<?UINT16(?SUPPORTED_VERSIONS_EXT), ?UINT16(Len),
30543069
ExtData:Len/binary, Rest/binary>>, Version, MessageType, Acc) when Len > 2 ->
30553070
<<?BYTE(_),Versions/binary>> = ExtData,
3071+
assert_unique_extension(client_hello_versions, Acc),
30563072
decode_extensions(Rest, Version, MessageType,
30573073
Acc#{client_hello_versions =>
30583074
#client_hello_versions{
@@ -3061,6 +3077,7 @@ decode_extensions(<<?UINT16(?SUPPORTED_VERSIONS_EXT), ?UINT16(Len),
30613077
decode_extensions(<<?UINT16(?SUPPORTED_VERSIONS_EXT), ?UINT16(Len),
30623078
?UINT16(SelectedVersion), Rest/binary>>, Version, MessageType, Acc)
30633079
when Len =:= 2, SelectedVersion =:= 16#0304 ->
3080+
assert_unique_extension(server_hello_selected_version, Acc),
30643081
decode_extensions(Rest, Version, MessageType,
30653082
Acc#{server_hello_selected_version =>
30663083
#server_hello_selected_version{selected_version = ?TLS_1_3}});
@@ -3069,6 +3086,7 @@ decode_extensions(<<?UINT16(?KEY_SHARE_EXT), ?UINT16(Len),
30693086
ExtData:Len/binary, Rest/binary>>,
30703087
Version, MessageType = client_hello, Acc) ->
30713088
<<?UINT16(_),ClientShares/binary>> = ExtData,
3089+
assert_unique_extension(key_share, Acc),
30723090
decode_extensions(Rest, Version, MessageType,
30733091
Acc#{key_share =>
30743092
#key_share_client_hello{
@@ -3078,6 +3096,7 @@ decode_extensions(<<?UINT16(?KEY_SHARE_EXT), ?UINT16(Len),
30783096
ExtData:Len/binary, Rest/binary>>,
30793097
Version, MessageType = server_hello, Acc) ->
30803098
<<?UINT16(Group),?UINT16(KeyLen),KeyExchange:KeyLen/binary>> = ExtData,
3099+
assert_unique_extension(key_share, Acc),
30813100
decode_extensions(Rest, Version, MessageType,
30823101
Acc#{key_share =>
30833102
#key_share_server_hello{
@@ -3098,6 +3117,7 @@ decode_extensions(<<?UINT16(?KEY_SHARE_EXT), ?UINT16(Len),
30983117
decode_extensions(<<?UINT16(?PSK_KEY_EXCHANGE_MODES_EXT), ?UINT16(Len),
30993118
ExtData:Len/binary, Rest/binary>>, Version, MessageType, Acc) ->
31003119
<<?BYTE(PLen),KEModes:PLen/binary>> = ExtData,
3120+
assert_unique_extension(psk_key_exchange_modes, Acc),
31013121
decode_extensions(Rest, Version, MessageType,
31023122
Acc#{psk_key_exchange_modes =>
31033123
#psk_key_exchange_modes{
@@ -3107,17 +3127,18 @@ decode_extensions(<<?UINT16(?PRE_SHARED_KEY_EXT), ?UINT16(Len),
31073127
ExtData:Len/binary, Rest/binary>>,
31083128
Version, MessageType = client_hello, Acc) ->
31093129
<<?UINT16(IdLen),Identities:IdLen/binary,?UINT16(BLen),Binders:BLen/binary>> = ExtData,
3130+
assert_unique_extension(pre_shared_key, Acc),
31103131
decode_extensions(Rest, Version, MessageType,
31113132
Acc#{pre_shared_key =>
31123133
#pre_shared_key_client_hello{
31133134
offered_psks = #offered_psks{
31143135
identities = decode_psk_identities(Identities),
31153136
binders = decode_psk_binders(Binders)}}});
3116-
31173137
decode_extensions(<<?UINT16(?PRE_SHARED_KEY_EXT), ?UINT16(Len),
31183138
ExtData:Len/binary, Rest/binary>>,
31193139
Version, MessageType = server_hello, Acc) ->
31203140
<<?UINT16(Identity)>> = ExtData,
3141+
assert_unique_extension(pre_shared_key, Acc),
31213142
decode_extensions(Rest, Version, MessageType,
31223143
Acc#{pre_shared_key =>
31233144
#pre_shared_key_server_hello{
@@ -3127,6 +3148,7 @@ decode_extensions(<<?UINT16(?COOKIE_EXT), ?UINT16(Len), ?UINT16(CookieLen),
31273148
Cookie:CookieLen/binary, Rest/binary>>,
31283149
Version, MessageType, Acc)
31293150
when Len == CookieLen + 2 ->
3151+
assert_unique_extension(cookie, Acc),
31303152
decode_extensions(Rest, Version, MessageType,
31313153
Acc#{cookie => #cookie{cookie = Cookie}});
31323154

@@ -3137,6 +3159,7 @@ decode_extensions(<<?UINT16(?STATUS_REQUEST), ?UINT16(Len),
31373159
_ExtensionData:Len/binary, Rest/binary>>, Version,
31383160
MessageType = server_hello, Acc)
31393161
when Len =:= 0 ->
3162+
assert_unique_extension(status_request, Acc),
31403163
decode_extensions(Rest, Version, MessageType,
31413164
Acc#{status_request => undefined});
31423165
%% RFC8446 4.4.2.1, In TLS1.3, the body of the "status_request" extension
@@ -3149,6 +3172,7 @@ decode_extensions(<<?UINT16(?STATUS_REQUEST), ?UINT16(Len),
31493172
<<?BYTE(?CERTIFICATE_STATUS_TYPE_OCSP),
31503173
?UINT24(OCSPLen),
31513174
ASN1OCSPResponse:OCSPLen/binary>> ->
3175+
assert_unique_extension(status_request, Acc),
31523176
decode_extensions(Rest, Version, MessageType,
31533177
Acc#{status_request => #certificate_status{response = ASN1OCSPResponse}});
31543178
_Other ->
@@ -3157,12 +3181,14 @@ decode_extensions(<<?UINT16(?STATUS_REQUEST), ?UINT16(Len),
31573181

31583182
decode_extensions(<<?UINT16(?EARLY_DATA_EXT), ?UINT16(0), Rest/binary>>,
31593183
Version, MessageType, Acc) ->
3184+
assert_unique_extension(early_data, Acc),
31603185
decode_extensions(Rest, Version, MessageType,
31613186
Acc#{early_data => #early_data_indication{}});
31623187

31633188
decode_extensions(<<?UINT16(?EARLY_DATA_EXT), ?UINT16(4), ?UINT32(MaxSize),
31643189
Rest/binary>>,
31653190
Version, MessageType, Acc) ->
3191+
assert_unique_extension(early_data, Acc),
31663192
decode_extensions(Rest, Version, MessageType,
31673193
Acc#{early_data =>
31683194
#early_data_indication_nst{indication = MaxSize}});
@@ -3171,6 +3197,7 @@ decode_extensions(<<?UINT16(?CERTIFICATE_AUTHORITIES_EXT), ?UINT16(Len),
31713197
Version, MessageType, Acc) ->
31723198
CertAutsLen = Len - 2,
31733199
<<?UINT16(CertAutsLen), EncCertAuts/binary>> = CertAutsExt,
3200+
assert_unique_extension(certificate_authorities, Acc),
31743201
decode_extensions(Rest, Version, MessageType,
31753202
Acc#{certificate_authorities =>
31763203
#certificate_authorities{authorities = decode_cert_auths(EncCertAuts, [])}});
@@ -3182,6 +3209,14 @@ decode_extensions(<<?UINT16(_), ?UINT16(Len), _Unknown:Len/binary, Rest/binary>>
31823209
decode_extensions(_, _, _, Acc) ->
31833210
Acc.
31843211

3212+
assert_unique_extension(Ext, Map) ->
3213+
case maps:get(Ext, Map, undefined) of
3214+
undefined ->
3215+
ok;
3216+
_ ->
3217+
throw(?ALERT_REC(?FATAL, ?ILLEGAL_PARAMETER, {duplicate_extension, Ext}))
3218+
end.
3219+
31853220
decode_sign_alg(?TLS_1_2, SignSchemeList) ->
31863221
%% Ignore unknown signature algorithms
31873222
Fun = fun(Elem) ->

0 commit comments

Comments
 (0)