Skip to content

Commit 75a4ebc

Browse files
committed
ssl: Assert that hello extensions are unique
1 parent 3431636 commit 75a4ebc

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
@@ -2885,10 +2885,12 @@ decode_extensions(<<?UINT16(?ALPN_EXT), ?UINT16(ExtLen), ?UINT16(Len),
28852885
ExtensionData:Len/binary, Rest/binary>>, Version, MessageType, Acc)
28862886
when Len + 2 =:= ExtLen ->
28872887
ALPN = #alpn{extension_data = ExtensionData},
2888+
assert_unique_extension(alpn, Acc),
28882889
decode_extensions(Rest, Version, MessageType, Acc#{alpn => ALPN});
28892890
decode_extensions(<<?UINT16(?NEXTPROTONEG_EXT), ?UINT16(Len),
28902891
ExtensionData:Len/binary, Rest/binary>>, Version, MessageType, Acc) ->
28912892
NextP = #next_protocol_negotiation{extension_data = ExtensionData},
2893+
assert_unique_extension(next_protocol_negotiation, Acc),
28922894
decode_extensions(Rest, Version, MessageType, Acc#{next_protocol_negotiation => NextP});
28932895
decode_extensions(<<?UINT16(?RENEGOTIATION_EXT), ?UINT16(Len),
28942896
Info:Len/binary, Rest/binary>>, Version, MessageType, Acc) ->
@@ -2900,6 +2902,7 @@ decode_extensions(<<?UINT16(?RENEGOTIATION_EXT), ?UINT16(Len),
29002902
<<?BYTE(VerifyLen), VerifyInfo/binary>> = Info,
29012903
VerifyInfo
29022904
end,
2905+
assert_unique_extension(renegotiation_info, Acc),
29032906
decode_extensions(Rest, Version, MessageType,
29042907
Acc#{renegotiation_info =>
29052908
#renegotiation_info{renegotiated_connection =
@@ -2908,6 +2911,7 @@ decode_extensions(<<?UINT16(?RENEGOTIATION_EXT), ?UINT16(Len),
29082911
decode_extensions(<<?UINT16(?SRP_EXT), ?UINT16(Len), ?BYTE(SRPLen),
29092912
SRP:SRPLen/binary, Rest/binary>>, Version, MessageType, Acc)
29102913
when Len == SRPLen + 1 ->
2914+
assert_unique_extension(srp, Acc),
29112915
decode_extensions(Rest, Version, MessageType, Acc#{srp => #srp{username = SRP}});
29122916

29132917
decode_extensions(<<?UINT16(?SIGNATURE_ALGORITHMS_EXT), ?UINT16(Len),
@@ -2917,6 +2921,7 @@ decode_extensions(<<?UINT16(?SIGNATURE_ALGORITHMS_EXT), ?UINT16(Len),
29172921
<<?UINT16(SignAlgoListLen), SignAlgoList/binary>> = ExtData,
29182922
HashSignAlgos = [{ssl_cipher:hash_algorithm(Hash), ssl_cipher:sign_algorithm(Sign)} ||
29192923
<<?BYTE(Hash), ?BYTE(Sign)>> <= SignAlgoList],
2924+
assert_unique_extension(signature_algs, Acc),
29202925
decode_extensions(Rest, Version, MessageType,
29212926
Acc#{signature_algs =>
29222927
#hash_sign_algos{hash_sign_algos =
@@ -2926,6 +2931,7 @@ decode_extensions(<<?UINT16(?SIGNATURE_ALGORITHMS_EXT), ?UINT16(Len),
29262931
SignSchemeListLen = Len - 2,
29272932
<<?UINT16(SignSchemeListLen), SignSchemeList/binary>> = ExtData,
29282933
HashSigns = decode_sign_alg(Version, SignSchemeList),
2934+
assert_unique_extension(signature_algs, Acc),
29292935
decode_extensions(Rest, Version, MessageType,
29302936
Acc#{signature_algs =>
29312937
#hash_sign_algos{
@@ -2935,6 +2941,7 @@ decode_extensions(<<?UINT16(?SIGNATURE_ALGORITHMS_EXT), ?UINT16(Len),
29352941
SignSchemeListLen = Len - 2,
29362942
<<?UINT16(SignSchemeListLen), SignSchemeList/binary>> = ExtData,
29372943
SignSchemes = decode_sign_alg(Version, SignSchemeList),
2944+
assert_unique_extension(signature_algs, Acc),
29382945
decode_extensions(Rest, Version, MessageType,
29392946
Acc#{signature_algs =>
29402947
#signature_algorithms{
@@ -2954,6 +2961,7 @@ decode_extensions(<<?UINT16(?SIGNATURE_ALGORITHMS_CERT_EXT), ?UINT16(Len),
29542961
end,
29552962
SignSchemes= lists:filtermap(Fun, [SignScheme ||
29562963
<<?UINT16(SignScheme)>> <= SignSchemeList]),
2964+
assert_unique_extension(signature_algs_cert, Acc),
29572965
decode_extensions(Rest, Version, MessageType,
29582966
Acc#{signature_algs_cert =>
29592967
#signature_algorithms_cert{
@@ -2963,6 +2971,7 @@ decode_extensions(<<?UINT16(?USE_SRTP_EXT), ?UINT16(Len),
29632971
ExtData:Len/binary, Rest/binary>>, Version, MessageType, Acc) ->
29642972
<<?UINT16(ProfilesLen), ProfilesBin:ProfilesLen/binary, ?BYTE(MKILen), MKI:MKILen/binary>> = ExtData,
29652973
Profiles = [P || <<P:2/binary>> <= ProfilesBin],
2974+
assert_unique_extension(use_srtp, Acc),
29662975
decode_extensions(Rest, Version, MessageType,
29672976
Acc#{use_srtp =>
29682977
#use_srtp{
@@ -2983,6 +2992,7 @@ decode_extensions(<<?UINT16(?ELLIPTIC_CURVES_EXT), ?UINT16(Len),
29832992
end
29842993
end,
29852994
EllipticCurves = lists:filtermap(Pick, [ECC || <<ECC:16>> <= EllipticCurveList]),
2995+
assert_unique_extension(elliptic_curves, Acc),
29862996
decode_extensions(Rest, Version, MessageType,
29872997
Acc#{elliptic_curves =>
29882998
#elliptic_curves{elliptic_curve_list =
@@ -3001,6 +3011,7 @@ decode_extensions(<<?UINT16(?ELLIPTIC_CURVES_EXT), ?UINT16(Len),
30013011
end
30023012
end,
30033013
SupportedGroups = lists:filtermap(Pick, [Group || <<Group:16>> <= GroupList]),
3014+
assert_unique_extension(elliptic_curves, Acc),
30043015
decode_extensions(Rest, Version, MessageType,
30053016
Acc#{elliptic_curves =>
30063017
#supported_groups{supported_groups =
@@ -3010,29 +3021,34 @@ decode_extensions(<<?UINT16(?EC_POINT_FORMATS_EXT), ?UINT16(Len),
30103021
ExtData:Len/binary, Rest/binary>>, Version, MessageType, Acc) ->
30113022
<<?BYTE(_), ECPointFormatList/binary>> = ExtData,
30123023
ECPointFormats = binary_to_list(ECPointFormatList),
3024+
assert_unique_extension(ec_point_formats, Acc),
30133025
decode_extensions(Rest, Version, MessageType,
30143026
Acc#{ec_point_formats =>
30153027
#ec_point_formats{ec_point_format_list =
30163028
ECPointFormats}});
30173029

30183030
decode_extensions(<<?UINT16(?SNI_EXT), ?UINT16(Len),
30193031
Rest/binary>>, Version, MessageType, Acc) when Len == 0 ->
3032+
assert_unique_extension(sni, Acc),
30203033
decode_extensions(Rest, Version, MessageType,
30213034
Acc#{sni => #sni{hostname = ""}}); %% Server may send an empty SNI
30223035

30233036
decode_extensions(<<?UINT16(?SNI_EXT), ?UINT16(Len),
30243037
ExtData:Len/binary, Rest/binary>>, Version, MessageType, Acc) ->
30253038
<<?UINT16(_), NameList/binary>> = ExtData,
3039+
assert_unique_extension(sni, Acc),
30263040
decode_extensions(Rest, Version, MessageType,
30273041
Acc#{sni => dec_sni(NameList)});
30283042

30293043
decode_extensions(<<?UINT16(?MAX_FRAGMENT_LENGTH_EXT), ?UINT16(1), ?BYTE(MaxFragEnum), Rest/binary>>,
30303044
Version, MessageType, Acc) ->
30313045
%% RFC 6066 Section 4
3046+
assert_unique_extension(max_frag_enum, Acc),
30323047
decode_extensions(Rest, Version, MessageType, Acc#{max_frag_enum => #max_frag_enum{enum = MaxFragEnum}});
30333048
decode_extensions(<<?UINT16(?SUPPORTED_VERSIONS_EXT), ?UINT16(Len),
30343049
ExtData:Len/binary, Rest/binary>>, Version, MessageType, Acc) when Len > 2 ->
30353050
<<?BYTE(_),Versions/binary>> = ExtData,
3051+
assert_unique_extension(client_hello_versions, Acc),
30363052
decode_extensions(Rest, Version, MessageType,
30373053
Acc#{client_hello_versions =>
30383054
#client_hello_versions{
@@ -3041,6 +3057,7 @@ decode_extensions(<<?UINT16(?SUPPORTED_VERSIONS_EXT), ?UINT16(Len),
30413057
decode_extensions(<<?UINT16(?SUPPORTED_VERSIONS_EXT), ?UINT16(Len),
30423058
?UINT16(SelectedVersion), Rest/binary>>, Version, MessageType, Acc)
30433059
when Len =:= 2, SelectedVersion =:= 16#0304 ->
3060+
assert_unique_extension(server_hello_selected_version, Acc),
30443061
decode_extensions(Rest, Version, MessageType,
30453062
Acc#{server_hello_selected_version =>
30463063
#server_hello_selected_version{selected_version = ?TLS_1_3}});
@@ -3049,6 +3066,7 @@ decode_extensions(<<?UINT16(?KEY_SHARE_EXT), ?UINT16(Len),
30493066
ExtData:Len/binary, Rest/binary>>,
30503067
Version, MessageType = client_hello, Acc) ->
30513068
<<?UINT16(_),ClientShares/binary>> = ExtData,
3069+
assert_unique_extension(key_share, Acc),
30523070
decode_extensions(Rest, Version, MessageType,
30533071
Acc#{key_share =>
30543072
#key_share_client_hello{
@@ -3058,6 +3076,7 @@ decode_extensions(<<?UINT16(?KEY_SHARE_EXT), ?UINT16(Len),
30583076
ExtData:Len/binary, Rest/binary>>,
30593077
Version, MessageType = server_hello, Acc) ->
30603078
<<?UINT16(Group),?UINT16(KeyLen),KeyExchange:KeyLen/binary>> = ExtData,
3079+
assert_unique_extension(key_share, Acc),
30613080
decode_extensions(Rest, Version, MessageType,
30623081
Acc#{key_share =>
30633082
#key_share_server_hello{
@@ -3078,6 +3097,7 @@ decode_extensions(<<?UINT16(?KEY_SHARE_EXT), ?UINT16(Len),
30783097
decode_extensions(<<?UINT16(?PSK_KEY_EXCHANGE_MODES_EXT), ?UINT16(Len),
30793098
ExtData:Len/binary, Rest/binary>>, Version, MessageType, Acc) ->
30803099
<<?BYTE(PLen),KEModes:PLen/binary>> = ExtData,
3100+
assert_unique_extension(psk_key_exchange_modes, Acc),
30813101
decode_extensions(Rest, Version, MessageType,
30823102
Acc#{psk_key_exchange_modes =>
30833103
#psk_key_exchange_modes{
@@ -3087,17 +3107,18 @@ decode_extensions(<<?UINT16(?PRE_SHARED_KEY_EXT), ?UINT16(Len),
30873107
ExtData:Len/binary, Rest/binary>>,
30883108
Version, MessageType = client_hello, Acc) ->
30893109
<<?UINT16(IdLen),Identities:IdLen/binary,?UINT16(BLen),Binders:BLen/binary>> = ExtData,
3110+
assert_unique_extension(pre_shared_key, Acc),
30903111
decode_extensions(Rest, Version, MessageType,
30913112
Acc#{pre_shared_key =>
30923113
#pre_shared_key_client_hello{
30933114
offered_psks = #offered_psks{
30943115
identities = decode_psk_identities(Identities),
30953116
binders = decode_psk_binders(Binders)}}});
3096-
30973117
decode_extensions(<<?UINT16(?PRE_SHARED_KEY_EXT), ?UINT16(Len),
30983118
ExtData:Len/binary, Rest/binary>>,
30993119
Version, MessageType = server_hello, Acc) ->
31003120
<<?UINT16(Identity)>> = ExtData,
3121+
assert_unique_extension(pre_shared_key, Acc),
31013122
decode_extensions(Rest, Version, MessageType,
31023123
Acc#{pre_shared_key =>
31033124
#pre_shared_key_server_hello{
@@ -3107,6 +3128,7 @@ decode_extensions(<<?UINT16(?COOKIE_EXT), ?UINT16(Len), ?UINT16(CookieLen),
31073128
Cookie:CookieLen/binary, Rest/binary>>,
31083129
Version, MessageType, Acc)
31093130
when Len == CookieLen + 2 ->
3131+
assert_unique_extension(cookie, Acc),
31103132
decode_extensions(Rest, Version, MessageType,
31113133
Acc#{cookie => #cookie{cookie = Cookie}});
31123134

@@ -3117,6 +3139,7 @@ decode_extensions(<<?UINT16(?STATUS_REQUEST), ?UINT16(Len),
31173139
_ExtensionData:Len/binary, Rest/binary>>, Version,
31183140
MessageType = server_hello, Acc)
31193141
when Len =:= 0 ->
3142+
assert_unique_extension(status_request, Acc),
31203143
decode_extensions(Rest, Version, MessageType,
31213144
Acc#{status_request => undefined});
31223145
%% RFC8446 4.4.2.1, In TLS1.3, the body of the "status_request" extension
@@ -3129,6 +3152,7 @@ decode_extensions(<<?UINT16(?STATUS_REQUEST), ?UINT16(Len),
31293152
<<?BYTE(?CERTIFICATE_STATUS_TYPE_OCSP),
31303153
?UINT24(OCSPLen),
31313154
ASN1OCSPResponse:OCSPLen/binary>> ->
3155+
assert_unique_extension(status_request, Acc),
31323156
decode_extensions(Rest, Version, MessageType,
31333157
Acc#{status_request => #certificate_status{response = ASN1OCSPResponse}});
31343158
_Other ->
@@ -3137,12 +3161,14 @@ decode_extensions(<<?UINT16(?STATUS_REQUEST), ?UINT16(Len),
31373161

31383162
decode_extensions(<<?UINT16(?EARLY_DATA_EXT), ?UINT16(0), Rest/binary>>,
31393163
Version, MessageType, Acc) ->
3164+
assert_unique_extension(early_data, Acc),
31403165
decode_extensions(Rest, Version, MessageType,
31413166
Acc#{early_data => #early_data_indication{}});
31423167

31433168
decode_extensions(<<?UINT16(?EARLY_DATA_EXT), ?UINT16(4), ?UINT32(MaxSize),
31443169
Rest/binary>>,
31453170
Version, MessageType, Acc) ->
3171+
assert_unique_extension(early_data, Acc),
31463172
decode_extensions(Rest, Version, MessageType,
31473173
Acc#{early_data =>
31483174
#early_data_indication_nst{indication = MaxSize}});
@@ -3151,6 +3177,7 @@ decode_extensions(<<?UINT16(?CERTIFICATE_AUTHORITIES_EXT), ?UINT16(Len),
31513177
Version, MessageType, Acc) ->
31523178
CertAutsLen = Len - 2,
31533179
<<?UINT16(CertAutsLen), EncCertAuts/binary>> = CertAutsExt,
3180+
assert_unique_extension(certificate_authorities, Acc),
31543181
decode_extensions(Rest, Version, MessageType,
31553182
Acc#{certificate_authorities =>
31563183
#certificate_authorities{authorities = decode_cert_auths(EncCertAuts, [])}});
@@ -3162,6 +3189,14 @@ decode_extensions(<<?UINT16(_), ?UINT16(Len), _Unknown:Len/binary, Rest/binary>>
31623189
decode_extensions(_, _, _, Acc) ->
31633190
Acc.
31643191

3192+
assert_unique_extension(Ext, Map) ->
3193+
case maps:get(Ext, Map, undefined) of
3194+
undefined ->
3195+
ok;
3196+
_ ->
3197+
throw(?ALERT_REC(?FATAL, ?ILLEGAL_PARAMETER, {dublicate_extension, Ext}))
3198+
end.
3199+
31653200
decode_sign_alg(?TLS_1_2, SignSchemeList) ->
31663201
%% Ignore unknown signature algorithms
31673202
Fun = fun(Elem) ->

0 commit comments

Comments
 (0)